Merge branch 'master' into ExtraMercs

This commit is contained in:
Asdow
2024-11-09 13:44:53 +02:00
371 changed files with 6539 additions and 13390 deletions
+9 -13
View File
@@ -352,9 +352,8 @@ INT32 PickRandomLocationAtMinSpacesAway( INT32 sGridNo, INT16 sMinValue, INT16 s
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"PickRandomLocationAtMinSpacesAway");
sX = CenterX( sGridNo );
sY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
while(TileIsOutOfBounds(sNewGridNo))
{
sNewX = sX + sMinValue + (INT16)Random( sRandomVar );
@@ -596,8 +595,7 @@ void BeginBombing( )
sGridNo = PickRandomLocationAtMinSpacesAway( gsDiveTargetLocation , 300, 200 );
// Save X, y:
gsDiveX = CenterX( sGridNo );
gsDiveY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &gsDiveX, &gsDiveY);
RESETTIMECOUNTER( giTimerAirRaidUpdate, RAID_DELAY );
@@ -657,8 +655,7 @@ void BeginDive( )
sGridNo = PickRandomLocationAtMinSpacesAway( gsDiveTargetLocation, 300, 200 );
// Save X, y:
gsDiveX = CenterX( sGridNo );
gsDiveY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &gsDiveX, &gsDiveY);
RESETTIMECOUNTER( giTimerAirRaidUpdate, RAID_DELAY );
giNumTurnsSinceDiveStarted = 0;
@@ -760,8 +757,7 @@ void DoDive( )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"DoDive: move towards target");
// Move Towards target....
sTargetX = CenterX( gsDiveTargetLocation );
sTargetY = CenterY( gsDiveTargetLocation );
ConvertGridNoToCenterCellXY(gsDiveTargetLocation, &sTargetX, &sTargetY);
// Determine deltas
dDeltaX = (FLOAT)( sTargetX - gsDiveX );
@@ -886,7 +882,7 @@ void DoBombing( )
INT16 sRange;
INT32 sGridNo, sOldGridNo, sBombGridNo;
INT16 sTargetX, sTargetY;
INT16 sTargetX, sTargetY, sBombX, sBombY;
UINT16 usItem;
INT16 sStrafeX, sStrafeY;
FLOAT dDeltaX, dDeltaY, dAngle, dDeltaXPos, dDeltaYPos;
@@ -933,8 +929,7 @@ void DoBombing( )
RESETTIMECOUNTER( giTimerAirRaidUpdate, RAID_DELAY );
// Move Towards target....
sTargetX = CenterX( gsDiveTargetLocation );
sTargetY = CenterY( gsDiveTargetLocation );
ConvertGridNoToCenterCellXY(gsDiveTargetLocation, &sTargetX, &sTargetY);
// Determine deltas
dDeltaX = (FLOAT)( sTargetX - gsDiveX );
@@ -1002,7 +997,8 @@ void DoBombing( )
}
// Drop bombs...
InternalIgniteExplosion( NOBODY, CenterX( sBombGridNo ), CenterY( sBombGridNo ), 0, sBombGridNo, usItem, fLocate, (UINT8)IsRoofPresentAtGridNo( sBombGridNo ) );
ConvertGridNoToCenterCellXY(sBombGridNo, &sBombX, &sBombY);
InternalIgniteExplosion( NOBODY, sBombX, sBombY, 0, sBombGridNo, usItem, fLocate , (UINT8)IsRoofPresentAtGridNo( sBombGridNo ) );
}
+5 -5
View File
@@ -4297,10 +4297,10 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
// ADJUST BASED ON ITEM IN HAND....
usItem = pSoldier->inv[ HANDPOS ].usItem;
if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !Item[usItem].rocketlauncher)
if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !ItemIsRocketLauncher(usItem) )
{
// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) )
if ( (Item[ usItem ].twohanded ) )
if (ItemIsTwoHanded(usItem))
{
ubWaterHandIndex = 0;
}
@@ -4321,7 +4321,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
// ADJUST BASED ON ITEM IN HAND....
usItem = pSoldier->inv[ HANDPOS ].usItem;
if ( !(Item[ usItem ].usItemClass == IC_GUN ) && !(Item[ usItem ].usItemClass == IC_LAUNCHER ) || Item[usItem].rocketlauncher )
if ( !(Item[ usItem ].usItemClass == IC_GUN ) && !(Item[ usItem ].usItemClass == IC_LAUNCHER ) || ItemIsRocketLauncher(usItem) )
{
if ( usAnimState == STANDING )
{
@@ -4342,10 +4342,10 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
else
{
// CHECK FOR HANDGUN
if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !Item[usItem].rocketlauncher )
if ( ( Item[ usItem ].usItemClass == IC_GUN || Item[ usItem ].usItemClass == IC_LAUNCHER ) && !ItemIsRocketLauncher(usItem) )
{
// if ( !(Item[ usItem ].fFlags & ITEM_TWO_HANDED) )
if ( !(Item[ usItem ].twohanded ) )
if ( !ItemIsTwoHanded(usItem) )
{
// SANDRO - new anim for running with pistol by PasHancock
if ( usAnimState == RUNNING )
+19 -50
View File
@@ -71,7 +71,6 @@ void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UIN
void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UINT8 ubAtMostNumItems );
void ArmsDealerGetsFreshStock( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubNumItems );
BOOLEAN ItemContainsLiquid( UINT16 usItemIndex );
UINT8 DetermineDealerItemCondition( UINT8 ubArmsDealer, UINT16 usItemIndex );
BOOLEAN DoesItemAppearInDealerInventoryList( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN fPurchaseFromPlayer );
@@ -85,8 +84,6 @@ BOOLEAN CanThisItemBeSoldToSimulatedCustomer( UINT8 ubArmsDealerID, UINT16 usIte
void GuaranteeMinimumAlcohol( UINT8 ubArmsDealer );
BOOLEAN ItemIsARocketRifle( INT16 sItemIndex );
BOOLEAN GetArmsDealerShopHours( UINT8 ubArmsDealer, UINT32 *puiOpeningTime, UINT32 *puiClosingTime );
ARMS_DEALER_STATUS& ARMS_DEALER_STATUS::operator=(const OLD_ARMS_DEALER_STATUS_101& status)
@@ -961,7 +958,7 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem )
return( ARMS_DEALER_HANDGUNCLASS );
break;
case RIFLECLASS:
if ( ItemIsARocketRifle( usItem ) )
if (ItemHasFingerPrintID( usItem ) )
return( ARMS_DEALER_ROCKET_RIFLE );
else
return( ARMS_DEALER_RIFLECLASS );
@@ -1010,15 +1007,15 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem )
{
if ( Item [usItem].alcohol > 0.0f )
return( ARMS_DEALER_ALCOHOL );
else if ( Item [usItem].electronic )
else if (ItemIsElectronic(usItem))
return( ARMS_DEALER_ELECTRONICS );
else if ( Item [usItem].hardware )
else if (ItemIsHardware(usItem))
return( ARMS_DEALER_HARDWARE );
else if ( Item [usItem].medical )
else if (ItemIsMedical(usItem))
return( ARMS_DEALER_MEDICAL );
else if ( Item [usItem].attachment )
else if (ItemIsAttachment(usItem))
return( ARMS_DEALER_ATTACHMENTS );
else if ( Item [usItem].detonator || Item [usItem].remotedetonator || Item [usItem].remotetrigger )
else if (ItemIsDetonator(usItem) || ItemIsRemoteDetonator(usItem) || ItemIsRemoteTrigger(usItem))
return( ARMS_DEALER_DETONATORS );
else
return( ARMS_DEALER_MISC );
@@ -1076,7 +1073,7 @@ UINT32 GetArmsDealerItemTypeFromItemNumber( UINT16 usItem )
return( ARMS_DEALER_AMMO );
break;
case IC_FACE:
if (Item[usItem].electronic )
if (ItemIsElectronic(usItem))
return ARMS_DEALER_ELECTRONICS;
else
return ARMS_DEALER_FACE;
@@ -1278,8 +1275,7 @@ BOOLEAN CanDealerRepairItem( UINT8 ubArmsDealer, UINT16 usItemIndex )
// uiFlags = Item[ usItemIndex ].fFlags;
// can't repair anything that's not repairable!
// if ( !( uiFlags & ITEM_REPAIRABLE ) )
if ( !( Item[ usItemIndex ].repairable ) )
if ( !ItemIsRepairable(usItemIndex) )
{
return(FALSE);
}
@@ -1297,8 +1293,7 @@ BOOLEAN CanDealerRepairItem( UINT8 ubArmsDealer, UINT16 usItemIndex )
case ARMS_DEALER_PERKO:
#endif
// repairs ANYTHING non-electronic
// if ( !( uiFlags & ITEM_ELECTRONIC ) )
if ( !( Item[ usItemIndex ].electronic ) )
if ( !ItemIsElectronic(usItemIndex) )
{
return(TRUE);
}
@@ -1306,8 +1301,7 @@ BOOLEAN CanDealerRepairItem( UINT8 ubArmsDealer, UINT16 usItemIndex )
case ARMS_DEALER_FREDO:
// repairs ONLY electronics
// if ( uiFlags & ITEM_ELECTRONIC )
if ( Item[ usItemIndex ].electronic )
if (ItemIsElectronic(usItemIndex))
{
return(TRUE);
}
@@ -1318,7 +1312,7 @@ BOOLEAN CanDealerRepairItem( UINT8 ubArmsDealer, UINT16 usItemIndex )
// Flugente: if we set this guy to be a repairguy, and this item is NOT electronic, well, we can
if ( armsDealerInfo[ubArmsDealer].ubTypeOfArmsDealer == ARMS_DEALER_REPAIRS )
{
if ( !( Item[ usItemIndex ].electronic ) )
if ( !ItemIsElectronic(usItemIndex) )
return(TRUE);
else
return(FALSE);
@@ -1369,7 +1363,7 @@ UINT8 DetermineDealerItemCondition( UINT8 ubArmsDealer, UINT16 usItemIndex )
// if it's a damagable item, and not a liquid (those are always sold full)
// if ( ( Item[ usItemIndex ].fFlags & ITEM_DAMAGEABLE ) && !ItemContainsLiquid( usItemIndex ) )
if ( ( Item[ usItemIndex ].damageable ) && !ItemContainsLiquid( usItemIndex ) )
if (ItemIsDamageable(usItemIndex) && !ItemContainsLiquid(usItemIndex))
{
// if he ONLY has used items, or 50% of the time if he carries both used & new items
if ( ( armsDealerInfo[ ubArmsDealer ].uiFlags & ARMS_DEALER_ONLY_USED_ITEMS ) ||
@@ -1383,25 +1377,6 @@ UINT8 DetermineDealerItemCondition( UINT8 ubArmsDealer, UINT16 usItemIndex )
return( ubCondition);
}
BOOLEAN ItemContainsLiquid( UINT16 usItemIndex )
{
return Item[usItemIndex].containsliquid;
//switch ( usItemIndex )
//{
// case CANTEEN:
// case BEER:
// case ALCOHOL:
// case JAR_HUMAN_BLOOD:
// case JAR_CREATURE_BLOOD:
// case JAR_QUEEN_CREATURE_BLOOD:
// case JAR_ELIXIR:
// case GAS_CAN:
// return( TRUE );
//}
//return( FALSE );
}
bool ItemIsSpecial(DEALER_SPECIAL_ITEM& item)
{
@@ -1839,7 +1814,7 @@ void MakeObjectOutOfDealerItems( DEALER_SPECIAL_ITEM *pSpclItemInfo, OBJECTTYPE
// they don't have ammo for by selling them to Tony & buying them right back fully loaded! One could repeat this
// ad nauseum (empty the gun between visits) as a (really expensive) way to get unlimited special ammo like rockets.
//CHRISL: If we're working with a SingleShotRocketLauncher, we need ubGunShotsLeft to equal 1
if(Item[pObject->usItem].singleshotrocketlauncher == TRUE)
if(ItemIsSingleShotRocketLauncher(pObject->usItem))
(*pObject)[subObject]->data.gun.ubGunShotsLeft = 1;
else
(*pObject)[subObject]->data.gun.ubGunShotsLeft = 0;
@@ -1863,7 +1838,7 @@ void GiveObjectToArmsDealerForRepair( UINT8 ubArmsDealer, OBJECTTYPE *pObject, U
Assert( CanDealerRepairItem( ubArmsDealer, pObject->usItem ) );
// c) Actually damaged, or a rocket rifle (being reset)
Assert( ( (*pObject)[0]->data.objectStatus < 100 ) || ItemIsARocketRifle( pObject->usItem ) );
Assert( ( (*pObject)[0]->data.objectStatus < 100 ) || ItemHasFingerPrintID( pObject->usItem ) );
/* ARM: Can now repair with removeable attachments still attached...
// d) Already stripped of all *detachable* attachments
@@ -1898,7 +1873,7 @@ void GiveItemToArmsDealerforRepair( UINT8 ubArmsDealer, OBJECTTYPE* pObject, UIN
Assert( DoesDealerDoRepairs( ubArmsDealer ) );
Assert( (*pObject)[0]->data.objectStatus > 0 );
Assert( ( (*pObject)[0]->data.objectStatus < 100 ) || ItemIsARocketRifle( pObject->usItem ) );
Assert( ( (*pObject)[0]->data.objectStatus < 100 ) || ItemHasFingerPrintID( pObject->usItem ) );
// figure out the earliest the repairman will be free to start repairing this item
uiTimeWhenFreeToStartIt = WhenWillRepairmanBeAllDoneRepairing( ubArmsDealer );
@@ -1995,8 +1970,7 @@ UINT32 CalculateSimpleItemRepairTime( UINT8 ubArmsDealer, UINT16 usItemIndex, IN
// repairs on electronic items take twice as long if the guy doesn't have the skill
// for dealers, this means anyone but Fredo the Electronics guy takes twice as long (but doesn't charge double)
// (Mind you, current he's the ONLY one who CAN repair Electronics at all! Oh well.)
// if( ( Item[ usItemIndex ].fFlags & ITEM_ELECTRONIC ) && ( ubArmsDealer != ARMS_DEALER_FREDO ) )
if( ( Item[ usItemIndex ].electronic ) && ( ubArmsDealer != ARMS_DEALER_FREDO ) )
if( ItemIsElectronic(usItemIndex) && ( ubArmsDealer != ARMS_DEALER_FREDO ) )
{
uiTimeToRepair *= 2;
}
@@ -2065,7 +2039,7 @@ UINT32 CalculateSimpleItemRepairCost( UINT8 ubArmsDealer, UINT16 usItemIndex, IN
}
*/
if ( ItemIsARocketRifle( usItemIndex ) )
if (ItemHasFingerPrintID( usItemIndex ) )
{
// resetting imprinting for a rocket rifle costs something extra even if rifle is at 100%
uiRepairCost += 100;
@@ -2167,7 +2141,7 @@ UINT16 CalcValueOfItemToDealer( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN
// the rest of this function applies only to the "general" dealers ( Jake, Keith, and Franz )
// Micky & Gabby specialize in creature parts & such, the others don't buy these at all (exception: jars)
if ( ( !Item[usItemIndex].jar ) &&
if ( ( !ItemIsJar(usItemIndex)) &&
( DoesItemAppearInDealerInventoryList( ARMS_DEALER_MICKY, usItemIndex, TRUE ) ||
DoesItemAppearInDealerInventoryList( ARMS_DEALER_GABBY, usItemIndex, TRUE ) ) )
{
@@ -2214,7 +2188,7 @@ UINT16 CalcValueOfItemToDealer( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN
{
// exception: Gas (Jake's)
// if ( usItemIndex != GAS_CAN )
if ( !Item[usItemIndex].gascan )
if ( !ItemIsGascan(usItemIndex))
{
// they pay only 1/3 of true value!
usValueToThisDealer /= 3;
@@ -2244,11 +2218,6 @@ void GuaranteeMinimumAlcohol( UINT8 ubArmsDealer )
GuaranteeAtLeastXItemsOfIndex( ubArmsDealer, ALCOHOL, ( UINT8 ) ( GetDealersMaxItemAmount( ubArmsDealer, ALCOHOL ) / 3 ) );
}
BOOLEAN ItemIsARocketRifle( INT16 sItemIndex )
{
return( Item[sItemIndex].fingerprintid );
}
BOOLEAN GetArmsDealerShopHours( UINT8 ubArmsDealer, UINT32 *puiOpeningTime, UINT32 *puiClosingTime )
{
SOLDIERTYPE *pSoldier;
+3 -5
View File
@@ -944,8 +944,7 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
}
// items normally not sold at shops are unsuitable
// if ( Item[ usItemIndex ].fFlags & ITEM_NOT_BUYABLE )
if ( Item[ usItemIndex ].notbuyable )
if (ItemIsNotBuyable(usItemIndex))
{
return(ITEM_SUITABILITY_NONE);
}
@@ -971,7 +970,7 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
// case JAR:
// case JAR_ELIXIR:
// case JAR_CREATURE_BLOOD:
if ( Item[usItemIndex].medical || Item[usItemIndex].canteen || Item[usItemIndex].medicalkit || Item[usItemIndex].locksmithkit || Item[usItemIndex].toolkit || Item[usItemIndex].crowbar || Item[usItemIndex].jar )
if (ItemIsMedical(usItemIndex) || ItemIsCanteen(usItemIndex) || ItemIsMedicalKit(usItemIndex) || ItemIsLocksmithKit(usItemIndex) || ItemIsToolkit(usItemIndex) || ItemIsCrowbar(usItemIndex) || ItemIsJar(usItemIndex) )
return(ITEM_SUITABILITY_ALWAYS);
//}
@@ -1455,8 +1454,7 @@ UINT8 GetDealerItemCategoryNumber( UINT16 usItemIndex )
BOOLEAN CanDealerItemBeSoldUsed( UINT16 usItemIndex )
{
// if ( !( Item[ usItemIndex ].fFlags & ITEM_DAMAGEABLE ) )
if ( !( Item[ usItemIndex ].damageable ) )
if ( !ItemIsDamageable(usItemIndex) )
return(FALSE);
// certain items, although they're damagable, shouldn't be sold in a used condition
+10 -6
View File
@@ -460,7 +460,7 @@ void AutoBandage( BOOLEAN fStart )
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pSoldier )
{
// 0verhaul: Make sure the merc is also in the sector before making him stand up!
if ( pSoldier->bActive && pSoldier->bInSector )
if (pSoldier && pSoldier->bActive && pSoldier->bInSector)
{
ActionDone( pSoldier );
if ( pSoldier->bSlotItemTakenFrom != NO_SLOT )
@@ -483,12 +483,16 @@ void AutoBandage( BOOLEAN fStart )
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( ; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++ubLoop)
{
ActionDone( MercPtrs[ ubLoop ] );
// If anyone is still doing aid animation, stop!
if ( MercPtrs[ ubLoop ]->usAnimState == GIVING_AID || MercPtrs[ ubLoop ]->usAnimState == GIVING_AID_PRN )
pSoldier = MercPtrs[ubLoop];
if (pSoldier && pSoldier->bActive && pSoldier->bInSector)
{
MercPtrs[ ubLoop ]->SoldierGotoStationaryStance( );
ActionDone(pSoldier);
// If anyone is still doing aid animation, stop!
if (pSoldier->usAnimState == GIVING_AID || pSoldier->usAnimState == GIVING_AID_PRN)
{
pSoldier->SoldierGotoStationaryStance();
}
}
}
+3 -3
View File
@@ -102,7 +102,7 @@ public:
return (returnHeap);
}
int moveUp(register int index, KEY newKey)
int moveUp(int index, KEY newKey)
{
while (index > 1) {
int current2 = index>>1;//divided by 2
@@ -120,7 +120,7 @@ public:
int moveDown(int index, KEY currentKey)
{
register int current2 = index+index;
int current2 = index+index;
while (current2 < heapCount) {
if (current2+1 < heapCount) {
//choose child to possibly move
@@ -314,7 +314,7 @@ insert:
int findData(const T data) const
{
register int current;
int current;
for (current = heapCount-1; current > 0; --current) {
if (BinaryHeap[current].data == data) {
break;
+1
View File
@@ -93,6 +93,7 @@ set(TacticalSrc
"${CMAKE_CURRENT_SOURCE_DIR}/VehicleMenu.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Weapons.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/World Items.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_AmmoStrings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_AmmoTypes.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/XML_Armour.cpp"
+32 -38
View File
@@ -167,25 +167,14 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
INT8 bCurrentRating;
UINT16 *psStatGainPtr;
BOOLEAN fAffectedByWisdom = TRUE;
INT8 evolution = NORMAL_EVOLUTION;
Assert(pProfile != NULL);
if ( !gGameExternalOptions.bDisableEvolution )
evolution = pProfile->bEvolution;
if ( evolution == NO_EVOLUTION )
return; // No change possible, quit right away
// if this is a Reverse-Evolving merc who attempting to train
if ( ( ubReason == FROM_TRAINING ) && ( evolution == DEVOLVE ) )
return; // he doesn't get any benefit, but isn't penalized either
if (usNumChances == 0)
return;
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel);
usSubpointsPerLevel = SubpointsPerPoint(EXPERAMT, pProfile->bExpLevel);
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile);
usSubpointsPerLevel = SubpointsPerPoint(EXPERAMT, pProfile);
switch (ubStat)
{
@@ -255,7 +244,6 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
return;
}
if (ubReason == FROM_TRAINING)
{
// training always affected by wisdom
@@ -271,7 +259,7 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
// loop once for each chance to improve
for (uiCnt = 0; uiCnt < usNumChances; ++uiCnt)
{
if ( evolution != DEVOLVE) // Evolves!
if (pProfile->fRegresses == FALSE) // Evolves!
{
// if this is improving from a failure, and a successful roll would give us enough to go up a point
if ((ubReason == FROM_FAILURE) && ((*psStatGainPtr + 1) >= usSubpointsPerPoint))
@@ -302,7 +290,7 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
// if there IS a usChance, adjust it for high or low wisdom (50 is avg)
if (usChance > 0 && fAffectedByWisdom)
{
usChance += (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile->bExpLevel)) - 50)) / 100;
usChance += (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile)) - 50)) / 100;
}
// rftr: reduced growth rates at 80+ and 90+ (to make mercs with higher base stats more valuable)
@@ -315,14 +303,6 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
usChance = min(gGameExternalOptions.ubMaxGrowthChanceAt80, usChance);
}
/*
// if the stat is Marksmanship, and the guy is a hopeless shot
if ((ubStat == MARKAMT) && (pProfile->bSpecialTrait == HOPELESS_SHOT))
{
usChance /= 5; // MUCH slower to improve, divide usChance by 5
}
*/
// SANDRO - penalty for primitive people, they get lesser chance to gain point for certain skills
if ( gGameOptions.fNewTraitSystem && (usChance > 10) && (ubStat != EXPERAMT) && (pProfile->bCharacterTrait == CHAR_TRAIT_PRIMITIVE) )
{
@@ -338,14 +318,6 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
}
}
// Buggler: more evolution rate choices
if ( evolution == THREEQUARTER_EVOLUTION)
usChance = max(1, usChance * 0.75);
else if ( evolution == HALF_EVOLUTION)
usChance = max(1, usChance * 0.5);
else if ( evolution == ONEQUARTER_EVOLUTION)
usChance = max(1, usChance * 0.25);
// maximum possible usChance is 99%
if (usChance > 99)
{
@@ -413,7 +385,7 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
// if there IS a usChance, adjust it for high or low wisdom (50 is avg)
if (usChance > 0 && fAffectedByWisdom)
{
usChance -= (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile->bExpLevel)) - 50)) / 100;
usChance -= (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile)) - 50)) / 100;
}
// if there's ANY usChance, minimum usChance is 1% regardless of wisdom
@@ -497,7 +469,7 @@ void ChangeStat( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UINT8 ubSta
UINT16 usSubpointsPerPoint;
INT8 bDamagedStatToRaise = -1; // added by SANDRO
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel );
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile );
// build ptrs to appropriate profiletype stat fields
switch( ubStat )
@@ -923,7 +895,7 @@ void ProcessUpdateStats( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UIN
// set default min & max, subpoints/pt.
bMinStatValue = 1;
bMaxStatValue = MAX_STAT_VALUE;
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel);
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile);
// build ptrs to appropriate profiletype stat fields
switch( ubStat )
@@ -1166,7 +1138,7 @@ UINT32 RoundOffSalary(UINT32 uiSalary)
}
UINT16 SubpointsPerPoint(UINT8 ubStat, INT8 bExpLevel)
UINT16 SubpointsPerPoint(UINT8 ubStat, MERCPROFILESTRUCT* pProfile)
{
UINT16 usSubpointsPerPoint;
@@ -1187,40 +1159,62 @@ UINT16 SubpointsPerPoint(UINT8 ubStat, INT8 bExpLevel)
// Attributes
case HEALTHAMT:
usSubpointsPerPoint = HEALTH_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierLife;
usSubpointsPerPoint = max(usSubpointsPerPoint, HEALTH_SUBPOINTS_TO_IMPROVE/2);
break;
case AGILAMT:
usSubpointsPerPoint = AGILITY_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierAgility;
usSubpointsPerPoint = max(usSubpointsPerPoint, AGILITY_SUBPOINTS_TO_IMPROVE/2);
break;
case DEXTAMT:
usSubpointsPerPoint = DEXTERITY_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierDexterity;
usSubpointsPerPoint = max(usSubpointsPerPoint, DEXTERITY_SUBPOINTS_TO_IMPROVE/2);
break;
case WISDOMAMT:
usSubpointsPerPoint = WISDOM_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierWisdom;
usSubpointsPerPoint = max(usSubpointsPerPoint, WISDOM_SUBPOINTS_TO_IMPROVE/2);
break;
case STRAMT:
usSubpointsPerPoint = STRENGTH_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierStrength;
usSubpointsPerPoint = max(usSubpointsPerPoint, STRENGTH_SUBPOINTS_TO_IMPROVE/2);
break;
// Skills
case MEDICALAMT:
usSubpointsPerPoint = MEDICAL_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierMedical;
usSubpointsPerPoint = max(usSubpointsPerPoint, MEDICAL_SUBPOINTS_TO_IMPROVE/2);
break;
case EXPLODEAMT:
usSubpointsPerPoint = EXPLOSIVES_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierExplosive;
usSubpointsPerPoint = max(usSubpointsPerPoint, EXPLOSIVES_SUBPOINTS_TO_IMPROVE/2);
break;
case MECHANAMT:
usSubpointsPerPoint = MECHANICAL_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierMechanical;
usSubpointsPerPoint = max(usSubpointsPerPoint, MECHANICAL_SUBPOINTS_TO_IMPROVE/2);
break;
case MARKAMT:
usSubpointsPerPoint = MARKSMANSHIP_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierMarksmanship;
usSubpointsPerPoint = max(usSubpointsPerPoint, MARKSMANSHIP_SUBPOINTS_TO_IMPROVE/2);
break;
case LDRAMT:
usSubpointsPerPoint = LEADERSHIP_SUBPOINTS_TO_IMPROVE;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierLeadership;
usSubpointsPerPoint = max(usSubpointsPerPoint, LEADERSHIP_SUBPOINTS_TO_IMPROVE/2);
break;
// Experience
case EXPERAMT:
usSubpointsPerPoint = LEVEL_SUBPOINTS_TO_IMPROVE * bExpLevel;
usSubpointsPerPoint = LEVEL_SUBPOINTS_TO_IMPROVE * pProfile->bExpLevel;
if (gGameExternalOptions.fMercGrowthModifiersEnabled) usSubpointsPerPoint += pProfile->bGrowthModifierExpLevel;
usSubpointsPerPoint = max(usSubpointsPerPoint, LEVEL_SUBPOINTS_TO_IMPROVE * pProfile->bExpLevel / 2);
break;
default:
@@ -1797,7 +1791,7 @@ void TestDumpStatChanges(void)
// print days served
fprintf(FDump, "%3d ", pProfile->usTotalDaysServed);
// print evolution type
fprintf(FDump, "%c ", cEvolutionChars[ pProfile->bEvolution ]);
fprintf(FDump, "%c ", cEvolutionChars[ pProfile->fRegresses ]);
// now print all non-zero stats
for( ubStat = FIRST_CHANGEABLE_STAT; ubStat <= LAST_CHANGEABLE_STAT; ubStat++ )
+2 -2
View File
@@ -73,7 +73,7 @@ void ProcessUpdateStats( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UIN
UINT32 CalcNewSalary(UINT32 uiOldSalary, BOOLEAN fIncrease, UINT32 uiMaxLimit, UINT32 uiIncreaseCap);
UINT32 RoundOffSalary(UINT32 uiSalary);
UINT16 SubpointsPerPoint(UINT8 ubStat, INT8 bExpLevel);
UINT16 SubpointsPerPoint(UINT8 ubStat, MERCPROFILESTRUCT* pProfile);
void HandleUnhiredMercImprovement( MERCPROFILESTRUCT *pProfile );
void HandleUnhiredMercDeaths( INT32 iProfileID );
@@ -92,4 +92,4 @@ void BuildStatChangeString( STR16 wString, STR16 wName, BOOLEAN fIncrease, INT16
void MERCMercWentUpALevelSendEmail( UINT8 ubMercMercIdValue );
#endif
#endif
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -373,7 +373,7 @@ BOOLEAN HasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& ubZ )
void AddCoverObjectsToViewArea()
{
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
BOOLEAN fNightTime = NightTime( );
@@ -406,7 +406,7 @@ void RemoveCoverObjectsFromViewArea()
return;
// Go through the whole gCoverViewArea when removing cover objects. Otherwise we don't clean up tiles that are not in the viewport which results in an annoying visual bug.
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
for ( ubX = 0; ubX < COVER_X_CELLS; ++ubX )
@@ -669,8 +669,8 @@ static void CalculateCoverFromEnemies()
void CalculateCover()
{
register INT32 ubX, ubY;
register INT8 ubZ;
INT32 ubX, ubY;
INT8 ubZ;
SOLDIERTYPE* pSoldier;
if (gusSelectedSoldier == NOBODY)
@@ -1144,7 +1144,7 @@ void AddMinesObjectsToViewArea()
if ( gsMaxCellY < 0 )
return;
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
BOOLEAN fNightTime = NightTime( );
@@ -1274,7 +1274,7 @@ void DetermineMineDisplayInTile( INT32 sGridNo, INT8 bLevel, INT8& bOverlayType,
{
case MINES_DRAW_PLAYERTEAM_NETWORKS:
{
if ( Item[pObj->usItem].tripwire == 1 )
if (ItemIsTripwire(pObj->usItem))
{
// if we're already marked as MINE_BOMB, switch to MINE_BOMB_AND_WIRE
if ( bOverlayType == MINE_BOMB )
@@ -1314,7 +1314,7 @@ void DetermineMineDisplayInTile( INT32 sGridNo, INT8 bLevel, INT8& bOverlayType,
case MINES_DRAW_NETWORKCOLOURING:
{
if ( Item[pObj->usItem].tripwire == 1 )
if (ItemIsTripwire(pObj->usItem))
{
// determine if wire is of the network we're searching for
// determine this tripwire's flag
@@ -1342,7 +1342,7 @@ void DetermineMineDisplayInTile( INT32 sGridNo, INT8 bLevel, INT8& bOverlayType,
case MINES_DRAW_NET_C:
case MINES_DRAW_NET_D:
{
if ( Item[pObj->usItem].tripwire == 1 )
if (ItemIsTripwire(pObj->usItem))
{
UINT32 specificnet = 0;
switch ( gubDrawMode )
@@ -1503,7 +1503,7 @@ void AddTraitObjectsToViewArea()
if ( gsMaxCellY < 0 )
return;
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
BOOLEAN fNightTime = NightTime( );
@@ -1657,7 +1657,7 @@ void AddTrackerObjectsToViewArea( )
if ( gsMaxCellY < 0 )
return;
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
BOOLEAN fNightTime = NightTime();
@@ -1717,10 +1717,10 @@ BOOLEAN TrackerTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32&
void CalculateFortify( )
{
// simply get all fortified gridnos and colour them
std::vector< std::pair<INT16, std::pair<UINT8, INT8> > > vec = GetAllForticationGridNo( );
auto vec = GetAllForticationGridNo();
std::vector< std::pair<INT16, std::pair<UINT8, INT8> > >::iterator itend = vec.end( );
for ( std::vector< std::pair<INT16, std::pair<UINT8, INT8> > >::iterator it = vec.begin( ); it != itend; ++it )
auto itend = vec.end();
for (auto it = vec.begin(); it != itend; ++it)
{
INT16 sX, sY;
ConvertGridNoToXY( (*it).first, &sX, &sY );
@@ -1731,7 +1731,7 @@ void CalculateFortify( )
if ( gsMaxCellY < 0 )
return;
register INT32 ubX, ubY, ubZ;
INT32 ubX, ubY, ubZ;
BOOLEAN fChanged = FALSE;
BOOLEAN fNightTime = NightTime( );
+1 -1
View File
@@ -205,7 +205,7 @@ BOOLEAN ApplyDrugs_New( SOLDIERTYPE *pSoldier, UINT16 usItem, UINT16 uStatusUsed
gMercProfiles[pSoldier->ubProfile].ubNumTimesDrugUseInLifetime++;
}
if ( Item[usItem].cigarette )
if (ItemIsCigarette(usItem))
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_MERC_TOOK_CIGARETTE], pSoldier->GetName( ), ShortItemNames[usItem] );
}
+309 -286
View File
@@ -8,7 +8,6 @@
#include "vsurface.h"
#include "Render Dirty.h"
#include "sysutil.h"
#include "container.h"
#include "wcheck.h"
#include "video.h"
#include "vobject_blitters.h"
@@ -60,7 +59,8 @@ void NewEye( FACETYPE *pFace );
void NewMouth( FACETYPE *pFace );
INT32 GetFreeFace(void);
void RecountFaces(void);
void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY );
UINT32 GetFaceShade(SOLDIERTYPE *pSoldier, FACETYPE *pFace, BOOLEAN fExternBlit);
void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY, UINT32 uiFaceShade);
extern BOOLEAN gfInItemPickupMenu;
@@ -155,6 +155,32 @@ INT32 InitFace( UINT8 usMercProfileID, UINT16 ubSoldierID, UINT32 uiInitFlags )
}
void SetPalettes(HVOBJECT *hVObject, UINT32 uiIndex)
{
SGPPaletteEntry Pal[256];
// Build a grayscale palette! ( for testing different looks )
for (UINT32 uiCount = 0; uiCount < 256; uiCount++)
{
Pal[uiCount].peRed = 255;
Pal[uiCount].peGreen = 255;
Pal[uiCount].peBlue = 255;
}
(*hVObject)->pShades[FLASH_PORTRAIT_NOSHADE] = Create16BPPPaletteShaded((*hVObject)->pPaletteEntry, 255, 255, 255, FALSE);
(*hVObject)->pShades[FLASH_PORTRAIT_STARTSHADE] = Create16BPPPaletteShaded(Pal, 255, 255, 255, FALSE);
(*hVObject)->pShades[FLASH_PORTRAIT_ENDSHADE] = Create16BPPPaletteShaded((*hVObject)->pPaletteEntry, 250, 25, 25, TRUE);
(*hVObject)->pShades[FLASH_PORTRAIT_DARKSHADE] = Create16BPPPaletteShaded((*hVObject)->pPaletteEntry, 100, 100, 100, TRUE);
(*hVObject)->pShades[FLASH_PORTRAIT_LITESHADE] = Create16BPPPaletteShaded((*hVObject)->pPaletteEntry, 100, 100, 100, FALSE);
for (UINT32 uiCount = 0; uiCount < 256; uiCount++)
{
Pal[uiCount].peRed = (UINT8)(uiCount % 128) + 128;
Pal[uiCount].peGreen = (UINT8)(uiCount % 128) + 128;
Pal[uiCount].peBlue = (UINT8)(uiCount % 128) + 128;
}
(*hVObject)->pShades[FLASH_PORTRAIT_GRAYSHADE] = Create16BPPPaletteShaded(Pal, 255, 255, 255, FALSE);
}
INT32 InternalInitFace( UINT8 usMercProfileID, UINT16 ubSoldierID, UINT32 uiInitFlags, INT32 iFaceFileID, UINT32 uiBlinkFrequency, UINT32 uiExpressionFrequency )
{
@@ -165,7 +191,6 @@ INT32 InternalInitFace( UINT8 usMercProfileID, UINT16 ubSoldierID, UINT32 uiInit
ETRLEObject ETRLEObject;
HVOBJECT hVObject;
UINT32 uiCount;
SGPPaletteEntry Pal[256];
if( ( iFaceIndex = GetFreeFace() )==(-1) )
return(-1);
@@ -434,33 +459,11 @@ INT32 InternalInitFace( UINT8 usMercProfileID, UINT16 ubSoldierID, UINT32 uiInit
// Set palette
if( GetVideoObject( &hVObject, uiVideoObject ) )
if (GetVideoObject(&hVObject, uiVideoObject))
{
// Build a grayscale palette! ( for testing different looks )
for(uiCount=0; uiCount < 256; uiCount++)
{
Pal[uiCount].peRed=255;
Pal[uiCount].peGreen=255;
Pal[uiCount].peBlue=255;
}
hVObject->pShades[ FLASH_PORTRAIT_NOSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 255, 255, 255, FALSE );
hVObject->pShades[ FLASH_PORTRAIT_STARTSHADE ] = Create16BPPPaletteShaded( Pal, 255, 255, 255, FALSE );
hVObject->pShades[ FLASH_PORTRAIT_ENDSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 250, 25, 25, TRUE );
hVObject->pShades[ FLASH_PORTRAIT_DARKSHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 100, 100, 100, TRUE );
hVObject->pShades[ FLASH_PORTRAIT_LITESHADE ] = Create16BPPPaletteShaded( hVObject->pPaletteEntry, 100, 100, 100, FALSE );
for(uiCount=0; uiCount < 256; uiCount++)
{
Pal[uiCount].peRed=(UINT8)(uiCount%128)+128;
Pal[uiCount].peGreen=(UINT8)(uiCount%128)+128;
Pal[uiCount].peBlue=(UINT8)(uiCount%128)+128;
}
hVObject->pShades[ FLASH_PORTRAIT_GRAYSHADE ] = Create16BPPPaletteShaded( Pal, 255, 255, 255, FALSE );
SetPalettes(&hVObject, uiVideoObject);
}
// Get FACE height, width
if( GetVideoObjectETRLEPropertiesFromIndex( uiVideoObject, &ETRLEObject, 0 ) == FALSE )
{
@@ -940,9 +943,13 @@ void BlinkAutoFace( INT32 iFaceIndex )
{
pFace = &gFacesData[ iFaceIndex ];
UINT32 uiFaceShade = FLASH_PORTRAIT_NOSHADE;
// CHECK IF BUDDY IS DEAD, UNCONSCIOUS, ASLEEP, OR POW!
if ( pFace->ubSoldierID != NOBODY )
{
uiFaceShade = GetFaceShade(MercPtrs[pFace->ubSoldierID], pFace, FALSE);
if ( ( MercPtrs[ pFace->ubSoldierID ]->stats.bLife < OKLIFE ) ||
( MercPtrs[ pFace->ubSoldierID ]->flags.fMercAsleep == TRUE ) ||
( MercPtrs[ pFace->ubSoldierID ]->bAssignment == ASSIGNMENT_POW ) )
@@ -1041,8 +1048,7 @@ void BlinkAutoFace( INT32 iFaceIndex )
}
HandleRenderFaceAdjustments( pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
HandleRenderFaceAdjustments(pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY, uiFaceShade);
}
}
@@ -1226,7 +1232,15 @@ void MouthAutoFace( INT32 iFaceIndex )
}
HandleRenderFaceAdjustments( pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
UINT32 uiFaceShade = FLASH_PORTRAIT_NOSHADE;
// Set shade
if (pFace->ubSoldierID != NOBODY)
{
uiFaceShade = GetFaceShade(MercPtrs[pFace->ubSoldierID], pFace, FALSE);
}
HandleRenderFaceAdjustments( pFace, TRUE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY, uiFaceShade);
}
}
@@ -1315,32 +1329,38 @@ void HandleTalkingAutoFace( INT32 iFaceIndex )
// Local function - uses these variables because they have already been validated
void SetFaceShade( SOLDIERTYPE *pSoldier, FACETYPE *pFace, BOOLEAN fExternBlit )
void SetFaceShade(FACETYPE *pFace, UINT32 uiFaceShade)
{
// Set to default
SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_NOSHADE );
SetObjectHandleShade(pFace->uiVideoObject, uiFaceShade);
}
if ( pFace->iVideoOverlay == -1 && !fExternBlit )
UINT32 GetFaceShade(SOLDIERTYPE *pSoldier, FACETYPE *pFace, BOOLEAN fExternBlit)
{
if (pFace->iVideoOverlay == -1 && !fExternBlit)
{
if ( ( pSoldier->bActionPoints == 0 ) && !( gTacticalStatus.uiFlags & REALTIME ) && (gTacticalStatus.uiFlags & INCOMBAT ) )
if ((pSoldier->bActionPoints == 0) && !(gTacticalStatus.uiFlags & REALTIME) && (gTacticalStatus.uiFlags & INCOMBAT))
{
SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_LITESHADE );
return FLASH_PORTRAIT_LITESHADE;
}
}
if ( pSoldier->stats.bLife < OKLIFE )
if (pSoldier->stats.bLife < OKLIFE)
{
SetObjectHandleShade( pFace->uiVideoObject, FLASH_PORTRAIT_DARKSHADE );
return FLASH_PORTRAIT_DARKSHADE;
}
// ATE: Don't shade for damage if blitting extern face...
if ( !fExternBlit )
if (!fExternBlit)
{
if ( pSoldier->flags.fFlashPortrait == FLASH_PORTRAIT_START )
if (pSoldier->flags.fFlashPortrait == FLASH_PORTRAIT_START)
{
SetObjectHandleShade( pFace->uiVideoObject, pSoldier->bFlashPortraitFrame );
return pSoldier->bFlashPortraitFrame;
}
}
// Set to default
return FLASH_PORTRAIT_NOSHADE;
}
BOOLEAN RenderAutoFaceFromSoldier( UINT16 ubSoldierID )
@@ -1448,45 +1468,46 @@ void DoRightIcon_legion_GAS_MASK( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16
}
*/
void GetXYForRightIconPlacement_FaceGera( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY, INT8 bNumIcons , UINT32 uIDFaceGear, BOOLEAN isIMP)
void GetXYForRightIconPlacement_FaceGear(FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY, INT8 bNumIcons, UINT32 uiFaceGearIndex, UINT32 uiFaceShade)
{
INT16 sX, sY;
UINT16 usWidth, usHeight;
ETRLEObject *pTrav;
HVOBJECT hVObject;
ETRLEObject *pTrav;
HVOBJECT hVObject = nullptr;
// Get height, width of icon...
if (isIMP)
GetVideoObject( &hVObject, zNewFaceGearIMP[uIDFaceGear].uiIndex );
else
GetVideoObject( &hVObject, zNewFaceGear[uIDFaceGear].uiIndex );
pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
usHeight = pTrav->usHeight;
usWidth = pTrav->usWidth;
if (GetVideoObject(&hVObject, uiFaceGearIndex))
{
SetPalettes(&hVObject, uiFaceGearIndex);
}
sX = sFaceX + ( usWidth * bNumIcons ) + 1;
sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
SetObjectShade(hVObject, uiFaceShade);
pTrav = &(hVObject->pETRLEObject[ubIndex]);
usHeight = pTrav->usHeight;
usWidth = pTrav->usWidth;
sX = sFaceX + (usWidth * bNumIcons);
sY = sFaceY + pFace->usFaceHeight - usHeight;
*psX = sX;
*psY = sY;
}
void DoRightIcon_FaceGear( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sFaceY, INT8 bNumIcons, UINT8 sIconIndex , UINT32 uIDFaceGear, BOOLEAN isIMP)
void DoRightIcon_FaceGear(UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sFaceY, INT8 bNumIcons, UINT8 sIconIndex, UINT32 uIDFaceGear, BOOLEAN isIMP, UINT32 uiFaceShade)
{
INT16 sIconX, sIconY;
INT16 sIconX, sIconY;
// Find X, y for placement
if (isIMP)
{
GetXYForRightIconPlacement_FaceGera( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons , uIDFaceGear,isIMP);
BltVideoObjectFromIndex( uiRenderBuffer, zNewFaceGearIMP[uIDFaceGear].uiIndex, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
GetXYForRightIconPlacement_FaceGear(pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons, zNewFaceGearIMP[uIDFaceGear].uiIndex, uiFaceShade);
BltVideoObjectFromIndex(uiRenderBuffer, zNewFaceGearIMP[uIDFaceGear].uiIndex, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL);
}
else
{
GetXYForRightIconPlacement_FaceGera( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons , uIDFaceGear,isIMP);
BltVideoObjectFromIndex( uiRenderBuffer, zNewFaceGear[uIDFaceGear].uiIndex, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
GetXYForRightIconPlacement_FaceGear(pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons, zNewFaceGear[uIDFaceGear].uiIndex, uiFaceShade);
BltVideoObjectFromIndex(uiRenderBuffer, zNewFaceGear[uIDFaceGear].uiIndex, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL);
}
}
//----------------------------------------------------------------
@@ -1546,7 +1567,7 @@ void DoRightIcon( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sF
}
void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY )
void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLEAN fUseExternBuffer, UINT32 uiBuffer, INT16 sFaceX, INT16 sFaceY, UINT16 usEyesX, UINT16 usEyesY, UINT32 uiFaceShade)
{
INT16 sIconX, sIconY;
INT16 sIconIndex = -1;
@@ -1610,6 +1631,190 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
{
pSoldier = MercPtrs[ pFace->ubSoldierID ];
UINT8 faceProfileId = gMercProfiles[pSoldier->ubProfile].ubFaceIndex;
BOOLEAN isIMP = gMercProfiles[pSoldier->ubProfile].Type == PROFILETYPE_IMP;
if (gGameSettings.fOptions[TOPTION_SHOW_TACTICAL_FACE_GEAR] && MercPtrs[pFace->ubSoldierID]->stats.bLife > 0 && !(pFace->uiFlags & FACE_BIGFACE))
{
if (MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem > 0)
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem;
if (uiFaceItemOne != NONE && zNewFaceGear[uiFaceItemOne].Type == 1) //back
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceItemOne, isIMP, uiFaceShade);
}
}
// this section chooses the pictures for gas mask and NV goggles if the ini setting "SHOW_TACTICAL_FACE_GEAR" is TRUE
// and the merc actually wears something to be shown
if (MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem + MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem > 0)
{
// WANNE: Removed the limitation
// silversurfer: don't overwrite icons if they shall be shown!
//if ( !gGameSettings.fOptions[ SHOW_TACTICAL_FACE_ICONS ] )
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem;
uiFaceItemTwo = MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem;
uiFaceOne = MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem;
uiFaceTwo = MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem;
// check first face slot
if (uiFaceItemOne != NONE)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
uiFaceItemOne = 1;
}
else if (zNewFaceGear[uiFaceOne].Type == 4)
{
uiFaceItemOne = 2;
}
else uiFaceItemOne = 0;
}
// check second face slot
if (uiFaceItemTwo != NONE)
{
if (zNewFaceGear[uiFaceTwo].Type == 3)
{
uiFaceItemTwo = 21;
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
uiFaceItemTwo = 42;
}
else uiFaceItemTwo = 0;
}
// Now select the correct picture. This uses a matrix from uiFaceOneItem and uiFaceTwoItem (simple addition)
// the numbers on the outer border are used if that is the only item worn in that slot
//
// 21 42 63 84
// face slot 1 \ slot 2 gas mask | NV goggles | sun goggles | extended ear
// 1 gas mask -- 43 64 85
// 2 NV goggles 23 -- -- 86
// 3 sun goggles 24 -- -- 87
// 4 extended ear 25 46 67 --
//
// this matrix leaves room for expansion
// we only need a few of the matrix' values this time because we only show gas mask or NV goggles pictures
ubFaceItemsCombined = uiFaceItemOne + uiFaceItemTwo;
}
// WANNE: Removed silversurfers limitation, because it is too complex for the players :)
// silversurfer: we don't want to display icons for gas mask or NV goggles because you can actually see the merc wearing the gear
// in case of gas mask together with NV we display the picture of the item in face slot 1 and the icon of the item
// in face slot 2 (if icons are allowed)
//Type : 3 - gas mask ; 4 - NV googles
// gas mask only
if (ubFaceItemsCombined == 1 || ubFaceItemsCombined == 21)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
// NV goggles only
if (ubFaceItemsCombined == 2 || ubFaceItemsCombined == 42)
{
if (zNewFaceGear[uiFaceOne].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
// NV goggles + gas mask
if (ubFaceItemsCombined == 23)
{
if (zNewFaceGear[uiFaceOne].Type == 4 && zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
}
// gas mask + NV goggles
if (ubFaceItemsCombined == 43)
{
if (zNewFaceGear[uiFaceOne].Type == 3 && zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
// gas mask + extended ear
if (ubFaceItemsCombined == 24 || ubFaceItemsCombined == 64)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
// gas mask + extended ear
if (ubFaceItemsCombined == 25 || ubFaceItemsCombined == 85)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
// NV goggles + extended ear
if (ubFaceItemsCombined == 46 || ubFaceItemsCombined == 86)
{
if (zNewFaceGear[uiFaceOne].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP, uiFaceShade);
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP, uiFaceShade);
}
}
}
if (MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem > 0)
// dirty hack for IMPs because they don't have pictures for face gear
// && ( MercPtrs[ pFace->ubSoldierID ]->ubProfile < 51 || MercPtrs[ pFace->ubSoldierID ]->ubProfile > 56 )
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem;
if (uiFaceItemOne != NONE)
{
if (uiFaceItemOne != NONE && zNewFaceGear[uiFaceItemOne].Type == 2) //front
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceItemOne, isIMP, uiFaceShade);
}
}
}
//------------------------------------end of tactical face gear-----------------------------
}
if ( (MercPtrs[pFace->ubSoldierID]->stats.bLife < CONSCIOUSNESS || MercPtrs[pFace->ubSoldierID]->flags.fDeadPanel ) )
{
// Blit Closed eyes here!
@@ -1705,34 +1910,6 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
// Blit hatch!
BltVideoObjectFromIndex( uiRenderBuffer, guiHATCH, 0, sFaceX, sFaceY, VO_BLT_SRCTRANSPARENCY, NULL );
}
if ( !pFace->fDisabled && !pFace->fInvalidAnim )
{
// Render text above here if that's what was asked for
if ( pFace->fDisplayTextOver != FACE_NO_TEXT_OVER )
{
SetFont( TINYFONT1 );
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_WHITE );
SetFontDestBuffer( uiRenderBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
VarFindFontCenterCoordinates( sFaceX, sFaceY, pFace->usFaceWidth, pFace->usFaceHeight, TINYFONT1, &sFontX, &sFontY, pFace->zDisplayText );
if ( pFace->fDisplayTextOver == FACE_DRAW_TEXT_OVER )
{
gprintfinvalidate( sFontX, sFontY, pFace->zDisplayText );
mprintf( sFontX, sFontY, pFace->zDisplayText );
}
else if ( pFace->fDisplayTextOver == FACE_ERASE_TEXT_OVER )
{
gprintfRestore( sFontX, sFontY, pFace->zDisplayText );
pFace->fDisplayTextOver = FACE_NO_TEXT_OVER;
}
SetFontDestBuffer( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE );
}
}
}
// sevenfm: only show for alive soldiers, no face icons for big faces
@@ -1758,15 +1935,6 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
//------------------------------------Legion 2 by jazz--------------------------------
UINT8 faceProfileId = gMercProfiles[MercPtrs[pFace->ubSoldierID]->ubProfile].ubFaceIndex;
BOOLEAN isIMP = FALSE;
//IMP
if (gMercProfiles[MercPtrs[pFace->ubSoldierID]->ubProfile].Type == PROFILETYPE_IMP)
{
isIMP = TRUE;
}
// rewritten by silversurfer
// this section chooses the icons for face gear if the ini setting "SHOW_TACTICAL_FACE_ICONS" is TRUE
// and the merc actually wears something to be shown
@@ -1780,7 +1948,7 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
// check first face slot
if (uiFaceItemOne != NONE)
{
if (Item[uiFaceItemOne].gasmask)
if (ItemIsGasmask(uiFaceItemOne))
uiFaceItemOne = 1;
else if (Item[uiFaceItemOne].nightvisionrangebonus > 0)
uiFaceItemOne = 2;
@@ -1795,7 +1963,7 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
// check second face slot
if (uiFaceItemTwo != NONE)
{
if (Item[uiFaceItemTwo].gasmask)
if (ItemIsGasmask(uiFaceItemTwo))
uiFaceItemTwo = 21;
else if (Item[uiFaceItemTwo].nightvisionrangebonus > 0)
uiFaceItemTwo = 42;
@@ -1881,187 +2049,6 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
}
}
if (gGameSettings.fOptions[TOPTION_SHOW_TACTICAL_FACE_GEAR])
{
if (MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem > 0)
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem;
if (uiFaceItemOne != NONE && zNewFaceGear[uiFaceItemOne].Type == 1) //back
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceItemOne, isIMP);
}
}
// this section chooses the pictures for gas mask and NV goggles if the ini setting "SHOW_TACTICAL_FACE_GEAR" is TRUE
// and the merc actually wears something to be shown
if (MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem + MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem > 0)
{
// WANNE: Removed the limitation
// silversurfer: don't overwrite icons if they shall be shown!
//if ( !gGameSettings.fOptions[ SHOW_TACTICAL_FACE_ICONS ] )
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem;
uiFaceItemTwo = MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem;
uiFaceOne = MercPtrs[pFace->ubSoldierID]->inv[HEAD1POS].usItem;
uiFaceTwo = MercPtrs[pFace->ubSoldierID]->inv[HEAD2POS].usItem;
// check first face slot
if (uiFaceItemOne != NONE)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
uiFaceItemOne = 1;
}
else if (zNewFaceGear[uiFaceOne].Type == 4)
{
uiFaceItemOne = 2;
}
else uiFaceItemOne = 0;
}
// check second face slot
if (uiFaceItemTwo != NONE)
{
if (zNewFaceGear[uiFaceTwo].Type == 3)
{
uiFaceItemTwo = 21;
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
uiFaceItemTwo = 42;
}
else uiFaceItemTwo = 0;
}
// Now select the correct picture. This uses a matrix from uiFaceOneItem and uiFaceTwoItem (simple addition)
// the numbers on the outer border are used if that is the only item worn in that slot
//
// 21 42 63 84
// face slot 1 \ slot 2 gas mask | NV goggles | sun goggles | extended ear
// 1 gas mask -- 43 64 85
// 2 NV goggles 23 -- -- 86
// 3 sun goggles 24 -- -- 87
// 4 extended ear 25 46 67 --
//
// this matrix leaves room for expansion
// we only need a few of the matrix' values this time because we only show gas mask or NV goggles pictures
ubFaceItemsCombined = uiFaceItemOne + uiFaceItemTwo;
}
// WANNE: Removed silversurfers limitation, because it is too complex for the players :)
// silversurfer: we don't want to display icons for gas mask or NV goggles because you can actually see the merc wearing the gear
// in case of gas mask together with NV we display the picture of the item in face slot 1 and the icon of the item
// in face slot 2 (if icons are allowed)
//Type : 3 - gas mask ; 4 - NV googles
// gas mask only
if (ubFaceItemsCombined == 1 || ubFaceItemsCombined == 21)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
// NV goggles only
if (ubFaceItemsCombined == 2 || ubFaceItemsCombined == 42)
{
if (zNewFaceGear[uiFaceOne].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
// NV goggles + gas mask
if (ubFaceItemsCombined == 23)
{
if (zNewFaceGear[uiFaceOne].Type == 4 && zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
}
// gas mask + NV goggles
if (ubFaceItemsCombined == 43)
{
if (zNewFaceGear[uiFaceOne].Type == 3 && zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
// gas mask + extended ear
if (ubFaceItemsCombined == 24 || ubFaceItemsCombined == 64)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
// gas mask + extended ear
if (ubFaceItemsCombined == 25 || ubFaceItemsCombined == 85)
{
if (zNewFaceGear[uiFaceOne].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
else if (zNewFaceGear[uiFaceTwo].Type == 3)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
// NV goggles + extended ear
if (ubFaceItemsCombined == 46 || ubFaceItemsCombined == 86)
{
if (zNewFaceGear[uiFaceOne].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceOne, isIMP);
}
else if (zNewFaceGear[uiFaceTwo].Type == 4)
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceTwo, isIMP);
}
}
}
if (MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem > 0)
// dirty hack for IMPs because they don't have pictures for face gear
// && ( MercPtrs[ pFace->ubSoldierID ]->ubProfile < 51 || MercPtrs[ pFace->ubSoldierID ]->ubProfile > 56 )
{
uiFaceItemOne = MercPtrs[pFace->ubSoldierID]->inv[HELMETPOS].usItem;
if (uiFaceItemOne != NONE)
{
if (uiFaceItemOne != NONE && zNewFaceGear[uiFaceItemOne].Type == 2) //front
{
DoRightIcon_FaceGear(uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, faceProfileId, uiFaceItemOne, isIMP);
}
}
}
//------------------------------------end of tactical face gear-----------------------------
}
// If blind...
if (MercPtrs[pFace->ubSoldierID]->bBlindedCounter > 0)
{
@@ -2261,7 +2248,7 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
sIconIndex_Assignment = 0;
fDoIcon_Assignment = TRUE;
// Show repair points if merc has a toolkit in his hand. Otherwise show cleaning points.
if (Item[pSoldier->inv[HANDPOS].usItem].toolkit)
if (ItemIsToolkit(pSoldier->inv[HANDPOS].usItem))
sPtsAvailable = CalculateRepairPointsForRepairman(MercPtrs[pFace->ubSoldierID], &usMaximumPts, FALSE);
else
sPtsAvailable = CalculateCleaningPointsForRepairman(MercPtrs[pFace->ubSoldierID], &usMaximumPts);
@@ -2540,6 +2527,37 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
}
}
}
if (!(pFace->uiFlags & FACE_INACTIVE_HANDLED_ELSEWHERE) || fUseExternBuffer)
{
if (!pFace->fDisabled && !pFace->fInvalidAnim)
{
// Render text above here if that's what was asked for
if (pFace->fDisplayTextOver != FACE_NO_TEXT_OVER)
{
SetFont(TINYFONT1);
SetFontBackground(FONT_MCOLOR_BLACK);
SetFontForeground(FONT_MCOLOR_WHITE);
SetFontDestBuffer(uiRenderBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE);
VarFindFontCenterCoordinates(sFaceX, sFaceY, pFace->usFaceWidth, pFace->usFaceHeight, TINYFONT1, &sFontX, &sFontY, pFace->zDisplayText);
if (pFace->fDisplayTextOver == FACE_DRAW_TEXT_OVER)
{
gprintfinvalidate(sFontX, sFontY, pFace->zDisplayText);
mprintf(sFontX, sFontY, pFace->zDisplayText);
}
else if (pFace->fDisplayTextOver == FACE_ERASE_TEXT_OVER)
{
gprintfRestore(sFontX, sFontY, pFace->zDisplayText);
pFace->fDisplayTextOver = FACE_NO_TEXT_OVER;
}
SetFontDestBuffer(FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, FALSE);
}
}
}
}
else
{
@@ -2599,10 +2617,13 @@ BOOLEAN RenderAutoFace( INT32 iFaceIndex )
// Check for disabled guy!
CHECKF( pFace->fDisabled != TRUE );
UINT32 uiFaceShade = FLASH_PORTRAIT_NOSHADE;
// Set shade
if ( pFace->ubSoldierID != NOBODY )
{
SetFaceShade( MercPtrs[ pFace->ubSoldierID ], pFace, FALSE );
uiFaceShade = GetFaceShade(MercPtrs[pFace->ubSoldierID], pFace, FALSE);
SetFaceShade(pFace, uiFaceShade);
}
// Blit face to save buffer!
@@ -2618,7 +2639,7 @@ BOOLEAN RenderAutoFace( INT32 iFaceIndex )
}
}
HandleRenderFaceAdjustments( pFace, FALSE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY );
HandleRenderFaceAdjustments(pFace, FALSE, FALSE, 0, pFace->usFaceX, pFace->usFaceY, pFace->usEyesX, pFace->usEyesY, uiFaceShade);
// Restore extern rect
if ( pFace->uiAutoRestoreBuffer == guiSAVEBUFFER )
@@ -2662,9 +2683,11 @@ BOOLEAN ExternRenderFace( UINT32 uiBuffer, INT32 iFaceIndex, INT16 sX, INT16 sY
// Here, any face can be rendered, even if disabled
// Set shade
UINT32 uiFaceShade = FLASH_PORTRAIT_NOSHADE;
if ( pFace->ubSoldierID != NOBODY )
{
SetFaceShade( MercPtrs[ pFace->ubSoldierID ], pFace , TRUE );
uiFaceShade = GetFaceShade(MercPtrs[pFace->ubSoldierID], pFace, TRUE);
SetFaceShade(pFace, uiFaceShade);
}
// Blit face to save buffer!
@@ -2672,7 +2695,7 @@ BOOLEAN ExternRenderFace( UINT32 uiBuffer, INT32 iFaceIndex, INT16 sX, INT16 sY
GetFaceRelativeCoordinates( pFace, &usEyesX, &usEyesY, &usMouthX, &usMouthY );
HandleRenderFaceAdjustments( pFace, FALSE, TRUE, uiBuffer, sX, sY, ( UINT16)( sX + usEyesX ), ( UINT16)( sY + usEyesY ) );
HandleRenderFaceAdjustments(pFace, FALSE, TRUE, uiBuffer, sX, sY, (UINT16)(sX + usEyesX), ( UINT16)(sY + usEyesY), uiFaceShade);
// Restore extern rect
if ( uiBuffer == guiSAVEBUFFER )
+16 -14
View File
@@ -174,7 +174,7 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, UINT16 usPointsTo
return( FALSE);
// workaround: canteens with 1% status are treated as 'empty'. They cannot be consumed, but refilled
if ( Item[pObject->usItem].canteen == TRUE && (*pObject)[0]->data.objectStatus == 1 )
if (ItemIsCanteen(pObject->usItem) && (*pObject)[0]->data.objectStatus == 1 )
return( FALSE);
// do we eat or drink this stuff?
@@ -364,7 +364,9 @@ void ReduceBPRegenForHunger( SOLDIERTYPE *pSoldier, INT32 *psPoints )
void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier )
{
if ( !pSoldier )
// A merc away on a minievent assignment is ignored since we cannot control their food or water intake.
// Without this they would end up losing stats and/or dying during long event assignments, which would lead to the game crashing when death occurs.
if ( !pSoldier || pSoldier->bAssignment == ASSIGNMENT_MINIEVENT)
return;
// determine our current activity level
@@ -691,7 +693,7 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
// if fcanteensonly is TRUE, omit everything that is not a canteen
if ( fcanteensonly )
{
if ( Item[pObj->usItem].canteen == FALSE )
if ( !ItemIsCanteen(pObj->usItem))
continue;
}
else
@@ -705,7 +707,7 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
if ( foodcondition < FOOD_BAD_THRESHOLD )
continue;
if ( Item[pObj->usItem].canteen == TRUE )
if (ItemIsCanteen(pObj->usItem))
continue;
}
@@ -739,7 +741,7 @@ void EatFromInventory( SOLDIERTYPE *pSoldier, BOOLEAN fcanteensonly )
// if fcanteensonly is TRUE, omit everything that is not a canteen
if ( fcanteensonly )
{
if ( Item[pObj->usItem].canteen == FALSE )
if (!ItemIsCanteen(pObj->usItem))
continue;
}
@@ -844,7 +846,7 @@ void SectorFillCanteens( void )
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen (that can have drink points) ...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].canteen && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
if (pSoldier->inv[bLoop].exists() == true && ItemIsCanteen(pSoldier->inv[bLoop].usItem) && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
{
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -876,7 +878,7 @@ void SectorFillCanteens( void )
if( gWorldItems[ uiCount ].fExists ) // ... if item exists ...
{
// ... if Item exists and is a canteen (only those are refillable) ...
if ( Item[gWorldItems[ uiCount ].object.usItem].canteen && Food[Item[gWorldItems[ uiCount ].object.usItem].foodtype].bDrinkPoints > 0)
if (ItemIsCanteen(gWorldItems[ uiCount ].object.usItem) && Food[Item[gWorldItems[ uiCount ].object.usItem].foodtype].bDrinkPoints > 0)
{
OBJECTTYPE* pObj = &(gWorldItems[ uiCount ].object); // ... get pointer for this item ...
@@ -918,7 +920,7 @@ void SectorFillCanteens( void )
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen and is NOT a water drum...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].canteen && (Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0) && !HasItemFlag(pSoldier->inv[bLoop].usItem, (WATER_DRUM)))
if (pSoldier->inv[bLoop].exists() == true && ItemIsCanteen(pSoldier->inv[bLoop].usItem) && (Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0) && !HasItemFlag(pSoldier->inv[bLoop].usItem, (WATER_DRUM)))
{
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -971,7 +973,7 @@ void SectorFillCanteens( void )
if( gWorldItems[ uiCount ].fExists ) // ... if item exists ...
{
// ... if Item exists and is a canteen (only those are refillable) ...
if ( Item[gWorldItems[ uiCount ].object.usItem].canteen )
if (ItemIsCanteen(gWorldItems[ uiCount ].object.usItem))
{
OBJECTTYPE* pObj = &(gWorldItems[ uiCount ].object); // ... get pointer for this item ...
@@ -1029,7 +1031,7 @@ OBJECTTYPE* GetUsableWaterDrumInSector( void )
if( gWorldItems[ uiCount ].fExists ) // ... if item exists ...
{
// ... if Item exists and is a canteen (only those are refillable) ...
if ( Item[gWorldItems[ uiCount ].object.usItem].canteen )
if (ItemIsCanteen(gWorldItems[ uiCount ].object.usItem))
{
OBJECTTYPE* pObj = &(gWorldItems[ uiCount ].object); // ... get pointer for this item ...
@@ -1075,7 +1077,7 @@ void SoldierAutoFillCanteens(SOLDIERTYPE *pSoldier)
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen (that can have drink points) ...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].canteen && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
if (pSoldier->inv[bLoop].exists() == true && ItemIsCanteen(pSoldier->inv[bLoop].usItem) && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
{
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -1116,7 +1118,7 @@ BOOLEAN HasFoodInInventory( SOLDIERTYPE *pSoldier, BOOLEAN fCheckFood, BOOLEAN f
if ( fCheckDrink && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints )
{
if ( Item[pSoldier->inv[bLoop].usItem].canteen )
if (ItemIsCanteen(pSoldier->inv[bLoop].usItem))
{
// empty canteens retain 1% status, so check ether something is in them
if ( pSoldier->inv[bLoop][0]->data.objectStatus > 1 )
@@ -1168,7 +1170,7 @@ void DrinkFromWaterTap( SOLDIERTYPE* pSoldier )
for (INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ...
{
// ... if Item exists and is canteen (that can have drink points) ...
if (pSoldier->inv[bLoop].exists() == true && Item[pSoldier->inv[bLoop].usItem].canteen && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
if (pSoldier->inv[bLoop].exists() == true && ItemIsCanteen(pSoldier->inv[bLoop].usItem) && Food[Item[pSoldier->inv[bLoop].usItem].foodtype].bDrinkPoints > 0)
{
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]); // ... get pointer for this item ...
@@ -1195,4 +1197,4 @@ void DrinkFromWaterTap( SOLDIERTYPE* pSoldier )
}
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szInteractiveActionText[8], pSoldier->GetName( ) );
}
}
+47 -41
View File
@@ -279,7 +279,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
{
pTargetSoldier = MercPtrs[ usSoldierIndex ];
if ( fFromUI )
// anv: don't try to heal interactive spots
if (fFromUI && Item[usHandItem].usItemClass != IC_MEDKIT)
{
INT32 sInteractiveGridNo;
@@ -318,13 +319,20 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
pSoldier->ubProfile != NO_PROFILE &&
pTargetSoldier &&
Item[usHandItem].usItemClass != IC_MEDKIT &&
!Item[usHandItem].gascan &&
!ItemIsGascan(usHandItem) &&
!ItemCanBeAppliedToOthers(usHandItem) &&
!HasItemFlag(usHandItem, EMPTY_BLOOD_BAG) &&
!HasItemFlag( usHandItem, MEDICAL_SPLINT ) )
{
if (pTargetSoldier->bTeam == gbPlayerNum || pTargetSoldier->aiData.bNeutral)
{
// anv: don't try to attack yourself, it will only cause deadlock
if (pSoldier == pTargetSoldier)
{
TacticalCharacterDialogue(pSoldier, QUOTE_REFUSING_ORDER);
return(ITEM_HANDLE_REFUSAL);
}
// nice mercs won't shoot other nice guys or neutral civilians
if ((gMercProfiles[pSoldier->ubProfile].ubMiscFlags3 & PROFILE_MISC_FLAG3_GOODGUY) &&
((pTargetSoldier->ubProfile == NO_PROFILE && pTargetSoldier->aiData.bNeutral && pTargetSoldier->ubBodyType != CROW) ||
@@ -465,8 +473,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
if ( Item[ usHandItem ].usItemClass == IC_GUN || Item[ usHandItem ].usItemClass == IC_THROWING_KNIFE )
{
// WEAPONS
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleItem: checking for fingerprintID, item id = %d,id required = %d, imprint id = %d, soldier id = %d",usHandItem,Item[usHandItem].fingerprintid,pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.ubImprintID,pSoldier->ubProfile));
if ( Item[usHandItem].fingerprintid )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleItem: checking for fingerprintID, item id = %d,id required = %d, imprint id = %d, soldier id = %d",usHandItem, ItemHasFingerPrintID(usHandItem), pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.ubImprintID,pSoldier->ubProfile));
if (ItemHasFingerPrintID(usHandItem))
{
// check imprint ID
// NB not-imprinted value is NO_PROFILE
@@ -799,7 +807,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
// ATE: Here to make cursor go back to move after LAW shot...
if ( fFromUI && Item[usHandItem].singleshotrocketlauncher)
if ( fFromUI && ItemIsSingleShotRocketLauncher(usHandItem) )
{
guiPendingOverrideEvent = A_CHANGE_TO_MOVE;
}
@@ -961,7 +969,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
BOOLEAN fCorpse = FALSE;
if(pCorpse != NULL)
fCorpse = IsValidDecapitationCorpse( pCorpse );
if ( Item[usHandItem].wirecutters && pTargetSoldier == NULL && !pCorpse ) // Madd: quick fix to allow wirecutter/knives
if (ItemIsWirecutters(usHandItem) && pTargetSoldier == NULL && !pCorpse ) // Madd: quick fix to allow wirecutter/knives
{
// See if we can get there to stab
sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
@@ -1017,7 +1025,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
}
if ( Item[usHandItem].toolkit )
if (ItemIsToolkit(usHandItem))
{
UINT16 ubMercID;
BOOLEAN fVehicle = FALSE;
@@ -1090,7 +1098,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
}
if ( Item[usHandItem].gascan )
if (ItemIsGascan(usHandItem))
{
UINT16 ubMercID;
INT32 sVehicleGridNo=-1;
@@ -1162,7 +1170,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
if ( Item[usHandItem].jar )
if (ItemIsJar(usHandItem))
{
sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE );
@@ -1606,7 +1614,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
}
}
if ( Item[usHandItem].canandstring )
if (ItemIsCanAndString(usHandItem))
{
STRUCTURE *pStructure;
LEVELNODE *pIntTile;
@@ -1678,7 +1686,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
{
DeductPoints( pSoldier, sAPCost, 0 );
if ( Item[usHandItem].xray )
if (ItemHasXRay(usHandItem))
{
PlayJA2Sample( USE_X_RAY_MACHINE, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
@@ -1859,7 +1867,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
sAPCost = MinAPsToAttack( pSoldier, sTargetGridNo, TRUE, pSoldier->aiData.bAimTime, 0 );
// Check if these is room to place mortar!
if ( Item[usHandItem].mortar )
if (ItemIsMortar(usHandItem))
{
ubDirection = (UINT8)GetDirectionFromGridNo( sTargetGridNo, pSoldier );
@@ -1873,7 +1881,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
//pSoldier->flags.fDontChargeAPsForStanceChange = TRUE;//dnl ch72 270913 no reason why not charge for stance change
}
else if ( Item[usHandItem].grenadelauncher )//usHandItem == GLAUNCHER || usHandItem == UNDER_GLAUNCHER )
else if (ItemIsGrenadeLauncher(usHandItem))//usHandItem == GLAUNCHER || usHandItem == UNDER_GLAUNCHER )
{
GetAPChargeForShootOrStabWRTGunRaises( pSoldier, sTargetGridNo, TRUE, &fAddingTurningCost, &fAddingRaiseGunCost, pSoldier->aiData.bAimTime );
usTurningCost = CalculateTurningCost(pSoldier, usHandItem, fAddingTurningCost);
@@ -1952,7 +1960,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
if ( Item[ usHandItem ].ubCursor == INVALIDCURS )
{
// Found detonator...
if ( HasAttachmentOfClass( &(pSoldier->inv[pSoldier->ubAttackingHand]), (AC_DETONATOR | AC_REMOTEDET | AC_DEFUSE) ) || Item[usHandItem].tripwire )
if ( HasAttachmentOfClass( &(pSoldier->inv[pSoldier->ubAttackingHand]), (AC_DETONATOR | AC_REMOTEDET | AC_DEFUSE) ) || ItemIsTripwire(usHandItem))
{
StartBombMessageBox( pSoldier, sGridNo );
@@ -1972,7 +1980,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
{
// Does this have detonator that needs info?
if ( HasAttachmentOfClass( &(pSoldier->inv[ HANDPOS ] ), (AC_DETONATOR | AC_REMOTEDET | AC_DEFUSE) ) || Item[ (&(pSoldier->inv[ HANDPOS ] ))->usItem ].tripwire == 1)
if ( HasAttachmentOfClass( &(pSoldier->inv[ HANDPOS ] ), (AC_DETONATOR | AC_REMOTEDET | AC_DEFUSE) ) || ItemIsTripwire((&(pSoldier->inv[ HANDPOS ] ))->usItem) )
{
StartBombMessageBox( pSoldier, sGridNo );
}
@@ -1995,7 +2003,7 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
if ( iResult >= 0 )
{
// Less explosives gain for placing tripwire
if ( Item[ pSoldier->inv[ HANDPOS ].usItem ].tripwire )
if (ItemIsTripwire(pSoldier->inv[ HANDPOS ].usItem))
StatChange( pSoldier, EXPLODEAMT, 1, FALSE );
else if ( HasItemFlag( (pSoldier->inv[HANDPOS]).usItem, BEARTRAP ) )
StatChange( pSoldier, MECHANAMT, 10, FALSE );
@@ -2019,7 +2027,7 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
pSoldier->inv[ HANDPOS ][0]->data.bTrap++;
// anv: additional tile properties - modify trap level depending on its placement
if(gGameExternalOptions.fAdditionalTileProperties && Item[ pSoldier->inv[ HANDPOS ].usItem ].tripwire != 1 )
if(gGameExternalOptions.fAdditionalTileProperties && !ItemIsTripwire(pSoldier->inv[ HANDPOS ].usItem))
{
ADDITIONAL_TILE_PROPERTIES_VALUES zAllTileValues = GetAllAdditonalTilePropertiesForGrid( sGridNo, pSoldier->pathing.bLevel );
pSoldier->inv[ HANDPOS ][0]->data.bTrap += zAllTileValues.bTrapBonus;
@@ -2064,7 +2072,7 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
StatChange( pSoldier, EXPLODEAMT, 10, FROM_FAILURE );
// oops! How badly did we screw up?
if ( iResult < -20 && Item[ pSoldier->inv[ HANDPOS ].usItem ].tripwire != 1 )
if ( iResult < -20 && !ItemIsTripwire(pSoldier->inv[ HANDPOS ].usItem) )
{
// OOPS! ... BOOM!
IgniteExplosion( NOBODY, pSoldier->sX, pSoldier->sY, (INT16) (gpWorldLevelData[pSoldier->sGridNo].sHeight), pSoldier->sGridNo, pSoldier->inv[ HANDPOS ].usItem, pSoldier->pathing.bLevel, pSoldier->ubDirection, &pSoldier->inv[ HANDPOS ] );
@@ -2179,7 +2187,7 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT32 sGridNo )
pSoldier->usPendingAnimation = LOB_ITEM;
}
// Draw item depending on distance from buddy
else if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE )
else if (PythSpacesAway( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE )
{
//ddd maybe need to add check for throwing item class - grenade
if( (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) &&
@@ -2568,7 +2576,7 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
if ( ItemExistsAtLocation( sGridNo, iItemIndex, pSoldier->pathing.bLevel ) )
{
// Flugente: if item is tripwireactivated and is a planted bomb, call the defuse dialogue. We obviously know about the items' existence already...
if ( gWorldItems[ iItemIndex ].object.exists() && gWorldItems[ iItemIndex ].object.fFlags & OBJECT_ARMED_BOMB && Item[gWorldItems[ iItemIndex ].object.usItem].tripwireactivation == 1 )
if ( gWorldItems[ iItemIndex ].object.exists() && gWorldItems[ iItemIndex ].object.fFlags & OBJECT_ARMED_BOMB && ItemHasTripwireActivation(gWorldItems[ iItemIndex ].object.usItem) )
{
gpBoobyTrapItemPool = GetItemPoolForIndex( sGridNo, iItemIndex, pSoldier->pathing.bLevel );
gpBoobyTrapSoldier = pSoldier;
@@ -2990,8 +2998,7 @@ OBJECTTYPE* InternalAddItemToPool( INT32 *psGridNo, OBJECTTYPE *pObject, INT8 bV
if ( TERRAIN_IS_WATER( bTerrainID) )
{
// if ( Item[ pObject->usItem ].fFlags & ITEM_SINKS )
if ( Item[ pObject->usItem ].sinks )
if (ItemSinks(pObject->usItem))
{
return( NULL );
}
@@ -3332,7 +3339,7 @@ BOOLEAN MarblesExistAtLocation( INT32 sGridNo, UINT8 ubLevel, INT32 * piItemInde
pItemPoolTemp = pItemPool;
while( pItemPoolTemp != NULL )
{
if ( Item[gWorldItems[ pItemPoolTemp->iItemIndex ].object.usItem].marbles )
if (ItemIsMarbles(gWorldItems[ pItemPoolTemp->iItemIndex ].object.usItem))
{
if ( piItemIndex )
{
@@ -5146,7 +5153,7 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo )
gpTempSoldier = pSoldier;
gsTempGridNo = sGridNo;
if (Item[ pSoldier->inv[HANDPOS].usItem].remotetrigger )
if (ItemIsRemoteTrigger(pSoldier->inv[HANDPOS].usItem))
{
wcscpy( gzUserDefinedButton[0], L"1" );
wcscpy( gzUserDefinedButton[1], L"2" );
@@ -5241,7 +5248,7 @@ void StartBombMessageBox( SOLDIERTYPE * pSoldier, INT32 sGridNo )
{
DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, TacticalStr[ CHOOSE_REMOTE_FREQUENCY_STR ], GAME_SCREEN, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS, BombMessageBoxCallBack, NULL );
}
else if ( Item[ (&(pSoldier->inv[HANDPOS]))->usItem ].tripwire == 1 )
else if (ItemIsTripwire((&(pSoldier->inv[HANDPOS]))->usItem))
{
wcscpy( gzUserDefinedButton[0], L"1-A" );
wcscpy( gzUserDefinedButton[1], L"1-B" );
@@ -5565,10 +5572,10 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
if (gpTempSoldier)
{
// sevenfm: remember last tripwire network settings
if(Item[ gpTempSoldier->inv[HANDPOS].usItem ].tripwire )
if(ItemIsTripwire(gpTempSoldier->inv[HANDPOS].usItem))
gubLastTripwire = ubExitValue;
if (Item[ gpTempSoldier->inv[HANDPOS].usItem ].remotetrigger )
if (ItemIsRemoteTrigger(gpTempSoldier->inv[HANDPOS].usItem))
{
// Flugente: jamming can prevent bomb activation
if ( !gSkillTraitValues.fVOJammingBlocksRemoteBombs || !SectorJammed() )
@@ -5594,7 +5601,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
if ( iResult >= 0 )
{
// Less explosives gain for placing tripwire
if ( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].tripwire == 1 )
if (ItemIsTripwire(gpTempSoldier->inv[ HANDPOS ].usItem))
StatChange( gpTempSoldier, EXPLODEAMT, 5, FALSE );
else if ( HasItemFlag( (gpTempSoldier->inv[HANDPOS]).usItem, BEARTRAP ) )
StatChange( gpTempSoldier, MECHANAMT, 10, FALSE );
@@ -5635,7 +5642,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
else
{
// we can't blow up tripwire, no matter how bad we fail
if ( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].tripwire != 1 )
if ( !ItemIsTripwire(gpTempSoldier->inv[ HANDPOS ].usItem))
{
// OOPS! ... BOOM!
IgniteExplosion( NOBODY, gpTempSoldier->sX, gpTempSoldier->sY, (INT16) (gpWorldLevelData[gpTempSoldier->sGridNo].sHeight), gpTempSoldier->sGridNo, gpTempSoldier->inv[ HANDPOS ].usItem, gpTempSoldier->pathing.bLevel, gpTempSoldier->ubDirection, &gpTempSoldier->inv[ HANDPOS ] );
@@ -5691,7 +5698,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
gTempObject[0]->data.ubDirection = gpTempSoldier->ubDirection; // Flugente: direction of bomb is direction of soldier
// Flugente: tripwire was called through a messagebox, but has to be buried nevertheless
if ( Item[ (&gTempObject)->usItem ].tripwire == 1 )
if (ItemIsTripwire((&gTempObject)->usItem))
{
AddItemToPool( gsTempGridNo, &gTempObject, BURIED, gpTempSoldier->pathing.bLevel, WORLD_ITEM_ARMED_BOMB, 0 );
// sevenfm: set flag only if planting tripwire
@@ -5831,7 +5838,7 @@ BOOLEAN HandItemWorks( SOLDIERTYPE *pSoldier, INT8 bSlot )
// shape to be usable, and doesn't break during use.
// Exception: land mines. You can bury them broken, they just won't blow!
// if ( (Item[ pObj->usItem ].fFlags & ITEM_DAMAGEABLE) && (pObj->usItem != MINE) && (Item[ pObj->usItem ].usItemClass != IC_MEDKIT) && pObj->usItem != GAS_CAN )
if ( Item[pObj->usItem].damageable && !Item[pObj->usItem].mine && (Item[pObj->usItem].usItemClass != IC_MEDKIT) && !Item[pObj->usItem].gascan && !IsStructureConstructItem( pObj->usItem, pSoldier->sGridNo, NULL ) )
if (ItemIsDamageable(pObj->usItem) && !ItemIsMine(pObj->usItem) && (Item[pObj->usItem].usItemClass != IC_MEDKIT) && !ItemIsGascan(pObj->usItem) && !IsStructureConstructItem( pObj->usItem, pSoldier->sGridNo, NULL ) )
{
// if it's still usable, check whether it breaks
if ( (*pObj)[0]->data.objectStatus >= USABLE)
@@ -5911,8 +5918,7 @@ void SetOffBoobyTrap( ITEM_POOL * pItemPool )
if ( pItemPool )
{
INT16 sX, sY;
sX = CenterX( pItemPool->sGridNo );
sY = CenterY( pItemPool->sGridNo );
ConvertGridNoToCenterCellXY(pItemPool->sGridNo, &sX, &sY);
IgniteExplosion( NOBODY, sX, sY, (INT16) (gpWorldLevelData[pItemPool->sGridNo].sHeight + pItemPool->bRenderZHeightAboveLevel), pItemPool->sGridNo, MINI_GRENADE, 0 );
RemoveItemFromPool( pItemPool->sGridNo, pItemPool->iItemIndex, pItemPool->ubLevel );
}
@@ -6096,7 +6102,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
CreateItem(gTempObject[0]->data.misc.usBombItem, gTempObject[0]->data.misc.bBombStatus, &TempObject);
// also spawn attached guns/explosives
if (gTempObject.usItem != ACTION_ITEM && (Item[gTempObject.usItem].tripwire || Item[gTempObject.usItem].usItemClass & IC_EXPLOSV))
if (gTempObject.usItem != ACTION_ITEM && (ItemIsTripwire(gTempObject.usItem) || Item[gTempObject.usItem].usItemClass & IC_EXPLOSV))
{
// search for attached items
OBJECTTYPE* pAttItem = NULL;
@@ -6983,7 +6989,7 @@ INT32 FindNearestAvailableGridNoForItem( INT32 sSweetGridNo, INT8 ubRadius )
BOOLEAN CanPlayerUseRocketRifle( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay )
{
if ( Item[pSoldier->inv[ pSoldier->ubAttackingHand ].usItem].fingerprintid )
if (ItemHasFingerPrintID(pSoldier->inv[ pSoldier->ubAttackingHand ].usItem))
{
// check imprint ID
// NB not-imprinted value is NO_PROFILE
@@ -7035,7 +7041,7 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet
fStealItem = FALSE;
pObject=&pOpponent->inv[i];
if ((pObject->exists() == true) && !(Item[pObject->usItem].defaultundroppable )) // CHECK! Undroppable items cannot be stolen - SANDRO
if ((pObject->exists() == true) && !ItemIsUndroppableByDefault(pObject->usItem)) // CHECK! Undroppable items cannot be stolen - SANDRO
{
// Is the enemy collapsed
if ( pOpponent->stats.bLife < OKLIFE || pOpponent->bCollapsed )
@@ -8158,7 +8164,7 @@ void CorrectDragStructData( INT32 sGridNo, INT8 sLevel, UINT8 ausHitpoints, UINT
if ( pStruct->ubHitPoints < pStruct->pDBStructureRef->pDBStructure->ubHitPoints
|| pStruct->ubDecalFlag & STRUCTURE_DECALFLAG_BLOOD )
{
gpWorldLevelData[sGridNo].uiFlags & MAPELEMENT_STRUCTURE_DAMAGED;
gpWorldLevelData[sGridNo].uiFlags |= MAPELEMENT_STRUCTURE_DAMAGED;
//SetRenderFlags( RENDER_FLAG_FULL );
}
@@ -8706,9 +8712,9 @@ void AddFortificationPlanNode( INT32 sGridNo, INT8 sLevel, INT16 sFortificationS
UpdateFortificationPossibleAmount();
}
std::vector< std::pair<INT16, std::pair<UINT8, INT8> > > GetAllForticationGridNo( )
GetAllForticationGridNoResult GetAllForticationGridNo()
{
std::vector< std::pair<INT16, std::pair<UINT8, INT8> > > gridnovector;
GetAllForticationGridNoResult gridnovector;
if ( !gWorldSectorX || !gWorldSectorY )
return gridnovector;
@@ -9848,7 +9854,7 @@ void ReadEquipmentTable( SOLDIERTYPE* pSoldier, std::string name )
}
}
// if we want to equip a two-handed item in our first hand, also drop whatever we have in the second hand
else if ( node.slot == HANDPOS && Item[node.item].twohanded && pSoldier->inv[SECONDHANDPOS].exists( ) )
else if ( node.slot == HANDPOS && ItemIsTwoHanded(node.item) && pSoldier->inv[SECONDHANDPOS].exists( ) )
{
AutoPlaceObjectInInventoryStash( &pSoldier->inv[SECONDHANDPOS], pSoldier->sGridNo, pSoldier->pathing.bLevel );
DeleteObj( &pSoldier->inv[SECONDHANDPOS] );
@@ -10261,7 +10267,7 @@ void ReadEquipmentTable( SOLDIERTYPE* pSoldier, std::string name )
}
// if there is water in this sector, refill canteens
if ( refillwaterfromsector && Item[(pSoldier->inv[slot]).usItem].canteen && Food[Item[(pSoldier->inv[slot]).usItem].foodtype].bDrinkPoints > 0 )
if ( refillwaterfromsector && ItemIsCanteen(pSoldier->inv[slot].usItem) && Food[Item[(pSoldier->inv[slot]).usItem].foodtype].bDrinkPoints > 0 )
{
OBJECTTYPE* pObj = &(pSoldier->inv[slot]);
+3 -2
View File
@@ -320,7 +320,8 @@ void AddFortificationPlanNode( INT32 sGridNo, INT8 sLevel, INT16 sFortificationS
void LoadSectorFortificationPlan( INT16 sSectorX, INT16 sSectorY, INT8 sSectorZ );
void SaveSectorFortificationPlan( INT16 sSectorX, INT16 sSectorY, INT8 sSectorZ );
std::vector< std::pair<INT16, std::pair<UINT8, INT8> > > GetAllForticationGridNo( );
using GetAllForticationGridNoResult = std::vector< std::pair<INT32, std::pair<UINT8, INT8> > >;
GetAllForticationGridNoResult GetAllForticationGridNo();
INT32 GetFirstObjectInSectorPosition( UINT16 ausItem );
@@ -334,4 +335,4 @@ BOOLEAN SpendMoney( SOLDIERTYPE *pSoldier, UINT32 aAmount ); // character spen
// Flugente: intel
void TakePhoto( SOLDIERTYPE* pSoldier, INT32 sGridNo, INT8 bLevel );
#endif
#endif
+12 -11
View File
@@ -2988,11 +2988,12 @@ UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent )
if ( pTSoldier != NULL )
{
// If this is one of our own guys.....pop up requiester...
UINT16 usItem = pSoldier->inv[HANDPOS].usItem;
if ( ( pTSoldier->bTeam == gbPlayerNum || pTSoldier->bTeam == MILITIA_TEAM )
&& Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass != IC_MEDKIT
&& !Item[pSoldier->inv[ HANDPOS ].usItem].gascan
&& !Item[pSoldier->inv[HANDPOS].usItem].toolkit
&& !ItemCanBeAppliedToOthers( pSoldier->inv[ HANDPOS ].usItem )
&& Item[ usItem ].usItemClass != IC_MEDKIT
&& !ItemIsGascan(usItem)
&& !ItemIsToolkit(usItem)
&& !ItemCanBeAppliedToOthers( usItem )
&& gTacticalStatus.ubLastRequesterTargetID != pTSoldier->ubProfile
&& ( pTSoldier->ubID != pSoldier->ubID ) )
{
@@ -3010,7 +3011,7 @@ UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent )
}
////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Should we ask if we really want to do the surgery?
else if (Item[ pSoldier->inv[ HANDPOS ].usItem ].medicalkit && (NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery)
else if (ItemIsMedicalKit(usItem) && (NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery)
&& (pTSoldier->bTeam == OUR_TEAM || pTSoldier->bTeam == MILITIA_TEAM)
&& (IS_MERC_BODY_TYPE( pTSoldier ) || IS_CIV_BODY_TYPE( pTSoldier ))
&& gGameOptions.fNewTraitSystem && pTSoldier->iHealableInjury >= 100
@@ -3894,7 +3895,7 @@ void UIHandleSoldierStanceChange( UINT16 ubSoldierID, INT8 bNewStance )
gGameExternalOptions.ubAllowAlternativeWeaponHolding &&
pSoldier->inv[HANDPOS].exists() &&
Weapon[pSoldier->inv[HANDPOS].usItem].HeavyGun &&
Item[pSoldier->inv[HANDPOS].usItem].twohanded &&
ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) &&
bNewStance == ANIM_STAND)
{
ChangeScopeMode(pSoldier, NOWHERE);
@@ -3937,7 +3938,7 @@ void UIHandleSoldierStanceChange( UINT16 ubSoldierID, INT8 bNewStance )
gGameExternalOptions.ubAllowAlternativeWeaponHolding &&
pSoldier->inv[HANDPOS].exists() &&
Weapon[pSoldier->inv[HANDPOS].usItem].HeavyGun &&
Item[pSoldier->inv[HANDPOS].usItem].twohanded &&
ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) &&
bNewStance == ANIM_STAND)
{
ChangeScopeMode(pSoldier, NOWHERE);
@@ -4628,7 +4629,7 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
}
else if ( uiFlags == MOVEUI_TARGET_BOMB )
{
if(Item[pSoldier->inv[HANDPOS].usItem].mine == 1)
if(ItemIsMine(pSoldier->inv[HANDPOS].usItem))
sAPCost += GetAPsToPlantMine( pSoldier );
else
sAPCost += GetAPsToDropBomb( pSoldier );
@@ -5014,7 +5015,7 @@ BOOLEAN UIMouseOnValidAttackLocation( SOLDIERTYPE *pSoldier )
}
// SANDRO - doctor with medical bag trying to do the surgery
if ((NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery) && Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit && gGameOptions.fNewTraitSystem
if ((NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery) && ItemIsMedicalKit(pSoldier->inv[ HANDPOS ].usItem) && gGameOptions.fNewTraitSystem
&& (pTSoldier->stats.bLife != pTSoldier->stats.bLifeMax) && (pTSoldier->iHealableInjury >= 100))
{
// should come a question first if you really want to do the surgery
@@ -5619,7 +5620,7 @@ UINT32 UIHandleTOnTerrain( UI_EVENT *pUIEvent )
sTargetGridNo = MercPtrs[ ubTargID ]->sGridNo;
}
uiRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sTargetGridNo );
uiRange = PythSpacesAway( pSoldier->sGridNo, sTargetGridNo );
if ( uiRange <= NPC_TALK_RADIUS )
@@ -6610,7 +6611,7 @@ BOOLEAN HandleTalkInit( )
}
// Check distance
uiRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, usMapPos );
uiRange = PythSpacesAway( pSoldier->sGridNo, usMapPos );
// Double check path
if ( GetCivType( pTSoldier ) != CIV_TYPE_NA )
+10 -4
View File
@@ -1827,7 +1827,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
EXITGRID ExitGrid;
INT32 iRandom = 0;
UINT8 ubMineIndex;
INT16 sX, sY, sX2, sY2;
pSoldier2 = NULL;
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Handling %s, action %d at %ld", gMercProfiles[ ubTargetNPC ].zNickname, usActionCode, GetJA2Clock() );
@@ -1840,7 +1840,9 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
if (pSoldier && pSoldier2)
{
// see if we are facing this person
ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(pSoldier2->sGridNo),CenterY(pSoldier2->sGridNo));
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(pSoldier2->sGridNo, &sX2, &sY2);
ubDesiredMercDir = atan8(sX, sY, sX2, sY2);
// if not already facing in that direction,
if (pSoldier->ubDirection != ubDesiredMercDir)
{
@@ -2317,7 +2319,9 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
if (!TileIsOutOfBounds(sGridNo))
{
// see if we are facing this person
ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sGridNo),CenterY(sGridNo));
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(sGridNo, &sX2, &sY2);
ubDesiredMercDir = atan8(sX, sY, sX2, sY2);
// if not already facing in that direction,
if (pSoldier->ubDirection != ubDesiredMercDir)
{
@@ -5632,7 +5636,9 @@ void HandleRaulBlowingHimselfUp()
//blow himself up with, hmmm, lets say TNT. :)
usItem = HAND_GRENADE;
IgniteExplosion( RAUL_UB, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, usItem, pSoldier->pathing.bLevel );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
IgniteExplosion( RAUL_UB, sX, sY, 0, pSoldier->sGridNo, usItem, pSoldier->pathing.bLevel );
SetJa25GeneralFlag( JA_GF__RAUL_BLOW_HIMSELF_UP );
}
+142 -142
View File
@@ -1555,7 +1555,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
/////////////////// DAMAGE
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_BLADE|IC_PUNCH|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_BLADE|IC_PUNCH|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) )
{
ubRegionOffset = 1;
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + ubRegionOffset ] );
@@ -1698,7 +1698,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
/////////////////// AP TO DRAW
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[ gpItemDescObject->usItem].rocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !ItemIsRocketLauncher(gpItemDescObject->usItem) )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 13 ] );
}
@@ -1709,25 +1709,25 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
/////////////////// AP TO BURST
if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[gpItemDescObject->usItem].rocketlauncher )
if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsRocketLauncher(gpItemDescObject->usItem) )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 15 ] );
}
/////////////////// AP TO AUTOFIRE
if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 16 ] );
}
/////////////////// AP TO RELOAD
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 17 ] );
}
/////////////////// AP TO RELOAD MANUALLY
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher && Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) && Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 18 ] );
}
@@ -1735,7 +1735,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
/////////////////// RECOIL X/Y
if( UsingNewCTHSystem() == true )
{
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher && (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 ) )
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) && (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 ) )
{
// HEADROCK HAM 5: One value to rule them all.
// MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 18 ] );
@@ -1751,7 +1751,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
/////////////////// BULLETS PER 5 AP
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher && GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) && GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 21 ] );
}
@@ -2333,7 +2333,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
if (Item[ gpItemDescObject->usItem ].usItemClass & IC_ARMOUR)
{
//////////////////// EXPLOSIVE RESISTANCE
if (Item[ gpItemDescObject->usItem ].flakjacket)
if (ItemIsFlakJacket(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 5 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 5 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2432,7 +2432,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
if (Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV)
{
////////////////// LOCK BOMB
if (Item[ gpItemDescObject->usItem ].lockbomb)
if (ItemIsLockBomb(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 25 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 25 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2445,7 +2445,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
// Draw stats that can be had by any item.
//////////////////// WATERPROOF
if (!Item[ gpItemDescObject->usItem ].waterdamages)
if (!ItemIsDamagedByWater(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 6 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 6 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2454,7 +2454,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// ELECTRONIC
if (Item[ gpItemDescObject->usItem ].electronic)
if (ItemIsElectronic(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 7 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 7 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2463,7 +2463,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// GAS MASK
if (Item[ gpItemDescObject->usItem ].gasmask)
if (ItemIsGasmask(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 8 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 8 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2472,7 +2472,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// NEEDS BATTERIES
if (Item[ gpItemDescObject->usItem ].needsbatteries)
if (ItemNeedsBatteries(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 9 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 9 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2481,7 +2481,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// LOCKSMITH'S KIT
if (Item[ gpItemDescObject->usItem ].locksmithkit)
if (ItemIsLocksmithKit(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s%d", szUDBGenSecondaryStatsTooltipText[ 10 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 10 ], (Item[ gpItemDescObject->usItem ].LockPickModifier > 0 ?
( Item[ gpItemDescObject->usItem ].LockPickModifier * (*gpItemDescObject)[0]->data.objectStatus / 100 ) : Item[ gpItemDescObject->usItem ].LockPickModifier ) );
@@ -2491,7 +2491,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// WIRE CUTTERS
if (Item[ gpItemDescObject->usItem ].wirecutters)
if (ItemIsWirecutters(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 11 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 11 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2500,7 +2500,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// CROWBAR
if (Item[ gpItemDescObject->usItem ].crowbar)
if (ItemIsCrowbar(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s%d", szUDBGenSecondaryStatsTooltipText[ 12 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 12 ], Item[ gpItemDescObject->usItem ].CrowbarModifier );
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2509,7 +2509,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// METAL DETECTOR
if (Item[ gpItemDescObject->usItem ].metaldetector)
if (ItemIsMetalDetector(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 13 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 13 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2518,7 +2518,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// REMOTE TRIGGER
if (Item[ gpItemDescObject->usItem ].remotetrigger)
if (ItemIsRemoteTrigger(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 14 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 14 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2527,7 +2527,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// REMOTE DETONATOR
if (Item[ gpItemDescObject->usItem ].remotedetonator)
if (ItemIsRemoteDetonator(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 15 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 15 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2536,7 +2536,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// TIMER DETONATOR
if (Item[ gpItemDescObject->usItem ].detonator)
if (ItemIsDetonator(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 16 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 16 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2545,7 +2545,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// GAS CAN
if (Item[ gpItemDescObject->usItem ].gascan)
if (ItemIsGascan(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 17 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 17 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2554,7 +2554,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// TOOLKIT
if (Item[ gpItemDescObject->usItem ].toolkit)
if (ItemIsToolkit(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s%d", szUDBGenSecondaryStatsTooltipText[ 18 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 18 ], Item[ gpItemDescObject->usItem ].RepairModifier );
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2563,7 +2563,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// THERMAL OPTICS
if (Item[ gpItemDescObject->usItem ].thermaloptics)
if (ItemIsThermalOptics(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 19 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 19 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2572,7 +2572,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// X-RAY DEVICE
if (Item[ gpItemDescObject->usItem ].xray)
if (ItemHasXRay(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 20 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 20 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2581,7 +2581,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// CANTEEN
if (Item[ gpItemDescObject->usItem ].canteen)
if (ItemIsCanteen(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 21 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 21 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2599,7 +2599,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// FIRST-AID KIT
if (Item[ gpItemDescObject->usItem ].firstaidkit)
if (ItemIsFirstAidKit(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 23 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 23 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2608,7 +2608,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// MEDICAL KIT
if (Item[ gpItemDescObject->usItem ].medicalkit)
if (ItemIsMedicalKit(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 24 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 24 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2681,7 +2681,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// NOT DAMAGEABLE
if ( Item[gpItemDescObject->usItem].damageable == 0 )
if (!ItemIsDamageable(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 32 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 32 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2690,7 +2690,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// METAL
if ( Item[gpItemDescObject->usItem].metal > 0 )
if (ItemIsMetal(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 33 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 33 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2699,7 +2699,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// SINKS
if ( Item[gpItemDescObject->usItem].sinks > 0 )
if (ItemSinks(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 34 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 34 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2708,7 +2708,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// TWO HANDED
if ( Item[gpItemDescObject->usItem].twohanded > 0 )
if (ItemIsTwoHanded(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 35 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 35 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -2717,7 +2717,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
//////////////////// BLOCKS IRON SIGHTS
if ( Item[gpItemDescObject->usItem].blockironsight > 0 )
if (ItemBlocksIronsight(gpItemDescObject->usItem))
{
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 36 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 36 ]);
SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
@@ -4070,7 +4070,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
}
cnt++;
}
else if ( Item[gpItemDescObject->usItem].barrel == TRUE ) // for barrel items
else if (ItemIsBarrel(gpItemDescObject->usItem)) // for barrel items
{
if (!fDrawGenIndexes) fDrawGenIndexes = ++cnt; // new index line here?
///////////////////// COOLDOWN FACTOR
@@ -4366,8 +4366,8 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
//////////////////// DAMAGE
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher ) )
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 1;
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 5, gItemDescGenRegions[ubNumLine][0].sLeft+sOffsetX, gItemDescGenRegions[ubNumLine][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
@@ -4525,8 +4525,8 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
ubNumLine = 11;
}
if ( !Item[gpItemDescObject->usItem].repairable ||
( fComparisonMode && !Item[gpComparedItemDescObject->usItem].repairable ) )
if ( !ItemIsRepairable(gpItemDescObject->usItem) ||
( fComparisonMode && !ItemIsRepairable(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 35, gItemDescGenRegions[ubNumLine][0].sLeft + sOffsetX, gItemDescGenRegions[ubNumLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
@@ -4542,16 +4542,16 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
//////////////////// DRAW COST
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem].rocketlauncher ) )
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsRocketLauncher(gpItemDescObject->usItem) ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 13;
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 1, gItemDescGenRegions[ubNumLine][0].sLeft+sOffsetX, gItemDescGenRegions[ubNumLine][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
//////////////////// SINGLE SHOT COST - GUN
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpComparedItemDescObject->usItem].rocketlauncher ) )
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 14;
// "NO SINGLE-SHOT" ICON
@@ -4565,8 +4565,8 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
/////////////////// SINGLE SHOT COST - ROCKET
if ( ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpItemDescObject->usItem].rocketlauncher && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpComparedItemDescObject->usItem].rocketlauncher ) )
if ( ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && ItemIsRocketLauncher(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && ItemIsRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 14;
// SINGLE ROCKET-LAUNCH AP ICON
@@ -4574,9 +4574,9 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
/////////////////// SINGLE SHOT COST - GRENADE LAUNCHER
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& !Weapon[gpItemDescObject->usItem].NoSemiAuto && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpComparedItemDescObject->usItem].rocketlauncher
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_LAUNCHER && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& !Weapon[gpComparedItemDescObject->usItem].NoSemiAuto ) )
{
ubNumLine = 14;
@@ -4608,8 +4608,8 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
/////////////////// BURST COST - GUN
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpComparedItemDescObject->usItem].rocketlauncher ) )
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 15;
// "NO BURST" ICON
@@ -4625,9 +4625,9 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
}
////////////////// BURST COST - GRENADE LAUNCHER
else if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher
else if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& GetShotsPerBurst(gpItemDescObject)> 0 ) ||
( fComparisonMode && Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher
( fComparisonMode && Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& GetShotsPerBurst(gpItemDescObject)> 0 ) )
{
ubNumLine = 15;
@@ -4635,8 +4635,8 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
////////////////// AUTOFIRE COST
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpComparedItemDescObject->usItem].rocketlauncher ) )
if ( ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem) ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 16;
// "NO-AUTO" ICON
@@ -4654,17 +4654,17 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
////////////////// RELOAD COST
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher ) )
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 17;
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 2, gItemDescGenRegions[ubNumLine][0].sLeft+sOffsetX, gItemDescGenRegions[ubNumLine][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
////////////////// MANUAL RELOAD COST
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher
if ( ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem)
&& Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem)
&& Weapon[gpComparedItemDescObject->usItem].APsToReloadManually > 0 ) )
{
ubNumLine = 18;
@@ -4675,9 +4675,9 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
if( UsingNewCTHSystem() == true )
{
ubNumLine = 20;
if ( ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
if ( ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& ( GetShotsPerBurst(gpItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 ) ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& ( GetShotsPerBurst(gpComparedItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) > 0 ) ) )
{
// HEADROCK HAM 5: One value to rule them all! Line 19 left empty intentionally.
@@ -4702,9 +4702,9 @@ void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
}
///////////////// AUTOFIRE SHOTS PER 5 AP ICON
if ( ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
if ( ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) > 0 ) )
{
ubNumLine = 21;
@@ -4946,8 +4946,8 @@ void DrawExplosiveStats( OBJECTTYPE * gpItemDescObject )
}
////////////////// REPAIR EASE
if ( ( !Item[gpItemDescObject->usItem].repairable && !fComparisonMode ) ||
( fComparisonMode && !Item[ gpComparedItemDescObject->usItem ].repairable ) )
if ( ( !ItemIsRepairable(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && !ItemIsRepairable(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 35, gItemDescGenRegions[11][0].sLeft + sOffsetX, gItemDescGenRegions[11][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
@@ -5036,8 +5036,8 @@ void DrawArmorStats( OBJECTTYPE * gpItemDescObject )
}
////////////////// REPAIR EASE
if ( ( !Item[gpItemDescObject->usItem].repairable && !fComparisonMode ) ||
( fComparisonMode && !Item[gpComparedItemDescObject->usItem].repairable ) )
if ( ( !ItemIsRepairable(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && !ItemIsRepairable(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 35, gItemDescGenRegions[3][0].sLeft + sOffsetX, gItemDescGenRegions[3][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
@@ -5782,8 +5782,8 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
cnt++;
}
if( ( Item[gpItemDescObject->usItem].barrel == TRUE ) || // for barrel items
( fComparisonMode && Item[gpComparedItemDescObject->usItem].barrel == TRUE ) )
if( (ItemIsBarrel(gpItemDescObject->usItem)) || // for barrel items
( fComparisonMode && ItemIsBarrel(gpComparedItemDescObject->usItem) ) )
{
if ( !fDrawGenIndexes ) fDrawGenIndexes = ++cnt; // new index line here?
@@ -5988,8 +5988,8 @@ void DrawMiscStats( OBJECTTYPE * gpItemDescObject )
// not for weapons. They have this one their primary page
if ( !(Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH) )
{
if ( !Item[gpItemDescObject->usItem].repairable && !fComparisonMode ||
( fComparisonMode && !Item[gpComparedItemDescObject->usItem].repairable ) )
if ( !ItemIsRepairable(gpItemDescObject->usItem) && !fComparisonMode ||
( fComparisonMode && !ItemIsRepairable(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 35, gItemDescGenRegions[0][0].sLeft + sOffsetX, gItemDescGenRegions[0][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
@@ -6076,8 +6076,8 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_ARMOUR))
{
////////////////// FLAK JACKET
if ( ( Item[ gpItemDescObject->usItem ].flakjacket && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].flakjacket ))
if ( (ItemIsFlakJacket(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsFlakJacket(gpComparedItemDescObject->usItem) ))
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 5, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -6162,8 +6162,8 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_EXPLOSV))
{
////////////////// LOCK BOMB
if ( ( Item[ gpItemDescObject->usItem ].lockbomb && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].lockbomb ) )
if (( ItemIsLockBomb(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsLockBomb(gpComparedItemDescObject->usItem) ))
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 25, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -6174,128 +6174,128 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
// Draw stats that can be had by any item.
//////////////////// WATERPROOF
if ( ( !Item[ gpItemDescObject->usItem ].waterdamages && !fComparisonMode ) ||
( fComparisonMode && !Item[ gpComparedItemDescObject->usItem ].waterdamages ) )
if ( ( !ItemIsDamagedByWater(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && !ItemIsDamagedByWater(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 6, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// ELECTRONIC
if ( ( Item[ gpItemDescObject->usItem ].electronic && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].electronic ) )
if ( (ItemIsElectronic(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsElectronic(gpComparedItemDescObject->usItem)) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 7, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// GAS MASK
if ( ( Item[ gpItemDescObject->usItem ].gasmask && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].gasmask ) )
if ( (ItemIsGasmask(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsGasmask(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 8, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// NEEDS BATTERIES
if ( ( Item[ gpItemDescObject->usItem ].needsbatteries && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].needsbatteries ) )
if ( (ItemNeedsBatteries(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemNeedsBatteries(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 9, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// LOCKSMITH'S KIT
if ( ( Item[ gpItemDescObject->usItem ].locksmithkit && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].locksmithkit ) )
if ( (ItemIsLocksmithKit(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsLocksmithKit(gpComparedItemDescObject->usItem)) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 10, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// WIRE CUTTERS
if ( ( Item[ gpItemDescObject->usItem ].wirecutters && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].wirecutters ) )
if ( (ItemIsWirecutters(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsWirecutters(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 11, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// CROWBAR
if ( ( Item[ gpItemDescObject->usItem ].crowbar && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].crowbar ) )
if ( (ItemIsCrowbar(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsCrowbar(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 12, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// CROWBAR
if ( ( Item[ gpItemDescObject->usItem ].metaldetector && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].metaldetector ) )
if ( (ItemIsMetalDetector(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsMetalDetector(gpComparedItemDescObject->usItem)) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 13, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// REMOTE TRIGGER
if ( ( Item[ gpItemDescObject->usItem ].remotetrigger && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].remotetrigger ) )
if ( (ItemIsRemoteTrigger(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsRemoteTrigger(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 14, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// REMOTE DETONATOR
if ( ( Item[ gpItemDescObject->usItem ].remotedetonator && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].remotedetonator ) )
if ( (ItemIsRemoteDetonator(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsRemoteDetonator(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 15, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// TIMER DETONATOR
if ( ( Item[ gpItemDescObject->usItem ].detonator && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].detonator ) )
if ( (ItemIsDetonator(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsDetonator(gpComparedItemDescObject->usItem)) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 16, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// GAS CAN
if ( ( Item[ gpItemDescObject->usItem ].gascan && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].gascan ) )
if ( (ItemIsGascan(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsGascan(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 17, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// TOOLKIT
if ( ( Item[ gpItemDescObject->usItem ].toolkit && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].toolkit ) )
if ( (ItemIsToolkit(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsToolkit(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 18, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// THERMAL OPTICS
if ( ( Item[ gpItemDescObject->usItem ].thermaloptics && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].thermaloptics ) )
if ( (ItemIsThermalOptics(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsThermalOptics(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 19, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// X-RAY DEVICE
if ( ( Item[ gpItemDescObject->usItem ].xray && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].xray ) )
if ( (ItemHasXRay(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemHasXRay(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 20, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// CANTEEN
if ( ( Item[ gpItemDescObject->usItem ].canteen && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].canteen ) )
if ( (ItemIsCanteen(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsCanteen(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 21, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -6310,16 +6310,16 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
}
//////////////////// FIRST-AID KIT
if ( ( Item[ gpItemDescObject->usItem ].firstaidkit && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].firstaidkit ) )
if ( (ItemIsFirstAidKit(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsFirstAidKit(gpComparedItemDescObject->usItem)) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 23, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// MEDICAL KIT
if ( ( Item[ gpItemDescObject->usItem ].medicalkit && !fComparisonMode ) ||
( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].medicalkit ) )
if ( (ItemIsMedicalKit(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsMedicalKit(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 24, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -6389,40 +6389,40 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
}
//////////////////// NOT DAMAGEABLE
if ( ( Item[gpItemDescObject->usItem].damageable == 0 && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].damageable == 0 ) )
if ( (!ItemIsDamageable(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && !ItemIsDamageable(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 31, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// METAL
if ( ( Item[gpItemDescObject->usItem].metal > 0 && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].metal > 0 ) )
if ( (ItemIsMetal(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsMetal(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 32, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// SINKS
if ( ( Item[gpItemDescObject->usItem].sinks > 0 && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].sinks > 0 ) )
if ( (ItemSinks(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemSinks(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 33, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// TWO HANDED
if ( ( Item[gpItemDescObject->usItem].twohanded > 0 && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].twohanded > 0 ) )
if ( (ItemIsTwoHanded(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemIsTwoHanded(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 34, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
//////////////////// BLOCKS IRON SIGHTS
if ( ( Item[gpItemDescObject->usItem].blockironsight > 0 && !fComparisonMode ) ||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].blockironsight > 0 ) )
if ( (ItemBlocksIronsight(gpItemDescObject->usItem) && !fComparisonMode ) ||
( fComparisonMode && ItemBlocksIronsight(gpComparedItemDescObject->usItem) ) )
{
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 35, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
@@ -6822,7 +6822,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// ShotsPer4Turns -> ubAttackAPs, used later for all shot AP values
// silversurfer: Knuckle Dusters count as bare hand attacks and use the AP_PUNCH constant.
if ( Item[gpItemDescObject->usItem].brassknuckles )
if (ItemIsBrassKnuckles(gpItemDescObject->usItem))
{
ubAttackAPs = APBPConstants[AP_PUNCH];
ubBasicAttackAPs = APBPConstants[AP_PUNCH];
@@ -7002,7 +7002,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyValueInColour( iFinalAccuracyValue, ubNumLine, 3, fComparisonMode, FALSE, TRUE, ITEMDESC_FONTPOSITIVE );
}
/////////////// DAMAGE
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) )
{
// Set line to draw into
ubNumLine = 1;
@@ -7060,7 +7060,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyValueInColour( iComparedFinalDamageValue - iFinalDamageValue, ubNumLine, 3, fComparisonMode, FALSE, TRUE );
}
}
else if( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher )
else if( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) )
{
// Set line to draw into
ubNumLine = 1;
@@ -7840,7 +7840,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
// Does gun have flash suppression?
BOOLEAN iFlashValue = Item[ gpItemDescObject->usItem ].hidemuzzleflash;
BOOLEAN iFlashValue = ItemHasHiddenMuzzleFlash(gpItemDescObject->usItem);
if( !fComparisonMode )
{
@@ -7864,7 +7864,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
else if( IsFlashSuppressorAlt( gpComparedItemDescObject ) == TRUE )
{
BOOLEAN iComparedFlashValue = Item[ gpComparedItemDescObject->usItem ].hidemuzzleflash;
BOOLEAN iComparedFlashValue = ItemHasHiddenMuzzleFlash(gpComparedItemDescObject->usItem);
if ( iFlashValue )
{
if (iComparedFlashValue)
@@ -7921,7 +7921,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
else
ubNumLine = 8;
// Does gun have flash suppression?
BOOLEAN iFlashValue = Item[ gpComparedItemDescObject->usItem ].hidemuzzleflash;
BOOLEAN iFlashValue = ItemHasHiddenMuzzleFlash(gpComparedItemDescObject->usItem);
if ( iFlashValue )
{
// Print base value
@@ -8077,7 +8077,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
///////////////////// DRAW AP
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsRocketLauncher(gpItemDescObject->usItem) )
{
// Set line to draw into
ubNumLine = 13;
@@ -8137,7 +8137,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyValueInColour( iComparedFinalDrawAPCost - iFinalDrawAPCost, ubNumLine, 3, fComparisonMode, FALSE, FALSE );
}
}
else if( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem].rocketlauncher )
else if( fComparisonMode && Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem) )
{
ubNumLine = 13;
// Get final Draw Cost
@@ -8376,7 +8376,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
///////////////////// RELOAD AP
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) )
{
// Set line to draw into
ubNumLine = 17;
@@ -8423,7 +8423,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColour( iFinalReloadAPCost, ubNumLine, 3, fComparisonMode, FALSE, FALSE, FONT_MCOLOR_WHITE );
}
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher )
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) )
{
// Get final Reload Cost
INT16 iComparedFinalReloadAPCost = GetAPsToReload( gpComparedItemDescObject );
@@ -8471,7 +8471,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyTextInColour( L"-", ubNumLine, 3, ITEMDESC_FONTPOSITIVE );
}
}
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher ) )
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) ) )
{
ubNumLine = 17;
// Get final Reload Cost
@@ -8515,7 +8515,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
///////////////////// MANUAL RELOAD AP
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem)
&& Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
{
// Set line to draw into
@@ -8555,7 +8555,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColour( iFinalManualReloadAPCost, ubNumLine, 3, fComparisonMode, FALSE, FALSE, FONT_MCOLOR_WHITE );
}
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem)
&& Weapon[gpComparedItemDescObject->usItem].APsToReloadManually > 0 )
{
// Get final Manual Reload Cost
@@ -8597,7 +8597,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyTextInColour( L"-", ubNumLine, 3, ITEMDESC_FONTPOSITIVE );
}
}
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem)
&& Weapon[gpComparedItemDescObject->usItem].APsToReloadManually > 0 ) )
{
ubNumLine = 18;
@@ -8637,7 +8637,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
///////////////////// RECOIL X/Y
if ( UsingNewCTHSystem() == true )
{
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& GetShotsPerBurst(gpItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject) )
{
// HEADROCK HAM 5: One value to rule them all.
@@ -8677,7 +8677,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColourFloat( dFinalRecoil, ubNumLine, 3, fComparisonMode, FALSE, FALSE, FONT_MCOLOR_WHITE, 1.0f );
}
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetShotsPerBurst(gpComparedItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) )
{
FLOAT iComparedFinalRecoilX = 0;
@@ -8775,7 +8775,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
SetFontForeground( 6 );
*/
}
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetShotsPerBurst(gpComparedItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) ) )
{
@@ -8848,7 +8848,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColour( iFinalBurstValue, ubNumLine, 3, fComparisonMode, FALSE, FALSE, FONT_MCOLOR_WHITE );
}
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpComparedItemDescObject->usItem ].singleshotrocketlauncher )
else if( Item[ gpComparedItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !ItemIsSingleShotRocketLauncher(gpComparedItemDescObject->usItem) )
{
// Get base Burst Penalty value
INT16 iComparedBurstValue = Weapon[gpComparedItemDescObject->usItem].ubBurstPenalty * (gGameExternalOptions.bAimedBurstEnabled?gGameExternalOptions.uAimedBurstPenalty:1);
@@ -8961,7 +8961,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
}
/////////////////// AUTOFIRE BULLETS PER 5 AP
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
// Set line to draw into
@@ -8982,7 +8982,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColour( iFinalB5AP, ubNumLine, 3, fComparisonMode, FALSE, TRUE, FONT_MCOLOR_WHITE );
}
else if ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
else if ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) > 0 )
{
// Get final B/5AP
@@ -9003,7 +9003,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
DrawPropertyTextInColour( L"-", ubNumLine, 3, ITEMDESC_FONTNEGATIVE );
}
}
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
else if( fComparisonMode && ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) > 0 ) )
{
ubNumLine = 21;
@@ -9054,7 +9054,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
// Print final value
DrawPropertyValueInColour( iFinalAutoValue, ubNumLine, 3, fComparisonMode, FALSE, FALSE, FONT_MCOLOR_WHITE );
}
else if ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpComparedItemDescObject->usItem].rocketlauncher
else if ( Item[ gpComparedItemDescObject->usItem ].usItemClass == IC_GUN && !ItemIsRocketLauncher(gpComparedItemDescObject->usItem)
&& GetAutofireShotsPerFiveAPs(gpComparedItemDescObject) > 0 )
{
// Get base Auto Penalty value
@@ -13805,8 +13805,8 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
cnt++;
}
else if ( ( Item[gpItemDescObject->usItem].barrel == TRUE ) || // display for barrel items
( fComparisonMode && Item[gpComparedItemDescObject->usItem].barrel == TRUE ) )
else if ( (ItemIsBarrel(gpItemDescObject->usItem)) || // display for barrel items
( fComparisonMode && ItemIsBarrel(gpComparedItemDescObject->usItem) ) )
{
if (!fDrawGenIndexes) fDrawGenIndexes = ++cnt; // insert Indexes here?
///////////////////// COOLDOWN FACTOR
+66 -73
View File
@@ -168,7 +168,7 @@ INT16 ITEMDESC_DONE_Y;
#define DOTDOTDOT L"..."
#define COMMA_AND_SPACE L", "
#define ITEM_PROS_AND_CONS( usItem ) ( ( Item[ usItem ].usItemClass & IC_GUN && !Item[ usItem ].rocketlauncher ) )
#define ITEM_PROS_AND_CONS( usItem ) ( ( Item[ usItem ].usItemClass & IC_GUN && !ItemIsRocketLauncher(usItem) ) )
#define ITEMDESC_ITEM_STATUS_WIDTH 2
#define ITEMDESC_ITEM_WIDTH 117
@@ -2666,7 +2666,7 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
}
// IF it's the second hand and this hand cannot contain anything, remove the second hand position graphic
if (sPocket == SECONDHANDPOS && Item[pSoldier->inv[HANDPOS].usItem].twohanded )
if (sPocket == SECONDHANDPOS && ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem))
{
// CHRISL: Change coords for STI that covers 2nd hand location when carrying a 2handed weapon
if( guiCurrentItemDescriptionScreen != MAP_SCREEN )
@@ -2710,7 +2710,7 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
fHatchItOut = TRUE;
}
// CHRISL: Don't hatch second hand position if we're holding a two handed item
else if ( sPocket == SECONDHANDPOS && Item[pSoldier->inv[HANDPOS].usItem].twohanded )
else if ( sPocket == SECONDHANDPOS && ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) )
{
fHatchItOut = FALSE;
}
@@ -2832,8 +2832,8 @@ BOOLEAN CompatibleItemForApplyingOnMerc(OBJECTTYPE *pTestObject)
//Shadooow: rewritten to use new item flags and check canteen not empty
if (((HasItemFlag(usItem, CAMO_REMOVAL) && gGameExternalOptions.fCamoRemoving) || Item[usItem].camouflagekit || usItem == JAR_ELIXIR ||
Item[usItem].clothestype || Item[usItem].drugtype || Item[usItem].foodtype) && (!Item[usItem].canteen || (*pTestObject)[0]->data.objectStatus > 1))
if (((HasItemFlag(usItem, CAMO_REMOVAL) && gGameExternalOptions.fCamoRemoving) || ItemIsCamoKit(usItem) || usItem == JAR_ELIXIR ||
Item[usItem].clothestype || Item[usItem].drugtype || Item[usItem].foodtype) && (!ItemIsCanteen(usItem) || (*pTestObject)[0]->data.objectStatus > 1))
{
return( TRUE );
}
@@ -2913,20 +2913,16 @@ void HandleAnyMercInSquadHasCompatibleStuff( UINT8 ubSquad, OBJECTTYPE *pObject,
BOOLEAN IsMutuallyValidAttachmentOrLaunchable(UINT16 usAttItem, UINT16 usItem)//dnl ch76 091113
{
UINT32 uiLoop = 0;
while ( Attachment[uiLoop][0] )
for (UINT32 uiLoop = 0; uiLoop < gMAXATTACHMENTS_READ; uiLoop++)
{
if(Attachment[uiLoop][0] == usAttItem && Attachment[uiLoop][1] == usItem || Attachment[uiLoop][0] == usItem && Attachment[uiLoop][1] == usAttItem )
if (Attachment[uiLoop].attachmentIndex == usAttItem && Attachment[uiLoop].itemIndex == usItem || Attachment[uiLoop].attachmentIndex == usItem && Attachment[uiLoop].itemIndex == usAttItem)
return(TRUE);
++uiLoop;
}
uiLoop = 0;
while ( Launchable[uiLoop][0] )
for (UINT32 uiLoop = 0; uiLoop < gMAXLAUNCHABLES_READ; uiLoop++)
{
if ( Launchable[uiLoop][0] == usAttItem && Launchable[uiLoop][1] == usItem || Launchable[uiLoop][0] == usItem && Launchable[uiLoop][1] == usAttItem )
return(TRUE);
++uiLoop;
}
return(FALSE);
@@ -3014,14 +3010,14 @@ BOOLEAN HandleCompatibleAmmoUIForMapScreen( SOLDIERTYPE *pSoldier, INT32 bInvPos
UINT32 invsize = pSoldier->inv.size();
// First test attachments, which almost any type of item can have....
if ( !(Item[ pTestObject->usItem ].hiddenaddon ) )
if ( !(ItemIsHiddenAddon(pTestObject->usItem)) )
{
for ( cnt = 0; cnt < invsize; ++cnt )
{
pObject = &(pSoldier->inv[ cnt ]);
if (pObject == pTestObject || Item[pObject->usItem].hiddenaddon || (!Item[pObject->usItem].attachment &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !Item[pTestObject->usItem].attachment &&
if (pObject == pTestObject || ItemIsHiddenAddon(pObject->usItem) || (!ItemIsAttachment(pObject->usItem) &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !ItemIsAttachment(pTestObject->usItem) &&
!Item[pTestObject->usItem].attachmentclass && !Item[pTestObject->usItem].nasAttachmentClass))
{
// don't consider for UI purposes
@@ -3120,14 +3116,14 @@ BOOLEAN HandleCompatibleAmmoUIForMapInventory(SOLDIERTYPE *pSoldier, INT32 bInvP
}
// First test attachments, which almost any type of item can have....
if (!(Item[pTestObject->usItem].hiddenaddon))
if (!(ItemIsHiddenAddon(pTestObject->usItem)))
{
for (cnt = 0; cnt < MAP_INVENTORY_POOL_SLOT_COUNT; ++cnt)
{
pObject = &(pInventoryPoolList[iStartSlotNumber + cnt].object);
if (pObject == pTestObject || Item[pObject->usItem].hiddenaddon || (!Item[pObject->usItem].attachment &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !Item[pTestObject->usItem].attachment &&
if (pObject == pTestObject || ItemIsHiddenAddon(pObject->usItem) || (!ItemIsAttachment(pObject->usItem) &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !ItemIsAttachment(pTestObject->usItem) &&
!Item[pTestObject->usItem].attachmentclass && !Item[pTestObject->usItem].nasAttachmentClass))
{
// don't consider for UI purposes
@@ -3274,14 +3270,14 @@ BOOLEAN InternalHandleCompatibleAmmoUI( SOLDIERTYPE *pSoldier, OBJECTTYPE *pTest
UINT32 invsize = pSoldier->inv.size();
// First test attachments, which almost any type of item can have....
if (!(Item[pTestObject->usItem].hiddenaddon))
if (!(ItemIsHiddenAddon(pTestObject->usItem)))
{
for (cnt = 0; cnt < invsize; ++cnt)
{
pObject = &(pSoldier->inv[cnt]);
if (pObject == pTestObject || Item[pObject->usItem].hiddenaddon || (!Item[pObject->usItem].attachment &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !Item[pTestObject->usItem].attachment &&
if (pObject == pTestObject || ItemIsHiddenAddon(pObject->usItem) || (!ItemIsAttachment(pObject->usItem) &&
!Item[pObject->usItem].attachmentclass && !Item[pObject->usItem].nasAttachmentClass && !ItemIsAttachment(pTestObject->usItem) &&
!Item[pTestObject->usItem].attachmentclass && !Item[pTestObject->usItem].nasAttachmentClass))
{
// don't consider for UI purposes
@@ -3306,7 +3302,7 @@ BOOLEAN InternalHandleCompatibleAmmoUI( SOLDIERTYPE *pSoldier, OBJECTTYPE *pTest
}
}
//if the test object is hidden addon or attachment, it won't be ammunition or gun so skip this
if (!Item[pTestObject->usItem].hiddenaddon && !Item[pTestObject->usItem].attachment)
if (!ItemIsHiddenAddon(pTestObject->usItem) && !ItemIsAttachment(pTestObject->usItem))
{
if( ( Item [ pTestObject->usItem ].usItemClass & IC_GUN ) )
{
@@ -3820,7 +3816,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
}
}
if ( pItem->usItemClass == IC_GUN && !Item[pObject->usItem].rocketlauncher )
if ( pItem->usItemClass == IC_GUN && !ItemIsRocketLauncher(pObject->usItem) )
{
sNewY = sY + sHeight - 10;
sNewX = sX + 1;
@@ -3876,7 +3872,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
}
}
if ( pItemShown->usItemClass == IC_GUN && !Item[pObjShown->usItem].rocketlauncher )
if ( pItemShown->usItemClass == IC_GUN && !ItemIsRocketLauncher(pObjShown->usItem) )
{
SetRGBFontForeground( AmmoTypes[( *pObjShown )[iter]->data.gun.ubGunAmmoType].red,
AmmoTypes[( *pObjShown )[iter]->data.gun.ubGunAmmoType].green,
@@ -3954,7 +3950,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
}
// Flugente: overheating
if ( gGameExternalOptions.fWeaponOverheating && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || Item[pObject->usItem].barrel ) )
if ( gGameExternalOptions.fWeaponOverheating && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || ItemIsBarrel(pObject->usItem)) )
{
OBJECTTYPE* pObjShown = pObject;
@@ -4205,7 +4201,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
}
if ( ( ( pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO ) ||
( Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_LAUNCHER && !Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher ) ) &&
( Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_LAUNCHER && !ItemIsRocketLauncher(pSoldier->inv[HANDPOS].usItem)) ) &&
pSoldier->usGLDelayMode )
{
wcscat( pStr, New113Message[MSG113_FIREMODE_GL_DELAYED] );
@@ -4235,7 +4231,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
if ( pSoldier && pObject == &(pSoldier->inv[SECONDHANDPOS] ) &&
(pSoldier->bWeaponMode == WM_BURST || pSoldier->bWeaponMode == WM_AUTOFIRE) &&
Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN &&
!(Item[ pSoldier->inv[HANDPOS ].usItem ].twohanded ) &&
!ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) &&
pSoldier->IsValidSecondHandBurst() )
{
sNewY = sY + 13; // rather arbitrary
@@ -4569,7 +4565,7 @@ void MAPINVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pOb
}
//////////////////// GUN DATA //////////////////
if ( pItem->usItemClass & IC_GUN && !Item[pObject->usItem].rocketlauncher )
if ( pItem->usItemClass & IC_GUN && !ItemIsRocketLauncher(pObject->usItem) )
{
//////////////// AMMO REMAINING
@@ -4808,7 +4804,7 @@ void MAPINVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pOb
}
iCurAsterisk = ATTACHMENT_GENERAL;
if (Item[iter->usItem].grenadelauncher )
if (ItemIsGrenadeLauncher(iter->usItem))
{
//iCurAsterisk = ATTACHMENT_GL;
uiNumAttachmentsGL++;
@@ -5237,7 +5233,7 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
}
// Add ammo eject button for GUN type objects.
if ( (Item[ pObject->usItem ].usItemClass & IC_GUN) && !Item[pObject->usItem].rocketlauncher )
if ( (Item[ pObject->usItem ].usItemClass & IC_GUN) && !ItemIsRocketLauncher(pObject->usItem) )
{
if ( GetMagSize(gpItemDescObject) <= 99 )
{
@@ -5614,7 +5610,7 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
}
// if ( !(Item[ pObject->usItem ].fFlags & ITEM_HIDDEN_ADDON) && ( ValidAttachment( gpItemPointer->usItem, pObject->usItem ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
if ( !(Item[ pObject->usItem ].hiddenaddon ) && ( ValidAttachment( gpItemPointer->usItem, pObject ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
if ( !(ItemIsHiddenAddon(pObject->usItem)) && ( ValidAttachment( gpItemPointer->usItem, pObject ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
{
SetUpFastHelpListRegions(
gItemDescHelpText.iXPosition,
@@ -5754,7 +5750,7 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
if (Item[usLoop].nasAttachmentClass & AttachmentSlots[usLoopSlotID].nasAttachmentClass && IsAttachmentPointAvailable(point, usLoop, TRUE))
{
usAttachment = usLoop;
if (!Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment))
if (!ItemIsHiddenAddon(usAttachment) && !ItemIsHiddenAttachment(usAttachment) && ItemIsLegal(usAttachment))
{
if (std::find(attachList.begin(), attachList.end(), usAttachment) == attachList.end())
{
@@ -5765,26 +5761,14 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
}
// sevenfm: check launchables
for (UINT16 usLoop = 0; usLoop < MAXITEMS + 1; usLoop++)
for (UINT16 usLoop = 0; usLoop < gMAXLAUNCHABLES_READ; usLoop++)
{
// check that reached end of valid launchables
if (Launchable[usLoop][0] == 0)
break;
usAttachment = 0;
if (Launchable[usLoop][1] == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Launchable[usLoop][0]].nasAttachmentClass)
{
//search primary item launchables.xml
usAttachment = Launchable[usLoop][0];
}
if (usAttachment > 0 && !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment))
{
if (std::find(attachList.begin(), attachList.end(), usAttachment) == attachList.end())
{
attachList.push_back(usAttachment);
}
}
else
{
//search for launchables made valid by other attachments
@@ -5793,25 +5777,33 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
while (cnt)
{
if (Launchable[usLoop][1] == *p && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Launchable[usLoop][0]].nasAttachmentClass)
{
usAttachment = Launchable[usLoop][0];
break;
}
cnt--, p++;
}
}
if (usAttachment > 0 && !ItemIsHiddenAddon(usAttachment) && !ItemIsHiddenAttachment(usAttachment) && ItemIsLegal(usAttachment))
{
if (std::find(attachList.begin(), attachList.end(), usAttachment) == attachList.end())
{
attachList.push_back(usAttachment);
}
}
}
// check all attachments
for (UINT16 usLoop = 0; usLoop < MAXATTACHMENTS; usLoop++)
//TODO: should be optimized using AttachmentBackmap and/or possibly FindAttachmentRange()
for (UINT32 uiLoop = 0; uiLoop < gMAXATTACHMENTS_READ; uiLoop++)
{
// check that reached end of valid attachments
if (Attachment[usLoop][0] == 0)
break;
usAttachment = 0;
if (Attachment[usLoop][1] == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[usLoop][0]].nasAttachmentClass)
if (Attachment[uiLoop].itemIndex == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[uiLoop].attachmentIndex].nasAttachmentClass)
{
//search primary item attachments.xml
usAttachment = Attachment[usLoop][0];
usAttachment = Attachment[uiLoop].attachmentIndex;
}
else
{
@@ -5820,14 +5812,17 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
UINT16* p = cnt ? &attachedList.front() : NULL;
while (cnt)
{
if (Attachment[usLoop][1] == *p && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[usLoop][0]].nasAttachmentClass)
usAttachment = Attachment[usLoop][0];
if (Attachment[uiLoop].itemIndex == *p && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[uiLoop].attachmentIndex].nasAttachmentClass)
{
usAttachment = Attachment[uiLoop].attachmentIndex;
break;
}
cnt--, p++;
}
}
if (usAttachment > 0 && !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment))
if (usAttachment > 0 && !ItemIsHiddenAddon(usAttachment) && !ItemIsHiddenAttachment(usAttachment) && ItemIsLegal(usAttachment))
{
if (std::find(attachList.begin(), attachList.end(), usAttachment) == attachList.end())
{
@@ -5900,7 +5895,7 @@ void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
for(UINT16 loop = 0; loop < attachList.size(); loop++){
usAttachment = attachList[loop];
// If the attachment is not hidden
if (usAttachment > 0 && !Item[ usAttachment ].hiddenaddon && !Item[ usAttachment ].hiddenattachment)
if (usAttachment > 0 && !ItemIsHiddenAddon(usAttachment) && !ItemIsHiddenAttachment(usAttachment))
{
if (wcslen( attachStr3 ) + wcslen(Item[usAttachment].szItemName) > 3600)
{
@@ -7026,8 +7021,7 @@ void RenderItemDescriptionBox( )
//WarmSteel - This hatches out attachment slots one by one, instead of all of em.
for(cnt = 0; cnt < (INT32)(*gpItemDescObject)[gubItemDescStatusIndex]->attachments.size(); cnt++)
{
//if ( ( Item[ gpItemPointer->usItem ].fFlags & ITEM_HIDDEN_ADDON ) ||
if ( ( Item[ gpItemPointer->usItem ].hiddenaddon ) ||
if (ItemIsHiddenAddon(gpItemPointer->usItem) ||
( !ValidItemAttachmentSlot( gpItemDescObject, gpItemPointer->usItem, FALSE, FALSE, gubItemDescStatusIndex, cnt, FALSE, NULL, usAttachmentSlotIndexVector) &&
!ValidMerge( gpItemPointer->usItem, gpItemDescObject->usItem ) ) )
@@ -7043,8 +7037,7 @@ void RenderItemDescriptionBox( )
} else {
for(cnt = 0; cnt < OLD_MAX_ATTACHMENTS_101; cnt++)
{
//if ( ( Item[ gpItemPointer->usItem ].fFlags & ITEM_HIDDEN_ADDON ) ||
if ( ( Item[ gpItemPointer->usItem ].hiddenaddon ) ||
if (ItemIsHiddenAddon(gpItemPointer->usItem) ||
( !ValidItemAttachment( gpItemDescObject, gpItemPointer->usItem, FALSE, FALSE, gubItemDescStatusIndex, usAttachmentSlotIndexVector) &&
!ValidMerge( gpItemPointer->usItem, gpItemDescObject->usItem ) && !ValidLaunchable( gpItemPointer->usItem, gpItemDescObject->usItem ) ) )
@@ -7076,7 +7069,7 @@ void RenderItemDescriptionBox( )
DrawItemUIBarEx( gpItemDescObject, (UINT8)(DRAW_ITEM_STATUS_ATTACHMENT1 + cnt), sCenX, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, Get16BPPColor( STATUS_BAR ), Get16BPPColor( STATUS_BAR_SHADOW ), TRUE , guiSAVEBUFFER, gubItemDescStatusIndex );
// Flugente: overheating
if ( gGameExternalOptions.fWeaponOverheating && ( Item[ (iter)->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[ (iter)->usItem ].barrel == TRUE) ) // Flugente
if ( gGameExternalOptions.fWeaponOverheating && ( Item[ (iter)->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) || ItemIsBarrel((iter)->usItem)) ) // Flugente
{
FLOAT overheatjampercentage = GetGunOverheatDisplayPercentage( &(*iter));
@@ -7224,7 +7217,7 @@ void RenderItemDescriptionBox( )
SetFontForeground( FONT_BLACK );
SetFontShadow( ITEMDESC_FONTSHADOW2 );
// Caliber
if ( (Item[gpItemDescObject->usItem].fingerprintid ) && (*gpItemDescObject)[gubItemDescStatusIndex]->data.ubImprintID < NO_PROFILE )
if ( ItemHasFingerPrintID(gpItemDescObject->usItem) && (*gpItemDescObject)[gubItemDescStatusIndex]->data.ubImprintID < NO_PROFILE )
{
// Fingerprint ID
swprintf( pStr, L"%s %s (%s)", AmmoCaliber[ Weapon[ gpItemDescObject->usItem ].ubCalibre ], WeaponType[ Weapon[ gpItemDescObject->usItem ].ubWeaponType ], gMercProfiles[ (*gpItemDescObject)[gubItemDescStatusIndex]->data.ubImprintID ].zNickname );
@@ -7289,7 +7282,7 @@ void RenderItemDescriptionBox( )
}
// Flugente: display temperature string
if ( gGameExternalOptions.fWeaponOverheating && ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN || Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER || Item[gpItemDescObject->usItem].barrel == TRUE ) )
if ( gGameExternalOptions.fWeaponOverheating && ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN || Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER || ItemIsBarrel(gpItemDescObject->usItem) ) )
{
// UDB system displays a string with colored condition text.
int regionindex = 8;
@@ -7617,7 +7610,7 @@ void RenderItemDescriptionBox( )
FindFontRightCoordinates( gODBItemDescRegions[2][7].sLeft, gODBItemDescRegions[2][7].sTop, gODBItemDescRegions[2][7].sRight - gODBItemDescRegions[2][7].sLeft, gODBItemDescRegions[2][7].sBottom - gODBItemDescRegions[2][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !ItemIsSingleShotRocketLauncher(gpItemDescObject->usItem) )
{
// DAMAGE
SetFontForeground( 6 );
@@ -8370,7 +8363,7 @@ void DeleteItemDescriptionBox( )
}
if (Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && ValidLaunchable(newIter->usItem, gpItemDescObject->usItem) ||
Item[gpItemDescObject->usItem].cannon)
ItemIsCannon(gpItemDescObject->usItem))
{
//lalien: changed to charge AP's for reloading a GL/RL
ubAPCost = GetAPsToReload(gpItemDescObject);
@@ -9578,7 +9571,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
BOOLEAN ItemCursorInLobRange( INT32 usMapPos )
{
// Draw item depending on distance from buddy
if ( GetRangeFromGridNoDiff( usMapPos, gpItemPointerSoldier->sGridNo ) > MIN_LOB_RANGE )
if (PythSpacesAway( usMapPos, gpItemPointerSoldier->sGridNo ) > MIN_LOB_RANGE )
{
return( FALSE );
}
@@ -10717,7 +10710,7 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason )
}
else
{
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpItemPopupObject->usItem].usItemClass == IC_GUN && (*gpItemPopupObject)[uiItemPos]->data.gun.ubGunShotsLeft > 0 && !(Item[gpItemPopupObject->usItem].singleshotrocketlauncher) )
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpItemPopupObject->usItem].usItemClass == IC_GUN && (*gpItemPopupObject)[uiItemPos]->data.gun.ubGunShotsLeft > 0 && !ItemIsSingleShotRocketLauncher(gpItemPopupObject->usItem) )
{
EmptyWeaponMagazine( gpItemPopupObject, &gItemPointer, uiItemPos );
InternalMAPBeginItemPointer( gpItemPopupSoldier );
@@ -10728,7 +10721,7 @@ void ItemPopupRegionCallback( MOUSE_REGION * pRegion, INT32 iReason )
}
else
{
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpItemPopupObject->usItem].usItemClass == IC_GUN && (*gpItemPopupObject)[uiItemPos]->data.gun.ubGunShotsLeft > 0 && !(Item[gpItemPopupObject->usItem].singleshotrocketlauncher) && !( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpItemPopupObject->usItem].usItemClass == IC_GUN && (*gpItemPopupObject)[uiItemPos]->data.gun.ubGunShotsLeft > 0 && !ItemIsSingleShotRocketLauncher(gpItemPopupObject->usItem) && !( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
{
EmptyWeaponMagazine( gpItemPopupObject, &gItemPointer, uiItemPos );
gpItemPointer = &gItemPointer;
@@ -12634,7 +12627,7 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
// Fingerprint ID (Soldier Name)
if ( ( Item[pObject->usItem].fingerprintid ) && (*pObject)[subObject]->data.ubImprintID < NO_PROFILE )
if ( ItemHasFingerPrintID(pObject->usItem) && (*pObject)[subObject]->data.ubImprintID < NO_PROFILE )
{
CHAR16 pStr2[20];
swprintf( pStr2, L" [%s]", gMercProfiles[ (*pObject)[subObject]->data.ubImprintID ].zNickname );
@@ -13821,7 +13814,7 @@ void BombInventoryMessageBoxCallBack( UINT8 ubExitValue )
if (gpItemDescSoldier)
{
// no planting tripwire in our inventory...
if ( Item[ gpItemDescObject->usItem ].tripwire == 1 )
if (ItemIsTripwire(gpItemDescObject->usItem))
return;
INT32 iResult;
@@ -13970,14 +13963,14 @@ void BombInventoryDisArmMessageBoxCallBack( UINT8 ubExitValue )
if ( (*gpItemDescObject)[0]->data.misc.ubBombOwner > 1 && ( (INT32)(*gpItemDescObject)[0]->data.misc.ubBombOwner - 2 >= gTacticalStatus.Team[ OUR_TEAM ].bFirstID && (*gpItemDescObject)[0]->data.misc.ubBombOwner - 2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID ) )
{
// Flugente: get a tripwire-related bonus if we have a wire cutter in our hands
if ( ( (&gpItemDescSoldier->inv[HANDPOS])->exists() && Item[ gpItemDescSoldier->inv[HANDPOS].usItem ].wirecutters == 1 ) || ( (&gpItemDescSoldier->inv[SECONDHANDPOS])->exists() && Item[ gpItemDescSoldier->inv[SECONDHANDPOS].usItem ].wirecutters == 1 ) )
if ( ( (&gpItemDescSoldier->inv[HANDPOS])->exists() && ItemIsWirecutters(gpItemDescSoldier->inv[HANDPOS].usItem) ) || ( (&gpItemDescSoldier->inv[SECONDHANDPOS])->exists() && ItemIsWirecutters(gpItemDescSoldier->inv[SECONDHANDPOS].usItem) ) )
{
// + 10 if item gets activated by tripwire
if ( Item[gpItemDescObject->usItem].tripwireactivation == 1 )
if (ItemHasTripwireActivation(gpItemDescObject->usItem))
diff += 10;
// + 10 if item is tripwire
if ( Item[gpItemDescObject->usItem].tripwire == 1 )
if (ItemIsTripwire(gpItemDescObject->usItem))
diff += 10;
}
+19 -18
View File
@@ -2598,7 +2598,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// AGI
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sAgilityGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sAgilityGain+1)) / SubpointsPerPoint(AGILAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sAgilityGain+1)) / SubpointsPerPoint(AGILAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_AGI_Y-1);
ClipRect.iBottom = (SM_AGI_Y-1) + SM_STATS_HEIGHT;
@@ -2610,7 +2610,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// DEX
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sDexterityGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sDexterityGain+1)) / SubpointsPerPoint(DEXTAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sDexterityGain+1)) / SubpointsPerPoint(DEXTAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_DEX_Y-1);
ClipRect.iBottom = (SM_DEX_Y-1) + SM_STATS_HEIGHT;
@@ -2622,7 +2622,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// STR
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sStrengthGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sStrengthGain+1)) / SubpointsPerPoint(STRAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sStrengthGain+1)) / SubpointsPerPoint(STRAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_STR_Y-1);
ClipRect.iBottom = (SM_STR_Y-1) + SM_STATS_HEIGHT;
@@ -2634,7 +2634,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// WIS
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sWisdomGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sWisdomGain+1)) / SubpointsPerPoint(WISDOMAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sWisdomGain+1)) / SubpointsPerPoint(WISDOMAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_WIS_Y-1);
ClipRect.iBottom = (SM_WIS_Y-1) + SM_STATS_HEIGHT;
@@ -2646,7 +2646,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// MRK
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMarksmanshipGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMarksmanshipGain+1)) / SubpointsPerPoint(MARKAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMarksmanshipGain+1)) / SubpointsPerPoint(MARKAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MRKM_Y-1);
ClipRect.iBottom = (SM_MRKM_Y-1) + SM_STATS_HEIGHT;
@@ -2658,7 +2658,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// LDR
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sLeadershipGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sLeadershipGain+1)) / SubpointsPerPoint(LDRAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sLeadershipGain+1)) / SubpointsPerPoint(LDRAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_CHAR_Y-1);
ClipRect.iBottom = (SM_CHAR_Y-1) + SM_STATS_HEIGHT;
@@ -2670,7 +2670,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// MECH
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMechanicGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMechanicGain+1)) / SubpointsPerPoint(MECHANAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMechanicGain+1)) / SubpointsPerPoint(MECHANAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MECH_Y-1);
ClipRect.iBottom = (SM_MECH_Y-1) + SM_STATS_HEIGHT;
@@ -2682,7 +2682,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// EXPLO
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExplosivesGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExplosivesGain+1)) / SubpointsPerPoint(EXPLODEAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExplosivesGain+1)) / SubpointsPerPoint(EXPLODEAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_EXPL_Y-1);
ClipRect.iBottom = (SM_EXPL_Y-1) + SM_STATS_HEIGHT;
@@ -2694,7 +2694,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// MED
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMedicalGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMedicalGain+1)) / SubpointsPerPoint(MEDICALAMT,0);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMedicalGain+1)) / SubpointsPerPoint(MEDICALAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MED_Y-1);
ClipRect.iBottom = (SM_MED_Y-1) + SM_STATS_HEIGHT;
@@ -2706,7 +2706,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// EXPLEVEL
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExpLevelGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExpLevelGain+1)) / SubpointsPerPoint(EXPERAMT, gpSMCurrentMerc->stats.bExpLevel);
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExpLevelGain+1)) / SubpointsPerPoint(EXPERAMT, &gMercProfiles[gpSMCurrentMerc->ubProfile]);
ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_EXPLVL_Y-1);
ClipRect.iBottom = (SM_EXPLVL_Y-1) + SM_STATS_HEIGHT;
@@ -3373,7 +3373,7 @@ BOOLEAN HandleNailsVestFetish( SOLDIERTYPE *pSoldier, UINT32 uiHandPos, UINT16 u
else
{
// Do we have nothing or the leather vest or kevlar leather vest?
if ( Item[usReplaceItem].leatherjacket ||
if (ItemIsLeatherJacket(usReplaceItem) ||
usReplaceItem == COMPOUND18 ||
usReplaceItem == JAR_QUEEN_CREATURE_BLOOD )
{
@@ -4044,7 +4044,7 @@ void SMInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
if ( !InItemDescriptionBox( ) )
{
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpSMCurrentMerc->inv[ uiHandPos ].usItem].usItemClass == IC_GUN && (gpSMCurrentMerc->inv[ uiHandPos ])[uiHandPos]->data.gun.ubGunShotsLeft > 0 && !(Item[gpSMCurrentMerc->inv[ uiHandPos ].usItem].singleshotrocketlauncher) && !( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
if ( _KeyDown(SHIFT) && gpItemPointer == NULL && Item[gpSMCurrentMerc->inv[ uiHandPos ].usItem].usItemClass == IC_GUN && (gpSMCurrentMerc->inv[ uiHandPos ])[uiHandPos]->data.gun.ubGunShotsLeft > 0 && !ItemIsSingleShotRocketLauncher(gpSMCurrentMerc->inv[ uiHandPos ].usItem) && !( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
{
EmptyWeaponMagazine( &(gpSMCurrentMerc->inv[ uiHandPos ]), &gItemPointer, uiHandPos );
gpItemPointer = &gItemPointer;
@@ -7096,22 +7096,23 @@ void CheckForAndAddMercToTeamPanel( SOLDIERTYPE *pSoldier )
void CleanUpStack( OBJECTTYPE * pObj, OBJECTTYPE * pCursorObj )
{
INT16 bMaxPoints;
UINT16 usItem = pObj->usItem;
if ( !(Item[pObj->usItem].usItemClass & IC_AMMO || Item[pObj->usItem].usItemClass & IC_KIT || Item[pObj->usItem].usItemClass & IC_MEDKIT || Item[pObj->usItem].canteen || Item[pObj->usItem].gascan || Item[pObj->usItem].alcohol > 0.0f) )
if ( !(Item[usItem].usItemClass & IC_AMMO || Item[usItem].usItemClass & IC_KIT || Item[usItem].usItemClass & IC_MEDKIT || ItemIsCanteen(usItem) || ItemIsGascan(usItem) || Item[usItem].alcohol > 0.0f) )
{
return;
}
if ( Item[ pObj->usItem ].usItemClass & IC_AMMO )
if ( Item[ usItem ].usItemClass & IC_AMMO )
{
bMaxPoints = Magazine[ Item[ pObj->usItem ].ubClassIndex ].ubMagSize;
bMaxPoints = Magazine[ Item[ usItem ].ubClassIndex ].ubMagSize;
}
else
{
bMaxPoints = 100;
}
if ( pCursorObj && pCursorObj->usItem == pObj->usItem )
if ( pCursorObj && pCursorObj->usItem == usItem )
{
DistributeStatus(pCursorObj, pObj, bMaxPoints);
}
@@ -7120,13 +7121,13 @@ void CleanUpStack( OBJECTTYPE * pObj, OBJECTTYPE * pCursorObj )
// Flugente: one of the items on the stack might not be full. Make sure it is the first one, so the player can see what is missing at a glance
if ( pObj->ubNumberOfObjects > 1 )
{
if ( Item[pObj->usItem].usItemClass & IC_AMMO )
if ( Item[usItem].usItemClass & IC_AMMO )
{
UINT16 shots_first = (*pObj)[0]->data.ubShotsLeft;
(*pObj)[0]->data.ubShotsLeft = (*pObj)[pObj->ubNumberOfObjects - 1]->data.ubShotsLeft;
(*pObj)[pObj->ubNumberOfObjects - 1]->data.ubShotsLeft = shots_first;
}
else if ( Item[pObj->usItem].usItemClass & IC_MAPFILTER_KIT )
else if ( Item[usItem].usItemClass & IC_MAPFILTER_KIT )
{
INT16 status_first = (*pObj)[0]->data.objectStatus;
(*pObj)[0]->data.objectStatus = (*pObj)[pObj->ubNumberOfObjects - 1]->data.objectStatus;
+12 -10
View File
@@ -978,12 +978,12 @@ void PopupMovementMenu( UI_EVENT *pUIEvent )
}
else
{
if ( Item[pSoldier->inv[ HANDPOS ].usItem].toolkit )
if (ItemIsToolkit(pSoldier->inv[ HANDPOS ].usItem))
{
uiActionImages = TOOLKITACTIONC_IMAGES;
swprintf( zActionString, TacticalStr[ NOT_APPLICABLE_POPUPTEXT ] );
}
else if ( Item[pSoldier->inv[ HANDPOS ].usItem].wirecutters )
else if (ItemIsWirecutters(pSoldier->inv[ HANDPOS ].usItem))
{
uiActionImages = WIRECUTACTIONC_IMAGES;
swprintf( zActionString, TacticalStr[ NOT_APPLICABLE_POPUPTEXT ] );
@@ -2478,14 +2478,16 @@ BOOLEAN DrawCTHIndicator()
//////////////////////////////////
// Calculate Aperture
INT16 sX, sY;
// Calculate the center point of the shooter, in world coordinates.
FLOAT dStartX = (FLOAT) CenterX( gCTHDisplay.iShooterGridNo );
FLOAT dStartY = (FLOAT) CenterY( gCTHDisplay.iShooterGridNo );
ConvertGridNoToCenterCellXY(gCTHDisplay.iShooterGridNo, &sX, &sY);
FLOAT dStartX = (FLOAT) sX;
FLOAT dStartY = (FLOAT) sY;
// Calculate the center point of the target, in world coordinates.
FLOAT dEndX = (FLOAT) CenterX( gCTHDisplay.iTargetGridNo );
FLOAT dEndY = (FLOAT) CenterY( gCTHDisplay.iTargetGridNo );
ConvertGridNoToCenterCellXY(gCTHDisplay.iTargetGridNo, &sX, &sY);
FLOAT dEndX = (FLOAT) sX;
FLOAT dEndY = (FLOAT) sY;
// Calculate a delta: the difference between the shooter and target.
FLOAT dDeltaX = dEndX - dStartX;
@@ -6041,7 +6043,7 @@ void GetEnemyInfoString( SOLDIERTYPE* pSelectedSoldier, SOLDIERTYPE* pTargetSold
}
else
{ // show general name
if( Item[pTargetSoldier->inv[HEAD1POS].usItem].gasmask )
if(ItemIsGasmask(pTargetSoldier->inv[HEAD1POS].usItem))
wcscat( NameStr, TacticalStr[ GENERAL_INFO_MASK ] );
else if( Item[pTargetSoldier->inv[HEAD1POS].usItem].nightvisionrangebonus || Item[pTargetSoldier->inv[HEAD1POS].usItem].cavevisionrangebonus )
wcscat( NameStr, TacticalStr[ GENERAL_INFO_NVG ] );
@@ -6057,7 +6059,7 @@ void GetEnemyInfoString( SOLDIERTYPE* pSelectedSoldier, SOLDIERTYPE* pTargetSold
}
else
{ // show general name
if( Item[pTargetSoldier->inv[HEAD1POS].usItem].gasmask )
if(ItemIsGasmask(pTargetSoldier->inv[HEAD1POS].usItem))
wcscat( NameStr, TacticalStr[ GENERAL_INFO_MASK ] );
else if( Item[pTargetSoldier->inv[HEAD1POS].usItem].nightvisionrangebonus || Item[pTargetSoldier->inv[HEAD1POS].usItem].cavevisionrangebonus )
wcscat( NameStr, TacticalStr[ GENERAL_INFO_NVG ] );
@@ -6647,4 +6649,4 @@ INT16 GetBackgroundValue( UINT8 usProfile, UINT16 aNr )
}
return 0;
}
}
+6
View File
@@ -211,6 +211,11 @@ enum {
BG_MAX,
};
enum class BackgroundVectorTypes {
BG_DRUGUSE_TYPES,
BG_DRUGUSE_ITEMS,
};
typedef struct
{
UINT16 uiIndex;
@@ -220,6 +225,7 @@ typedef struct
UINT64 uiFlags; // this flagmask defines what special properties this background has (on/off behaviour)
INT16 value[BG_MAX]; // property values
std::map<BackgroundVectorTypes, std::vector<INT16>> valueVectors; // optional additional data
} BACKGROUND_VALUES;
#define NUM_BACKGROUND 500
+35 -19
View File
@@ -738,7 +738,7 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
switch( Item[ pItem->usItem ].usItemClass )
{
case IC_GUN:
if ( !Item[pItem->usItem].rocketlauncher )
if ( !ItemIsRocketLauncher(pItem->usItem) )
{
bWeaponClass *= -1;
}
@@ -873,7 +873,7 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC
pp->Inv[ i ][0]->data.gun.ubGunAmmoType = Magazine[Item[usAmmoIndex].ubClassIndex].ubAmmoType;
pp->Inv[ i ][0]->data.gun.usGunAmmoItem = usAmmoIndex;
if ( Item[usGunIndex].fingerprintid )
if (ItemHasFingerPrintID(usGunIndex))
{
pp->Inv[ i ][0]->data.ubImprintID = (NO_PROFILE + 1);
}
@@ -951,7 +951,7 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC
pp->Inv[ HANDPOS ].fFlags |= OBJECT_UNDROPPABLE;
// Rocket Rifles must come pre-imprinted, in case carrier gets killed without getting a shot off
if ( Item[usGunIndex].fingerprintid )
if (ItemHasFingerPrintID(usGunIndex))
{
pp->Inv[ HANDPOS ][0]->data.ubImprintID = (NO_PROFILE + 1);
}
@@ -2246,29 +2246,45 @@ void ChooseBombsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bBombClas
void ChooseLBEsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bLBEClass )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ChooseLBEsForSoldierCreateStruct");
//UINT16 i;
//INVTYPE *pItem;
//UINT16 usRandom;
UINT16 usItem = 0;
// CHRISL: If we're using the old inventory system, just return
if((UsingNewInventorySystem() == false))
return;
usItem = PickARandomItem( LBE, pp->ubSoldierClass, bLBEClass, FALSE );
UINT16 usItem = PickARandomItem( LBE, pp->ubSoldierClass, bLBEClass, FALSE );
if ( usItem > 0 )
{
CreateItem( usItem, (INT8)(80 + Random( 21 )), &gTempObject );
gTempObject.fFlags |= OBJECT_UNDROPPABLE;
// put backpacks into the backpack slot for LOBOT
if ((UsingNewInventorySystem()) && (Item[usItem].usItemClass & IC_LBEGEAR) && (LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass == BACKPACK))
auto isLBEgear = Item[usItem].usItemClass & IC_LBEGEAR;
if (isLBEgear)
{
pp->Inv[BPACKPOCKPOS] = gTempObject;
}
else
{
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
// put backpacks into the backpack slot for LOBOT
auto lbeClass = LoadBearingEquipment[Item[usItem].ubClassIndex].lbeClass;
if (lbeClass == BACKPACK && !pp->Inv[BPACKPOCKPOS].exists())
{
pp->Inv[BPACKPOCKPOS] = gTempObject;
return;
}
// same for pistol holster
if (lbeClass == THIGH_PACK)
{
if (!pp->Inv[LTHIGHPOCKPOS].exists())
{
pp->Inv[LTHIGHPOCKPOS] = gTempObject;
return;
}
if (!pp->Inv[RTHIGHPOCKPOS].exists())
{
pp->Inv[RTHIGHPOCKPOS] = gTempObject;
return;
}
}
}
// Couldn't find a specific pocket, just stuff it somewhere
PlaceObjectInSoldierCreateStruct( pp, &gTempObject );
}
}
@@ -3128,7 +3144,7 @@ void ReplaceExtendedGuns( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass )
{
usItem = pp->Inv[ uiLoop ].usItem;
if ( ( Item[ usItem ].usItemClass & IC_GUN ) && ExtendedGunListGun( usItem ) )
if ( ( Item[ usItem ].usItemClass & IC_GUN ) && ItemIsOnlyInTonsOfGuns( usItem ) )
{
if ( bSoldierClass == SOLDIER_CLASS_NONE )
{
@@ -3512,7 +3528,7 @@ UINT32 ItemFitness( OBJECTTYPE* pObj, UINT8 idx )
}
else if ( Item[ pObj->usItem ].usItemClass & IC_FACE )
{
if ( Item[ pObj->usItem ].gasmask )
if (ItemIsGasmask(pObj->usItem))
value = (*pObj)[idx]->data.objectStatus;
else if ( Item[ pObj->usItem ].hearingrangebonus )
{
@@ -4170,7 +4186,7 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI
else if ( Item[pWorldItem[ uiCount ].object.usItem].usItemClass & IC_FACE && (!si[SI_SIGHT].done || !si[SI_FACE2].done || !si[SI_FACE_SPARESIGHT].done || !si[SI_GASMASK].done) )
{
// gasmasks are reserved for a special slot and will only be worn if we do not have 2 face items. items that increase our vision (NVGs adn sungooggles) get to slot 1, everything else in 2
if ( Item[ pWorldItem[ uiCount ].object.usItem ].gasmask )
if (ItemIsGasmask(pWorldItem[ uiCount ].object.usItem))
EvaluateObjForItem( pWorldItem, pObj, uiCount, &si[SI_GASMASK] );
else if ( Item[ pWorldItem[ uiCount ].object.usItem ].nightvisionrangebonus > 0 )
{
@@ -4249,7 +4265,7 @@ void TakeMilitiaEquipmentfromSector( INT16 sMapX, INT16 sMapY, INT8 sMapZ, SOLDI
if ( fnd == launcherhelpmap.end() )
{
LauncherHelpStruct tmp;
tmp.fNeedsAmmo = !Item[pWorldItem[ uiCount ].object.usItem].singleshotrocketlauncher;
tmp.fNeedsAmmo = !ItemIsSingleShotRocketLauncher(pWorldItem[ uiCount ].object.usItem);
launcherhelpmap[ pWorldItem[ uiCount ].object.usItem ] = tmp;
}
}
+2 -2
View File
@@ -592,7 +592,7 @@ LBENODE* OBJECTTYPE::GetLBEPointer(unsigned int index)
}
bool OBJECTTYPE::exists()
bool OBJECTTYPE::exists() const
{
return(this && ubNumberOfObjects && usItem);
}
@@ -1595,7 +1595,7 @@ OBJECTTYPE& OBJECTTYPE::operator=(const OLD_OBJECTTYPE_101& src)
}
else if ( EXPLOSIVE_GUN( this->usItem ) )
{
if ( Item[this->usItem].singleshotrocketlauncher )
if (ItemIsSingleShotRocketLauncher(this->usItem))
{
(*this)[0]->data.gun.ubGunShotsLeft = 1;
}
+237 -254
View File
@@ -546,7 +546,7 @@ public:
bool operator==(OBJECTTYPE& compare);
bool operator==(const OBJECTTYPE& compare)const;
bool exists();
bool exists() const;
bool IsActiveLBE(unsigned int index);
bool HasAnyActiveLBEs(SOLDIERTYPE * pSoldier = NULL, UINT8 iter = 0);
LBENODE* GetLBEPointer(unsigned int index);
@@ -779,6 +779,98 @@ extern OBJECTTYPE gTempObject;
// extended flagmask to UINT64
#define EMPTY_BLOOD_BAG 0x0000000100000000 // this item is a empty blood bag
#define MEDICAL_SPLINT 0x0000000200000000 // this item is a medical splint that can be applied to some diseases
#define ITEM_damageable 0x0000000400000000
#define ITEM_repairable 0x0000000800000000
#define ITEM_waterdamages 0x0000001000000000
#define ITEM_metal 0x0000002000000000
#define ITEM_sinks 0x0000004000000000
#define ITEM_showstatus 0x0000008000000000
#define ITEM_hiddenaddon 0x0000010000000000
#define ITEM_twohanded 0x0000020000000000
#define ITEM_notbuyable 0x0000040000000000
#define ITEM_attachment 0x0000080000000000
#define ITEM_hiddenattachment 0x0000100000000000
#define ITEM_biggunlist 0x0000200000000000
#define ITEM_notineditor 0x0000400000000000
#define ITEM_defaultundroppable 0x0000800000000000
#define ITEM_unaerodynamic 0x0001000000000000
#define ITEM_electronic 0x0002000000000000
#define ITEM_cannon 0x0004000000000000
#define ITEM_rocketrifle 0x0008000000000000
#define ITEM_fingerprintid 0x0010000000000000
#define ITEM_metaldetector 0x0020000000000000
#define ITEM_gasmask 0x0040000000000000
#define ITEM_lockbomb 0x0080000000000000
#define ITEM_flare 0x0100000000000000
#define ITEM_grenadelauncher 0x0200000000000000
#define ITEM_mortar 0x0400000000000000
#define ITEM_duckbill 0x0800000000000000
#define ITEM_detonator 0x1000000000000000
#define ITEM_remotedetonator 0x2000000000000000
#define ITEM_hidemuzzleflash 0x4000000000000000
#define ITEM_rocketlauncher 0x8000000000000000
// New UINT64 Item Flag => usItemFlag2
#define ITEM_singleshotrocketlauncher 0x00000001
#define ITEM_brassknuckles 0x00000002
#define ITEM_crowbar 0x00000004
#define ITEM_glgrenade 0x00000008
#define ITEM_flakjacket 0x00000010
#define ITEM_leatherjacket 0x00000020
#define ITEM_batteries 0x00000040
#define ITEM_needsbatteries 0x00000080
#define ITEM_xray 0x00000100
#define ITEM_wirecutters 0x00000200
#define ITEM_toolkit 0x00000400
#define ITEM_firstaidkit 0x00000800
#define ITEM_medicalkit 0x00001000
#define ITEM_canteen 0x00002000
#define ITEM_jar 0x00004000
#define ITEM_canandstring 0x00008000
#define ITEM_marbles 0x00010000
#define ITEM_walkman 0x00020000
#define ITEM_remotetrigger 0x00040000
#define ITEM_robotremotecontrol 0x00080000
#define ITEM_camouflagekit 0x00100000
#define ITEM_locksmithkit 0x00200000
#define ITEM_mine 0x00400000
#define ITEM_antitankmine 0x00800000
#define ITEM_hardware 0x01000000
#define ITEM_medical 0x02000000
#define ITEM_gascan 0x04000000
#define ITEM_containsliquid 0x08000000
#define ITEM_rock 0x10000000
#define ITEM_thermaloptics 0x20000000
#define ITEM_scifi 0x40000000
#define ITEM_newinv 0x80000000
#define ITEM_DiseaseSystemExclusive 0x0000000100000000 // kitty: item exclusively available with disease feature
#define ITEM_barrel 0x0000000200000000 // item can be used on some guns as an exchange barrel
#define ITEM_tripwireactivation 0x0000000400000000 // item (mine) can be activated by nearby tripwire
#define ITEM_tripwire 0x0000000800000000 // item is tripwire
#define ITEM_directional 0x0000001000000000 // item is a directional mine/bomb (actual direction is set upon planting)
#define ITEM_blockironsight 0x0000002000000000 // 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)
#define ITEM_fAllowClimbing 0x0000004000000000 // JMich: BackpackClimb does item allow climbing while wearing it
#define ITEM_cigarette 0x0000008000000000 // Flugente: this item can be smoked
#define ITEM_fProvidesRobotCamo 0x0000010000000000 // rftr: robot attachments
#define ITEM_fProvidesRobotNightVision 0x0000020000000000 // rftr: robot attachments
#define ITEM_fProvidesRobotLaserBonus 0x0000040000000000 // rftr: robot attachments
// ----------------------------------------------------------------
@@ -947,163 +1039,48 @@ extern OBJECTTYPE gTempObject;
// autofiretohitbonus,
// bursttohitbonus
// bitflags for usLimitedToSystem
#define FOOD_SYSTEM_FLAG 1
#define DISEASE_SYSTEM_FLAG 2
typedef struct
{
UINT32 usItemClass;
UINT64 nasAttachmentClass; //CHRISL: Identify the class of attachment
UINT64 nasLayoutClass;
//Madd: Common Attachment Framework: attach items based on matching connection points rather than using the old long attachmentinfo method
UINT64 ulAvailableAttachmentPoint;
UINT64 ulAttachmentPoint;
UINT8 ubAttachToPointAPCost; // cost to attach to any matching point
UINT16 ubClassIndex;
UINT8 ubCursor;
INT8 bSoundType;
UINT8 ubGraphicType;
UINT16 ubGraphicNum;
UINT16 ubWeight; //2 units per kilogram; roughly 1 unit per pound
UINT8 ubPerPocket;
UINT16 ItemSize;
UINT16 usPrice;
UINT8 ubCoolness;
INT8 bReliability;
INT8 bRepairEase;
UINT16 fFlags;
UINT32 uiIndex; // added
CHAR16 szItemName[80]; //+1 for the null terminator //added
BOOLEAN damageable;
BOOLEAN repairable;
BOOLEAN waterdamages;
BOOLEAN metal;
BOOLEAN sinks;
BOOLEAN showstatus;
BOOLEAN hiddenaddon;
BOOLEAN twohanded;
BOOLEAN notbuyable;
BOOLEAN attachment;
BOOLEAN hiddenattachment;
BOOLEAN biggunlist;
BOOLEAN notineditor;
BOOLEAN defaultundroppable;
BOOLEAN unaerodynamic;
BOOLEAN electronic;
UINT8 inseparable; //Madd:Normally, an inseparable attachment can never be removed.
//But now we will make it so that these items can be replaced, but still not removed directly.
//0 = removeable (as before)
//1 = inseparable (as before)
//2 = inseparable, but replaceable
CHAR16 szLongItemName[80];
CHAR16 szItemDesc[400];
CHAR16 szBRName[80];
CHAR16 szBRDesc[400];
//TODO: quest items, boosters, money
// special item/attachment functions:
BOOLEAN cannon;
BOOLEAN rocketrifle;
BOOLEAN fingerprintid;
BOOLEAN metaldetector;
BOOLEAN gasmask;
BOOLEAN lockbomb;
BOOLEAN flare;
INT16 percentnoisereduction;
INT16 bipod;
INT16 tohitbonus;
INT16 bestlaserrange;
INT16 rangebonus;
INT16 percentrangebonus;
INT16 aimbonus;
INT16 minrangeforaimbonus;
INT16 percentapreduction;
INT16 percentstatusdrainreduction;
BOOLEAN grenadelauncher;
BOOLEAN mortar;
BOOLEAN duckbill;
BOOLEAN detonator;
BOOLEAN remotedetonator;
BOOLEAN hidemuzzleflash;
BOOLEAN rocketlauncher;
BOOLEAN singleshotrocketlauncher;
UINT16 discardedlauncheritem;
BOOLEAN brassknuckles;
//*** ddd UINT16 bloodieditem;
INT16 bloodieditem;
BOOLEAN crowbar;
BOOLEAN glgrenade;
BOOLEAN flakjacket;
INT16 hearingrangebonus;
INT16 visionrangebonus;
INT16 nightvisionrangebonus;
INT16 dayvisionrangebonus;
INT16 cavevisionrangebonus;
INT16 brightlightvisionrangebonus;
INT16 itemsizebonus;
BOOLEAN leatherjacket;
BOOLEAN batteries;
BOOLEAN needsbatteries;
BOOLEAN xray;
BOOLEAN wirecutters;
BOOLEAN toolkit;
BOOLEAN firstaidkit;
BOOLEAN medicalkit;
BOOLEAN canteen;
BOOLEAN jar;
BOOLEAN canandstring;
BOOLEAN marbles;
BOOLEAN walkman;
BOOLEAN remotetrigger;
BOOLEAN robotremotecontrol;
BOOLEAN camouflagekit;
BOOLEAN locksmithkit;
BOOLEAN mine;
BOOLEAN antitankmine;
FLOAT alcohol;
BOOLEAN hardware;
BOOLEAN medical;
BOOLEAN gascan;
BOOLEAN containsliquid;
BOOLEAN rock;
INT16 damagebonus;
INT16 meleedamagebonus;
INT16 magsizebonus;
INT16 percentautofireapreduction;
INT16 autofiretohitbonus;
INT16 APBonus;
INT16 rateoffirebonus;
INT16 burstsizebonus;
INT16 bursttohitbonus;
INT16 percentreadytimeapreduction;
INT16 bulletspeedbonus;
BOOLEAN thermaloptics;
UINT8 percenttunnelvision;
INT16 percentreloadtimeapreduction;
INT16 percentburstfireapreduction;
INT16 camobonus;
INT16 stealthbonus;
INT16 urbanCamobonus;
INT16 desertCamobonus;
INT16 snowCamobonus;
BOOLEAN scifi; // item only available in scifi mode
BOOLEAN newinv; // item only available in new inventory mode
UINT8 ubAttachmentSystem; //Item availability per attachment system: 0 = both, 1 = OAS, 2 = NAS
CHAR16 szItemName[80]; //+1 for the null terminator //added
CHAR16 szLongItemName[80];
CHAR16 szBRName[80];
UINT16 defaultattachments[MAX_DEFAULT_ATTACHMENTS]; //Need more default attachments, chose an array to do so. (no vector / list just to keep this all plain data)
UINT64 nasAttachmentClass; //CHRISL: Identify the class of attachment
UINT64 nasLayoutClass;
UINT64 ulAvailableAttachmentPoint;
UINT64 ulAttachmentPoint;
UINT64 usItemFlag; // bitflags to store various item properties (better than introducing 64 BOOLEAN values). If I only had thought of this earlier....
UINT64 usItemFlag2; // bitflags to store various item properties
UINT32 uiIndex;
UINT32 usItemClass;
UINT32 attachmentclass; // attachmentclass used
UINT32 drugtype; // this flagmask determines what different components are used in a drug, which results in different effects
UINT32 foodtype;
UINT32 usActionItemFlag; // Flugente: a flag that is necessary for transforming action items to objects with new abilities (for now, tripwire networks and directional explosives)
UINT32 clothestype; // Flugente: clothes type that 'links' to an entry in Clothes.xml
//zilpin: pellet spread patterns externalized in XML
INT32 spreadPattern;
FLOAT alcohol;
// HEADROCK HAM 4: New modifiers that do not require a stance array, since they affect the gun objectively, not
// subjectively.
FLOAT RecoilModifierX;
FLOAT RecoilModifierY;
FLOAT scopemagfactor;
FLOAT projectionfactor;
FLOAT usOverheatingCooldownFactor; // every turn/5 seconds, a gun's temperature is lowered by this amount
FLOAT overheatTemperatureModificator; // percentage modifier of heat a shot generates (read from attachments)
FLOAT overheatCooldownModificator; // percentage modifier of cooldown amount (read from attachments, applies to guns & barrels)
FLOAT overheatJamThresholdModificator; // percentage modifier of a gun's jam threshold (read from attachments)
FLOAT overheatDamageThresholdModificator; // percentage modifier of a gun's damage threshold (read from attachments)
FLOAT dirtIncreaseFactor; // Flugente: advanced repair/dirt system. One shot causes this much dirt on a gun
FLOAT fRobotDamageReductionModifier; // rftr: robot attachments
// HEADROCK HAM 4: New variable arrays for the New CTH system.
INT16 flatbasemodifier[3];
INT16 percentbasemodifier[3];
@@ -1116,114 +1093,98 @@ typedef struct
INT16 counterforceaccuracymodifier[3];
INT16 targettrackingmodifier[3];
INT16 aimlevelsmodifier[3];
// HEADROCK HAM 4: New modifiers that do not require a stance array, since they affect the gun objectively, not
// subjectively.
FLOAT RecoilModifierX;
FLOAT RecoilModifierY;
//Madd: Common Attachment Framework: attach items based on matching connection points rather than using the old long attachmentinfo method
UINT16 ubClassIndex;
UINT16 ubGraphicNum;
UINT16 ubWeight; //2 units per kilogram; roughly 1 unit per pound
UINT16 ItemSize;
UINT16 usPrice;
UINT16 discardedlauncheritem;
UINT16 randomitem; // Flugente: a link to RandomItemsClass.xml. Out of such an item, a random object is created, depending on the entries in the xml
UINT16 usBuddyItem; // Flugente: item is connected to another item. Type of connection depends on item specifics
UINT16 usRiotShieldStrength; // Flugente: riot shields. strength of shield
UINT16 usRiotShieldGraphic; // Flugente: riot shields. graphic of shield (when deployed in tactical, taken from Tilecache/riotshield.sti)
INT16 percentnoisereduction;
INT16 bipod;
INT16 tohitbonus;
INT16 bestlaserrange;
INT16 rangebonus;
INT16 percentrangebonus;
INT16 aimbonus;
INT16 minrangeforaimbonus;
INT16 percentapreduction;
INT16 percentstatusdrainreduction;
INT16 bloodieditem;
INT16 hearingrangebonus;
INT16 visionrangebonus;
INT16 nightvisionrangebonus;
INT16 dayvisionrangebonus;
INT16 cavevisionrangebonus;
INT16 brightlightvisionrangebonus;
INT16 itemsizebonus;
INT16 damagebonus;
INT16 meleedamagebonus;
INT16 magsizebonus;
INT16 percentautofireapreduction;
INT16 autofiretohitbonus;
INT16 APBonus;
INT16 rateoffirebonus;
INT16 burstsizebonus;
INT16 bursttohitbonus;
INT16 percentreadytimeapreduction;
INT16 bulletspeedbonus;
INT16 percentreloadtimeapreduction;
INT16 percentburstfireapreduction;
INT16 camobonus;
INT16 stealthbonus;
INT16 urbanCamobonus;
INT16 desertCamobonus;
INT16 snowCamobonus;
INT16 PercentRecoilModifier;
INT16 percentaccuracymodifier;
FLOAT scopemagfactor;
FLOAT projectionfactor;
BOOLEAN speeddot;
INT16 usSpotting; // Flugente: spotting effectiveness
INT16 sBackpackWeightModifier; // JMich: BackpackClimb modifier to weight calculation to climb.
INT16 sFireResistance;
// Flugente
BOOLEAN barrel; // item can be used on some guns as an exchange barrel
FLOAT usOverheatingCooldownFactor; // every turn/5 seconds, a gun's temperature is lowered by this amount
FLOAT overheatTemperatureModificator; // percentage modifier of heat a shot generates (read from attachments)
FLOAT overheatCooldownModificator; // percentage modifier of cooldown amount (read from attachments, applies to guns & barrels)
FLOAT overheatJamThresholdModificator; // percentage modifier of a gun's jam threshold (read from attachments)
FLOAT overheatDamageThresholdModificator; // percentage modifier of a gun's damage threshold (read from attachments)
UINT8 ubAttachToPointAPCost; // cost to attach to any matching point
UINT8 ubCursor;
UINT8 ubGraphicType;
UINT8 ubPerPocket;
UINT8 ubCoolness;
UINT8 percenttunnelvision;
UINT8 ubAttachmentSystem; //Item availability per attachment system: 0 = both, 1 = OAS, 2 = NAS
UINT8 CrowbarModifier;
UINT8 DisarmModifier;
UINT8 usHackingModifier;
UINT8 usBurialModifier; // Flugente: a modifier for burial effectiveness
UINT8 usDamageChance; // Flugente: advanced repair/dirt system. Chance that damage to the status will also damage the repair threshold
UINT8 usFlashLightRange; // Flugente: range of a flashlight (an item with usFlashLightRange > 0 is deemed a flashlight)
UINT8 usItemChoiceTimeSetting; // Flugente: determine wether the AI should pick this item for its choices only at certain times
UINT8 ubSleepModifier; // silversurfer: item provides breath regeneration bonus while resting
UINT8 usPortionSize; // Flugente: for consumables: how much of this item is consumed at once
UINT8 usAdministrationModifier; // Flugente: a modifier for administration effectiveness
UINT8 inseparable; //Madd:Normally, an inseparable attachment can never be removed.
//But now we will make it so that these items can be replaced, but still not removed directly.
//0 = removeable (as before)
//1 = inseparable (as before)
//2 = inseparable, but replaceable
UINT32 attachmentclass; // attachmentclass used
BOOLEAN tripwireactivation; // item (mine) can be activated by nearby tripwire
BOOLEAN tripwire; // item is tripwire
BOOLEAN directional; // item is a directional mine/bomb (actual direction is set upon planting)
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)
UINT64 usItemFlag; // bitflags to store various item properties (better than introducing 32 BOOLEAN values). If I only had thought of this earlier....
// Flugente: food type
UINT32 foodtype;
//JMich_SkillModifiers: Adding new skill modifiers
INT8 LockPickModifier;
UINT8 CrowbarModifier;
UINT8 DisarmModifier;
INT8 RepairModifier;
// Flugente: a modifier to hacking
UINT8 usHackingModifier;
// Flugente: a modifier for burial effectiveness
UINT8 usBurialModifier;
// Flugente: advanced repair/dirt system
UINT8 usDamageChance; // chance that damage to the status will also damage the repair threshold
FLOAT dirtIncreaseFactor; // one shot causes this much dirt on a gun
// Flugente: a flag that is necessary for transforming action items to objects with new abilities (for now, tripwire networks and directional explosives)
UINT32 usActionItemFlag;
// Flugente: clothes type that 'links' to an entry in Clothes.xml
UINT32 clothestype;
// Flugente: a link to RandomItemsClass.xml. Out of such an item, a random object is created, depending on the entries in the xml
UINT16 randomitem;
INT8 randomitemcoolnessmodificator; // alters the allowed maximum coolness a random item can have
// Flugente: range of a flashlight (an item with usFlashLightRange > 0 is deemed a flashlight)
UINT8 usFlashLightRange;
// Flugente: determine wether the AI should pick this item for its choices only at certain times
UINT8 usItemChoiceTimeSetting;
// Flugente: item is connected to another item. Type of connection depends on item specifics
UINT16 usBuddyItem;
// silversurfer: item provides breath regeneration bonus while resting
UINT8 ubSleepModifier;
// Flugente: spotting effectiveness
INT16 usSpotting;
//JMich.BackpackClimb
INT16 sBackpackWeightModifier; //modifier to weight calculation to climb.
BOOLEAN fAllowClimbing; //does item allow climbing while wearing it
BOOLEAN cigarette; // Flugente: this item can be smoked
UINT8 usPortionSize; // Flugente: for consumables: how much of this item is consumed at once
// Flugente: riot shields
UINT16 usRiotShieldStrength; // strength of shield
UINT16 usRiotShieldGraphic; // graphic of shield (when deployed in tactical, taken from Tilecache/riotshield.sti)
// Flugente: fire resistance
INT16 sFireResistance;
// Flugente: a modifier for administration effectiveness
UINT8 usAdministrationModifier;
// rftr: robot attachments
FLOAT fRobotDamageReductionModifier;
INT8 bRobotStrBonus;
INT8 bRobotAgiBonus;
INT8 bRobotDexBonus;
INT8 bRobotTargetingSkillGrant;
INT8 bRobotChassisSkillGrant;
INT8 bRobotUtilitySkillGrant;
BOOLEAN fProvidesRobotCamo;
BOOLEAN fProvidesRobotNightVision;
BOOLEAN fProvidesRobotLaserBonus;
//shadooow: bitflag controlling what system needs to be in play for item to appear
UINT8 usLimitedToSystem;
// rftr: the progress bounds that allow a transport group to drop an item
INT8 iTransportGroupMinProgress;
INT8 iTransportGroupMaxProgress;
INT8 bSoundType;
INT8 bReliability;
INT8 bRepairEase;
INT8 LockPickModifier;
INT8 RepairModifier;
INT8 randomitemcoolnessmodificator; // Flugente: a link to RandomItemsClass.xml. alters the allowed maximum coolness a random item can have
INT8 bRobotStrBonus; // rftr: robot attachments
INT8 bRobotAgiBonus; // rftr: robot attachments
INT8 bRobotDexBonus; // rftr: robot attachments
INT8 bRobotTargetingSkillGrant; // rftr: robot attachments
INT8 bRobotChassisSkillGrant; // rftr: robot attachments
INT8 bRobotUtilitySkillGrant; // rftr: robot attachments
INT8 iTransportGroupMinProgress; // rftr: the progress bounds that allow a transport group to drop an item
INT8 iTransportGroupMaxProgress; // rftr: the progress bounds that allow a transport group to drop an item
} INVTYPE;
@@ -1724,9 +1685,30 @@ typedef enum
MAXITEMS = 16001
} ITEMDEFINE;
struct AttachmentStruct
{
UINT16 attachmentIndex;
UINT16 itemIndex;
UINT16 APCost;
UINT16 NASOnly;
bool operator<(const AttachmentStruct& a) const
{
bool result = false;
if (attachmentIndex < a.attachmentIndex)
result = true;
else if (attachmentIndex == a.attachmentIndex)
result = itemIndex < a.itemIndex;
return result;
}
};
// Flugente: in order not to loop over MAXITEMS items if we only have a few thousand, remember the actual number of items in the xml
extern UINT32 gMAXITEMS_READ;
extern UINT32 gMAXAMMOTYPES_READ;
extern UINT32 gMAXATTACHMENTS_READ;
extern UINT32 gMAXLAUNCHABLES_READ;
/* CHRISL: Arrays to track ic group information. These allow us to determine which LBE slots control which pockets and
what LBE class the pockets are.*/
@@ -1781,7 +1763,8 @@ const INT16 icDefault[NUM_INV_SLOTS] = {
#define MAXATTACHMENTS 60000
extern INVTYPE Item[MAXITEMS];
extern UINT16 Attachment[MAXATTACHMENTS][4];
extern AttachmentStruct Attachment[MAXATTACHMENTS];
extern std::multimap<UINT16, AttachmentStruct> AttachmentBackmap;
//WarmSteel - Here we have some definitions for NAS
typedef struct
+322 -222
View File
File diff suppressed because it is too large Load Diff
+75 -4
View File
@@ -179,8 +179,78 @@ BOOLEAN ValidAttachmentClass( UINT16 usAttachment, UINT16 usItem );
//Determines if it is possible to equip this weapon with this ammo.
BOOLEAN ValidAmmoType( UINT16 usItem, UINT16 usAmmoType );
//Determines if this item is a two handed item.
BOOLEAN TwoHandedItem( UINT16 usItem );
BOOLEAN ItemIsDamageable(UINT16 usItem);
BOOLEAN ItemIsRepairable(UINT16 usItem);
BOOLEAN ItemIsDamagedByWater(UINT16 usItem);
BOOLEAN ItemIsMetal(UINT16 usItem);
BOOLEAN ItemSinks(UINT16 usItem);
BOOLEAN ItemIsTwoHanded(UINT16 usItem);
BOOLEAN ItemIsHiddenAddon(UINT16 usItem);
BOOLEAN ItemIsNotBuyable(UINT16 usItem);
BOOLEAN ItemIsAttachment(UINT16 usItem);
BOOLEAN ItemIsHiddenAttachment(UINT16 usItem);
BOOLEAN ItemIsOnlyInTonsOfGuns(UINT16 usItem);
BOOLEAN ItemIsNotInEditor(UINT16 usItem);
BOOLEAN ItemIsUndroppableByDefault(UINT16 usItem);
BOOLEAN ItemIsUnaerodynamic(UINT16 usItem);
BOOLEAN ItemIsElectronic(UINT16 usItem);
BOOLEAN ItemIsCannon(UINT16 usItem);
BOOLEAN ItemIsRocketRifle(UINT16 usItem);
BOOLEAN ItemHasFingerPrintID(UINT16 usItem);
BOOLEAN ItemIsMetalDetector(UINT16 usItem);
BOOLEAN ItemIsGasmask(UINT16 usItem);
BOOLEAN ItemIsLockBomb(UINT16 usItem);
BOOLEAN ItemIsFlare(UINT16 usItem);
BOOLEAN ItemIsGrenadeLauncher(UINT16 usItem);
BOOLEAN ItemIsMortar(UINT16 usItem);
BOOLEAN ItemIsDuckbill(UINT16 usItem);
BOOLEAN ItemIsDetonator(UINT16 usItem);
BOOLEAN ItemIsRemoteDetonator(UINT16 usItem);
BOOLEAN ItemHasHiddenMuzzleFlash(UINT16 usItem);
BOOLEAN ItemIsRocketLauncher(UINT16 usItem);
BOOLEAN ItemIsSingleShotRocketLauncher(UINT16 usItem);
BOOLEAN ItemIsBrassKnuckles(UINT16 usItem);
BOOLEAN ItemIsCrowbar(UINT16 usItem);
BOOLEAN ItemIsGLgrenade(UINT16 usItem);
BOOLEAN ItemIsFlakJacket(UINT16 usItem);
BOOLEAN ItemIsLeatherJacket(UINT16 usItem);
BOOLEAN ItemIsBatteries(UINT16 usItem);
BOOLEAN ItemNeedsBatteries(UINT16 usItem);
BOOLEAN ItemHasXRay(UINT16 usItem);
BOOLEAN ItemIsWirecutters(UINT16 usItem);
BOOLEAN ItemIsToolkit(UINT16 usItem);
BOOLEAN ItemIsFirstAidKit(UINT16 usItem);
BOOLEAN ItemIsMedicalKit(UINT16 usItem);
BOOLEAN ItemIsCanteen(UINT16 usItem);
BOOLEAN ItemIsJar(UINT16 usItem);
BOOLEAN ItemIsCanAndString(UINT16 usItem);
BOOLEAN ItemIsMarbles(UINT16 usItem);
BOOLEAN ItemIsWalkman(UINT16 usItem);
BOOLEAN ItemIsRemoteTrigger(UINT16 usItem);
BOOLEAN ItemIsRobotRemote(UINT16 usItem);
BOOLEAN ItemIsCamoKit(UINT16 usItem);
BOOLEAN ItemIsLocksmithKit(UINT16 usItem);
BOOLEAN ItemIsMine(UINT16 usItem);
BOOLEAN ItemIsATMine(UINT16 usItem);
BOOLEAN ItemIsHardware(UINT16 usItem);
BOOLEAN ItemIsMedical(UINT16 usItem);
BOOLEAN ItemIsGascan(UINT16 usItem);
BOOLEAN ItemContainsLiquid(UINT16 usItem);
BOOLEAN ItemIsRock(UINT16 usItem);
BOOLEAN ItemIsThermalOptics(UINT16 usItem);
BOOLEAN ItemIsOnlyInScifi(UINT16 usItem);
BOOLEAN ItemIsOnlyInNIV(UINT16 usItem);
BOOLEAN ItemIsBarrel(UINT16 usItem);
BOOLEAN ItemHasTripwireActivation(UINT16 usItem);
BOOLEAN ItemIsTripwire(UINT16 usItem);
BOOLEAN ItemIsDirectional(UINT16 usItem);
BOOLEAN ItemBlocksIronsight(UINT16 usItem);
BOOLEAN ItemAllowsClimbing(UINT16 usItem);
BOOLEAN ItemIsCigarette(UINT16 usItem);
BOOLEAN ItemIsOnlyInDisease(UINT16 usItem);
BOOLEAN ItemProvidesRobotCamo(UINT16 usItem);
BOOLEAN ItemProvidesRobotNightvision(UINT16 usItem);
BOOLEAN ItemProvidesRobotLaserBonus(UINT16 usItem);
//Existing functions without header def's, added them here, just incase I'll need to call
//them from the editor.
@@ -222,7 +292,6 @@ UINT8 ConvertObjectTypeMoneyValueToProfileMoneyValue( UINT32 uiMoneyAmount );
BOOLEAN CheckForChainReaction( UINT16 usItem, INT16 bStatus, INT16 bDamage, BOOLEAN fOnGround );
BOOLEAN ItemIsLegal( UINT16 usItemIndex, BOOLEAN fIgnoreCoolness = FALSE );
BOOLEAN ExtendedGunListGun( UINT16 usGun );
UINT16 StandardGunListReplacement( UINT16 usGun );
UINT16 FindReplacementMagazine( UINT8 ubCalibre, UINT16 ubMagSize, UINT8 ubAmmoType);
UINT16 FindReplacementMagazineIfNecessary( UINT16 usOldGun, UINT16 usOldAmmo, UINT16 usNewGun );
@@ -497,7 +566,8 @@ UINT64 GetAvailableAttachmentPoint ( OBJECTTYPE * pObject, UINT8 subObject );
void CheckBombSpecifics( OBJECTTYPE * pObj, INT8* detonatortype, INT8* setting, INT8* defusefrequency );
// Flugente: check for specific flags
BOOLEAN HasItemFlag( UINT16 usItem, UINT64 aFlag );
BOOLEAN HasItemFlag(UINT16 usItem, UINT64 aFlag);
BOOLEAN HasItemFlag2(UINT16 usItem, UINT64 aFlag);
// Flugente: get first item number that has this flag. Use with caution, as we search in all items
BOOLEAN GetFirstItemWithFlag( UINT16* pusItem, UINT64 aFlag );
@@ -568,6 +638,7 @@ INT32 GetPercentRangeBonus( OBJECTTYPE * pObj );
UINT8 GetInventorySleepModifier( SOLDIERTYPE *pSoldier );
void AttachDefaultAttachments(OBJECTTYPE *pObj, BOOLEAN fAllDefaultAttachments=TRUE);//dnl ch75 261013
BOOLEAN FindAttachmentRange(UINT16 usAttachment, UINT32* pStartIndex, UINT32* pEndIndex);
// Flugente: is this object useable by militia?
BOOLEAN ObjectIsMilitiaRelevant( OBJECTTYPE *pObj );
+4 -3
View File
@@ -669,7 +669,9 @@ void HandleDoorTrap( SOLDIERTYPE * pSoldier, DOOR * pDoor )
{
case EXPLOSION:
// cause damage as a regular hand grenade
IgniteExplosion( NOBODY, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 25, pSoldier->sGridNo, HAND_GRENADE, 0 );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
IgniteExplosion( NOBODY, sX, sY, 25, pSoldier->sGridNo, HAND_GRENADE, 0 );
break;
case SIREN:
@@ -760,8 +762,7 @@ BOOLEAN AttemptToBlowUpLock(SOLDIERTYPE * pSoldier, DOOR * pDoor)
sGridNo = pDoor->sGridNo;
// Get sX, sy;
sX = CenterX(sGridNo);
sY = CenterY(sGridNo);
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
// Get Z position, based on orientation....
sZ = 20;
+101 -82
View File
@@ -2380,12 +2380,15 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
UINT8 ubNumberOfTiles = pBase->pDBStructureRef->pDBStructure->ubNumberOfTiles;
INT32 sStructGridNo;
INT16 sX, sY, sX2, sY2;
ConvertGridNoToCenterCellXY(pStartSoldier->sGridNo, &sX, &sY);
// loop through all tiles
for (UINT8 ubLoop = BASE_TILE; ubLoop < ubNumberOfTiles; ubLoop++)
{
sStructGridNo = AddPosRelToBase(pBase->sGridNo, ppTile[ubLoop]);
if( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( sStructGridNo ), (FLOAT) CenterY( sStructGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) )
ConvertGridNoToCenterCellXY(sStructGridNo, &sX2, &sY2);
if( LineOfSightTest( (FLOAT) sX, (FLOAT) sY, dStartZPos, (FLOAT) sX2, (FLOAT) sY2, dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) )
{
return( TRUE );
}
@@ -2393,14 +2396,18 @@ INT32 SoldierToSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE
return( FALSE );
}
return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) );
INT16 sX, sY, sX2, sY2;
ConvertGridNoToCenterCellXY(pStartSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(pEndSoldier->sGridNo, &sX2, &sY2);
return( LineOfSightTest( (FLOAT) sX, (FLOAT) sY, dStartZPos, (FLOAT) sX2, (FLOAT) sY2, dEndZPos, iTileSightLimit, bAware, fSmell, NULL, adjustForSight, cthCalc ) );
}
INT32 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT32 sEndGridNo )
{
// figure out if there is a SINGLE window between the looker and target
FLOAT dStartZPos, dEndZPos;
INT16 sXPos, sYPos;
INT16 sX, sY, sX2, sY2;
INT32 sWindowGridNo = NOWHERE;
INT32 iRet;
@@ -2413,24 +2420,23 @@ INT32 SoldierToLocationWindowTest( SOLDIERTYPE * pStartSoldier, INT32 sEndGridNo
dStartZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[pStartSoldier->sGridNo].sHeight );
dEndZPos = dStartZPos;
ConvertGridNoToXY( sEndGridNo, &sXPos, &sYPos );
sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
ConvertGridNoToCenterCellXY(pStartSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(sEndGridNo, &sX2, &sY2);
//ADB changed from 255 to 511 to handle new LOS test
// We don't want to consider distance limits here so pass in tile sight limit of 255( + 256)
// and consider trees as little as possible
iRet = LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, 511, TRUE, FALSE, &sWindowGridNo );
iRet = LineOfSightTest( (FLOAT) sX, (FLOAT) sY, dStartZPos, (FLOAT) sX2, (FLOAT) sY2, dEndZPos, 511, TRUE, FALSE, &sWindowGridNo );
return( sWindowGridNo );
}
INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32 sGridNo, INT8 bLevel, INT8 bCubeLevel, INT8 bAware, int iTileSightLimit, bool adjustForSight )
{
FLOAT dStartZPos, dEndZPos;
INT16 sXPos, sYPos;
UINT16 ubTargetID;
BOOLEAN fOk;
FLOAT dStartZPos, dEndZPos;
INT16 sXPos, sYPos;
UINT16 ubTargetID;
BOOLEAN fOk;
CHECKF( pStartSoldier );
@@ -2457,9 +2463,6 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32 sGr
dEndZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ sGridNo ].sHeight );
}
ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );
sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
if (iTileSightLimit == CALC_FROM_ALL_DIRS || iTileSightLimit == CALC_FROM_WANTED_DIR) {
iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, iTileSightLimit );
@@ -2468,14 +2471,17 @@ INT32 SoldierTo3DLocationLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32 sGr
iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, CALC_FROM_ALL_DIRS );
}
return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, bAware, HasThermalOptics( pStartSoldier), NULL, adjustForSight ) );
ConvertGridNoToCenterCellXY(pStartSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(sGridNo, &sX2, &sY2);
return( LineOfSightTest( (FLOAT) sX, (FLOAT) sY, dStartZPos, (FLOAT) sX2, (FLOAT) sY2, dEndZPos, iTileSightLimit, bAware, HasThermalOptics( pStartSoldier), NULL, adjustForSight ) );
}
INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32 sGridNo, INT8 bLevel, INT8 bStance, INT8 bAware, int iTileSightLimit )
{
FLOAT dStartZPos, dEndZPos;
INT16 sXPos, sYPos;
BOOLEAN fOk;
FLOAT dStartZPos, dEndZPos;
INT16 endXPos, endYPos, startXPos, startYPos;
BOOLEAN fOk;
CHECKF( pStartSoldier );
@@ -2504,10 +2510,6 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32
}
ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );
sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
if (iTileSightLimit == CALC_FROM_ALL_DIRS || iTileSightLimit == CALC_FROM_WANTED_DIR) {
iTileSightLimit = pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, iTileSightLimit );
}
@@ -2515,13 +2517,15 @@ INT32 SoldierToVirtualSoldierLineOfSightTest( SOLDIERTYPE * pStartSoldier, INT32
iTileSightLimit = 255 + pStartSoldier->GetMaxDistanceVisible( sGridNo, bLevel, CALC_FROM_ALL_DIRS );
}
return( LineOfSightTest( (FLOAT) CenterX( pStartSoldier->sGridNo ), (FLOAT) CenterY( pStartSoldier->sGridNo ), dStartZPos, (FLOAT) sXPos, (FLOAT) sYPos, dEndZPos, iTileSightLimit, bAware, HasThermalOptics( pStartSoldier), NULL, false ) );
ConvertGridNoToCenterCellXY(pStartSoldier->sGridNo, &startXPos, &startYPos);
ConvertGridNoToCenterCellXY(sGridNo, &endXPos, &endYPos);
return(LineOfSightTest((FLOAT)startXPos, (FLOAT)startYPos, dStartZPos, (FLOAT)endXPos, (FLOAT)endYPos, dEndZPos, iTileSightLimit, bAware, HasThermalOptics(pStartSoldier), NULL, false));
}
INT32 LocationToLocationLineOfSightTest( INT32 sStartGridNo, INT8 bStartLevel, INT32 sEndGridNo, INT8 bEndLevel, INT8 bAware, int iTileSightLimit, FLOAT dStartPos, FLOAT dEndPos )
{
FLOAT dStartZPos, dEndZPos;
INT16 sStartXPos, sStartYPos, sEndXPos, sEndYPos;
FLOAT dStartZPos, dEndZPos;
INT16 sStartXPos, sStartYPos, sEndXPos, sEndYPos;
// Bob: prevent access violation
if (sStartGridNo < 0) {
@@ -2544,19 +2548,11 @@ INT32 LocationToLocationLineOfSightTest( INT32 sStartGridNo, INT8 bStartLevel, I
// add in ground height
dStartZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ sStartGridNo ].sHeight );
ConvertGridNoToXY( sStartGridNo, &sStartXPos, &sStartYPos );
sStartXPos = sStartXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sStartYPos = sStartYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
// sevenfm: use height argument
dEndZPos = dEndPos + bEndLevel * HEIGHT_UNITS;
// add in ground height
dEndZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[ sEndGridNo ].sHeight );
ConvertGridNoToXY( sEndGridNo, &sEndXPos, &sEndYPos );
sEndXPos = sEndXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sEndYPos = sEndYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
if (iTileSightLimit == CALC_FROM_ALL_DIRS || iTileSightLimit == CALC_FROM_WANTED_DIR)
{
iTileSightLimit = MaxNormalDistanceVisible();
@@ -2565,6 +2561,10 @@ INT32 LocationToLocationLineOfSightTest( INT32 sStartGridNo, INT8 bStartLevel, I
{
iTileSightLimit = 255 + MaxNormalDistanceVisible();
}
ConvertGridNoToCenterCellXY(sStartGridNo, &sStartXPos, &sStartYPos);
ConvertGridNoToCenterCellXY(sEndGridNo, &sEndXPos, &sEndYPos);
return( LineOfSightTest( (FLOAT)sStartXPos, (FLOAT)sStartYPos, dStartZPos, (FLOAT) sEndXPos, (FLOAT) sEndYPos, dEndZPos, iTileSightLimit, bAware, FALSE, NULL ) );
}
@@ -2931,20 +2931,24 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend
// Flugente: we measure the distance of the bullet's location to the location of the soldier, and to the 2 gridnos his head and leg occupy
// From this we can decide what body part was hit
FLOAT bodycenterX = (FLOAT)CenterX( pTarget->sGridNo );
FLOAT bodycenterY = (FLOAT)CenterY( pTarget->sGridNo );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pTarget->sGridNo, &sX, &sY);
FLOAT bodycenterX = (FLOAT) sX;
FLOAT bodycenterY = (FLOAT) sY;
FLOAT difftobodycenter = sqrt( (bodycenterX - x) * (bodycenterX - x) + (bodycenterY - y) * (bodycenterY - y) );
INT32 viewdirectiongridno = NewGridNo( pTarget->sGridNo, DirectionInc( pTarget->ubDirection ) );
FLOAT nextgridnocenterX = (FLOAT)CenterX( viewdirectiongridno );
FLOAT nextgridnocenterY = (FLOAT)CenterY( viewdirectiongridno );
ConvertGridNoToCenterCellXY(viewdirectiongridno, &sX, &sY);
FLOAT nextgridnocenterX = (FLOAT) sX;
FLOAT nextgridnocenterY = (FLOAT) sY;
FLOAT difftonextgridno = sqrt( (nextgridnocenterX - x) * (nextgridnocenterX - x) + (nextgridnocenterY - y) * (nextgridnocenterY - y) );
INT32 oppositeviewdirectiongridno = NewGridNo( pTarget->sGridNo, DirectionInc( gOppositeDirection[pTarget->ubDirection] ) );
FLOAT oppositenextgridnocenterX = (FLOAT)CenterX( oppositeviewdirectiongridno );
FLOAT oppositenextgridnocenterY = (FLOAT)CenterY( oppositeviewdirectiongridno );
ConvertGridNoToCenterCellXY(oppositeviewdirectiongridno, &sX, &sY);
FLOAT oppositenextgridnocenterX = (FLOAT) sX;
FLOAT oppositenextgridnocenterY = (FLOAT) sY;
FLOAT difftooppositenextgridno = sqrt( (oppositenextgridnocenterX - x) * (oppositenextgridnocenterX - x) + (oppositenextgridnocenterY - y) * (oppositenextgridnocenterY - y) );
@@ -4319,8 +4323,9 @@ UINT8 CalcChanceToGetThrough( BULLET * pBullet )
UINT8 SoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier )
{
FLOAT dEndZPos;
BOOLEAN fOk;
INT16 sX, sY;
FLOAT dEndZPos;
BOOLEAN fOk;
if (pStartSoldier == pEndSoldier)
{
@@ -4337,15 +4342,18 @@ UINT8 SoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTY
// set startsoldier's target ID ... need an ID stored in case this
// is the AI calculating cover to a location where he might not be any more
pStartSoldier->ubCTGTTargetID = pEndSoldier->ubID;
return( ChanceToGetThrough( pStartSoldier, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos ) );
ConvertGridNoToCenterCellXY(pEndSoldier->sGridNo, &sX, &sY);
return( ChanceToGetThrough( pStartSoldier, (FLOAT) sX, (FLOAT) sY, dEndZPos ) );
}
UINT8 SoldierToSoldierBodyPartChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier, UINT8 ubAimLocation )
{
// does like StS-CTGT but with a particular body part in mind
FLOAT dEndZPos;
BOOLEAN fOk;
UINT8 ubPosType;
INT16 sX, sY;
FLOAT dEndZPos;
BOOLEAN fOk;
UINT8 ubPosType;
if (pStartSoldier == pEndSoldier)
{
@@ -4378,7 +4386,8 @@ UINT8 SoldierToSoldierBodyPartChanceToGetThrough( SOLDIERTYPE * pStartSoldier, S
// set startsoldier's target ID ... need an ID stored in case this
// is the AI calculating cover to a location where he might not be any more
pStartSoldier->ubCTGTTargetID = pEndSoldier->ubID;
return( ChanceToGetThrough( pStartSoldier, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos ) );
ConvertGridNoToCenterCellXY(pEndSoldier->sGridNo, &sX, &sY);
return( ChanceToGetThrough( pStartSoldier, (FLOAT) sX, (FLOAT) sY, dEndZPos ) );
}
UINT8 SoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT32 sGridNo, INT8 bLevel, INT8 bCubeLevel, UINT16 ubTargetID )
@@ -4423,9 +4432,7 @@ UINT8 SoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT32 sG
}
dEndZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[sGridNo].sHeight );
ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );
sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
ConvertGridNoToCenterCellXY(sGridNo, &sXPos, &sYPos);
// set startsoldier's target ID ... need an ID stored in case this
// is the AI calculating cover to a location where he might not be any more
@@ -4437,6 +4444,7 @@ UINT8 SoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT32 sG
UINT8 AISoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIERTYPE * pEndSoldier )
{
// Like a standard CTGT algorithm BUT fakes the start soldier at standing height
INT16 sX, sY;
FLOAT dEndZPos;
BOOLEAN fOk;
UINT8 ubChance;
@@ -4460,7 +4468,8 @@ UINT8 AISoldierToSoldierChanceToGetThrough( SOLDIERTYPE * pStartSoldier, SOLDIER
// is the AI calculating cover to a location where he might not be any more
pStartSoldier->ubCTGTTargetID = NOBODY;
ubChance = ChanceToGetThrough( pStartSoldier, (FLOAT) CenterX( pEndSoldier->sGridNo ), (FLOAT) CenterY( pEndSoldier->sGridNo ), dEndZPos );
ConvertGridNoToCenterCellXY(pEndSoldier->sGridNo, &sX, &sY);
ubChance = ChanceToGetThrough( pStartSoldier, (FLOAT) sX, (FLOAT) sY, dEndZPos );
pStartSoldier->usAnimState = usTrueState;
return( ubChance );
}
@@ -4510,9 +4519,7 @@ UINT8 AISoldierToLocationChanceToGetThrough( SOLDIERTYPE * pStartSoldier, INT32
}
dEndZPos += CONVERT_PIXELS_TO_HEIGHTUNITS( gpWorldLevelData[sGridNo].sHeight );
ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );
sXPos = sXPos * CELL_X_SIZE + (CELL_X_SIZE / 2);
sYPos = sYPos * CELL_Y_SIZE + (CELL_Y_SIZE / 2);
ConvertGridNoToCenterCellXY(sGridNo, &sXPos, &sYPos);
// set startsoldier's target ID ... need an ID stored in case this
// is the AI calculating cover to a location where he might not be any more
@@ -4788,6 +4795,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
UINT8 ubSpreadIndex = 0;
UINT16 usBulletFlags = 0;
int n=0;
INT16 sXPos, sYPos;
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
@@ -4799,8 +4807,9 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
dStartX = (FLOAT) CenterX( pFirer->sGridNo );
dStartY = (FLOAT) CenterY( pFirer->sGridNo );
ConvertGridNoToCenterCellXY(pFirer->sGridNo, &sXPos, &sYPos);
dStartX = (FLOAT) sXPos;
dStartY = (FLOAT) sYPos;
dDeltaX = dEndX - dStartX;
dDeltaY = dEndY - dStartY;
@@ -4831,15 +4840,15 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
{
usBulletFlags |= BULLET_FLAG_KNIFE;
}
else if ( Item[usHandItem].rocketlauncher )
else if (ItemIsRocketLauncher(usHandItem))
{
usBulletFlags |= BULLET_FLAG_MISSILE;
}
else if ( Item[usHandItem].cannon )
else if (ItemIsCannon(usHandItem))
{
usBulletFlags |= BULLET_FLAG_TANK_CANNON;
}
else if ( Item[usHandItem].rocketrifle )
else if (ItemIsRocketRifle(usHandItem))
{
usBulletFlags |= BULLET_FLAG_SMALL_MISSILE;
}
@@ -5228,7 +5237,7 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY,
if( !fFake && ( pFirer->ubProfile != NO_PROFILE ) && ( pFirer->bTeam == gbPlayerNum ) )
{
// another shot fired
if ( Item[usHandItem].usItemClass == IC_LAUNCHER || Item[usHandItem].grenadelauncher || Item[usHandItem].rocketlauncher || Item[usHandItem].singleshotrocketlauncher || Item[usHandItem].mortar)
if ( Item[usHandItem].usItemClass == IC_LAUNCHER || ItemIsGrenadeLauncher(usHandItem) || ItemIsRocketLauncher(usHandItem) || ItemIsSingleShotRocketLauncher(usHandItem) || ItemIsMortar(usHandItem))
gMercProfiles[ pFirer->ubProfile ].records.usMissilesLaunched++;
else if ( Item[usHandItem].usItemClass == IC_THROWING_KNIFE )
gMercProfiles[ pFirer->ubProfile ].records.usKnivesThrown++;
@@ -5279,6 +5288,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
UINT8 ubSpreadIndex = 0;
UINT16 usBulletFlags = 0;
int n=0;
INT16 sXPos, sYPos;
OBJECTTYPE* pObjAttHand = pFirer->GetUsedWeapon( &(pFirer->inv[pFirer->ubAttackingHand]) );
@@ -5290,8 +5300,9 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
CalculateSoldierZPos( pFirer, FIRING_POS, &dStartZ );
dStartX = (FLOAT) CenterX( pFirer->sGridNo );
dStartY = (FLOAT) CenterY( pFirer->sGridNo );
ConvertGridNoToCenterCellXY(pFirer->sGridNo, &sXPos, &sYPos);
dStartX = (FLOAT) sXPos;
dStartY = (FLOAT) sYPos;
dDeltaX = dEndX - dStartX;
dDeltaY = dEndY - dStartY;
@@ -5324,15 +5335,15 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
{
usBulletFlags |= BULLET_FLAG_KNIFE;
}
else if ( Item[usHandItem].rocketlauncher )
else if (ItemIsRocketLauncher(usHandItem))
{
usBulletFlags |= BULLET_FLAG_MISSILE;
}
else if ( Item[usHandItem].cannon )
else if (ItemIsCannon(usHandItem))
{
usBulletFlags |= BULLET_FLAG_TANK_CANNON;
}
else if ( Item[usHandItem].rocketrifle )
else if (ItemIsRocketRifle(usHandItem))
{
usBulletFlags |= BULLET_FLAG_SMALL_MISSILE;
}
@@ -5742,7 +5753,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
if( !fFake && ( pFirer->ubProfile != NO_PROFILE ) && ( pFirer->bTeam == gbPlayerNum ) )
{
// another shot fired
if ( Item[usHandItem].usItemClass == IC_LAUNCHER || Item[usHandItem].grenadelauncher || Item[usHandItem].rocketlauncher || Item[usHandItem].singleshotrocketlauncher || Item[usHandItem].mortar)
if ( Item[usHandItem].usItemClass == IC_LAUNCHER || ItemIsGrenadeLauncher(usHandItem) || ItemIsRocketLauncher(usHandItem) || ItemIsSingleShotRocketLauncher(usHandItem) || ItemIsMortar(usHandItem))
gMercProfiles[ pFirer->ubProfile ].records.usMissilesLaunched++;
else if ( Item[usHandItem].usItemClass == IC_THROWING_KNIFE )
gMercProfiles[ pFirer->ubProfile ].records.usKnivesThrown++;
@@ -5954,6 +5965,7 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT
UINT8 ubSpreadIndex = 0;
UINT16 usBulletFlags = 0;
int n=0;
INT16 sXPos, sYPos;
UINT16 usItem = pObj->usItem;
UINT8 ammotype = ( *pObj )[0]->data.gun.ubGunAmmoType;
@@ -5962,8 +5974,9 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT
if ( AmmoTypes[ammotype].numberOfBullets > 1 )
fBuckshot = TRUE;
dStartX = (FLOAT) CenterX( gridno );
dStartY = (FLOAT) CenterY( gridno );
ConvertGridNoToCenterCellXY(gridno, &sXPos, &sYPos);
dStartX = (FLOAT) sXPos;
dStartY = (FLOAT) sYPos;
dDeltaX = dEndX - dStartX;
dDeltaY = dEndY - dStartY;
@@ -5994,15 +6007,15 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT
{
usBulletFlags |= BULLET_FLAG_KNIFE;
}
else if ( Item[usItem].rocketlauncher )
else if (ItemIsRocketLauncher(usItem))
{
usBulletFlags |= BULLET_FLAG_MISSILE;
}
else if ( Item[usItem].cannon )
else if (ItemIsCannon(usItem))
{
usBulletFlags |= BULLET_FLAG_TANK_CANNON;
}
else if ( Item[usItem].rocketrifle )
else if (ItemIsRocketRifle(usItem))
{
usBulletFlags |= BULLET_FLAG_SMALL_MISSILE;
}
@@ -6541,13 +6554,15 @@ INT8 FireBulletGivenTarget_NoObjectNoSoldier( UINT16 usItem, UINT8 ammotype, UIN
UINT8 ubSpreadIndex = 0;
UINT16 usBulletFlags = 0;
int n = 0;
INT16 sXPos, sYPos;
BOOLEAN fBuckshot = FALSE;
if ( AmmoTypes[ammotype].numberOfBullets > 1 )
fBuckshot = TRUE;
dStartX = (FLOAT)CenterX( gridno );
dStartY = (FLOAT)CenterY( gridno );
ConvertGridNoToCenterCellXY(gridno, &sXPos, &sYPos);
dStartX = (FLOAT)sXPos;
dStartY = (FLOAT)sYPos;
dDeltaX = dEndX - dStartX;
dDeltaY = dEndY - dStartY;
@@ -6579,15 +6594,15 @@ INT8 FireBulletGivenTarget_NoObjectNoSoldier( UINT16 usItem, UINT8 ammotype, UIN
{
usBulletFlags |= BULLET_FLAG_KNIFE;
}
else if ( Item[usItem].rocketlauncher )
else if (ItemIsRocketLauncher(usItem))
{
usBulletFlags |= BULLET_FLAG_MISSILE;
}
else if ( Item[usItem].cannon )
else if (ItemIsCannon(usItem))
{
usBulletFlags |= BULLET_FLAG_TANK_CANNON;
}
else if ( Item[usItem].rocketrifle )
else if (ItemIsRocketRifle(usItem))
{
usBulletFlags |= BULLET_FLAG_SMALL_MISSILE;
}
@@ -6908,7 +6923,7 @@ INT8 ChanceToGetThrough(SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOAT dE
// sevenfm: check that weapon exists!
if (pObjHand->exists() &&
pObjHand->usItem == pFirer->usAttackingWeapon &&
(Item[pFirer->usAttackingWeapon].usItemClass == IC_GUN || Item[pFirer->usAttackingWeapon].usItemClass == IC_THROWING_KNIFE || Item[pFirer->usAttackingWeapon].rocketlauncher))
(Item[pFirer->usAttackingWeapon].usItemClass == IC_GUN || Item[pFirer->usAttackingWeapon].usItemClass == IC_THROWING_KNIFE || ItemIsRocketLauncher(pFirer->usAttackingWeapon)))
{
BOOLEAN fBuckShot = FALSE;
@@ -8537,8 +8552,10 @@ void AdjustTargetCenterPoint( SOLDIERTYPE *pShooter, INT32 iTargetGridNo, FLOAT
CalculateSoldierZPos( pShooter, FIRING_POS, &dStartZ );
// Locate absolute center X,Y of the shooter
dStartX = (FLOAT) CenterX( pShooter->sGridNo );
dStartY = (FLOAT) CenterY( pShooter->sGridNo );
INT16 sXPos, sYPos;
ConvertGridNoToCenterCellXY(pShooter->sGridNo, &sXPos, &sYPos);
dStartX = (FLOAT) sXPos;
dStartY = (FLOAT) sYPos;
////////////////////////////////////////////////////////////////////////////
// Calculate difference (Delta) between start and end point of bullet flight
@@ -8626,7 +8643,7 @@ void AdjustTargetCenterPoint( SOLDIERTYPE *pShooter, INT32 iTargetGridNo, FLOAT
//INT32 iLaserRange = GetBestLaserRange(&(pShooter->inv[pSoldier->ubAttackingHand]));
INT16 sLaserRange = GetBestLaserRange(pWeapon);
if (AM_A_ROBOT(pShooter) && Item[pShooter->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotLaserBonus)
if (AM_A_ROBOT(pShooter) && ItemProvidesRobotLaserBonus(pShooter->inv[ROBOT_TARGETING_SLOT].usItem))
{
sLaserRange = max(sLaserRange, GetBestLaserRange(&pShooter->inv[ROBOT_TARGETING_SLOT]));
}
@@ -9157,8 +9174,10 @@ void CalcTargetMovementOffset( SOLDIERTYPE *pShooter, SOLDIERTYPE *pTarget, OBJE
{
// HEADROCK HAM 4: Hopefully the right spot for this: This soldier has no "old" coordinates, so just set them
// to wherever he/she is currently standing.
pTarget->sOldXPos = CenterX( pTarget->sGridNo );
pTarget->sOldYPos = CenterY( pTarget->sGridNo );
INT16 sXPos, sYPos;
ConvertGridNoToCenterCellXY(pTarget->sGridNo, &sXPos, &sYPos);
pTarget->sOldXPos = sXPos;
pTarget->sOldYPos = sYPos;
// Since movement is now nonexistent, break the formula here without adjusting coordinates.
return;
}
+2 -2
View File
@@ -214,10 +214,10 @@ bool Filter::Match(SOLDIERTYPE* pSoldier) {
cmp_val = Weapon[pSoldier->inv[HANDPOS].usItem].ubCalibre;
break;
case REQ_WEAPON_TWOHANDED:
cmp_val = TwoHandedItem(pSoldier->inv[HANDPOS].usItem);
cmp_val = ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem);
break;
case REQ_LEFT_WEAPON_TWOHANDED:
cmp_val = TwoHandedItem(pSoldier->inv[SECONDHANDPOS].usItem);
cmp_val = ItemIsTwoHanded(pSoldier->inv[SECONDHANDPOS].usItem);
break;
case REQ_VEST_AMOR_PROTECTION:
cmp_val = Armour[Item[pSoldier->inv[VESTPOS].usItem].ubClassIndex].ubProtection;
+15 -14
View File
@@ -1038,27 +1038,28 @@ UINT16 SpawnAirDropElite( INT32 sGridNo )
// Flugente hack
pSoldier = TacticalCreateEliteEnemy( );
if ( pSoldier == nullptr)
{
return NOBODY;
}
//Add soldier strategic info, so it doesn't break the counters!
if ( pSoldier )
if ( !gbWorldSectorZ )
{
if ( !gbWorldSectorZ )
SECTORINFO *pSector = &SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )];
switch ( pSoldier->ubSoldierClass )
{
SECTORINFO *pSector = &SectorInfo[SECTOR( gWorldSectorX, gWorldSectorY )];
switch ( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
case SOLDIER_CLASS_ADMINISTRATOR: pSector->ubNumAdmins++; pSector->ubAdminsInBattle++; break;
case SOLDIER_CLASS_ARMY: pSector->ubNumTroops++; pSector->ubTroopsInBattle++; break;
case SOLDIER_CLASS_ELITE: pSector->ubNumElites++; pSector->ubElitesInBattle++; break;
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CHOPPER;
pSoldier->usStrategicInsertionData = sGridNo; // required, otherwise soldiers will spawn in map before jumping out of the heli
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
//AllTeamsLookForAll( NO_INTERRUPTS );
}
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CHOPPER;
pSoldier->usStrategicInsertionData = sGridNo; // required, otherwise soldiers will spawn in map before jumping out of the heli
UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
//AllTeamsLookForAll( NO_INTERRUPTS );
return pSoldier->ubID;
}
+13 -8
View File
@@ -50,6 +50,7 @@
#include "DynamicDialogue.h"// added by Flugente
#include "Dialogue Control.h" // added by Flugente
#include "connect.h"
#include "Map Information.h"
#ifdef JA2UB
#include "Soldier Control.h"
@@ -534,16 +535,23 @@ void MercArrivesCallback( UINT16 ubSoldierID )
#ifdef JA2UB
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER && pSoldier->sSectorX == gGameExternalOptions.ubDefaultArrivalSectorX && pSoldier->sSectorY == gGameExternalOptions.ubDefaultArrivalSectorY && gGameUBOptions.InGameHeli == TRUE )
#else
if ( pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER && pSoldier->sSectorX == gGameExternalOptions.ubDefaultArrivalSectorX && pSoldier->sSectorY == gGameExternalOptions.ubDefaultArrivalSectorY )
if (pSoldier->ubStrategicInsertionCode != INSERTION_CODE_CHOPPER )
#endif
{
gfTacticalDoHeliRun = TRUE;
SetHelicopterDroppoint(gGameExternalOptions.iInitialMercArrivalLocation);
if (gfFirstHeliRun)
{
SetHelicopterDroppoint(gGameExternalOptions.iInitialMercArrivalLocation);
}
else
{
SetHelicopterDroppoint(gMapInformation.sCenterGridNo);
}
// OK, If we are in mapscreen, get out...
if ( guiCurrentScreen == MAP_SCREEN )
{
// ATE: Make sure the current one is selected!
// ATE: Make sure the current one is selected!
ChangeSelectedMapSector( gWorldSectorX, gWorldSectorY, 0 );
RequestTriggerExitFromMapscreen( MAP_EXIT_TO_TACTICAL );
@@ -554,17 +562,14 @@ void MercArrivesCallback( UINT16 ubSoldierID )
UpdateMercInSector( pSoldier, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
// Strategic map arrival to a sector that's not loaded
else
{
// OK, otherwise, set them in north area, so once we load again, they are here.
#ifdef JA2UB
//pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = gGameUBOptions.LOCATEGRIDNO;
#else
//pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_GRIDNO;
pSoldier->usStrategicInsertionData = gGameExternalOptions.iInitialMercArrivalLocation;
pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CENTER;
#endif
}
+15 -9
View File
@@ -5081,11 +5081,17 @@ BOOLEAN NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT32 sGridNo, BOOLEAN fPe
INT16 sDesiredLevel;
BOOLEAN fOKCheckStruct;
// sevenfm: allow civilians and NPCs with profile to go off screen
if (!GridNoOnVisibleWorldTile(sGridNo) && (pCurrSoldier->bTeam != CIV_TEAM || pCurrSoldier->ubProfile == NO_PROFILE))
{
return(FALSE);
}
// Allow civilians and NPCs with profile to go off screen, and also enemies if tactical retreat is enabled
auto destinationOffscreen = !(GridNoOnVisibleWorldTile(sGridNo));
auto hasProfile = pCurrSoldier->ubProfile != NO_PROFILE;
auto isCivilian = pCurrSoldier->bTeam == CIV_TEAM;
auto isEnemy = pCurrSoldier->bTeam == ENEMY_TEAM;
auto retreatAllowed = gGameExternalOptions.fAITacticalRetreat == true;
if (destinationOffscreen && !(isCivilian || hasProfile || (isEnemy && retreatAllowed)))
{
return(FALSE);
}
if (fPeopleToo && ( bPerson = WhoIsThere2( sGridNo, bLevel ) ) != NOBODY )
{
@@ -7281,7 +7287,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
// Check if it's supposed to be dropped
if ( !((*pObj).fFlags & OBJECT_UNDROPPABLE) || pTeamSoldier->bTeam == gbPlayerNum )
{
if ( !(Item[pObj->usItem].defaultundroppable) )
if ( !ItemIsUndroppableByDefault(pObj->usItem) )
{
//ReduceAmmoDroppedByNonPlayerSoldiers( pTeamSoldier, cnt );
@@ -7295,7 +7301,7 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
//add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items
usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY;
if ( Item[pObj->usItem].damageable && Item[pObj->usItem].usItemClass != IC_THROWING_KNIFE ) // Madd: drop crappier items from enemies on higher difficulty levels - note the quick fix for throwing knives
if (ItemIsDamageable(pObj->usItem) && Item[pObj->usItem].usItemClass != IC_THROWING_KNIFE ) // Madd: drop crappier items from enemies on higher difficulty levels - note the quick fix for throwing knives
{
// silversurfer: externalized this
//(*pObj)[0]->data.objectStatus -= (gGameOptions.ubDifficultyLevel - 1) * Random( 20 );
@@ -9313,7 +9319,7 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp
if ( gTacticalStatus.bBoxingState == BOXING )
{
// should have a check for "in boxing ring", no?
if ( ( pSoldier->usAttackingWeapon != NOTHING && !Item[pSoldier->usAttackingWeapon].brassknuckles ) || !( pSoldier->flags.uiStatusFlags & SOLDIER_BOXER ) || pSoldier->IsRiotShieldEquipped() )
if ( ( pSoldier->usAttackingWeapon != NOTHING && !ItemIsBrassKnuckles(pSoldier->usAttackingWeapon)) || !( pSoldier->flags.uiStatusFlags & SOLDIER_BOXER ) || pSoldier->IsRiotShieldEquipped() )
{
// someone's cheating!
if ( (Item[ pSoldier->usAttackingWeapon ].usItemClass == IC_BLADE || Item[ pSoldier->usAttackingWeapon ].usItemClass == IC_PUNCH) && (pTarget->flags.uiStatusFlags & SOLDIER_BOXER) )
@@ -9914,7 +9920,7 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
pSoldier->bDoAutofire = 1;
pSoldier->bDoBurst = TRUE;
}
if ( Item[pSoldier->inv[ HANDPOS ].usItem].twohanded && Weapon[pSoldier->inv[ HANDPOS ].usItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
if (ItemIsTwoHanded(pSoldier->inv[ HANDPOS ].usItem) && Weapon[pSoldier->inv[ HANDPOS ].usItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD;
else
pSoldier->bScopeMode = USE_BEST_SCOPE;
-1
View File
@@ -76,7 +76,6 @@ private:
SOLDIERTYPE* pSoldier;
INT8 onRooftop;//aka ubLevel, not sure if this bool is logically reversed yet
bool fNonFenceJumper;
bool fNonSwimmer;
bool fPathingForPlayer;
bool fPathAroundPeople;
+25 -24
View File
@@ -18,7 +18,6 @@
#include "Animation Cache.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "container.h"
#include "interface.h"
#include <math.h>
@@ -454,10 +453,15 @@ UINT32 guiFailedPathChecks = 0;
UINT32 guiUnsuccessfulPathChecks = 0;
#endif
static auto canJumpFences(SOLDIERTYPE* pSoldier) -> bool {
return IS_MERC_BODY_TYPE(pSoldier) && pSoldier->CanClimbWithCurrentBackpack();
}
//ADB the extra cover feature is supposed to pick a path of the same distance as one calculated with the feature off,
//but a safer path, usually farther away from an enemy or following behind some cover.
//however it has not been tested and it may need some work, I haven't touched it in a while
//#define ASTAR_USING_EXTRACOVER
#define ASTAR_USING_EXTRACOVER
using namespace std;
using namespace ASTAR;
@@ -638,7 +642,6 @@ int AStarPathfinder::GetPath(SOLDIERTYPE *s ,
fTurnBased = ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) );
fPathingForPlayer = ( (pSoldier->bTeam == gbPlayerNum) && (!gTacticalStatus.fAutoBandageMode) && !(pSoldier->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) );
fNonFenceJumper = !( IS_MERC_BODY_TYPE( pSoldier ) );
fNonSwimmer = !( IS_MERC_BODY_TYPE( pSoldier ) );
fPathAroundPeople = ( (fFlags & PATH_THROUGH_PEOPLE) == 0 );
fCloseGoodEnough = ( (fFlags & PATH_CLOSE_GOOD_ENOUGH) != 0);
@@ -1161,7 +1164,7 @@ void AStarPathfinder::ExecuteAStarLogic()
#ifdef ASTAR_USING_EXTRACOVER
//check if we will run out of AP while entering this node or before
//if we run out, the merc will stop at the parent node for a turn and be vulnerable
if (mercsMaxAPs && APCost > mercsMaxAPs)
if (gfTurnBasedAI && mercsMaxAPs && AStarG > mercsMaxAPs)
{
extraGCoverCost = GetExtraGCover(ParentNode);
@@ -1171,7 +1174,7 @@ void AStarPathfinder::ExecuteAStarLogic()
//use the stance and cover to see how much we really want to stop at the parent node
//as opposed to an equal path with different cover
//because other nodes further on the path will stop here too, add this value to the F cost
extraGCoverCost = CalcGCover(ParentNodeIndex, APCost);
extraGCoverCost = CalcGCover(ParentNode, AStarG);
//remember, we have run out of points to *enter* this node, so we are stuck at the *parent* node
//cache the cost to stay at the parent node
@@ -1509,9 +1512,9 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
INT32 iMyThreatValue;
INT16 sThreatLoc;
UINT32 uiThreatCnt = 0;
INT16 * pusLastLoc;
INT8 * pbPersOL;
INT8 * pbPublOL;
INT32* pusLastLoc;
INT8 * pbPersOL;
INT8 * pbPublOL;
//although we have run out of APs to get here, it could just mean we have some APs but not enough to enter
int APLeft = this->mercsMaxAPs - APCost;
@@ -1520,7 +1523,7 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
pusLastLoc = &(gsLastKnownOppLoc[pSoldier->ubID][0]);
// hang a pointer into personal opplist
pbPersOL = &(pSoldier->bOppList[0]);
pbPersOL = &(pSoldier->aiData.bOppList[0]);
// hang a pointer into public opplist
pbPublOL = &(gbPublicOpplist[pSoldier->bTeam][0]);
@@ -1532,7 +1535,7 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
SOLDIERTYPE* pOpponent = MercSlots[ uiLoop ];
// if this merc is inactive, at base, on assignment, dead, unconscious
if (!pOpponent || pOpponent->bLife < OKLIFE) {
if (!pOpponent || pOpponent->stats.bLife < OKLIFE) {
continue; // next merc
}
@@ -1541,7 +1544,7 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
continue; // next merc
}
pbPersOL = pSoldier->bOppList + pOpponent->ubID;
pbPersOL = pSoldier->aiData.bOppList + pOpponent->ubID;
pbPublOL = gbPublicOpplist[pSoldier->bTeam] + pOpponent->ubID;
pusLastLoc = gsLastKnownOppLoc[pSoldier->ubID] + pOpponent->ubID;
@@ -1551,7 +1554,7 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
}
// Special stuff for Carmen the bounty hunter
if (pSoldier->bAttitude == ATTACKSLAYONLY && pOpponent->ubProfile != 64) {
if (pSoldier->aiData.bAttitude == ATTACKSLAYONLY && pOpponent->ubProfile != 64) {
continue; // next opponent
}
@@ -1596,7 +1599,7 @@ int AStarPathfinder::CalcGCover(int const NodeIndex,
Threats[uiThreatCnt].iOrigRange = iThreatRange;
// calculate how many APs he will have at the start of the next turn
Threats[uiThreatCnt].iAPs = CalcActionPoints(pOpponent);
Threats[uiThreatCnt].iAPs = pOpponent->CalcActionPoints();
if (iThreatRange < iClosestThreatRange) {
iClosestThreatRange = iThreatRange;
@@ -1638,7 +1641,7 @@ int AStarPathfinder::CalcCoverValue(INT32 sMyGridNo, INT32 iMyThreat, INT32 iMyA
INT32 myThreatsiValue, INT32 myThreatsiAPs, INT32 myThreatsiCertainty)
{
SOLDIERTYPE* pMe = this->pSoldier;
INT32 morale = pSoldier->bAIMorale;
INT32 morale = pSoldier->aiData.bAIMorale;
INT32 iRange = myThreatsiOrigRange;
// all 32-bit integers for max. speed
@@ -1687,7 +1690,7 @@ int AStarPathfinder::CalcCoverValue(INT32 sMyGridNo, INT32 iMyThreat, INT32 iMyA
else
{
// optimistically assume we'll be behind the best cover available at this spot
bHisActualCTGT = CalcWorstCTGTForPosition( pHim, pMe->ubID, sMyGridNo, pMe->bLevel, iMyAPsLeft );
bHisActualCTGT = CalcWorstCTGTForPosition( pHim, pMe->ubID, sMyGridNo, pMe->pathing.bLevel, iMyAPsLeft );
}
// normally, that will be the cover I'll use, unless worst case over-rides it
@@ -1706,7 +1709,7 @@ int AStarPathfinder::CalcCoverValue(INT32 sMyGridNo, INT32 iMyThreat, INT32 iMyA
}
// calculate where my cover is worst if opponent moves just 1 tile over
bHisBestCTGT = CalcBestCTGT(pHim, pMe->ubID, sMyGridNo, pMe->bLevel, iMyAPsLeft);
bHisBestCTGT = CalcBestCTGT(pHim, pMe->ubID, sMyGridNo, pMe->pathing.bLevel, iMyAPsLeft);
// if he can actually improve his CTGT by moving to a nearby gridno
if (bHisBestCTGT > bHisActualCTGT)
@@ -1735,7 +1738,7 @@ int AStarPathfinder::CalcCoverValue(INT32 sMyGridNo, INT32 iMyThreat, INT32 iMyA
// let's not assume anything about the stance the enemy might take, so take an average
// value... no cover give a higher value than partial cover
bMyCTGT = CalcAverageCTGTForPosition( pMe, pHim->ubID, sHisGridNo, pHim->bLevel, iMyAPsLeft );
bMyCTGT = CalcAverageCTGTForPosition( pMe, pHim->ubID, sHisGridNo, pHim->pathing.bLevel, iMyAPsLeft );
// since NPCs are too dumb to shoot "blind", ie. at opponents that they
// themselves can't see (mercs can, using another as a spotter!), if the
@@ -1765,14 +1768,14 @@ int AStarPathfinder::CalcCoverValue(INT32 sMyGridNo, INT32 iMyThreat, INT32 iMyA
// try to account for who outnumbers who: the side with the advantage thus
// (hopefully) values offense more, while those in trouble will play defense
if (pHim->bOppCnt > 1)
if (pHim->aiData.bOppCnt > 1)
{
HisPosValue /= pHim->bOppCnt;
HisPosValue /= pHim->aiData.bOppCnt;
}
if (pMe->bOppCnt > 1)
if (pMe->aiData.bOppCnt > 1)
{
MyPosValue /= pMe->bOppCnt;
MyPosValue /= pMe->aiData.bOppCnt;
}
@@ -2244,7 +2247,6 @@ INT32 FindBestPath(SOLDIERTYPE *s , INT32 sDestination, INT8 bLevel, INT16 usMov
DOOR * pDoor;
STRUCTURE * pDoorStructure;
BOOLEAN fDoorIsOpen = FALSE;
BOOLEAN fNonFenceJumper;
BOOLEAN fNonSwimmer;
BOOLEAN fPathAroundPeople;
BOOLEAN fConsiderPersonAtDestAsObstacle;
@@ -2316,7 +2318,6 @@ if(!GridNoOnVisibleWorldTile(iDestination))
fTurnBased = ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) );
fPathingForPlayer = ( (s->bTeam == gbPlayerNum) && (!gTacticalStatus.fAutoBandageMode) && !(s->flags.uiStatusFlags & SOLDIER_PCUNDERAICONTROL) );
fNonFenceJumper = !( IS_MERC_BODY_TYPE( s ) ) || (!s->CanClimbWithCurrentBackpack());//Moa: added backpack check
// Flugente: nonswimmers are those who are not mercs and not boats
fNonSwimmer = !(IS_MERC_BODY_TYPE( s ) );
@@ -2930,7 +2931,7 @@ if(!GridNoOnVisibleWorldTile(iDestination))
nextCost = gTileTypeMovementCost[ gpWorldLevelData[ newLoc ].ubTerrainID ];
}
}
else if ( nextCost == TRAVELCOST_FENCE && fNonFenceJumper )
else if ( nextCost == TRAVELCOST_FENCE && !canJumpFences(s))
{
goto NEXTDIR;
}
+21 -21
View File
@@ -2375,9 +2375,9 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
// Do we need to stand up?
bAPCost += GetAPsToChangeStance( pSoldier, ANIM_STAND );
}
else if(Item[usItem].rocketlauncher || Item[usItem].grenadelauncher || Item[usItem].mortar)//dnl ch72 260913 move this here from bottom, need to change as rocketlaucher could be fired from crouch too
else if(ItemIsRocketLauncher(usItem) || ItemIsGrenadeLauncher(usItem) || ItemIsMortar(usItem))//dnl ch72 260913 move this here from bottom, need to change as rocketlaucher could be fired from crouch too
{
if(gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE || Item[usItem].mortar && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_STAND)
if(gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE || ItemIsMortar(usItem) && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_STAND)
bAPCost += GetAPsToChangeStance(pSoldier, ANIM_CROUCH);
else
bAPCost += GetAPsToChangeStance(pSoldier, gAnimControl[pSoldier->usAnimState].ubEndHeight);
@@ -2393,9 +2393,9 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
if (!TileIsOutOfBounds(sGridNo))
{
{
if(Item[usItem].rocketlauncher || Item[usItem].grenadelauncher || Item[usItem].mortar)//dnl ch72 260913
if(ItemIsRocketLauncher(usItem) || ItemIsGrenadeLauncher(usItem) || ItemIsMortar(usItem))//dnl ch72 260913
{
if(gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE || Item[usItem].mortar && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_STAND)
if(gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE || ItemIsMortar(usItem) && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_STAND)
usTurningCost = CalculateTurningCost(pSoldier, usItem, fAddingTurningCost, ANIM_CROUCH);
else
usTurningCost = CalculateTurningCost(pSoldier, usItem, fAddingTurningCost);
@@ -2429,7 +2429,7 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime,
// if attacking a new target (or if the specific target is uncertain)
// Added check if the weapon is throwing knife/melee weapons - otherwise it would add APs for change target on cursor but not actually deduct them afterwards - SANDRO
if ( ubForceRaiseGunCost == TRUE || (( sGridNo != pSoldier->sLastTarget ) && !Item[usUBItem].rocketlauncher && ( Item[ usUBItem ].usItemClass != IC_THROWING_KNIFE )/* && ( Item[ usUBItem ].usItemClass != IC_PUNCH ) && ( Item[ usUBItem ].usItemClass != IC_BLADE )*/ ) )//dnl ch69 140913 //dnl ch73 290913
if ( ubForceRaiseGunCost == TRUE || (( sGridNo != pSoldier->sLastTarget ) && !ItemIsRocketLauncher(usUBItem) && ( Item[ usUBItem ].usItemClass != IC_THROWING_KNIFE )/* && ( Item[ usUBItem ].usItemClass != IC_PUNCH ) && ( Item[ usUBItem ].usItemClass != IC_BLADE )*/ ) )//dnl ch69 140913 //dnl ch73 290913
{
if ( pSoldier->IsValidAlternativeFireMode( bAimTime, sGridNo ) )
bAPCost += (APBPConstants[AP_CHANGE_TARGET] / 2);
@@ -2635,13 +2635,13 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( &(pSoldier->inv[bInvPos]) );
UINT16 usItemUsed = pSoldier->GetUsedWeaponNumber( &(pSoldier->inv[bInvPos]) );
if ( Item[usItemUsed].singleshotrocketlauncher )
if (ItemIsSingleShotRocketLauncher(usItemUsed))
{
// hack... they turn empty afterwards anyways
return( TRUE );
}
if (Item[ usItemUsed ].usItemClass == IC_LAUNCHER || Item[usItemUsed].cannon )
if (Item[ usItemUsed ].usItemClass == IC_LAUNCHER || ItemIsCannon(usItemUsed))
{
if ( FindAttachmentByClass( pObjUsed, IC_GRENADE ) != 0 )
{
@@ -2661,7 +2661,7 @@ BOOLEAN EnoughAmmo( SOLDIERTYPE *pSoldier, BOOLEAN fDisplay, INT8 bInvPos )
}
// WANNE: If there is a tank, it always have ammo to shoot, no check!
if (Item[usItemUsed].cannon)
if (ItemIsCannon(usItemUsed))
{
return ( TRUE );
}
@@ -2715,13 +2715,13 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj )
{
// tanks never run out of MG ammo!
// unlimited cannon ammo is handled in AI
if ( (ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier )) && !Item[pObj->usItem].cannon )
if ( (ARMED_VEHICLE( pSoldier ) || ENEMYROBOT( pSoldier )) && !ItemIsCannon(pObj->usItem) )
return;
if ( Item[pObj->usItem].cannon )
if (ItemIsCannon(pObj->usItem))
{
}
else if ( Item[ pObj->usItem ].usItemClass == IC_GUN && !Item[pObj->usItem].cannon && pSoldier->bWeaponMode != WM_ATTACHED_GL && pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bWeaponMode != WM_ATTACHED_GL_AUTO )
else if ( Item[ pObj->usItem ].usItemClass == IC_GUN && !ItemIsCannon(pObj->usItem) && pSoldier->bWeaponMode != WM_ATTACHED_GL && pSoldier->bWeaponMode != WM_ATTACHED_GL_BURST && pSoldier->bWeaponMode != WM_ATTACHED_GL_AUTO )
{
// Flugente: check for underbarrel weapons and use that object if necessary
OBJECTTYPE* pObjUsed = pSoldier->GetUsedWeapon( pObj );
@@ -2754,7 +2754,7 @@ void DeductAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE* pObj )
gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_AMMO, (FLOAT)(Item[(*pObjUsed)[0]->data.gun.usGunAmmoItem].ubWeight) / (FLOAT)(Magazine[ Item[ (*pObjUsed)[0]->data.gun.usGunAmmoItem ].ubClassIndex ].ubMagSize ) );
}
}
else if ( Item[ pObj->usItem ].usItemClass == IC_LAUNCHER || Item[pObj->usItem].cannon || pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )
else if ( Item[ pObj->usItem ].usItemClass == IC_LAUNCHER || ItemIsCannon(pObj->usItem) || pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO )
{
OBJECTTYPE* pAttachment = FindAttachmentByClass( pObj, IC_GRENADE );
if ( !pAttachment->exists() )
@@ -3214,7 +3214,7 @@ BOOLEAN CheckForMercContMove( SOLDIERTYPE *pSoldier )
return( FALSE );
}
if( pSoldier->stats.bLife >= OKLIFE )
if( pSoldier->stats.bLife >= OKLIFE && !(pSoldier->bCollapsed && pSoldier->bBreath < OKBREATH) )
{
if( pSoldier->sGridNo != pSoldier->pathing.sFinalDestination || pSoldier->bGoodContPath )
{
@@ -3325,7 +3325,7 @@ INT16 GetAPsToReadyWeapon( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
// If we are told to go to the alt weapon holding mode
if ( gAnimControl[ usAnimState ].uiFlags & ( ANIM_ALT_WEAPON_HOLDING ) || (pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD && usAnimState == INVALID_ANIMATION) )//dnl ch71 180913
{
if ( Item[ usItem ].twohanded )
if (ItemIsTwoHanded(usItem))
{
// Raising only to hip, either charge no APs or a portion of them
ubReadyAPs = ((ubReadyAPs * gGameExternalOptions.ubToAltWeaponHoldReadyAPsPerc) + 99) / 100 ; // round up for rifles
@@ -3339,7 +3339,7 @@ INT16 GetAPsToReadyWeapon( SOLDIERTYPE *pSoldier, UINT16 usAnimState )
// If we are told to go from alternative to standard weapon holding
else if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_ALT_WEAPON_HOLDING ) )
{
if ( Item[ usItem ].twohanded )
if (ItemIsTwoHanded(usItem))
{
ubReadyAPs = ubReadyAPs * gGameExternalOptions.ubFromAltWeaponHoldReadyAPsPerc / 100; // round down for rifles
}
@@ -3640,11 +3640,11 @@ INT16 MinAPsToThrow( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubAddTurningCos
iAPCost += ( ( ( 100 * iTop ) / iBottom) + 1) / 2;
// SANDRO - STOMP traits - reduce APs needed to throw grenades if having Demolitions skill
if( HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT ) && gGameOptions.fNewTraitSystem )
if( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) && gGameOptions.fNewTraitSystem )
{
if ( grenadAPreductionpossible )
{
iAPCost = max( 1, (INT32)(iAPCost * (100 - gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction) / 100));
iAPCost = max( 1, (INT32)(iAPCost * (100 - gSkillTraitValues.ubTHAPsNeededToThrowGrenadesReduction) / 100));
}
}
@@ -3703,7 +3703,7 @@ UINT16 GetTotalAPsToDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
if ( sAPs > 0 )
{
if(Item[pSoldier->inv[HANDPOS].usItem].mine == 1)
if(ItemIsMine(pSoldier->inv[HANDPOS].usItem))
sAPs += GetAPsToPlantMine( pSoldier ); // changed by SANDRO
else
sAPs += GetAPsToDropBomb( pSoldier ); // changed by SANDRO
@@ -4154,7 +4154,7 @@ INT32 GetBPCostPer10APsForGunHolding( SOLDIERTYPE * pSoldier, BOOLEAN fEstimate
// Alternative weapon holding?
if (( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_ALT_WEAPON_HOLDING ) || (fEstimate && pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD) )
{
if ( Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].twohanded ) // firing from hip is not nearly ?n effort
if (ItemIsTwoHanded(pSoldier->inv[pSoldier->ubAttackingHand].usItem)) // firing from hip is not nearly ?n effort
dModifier += 80; // only 20% cost if on hip
else // holding pistol in one hand is worse in this case
dModifier -= 25; // increased cost by 25%
@@ -4265,7 +4265,7 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier )
iKickPower = iKickPower * (100 - sWeaponWeight) / 100;
// If one-handed gun, reduce it a bit, since the whole thing is somewhat different.
if ( !Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].twohanded )
if ( !ItemIsTwoHanded(pSoldier->inv[pSoldier->ubAttackingHand].usItem) )
iKickPower = iKickPower * 3 / 4; // -25%
// ::: overview :::
@@ -4310,7 +4310,7 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier )
// Alternative weapon holding?
if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_ALT_WEAPON_HOLDING )
{
if ( Item[pSoldier->inv[pSoldier->ubAttackingHand].usItem].twohanded ) // firing from hip makes the kicking rather diminishing
if (ItemIsTwoHanded(pSoldier->inv[pSoldier->ubAttackingHand].usItem)) // firing from hip makes the kicking rather diminishing
dModifier += 80; // only 20% of the regular kick power
else // holding pistol in one hand is worse in this case
dModifier -= 33; // plus 33% power
+5 -4
View File
@@ -460,7 +460,7 @@ INVTYPE* GearGetRandomFaceItem(INT8 min_coolness = -1, INT8 max_coolness = -1, U
if (HasItemFlag((*it)->uiIndex, SCUBA_MASK))
continue;
if (item_type == FACEITEM_GAS_MASK && (*it)->gasmask < 1) continue;
if (item_type == FACEITEM_GAS_MASK && !ItemIsGasmask((*it)->uiIndex)) continue;
if (item_type == FACEITEM_SPECTACLES && (*it)->brightlightvisionrangebonus < 1) continue;
if (item_type == FACEITEM_NVG && (*it)->nightvisionrangebonus < 1) continue;
if (item_type == FACEITEM_HEADSET && (*it)->hearingrangebonus < 1) continue;
@@ -643,7 +643,8 @@ std::vector<INVTYPE*> GearFindAttachmentsForWeapon(INVTYPE* weapon, BOOL attach_
{
INVTYPE* item = *it;
if (item->attachment < 1)
//if (item->attachment < 1)
if (!ItemIsAttachment(item->uiIndex))
continue;
if (!ValidAttachment(item->uiIndex, weapon->uiIndex))
@@ -680,7 +681,7 @@ std::vector<INVTYPE*> GearFindItemsForRole(std::vector<UINT8>* roles, std::vecto
INVTYPE* item = *it;
INT8 chance = 0;
if (item->glgrenade > 0)
if (ItemIsGLgrenade(item->uiIndex))
continue;
if (item->attachmentclass == AC_GRENADE || item->attachmentclass == AC_ROCKET)
@@ -1061,4 +1062,4 @@ void RandomizeMerc(UINT8 profile_id, MERCPROFILESTRUCT* merc, BOOL random_gear_k
merc->usOptionalGearCost = kit_cost;
}
}
}
}
+9 -9
View File
@@ -561,8 +561,7 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
}
else
{
AniParams.sX = CenterX(pCorpse->def.sGridNo);
AniParams.sY = CenterY(pCorpse->def.sGridNo);
ConvertGridNoToCenterCellXY(pCorpse->def.sGridNo, &AniParams.sX, &AniParams.sY);
}
AniParams.sZ = (INT16)pCorpse->def.sHeightAdjustment;
@@ -1015,7 +1014,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
{
// and make sure that it really is a droppable item type
// if ( !(Item[ pObj->usItem ].fFlags & ITEM_DEFAULT_UNDROPPABLE) )
if ( !(Item[ pObj->usItem ].defaultundroppable ) )
if ( !ItemIsUndroppableByDefault(pObj->usItem) )
{
ReduceAmmoDroppedByNonPlayerSoldiers( pSoldier, cnt );
//if this soldier was an enemy
@@ -1028,7 +1027,7 @@ BOOLEAN TurnSoldierIntoCorpse( SOLDIERTYPE *pSoldier, BOOLEAN fRemoveMerc, BOOLE
//add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items
usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY;
if ( Item[pObj->usItem].damageable && Item[pObj->usItem].usItemClass != IC_THROWING_KNIFE ) // Madd: drop crappier items from enemies on higher difficulty levels - note the quick fix for throwing knives
if (ItemIsDamageable(pObj->usItem) && Item[pObj->usItem].usItemClass != IC_THROWING_KNIFE ) // Madd: drop crappier items from enemies on higher difficulty levels - note the quick fix for throwing knives
{
// silversurfer: externalized this
//(*pObj)[0]->data.objectStatus -= (gGameOptions.ubDifficultyLevel - 1) * Random(20);
@@ -1588,8 +1587,7 @@ void VaporizeCorpse( INT32 sGridNo, INT8 asLevel, UINT16 usStructureID )
AniParams.sDelay = (INT16)( 80 );
AniParams.sStartFrame = 0;
AniParams.uiFlags = ANITILE_CACHEDTILE | ANITILE_FORWARD;
AniParams.sX = CenterX( sBaseGridNo );
AniParams.sY = CenterY( sBaseGridNo );
ConvertGridNoToCenterCellXY(sBaseGridNo, &AniParams.sX, &AniParams.sY);
AniParams.sZ = (INT16)pCorpse->def.sHeightAdjustment;
strcpy( AniParams.zCachedFile, "TILECACHE\\GEN_BLOW.STI" );
@@ -2284,10 +2282,12 @@ BOOLEAN AddCorpseFromObject(OBJECTTYPE* pObj, INT32 sGridNo, INT8 bLevel )
Corpse.ubBodyType = REGMALE;
}
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
Corpse.sGridNo = sGridNo;
Corpse.dXPos = CenterX(Corpse.sGridNo);
Corpse.dYPos = CenterY(Corpse.sGridNo);
Corpse.dXPos = sX;
Corpse.dYPos = sY;
Corpse.sHeightAdjustment = 0;
+7 -19
View File
@@ -607,8 +607,6 @@ void EnableAllDealersOfferSlots( void );
void HatchOutInvSlot( UINT16 usPosX, UINT16 usPosY );
extern BOOLEAN ItemIsARocketRifle( INT16 sItemIndex );
#ifdef JA2TESTVERSION
BOOLEAN gfTestDisplayDealerCash = FALSE;
void DisplayAllDealersCash();
@@ -776,7 +774,7 @@ BOOLEAN EnterShopKeeperInterface()
else
pShopkeeper = FindSoldierByProfileID( armsDealerInfo[gbSelectedArmsDealerID].ubShopKeeperID, FALSE );
if ( GetRangeFromGridNoDiff( pSoldier->sGridNo, pShopkeeper->sGridNo ) > NPC_TALK_RADIUS )
if (PythSpacesAway( pSoldier->sGridNo, pShopkeeper->sGridNo ) > NPC_TALK_RADIUS )
{
//so now we know we are too far away to trade, so instead of just quitting,
//either post a message or run to the guy like HandleTalkInit does
@@ -2896,13 +2894,6 @@ BOOLEAN DetermineArmsDealersSellingInventory( )
continue;
}
//shadooow: do not sell any item that is limited to specific system and this system isn't enabled
if (((Item[iter->object.usItem].usLimitedToSystem & FOOD_SYSTEM_FLAG) && !UsingFoodSystem()) || ((Item[iter->object.usItem].usLimitedToSystem & DISEASE_SYSTEM_FLAG) && !gGameExternalOptions.fDisease))
{
++iter;
continue;
}
bool increment = true;
if (ItemIsSpecial(*iter) == false) {
StoreObjectsInNextFreeDealerInvSlot( &(*iter), gpTempDealersInventory, gbSelectedArmsDealerID );
@@ -3399,8 +3390,7 @@ FLOAT ItemConditionModifier(UINT16 usItemIndex, INT16 bStatus)
// an item at 100% is worth full price...
// if ( Item[ usItemIndex ].fFlags & ITEM_REPAIRABLE )
if ( Item[ usItemIndex ].repairable )
if (ItemIsRepairable(usItemIndex))
{
// a REPAIRABLE item at 0% is still worth 50% of its full price, not 0%
dConditionModifier = 0.5f + ( bStatus / (FLOAT)200 );
@@ -5014,8 +5004,7 @@ BOOLEAN IsGunOrAmmoOfSameTypeSelected( OBJECTTYPE *pItemObject )
}
//if the highlighted object is an attachment
// if( Item[ pItemObject->usItem ].fFlags & ITEM_ATTACHMENT )
if( Item[ pItemObject->usItem ].attachment )
if(ItemIsAttachment(pItemObject->usItem))
{
if( ValidAttachment( pItemObject->usItem, gpHighLightedItemObject ) )
return( TRUE );
@@ -5653,7 +5642,7 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
}
//if the item is a rocket rifle
if( ItemIsARocketRifle( PlayersOfferArea[ bSlotID ].sItemIndex ) )
if(ItemHasFingerPrintID( PlayersOfferArea[ bSlotID ].sItemIndex ) )
{
fRocketRifleWasEvaluated = TRUE;
}
@@ -5723,8 +5712,7 @@ void EvaluateItemAddedToPlayersOfferArea( INT8 bSlotID, BOOLEAN fFirstOne )
if( armsDealerInfo[ gbSelectedArmsDealerID ].ubTypeOfArmsDealer == ARMS_DEALER_REPAIRS )
{
// only otherwise repairable items count as actual rejections
// if ( Item[ PlayersOfferArea[ bSlotID ].sItemIndex ].fFlags & ITEM_REPAIRABLE )
if ( Item[ PlayersOfferArea[ bSlotID ].sItemIndex ].repairable )
if (ItemIsRepairable(PlayersOfferArea[bSlotID].sItemIndex))
{
uiEvalResult = EVAL_RESULT_DONT_HANDLE;
}
@@ -6363,7 +6351,7 @@ void SplitComplexObjectIntoSubObjects( OBJECTTYPE *pComplexObject )
// strip off any loaded ammo/payload
// Exception: don't do this with rocket launchers, their "shots left" are fake and this screws 'em up!
if ( !Item[usItem].singleshotrocketlauncher ) // Madd rpg - still do this
if ( !ItemIsSingleShotRocketLauncher(usItem)) // Madd rpg - still do this
{
pData->data.gun.usGunAmmoItem = NONE;
pData->data.gun.ubGunShotsLeft = 0;
@@ -6668,7 +6656,7 @@ BOOLEAN CanMercInteractWithSelectedShopkeeper( SOLDIERTYPE *pSoldier )
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, sDestGridNo, bDestLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
{
// Get range to shopkeeper
uiRange = GetRangeFromGridNoDiff( pSoldier->sGridNo, sDestGridNo );
uiRange = PythSpacesAway( pSoldier->sGridNo, sDestGridNo );
// and is close enough to talk to the shopkeeper (use this define INSTEAD of PASSING_ITEM_DISTANCE_OKLIFE!)
if ( uiRange <= NPC_TALK_RADIUS )
+14 -22
View File
@@ -93,6 +93,9 @@ INT32 FindGridNoFromSweetSpot( SOLDIERTYPE *pSoldier, INT32 sSweetGridNo, INT8 u
soldier.pathing.bLevel = 0;
soldier.bTeam = 1;
soldier.sGridNo = sSweetGridNo;
soldier.sDragCorpseID = pSoldier->sDragCorpseID;
soldier.sDragGridNo = pSoldier->sDragGridNo;
soldier.usDragPersonID = pSoldier->usDragPersonID;
sTop = ubRadius;
sBottom = -ubRadius;
@@ -1365,11 +1368,9 @@ void InternalSoldierInSectorSleep( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN
usAnim = STANDING;
}
// OK, look for sutable placement....
// OK, look for suitable placement....
sGoodGridNo = FindGridNoFromSweetSpotWithStructData( pSoldier, usAnim, sGridNo, 5, &ubNewDirection, FALSE );
sWorldX = CenterX( sGoodGridNo );
sWorldY = CenterY( sGoodGridNo );
ConvertGridNoToCenterCellXY(sGoodGridNo, &sWorldX, &sWorldY);
pSoldier->EVENT_SetSoldierPosition( sWorldX, sWorldY );
@@ -1406,11 +1407,9 @@ void SoldierInSectorIncompaciated( SOLDIERTYPE *pSoldier, INT32 sGridNo )
return;
}
// OK, look for sutable placement....
// OK, look for suitable placement....
sGoodGridNo = FindGridNoFromSweetSpotWithStructData( pSoldier, STAND_FALLFORWARD_STOP, sGridNo, 5, &ubNewDirection, FALSE );
sWorldX = CenterX( sGoodGridNo );
sWorldY = CenterY( sGoodGridNo );
ConvertGridNoToCenterCellXY(sGoodGridNo, &sWorldX, &sWorldY);
pSoldier->EVENT_SetSoldierPosition( sWorldX, sWorldY );
@@ -1442,11 +1441,9 @@ void SoldierInSectorPatient( SOLDIERTYPE *pSoldier, INT32 sGridNo )
return;
}
// OK, look for sutable placement....
// OK, look for suitable placement....
sGoodGridNo = FindGridNoFromSweetSpotWithStructData( pSoldier, BEING_PATIENT, sGridNo, 5, &ubNewDirection, FALSE );
sWorldX = CenterX( sGoodGridNo );
sWorldY = CenterY( sGoodGridNo );
ConvertGridNoToCenterCellXY(sGoodGridNo, &sWorldX, &sWorldY);
pSoldier->EVENT_SetSoldierPosition( sWorldX, sWorldY );
@@ -1477,11 +1474,9 @@ void SoldierInSectorDoctor( SOLDIERTYPE *pSoldier, INT32 sGridNo )
return;
}
// OK, look for sutable placement....
// OK, look for suitable placement....
sGoodGridNo = FindGridNoFromSweetSpotWithStructData( pSoldier, BEING_DOCTOR, sGridNo, 5, &ubNewDirection, FALSE );
sWorldX = CenterX( sGoodGridNo );
sWorldY = CenterY( sGoodGridNo );
ConvertGridNoToCenterCellXY(sGoodGridNo, &sWorldX, &sWorldY);
pSoldier->EVENT_SetSoldierPosition( sWorldX, sWorldY );
@@ -1512,11 +1507,9 @@ void SoldierInSectorRepair( SOLDIERTYPE *pSoldier, INT32 sGridNo )
return;
}
// OK, look for sutable placement....
// OK, look for suitable placement....
sGoodGridNo = FindGridNoFromSweetSpotWithStructData( pSoldier, BEING_REPAIRMAN, sGridNo, 5, &ubNewDirection, FALSE );
sWorldX = CenterX( sGoodGridNo );
sWorldY = CenterY( sGoodGridNo );
ConvertGridNoToCenterCellXY(sGoodGridNo, &sWorldX, &sWorldY);
pSoldier->EVENT_SetSoldierPosition( sWorldX, sWorldY );
@@ -1548,8 +1541,7 @@ void AddSoldierToSectorGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubDir
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddSoldierToSectorGridNo"));
// Add merc to gridno
sWorldX = CenterX( sGridNo );
sWorldY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &sWorldX, &sWorldY);
// Set reserved location!
pSoldier->sReservedMovementGridNo = NOWHERE;
+9 -10
View File
@@ -280,7 +280,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
INT16 sXPos, sYPos;
//sNewGridNo = NewGridNo( pSoldier->sGridNo, (UINT16)DirectionInc( pSoldier->ubDirection ) );
ConvertMapPosToWorldTileCenter( pSoldier->sTempNewGridNo, &sXPos, &sYPos );
ConvertGridNoToCenterCellXY( pSoldier->sTempNewGridNo, &sXPos, &sYPos );
pSoldier->EVENT_SetSoldierPosition( (FLOAT)sXPos, (FLOAT)sYPos );
}
@@ -375,8 +375,8 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
{
// sevenfm: breaking window with crowbar code
if (pSoldier->inv[HANDPOS].exists() &&
(Item[pSoldier->inv[HANDPOS].usItem].crowbar && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[pSoldier->inv[HANDPOS].usItem].twohanded && Item[pSoldier->inv[HANDPOS].usItem].metal))
(ItemIsCrowbar(pSoldier->inv[HANDPOS].usItem) && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN && ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) && ItemIsMetal(pSoldier->inv[HANDPOS].usItem)))
{
INT32 sWindowGridNo = pSoldier->sTargetGridNo;
if (pSoldier->ubDirection == NORTH || pSoldier->ubDirection == WEST)
@@ -717,8 +717,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
// CODE: End Hop Fence
// MOVE TO FORCASTED GRIDNO
sX = CenterX( pSoldier->sForcastGridno );
sY = CenterY( pSoldier->sForcastGridno );
ConvertGridNoToCenterCellXY(pSoldier->sForcastGridno, &sX, &sY);
pSoldier->EVENT_InternalSetSoldierPosition( (FLOAT) sX, (FLOAT) sY, FALSE, FALSE, FALSE );
pSoldier->EVENT_SetSoldierDirection( gTwoCDirection[ pSoldier->ubDirection ] );
@@ -1136,10 +1135,10 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
UINT16 usItem = pSoldier->pTempObject->usItem;
UINT16 usBuddyItem = Item[usItem].usBuddyItem;
if (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM &&
(Item[usItem].flare ||
(ItemIsFlare(usItem) ||
Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLARE ||
Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_BURNABLEGAS ||
usBuddyItem && (Item[usBuddyItem].usItemClass & IC_EXPLOSV) && (Item[usBuddyItem].flare || Explosive[Item[usBuddyItem].ubClassIndex].ubType == EXPLOSV_FLARE)))
usBuddyItem && (Item[usBuddyItem].usItemClass & IC_EXPLOSV) && (ItemIsFlare(usBuddyItem) || Explosive[Item[usBuddyItem].ubClassIndex].ubType == EXPLOSV_FLARE)))
{
if ((pSoldier->iMuzFlash = LightSpriteCreate("L-R03.LHT", 0)) != -1)
{
@@ -1806,7 +1805,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
if ( Item[ usItem ].usItemClass == IC_GUN )
{
// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) )
if ( (Item[ usItem ].twohanded ) )
if (ItemIsTwoHanded(usItem))
{
// Set to rifle
ubRandomHandIndex = RANDOM_ANIM_RIFLEINHAND;
@@ -2715,7 +2714,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier )
case BIGBUY_STRECH:
case FEM_KICKSN:
case FEM_WIPE:
if ( pSoldier->inv[ HANDPOS ].exists() == true && Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN && Item[ pSoldier->inv[ HANDPOS ].usItem ].twohanded )
if ( pSoldier->inv[ HANDPOS ].exists() == true && Item[ pSoldier->inv[ HANDPOS ].usItem ].usItemClass == IC_GUN && ItemIsTwoHanded(pSoldier->inv[ HANDPOS ].usItem) )
{
pSoldier->EVENT_InitNewSoldierAnim( RAISE_RIFLE, 0 , FALSE );
return( TRUE );
@@ -4457,7 +4456,7 @@ void CheckForAndHandleSoldierIncompacitated( SOLDIERTYPE *pSoldier )
// SANDRO - if Martial Artist took someone down, always fall back if possible (for the fun)
if ( pSoldier->ubAttackerID != NOBODY && gGameOptions.fNewTraitSystem )
{
if ( HAS_SKILL_TRAIT( MercPtrs[ pSoldier->ubAttackerID ], MARTIAL_ARTS_NT ) && (!MercPtrs[ pSoldier->ubAttackerID ]->usAttackingWeapon || Item[MercPtrs[ pSoldier->ubAttackerID ]->inv[HANDPOS].usItem].brassknuckles ) )
if ( HAS_SKILL_TRAIT( MercPtrs[ pSoldier->ubAttackerID ], MARTIAL_ARTS_NT ) && (!MercPtrs[ pSoldier->ubAttackerID ]->usAttackingWeapon || ItemIsBrassKnuckles(MercPtrs[ pSoldier->ubAttackerID ]->inv[HANDPOS].usItem)) )
{
fAlwaysFallBack = TRUE;
}
+170 -114
View File
@@ -12,7 +12,6 @@
#include "Animation Cache.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "container.h"
#define _USE_MATH_DEFINES // for C
#include <math.h>
#include "pathai.h"
@@ -379,6 +378,10 @@ unsigned int Inventory::size( ) const {
return inv.size( );
}
auto Inventory::get() const -> const std::vector<OBJECTTYPE>& {
return inv;
}
// Assignment operator
Inventory& Inventory::operator=(const Inventory& src)
{
@@ -1339,7 +1342,7 @@ MERCPROFILESTRUCT& MERCPROFILESTRUCT::operator=(const OLD_MERCPROFILESTRUCT_101&
this->bSex = src.bSex;
this->bArmourAttractiveness = src.bArmourAttractiveness;
this->ubMiscFlags2 = src.ubMiscFlags2;
this->bEvolution = src.bEvolution;
this->fRegresses = src.bEvolution == 2; // formerly, 2 == CharacterEvolution::DEVOLVES
this->ubMiscFlags = src.ubMiscFlags;
this->bSexist = src.bSexist;
this->bLearnToHate = src.bLearnToHate;
@@ -3014,7 +3017,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
}
else
{
if (Item[usItem].flare ||
if (ItemIsFlare(usItem) ||
Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_SIGNAL_SMOKE ||
Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_FLARE)
{
@@ -3156,7 +3159,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// Going from shoulder stance to hip stance
else if ( usNewState == READY_ALTERNATIVE_STAND && (gAnimControl[this->usAnimState].uiFlags & (ANIM_FIREREADY | ANIM_FIRE)) )
{
if ( Item[this->inv[HANDPOS].usItem].twohanded )
if (ItemIsTwoHanded(this->inv[HANDPOS].usItem))
usStartingAniCode = 1;
else
usStartingAniCode = 2;
@@ -3275,7 +3278,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// 1) We have a rifle in hand...
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[HANDPOS].exists( ) == true && (Item[usItem].twohanded) && !Item[usItem].rocketlauncher )
if ( this->inv[HANDPOS].exists( ) == true && ItemIsTwoHanded(usItem) && !ItemIsRocketLauncher(usItem) )
{
// Switch on height!
switch ( gAnimControl[this->usAnimState].ubEndHeight )
@@ -3298,7 +3301,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// 1) We have a rifle in hand...
//usItem = this->inv[ HANDPOS ].usItem;
if ( this->inv[HANDPOS].exists( ) == true && (Item[usItem].twohanded) && !Item[usItem].rocketlauncher )
if ( this->inv[HANDPOS].exists( ) == true && ItemIsTwoHanded(usItem) && !ItemIsRocketLauncher(usItem) )
{
// Switch on height!
switch ( gAnimControl[this->usAnimState].ubEndHeight )
@@ -3426,10 +3429,10 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( this->inv[HANDPOS].exists( ) == true )
{
if ( Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
if ( Item[usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(usItem) )
{
// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) )
if ( (Item[usItem].twohanded) )
if (ItemIsTwoHanded(usItem))
{
usNewState = BIGMERC_CROUCH_TRANS_INTO;
}
@@ -3446,10 +3449,10 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( this->inv[HANDPOS].exists( ) == true )
{
if ( Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
if ( Item[usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(usItem) )
{
// if ( (Item[ usItem ].fFlags & ITEM_TWO_HANDED) )
if ( (Item[usItem].twohanded) )
if (ItemIsTwoHanded(usItem))
{
usNewState = BIGMERC_CROUCH_TRANS_OUTOF;
}
@@ -3474,7 +3477,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
if ( ((gAnimControl[this->usAnimState].uiFlags & ANIM_FIREREADY) ||
(gAnimControl[this->usAnimState].uiFlags & ANIM_FIRE)) && gGameExternalOptions.fAllowWalkingWithWeaponRaised )
{
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(usItem) )
{
if ( gAnimControl[this->usAnimState].ubEndHeight == ANIM_STAND )
{
@@ -3521,7 +3524,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
{
if ( gAnimControl[this->usAnimState].ubEndHeight == ANIM_CROUCH )
{
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && Item[usItem].twohanded && !Item[usItem].rocketlauncher )
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && ItemIsTwoHanded(usItem) && !ItemIsRocketLauncher(usItem) )
usNewState = SWAT_BACKWARDS;
else
usNewState = SWAT_BACKWARDS_NOTHING;
@@ -3592,7 +3595,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
// SANDRO - check if we are gonna move with weapon raised
else if ( gGameExternalOptions.fAllowWalkingWithWeaponRaised && ( (gAnimControl[this->usAnimState].uiFlags & ANIM_FIREREADY) || (gAnimControl[this->usAnimState].uiFlags & ANIM_FIRE) ) )
{
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && !Item[usItem].rocketlauncher )
if ( this->inv[HANDPOS].exists( ) == true && Item[usItem].usItemClass == IC_GUN && !ItemIsRocketLauncher(usItem) )
{
if ( usNewState == WALKING )
{
@@ -3615,7 +3618,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
{
usNewState = CROUCHEDMOVE_DUAL_READY;
}
else if ( !Item[this->inv[HANDPOS].usItem].twohanded )
else if (!ItemIsTwoHanded(this->inv[HANDPOS].usItem))
{
usNewState = CROUCHEDMOVE_PISTOL_READY;
}
@@ -3988,7 +3991,7 @@ BOOLEAN SOLDIERTYPE::EVENT_InitNewSoldierAnim( UINT16 usNewState, UINT16 usStart
case PLANT_BOMB:
if ( Item[this->inv[HANDPOS].usItem].mine == 1 ) // bury a mine
if (ItemIsMine(this->inv[HANDPOS].usItem)) // bury a mine
DeductPoints( this, GetAPsToPlantMine( this ), APBPConstants[BP_BURY_MINE] ); // changed by SANDRO
else
DeductPoints( this, GetAPsToDropBomb( this ), APBPConstants[BP_DROP_BOMB] ); // changed by SANDRO
@@ -4957,9 +4960,9 @@ void SOLDIERTYPE::EVENT_FireSoldierWeapon( INT32 sTargetGridNo )
usItem = GetAttachedGrenadeLauncher( &this->inv[HANDPOS] );
else
usItem = this->inv[HANDPOS].usItem;
if ( Item[usItem].rocketlauncher || Item[usItem].grenadelauncher || Item[usItem].mortar )
if (ItemIsRocketLauncher(usItem) || ItemIsGrenadeLauncher(usItem) || ItemIsMortar(usItem) )
{
if ( gAnimControl[this->usAnimState].ubEndHeight == ANIM_PRONE || Item[usItem].mortar && gAnimControl[this->usAnimState].ubEndHeight == ANIM_STAND )
if ( gAnimControl[this->usAnimState].ubEndHeight == ANIM_PRONE || ItemIsMortar(usItem) && gAnimControl[this->usAnimState].ubEndHeight == ANIM_STAND )
SendChangeSoldierStanceEvent( this, ANIM_CROUCH );
fDoFireRightAway = TRUE;
}
@@ -5041,8 +5044,10 @@ void SOLDIERTYPE::EVENT_FireSoldierWeapon( INT32 sTargetGridNo )
}
else if (!TileIsOutOfBounds(sTargetGridNo) && !GridNoOnScreen(sTargetGridNo))
{
INT16 sNewCenterWorldX = CenterX(sTargetGridNo);
INT16 sNewCenterWorldY = CenterY(sTargetGridNo);
INT16 sNewCenterWorldX;
INT16 sNewCenterWorldY;
ConvertGridNoToCenterCellXY(sTargetGridNo, &sNewCenterWorldX, &sNewCenterWorldY);
SetRenderCenter(sNewCenterWorldX, sNewCenterWorldY);
// Plot new path!
@@ -5113,7 +5118,7 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight )
}
// Check for rocket laucncher....
if ( Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
if (ItemIsRocketLauncher(pSoldier->inv[HANDPOS].usItem))
{
//***ddd if shoot crouched
if ( ubHeight == ANIM_STAND )
@@ -5123,14 +5128,14 @@ UINT16 SelectFireAnimation( SOLDIERTYPE *pSoldier, UINT8 ubHeight )
}
// Check for mortar....
if ( Item[pSoldier->inv[HANDPOS].usItem].mortar )
if (ItemIsMortar(pSoldier->inv[HANDPOS].usItem))
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "SelectFireAnimation: shoot_mortar" );
return(SHOOT_MORTAR);
}
// Check for tank cannon
if ( Item[pSoldier->inv[HANDPOS].usItem].cannon )
if (ItemIsCannon(pSoldier->inv[HANDPOS].usItem))
{
return(TANK_SHOOT);
}
@@ -5442,7 +5447,7 @@ BOOLEAN SOLDIERTYPE::InternalSoldierReadyWeapon( UINT8 sFacingDir, BOOLEAN fEndR
}
//dnl ch72 270913 ugly but fast fix for not charging turning APs as there is no fire ready animation for mortars and rocket launchers
UINT16 usItem = this->inv[HANDPOS].usItem;
if ( Item[usItem].rocketlauncher || Item[usItem].mortar )
if (ItemIsRocketLauncher(usItem) || ItemIsMortar(usItem) )
usForceAnimState = this->usAnimState;
EVENT_InternalSetSoldierDesiredDirection( this, sFacingDir, FALSE, usAnimState );
usForceAnimState = INVALID_ANIMATION;
@@ -5530,12 +5535,12 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOL
}
// Check if we have a gun.....
if ( Item[pSoldier->inv[HANDPOS].usItem].usItemClass != IC_GUN && !Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher )
if ( Item[pSoldier->inv[HANDPOS].usItem].usItemClass != IC_GUN && !ItemIsGrenadeLauncher(pSoldier->inv[HANDPOS].usItem) )
{
return(INVALID_ANIMATION);
}
if ( Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
if (ItemIsRocketLauncher(pSoldier->inv[HANDPOS].usItem))
{
return(INVALID_ANIMATION);
}
@@ -5616,7 +5621,7 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOL
// this is a specific situation when we have a gun in standard holding (shouldered rifle/two-hand pistol) and was told to go to alternative holding
else if ( (gAnimControl[pSoldier->usAnimState].uiFlags & (ANIM_FIREREADY | ANIM_FIRE)) && !(gAnimControl[pSoldier->usAnimState].uiFlags & (ANIM_ALT_WEAPON_HOLDING))
&& fAltWeaponHolding && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 && pSoldier->bScopeMode == -1 && gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_STAND
&& ((!Item[pSoldier->inv[HANDPOS].usItem].twohanded && !pSoldier->IsValidSecondHandShot( ) && !pSoldier->MercInWater( )) || Item[pSoldier->inv[HANDPOS].usItem].twohanded) )
&& ((!ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) && !pSoldier->IsValidSecondHandShot( ) && !pSoldier->MercInWater( )) || ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem)) )
{
return(READY_ALTERNATIVE_STAND);
}
@@ -5636,7 +5641,7 @@ UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady, BOOL
{
if ( gGameExternalOptions.ubAllowAlternativeWeaponHolding )
{
if ( fAltWeaponHolding || (Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].HeavyGun && Item[pSoldier->inv[HANDPOS].usItem].twohanded) )
if ( fAltWeaponHolding || (Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].HeavyGun && ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem)) )
{
return(READY_ALTERNATIVE_STAND);
}
@@ -5872,7 +5877,7 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
{
if ( ubAttackerID != NOBODY )
{
if ( !(MercPtrs[ubAttackerID]->inv[HANDPOS].exists( )) || Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].brassknuckles )
if ( !(MercPtrs[ubAttackerID]->inv[HANDPOS].exists( )) || ItemIsBrassKnuckles(MercPtrs[ubAttackerID]->inv[HANDPOS].usItem) )
{
// with enhanced CCS, make the lost breath harder to regenerate, which makes CQC more usable
if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
@@ -5939,7 +5944,7 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
if ( HasItemFlag( usWeaponIndex, TASER ) )
{
// tasers need batteries, because I say so
if ( Item[usWeaponIndex].needsbatteries )
if (ItemNeedsBatteries(usWeaponIndex))
{
// check for batteries
OBJECTTYPE* pBatteries = FindAttachedBatteries( &(MercPtrs[ubAttackerID]->inv[HANDPOS]) );
@@ -7359,7 +7364,7 @@ void SOLDIERTYPE::EVENT_InternalSetSoldierDestination( UINT16 usNewDirection, BO
// Get dest gridno, convert to center coords
sNewGridNo = NewGridNo( this->sGridNo, DirectionInc( (UINT8)usNewDirection ) );
ConvertMapPosToWorldTileCenter( sNewGridNo, &sXPos, &sYPos );
ConvertGridNoToCenterCellXY( sNewGridNo, &sXPos, &sYPos );
// Save new dest gridno, x, y
this->pathing.sDestination = sNewGridNo;
@@ -9729,7 +9734,7 @@ BOOLEAN SOLDIERTYPE::CanClimbWithCurrentBackpack()
// only apply backpack climbing limitations to player mercs
if (UsingNewInventorySystem() == true && this->inv[BPACKPOCKPOS].exists() == true && this->bTeam == OUR_TEAM
&& ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)this->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[this->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb)
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[this->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE)))
&& ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || !ItemAllowsClimbing(this->inv[BPACKPOCKPOS].usItem)))
return FALSE;
return TRUE;
@@ -10434,7 +10439,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
&& this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_ARMS ) )
{
// drop item in main hand if twohanded
if ( this->inv[HANDPOS].exists() == true && TwoHandedItem( this->inv[HANDPOS].usItem ) )
if ( this->inv[HANDPOS].exists() == true && ItemIsTwoHanded( this->inv[HANDPOS].usItem ) )
dropiteminmainhand = true;
// we can only use one hand, so drop items in second hand
@@ -10700,6 +10705,22 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr
return(ubCombinedLoss);
}
void SOLDIERTYPE::SoldierTakeDelayedDamage(INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathLoss, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage)
{
delayedDamageFunction = [this, bHeight, sLifeDeduct, sBreathLoss, ubReason, ubAttacker, sSourceGrid, sSubsequent, fShowDamage]()
{
this->SoldierTakeDamage(bHeight, sLifeDeduct, sBreathLoss, ubReason, ubAttacker, sSourceGrid, sSubsequent, fShowDamage);
};
}
void SOLDIERTYPE::ResolveDelayedDamage()
{
if (delayedDamageFunction)
{
delayedDamageFunction();
delayedDamageFunction = nullptr;
}
}
extern BOOLEAN IsMercSayingDialogue( UINT8 ubProfileID );
@@ -11499,6 +11520,8 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR
// OK, set new position
this->EVENT_InternalSetSoldierPosition( dXPos, dYPos, FALSE, FALSE, FALSE );
this->ResolveDelayedDamage();
// Flugente: drag people
if ( currentlydragging )
{
@@ -11526,7 +11549,7 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR
{
INT16 this_base_x = 0;
INT16 this_base_y = 0;
ConvertMapPosToWorldTileCenter( this->sGridNo, &this_base_x, &this_base_y );
ConvertGridNoToCenterCellXY( this->sGridNo, &this_base_x, &this_base_y );
dx = this->dXPos - this_base_x;
dy = this->dYPos - this_base_y;
@@ -11534,7 +11557,7 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR
INT16 base_x = 0;
INT16 base_y = 0;
ConvertMapPosToWorldTileCenter( gridnotouse, &base_x, &base_y );
ConvertGridNoToCenterCellXY( gridnotouse, &base_x, &base_y );
pSoldier->EVENT_InternalSetSoldierPosition( base_x + dx, base_y + dy, FALSE, FALSE, FALSE );
}
@@ -11568,27 +11591,33 @@ void SOLDIERTYPE::MoveMerc( FLOAT dMovementChange, FLOAT dAngle, BOOLEAN fCheckR
// adjust both gridno and x,y coordinates
if (sOldGridNo != this->sGridNo)
{
CorpseDef.sGridNo = sOldGridNo;
CorpseDef.dXPos = CenterX(CorpseDef.sGridNo);
CorpseDef.dYPos = CenterY(CorpseDef.sGridNo);
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sOldGridNo, &sX, &sY);
CorpseDef.sGridNo = sOldGridNo;
CorpseDef.dXPos = sX;
CorpseDef.dYPos = sY;
}
else
{
// move corpse a bit
INT16 this_base_x = 0;
INT16 this_base_y = 0;
ConvertMapPosToWorldTileCenter(this->sGridNo, &this_base_x, &this_base_y);
ConvertGridNoToCenterCellXY(this->sGridNo, &this_base_x, &this_base_y);
FLOAT dx = this->dXPos - this_base_x;
FLOAT dy = this->dYPos - this_base_y;
INT16 base_x = 0;
INT16 base_y = 0;
ConvertMapPosToWorldTileCenter(pCorpse->def.sGridNo, &base_x, &base_y);
ConvertGridNoToCenterCellXY(pCorpse->def.sGridNo, &base_x, &base_y);
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pCorpse->def.sGridNo, &sX, &sY);
CorpseDef.sGridNo = pCorpse->def.sGridNo;
CorpseDef.dXPos = CenterX(CorpseDef.sGridNo) + dx;
CorpseDef.dYPos = CenterY(CorpseDef.sGridNo) + dy;
CorpseDef.dXPos = sX + dx;
CorpseDef.dYPos = sY + dy;
}
CorpseDef.usFlags |= ROTTING_CORPSE_USE_XY_PROVIDED;
@@ -11750,6 +11779,17 @@ UINT8 GetDirectionFromXY( INT16 sXPos, INT16 sYPos, SOLDIERTYPE *pSoldier )
return(atan8( sXPos2, sYPos2, sXPos, sYPos ));
}
INT16 GetDirectionFromCenterCellXYGridNo(INT32 EndGridNo, INT32 StartGridNo)
{
INT16 sXPos2, sYPos2;
INT16 sXPos, sYPos;
ConvertGridNoToCenterCellXY(StartGridNo, &sXPos, &sYPos);
ConvertGridNoToCenterCellXY(EndGridNo, &sXPos2, &sYPos2);
return(atan8(sXPos2, sYPos2, sXPos, sYPos));
}
//#if 0
UINT8 atan8( INT16 sXPos, INT16 sYPos, INT16 sXPos2, INT16 sYPos2 )
@@ -12243,8 +12283,7 @@ void SOLDIERTYPE::ReviveSoldier( void )
this->BeginSoldierGetup( );
// Makesure center of tile
sX = CenterX( this->sGridNo );
sY = CenterY( this->sGridNo );
ConvertGridNoToCenterCellXY(this->sGridNo, &sX, &sY);
this->EVENT_SetSoldierPosition( (FLOAT)sX, (FLOAT)sY );
@@ -12724,9 +12763,9 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
//Ja25 No meanwhiles
#ifdef JA2UB
if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE )
if ( fMartialArtist && !ItemIsCrowbar(usItem) && this->ubBodyType == REGMALE )
#else
if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie( )
if ( fMartialArtist && !AreInMeanwhile( ) && !ItemIsCrowbar(usItem) && this->ubBodyType == REGMALE && !IsZombie( )
&& !( gGameExternalOptions.fDiseaseSevereLimitations && this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS )) ) // SANDRO - added check for body type
#endif
{
@@ -12832,7 +12871,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio
case ANIM_STAND:
case ANIM_CROUCH:
if ( !Item[usItem].crowbar )
if ( !ItemIsCrowbar(usItem) )
{
BOOLEAN fCannotKick = (ubDirection & 1);
// SANDRO - we will determine here what type of punch we are gonna use
@@ -13056,7 +13095,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginDropBomb( )
void SOLDIERTYPE::EVENT_SoldierDefuseTripwire( INT32 sGridNo, INT32 sItem )
{
// Flugente: if item is tripwireactivated and is a planted bomb, call the defuse dialogue. We obviously know about the item's existence already...
if ( gWorldItems[sItem].object.exists( ) && gWorldItems[sItem].object.fFlags & OBJECT_ARMED_BOMB && Item[gWorldItems[sItem].object.usItem].tripwire == 1 )
if ( gWorldItems[sItem].object.exists( ) && gWorldItems[sItem].object.fFlags & OBJECT_ARMED_BOMB && ItemIsTripwire(gWorldItems[sItem].object.usItem) )
{
// Increment the number of people busy doing stuff because of an attack
switch ( gAnimControl[this->usAnimState].ubHeight )
@@ -13109,7 +13148,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginFirstAid( INT32 sGridNo, UINT8 ubDirection )
//SANDRO - hack! Find out if we are a doctor with medical bag trying to make a surgery
this->fDoingSurgery = FALSE;
if ( (NUM_SKILL_TRAITS( this, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery) && Item[this->inv[HANDPOS].usItem].medicalkit && gGameOptions.fNewTraitSystem )
if ( (NUM_SKILL_TRAITS( this, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery) && ItemIsMedicalKit(this->inv[HANDPOS].usItem) && gGameOptions.fNewTraitSystem )
{
if ( ((pTSoldier->bTeam == OUR_TEAM) || (pTSoldier->bTeam == MILITIA_TEAM))
&& (IS_MERC_BODY_TYPE( pTSoldier ) || IS_CIV_BODY_TYPE( pTSoldier ))
@@ -13281,7 +13320,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
// Flugente: AI medics are allowed to perform surgery without first aid kits, and can do this on themselves
if ( pVictim->iHealableInjury > 0 && this->fDoingSurgery && (this->ubID != pVictim->ubID || (gGameExternalOptions.fEnemyMedicsHealSelf && this->bTeam == ENEMY_TEAM))
&& gGameOptions.fNewTraitSystem && (NUM_SKILL_TRAITS( this, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery)
&& (Item[this->inv[HANDPOS].usItem].medicalkit || this->bTeam == ENEMY_TEAM) )
&& (ItemIsMedicalKit(this->inv[HANDPOS].usItem) || this->bTeam == ENEMY_TEAM) )
{
fOnSurgery = TRUE;
}
@@ -13320,7 +13359,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
return(0);
// using the GOOD medic stuff
if ( Item[this->inv[HANDPOS].usItem].medicalkit && !(fOnSurgery) ) // added check
if (ItemIsMedicalKit(this->inv[HANDPOS].usItem) && !(fOnSurgery) ) // added check
{
uiPossible += (uiPossible / 2); // add extra 50 %
}
@@ -13378,7 +13417,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
}
// now make sure we HAVE that much
if ( Item[this->inv[HANDPOS].usItem].medicalkit )
if (ItemIsMedicalKit(this->inv[HANDPOS].usItem))
{
if ( fOnSurgery )
uiMedcost = (uiActual * gSkillTraitValues.usDOSurgeryMedBagConsumption) / 100; // surgery drains the kit a lot
@@ -13626,7 +13665,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
// usedAPs equals (actionPts) * (%of possible points actually used)
uiUsedAPs = (uiActual * uiAvailAPs) / uiPossible;
if ( Item[this->inv[HANDPOS].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
if (ItemIsMedicalKit(this->inv[HANDPOS].usItem) && !(fOnSurgery) ) // using the GOOD medic stuff
{
uiUsedAPs = (uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds
}
@@ -13944,8 +13983,7 @@ void SOLDIERTYPE::EVENT_StopMerc( INT32 sGridNo, INT8 bDirection )
// MOVE GUY TO GRIDNO--- SHOULD BE THE SAME UNLESS IN MULTIPLAYER
// Makesure center of tile
sX = CenterX( sGridNo );
sY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
//Cancel pending events
if ( !this->flags.fDelayedMovement )
@@ -14033,7 +14071,7 @@ void SOLDIERTYPE::ReLoadSoldierAnimationDueToHandItemChange( UINT16 usOldItem, U
this->bWeaponMode = WM_ATTACHED_GL;
}
if ( Item[usNewItem].twohanded && Weapon[usNewItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
if (ItemIsTwoHanded(usNewItem) && Weapon[usNewItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
this->bScopeMode = USE_ALT_WEAPON_HOLD;
else
this->bScopeMode = USE_BEST_SCOPE;
@@ -14056,8 +14094,7 @@ void SOLDIERTYPE::ReLoadSoldierAnimationDueToHandItemChange( UINT16 usOldItem, U
{
if ( Item[usOldItem].usItemClass == IC_GUN )
{
// if ( (Item[ usOldItem ].fFlags & ITEM_TWO_HANDED) && usOldItem != ROCKET_LAUNCHER )
if ( (Item[usOldItem].twohanded) && !Item[usOldItem].rocketlauncher )
if (ItemIsTwoHanded(usOldItem) && !ItemIsRocketLauncher(usOldItem))
{
fOldRifle = TRUE;
}
@@ -14068,8 +14105,7 @@ void SOLDIERTYPE::ReLoadSoldierAnimationDueToHandItemChange( UINT16 usOldItem, U
{
if ( Item[usNewItem].usItemClass == IC_GUN )
{
// if ( (Item[ usNewItem ].fFlags & ITEM_TWO_HANDED) && usNewItem != ROCKET_LAUNCHER )
if ( (Item[usNewItem].twohanded) && !Item[usNewItem].rocketlauncher )
if (ItemIsTwoHanded(usNewItem) && !ItemIsRocketLauncher(usNewItem))
{
fNewRifle = TRUE;
}
@@ -14594,7 +14630,7 @@ BOOLEAN SOLDIERTYPE::SoldierCarriesTwoHandedWeapon( void )
usItem = this->inv[HANDPOS].usItem;
if ( this->inv[HANDPOS].exists( ) == true && (Item[usItem].twohanded) )
if ( this->inv[HANDPOS].exists( ) == true && ItemIsTwoHanded(usItem) )
{
return(TRUE);
}
@@ -15491,7 +15527,7 @@ BOOLEAN SOLDIERTYPE::LooksLikeACivilian( void )
{
// if that item is a gun, explosives, military armour or facewear, we're screwed
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_WEAPON | IC_GRENADE | IC_BOMB)) ||
((Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR)) && !Item[this->inv[bLoop].usItem].leatherjacket && Armour[Item[this->inv[bLoop].usItem].ubClassIndex].ubProtection > 10) ||
((Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR)) && !ItemIsLeatherJacket(this->inv[bLoop].usItem) && Armour[Item[this->inv[bLoop].usItem].ubClassIndex].ubProtection > 10) ||
(Item[this->inv[bLoop].usItem].nightvisionrangebonus > 0 || Item[this->inv[bLoop].usItem].hearingrangebonus > 0)
)
{
@@ -15513,7 +15549,7 @@ BOOLEAN SOLDIERTYPE::LooksLikeACivilian( void )
{
// if that item is a gun, explosives, military armour or facewear, we're screwed
if ( (Item[this->inv[bLoop].usItem].usItemClass & (IC_WEAPON | IC_GRENADE | IC_BOMB)) ||
((Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR)) && !Item[this->inv[bLoop].usItem].leatherjacket && Armour[Item[this->inv[bLoop].usItem].ubClassIndex].ubProtection > 10) ||
((Item[this->inv[bLoop].usItem].usItemClass & (IC_ARMOUR)) && !ItemIsLeatherJacket(this->inv[bLoop].usItem) && Armour[Item[this->inv[bLoop].usItem].ubClassIndex].ubProtection > 10) ||
(Item[this->inv[bLoop].usItem].nightvisionrangebonus > 0 || Item[this->inv[bLoop].usItem].hearingrangebonus > 0)
)
{
@@ -15844,7 +15880,7 @@ BOOLEAN SOLDIERTYPE::SeemsLegit( UINT16 ubObserverID )
}
UINT8 covertlevel = NUM_SKILL_TRAITS( this, COVERT_NT ); // our level in covert operations
INT32 distance = GetRangeFromGridNoDiff( this->sGridNo, pSoldier->sGridNo );
INT32 distance = PythSpacesAway( this->sGridNo, pSoldier->sGridNo );
// if we are closer than this, our cover will always break if we do not have the skill
// if we have the skill, our cover will blow if we dress up as a soldier, but not if we are dressed like a civilian
@@ -16810,7 +16846,7 @@ void SOLDIERTYPE::DropSectorEquipment( )
if ( pObj->exists( ) )
{
// Check if it's supposed to be dropped
if ( !((*pObj).fFlags & OBJECT_UNDROPPABLE) && !(Item[pObj->usItem].defaultundroppable) && (*pObj)[0]->data.sObjectFlag & TAKEN_BY_MILITIA )
if ( !((*pObj).fFlags & OBJECT_UNDROPPABLE) && !ItemIsUndroppableByDefault(pObj->usItem) && (*pObj)[0]->data.sObjectFlag & TAKEN_BY_MILITIA )
{
(*pObj)[0]->data.sObjectFlag &= ~TAKEN_BY_MILITIA;
@@ -16836,7 +16872,7 @@ void SOLDIERTYPE::DropSectorEquipment( )
if ( pObj->exists( ) )
{
// Check if it's supposed to be dropped
if ( !((*pObj).fFlags & OBJECT_UNDROPPABLE) && !(Item[pObj->usItem].defaultundroppable) && (*pObj)[0]->data.sObjectFlag & TAKEN_BY_MILITIA )
if ( !((*pObj).fFlags & OBJECT_UNDROPPABLE) && !ItemIsUndroppableByDefault(pObj->usItem) && (*pObj)[0]->data.sObjectFlag & TAKEN_BY_MILITIA )
{
(*pObj)[0]->data.sObjectFlag &= ~TAKEN_BY_MILITIA;
@@ -16906,12 +16942,13 @@ void SOLDIERTYPE::TakeNewBombFromInventory( UINT16 usItem )
// take tripwire-activated item only if used item is tripwire activated
for ( i = 0; i < invsize; i++ )
{
UINT16 usItem = this->inv[i].usItem;
if ( this->inv[i].exists( ) == true &&
Item[this->inv[i].usItem].usItemClass == IC_BOMB &&
Item[this->inv[i].usItem].ubCursor == BOMBCURS &&
!Item[this->inv[i].usItem].tripwire &&
((Item[this->inv[i].usItem].tripwireactivation && Item[usItem].tripwireactivation) ||
(!Item[this->inv[i].usItem].tripwireactivation && !Item[usItem].tripwireactivation)) )
Item[usItem].usItemClass == IC_BOMB &&
Item[usItem].ubCursor == BOMBCURS &&
!ItemIsTripwire(usItem) &&
((ItemHasTripwireActivation(usItem) && ItemHasTripwireActivation(usItem)) ||
(!ItemHasTripwireActivation(usItem) && !ItemHasTripwireActivation(usItem))) )
{
this->inv[i].MoveThisObjectTo( this->inv[HANDPOS], 1, this );
return;
@@ -17034,7 +17071,7 @@ void SOLDIERTYPE::SwitchWeapons( BOOLEAN fKnife, BOOLEAN fSideArm )
else
handCanMove = (CanItemFitInPosition( this, &this->inv[HANDPOS], handobjstorageslot, FALSE ) || (this->inv[HANDPOS].exists( ) == false && this->inv[SECONDHANDPOS].exists( ) == false));
if ( Item[this->inv[retrieveslot].usItem].twohanded && this->inv[SECONDHANDPOS].exists( ) == true )
if ( ItemIsTwoHanded(this->inv[retrieveslot].usItem) && this->inv[SECONDHANDPOS].exists( ) == true )
searchitemCanMove = FALSE;
else
searchitemCanMove = (CanItemFitInPosition( this, &this->inv[retrieveslot], HANDPOS, FALSE ) || this->inv[retrieveslot].exists( ) == false);
@@ -17133,7 +17170,7 @@ INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubT
{
// Bonus for heavy weapons moved here from above to get instant CtH bonus and not marksmanship bonus,
// which is supressed by weapon condition
if ( Item[usItem].rocketlauncher || Item[usItem].singleshotrocketlauncher )
if (ItemIsRocketLauncher(usItem) || ItemIsSingleShotRocketLauncher(usItem))
{
modifier += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!!
@@ -17587,6 +17624,24 @@ INT16 SOLDIERTYPE::GetBackgroundValue( UINT16 aNr )
return 0;
}
const std::vector<INT16>& SOLDIERTYPE::GetBackgroundValueVector(BackgroundVectorTypes backgroundVectorType) const
{
static const std::vector<INT16> emptyVector;
if (UsingBackGroundSystem() && this->ubProfile != NO_PROFILE)
{
const BACKGROUND_VALUES& background = zBackground[gMercProfiles[this->ubProfile].usBackground];
auto iterator = background.valueVectors.find(backgroundVectorType);
if (iterator != background.valueVectors.end())
{
return iterator->second;
}
}
return emptyVector;
}
INT8 SOLDIERTYPE::GetSuppressionResistanceBonus( )
{
INT8 bonus = 0;
@@ -17811,7 +17866,7 @@ void SOLDIERTYPE::SoldierPropertyUpkeep( )
if ( this->usSkillCooldown[SOLDIER_COOLDOWN_DRUGUSER_COMBAT] )
this->usSkillCooldown[SOLDIER_COOLDOWN_DRUGUSER_COMBAT]--;
if (AM_A_ROBOT(this) && Item[this->inv[ROBOT_UTILITY_SLOT].usItem].xray == 1)
if (AM_A_ROBOT(this) && ItemHasXRay(this->inv[ROBOT_UTILITY_SLOT].usItem))
{
if (this->usSkillCooldown[SOLDIER_COOLDOWN_ROBOT_XRAY])
this->usSkillCooldown[SOLDIER_COOLDOWN_ROBOT_XRAY]--;
@@ -18499,7 +18554,7 @@ BOOLEAN SOLDIERTYPE::HasMortar( )
INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop )
{
if ( inv[bLoop].exists( ) == true && Item[inv[bLoop].usItem].mortar )
if ( inv[bLoop].exists( ) == true && ItemIsMortar(inv[bLoop].usItem) )
{
return TRUE;
}
@@ -18515,7 +18570,7 @@ BOOLEAN SOLDIERTYPE::GetSlotOfSignalShellIfMortar( UINT8* pbLoop )
INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop )
{
if ( inv[bLoop].exists( ) == true && Item[inv[bLoop].usItem].mortar )
if ( inv[bLoop].exists( ) == true && ItemIsMortar(inv[bLoop].usItem) )
{
mortaritem = inv[bLoop].usItem;
break;
@@ -18534,7 +18589,7 @@ BOOLEAN SOLDIERTYPE::GetSlotOfSignalShellIfMortar( UINT8* pbLoop )
return TRUE;
}
if ( Item[inv[bLoop].usItem].mortar )
if (ItemIsMortar(inv[bLoop].usItem))
{
OBJECTTYPE* pAttObj = FindAttachmentByClass( &(inv[bLoop]), IC_BOMB );
@@ -18823,7 +18878,7 @@ BOOLEAN SOLDIERTYPE::OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridN
for ( INT8 bLoop = 0; (bLoop < invsize) && (mortaritemcnt < maxFiringMortarsAmount); ++bLoop )
{
if ( pSoldier->inv[bLoop].exists( ) == true && Item[pSoldier->inv[bLoop].usItem].mortar )
if ( pSoldier->inv[bLoop].exists( ) == true && ItemIsMortar(pSoldier->inv[bLoop].usItem))
{
// if not already in list, remember this mortar
bool alreadyInList = false;
@@ -18868,7 +18923,7 @@ BOOLEAN SOLDIERTYPE::OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridN
{
if ( pSoldier->inv[bLoop].exists( ) == true )
{
if ( Item[pSoldier->inv[bLoop].usItem].mortar )
if (ItemIsMortar(pSoldier->inv[bLoop].usItem))
{
OBJECTTYPE* pAttObj = FindAttachmentByClass( &(pSoldier->inv[bLoop]), IC_BOMB );
@@ -19883,22 +19938,19 @@ FLOAT SOLDIERTYPE::GetDiseaseContactProtection( )
// if we wear special equipment, lower our chances of being infected
FLOAT bestfacegear = 0.0f;
FLOAT bestprotectivegear = 0.0f;
INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly
for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop )
for ( const auto &item : inv.get() )
{
if ( inv[bLoop].exists( ) )
if ( item.exists( ) )
{
OBJECTTYPE* pObj = &(inv[bLoop]);
if ( pObj && (*pObj)[0]->data.objectStatus >= USABLE )
if ( item[0]->data.objectStatus >= USABLE )
{
if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_1 ) )
if ( HasItemFlag( item.usItem, DISEASEPROTECTION_1 ) )
{
bestfacegear = max( bestfacegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) );
bestfacegear = max( bestfacegear, (FLOAT)(item[0]->data.objectStatus / 100) );
}
if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_2 ) )
if ( HasItemFlag( item.usItem, DISEASEPROTECTION_2 ) )
{
bestprotectivegear = max( bestprotectivegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) );
bestprotectivegear = max( bestprotectivegear, (FLOAT)(item[0]->data.objectStatus / 100) );
}
}
}
@@ -20830,7 +20882,7 @@ void SOLDIERTYPE::CancelDrag()
{
INT16 base_x = 0;
INT16 base_y = 0;
ConvertMapPosToWorldTileCenter(pSoldier->sGridNo, &base_x, &base_y);
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &base_x, &base_y);
pSoldier->EVENT_InternalSetSoldierPosition(base_x, base_y, FALSE, FALSE, FALSE);
}
@@ -21820,6 +21872,8 @@ void SoldierCollapse( SOLDIERTYPE *pSoldier )
pSoldier->bCollapsed = TRUE;
pSoldier->usUIMovementMode = CRAWLING;
pSoldier->ReceivingSoldierCancelServices( );
// CC has requested - handle sight here...
@@ -22375,7 +22429,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginAttachCan( INT32 sGridNo, UINT8 ubDirection
// OK, find door, attach to door, do animation...., remove item....
// First make sure we still have item in hand....
if ( !Item[this->inv[HANDPOS].usItem].canandstring )
if ( !ItemIsCanAndString(this->inv[HANDPOS].usItem))
{
return;
}
@@ -22687,7 +22741,7 @@ void SOLDIERTYPE::EVENT_SoldierApplyItemToPerson( INT32 sGridNo, UINT8 ubDirecti
if ( success )
{
if ( Item[usItem].gasmask )
if (ItemIsGasmask(usItem))
{
// put this item into a (at best empty) faceslot if no gasmask is been worn
INT8 bSlot = FindGasMask( pSoldier );
@@ -23162,7 +23216,7 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT16 ubTargetID, BOOLEAN fVali
return(FALSE);
}
uiRange = GetRangeFromGridNoDiff( this->sGridNo, pTSoldier->sGridNo );
uiRange = PythSpacesAway( this->sGridNo, pTSoldier->sGridNo );
if ( uiRange > (NPC_TALK_RADIUS * 2) )
{
@@ -23308,11 +23362,11 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT16 ubTargetID, BOOLEAN fVali
BOOLEAN SOLDIERTYPE::IsValidSecondHandShot( void )
{
if ( Item[this->inv[SECONDHANDPOS].usItem].usItemClass == IC_GUN &&
!(Item[this->inv[SECONDHANDPOS].usItem].twohanded) &&
!ItemIsTwoHanded(this->inv[SECONDHANDPOS].usItem) &&
(!this->bDoBurst || this->IsValidSecondHandBurst( )) &&
!Item[this->inv[HANDPOS].usItem].grenadelauncher &&
!ItemIsGrenadeLauncher(this->inv[HANDPOS].usItem) &&
Item[this->inv[HANDPOS].usItem].usItemClass == IC_GUN &&
!(Item[this->inv[HANDPOS].usItem].twohanded) &&
!ItemIsTwoHanded(this->inv[HANDPOS].usItem) &&
this->inv[SECONDHANDPOS][0]->data.gun.bGunStatus >= USABLE &&
this->inv[SECONDHANDPOS][0]->data.gun.ubGunShotsLeft > 0 )
{
@@ -23326,11 +23380,11 @@ BOOLEAN SOLDIERTYPE::IsValidSecondHandBurst( void )
{
// SANDRO - a function to determine if we can autofire with both weapons
if ( Item[this->inv[SECONDHANDPOS].usItem].usItemClass == IC_GUN &&
!(Item[this->inv[SECONDHANDPOS].usItem].twohanded) &&
!Item[this->inv[HANDPOS].usItem].grenadelauncher &&
!ItemIsTwoHanded(this->inv[SECONDHANDPOS].usItem) &&
!ItemIsGrenadeLauncher(this->inv[HANDPOS].usItem) &&
this->bDoBurst &&
Item[this->inv[HANDPOS].usItem].usItemClass == IC_GUN &&
!(Item[this->inv[HANDPOS].usItem].twohanded) &&
!ItemIsTwoHanded(this->inv[HANDPOS].usItem) &&
this->inv[SECONDHANDPOS][0]->data.gun.bGunStatus >= USABLE &&
this->inv[SECONDHANDPOS][0]->data.gun.ubGunShotsLeft > 0 )
{
@@ -23362,7 +23416,7 @@ BOOLEAN SOLDIERTYPE::IsValidSecondHandShotForReloadingPurposes( void )
// about ammo taken out!
if ( Item[this->inv[SECONDHANDPOS].usItem].usItemClass == IC_GUN &&
//!this->bDoBurst &&
!Item[this->inv[HANDPOS].usItem].grenadelauncher &&
!ItemIsGrenadeLauncher(this->inv[HANDPOS].usItem) &&
Item[this->inv[HANDPOS].usItem].usItemClass == IC_GUN &&
this->inv[SECONDHANDPOS][0]->data.gun.bGunStatus >= USABLE //&&
// this->inv[SECONDHANDPOS][0]->data.gun.ubGunShotsLeft > 0 &&
@@ -23398,7 +23452,7 @@ BOOLEAN SOLDIERTYPE::IsValidShotFromHip( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE);
}
// must be two handed for this
if ( !Item[this->inv[HANDPOS].usItem].twohanded )
if ( !ItemIsTwoHanded(this->inv[HANDPOS].usItem) )
{
return(FALSE);
}
@@ -23455,7 +23509,7 @@ BOOLEAN SOLDIERTYPE::IsValidPistolFastShot( INT16 bAimTime, INT32 iTrgGridNo )
return(FALSE);
}
// must be one handed for this
if ( Item[this->inv[HANDPOS].usItem].twohanded )
if (ItemIsTwoHanded(this->inv[HANDPOS].usItem))
{
return(FALSE);
}
@@ -24124,8 +24178,8 @@ void SOLDIERTYPE::BreakWindow(void)
{
if (this->inv[HANDPOS].exists() &&
this->inv[HANDPOS][0]->data.objectStatus >= USABLE &&
(Item[this->inv[HANDPOS].usItem].crowbar && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[this->inv[HANDPOS].usItem].twohanded && Item[this->inv[HANDPOS].usItem].metal))
(ItemIsCrowbar(this->inv[HANDPOS].usItem) && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && ItemIsTwoHanded(this->inv[HANDPOS].usItem) && ItemIsMetal(this->inv[HANDPOS].usItem) ))
{
this->usAttackingWeapon = this->inv[HANDPOS].usItem;
this->aiData.bAction = AI_ACTION_KNIFE_STAB;
@@ -24149,8 +24203,8 @@ BOOLEAN SOLDIERTYPE::CanBreakWindow(void)
IS_MERC_BODY_TYPE(this) &&
this->inv[HANDPOS].exists() &&
this->inv[HANDPOS][0]->data.objectStatus >= USABLE &&
(Item[this->inv[HANDPOS].usItem].crowbar && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[this->inv[HANDPOS].usItem].twohanded && Item[this->inv[HANDPOS].usItem].metal))
(ItemIsCrowbar(this->inv[HANDPOS].usItem) && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) ||
Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && ItemIsTwoHanded(this->inv[HANDPOS].usItem) && ItemIsMetal(this->inv[HANDPOS].usItem) ))
{
//INT32 sWindowGridNo = this->sTargetGridNo;
INT32 sWindowGridNo = this->sGridNo;
@@ -25009,7 +25063,7 @@ BOOLEAN AIDecideHipOrShoulderStance( SOLDIERTYPE * pSoldier, INT32 iGridNo )
UINT16 usInHand = pSoldier->usAttackingWeapon;
// not 2-handed or not standing
if ( gAnimControl[pSoldier->usAnimState].ubEndHeight != ANIM_STAND || !Item[pSoldier->inv[HANDPOS].usItem].twohanded )
if ( gAnimControl[pSoldier->usAnimState].ubEndHeight != ANIM_STAND || !ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) )
{
return FALSE;
}
@@ -25542,7 +25596,7 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
if ( !uiPossible )
return 0;
if ( Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
if (ItemIsMedicalKit(pSoldier->inv[0].usItem) && !(fOnSurgery) ) // using the GOOD medic stuff
uiPossible += (uiPossible / 2); // add extra 50 %
// Doctor trait improves basic bandaging ability
@@ -25578,7 +25632,7 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
uiActual = uiDeficiency; // reduce actual not to waste anything
// now make sure we HAVE that much
if ( Item[pKit->usItem].medicalkit )
if (ItemIsMedicalKit(pKit->usItem))
{
if ( fOnSurgery )
uiMedcost = (uiActual * gSkillTraitValues.usDOSurgeryMedBagConsumption) / 100; // surgery drains the kit a lot
@@ -25797,7 +25851,7 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
// usedAPs equals (actionPts) * (%of possible points actually used)
uiUsedAPs = (uiActual * uiAvailAPs) / uiPossible;
if ( Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
if (ItemIsMedicalKit(pSoldier->inv[0].usItem) && !(fOnSurgery) ) // using the GOOD medic stuff
uiUsedAPs = (uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds
// surgery is harder so cost more BPs
@@ -25929,7 +25983,7 @@ BOOLEAN ApplyConsumable(SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, BOOLEAN fForce,
// how much of this item do we use up
UINT16 statusused = min(portionsize, (*pObj)[0]->data.objectStatus);
if (!statusused || (statusused == 1 && Item[pObj->usItem].canteen))
if (!statusused || (statusused == 1 && ItemIsCanteen(pObj->usItem)))
return FALSE;
INT16 apcost = 0;
@@ -25946,12 +26000,12 @@ BOOLEAN ApplyConsumable(SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, BOOLEAN fForce,
apcost = max( apcost, (APBPConstants[AP_CAMOFLAGE] / 2) );
}
if ( Item[pObj->usItem].camouflagekit )
if (ItemIsCamoKit(pObj->usItem))
{
apcost = max( apcost, APBPConstants[AP_CAMOFLAGE] );
}
if ( Item[pObj->usItem].canteen )
if (ItemIsCanteen(pObj->usItem))
{
apcost = max( apcost, APBPConstants[AP_DRINK] );
}
@@ -25998,7 +26052,7 @@ BOOLEAN ApplyConsumable(SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, BOOLEAN fForce,
}
// some mercs will refuse to smoke
if ( Item[pObj->usItem].cigarette && pSoldier->GetBackgroundValue( BG_SMOKERTYPE ) == 2 )
if (ItemIsCigarette(pObj->usItem) && pSoldier->GetBackgroundValue( BG_SMOKERTYPE ) == 2 )
{
// merc gets slightly pissed by the player even suggesting this
TacticalCharacterDialogue( pSoldier, QUOTE_REFUSE_TO_SMOKE );
@@ -26054,7 +26108,7 @@ BOOLEAN ApplyConsumable(SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, BOOLEAN fForce,
fSuccess = TRUE;
// no sound on consuming cigarettes, as that is very annoying
if ( !Item[pObj->usItem].cigarette )
if ( !ItemIsCigarette(pObj->usItem) )
{
fDoSound = TRUE;
}
@@ -26235,4 +26289,6 @@ void SOLDIERTYPE::InitializeExtraData(void)
this->ubQuickItemSlot = 0;
this->usGrenadeItem = 0;
this->delayedDamageFunction = nullptr;
}
+20 -3
View File
@@ -20,6 +20,7 @@
#include <iterator>
#include "GameSettings.h" // added by Flugente
#include "Disease.h" // added by Flugente
#include <functional>
#define PTR_CIVILIAN (pSoldier->bTeam == CIV_TEAM)
#define PTR_CROUCHED (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH)
@@ -465,12 +466,13 @@ enum
#define BACKGROUND_ANIMALFRIEND 0x0000000000000200 //512 // refuses to attack animals
#define BACKGROUND_CIVGROUPLOYAL 0x0000000000000400 //1024 // refuses to attack members of the same civgroup
#define BACKGROUND_ALT_IMP_CREATION 0x0000000000000800 //2048 // BG can only be used when ALT_IMP_CREATION is TRUE in ja2options.ini (IMP creation)
#define BACKGROUND_FLAG_MAX 11 // number of flagged backgrounds - keep this updated, or properties will get lost!
#define BACKGROUND_FLAG_MAX 12 // number of flagged backgrounds - keep this updated, or properties will get lost!
// some properties are hidden (forbid background in MP creation)
// corruption property is not relevant in 1.13
#define BACKGROUND_HIDDEN_FLAGS (BACKGROUND_NO_MALE|BACKGROUND_NO_FEMALE|BACKGROUND_CORRUPTIONSPREAD)
#define BACKGROUND_HIDDEN_FLAGS (BACKGROUND_NO_MALE|BACKGROUND_NO_FEMALE|BACKGROUND_CORRUPTIONSPREAD|BACKGROUND_ALT_IMP_CREATION)
// anv: externalised taunts
// taunt properties
@@ -770,6 +772,9 @@ public:
// How any slots are there in this inventory?
unsigned int size() const;
// const-only accessor
auto get() const -> const std::vector<OBJECTTYPE>&;
//temporarily? public
std::vector<int> bNewItemCount;
std::vector<int> bNewItemCycleCount;
@@ -1069,6 +1074,8 @@ public:
INT8 bPathStored; // good for AI to reduct redundancy
};
enum class BackgroundVectorTypes;
class SOLDIERTYPE//last edited at version 102
{
public:
@@ -1655,6 +1662,10 @@ public:
UINT8 ubQuickItemSlot;
UINT16 usGrenadeItem;
// anv: resolve damage with delay, e.g. damage applied mid movement that would cause issues with world data if applied immediately
std::function<void()> delayedDamageFunction;
public:
// CREATION FUNCTIONS
BOOLEAN DeleteSoldier( void );
@@ -1718,6 +1729,9 @@ public:
void ReviveSoldier( void );
UINT8 SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathDeduct, UINT8 ubReason, UINT16 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage );
// anv: resolve damage with delay, e.g. damage applied mid movement that would cause issues with world data if applied immediately
void SoldierTakeDelayedDamage(INT8 bHeight, INT16 sLifeDeduct, INT16 sBreathDeduct, UINT8 ubReason, UINT8 ubAttacker, INT32 sSourceGrid, INT16 sSubsequent, BOOLEAN fShowDamage);
void ResolveDelayedDamage();
// Palette functions for soldiers
BOOLEAN CreateSoldierPalettes( void );
@@ -1945,6 +1959,8 @@ public:
BOOLEAN HasBackgroundFlag( UINT64 aFlag );
INT16 GetBackgroundValue( UINT16 aNr );
const std::vector<INT16>& SOLDIERTYPE::GetBackgroundValueVector(BackgroundVectorTypes backgroundVectorType) const;
INT8 GetSuppressionResistanceBonus(); // bonus to resistance against suppression
INT16 GetMeleeDamageBonus();
INT16 GetAPBonus();
@@ -2191,7 +2207,8 @@ BOOLEAN GetDirectionChangeAmount( INT32 sGridNo, SOLDIERTYPE *pSoldier, UINT8 ui
UINT8 GetDirectionFromGridNo( INT32 sGridNo, SOLDIERTYPE *pSoldier );
UINT8 atan8( INT16 sXPos, INT16 sYPos, INT16 sXPos2, INT16 sYPos2 );
UINT8 atan8FromAngle( DOUBLE dAngle );
INT16 GetDirectionToGridNoFromGridNo( INT32 sGridNoDest, INT32 sGridNoSrc );
INT16 GetDirectionToGridNoFromGridNo(INT32 sGridNoDest, INT32 sGridNoSrc);
INT16 GetDirectionFromCenterCellXYGridNo(INT32 EndGridNo, INT32 StartGridNo);
// This function is now obsolete. Call ReduceAttackBusyCount instead.
// void ReleaseSoldiersAttacker( SOLDIERTYPE *pSoldier );
+22 -21
View File
@@ -4164,7 +4164,7 @@ void CopyProfileItems( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruc
UINT32 invsize = pProfile->inv.size();
for ( cnt = 0; cnt < pProfile->inv.size(); ++cnt )
{
if ( pProfile->inv[ cnt ] == NOTHING || Item[pProfile->inv[cnt]].attachment) {
if ( pProfile->inv[ cnt ] == NOTHING || ItemIsAttachment(pProfile->inv[cnt]) ) {
continue;
}
fRet = CreateItems( pProfile->inv[ cnt ], pProfile->bInvStatus[ cnt ], pProfile->bInvNumber[ cnt ], &gTempObject );
@@ -4189,7 +4189,7 @@ void CopyProfileItems( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruc
if ( pProfile->inv[ cnt ] == NOTHING) {
continue;
}
if (!Item[pProfile->inv[cnt]].attachment) {
if (!ItemIsAttachment(pProfile->inv[cnt])) {
continue;
}
fRet = CreateItems( pProfile->inv[ cnt ], pProfile->bInvStatus[ cnt ], pProfile->bInvNumber[ cnt ], &gTempObject );
@@ -4294,7 +4294,7 @@ void CopyProfileItems( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCreateStruc
if(fRet)
{
pSoldier->inv[cnt] = gTempObject;
if ( Item[gTempObject.usItem].fingerprintid )
if (ItemHasFingerPrintID(gTempObject.usItem))
{
for (int x = 0; x < pProfile->bInvNumber[ cnt ]; ++x) {
gTempObject[x]->data.ubImprintID = pSoldier->ubProfile;
@@ -5091,7 +5091,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
}
}
// Chance to gain second weapon
if ( Chance( iChance / 4 ) && !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded ) // 1/4 of chance
if ( Chance( iChance / 4 ) && !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) ) // 1/4 of chance
{
(pCreateStruct->Inv[SECONDHANDPOS]) = (pCreateStruct->Inv[HANDPOS]);
@@ -5179,7 +5179,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
BTraitAssigned = TRUE;
// elites can have third skill trait
if ( Chance( iChance / 3 ) && !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded &&
if ( Chance( iChance / 3 ) && !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) &&
(ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ELITE_MILITIA) )
{
pSoldier->stats.ubSkillTraits[2] = AMBIDEXTROUS_NT;
@@ -5189,7 +5189,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
}
// Chance to gain second weapon and ambidextrous trait
else if ( Chance( iChance / 2 ) && !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded && !BTraitAssigned ) // 1/2 of chance
else if ( Chance( iChance / 2 ) && !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) && !BTraitAssigned ) // 1/2 of chance
{
if ( pCreateStruct->bTeam == MILITIA_TEAM && gGameExternalOptions.fMilitiaUseSectorInventory && gGameExternalOptions.fMilitiaUseSectorInventory_Gun )
;
@@ -5207,7 +5207,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
BTraitAssigned = TRUE;
// elites can have third skill trait
if ( Chance( iChance / 3 ) && !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded &&
if ( Chance( iChance / 3 ) && !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) &&
(ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ELITE_MILITIA) )
{
pSoldier->stats.ubSkillTraits[2] = AMBIDEXTROUS_NT;
@@ -5223,7 +5223,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
pSoldier->stats.ubSkillTraits[0] = AMBIDEXT_OT;
ATraitAssigned = TRUE;
// Ambidextrous trait gives us second weapon automatically
if ( !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded )
if ( !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) )
{
(pCreateStruct->Inv[SECONDHANDPOS]) = (pCreateStruct->Inv[HANDPOS]);
}
@@ -5233,7 +5233,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
pSoldier->stats.ubSkillTraits[1] = AMBIDEXT_OT;
BTraitAssigned = TRUE;
// Ambidextrous trait gives us second weapon automatically
if ( !Item[pCreateStruct->Inv[HANDPOS].usItem].twohanded )
if ( !ItemIsTwoHanded(pCreateStruct->Inv[HANDPOS].usItem) )
{
(pCreateStruct->Inv[SECONDHANDPOS]) = (pCreateStruct->Inv[HANDPOS]);
}
@@ -5268,28 +5268,29 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
{
if ( pCreateStruct->Inv[bLoop].exists( ) == true )
{
if ( Item[pCreateStruct->Inv[bLoop].usItem].mortar )
UINT16 usItem = pCreateStruct->Inv[bLoop].usItem;
if (ItemIsMortar(usItem))
foundMortar = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].rocketlauncher )
else if (ItemIsRocketLauncher(usItem))
foundRocketlauncher = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].grenadelauncher )
else if (ItemIsGrenadeLauncher(usItem))
foundGrenadelauncher = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == IC_BLADE )
else if ( Item[usItem].usItemClass == IC_BLADE )
foundKnife = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == IC_THROWING_KNIFE )
else if ( Item[usItem].usItemClass == IC_THROWING_KNIFE )
foundThrowing = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == IC_GRENADE )
else if ( Item[usItem].usItemClass == IC_GRENADE )
foundGrenades = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].brassknuckles )
else if (ItemIsBrassKnuckles(usItem))
foundHtH = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == 128 && // 128 is an identifier of blunt melee weapons
Item[pCreateStruct->Inv[bLoop].usItem].uiIndex != 0 )
else if ( Item[usItem].usItemClass == 128 && // 128 is an identifier of blunt melee weapons
Item[usItem].uiIndex != 0 )
foundMelee = TRUE;
else if ( HasItemFlag( pCreateStruct->Inv[bLoop].usItem, RADIO_SET ) )
else if ( HasItemFlag( usItem, RADIO_SET ) )
fRadioSetFound = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].firstaidkit )
else if (ItemIsFirstAidKit(usItem))
fFirstAidKitFound = TRUE;
else if ( Item[pCreateStruct->Inv[bLoop].usItem].medicalkit )
else if (ItemIsMedicalKit(usItem))
{
// Flugente: for enemy medic purposes, med kits also count as first aid kits
fFirstAidKitFound = TRUE;
+16 -12
View File
@@ -814,8 +814,7 @@ BOOLEAN SoldierLocationRelativeToScreen( INT32 sGridNo, UINT16 usReasonID, INT8
*puiScrollFlags = 0;
sX = CenterX( sGridNo );
sY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
// Get screen coordinates for current position of soldier
GetWorldXYAbsoluteScreenXY( (INT16)(sX/CELL_X_SIZE), (INT16)(sY/CELL_Y_SIZE), &sWorldX, &sWorldY);
@@ -954,25 +953,28 @@ BOOLEAN FindRelativeSoldierPosition( SOLDIERTYPE *pSoldier, UINT16 *usFlags, INT
// Then, depending on whether this is the gridno we are looking at, this will be head or legs
if ( gGameExternalOptions.fAllowTargetHeadAndLegIfProne )
{
INT16 sWorldX, sWorldY;
INT16 sWorldX, sWorldY, sX, sY;
GetMouseWorldCoords( &sWorldX, &sWorldY );
// Flugente: we measure the distance of the bullet's location to the location of the soldier, and to the 2 gridnos his head and leg occupy
// From this we can decide what body part was hit
FLOAT bodycenterX = (FLOAT)CenterX( pSoldier->sGridNo );
FLOAT bodycenterY = (FLOAT)CenterY( pSoldier->sGridNo );
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
FLOAT bodycenterX = (FLOAT) sX;
FLOAT bodycenterY = (FLOAT) sY;
FLOAT difftobodycenter = sqrt( (bodycenterX - sWorldX) * (bodycenterX - sWorldX) + (bodycenterY - sWorldY) * (bodycenterY - sWorldY) );
INT32 viewdirectiongridno = NewGridNo( pSoldier->sGridNo, DirectionInc( pSoldier->ubDirection ) );
FLOAT nextgridnocenterX = (FLOAT)CenterX( viewdirectiongridno );
FLOAT nextgridnocenterY = (FLOAT)CenterY( viewdirectiongridno );
ConvertGridNoToCenterCellXY(viewdirectiongridno, &sX, &sY);
FLOAT nextgridnocenterX = (FLOAT) sX;
FLOAT nextgridnocenterY = (FLOAT) sY;
FLOAT difftonextgridno = sqrt( (nextgridnocenterX - sWorldX) * (nextgridnocenterX - sWorldX) + (nextgridnocenterY - sWorldY) * (nextgridnocenterY - sWorldY) );
INT32 oppositeviewdirectiongridno = NewGridNo( pSoldier->sGridNo, DirectionInc( gOppositeDirection[pSoldier->ubDirection] ) );
FLOAT oppositenextgridnocenterX = (FLOAT)CenterX( oppositeviewdirectiongridno );
FLOAT oppositenextgridnocenterY = (FLOAT)CenterY( oppositeviewdirectiongridno );
ConvertGridNoToCenterCellXY(oppositeviewdirectiongridno, &sX, &sY);
FLOAT oppositenextgridnocenterX = (FLOAT) sX;
FLOAT oppositenextgridnocenterY = (FLOAT) sY;
FLOAT difftooppositenextgridno = sqrt( (oppositenextgridnocenterX - sWorldX) * (oppositenextgridnocenterX - sWorldX) + (oppositenextgridnocenterY - sWorldY) * (oppositenextgridnocenterY - sWorldY) );
@@ -1030,13 +1032,15 @@ UINT16 QuickFindSoldier( INT32 sGridNo )
void GetGridNoScreenPos( INT32 sGridNo, UINT8 ubLevel, INT16 *psScreenX, INT16 *psScreenY )
{
INT16 sScreenX, sScreenY;
INT16 sScreenX, sScreenY, sX, sY;
FLOAT dOffsetX, dOffsetY;
FLOAT dTempX_S, dTempY_S;
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
// Get 'TRUE' merc position
dOffsetX = (FLOAT)( CenterX( sGridNo ) - gsRenderCenterX );
dOffsetY = (FLOAT)( CenterY( sGridNo ) - gsRenderCenterY );
dOffsetX = (FLOAT)( sX - gsRenderCenterX );
dOffsetY = (FLOAT)( sY - gsRenderCenterY );
// OK, DONT'T ASK... CONVERSION TO PROPER Y NEEDS THIS...
dOffsetX -= CELL_Y_SIZE;
+47 -2
View File
@@ -98,6 +98,7 @@ extern UINT8 gubItemDroppableFlag[NUM_INV_SLOTS];
//Random Stats
RANDOM_STATS_VALUES gRandomStatsValue[NUM_PROFILES];
void RandomStats();
void RandomGrowthModifiers();
void RandomStartSalary();
//Jenilee
@@ -459,6 +460,35 @@ void RandomStats()
ExitRandomMercs(); }
}
void RandomGrowthModifiers()
{
UINT32 cnt;
MERCPROFILESTRUCT * pProfile;
BOOLEAN useBellCurve = TRUE;
if (gGameExternalOptions.fMercRandomGrowthModifiers == TRUE)
{
for (cnt = 0; cnt < NUM_PROFILES; cnt++)
{
pProfile = &(gMercProfiles[cnt]);
// cap minimum growth modifier to negative half subpoints. this is effectively double speed using default values (subpoints = 50)
// cap maximum growth modifier to 30000. this would make a merc take 600x as long to level up a stat using default values
pProfile->bGrowthModifierExpLevel = RandomAbsoluteRange( pProfile->bGrowthModifierExpLevel, -gGameExternalOptions.usLevelSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierLife = RandomAbsoluteRange( pProfile->bGrowthModifierLife, -gGameExternalOptions.usHealthSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierAgility = RandomAbsoluteRange( pProfile->bGrowthModifierAgility, -gGameExternalOptions.usAgilitySubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierDexterity = RandomAbsoluteRange( pProfile->bGrowthModifierDexterity, -gGameExternalOptions.usDexteritySubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierStrength = RandomAbsoluteRange( pProfile->bGrowthModifierStrength, -gGameExternalOptions.usStrengthSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierLeadership = RandomAbsoluteRange( pProfile->bGrowthModifierLeadership, -gGameExternalOptions.usLeadershipSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierWisdom = RandomAbsoluteRange( pProfile->bGrowthModifierWisdom, -gGameExternalOptions.usWisdomSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierMarksmanship = RandomAbsoluteRange( pProfile->bGrowthModifierMarksmanship, -gGameExternalOptions.usMarksmanshipSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierMechanical = RandomAbsoluteRange( pProfile->bGrowthModifierMechanical, -gGameExternalOptions.usMechanicalSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierExplosive = RandomAbsoluteRange( pProfile->bGrowthModifierExplosive, -gGameExternalOptions.usExplosivesSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
pProfile->bGrowthModifierMedical = RandomAbsoluteRange( pProfile->bGrowthModifierMedical, -gGameExternalOptions.usMedicalSubpointsToImprove/2, 30000, gGameExternalOptions.iMercRandomGrowthModifiersRange, useBellCurve );
}
}
}
void RandomStartSalary()
{
UINT32 cnt;
@@ -996,6 +1026,8 @@ for( int i = 0; i < NUM_PROFILES; i++ )
// ---------------
RandomStats (); //random stats by Jazz
RandomGrowthModifiers();
// Buggler: random starting salary
RandomStartSalary ();
@@ -1813,7 +1845,7 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
if ( bSlot != NO_SLOT )
{
// if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].fFlags & ITEM_TWO_HANDED )
if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].twohanded )
if (ItemIsTwoHanded(pNewSoldier->inv[ bSlot ].usItem))
{
if ( bSlot != SECONDHANDPOS && pNewSoldier->inv[ SECONDHANDPOS ].exists() == true )
{
@@ -2522,7 +2554,7 @@ void OverwriteMercProfileWithXMLData( UINT32 uiLoop )
gMercProfiles[ uiLoop ].bMechanical = tempProfiles[ uiLoop ].bMechanical ;
gMercProfiles[ uiLoop ].bExpLevel = tempProfiles[ uiLoop ].bExpLevel ;
gMercProfiles[ uiLoop ].bEvolution = tempProfiles[ uiLoop ].bEvolution ;
gMercProfiles[uiLoop].fRegresses = tempProfiles[ uiLoop ].fRegresses;
//////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Check old/new traits and repair possible errors
if (gGameOptions.fNewTraitSystem)
@@ -2637,6 +2669,19 @@ void OverwriteMercProfileWithXMLData( UINT32 uiLoop )
gMercProfiles[ uiLoop ].usVoiceIndex = tempProfiles[uiLoop].usVoiceIndex;
gMercProfiles[ uiLoop ].Type = tempProfiles[uiLoop].Type;
gMercProfiles[uiLoop].fRegresses = tempProfiles[uiLoop].fRegresses;
gMercProfiles[uiLoop].bGrowthModifierLife = tempProfiles[uiLoop].bGrowthModifierLife;
gMercProfiles[uiLoop].bGrowthModifierStrength = tempProfiles[uiLoop].bGrowthModifierStrength;
gMercProfiles[uiLoop].bGrowthModifierAgility = tempProfiles[uiLoop].bGrowthModifierAgility;
gMercProfiles[uiLoop].bGrowthModifierDexterity = tempProfiles[uiLoop].bGrowthModifierDexterity;
gMercProfiles[uiLoop].bGrowthModifierWisdom = tempProfiles[uiLoop].bGrowthModifierWisdom;
gMercProfiles[uiLoop].bGrowthModifierMarksmanship = tempProfiles[uiLoop].bGrowthModifierMarksmanship;
gMercProfiles[uiLoop].bGrowthModifierExplosive = tempProfiles[uiLoop].bGrowthModifierExplosive;
gMercProfiles[uiLoop].bGrowthModifierLeadership = tempProfiles[uiLoop].bGrowthModifierLeadership;
gMercProfiles[uiLoop].bGrowthModifierMedical = tempProfiles[uiLoop].bGrowthModifierMedical;
gMercProfiles[uiLoop].bGrowthModifierMechanical = tempProfiles[uiLoop].bGrowthModifierMechanical;
gMercProfiles[uiLoop].bGrowthModifierExpLevel = tempProfiles[uiLoop].bGrowthModifierExpLevel;
gProfileType[uiLoop] = gMercProfiles[uiLoop].Type;
switch ( tempProfiles[uiLoop].Type )
+12 -1
View File
@@ -314,7 +314,18 @@ typedef struct
INT8 bExpLevel;
INT8 bEvolution;
BOOLEAN fRegresses;
INT16 bGrowthModifierLife;
INT16 bGrowthModifierStrength;
INT16 bGrowthModifierAgility;
INT16 bGrowthModifierDexterity;
INT16 bGrowthModifierWisdom;
INT16 bGrowthModifierMarksmanship;
INT16 bGrowthModifierExplosive;
INT16 bGrowthModifierLeadership;
INT16 bGrowthModifierMedical;
INT16 bGrowthModifierMechanical;
INT16 bGrowthModifierExpLevel;
// changed by SANDRO
INT8 bOldSkillTrait;
INT8 bOldSkillTrait2;
+1 -3
View File
@@ -10,7 +10,6 @@
#include "Animation Cache.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "container.h"
#include "pathai.h"
#include "Random.h"
#include "worldman.h"
@@ -738,8 +737,7 @@ BOOLEAN TeleportSoldier( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fForce )
if ( NewOKDestination( pSoldier, sGridNo, TRUE, 0 ) || fForce )
{
// TELEPORT TO THIS LOCATION!
sX = CenterX( sGridNo );
sY = CenterY( sGridNo );
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
pSoldier->EVENT_SetSoldierPosition( (FLOAT) sX, (FLOAT) sY );
pSoldier->pathing.sFinalDestination = sGridNo;
+2 -2
View File
@@ -598,7 +598,7 @@ void SoldierTooltip( SOLDIERTYPE* pSoldier )
break;
}
if ( Item[ pSoldier->inv[ BigSlot ].usItem ].rocketlauncher )
if (ItemIsRocketLauncher(pSoldier->inv[ BigSlot ].usItem))
iCarriedRL = pSoldier->inv[ BigSlot ].usItem; // remember that enemy is carrying a rocket launcher when check for rocket ammo is made later on
if ( ( Item[ pSoldier->inv[ BigSlot ].usItem ].usItemClass == IC_LAUNCHER ) ||
@@ -712,7 +712,7 @@ void DisplayWeaponInfo( SOLDIERTYPE* pSoldier, CHAR16* pStrInfo, UINT8 ubSlot, U
if ( ubTooltipDetailLevel == DL_Basic || ubTooltipDetailLevel == DL_Full ) // Madd: also hidden attachments should be hidden at the full level as well... unless the mercs have x-ray vision to see that rod&spring inside the gun!! :p
{
// display only externally-visible weapon attachments
if ( Item[iter->usItem].hiddenattachment )
if (ItemIsHiddenAttachment(iter->usItem))
fDisplayAttachment = FALSE;
else
fDisplayAttachment = TRUE;
+14 -1
View File
@@ -1700,7 +1700,20 @@ void CheckSquadMovementGroups( void )
for (INT8 iSoldier = 0; iSoldier < NUMBER_OF_SOLDIERS_PER_SQUAD; iSoldier++) {
if (Squad[iSquad][iSoldier] != NULL)
{
Squad[iSquad][iSoldier]->ubGroupID = pGroup->ubGroupID;
if (IsVehicle(Squad[iSquad][iSoldier]))
{
INT32 iCounter = 0;
for (iCounter = 0; iCounter < ubNumberOfVehicles; iCounter++)
{
if (pVehicleList[iCounter].ubProfileID == Squad[iSquad][iSoldier]->ubProfile)
break;
}
Squad[iSquad][iSoldier]->ubGroupID = pVehicleList[iCounter].ubMovementGroup;
}
else
{
Squad[iSquad][iSoldier]->ubGroupID = pGroup->ubGroupID;
}
}
}
}
+14 -39
View File
@@ -1027,6 +1027,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( )
// handle all reachable before save
HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
UpdateWorldItems(gWorldSectorX, gWorldSectorY, gbWorldSectorZ, guiNumWorldItems, gWorldItems);
PruneWorldItems();
std::vector<ROTTING_CORPSE_DEFINITION> corpsedefvector;
@@ -1678,33 +1679,7 @@ BOOLEAN RetrieveTempFileFromSavedGame( HWFILE hFile, UINT32 uiType, INT16 sMapX,
//Deletes the Temp map Directory
BOOLEAN InitTacticalSave( BOOLEAN fCreateTempDir )
{
#ifndef USE_VFS
UINT32 uiRetVal;
//If the Map Temp directory exists, removes the temp files
uiRetVal = FileGetAttributes( MAPS_DIR );
if( uiRetVal != 0xFFFFFFFF )
{
if( uiRetVal & FILE_ATTRIBUTES_DIRECTORY )
{
//Erase the directory
if( !EraseDirectory( MAPS_DIR ) )
{
//error erasing the temporary maps directory
}
}
}
else
{
if( !MakeFileManDirectory( MAPS_DIR ) )
{
//Erro creating the temp map directory
AssertMsg( 0, "Error creating the Temp Directory.");
}
}
#else
EraseDirectory( MAPS_DIR );
#endif
if( fCreateTempDir )
{
//Create the initial temp file for the Npc Quote Info
@@ -1878,8 +1853,10 @@ BOOLEAN LoadRottingCorpsesFromTempCorpseFile( INT16 sMapX, INT16 sMapY, INT8 bMa
def.sGridNo = gMapInformation.sWestGridNo;
}
//Recalculate the dx,dy info
def.dXPos = CenterX( def.sGridNo );
def.dYPos = CenterY( def.sGridNo );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(def.sGridNo, &sX, &sY);
def.dXPos = sX;
def.dYPos = sY;
// If not from loading a save....
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
@@ -2701,7 +2678,7 @@ BOOLEAN AddDeadSoldierToUnLoadedSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, S
pWorldItems[ bCount ].bVisible = TRUE;
pWorldItems[ bCount ].bRenderZHeightAboveLevel = 0;
if ( Item[pSoldier->inv[i].usItem].damageable ) // Madd: drop crappier items on higher difficulty levels
if (ItemIsDamageable(pSoldier->inv[i].usItem)) // Madd: drop crappier items on higher difficulty levels
{
// silversurfer: externalized this
//pSoldier->inv[i][0]->data.objectStatus -= (gGameOptions.ubDifficultyLevel - 1) * Random(20);
@@ -2737,15 +2714,14 @@ BOOLEAN AddDeadSoldierToUnLoadedSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, S
memset( &Corpse, 0, sizeof( ROTTING_CORPSE_DEFINITION ) );
// Setup some values!
Corpse.ubBodyType = pSoldier->ubBodyType;
Corpse.sGridNo = sGridNo;
ConvertGridNoToCenterCellXY(sGridNo, &sXPos, &sYPos);
ConvertGridNoToXY( sGridNo, &sXPos, &sYPos );
Corpse.dXPos = (FLOAT)( CenterX( sXPos ) );
Corpse.dYPos = (FLOAT)( CenterY( sYPos ) );
Corpse.sHeightAdjustment = pSoldier->sHeightAdjustment;
Corpse.bVisible = TRUE;
Corpse.ubBodyType = pSoldier->ubBodyType;
Corpse.sGridNo = sGridNo;
Corpse.dXPos = (FLOAT)( sXPos );
Corpse.dYPos = (FLOAT)( sYPos );
Corpse.sHeightAdjustment = pSoldier->sHeightAdjustment;
Corpse.bVisible = TRUE;
SET_PALETTEREP_ID ( Corpse.HeadPal, pSoldier->HeadPal );
SET_PALETTEREP_ID ( Corpse.VestPal, pSoldier->VestPal );
@@ -3194,14 +3170,13 @@ void LoadWorldItemsFromTempFiles(INT16 sMapX, INT16 sMapY, INT8 bMapZ)
void SaveWorldItemsToTempFiles()
{
PruneWorldItems();
for (size_t i = 0; i < gAllWorldItems.sectors.size(); i++)
{
const auto x = gAllWorldItems.sectors[i].x;
const auto y = gAllWorldItems.sectors[i].y;
const auto z = gAllWorldItems.sectors[i].z;
const auto nItems = gAllWorldItems.NumItems[i];
auto Items = gAllWorldItems.Items[i];
auto &Items = gAllWorldItems.Items[i];
SaveWorldItemsToTempItemFile(x, y, (INT8)z, nItems, Items);
}
+6 -6
View File
@@ -8306,7 +8306,7 @@ void HandleTBLevelUp(void)
void HandleTBBackpacks(void)
{
if (UsingNewInventorySystem)
if (UsingNewInventorySystem())
{
bool backpackDropped = false;
SOLDIERTYPE* pTeamSoldier;
@@ -8315,7 +8315,7 @@ void HandleTBBackpacks(void)
{
pTeamSoldier = MercPtrs[ubLoop];
if (pTeamSoldier->flags.DropPackFlag)
if (OK_CONTROLLABLE_MERC(pTeamSoldier) && pTeamSoldier->flags.DropPackFlag)
{
backpackDropped = true;
break;
@@ -8966,7 +8966,7 @@ void HandleTacticalTakeInvItem( INT32 iType )
for(UINT8 i = GUNSLINGPOCKPOS; i < NUM_INV_SLOTS; ++i)
{
if ( pSoldier->inv[i].exists() &&
!Item[ pSoldier->inv[i].usItem ].twohanded &&
!ItemIsTwoHanded(pSoldier->inv[i].usItem) &&
( iType > 0 ? ( pSoldier->inv[i].usItem == iType ) : ( InvItemType( pSoldier->inv[i].usItem ) == iType ) ) )
{
ubItemSlot = i;
@@ -9016,7 +9016,7 @@ INT32 InvItemType( UINT16 usItem )
{
if( usItem == XRAY_DEVICE )
return INV_ITEM_TYPE_XRAY;
if( Item[ usItem ].firstaidkit )
if(ItemIsFirstAidKit(usItem))
return INV_ITEM_TYPE_FIRSTAID;
if( Item[ usItem ].usItemClass == IC_BLADE )
return INV_ITEM_TYPE_MELEE;
@@ -9030,9 +9030,9 @@ INT32 InvItemType( UINT16 usItem )
return INV_ITEM_TYPE_BINOCULARS;
if( HasItemFlag( usItem, TASER ) )
return INV_ITEM_TYPE_TASER;
if( Item[ usItem ].usItemClass == IC_GUN && !Item[ usItem ].twohanded && Weapon[Item[ usItem ].ubClassIndex].ubWeaponType <= GUN_SMG )
if( Item[ usItem ].usItemClass == IC_GUN && !ItemIsTwoHanded(usItem) && Weapon[Item[ usItem ].ubClassIndex].ubWeaponType <= GUN_SMG )
return INV_ITEM_TYPE_SIDEARM;
if( Item[ usItem ].usItemClass == IC_MISC && Item[ usItem ].metaldetector )
if( Item[ usItem ].usItemClass == IC_MISC && ItemIsMetalDetector(usItem) )
return INV_ITEM_TYPE_METALDETECTOR;
return INV_ITEM_TYPE_UNKNOWN;
+23 -11
View File
@@ -180,7 +180,7 @@ UINT8 GetProperItemCursor( UINT16 ubSoldierID, UINT16 ubItemIndex, INT32 usMapPo
//Madd: quick hack to make wirecutter cursor appear when using a knife that can cut through wire
// sevenfm: check that not using bayonet attached to the gun
//if ( Item[ubItemIndex].wirecutters && IsCuttableWireFenceAtGridNo( sTargetGridNo ) && pSoldier->pathing.bLevel == 0 )
if ( Item[ubItemIndex].wirecutters &&
if (ItemIsWirecutters(ubItemIndex) &&
IsCuttableWireFenceAtGridNo( sTargetGridNo ) &&
pSoldier->pathing.bLevel == 0 &&
pSoldier->bWeaponMode != WM_ATTACHED_BAYONET)
@@ -676,8 +676,12 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
gCTHDisplay.iTargetGridNo = usMapPos;
// Calculate distance to target
FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
INT16 sX, sY, sXMap, sYMap;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(usMapPos, &sXMap, &sYMap);
FLOAT dDeltaX = (FLOAT)( sX - sXMap );
FLOAT dDeltaY = (FLOAT)( sY - sYMap );
FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime, usMapPos );
@@ -782,8 +786,12 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
gbCtHBurstCount = 0;
// Calculate distance to target
FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
INT16 sX, sY, sXMap, sYMap;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(usMapPos, &sXMap, &sYMap);
FLOAT dDeltaX = (FLOAT)(sX - sXMap);
FLOAT dDeltaY = (FLOAT)(sY - sYMap);
FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime, usMapPos );
@@ -884,8 +892,12 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
gCTHDisplay.iTargetGridNo = usMapPos;
// Calculate distance to target
FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
INT16 sX, sY, sXMap, sYMap;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(usMapPos, &sXMap, &sYMap);
FLOAT dDeltaX = (FLOAT)(sX - sXMap);
FLOAT dDeltaY = (FLOAT)(sY - sYMap);
FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime, usMapPos );
@@ -1269,7 +1281,7 @@ UINT8 HandleNonActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos , BO
//CHRISL: We need to only check the second hand if the weapon in the second hand is onehanded
// Check for enough ammo...
if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) || (pSoldier->IsValidSecondHandShotForReloadingPurposes( ) && !Item[pSoldier->inv[SECONDHANDPOS].usItem].twohanded && !EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS) ) )
if ( !EnoughAmmo( pSoldier, FALSE, HANDPOS ) || (pSoldier->IsValidSecondHandShotForReloadingPurposes( ) && !ItemIsTwoHanded(pSoldier->inv[SECONDHANDPOS].usItem) && !EnoughAmmo( pSoldier, FALSE, SECONDHANDPOS) ) )
{
// Check if ANY ammo exists.....
if ( FindAmmoToReload( pSoldier, HANDPOS, NO_SLOT ) == NO_SLOT )
@@ -2925,14 +2937,14 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
return( TRAJECTORYCURS );
}
if ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || ( pSoldier->bWeaponMode == WM_BURST && Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher ) )
if ( pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || ( pSoldier->bWeaponMode == WM_BURST && ItemIsGrenadeLauncher(pSoldier->inv[HANDPOS].usItem) ) )
{
if ( gGameSettings.fOptions [ TOPTION_GL_BURST_CURSOR ] )
return( TARGETCURS );
else
return ( TRAJECTORYCURS );
}
else if ( pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO || ( pSoldier->bWeaponMode == WM_AUTOFIRE && Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher ) )
else if ( pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO || ( pSoldier->bWeaponMode == WM_AUTOFIRE && ItemIsGrenadeLauncher(pSoldier->inv[HANDPOS].usItem) ) )
{
if ( gGameSettings.fOptions [ TOPTION_GL_BURST_CURSOR ] )
return( TARGETCURS );
@@ -2964,7 +2976,7 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
// Flugente: cursor for constructing/deconstructing
// at the moment the gridno is not required in these functions, thus 1 suffices
if (!Item[usInHand].wirecutters && (IsStructureConstructItem(usInHand, 1, pSoldier) || IsStructureDeconstructItem(usInHand, 1, pSoldier)))
if (!ItemIsWirecutters(usInHand) && (IsStructureConstructItem(usInHand, 1, pSoldier) || IsStructureDeconstructItem(usInHand, 1, pSoldier)))
{
ubCursor = FORTICURS;
}
+6 -2
View File
@@ -1787,7 +1787,9 @@ BOOLEAN ExitVehicle( SOLDIERTYPE *pSoldier )
pSoldier->aiData.bOppList[ pVehicle->ubID ] = 1;
// Add to sector....
pSoldier->EVENT_SetSoldierPosition( CenterX( sGridNo ), CenterY( sGridNo ) );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
pSoldier->EVENT_SetSoldierPosition( sX, sY );
// anv: since now they can shoot it's important to set passenger to proper stance
// namely, back to standing, because we set them to crouching when entering
@@ -2064,7 +2066,9 @@ void HandleCriticalHitForVehicleInLocation( UINT8 ubID, INT16 sDmg, INT32 sGridN
pVehicleList[ ubID ].fDestroyed = TRUE;
// Explode vehicle...
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, GREAT_BIG_EXPLOSION, 0 );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, GREAT_BIG_EXPLOSION, 0 );
if ( pSoldier != NULL )
{
+111 -89
View File
@@ -1210,7 +1210,7 @@ INT32 ExplosiveEffectiveArmour( OBJECTTYPE * pObj )
}
iValue = Armour[ Item[pObj->usItem].ubClassIndex ].ubProtection;
iValue = iValue * (*pObj)[0]->data.objectStatus * Armour[ Item[pObj->usItem].ubClassIndex ].ubCoverage / 10000;
if ( Item[pObj->usItem].flakjacket )
if (ItemIsFlakJacket(pObj->usItem))
{
// increase value for flak jackets!
iValue *= 3;
@@ -1654,7 +1654,7 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
break;
case IC_LAUNCHER:
if ( Item[pSoldier->usAttackingWeapon].rocketlauncher ){
if (ItemIsRocketLauncher(pSoldier->usAttackingWeapon)){
UseGunWrapper( pSoldier, sTargetGridNo );
} else {
// ATE: PAtch up - bookkeeping for spreading done out of whak
@@ -1714,7 +1714,7 @@ void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, FLOAT
FLOAT dTargetZ;
SOLDIERTYPE* pTargetSoldier = NULL;
INT8 bStructHeight;
INT16 sXMapPos, sYMapPos;
INT16 sXMapPos, sYMapPos, sX, sY;
UINT32 uiRoll;
INT8 bTargetCubeLevel = 0;
INT8 bTargetLevel = 0;
@@ -1731,8 +1731,9 @@ void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, FLOAT
{
// SAVE OPP ID
pSoldier->ubOppNum = pTargetSoldier->ubID;
dTargetX = (FLOAT) CenterX( pTargetSoldier->sGridNo );
dTargetY = (FLOAT) CenterY( pTargetSoldier->sGridNo );
ConvertGridNoToCenterCellXY(pTargetSoldier->sGridNo, &sX, &sY);
dTargetX = (FLOAT) sX;
dTargetY = (FLOAT) sY;
if (pSoldier->bAimShotLocation == AIM_SHOT_RANDOM)
{
uiRoll = PreRandom( 100 );
@@ -1773,9 +1774,11 @@ void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, FLOAT
if ( gGameExternalOptions.fAllowTargetHeadAndLegIfProne && gAnimControl[pTargetSoldier->usAnimState].ubHeight == ANIM_PRONE )
{
INT32 viewdirectiongridno = NewGridNo( pTargetSoldier->sGridNo, DirectionInc( pTargetSoldier->ubDirection ) );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(viewdirectiongridno, &sX, &sY);
dTargetX = (0.3f * dTargetX + 0.7f * (FLOAT)CenterX( viewdirectiongridno )) / 1.0f;
dTargetY = (0.3f * dTargetY + 0.7f * (FLOAT)CenterY( viewdirectiongridno )) / 1.0f;
dTargetX = (0.3f * dTargetX + 0.7f * (FLOAT)sX) / 1.0f;
dTargetY = (0.3f * dTargetY + 0.7f * (FLOAT)sY) / 1.0f;
}
}
break;
@@ -1789,9 +1792,11 @@ void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, FLOAT
if ( gGameExternalOptions.fAllowTargetHeadAndLegIfProne && gAnimControl[pTargetSoldier->usAnimState].ubHeight == ANIM_PRONE )
{
INT32 viewdirectiongridno = NewGridNo( pTargetSoldier->sGridNo, DirectionInc( gOppositeDirection[pTargetSoldier->ubDirection] ) );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(viewdirectiongridno, &sX, &sY);
dTargetX = (0.3f * dTargetX + 0.7f * (FLOAT)CenterX( viewdirectiongridno )) / 1.0f;
dTargetY = (0.3f * dTargetY + 0.7f * (FLOAT)CenterY( viewdirectiongridno )) / 1.0f;
dTargetX = (0.3f * dTargetX + 0.7f * (FLOAT)sX) / 1.0f;
dTargetY = (0.3f * dTargetY + 0.7f * (FLOAT)sY) / 1.0f;
}
}
break;
@@ -2558,7 +2563,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
for (attachmentList::iterator iter = (*pObjAttHand)[0]->attachments.begin(); iter != (*pObjAttHand)[0]->attachments.end(); ++iter)
{
if (Item[iter->usItem].hidemuzzleflash )
if (ItemHasHiddenMuzzleFlash(iter->usItem))
{
OBJECTTYPE* pA= &(*iter);
if ( (*pA)[0]->data.objectStatus >=USABLE)
@@ -2699,7 +2704,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// ATE: Check if we should say quote...
if ( (*pObjHand)[0]->data.gun.ubGunShotsLeft == 0 &&
!Item[usUBItem].rocketlauncher &&
!ItemIsRocketLauncher(usUBItem) &&
pSoldier->bTeam == gbPlayerNum &&
(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) || GetMagSize(pObjHand) > 4))
{
@@ -2714,15 +2719,18 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// Deduct knife from inv! (not here, later?)
}
if ( Item[usUBItem].rocketlauncher )
if (ItemIsRocketLauncher(usUBItem))
{
if ( WillExplosiveWeaponFail( pSoldier, pObjHand ) )
{
if ( Item[usUBItem].singleshotrocketlauncher )
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
if ( ItemIsSingleShotRocketLauncher(usUBItem) )
{
CreateItem( Item[usItemNum].discardedlauncheritem , (*pObjHand)[0]->data.objectStatus, pObjHand );
// Flugente: why would we keep a piece of scrap in our ahnds in the first place? just drop it to the ground
// Flugente: why would we keep a piece of scrap in our hands in the first place? just drop it to the ground
AddItemToPool( pSoldier->sGridNo, pObjHand, 1, pSoldier->pathing.bLevel, 0, -1 );
// Delete object
@@ -2730,20 +2738,21 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
if ( Item[usUBItem].usBuddyItem != 0 && Item[Item[usUBItem].usBuddyItem].usItemClass & IC_EXPLOSV )
{
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, Item[usUBItem].usBuddyItem, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, Item[usUBItem].usBuddyItem, pSoldier->pathing.bLevel );
}
else
{
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
}
}
else
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d", usUBItem , (*pObjHand)[0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, (*pObjHand)[0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, (*pObjHand)[0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
}
// Reduce again for attack end 'cause it has been incremented for a normal attack
@@ -2880,7 +2889,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
if (IS_MERC_BODY_TYPE(pSoldier) &&
pSoldier->bVisible == TRUE &&
Item[usUBItem].usItemClass == IC_GUN &&
!Item[usUBItem].rocketlauncher &&
!ItemIsRocketLauncher(usUBItem) &&
strlen(AmmoTypes[Magazine[Item[(*pObjAttHand)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType].shotAnimation) > 0)
{
ANITILE_PARAMS AniParams;
@@ -2893,8 +2902,8 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
sTempGridNo = NewGridNo(sTempGridNo, DirectionInc(pSoldier->ubDirection));
}
INT16 sX = CenterX(sTempGridNo);
INT16 sY = CenterY(sTempGridNo);
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sTempGridNo, &sX, &sY);
AniParams.sGridNo = pSoldier->sGridNo;
AniParams.ubLevelID = ANI_TOPMOST_LEVEL;
@@ -2934,9 +2943,9 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
}
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
}
else if ( Item[usUBItem].rocketlauncher )
else if (ItemIsRocketLauncher(usUBItem))
{
if ( Item[usUBItem].singleshotrocketlauncher )
if ( ItemIsSingleShotRocketLauncher(usUBItem) )
{
CreateItem( Item[usUBItem].discardedlauncheritem, (*pObjHand)[0]->data.objectStatus, pObjHand );
@@ -3340,7 +3349,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
for (attachmentList::iterator iter = (*pObjUsed)[0]->attachments.begin(); iter != (*pObjUsed)[0]->attachments.end(); ++iter)
{
if (Item[iter->usItem].hidemuzzleflash )
if (ItemHasHiddenMuzzleFlash(iter->usItem))
{
OBJECTTYPE* pA= &(*iter);
if ( (*pA)[0]->data.objectStatus >=USABLE)
@@ -3518,7 +3527,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// ATE: Check if we should say quote...
if ( (*pObjUsed)[0]->data.gun.ubGunShotsLeft == 0 &&
!Item[usUBItem].rocketlauncher &&
!ItemIsRocketLauncher(usUBItem) &&
pSoldier->bTeam == gbPlayerNum &&
(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) || GetMagSize(pObjUsed) > 4))
{
@@ -3639,11 +3648,14 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
}
}
if ( Item[usUBItem].rocketlauncher )
if (ItemIsRocketLauncher(usUBItem))
{
if ( WillExplosiveWeaponFail( pSoldier, pObjUsed ) )
{
if ( Item[usUBItem].singleshotrocketlauncher )
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
if ( ItemIsSingleShotRocketLauncher(usUBItem) )
{
CreateItem( Item[usUBItem].discardedlauncheritem , (*pObjUsed)[0]->data.objectStatus, pObjUsed );
@@ -3655,20 +3667,21 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
if ( Item[usUBItem].usBuddyItem != 0 && Item[Item[usUBItem].usBuddyItem].usItemClass & IC_EXPLOSV )
{
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
}
else
{
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
}
}
else
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d", usUBItem , (*pObjUsed)[0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, (*pObjUsed)[0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, (*pObjUsed)[0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
OBJECTTYPE * pLaunchable = FindLaunchableAttachment( pObjUsed, usUBItem );
if(pLaunchable)
@@ -3695,7 +3708,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
if (IS_MERC_BODY_TYPE(pSoldier) &&
pSoldier->bVisible == TRUE &&
Item[usUBItem].usItemClass == IC_GUN &&
!Item[usUBItem].rocketlauncher &&
!ItemIsRocketLauncher(usUBItem) &&
strlen(AmmoTypes[Magazine[Item[(*pObjAttHand)[0]->data.gun.usGunAmmoItem].ubClassIndex].ubAmmoType].shotAnimation) > 0)
{
ANITILE_PARAMS AniParams;
@@ -3708,8 +3721,8 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
sTempGridNo = NewGridNo(sTempGridNo, DirectionInc(pSoldier->ubDirection));
}
INT16 sX = CenterX(sTempGridNo);
INT16 sY = CenterY(sTempGridNo);
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sTempGridNo, &sX, &sY);
AniParams.sGridNo = pSoldier->sGridNo;
AniParams.ubLevelID = ANI_TOPMOST_LEVEL;
@@ -3748,9 +3761,9 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
}
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
}
else if ( Item[usUBItem].rocketlauncher )
else if (ItemIsRocketLauncher(usUBItem))
{
if ( Item[usUBItem].singleshotrocketlauncher )
if ( ItemIsSingleShotRocketLauncher(usUBItem) )
{
CreateItem( Item[usUBItem].discardedlauncheritem, (*pObjUsed)[0]->data.objectStatus, pObjUsed );
@@ -4411,7 +4424,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
}
}
// if twohanded item, place the secondhand item if any to temp space
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pTargetSoldier->inv[HANDPOS].usItem].twohanded)
if (pSoldier->inv[SECONDHANDPOS].exists() == true && ItemIsTwoHanded(pTargetSoldier->inv[HANDPOS].usItem))
{
if( pSoldier->bTeam != gbPlayerNum ) // for enemies, ignore rules and place it anywhere
{
@@ -5167,7 +5180,9 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
// So we still should have ABC > 0
// Begin explosion due to failure...
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, Launchable.usItem, pSoldier->pathing.bLevel );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
IgniteExplosion( pSoldier->ubID, sX, sY, 0, pSoldier->sGridNo, Launchable.usItem, pSoldier->pathing.bLevel );
// Reduce again for attack end 'cause it has been incremented for a normal attack
// Nope, not anymore.
@@ -5251,8 +5266,8 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
/////////////////////////////////////////////////////////////////////////////////////
// SANDRO - new mercs' records
if ( Item[ usItemNum ].usItemClass == IC_LAUNCHER || Item[usItemNum].grenadelauncher ||
Item[usItemNum].rocketlauncher || Item[usItemNum].singleshotrocketlauncher || Item[usItemNum].mortar )
if ( Item[ usItemNum ].usItemClass == IC_LAUNCHER || ItemIsGrenadeLauncher(usItemNum) ||
ItemIsRocketLauncher(usItemNum) || ItemIsSingleShotRocketLauncher(usItemNum) || ItemIsMortar(usItemNum) )
{
gMercProfiles[ pSoldier->ubProfile ].records.usMissilesLaunched++;
}
@@ -5504,9 +5519,9 @@ void WeaponHit( UINT16 usSoldierID, UINT16 usWeaponIndex, INT16 sDamage, INT16 s
//TODO: Madd --- I don't think this code will ever get called for the HE ammo -- the EXPLOSIVE_GUN check filters out regular guns
// marke test mag ammo type: pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.ubGunAmmoType
// 2cond 'or' added
if ( Item[usWeaponIndex].rocketlauncher || AmmoTypes[ubAmmoType].explosionSize > 1 )
if (ItemIsRocketLauncher(usWeaponIndex) || AmmoTypes[ubAmmoType].explosionSize > 1 )
{
if ( Item[usWeaponIndex].singleshotrocketlauncher )
if (ItemIsSingleShotRocketLauncher(usWeaponIndex))
{
if ( Item[usWeaponIndex].usBuddyItem != 0 && Item[Item[usWeaponIndex].usBuddyItem].usItemClass & IC_EXPLOSV )
{
@@ -5518,7 +5533,7 @@ void WeaponHit( UINT16 usSoldierID, UINT16 usWeaponIndex, INT16 sDamage, INT16 s
}
}
// changed rpg type to work only with two flags matching
else if ( pSoldier && !Item[usWeaponIndex].singleshotrocketlauncher && Item[usWeaponIndex].rocketlauncher)
else if ( pSoldier && !ItemIsSingleShotRocketLauncher(usWeaponIndex) && ItemIsRocketLauncher(usWeaponIndex))
//we shouldn't be able to have an underbarrel firing mode in this step, so we keep the original code :JMich
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("WeaponHit: RPG7 item: %d, Ammo: %d",pSoldier->inv[HANDPOS].usItem , pSoldier->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
@@ -5668,7 +5683,7 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
usDirection = (UINT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, sGridNo );
// marke added one 'or' to get this working with HE ammo
if ( Item[usWeaponIndex].rocketlauncher || (pObj && AmmoTypes[ (*pObj)[0]->data.gun.ubGunAmmoType].explosionSize > 1 ))
if (ItemIsRocketLauncher(usWeaponIndex) || (pObj && AmmoTypes[ (*pObj)[0]->data.gun.ubGunAmmoType].explosionSize > 1 ))
{
// Reduce attacker count!
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of LAW fire") );
@@ -5676,23 +5691,26 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
// HEADROCK HAM 5: Fragments fired by such weapons should not explode.
if ( pBullet->fFragment == false)
{
if ( Item[usWeaponIndex].singleshotrocketlauncher )
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
if (ItemIsSingleShotRocketLauncher(usWeaponIndex))
{
if ( Item[usWeaponIndex].usBuddyItem != 0 && Item[Item[usWeaponIndex].usBuddyItem].usItemClass & IC_EXPLOSV )
{
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, Item[usWeaponIndex].usBuddyItem, bLevel, usDirection );
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, Item[usWeaponIndex].usBuddyItem, bLevel, usDirection );
}
else
{
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, C1, bLevel, usDirection );
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, C1, bLevel, usDirection );
}
}
// changed too to use 2 flag to determine
else if ( ubAttackerID != NOBODY && !Item[usWeaponIndex].singleshotrocketlauncher && Item[usWeaponIndex].rocketlauncher)
else if ( ubAttackerID != NOBODY && !ItemIsSingleShotRocketLauncher(usWeaponIndex) && ItemIsRocketLauncher(usWeaponIndex) )
//there shouldn't be a way to enter here with an UnderBarrel weapon, so retaining original code :JMich
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d",pAttacker->inv[HANDPOS].usItem , pAttacker->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, pAttacker->inv[pAttacker->ubAttackingHand][0]->data.gun.usGunAmmoItem, bLevel, usDirection );
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, pAttacker->inv[pAttacker->ubAttackingHand][0]->data.gun.usGunAmmoItem, bLevel, usDirection );
//This is just to make multishot launchers work in semi auto. It's not really a permanent solution because it still doesn't allow autofire, but it will do for now.
OBJECTTYPE * pLaunchable = FindLaunchableAttachment( &(pAttacker->inv[pAttacker->ubAttackingHand ]), pAttacker->inv[pAttacker->ubAttackingHand ].usItem );
@@ -5708,7 +5726,7 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
else if ( AmmoTypes[(*pObj)[0]->data.gun.ubGunAmmoType].explosionSize > 1)
{
// re-routed the Highexplosive value to define exposion type
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, AmmoTypes[(*pObj)[0]->data.gun.ubGunAmmoType].highExplosive, bLevel, usDirection );
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, AmmoTypes[(*pObj)[0]->data.gun.ubGunAmmoType].highExplosive, bLevel, usDirection );
// pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
}
}
@@ -5719,14 +5737,16 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
return;
}
if ( Item[usWeaponIndex].cannon )
if (ItemIsCannon(usWeaponIndex))
{
// Reduce attacker count!
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - end of TANK fire") );
//FreeUpAttacker( ubAttackerID );
// HEADROCK HAM 5 TODO: Tank shell!!
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, TANK_SHELL, bLevel, usDirection );
INT16 sX, sY;
ConvertGridNoToCenterCellXY(sGridNo, &sX, &sY);
IgniteExplosion( ubAttackerID, sX, sY, 0, sGridNo, TANK_SHELL, bLevel, usDirection );
//FreeUpAttacker( (UINT8) ubAttackerID );
// Moved here to keep ABC >0 as long as possible
@@ -6250,7 +6270,7 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// Basic defines
SOLDIERTYPE * pTarget;
INT32 iRange, iSightRange; //, minRange;
INT16 sX, sY, sX2, sY2;
UINT16 usInHand;
OBJECTTYPE * pInHand;
INT16 sDistVis, sDistVisNoScope;
@@ -6270,8 +6290,11 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// calculate actual range (in units, 10 units = 1 tile)
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( sGridNo ));
FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( sGridNo ));
ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sX, &sY);
ConvertGridNoToCenterCellXY(sGridNo, &sX2, &sY2);
FLOAT dDeltaX = (FLOAT)( sX - sX2 );
FLOAT dDeltaY = (FLOAT)( sY - sY2 );
FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
// Find a target in the tile
@@ -6742,7 +6765,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
/////////////////////////////////////////////////////////////////////////////////////
// Determine iMarksmanship and Base CTH
if (Item[usItemUsed].rocketlauncher ){
if (ItemIsRocketLauncher(usItemUsed)){
// use the same calculation as for mechanical thrown weapons
iMarksmanship = ( EffectiveDexterity( pSoldier, FALSE ) + EffectiveMarksmanship( pSoldier ) + EffectiveWisdom( pSoldier ) + (10 * EffectiveExpLevel( pSoldier ) )) / 4;
// heavy weapons trait helps out
@@ -7143,7 +7166,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
/////////////////////////////////////////////////////////////////////////////////////
// Modify for using one hand
if ( !(Item[ usInHand ].twohanded ) )
if ( !ItemIsTwoHanded(usInHand) )
//check for 2weapon, retaining original code :JMich
{
if (pSoldier->inv[SECONDHANDPOS].exists() == false)
@@ -7475,14 +7498,14 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// Equipment Modifiers
iChance += GetGearToHitBonus ( pSoldier );
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotLaserBonus)
if (AM_A_ROBOT(pSoldier) && ItemProvidesRobotLaserBonus(pSoldier->inv[ROBOT_TARGETING_SLOT].usItem))
{
iChance += GetToHitBonus(&(pSoldier->inv[ROBOT_TARGETING_SLOT]), iRange, bLightLevel, FALSE);
}
else
{
INT16 moda = GetToHitBonus(pInHand, iRange, bLightLevel, stance && iRange > MIN_PRONE_RANGE);
INT16 modb = GetToHitBonus(pInHand, iRange, bLightLevel, gAnimControl[pSoldier->usAnimState].ubEndHeight && iRange > MIN_PRONE_RANGE);
INT16 moda = GetToHitBonus(pInHand, iRange, bLightLevel, stance == ANIM_PRONE && iRange > MIN_PRONE_RANGE);
INT16 modb = GetToHitBonus(pInHand, iRange, bLightLevel, gAnimControl[pSoldier->usAnimState].ubEndHeight == ANIM_PRONE && iRange > MIN_PRONE_RANGE);
iChance += (INT32)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb) / 100);
}
@@ -7974,7 +7997,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
{
INT32 protection = ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
if ( fConsiderFlak && Item[iter->usItem].flakjacket )
if ( fConsiderFlak && ItemIsFlakJacket(iter->usItem) )
{
// increase value for flak jackets!
protection *= 3;
@@ -8007,7 +8030,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
// bullet got through jacket; apply ceramic plate armour
INT32 protection = ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
if ( fConsiderFlak && Item[iter->usItem].flakjacket )
if ( fConsiderFlak && ItemIsFlakJacket(iter->usItem) )
{
// increase value for flak jackets!
protection *= 3;
@@ -8036,7 +8059,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 i
{
INT32 protection = ArmourProtection( pTarget, Item[pArmour->usItem].ubClassIndex, &((*pArmour)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
if ( fConsiderFlak && Item[pArmour->usItem].flakjacket )
if ( fConsiderFlak && ItemIsFlakJacket(pArmour->usItem) )
{
// increase value for flak jackets!
protection *= 3;
@@ -8839,7 +8862,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
{
if ( gGameOptions.fNewTraitSystem )
{
if (!pSoldier->usAttackingWeapon || Item[pSoldier->inv[HANDPOS].usItem].brassknuckles)
if (!pSoldier->usAttackingWeapon || ItemIsBrassKnuckles(pSoldier->inv[HANDPOS].usItem))
{
if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
{
@@ -9351,7 +9374,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iAttRating += gSkillTraitValues.ubMABonusCtHBareHands * NUM_SKILL_TRAITS( pAttacker, MARTIAL_ARTS_NT );
}
// brass knuckles - bonus for Martial Arts (but a little lesser)
else if (Item[pAttacker->inv[HANDPOS].usItem].brassknuckles && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ))
else if (ItemIsBrassKnuckles(pAttacker->inv[HANDPOS].usItem) && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ))
{
iAttRating += gSkillTraitValues.ubMABonusCtHBrassKnuckles * NUM_SKILL_TRAITS( pAttacker, MARTIAL_ARTS_NT );
}
@@ -9565,7 +9588,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
{
iDefRating += gSkillTraitValues.bModifierDodgeHtHChance; // Make HtH dodging a little more problematic for untrained mercs
if ( !pAttacker->usAttackingWeapon || Item[pAttacker->inv[HANDPOS].usItem].brassknuckles )
if ( !pAttacker->usAttackingWeapon || ItemIsBrassKnuckles(pAttacker->inv[HANDPOS].usItem) )
{
if (HAS_SKILL_TRAIT( pDefender, MARTIAL_ARTS_NT ))
{
@@ -9578,7 +9601,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
{
iDefRating += ( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ) );
}
else if ( Item[pDefender->inv[HANDPOS].usItem].brassknuckles )
else if (ItemIsBrassKnuckles(pDefender->inv[HANDPOS].usItem))
{
iDefRating += ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ) );
}
@@ -9848,17 +9871,17 @@ BOOLEAN IsGunWeaponModeCapable( OBJECTTYPE* pObject, WeaponMode bWpnMode, SOLDIE
case WM_AUTOFIRE:
//return ((IsGunAutofireCapable(pSoldier, ubHandPos) || Weapon[ pSoldier->inv[ ubHandPos ].usItem ].NoSemiAuto )&& !Item[pSoldier->inv[ubHandPos].usItem].grenadelauncher );
return ((IsGunAutofireCapable(pObject) || Weapon[ pObject->usItem ].NoSemiAuto )&& !Item[pObject->usItem].grenadelauncher );
return ((IsGunAutofireCapable(pObject) || Weapon[ pObject->usItem ].NoSemiAuto )&& !ItemIsGrenadeLauncher(pObject->usItem));
case WM_ATTACHED_GL:
// return (FindAttachment( &(pSoldier->inv[ubHandPos]), UNDER_GLAUNCHER ) != 0 && FindLaunchableAttachment( &(pSoldier->inv[ubHandPos]), UNDER_GLAUNCHER ) != 0 );
//return (!Item[pSoldier->inv[ubHandPos].usItem].grenadelauncher && IsGrenadeLauncherAttached( &(pSoldier->inv[ubHandPos]) ) && FindLaunchableAttachment( &(pSoldier->inv[ubHandPos]), GetAttachedGrenadeLauncher( &(pSoldier->inv[ubHandPos]) )) != 0 );
return ( (!Item[pObject->usItem].grenadelauncher && !IsAttachmentClass(pObject->usItem, AC_RIFLEGRENADE) ) && IsGrenadeLauncherAttached( pObject ) && FindLaunchableAttachment( pObject, GetAttachedGrenadeLauncher( pObject )) != 0 );
return ( (!ItemIsGrenadeLauncher(pObject->usItem) && !IsAttachmentClass(pObject->usItem, AC_RIFLEGRENADE) ) && IsGrenadeLauncherAttached( pObject ) && FindLaunchableAttachment( pObject, GetAttachedGrenadeLauncher( pObject )) != 0 );
case WM_ATTACHED_GL_BURST:
//return (!Item[pSoldier->inv[ubHandPos].usItem].grenadelauncher && IsGrenadeLauncherAttached( &(pSoldier->inv[ubHandPos]) ) && Weapon[GetAttachedGrenadeLauncher(&pSoldier->inv[ubHandPos])].ubShotsPerBurst > 0 && FindLaunchableAttachment( &(pSoldier->inv[ubHandPos]), GetAttachedGrenadeLauncher( &(pSoldier->inv[ubHandPos]))) != 0 );
return ( (!Item[pObject->usItem].grenadelauncher && !HasAttachmentOfClass( pObject, AC_RIFLEGRENADE ) ) && IsGrenadeLauncherAttached( pObject ) && Weapon[GetAttachedGrenadeLauncher(pObject)].ubShotsPerBurst > 0 && FindLaunchableAttachment( pObject, GetAttachedGrenadeLauncher( pObject)) != 0 );
return ( (!ItemIsGrenadeLauncher(pObject->usItem) && !HasAttachmentOfClass( pObject, AC_RIFLEGRENADE ) ) && IsGrenadeLauncherAttached( pObject ) && Weapon[GetAttachedGrenadeLauncher(pObject)].ubShotsPerBurst > 0 && FindLaunchableAttachment( pObject, GetAttachedGrenadeLauncher( pObject)) != 0 );
case WM_ATTACHED_GL_AUTO:
return FALSE;
@@ -9976,7 +9999,7 @@ void HandleTacticalEffectsOfEquipmentChange( SOLDIERTYPE *pSoldier, UINT32 uiInv
pSoldier->bDoBurst = TRUE;
pSoldier->bDoAutofire = 1;
}
if ( Item[ pSoldier->inv[ HANDPOS ].usItem ].twohanded && Weapon[ pSoldier->inv[ HANDPOS ].usItem ].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
if (ItemIsTwoHanded(pSoldier->inv[ HANDPOS ].usItem) && Weapon[ pSoldier->inv[ HANDPOS ].usItem ].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD;
else
pSoldier->bScopeMode = USE_BEST_SCOPE;
@@ -10017,7 +10040,7 @@ void HandleTacticalEffectsOfEquipmentChange( SOLDIERTYPE *pSoldier, UINT32 uiInv
pSoldier->bDoAutofire = 1;
pSoldier->bDoBurst = TRUE;
}
if ( Item[ pSoldier->inv[ HANDPOS ].usItem ].twohanded && Weapon[ pSoldier->inv[ HANDPOS ].usItem ].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
if (ItemIsTwoHanded(pSoldier->inv[ HANDPOS ].usItem) && Weapon[ pSoldier->inv[ HANDPOS ].usItem ].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD;
else
pSoldier->bScopeMode = USE_BEST_SCOPE;
@@ -10135,7 +10158,7 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed, O
else
itemWeight=Item[usItem].ubWeight;
if ( Item[ usItem ].unaerodynamic )
if (ItemIsUnaerodynamic(usItem))
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"calcmaxtossrange: not aerodynamic");
iRange = 1;
@@ -10159,7 +10182,7 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed, O
}
// sevenfm: for grenades and aerodynamic items - apply modifier
if ( ! Item[ usItem ].unaerodynamic )
if ( !ItemIsUnaerodynamic(usItem))
iRange = (INT32)( iRange * gItemSettings.fRangeModifierGrenade );
// adjust for thrower's remaining breath (lose up to 1/2 of range)
@@ -10177,10 +10200,10 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed, O
iRange += ((iRange * gSkillTraitValues.ubTHBladesMaxRange ) / 100);
}
// sevenfm: add range only for hand grenades and not launched grenades
else if ( (Item[ usItem ].usItemClass == IC_GRENADE) && Item[usItem].ubCursor == TOSSCURS && (HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT )) )
else if ( (Item[ usItem ].usItemClass == IC_GRENADE) && Item[usItem].ubCursor == TOSSCURS && HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) )
{
// better max range due to expertise
iRange += ((iRange * gSkillTraitValues.ubDEMaxRangeToThrowGrenades) / 100);
iRange += ((iRange * gSkillTraitValues.ubTHMaxRangeToThrowGrenades) / 100);
}
}
else
@@ -10262,9 +10285,8 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
else
{
iChance += gSkillTraitValues.bCtHModifierThrowingGrenades; // -10% for untrained mercs
if ( HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT ) )
iChance += gSkillTraitValues.ubDECtHWhenThrowingGrenades; // +30% chance
if ( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) )
iChance += gSkillTraitValues.ubTHCtHWhenThrowingGrenades;
}
}
else
@@ -10290,7 +10312,7 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// SANDRO - old/new traits
if (gGameOptions.fNewTraitSystem)
{
if (Item[usHandItem].mortar)
if (ItemIsMortar(usHandItem))
{
if (HAS_SKILL_TRAIT(pSoldier, HEAVY_WEAPONS_NT))
iChance += gSkillTraitValues.sCtHModifierMortar * max(0, 100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS(pSoldier, HEAVY_WEAPONS_NT)) / 100;
@@ -10310,7 +10332,7 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// This feature is available only if not having new traits on - SANDRO
// Also.. this was moved here before the Heavy Weapons bonus
// HEADROCK HAM 3.2: External divisor for CTH with mortars, now that they are more prevalent in the battlefield.
if (Item[usHandItem].mortar)
if (ItemIsMortar(usHandItem))
{
iChance = iChance / gGameExternalOptions.ubMortarCTHDivisor;
}
@@ -10416,7 +10438,7 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// ADJUST FOR RANGE
if ( Item[usHandItem].mortar && iRange < MIN_MORTAR_RANGE)
if (ItemIsMortar(usHandItem) && iRange < MIN_MORTAR_RANGE)
{
return(0);
}
@@ -10532,7 +10554,7 @@ void ChangeWeaponMode( SOLDIERTYPE * pSoldier )
// Flugente: if we are in a GL fire mode, switch between impact/delayed mode
if (((pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO) ||
(Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_LAUNCHER && !Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher)) &&
(Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_LAUNCHER && !ItemIsRocketLauncher(pSoldier->inv[HANDPOS].usItem))) &&
!pSoldier->usGLDelayMode &&
!gGameExternalOptions.fDelayedGrenadeExplosion)
{
@@ -10626,7 +10648,7 @@ void ChangeScopeMode( SOLDIERTYPE * pSoldier, INT32 iTrgGridNo )
INT8 bOldAimTime = pSoldier->aiData.bShownAimTime;
// SANDRO - if the gun is flagged as HeavyGun, then we can only fire it from hip, thus no scopes to use at all, not even iron sights
if ( Item[pSoldier->inv[HANDPOS].usItem].twohanded && Weapon[pSoldier->inv[HANDPOS].usItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
if (ItemIsTwoHanded(pSoldier->inv[HANDPOS].usItem) && Weapon[pSoldier->inv[HANDPOS].usItem].HeavyGun && gGameExternalOptions.ubAllowAlternativeWeaponHolding == 3 )
{
pSoldier->bScopeMode = USE_ALT_WEAPON_HOLD;
}
@@ -10647,7 +10669,7 @@ void ChangeScopeMode( SOLDIERTYPE * pSoldier, INT32 iTrgGridNo )
while( ObjList[pSoldier->bScopeMode] == NULL && pSoldier->bScopeMode != USE_ALT_WEAPON_HOLD); //USE_BEST_SCOPE);
// If this mode is not allowed, or we are not standing, or holding something weird, skip it
if ( pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD && ( gGameExternalOptions.ubAllowAlternativeWeaponHolding != 3 || gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_STAND || AM_A_ROBOT(pSoldier) || Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher || Item[pSoldier->inv[HANDPOS].usItem].singleshotrocketlauncher ) )
if ( pSoldier->bScopeMode == USE_ALT_WEAPON_HOLD && ( gGameExternalOptions.ubAllowAlternativeWeaponHolding != 3 || gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_STAND || AM_A_ROBOT(pSoldier) || ItemIsRocketLauncher(pSoldier->inv[HANDPOS].usItem) || ItemIsSingleShotRocketLauncher(pSoldier->inv[HANDPOS].usItem)) )
pSoldier->bScopeMode = USE_BEST_SCOPE;
}
// changing scope mode can change number of aiming levels, we should reset the aiming variable here
@@ -11208,7 +11230,7 @@ void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTi
iHighestMagFactor = 1.0;
}
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotLaserBonus)
if (AM_A_ROBOT(pSoldier) && ItemProvidesRobotLaserBonus(pSoldier->inv[ROBOT_TARGETING_SLOT].usItem))
{
gCTHDisplay.iBestLaserRange = max(gCTHDisplay.iBestLaserRange, GetBestLaserRange(&pSoldier->inv[ROBOT_TARGETING_SLOT]));
}
@@ -11494,7 +11516,7 @@ FLOAT CalcNewChanceToHitBaseWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, IN
}
// FIRING 1-HANDED WEAPONS
if ( !(Item[ usInHand ].twohanded ) ) //JMich todo: underbarrel
if ( !ItemIsTwoHanded(usInHand) ) //JMich todo: underbarrel
{
if (pSoldier->inv[SECONDHANDPOS].exists() != false)
{
@@ -11533,7 +11555,7 @@ FLOAT CalcNewChanceToHitBaseWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, IN
}
// HEAVY WEAPON in OLD trait system
if (Item[usInHand].rocketlauncher && !(gGameOptions.fNewTraitSystem) )
if (ItemIsRocketLauncher(usInHand) && !(gGameOptions.fNewTraitSystem) )
{
// Penalty for shooting heavy weapons (launchers). Heavy Weapons skill halves this, once per skill level.
FLOAT fTempPenalty = (gGameCTHConstants.BASE_HEAVY_WEAPON * fGunBaseDifficulty) - fGunBaseDifficulty;
@@ -11863,7 +11885,7 @@ FLOAT CalcNewChanceToHitAimWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT
}
// FIRING 1-HANDED WEAPONS
if ( !(Item[ usInHand ].twohanded ) ) //JMich Todo: fix for UnderBarrel firing
if ( !ItemIsTwoHanded(usInHand) ) //JMich Todo: fix for UnderBarrel firing
{
if (pSoldier->inv[SECONDHANDPOS].exists() != false)
{
@@ -11902,7 +11924,7 @@ FLOAT CalcNewChanceToHitAimWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT
}
// HEAVY WEAPON in OLD trait system
if (Item[usInHand].rocketlauncher && !(gGameOptions.fNewTraitSystem) )
if (ItemIsRocketLauncher(usInHand) && !(gGameOptions.fNewTraitSystem) )
{
// Penalty for shooting heavy weapons (launchers). Heavy Weapons skill halves this, once per skill level.
FLOAT fTempPenalty = (gGameCTHConstants.AIM_HEAVY_WEAPON * fGunAimDifficulty) - fGunAimDifficulty;
@@ -12198,4 +12220,4 @@ BOOLEAN ArtilleryStrike( UINT16 usItem, UINT16 ubOwnerID, UINT32 usStartingGridN
//REAL_OBJECT* pObject = &( ObjectSlots[ iID ] );
return TRUE;
}
}
+8 -3
View File
@@ -136,7 +136,7 @@ void PruneWorldItems(void)
for (size_t i = 0; i < gAllWorldItems.Items.size(); i++)
{
std::vector<WORLDITEM>& items = gAllWorldItems.Items[i];
for (INT32 j = items.size()-1; j > 0; j--)
for (INT32 j = items.size()-1; j >= 0; j--)
{
if (items[j].fExists == false)
{
@@ -149,6 +149,11 @@ void PruneWorldItems(void)
}
else
{
auto x = gAllWorldItems.sectors[i].x;
auto y = gAllWorldItems.sectors[i].y;
auto z = gAllWorldItems.sectors[i].z;
ReSetSectorFlag(x, y, z, SF_ITEM_TEMP_FILE_EXISTS);
gAllWorldItems.sectors.erase(gAllWorldItems.sectors.begin() + i);
gAllWorldItems.NumItems.erase(gAllWorldItems.NumItems.begin() + i);
gAllWorldItems.Items.erase(gAllWorldItems.Items.begin() + i);
@@ -452,7 +457,7 @@ INT32 FindWorldItemForTripwireInGridNo( INT32 sGridNo, INT8 bLevel, BOOLEAN fKno
{
pObj = &( gWorldItems[ gWorldBombs[ uiBombIndex ].iItemIndex ].object );
if ( pObj && Item[pObj->usItem].tripwire )
if ( pObj && ItemIsTripwire(pObj->usItem) )
{
if ( !fKnown )
return( gWorldBombs[ uiBombIndex ].iItemIndex );
@@ -862,7 +867,7 @@ void LoadWorldItemsFromMap( INT8 **hBuffer, float dMajorMapVersion, int ubMinorM
}
}
else if ( dummyItem.bVisible == HIDDEN_ITEM && dummyItem.object[0]->data.bTrap > 0 && ( Item[dummyItem.object.usItem].mine || dummyItem.object.usItem == TRIP_FLARE || dummyItem.object.usItem == TRIP_KLAXON) )
else if ( dummyItem.bVisible == HIDDEN_ITEM && dummyItem.object[0]->data.bTrap > 0 && (ItemIsMine(dummyItem.object.usItem) || dummyItem.object.usItem == TRIP_FLARE || dummyItem.object.usItem == TRIP_KLAXON) )
{
ArmBomb( &dummyItem.object, BOMB_PRESSURE );
dummyItem.usFlags |= WORLD_ITEM_ARMED_BOMB;
+9
View File
@@ -0,0 +1,9 @@
#include "XML.h"
const XML_Char* GetAttribute(const XML_Char* name, const XML_Char** atts) {
for (const XML_Char** pIter = atts; *pIter != NULL; pIter++) {
const XML_Char* key = *pIter++;
if (strcmp(key, name) == 0) return *pIter;
}
return NULL;
}
+9 -3
View File
@@ -1,6 +1,7 @@
#ifndef __XML_H
#define __XML_H
#include "expat.h"
#include "armsdealerinvinit.h"
#include "EnemyItemDrops.h"
#include "Loading Screen.h"
@@ -44,7 +45,10 @@ enum
ELEMENT_DISABILITY_EFFECT,
ELEMENT_DISABILITY_EFFECT_PROPERTY,
ELEMENT_PERSONALITY_EFFECT,
ELEMENT_PERSONALITY_EFFECT_PROPERTY
ELEMENT_PERSONALITY_EFFECT_PROPERTY,
ELEMENT_VECTOR_OF_NUMBERS,
ELEMENT_VECTOR_OF_NUMBERS_NUMBER,
}
typedef PARSE_STAGE;
@@ -157,8 +161,8 @@ typedef PARSE_STAGE;
#define ALTSECTORSFILENAME "Map\\AltSectors.xml"
#define SAMSITESFILENAME "Map\\SamSites.xml"
#define HELISITESFILENAME "Map\\HeliSites.xml"
#define EXTRAITEMSFILENAME "Map\\A9_0_ExtraItems" // ".xml" will be added @runtime
#define EXTRAITEMSFILENAME2 "Map\\A11_0_ExtraItems" // ".xml" will be added @runtime
#define EXTRAITEMSFILENAME "Map\\ExtraItems\\A9_0_ExtraItems" // ".xml" will be added @runtime
#define EXTRAITEMSFILENAME2 "Map\\ExtraItems\\A11_0_ExtraItems" // ".xml" will be added @runtime
#define SHIPPINGDESTINATIONSFILENAME "Map\\ShippingDestinations.xml"
#define DELIVERYMETHODSFILENAME "Map\\DeliveryMethods.xml"
#define DELIVERYMETHODSFILENAME "Map\\DeliveryMethods.xml"
@@ -578,4 +582,6 @@ extern BOOLEAN ReadInAimOldArchive(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN ReadInHistorys(STR fileName, BOOLEAN localizedVersion );
extern BOOLEAN ReadInDifficultySettings(STR fileName, BOOLEAN localizedVersion);
extern const XML_Char* GetAttribute(const XML_Char* name, const XML_Char** atts);
#endif
+31 -10
View File
@@ -20,6 +20,8 @@ struct
}
typedef attachmentParseData;
UINT32 gMAXATTACHMENTS_READ = 0;
static void XMLCALL
attachmentStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
@@ -93,9 +95,9 @@ attachmentEndElementHandle(void *userData, const XML_Char *name)
if(pData->curIndex < pData->maxArraySize)
{
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3,"AttachmentStartElementHandle: writing attachment to array");
Attachment[pData->curIndex][0] = pData->curAttachment[0]; //write the attachment into the table
Attachment[pData->curIndex][1] = pData->curAttachment[1];
Attachment[pData->curIndex][2] = pData->curAttachment[2];
Attachment[pData->curIndex].attachmentIndex = pData->curAttachment[0]; //write the attachment into the table
Attachment[pData->curIndex].itemIndex = pData->curAttachment[1];
Attachment[pData->curIndex].APCost = pData->curAttachment[2];
}
}
else if(strcmp(name, "attachmentIndex") == 0)
@@ -127,7 +129,25 @@ attachmentEndElementHandle(void *userData, const XML_Char *name)
}
static void MapAttachments()
{
std::list<AttachmentStruct> stdList;
std::list<AttachmentStruct>::iterator it;
UINT32 i = 0;
for (i = 0; i < gMAXATTACHMENTS_READ; i++)
{
stdList.push_back(Attachment[i]);
AttachmentBackmap.insert(std::make_pair(Attachment[i].itemIndex, Attachment[i]));
}
stdList.sort();
for (it = stdList.begin(), i = 0; it != stdList.end(); it++, i++)
{
Attachment[i] = *it;
}
}
BOOLEAN ReadInAttachmentStats(STR fileName)
{
@@ -171,7 +191,6 @@ BOOLEAN ReadInAttachmentStats(STR fileName)
XML_SetUserData(parser, &pData);
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
@@ -183,13 +202,15 @@ BOOLEAN ReadInAttachmentStats(STR fileName)
return FALSE;
}
gMAXATTACHMENTS_READ = pData.curIndex + 1;
MapAttachments();
MemFree(lpcBuffer);
XML_ParserFree(parser);
return( TRUE );
}
BOOLEAN WriteAttachmentStats()
{
HWFILE hFile;
@@ -208,10 +229,10 @@ BOOLEAN WriteAttachmentStats()
{
FilePrintf(hFile,"\t<ATTACHMENT>\r\n");
FilePrintf(hFile,"\t\t<attachmentIndex>%d</attachmentIndex>\r\n", Attachment[cnt][0]);
FilePrintf(hFile,"\t\t<itemIndex>%d</itemIndex>\r\n", Attachment[cnt][1]);
FilePrintf(hFile,"\t\t<APCost>%d</APCost>\r\n", Attachment[cnt][2]);
FilePrintf(hFile,"\t\t<NASOnly>%d</NASOnly>\r\n", Attachment[cnt][3]);
FilePrintf(hFile,"\t\t<attachmentIndex>%d</attachmentIndex>\r\n", Attachment[cnt].attachmentIndex);
FilePrintf(hFile,"\t\t<itemIndex>%d</itemIndex>\r\n", Attachment[cnt].itemIndex);
FilePrintf(hFile,"\t\t<APCost>%d</APCost>\r\n", Attachment[cnt].APCost);
FilePrintf(hFile,"\t\t<NASOnly>%d</NASOnly>\r\n", Attachment[cnt].NASOnly);
FilePrintf(hFile,"\t</ATTACHMENT>\r\n");
}
+59 -7
View File
@@ -41,8 +41,13 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
{
pData->curElement = ELEMENT_LIST;
if ( !localizedTextOnly_BG )
memset(pData->curArray,0,sizeof(BACKGROUND_VALUES)*pData->maxArraySize);
if (!localizedTextOnly_BG)
{
for (UINT32 i = 0; i < pData->maxArraySize; i++)
{
pData->curArray[i] = BACKGROUND_VALUES();
}
}
pData->maxReadDepth++; //we are not skipping this element
}
@@ -50,8 +55,8 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
{
pData->curElement = ELEMENT;
if ( !localizedTextOnly_BG )
memset(&pData->curBackground,0,sizeof(BACKGROUND_VALUES));
if (!localizedTextOnly_BG)
pData->curBackground = BACKGROUND_VALUES();
pData->maxReadDepth++; //we are not skipping this element
}
@@ -147,12 +152,34 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
strcmp(name, "no_female") == 0 ||
strcmp(name, "loyalitylossondeath" ) == 0 ||
strcmp(name, "animal_friend") == 0 ||
strcmp(name, "civgroup_loyal") == 0 ))
strcmp(name, "civgroup_loyal") == 0 ||
strcmp(name, "alt_impcreation") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
else if (strcmp(name, "drugtypes") == 0 && pData->curElement == ELEMENT)
{
pData->curElement = ELEMENT_VECTOR_OF_NUMBERS;
pData->curBackground.valueVectors[BackgroundVectorTypes::BG_DRUGUSE_TYPES].clear();
pData->maxReadDepth++; //we are not skipping this element
}
else if (strcmp(name, "drugitems") == 0 && pData->curElement == ELEMENT)
{
pData->curElement = ELEMENT_VECTOR_OF_NUMBERS;
pData->curBackground.valueVectors[BackgroundVectorTypes::BG_DRUGUSE_ITEMS].clear();
pData->maxReadDepth++; //we are not skipping this element
}
else if (pData->curElement == ELEMENT_VECTOR_OF_NUMBERS &&
(strcmp(name, "drugtype") == 0 ||
strcmp(name, "drugitem") == 0))
{
pData->curElement = ELEMENT_VECTOR_OF_NUMBERS_NUMBER;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
@@ -667,7 +694,32 @@ backgroundEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curBackground.uiFlags |= (UINT16)atol(pData->szCharData) ? BACKGROUND_CIVGROUPLOYAL : 0;
}
else if (strcmp(name, "alt_impcreation") == 0)
{
pData->curElement = ELEMENT;
pData->curBackground.uiFlags |= (UINT16)atol(pData->szCharData) ? BACKGROUND_ALT_IMP_CREATION : 0;
}
else if (strcmp(name, "drugtypes") == 0)
{
pData->curElement = ELEMENT;
}
else if (strcmp(name, "drugitems") == 0)
{
pData->curElement = ELEMENT;
}
else if (strcmp(name, "drugtype") == 0)
{
pData->curElement = ELEMENT_VECTOR_OF_NUMBERS;
INT16 drugValue = (INT16)atol(pData->szCharData);
pData->curBackground.valueVectors[BackgroundVectorTypes::BG_DRUGUSE_TYPES].push_back(drugValue);
}
else if (strcmp(name, "drugitem") == 0)
{
pData->curElement = ELEMENT_VECTOR_OF_NUMBERS;
INT16 drugValue = (INT16)atol(pData->szCharData);
pData->curBackground.valueVectors[BackgroundVectorTypes::BG_DRUGUSE_ITEMS].push_back(drugValue);
}
pData->maxReadDepth--;
}
pData->currentDepth--;
@@ -711,7 +763,7 @@ BOOLEAN ReadInBackgrounds(STR fileName, BOOLEAN localizedVersion)
XML_SetCharacterDataHandler(parser, backgroundCharacterDataHandle);
memset(&pData,0,sizeof(pData));
pData = enemyRankParseData();
pData.curArray = zBackground;
pData.maxArraySize = NUM_BACKGROUND;
+4 -2
View File
@@ -19,6 +19,8 @@ struct
}
typedef launchableParseData;
UINT32 gMAXLAUNCHABLES_READ = 0;
static void XMLCALL
launchableStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
@@ -168,9 +170,9 @@ BOOLEAN ReadInLaunchableStats(STR fileName)
return FALSE;
}
gMAXLAUNCHABLES_READ = pData.curIndex + 1;
MemFree(lpcBuffer);
XML_ParserFree(parser);
return( TRUE );
+18 -33
View File
@@ -70,21 +70,21 @@ opinionStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
pData->maxReadDepth++; //we are not skipping this element
}
else if(pData->curElement == ELEMENT)
else if (pData->curElement == ELEMENT && strcmp(name, "AnOpinion") == 0)
{
for(UINT8 i = 0; i < NUMBER_OF_OPINIONS; ++i)
pData->curElement = ELEMENT;
pData->maxReadDepth++; //we are not skipping this element
XML_Char const* anID = GetAttribute("id", atts);
XML_Char const* modifier = GetAttribute("modifier", atts);
INT32 id, value;
id = atoi(anID);
value = atoi(modifier);
if (id >= 0 && id < NUMBER_OF_OPINIONS)
{
XML_Char bla[12];
sprintf(bla, "Opinion%d", i);
if(strcmp(name, bla) == 0)
{
pData->curElement = ELEMENT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
break;
}
pData->curProfile.bMercOpinion[id] = value;
}
}
@@ -92,9 +92,9 @@ opinionStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
}
pData->currentDepth++;
}
static void XMLCALL
opinionCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
@@ -149,24 +149,6 @@ opinionEndElementHandle(void *userData, const XML_Char *name)
pData->curIndex = (UINT32) strtoul(pData->szCharData, NULL, 0);
}
else
{
for(UINT8 i = 0; i < NUMBER_OF_OPINIONS; ++i)
{
XML_Char bla[12];
sprintf(bla, "Opinion%d", i);
if(strcmp(name, bla) == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bMercOpinion[i] = (INT8) atol(pData->szCharData);
break;
}
}
}
pData->maxReadDepth--;
}
@@ -315,7 +297,10 @@ BOOLEAN WriteMercOpinions()
UINT8 cnt_b = 0;
for (cnt_b = 0; cnt_b < NUMBER_OF_OPINIONS; ++cnt_b)
{
FilePrintf(hFile,"\t\t<Opinion%d>%d</Opinion%d>\r\n", cnt_b, gMercProfiles[ cnt ].bMercOpinion[cnt_b], cnt_b);
if (gMercProfiles[cnt].bMercOpinion[cnt_b] != 0)
{
FilePrintf(hFile, "\t\t<AnOpinion id = \"%d\" modifier = \"%d\" />\r\n", cnt_b, gMercProfiles[cnt].bMercOpinion[cnt_b]);
}
}
+88 -6
View File
@@ -101,7 +101,19 @@ profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
strcmp(name, "bMedical") == 0 ||
strcmp(name, "bMechanical") == 0 ||
strcmp(name, "bExpLevel") == 0 ||
strcmp(name, "bEvolution") == 0 ||
strcmp(name, "fRegresses") == 0 ||
// rftr: growth rates are intended to replace the <bEvolution> tag, letting each stat have its own growth modifier
strcmp(name, "bGrowthModifierLife") == 0 ||
strcmp(name, "bGrowthModifierStrength") == 0 ||
strcmp(name, "bGrowthModifierAgility") == 0 ||
strcmp(name, "bGrowthModifierDexterity") == 0 ||
strcmp(name, "bGrowthModifierWisdom") == 0 ||
strcmp(name, "bGrowthModifierMarksmanship") == 0 ||
strcmp(name, "bGrowthModifierExplosive") == 0 ||
strcmp(name, "bGrowthModifierLeadership") == 0 ||
strcmp(name, "bGrowthModifierMedical") == 0 ||
strcmp(name, "bGrowthModifierMechanical") == 0 ||
strcmp(name, "bGrowthModifierExpLevel") == 0 ||
// added by SANDRO
strcmp(name, "bOldSkillTrait") == 0 ||
strcmp(name, "bOldSkillTrait2") == 0 ||
@@ -280,7 +292,18 @@ profileEndElementHandle(void *userData, const XML_Char *name)
tempProfiles[pData->curIndex].bMechanical = pData->curProfile.bMechanical;
tempProfiles[pData->curIndex].bExpLevel = pData->curProfile.bExpLevel;
tempProfiles[pData->curIndex].bEvolution = pData->curProfile.bEvolution;
tempProfiles[pData->curIndex].fRegresses = pData->curProfile.fRegresses;
tempProfiles[pData->curIndex].bGrowthModifierLife = pData->curProfile.bGrowthModifierLife;
tempProfiles[pData->curIndex].bGrowthModifierStrength = pData->curProfile.bGrowthModifierStrength;
tempProfiles[pData->curIndex].bGrowthModifierAgility = pData->curProfile.bGrowthModifierAgility;
tempProfiles[pData->curIndex].bGrowthModifierDexterity = pData->curProfile.bGrowthModifierDexterity;
tempProfiles[pData->curIndex].bGrowthModifierWisdom = pData->curProfile.bGrowthModifierWisdom;
tempProfiles[pData->curIndex].bGrowthModifierMarksmanship = pData->curProfile.bGrowthModifierMarksmanship;
tempProfiles[pData->curIndex].bGrowthModifierExplosive = pData->curProfile.bGrowthModifierExplosive;
tempProfiles[pData->curIndex].bGrowthModifierLeadership = pData->curProfile.bGrowthModifierLeadership;
tempProfiles[pData->curIndex].bGrowthModifierMedical = pData->curProfile.bGrowthModifierMedical;
tempProfiles[pData->curIndex].bGrowthModifierMechanical = pData->curProfile.bGrowthModifierMechanical;
tempProfiles[pData->curIndex].bGrowthModifierExpLevel = pData->curProfile.bGrowthModifierExpLevel;
// added by SANDRO
tempProfiles[pData->curIndex].bOldSkillTrait = pData->curProfile.bOldSkillTrait;
tempProfiles[pData->curIndex].bOldSkillTrait2 = pData->curProfile.bOldSkillTrait2;
@@ -586,11 +609,70 @@ profileEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curProfile.bExpLevel = (UINT32) strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bEvolution") == 0)
else if(strcmp(name, "fRegresses") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bEvolution = (UINT32) strtoul(pData->szCharData, NULL, 0);
pData->curProfile.fRegresses = (BOOLEAN) strtoul(pData->szCharData, NULL, 0);
}
else if (strncmp(name, "bGrowthModifier", 11) == 0) // doing this to avoid C1061
{
if (strcmp(name, "bGrowthModifierLife") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierLife = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierStrength") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierStrength = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierAgility") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierAgility = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierDexterity") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierDexterity = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierWisdom") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierWisdom = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierMarksmanship") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierMarksmanship = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierExplosive") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierExplosive = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierLeadership") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierLeadership = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierMedical") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierMedical = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierMechanical") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierMechanical = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
else if(strcmp(name, "bGrowthModifierExpLevel") == 0)
{
pData->curElement = ELEMENT;
pData->curProfile.bGrowthModifierExpLevel = (UINT32)strtoul(pData->szCharData, NULL, 0);
}
}
////////////////////////////////////////////////////////////////////////////
// SANDRO was here - messed this a bit
@@ -1600,7 +1682,7 @@ BOOLEAN WriteMercProfiles()
FilePrintf(hFile,"\t\t<bMedical>%d</bMedical>\r\n", gMercProfiles[ cnt ].bMedical);
FilePrintf(hFile,"\t\t<bMechanical>%d</bMechanical>\r\n", gMercProfiles[ cnt ].bMechanical);
FilePrintf(hFile,"\t\t<bExpLevel>%d</bExpLevel>\r\n", gMercProfiles[ cnt ].bExpLevel);
FilePrintf(hFile,"\t\t<bEvolution>%d</bEvolution>\r\n", gMercProfiles[ cnt ].bEvolution);
FilePrintf(hFile,"\t\t<fRegresses>%d</fRegresses>\r\n", gMercProfiles[ cnt ].fRegresses);
////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - old/new traits
if (gGameOptions.fNewTraitSystem)
-1
View File
@@ -7,7 +7,6 @@
#include "renderworld.h"
#include "vsurface.h"
#include "sysutil.h"
#include "container.h"
#include "wcheck.h"
#include "video.h"
#include "vobject_blitters.h"
+3 -7
View File
@@ -6134,10 +6134,8 @@ void ProcessNoise(UINT16 ubNoiseMaker, INT32 sGridNo, INT8 bLevel, UINT8 ubTerrT
{
// ALL RIGHT! Passed all the tests, this listener hears this noise!!!
HearNoise(pSoldier,ubSource,sGridNo,bLevel,ubEffVolume,ubNoiseType, (UINT8 *)&bSeen);
bHeard = TRUE;
ubNoiseDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sGridNo),CenterY(sGridNo));
ubNoiseDir = GetDirectionFromCenterCellXYGridNo(pSoldier->sGridNo, sGridNo);
// check the 'noise heard & reported' bit for that soldier & direction
if ( ubNoiseType != NOISE_MOVEMENT || bTeam != OUR_TEAM || (pSoldier->aiData.bInterruptDuelPts != NO_INTERRUPT) || !(pSoldier->ubMovementNoiseHeard & (1 << ubNoiseDir) ) )
@@ -6445,8 +6443,7 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT16 ubNoiseMaker, INT32 sGridNo, INT8 b
// ignore muzzle flashes when turning head to see noise
if ( ubNoiseType == NOISE_GUNFIRE && ubNoiseMaker != NOBODY && MercPtrs[ ubNoiseMaker ]->flags.fMuzzleFlash )
{
sNoiseX = CenterX(sGridNo);
sNoiseY = CenterY(sGridNo);
ConvertGridNoToCenterCellXY(sGridNo, &sNoiseX, &sNoiseY);
bDirection = atan8(pSoldier->sX,pSoldier->sY,sNoiseX,sNoiseY);
if ( pSoldier->ubDirection != bDirection && pSoldier->ubDirection != gOneCDirection[ bDirection ] && pSoldier->ubDirection != gOneCCDirection[ bDirection ] )
{
@@ -6467,8 +6464,7 @@ void HearNoise(SOLDIERTYPE *pSoldier, UINT16 ubNoiseMaker, INT32 sGridNo, INT8 b
if (PythSpacesAway(pSoldier->sGridNo,sGridNo) <= sDistVisible )
{
// just use the XXadjustedXX center of the gridno
sNoiseX = CenterX(sGridNo);
sNoiseY = CenterY(sGridNo);
ConvertGridNoToCenterCellXY(sGridNo, &sNoiseX, &sNoiseY);
if (pSoldier->ubDirection != atan8(pSoldier->sX,pSoldier->sY,sNoiseX,sNoiseY))
{
+15 -13
View File
@@ -402,18 +402,7 @@ typedef enum
NUM_SEXIST
} SexistLevels;
// training defines for evolution, no stat increase, stat decrease( de-evolve )
typedef enum
{
NORMAL_EVOLUTION =0,
NO_EVOLUTION,
DEVOLVE,
THREEQUARTER_EVOLUTION,
HALF_EVOLUTION,
ONEQUARTER_EVOLUTION,
} CharacterEvolution;
// rftr: removed the CharacterEvolution enum as it was replaced by growth modifiers
#define BUDDY_MERC( prof, bud ) ((prof)->bBuddy[0] == (bud) || (prof)->bBuddy[1] == (bud) || (prof)->bBuddy[2] == (bud) || (prof)->bBuddy[3] == (bud) || (prof)->bBuddy[4] == (bud) || ( (prof)->bLearnToLike == (bud) && (prof)->bLearnToLikeCount == 0 ) )
#define HATED_MERC( prof, hat ) ((prof)->bHated[0] == (hat) || (prof)->bHated[1] == (hat) || (prof)->bHated[2] == (hat) || (prof)->bHated[3] == (hat) || (prof)->bHated[4] == (hat) || ( (prof)->bLearnToHate == (hat) && (prof)->bLearnToHateCount == 0 ) )
@@ -789,7 +778,7 @@ public:
INT8 bSex;
INT8 bArmourAttractiveness;
UINT8 ubMiscFlags2;
INT8 bEvolution;
BOOLEAN fRegresses;
UINT8 ubMiscFlags;
UINT8 bSexist;
UINT8 bLearnToHate;
@@ -1009,6 +998,19 @@ public:
// Flugente: type of profile
UINT32 Type;
// rftr: growth modifiers - ignored if fRegresses is TRUE
INT16 bGrowthModifierLife;
INT16 bGrowthModifierStrength;
INT16 bGrowthModifierAgility;
INT16 bGrowthModifierDexterity;
INT16 bGrowthModifierWisdom;
INT16 bGrowthModifierMarksmanship;
INT16 bGrowthModifierExplosive;
INT16 bGrowthModifierLeadership;
INT16 bGrowthModifierMedical;
INT16 bGrowthModifierMechanical;
INT16 bGrowthModifierExpLevel;
}; // MERCPROFILESTRUCT;
// WANNE - BMP: DONE!