- New Feature: Block iron sights (by Flugente)

o if a gun/attachment has the boolean tag <BlockIronSight> in Items.xml, a gun's iron sights wont be selectable while selecting scope modes.
o if using dual weapons, only iron sights can be used
o new attachmentclass: AC_IRONSIGHT (4194304) for attachable iron sights (display on gun is different from reflex sights, no other differences... yet)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5291 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2012-05-20 17:18:28 +00:00
parent eb2ca0ba70
commit 93ea315502
7 changed files with 145 additions and 40 deletions
+1 -1
View File
@@ -166,7 +166,7 @@ BobbyRayPurchaseStruct BobbyRayPurchases[ 100 ];
#define BOBBYR_MISC_FILTER_BUTTON_GAP BOBBYR_CATALOGUE_BUTTON_GAP - 1
//Madd: new BR filters
#define BR_MISC_FILTER_OPTICS (AC_SCOPE | AC_SIGHT)
#define BR_MISC_FILTER_OPTICS (AC_SCOPE | AC_SIGHT | AC_IRONSIGHT)
#define BR_MISC_FILTER_SIDE_BOTTOM (AC_LASER | AC_FOREGRIP | AC_BIPOD)
#define BR_MISC_FILTER_MUZZLE (AC_SUPPRESSOR | AC_EXTENDER)
#define BR_MISC_FILTER_STOCK AC_STOCK
+21
View File
@@ -3837,6 +3837,27 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
mprintf( sMagX, sNewY, pStr );
gprintfinvalidate( sMagX, sNewY, pStr );
}
// improved iron sights are attachable iron sights (the 'normal' iron sight is the gun itself)
else if ( IsAttachmentClass(ObjList[pSoldier->bScopeMode]->usItem, AC_IRONSIGHT ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 52, sNewX, sNewY, VO_BLT_TRANSSHADOW, NULL );
SetFontForeground( FONT_ORANGE );
INT16 sMagX = sNewX + 13;
swprintf( pStr, L"*" );
// Get length of string
uiStringLength=StringPixLength(pStr, ITEM_FONT );
if ( uiBuffer == guiSAVEBUFFER )
{
RestoreExternBackgroundRect( sNewX, sNewY, 20, 15 );
}
mprintf( sMagX, sNewY, pStr );
gprintfinvalidate( sMagX, sNewY, pStr );
}
else if ( IsAttachmentClass(ObjList[pSoldier->bScopeMode]->usItem, AC_SIGHT ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 53, sNewX, sNewY, VO_BLT_TRANSSHADOW, NULL );
+6 -4
View File
@@ -648,10 +648,10 @@ extern OBJECTTYPE gTempObject;
#define AC_DETONATOR 0x00010000 //65536
#define AC_BATTERY 0x00020000 //131072
#define AC_EXTENDER 0x00040000 //262144
#define AC_SLING 0x00080000 //524288
#define AC_REMOTEDET 0x00100000 //1048576
#define AC_DEFUSE 0x00200000 //2097152
#define AC_MISC11 0x00400000 //4194304
#define AC_SLING 0x00080000 //524288 // rifle sling
#define AC_REMOTEDET 0x00100000 //1048576 // remote detonator for bombs
#define AC_DEFUSE 0x00200000 //2097152 // defuse item for bombs
#define AC_IRONSIGHT 0x00400000 //4194304 // for attachable Iron Sights
#define AC_MISC12 0x00800000 //8388608
#define AC_MISC13 0x01000000 //16777216
#define AC_MISC14 0x02000000 //33554432
@@ -954,6 +954,8 @@ typedef struct
UINT32 drugtype; // this flagmask determines what different components are used in a drug, which results in different effects
BOOLEAN blockironsight; // if a gun or any attachment have this property, the iron sight won't be usable (if there is at least one other usable sight)
} INVTYPE;
// CHRISL: Added new structures to handle LBE gear and the two new XML files that will be needed to deal
+68 -34
View File
@@ -9200,7 +9200,7 @@ INT16 GetAimBonus( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj, INT32 iRange, INT1
attachmentList::iterator iterend = (*pObj)[0]->attachments.end();
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
bonus += BonusReduceMore( GetItemAimBonus( &Item[iter->usItem], iRange, ubAimTime ), (*iter)[0]->data.objectStatus );
}
@@ -9938,7 +9938,7 @@ INT16 GetPercentAPReduction( SOLDIERTYPE * pSoldier, OBJECTTYPE * pObj )
bonus += Item[(*pObj)[0]->data.gun.usGunAmmoItem].percentapreduction;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if( iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if( iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
bonus += BonusReduceMore( Item[iter->usItem].percentapreduction,
(*iter)[0]->data.objectStatus );
@@ -10182,7 +10182,7 @@ INT16 GetVisionRangeBonus( SOLDIERTYPE * pSoldier )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if( iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if( iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
sScopebonus += BonusReduceMore( Item[iter->usItem].visionrangebonus, (*iter)[0]->data.objectStatus );
}
@@ -10289,7 +10289,7 @@ INT16 GetNightVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
sScopebonus += BonusReduceMore(
NightBonusScale( Item[iter->usItem].nightvisionrangebonus, bLightLevel ),
@@ -10389,7 +10389,7 @@ INT16 GetCaveVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
sScopebonus += BonusReduceMore(
NightBonusScale( Item[iter->usItem].cavevisionrangebonus, bLightLevel ),
@@ -10495,7 +10495,7 @@ INT16 GetDayVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
sScopebonus += BonusReduceMore( idiv( Item[iter->usItem].dayvisionrangebonus
* (NORMAL_LIGHTLEVEL_NIGHT - __max(bLightLevel,NORMAL_LIGHTLEVEL_DAY)), (NORMAL_LIGHTLEVEL_NIGHT-NORMAL_LIGHTLEVEL_DAY) ),
@@ -10597,7 +10597,7 @@ INT16 GetBrightLightVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
sScopebonus += BonusReduceMore( idiv( Item[iter->usItem].brightlightvisionrangebonus
* (NORMAL_LIGHTLEVEL_DAY - bLightLevel), NORMAL_LIGHTLEVEL_DAY ),
@@ -10748,7 +10748,7 @@ UINT8 GetPercentTunnelVision( SOLDIERTYPE * pSoldier )
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
// add boni only from non-scope items
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
bonus += Item[iter->usItem].percenttunnelvision;
}
@@ -11810,7 +11810,7 @@ INT16 GetMinRangeForAimBonus( SOLDIERTYPE* pSoldier, OBJECTTYPE * pObj )
attachmentList::iterator iterend = (*pObj)[0]->attachments.end();
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if ( !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
bonus += Item[iter->usItem].minrangeforaimbonus;
}
}
@@ -13141,46 +13141,80 @@ void GetScopeLists( OBJECTTYPE * pObj, std::map<INT8, OBJECTTYPE*>& arScopeMap
{
arScopeMap[i] = NULL;
}
// certain attachments prohibit the use of an iron sight once they are installed (flip-up built-in sights)
BOOLEAN noironsight = ( Item[pObj->usItem].blockironsight == TRUE );
attachmentList::iterator iterend = (*pObj)[0]->attachments.end();
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter)
{
if ( iter->exists() && IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) )
if ( iter->exists() )
{
FLOAT magfactor = Item[iter->usItem].scopemagfactor;
BOOLEAN isplaced = false;
if ( Item[iter->usItem].blockironsight == TRUE )
noironsight = TRUE;
if ( IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) )
{
FLOAT magfactor = Item[iter->usItem].scopemagfactor;
BOOLEAN isplaced = false;
for (INT8 i = USE_BEST_SCOPE; i < NUM_SCOPE_MODES; ++i)
{
if ( arScopeMap[i] && magfactor > Item[arScopeMap[i]->usItem].scopemagfactor )
{
// fit scope into existing list: move other entries down
for (INT8 j = NUM_SCOPE_MODES; j > i; --j)
{
arScopeMap[j] = arScopeMap[j-1];
}
arScopeMap[i] = &(*iter);
isplaced = true;
break;
}
}
// we have a scope that wasn't placed anywhere, as its magfactor is worse than everything else we have. Still, we put this thing to the end of our list
if ( !isplaced )
{
// determine which scope this would be and insert it
for (INT8 i = USE_BEST_SCOPE; i < NUM_SCOPE_MODES; ++i)
{
if ( !arScopeMap[i] )
{
arScopeMap[i] = &(*iter);
break;
}
}
}
}
}
}
// attachments might block the iron sights, we might not be able to use them...
if ( noironsight )
{
// if we have at least one other scope to use
if ( arScopeMap[USE_BEST_SCOPE] != NULL && arScopeMap[USE_SCOPE_2] != NULL )
{
// determine position of iron sight, delete it, move up all following scopes
for (INT8 i = USE_BEST_SCOPE; i < NUM_SCOPE_MODES; ++i)
{
if ( arScopeMap[i] && magfactor > Item[arScopeMap[i]->usItem].scopemagfactor )
{
// fit scope into existing list: move other entries down
if ( arScopeMap[i] == pObj )
{
arScopeMap.erase(i);
// move other entries down
for (INT8 j = NUM_SCOPE_MODES; j > i; --j)
{
arScopeMap[j] = arScopeMap[j-1];
}
arScopeMap[i] = &(*iter);
isplaced = true;
break;
}
}
// we have a scope that wasn't placed anywhere, as its magfactor is worse than everything else we have. Still, we put this thing to the end of our list
if ( !isplaced )
{
// determine which scope this would be and insert it
for (INT8 i = USE_BEST_SCOPE; i < NUM_SCOPE_MODES; ++i)
{
if ( !arScopeMap[i] )
{
arScopeMap[i] = &(*iter);
break;
}
}
}
}
}
}
+18
View File
@@ -12458,6 +12458,24 @@ void SOLDIERTYPE::ReLoadSoldierAnimationDueToHandItemChange( UINT16 usOldItem, U
{
fNewRifle = TRUE;
}
// Flugente: if we are using dual weapons, only allow iron sights (we can't look through two scopes simultaneously, can we?)
if ( (Item[ inv[ HANDPOS ].usItem ].usItemClass & IC_WEAPON) && (Item[ inv[ SECONDHANDPOS ].usItem ].usItemClass & IC_WEAPON) )
{
std::map<INT8, OBJECTTYPE*> ObjList;
GetScopeLists(&inv[ HANDPOS ], ObjList);
std::map<INT8, OBJECTTYPE*>::iterator itend = ObjList.end();
for (std::map<INT8, OBJECTTYPE*>::iterator it = ObjList.begin(); it != itend; ++it)
{
if ( (*it).second != NULL )
{
bScopeMode = (*it).first;
}
else
break;
}
}
}
}
+22 -1
View File
@@ -6350,7 +6350,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
attachmentList::iterator iter_end = (*&(pSoldier->inv[pSoldier->ubAttackingHand]))[0]->attachments.end();
for(attachmentList::iterator iter = (*&(pSoldier->inv[pSoldier->ubAttackingHand]))[0]->attachments.begin(); iter != iter_end; ++iter)
{
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT ) && Item[iter->usItem].aimbonus >= gGameExternalOptions.sHighPowerScope && iRange > Item[iter->usItem].minrangeforaimbonus)
if(iter->exists() && !IsAttachmentClass(iter->usItem, AC_SCOPE|AC_SIGHT|AC_IRONSIGHT ) && Item[iter->usItem].aimbonus >= gGameExternalOptions.sHighPowerScope && iRange > Item[iter->usItem].minrangeforaimbonus)
{
iPenalty = (Item[iter->usItem].aimbonus * (iRange - Item[iter->usItem].minrangeforaimbonus)) / 1000;
iPenalty = min(AIM_BONUS_PRONE, iPenalty);
@@ -10212,6 +10212,27 @@ void HandleTacticalEffectsOfEquipmentChange( SOLDIERTYPE *pSoldier, UINT32 uiInv
pSoldier->bScopeMode = USE_BEST_SCOPE;
}
}
// Flugente: if we are using dual weapons, only allow iron sights (we can't look through two scopes simultaneously, can we?)
if ( uiInvPos == HANDPOS || uiInvPos == SECONDHANDPOS )
{
if ( (Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass & IC_WEAPON) && (Item[ pSoldier->inv[ SECONDHANDPOS ].usItem ].usItemClass & IC_WEAPON) )
{
std::map<INT8, OBJECTTYPE*> ObjList;
GetScopeLists(&pSoldier->inv[ HANDPOS ], ObjList);
std::map<INT8, OBJECTTYPE*>::iterator itend = ObjList.end();
for (std::map<INT8, OBJECTTYPE*>::iterator it = ObjList.begin(); it != itend; ++it)
{
if ( (*it).second != NULL )
{
pSoldier->bScopeMode = (*it).first;
}
else
break;
}
}
}
}
+9
View File
@@ -264,6 +264,7 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "TripWire") == 0 ||
strcmp(name, "Directional") == 0 ||
strcmp(name, "DrugType") == 0 ||
strcmp(name, "BlockIronSight") == 0 ||
strcmp(name, "fFlags") == 0 ))
{
@@ -1325,7 +1326,13 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.drugtype = (UINT32) atol(pData->szCharData);
}
else if(strcmp(name, "BlockIronSight") == 0)
{
pData->curElement = ELEMENT;
pData->curItem.blockironsight = (BOOLEAN) atol(pData->szCharData);
}
pData->maxReadDepth--;
}
@@ -1938,6 +1945,8 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t<DrugType>%d</DrugType>\r\n", Item[cnt].drugtype );
FilePrintf(hFile,"\t\t<BlockIronSight>%d</BlockIronSight>\r\n", Item[cnt].blockironsight );
FilePrintf(hFile,"\t</ITEM>\r\n");
}
FilePrintf(hFile,"</ITEMLIST>\r\n");