new feature: madlab's robot can be upgraded

requires gamedir r2642

https://thepit.ja-galaxy-forum.com/index.php?t=msg&goto=364403

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9338 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
rftr
2022-03-21 17:34:49 +00:00
parent f7315115af
commit 87b0c7c6b7
26 changed files with 1114 additions and 162 deletions
+28 -1
View File
@@ -1343,6 +1343,22 @@ void InitInventoryVehicle(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCa
MSYS_SetRegionUserData( &gSMInvRegion[ cnt ], 0, cnt );
}
}
void InitInventoryRobot(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCallback, MOUSE_CALLBACK INVClickCallback, BOOLEAN fSetHighestPrioity)
{
for(int cnt=INV_START_POS; cnt<NUM_INV_SLOTS; cnt++)
{
MSYS_RemoveRegion( &gSMInvRegion[ cnt ]);
if(robotInv[cnt] || cnt == HANDPOS)
InitInvData(gSMInvData[cnt], TRUE, INV_BAR_DX, INV_BAR_DY, BIG_INV_SLOT_WIDTH, BIG_INV_SLOT_HEIGHT, pRegionDesc[cnt].sX, pRegionDesc[cnt].sY);
else
InitInvData(gSMInvData[cnt], FALSE, 0, 0, 0, 0, 0, 0);
MSYS_DefineRegion( &gSMInvRegion[ cnt ], gSMInvData[ cnt ].sX, gSMInvData[ cnt ].sY, (INT16)(gSMInvData[ cnt ].sX + gSMInvData[ cnt ].sWidth), (INT16)(gSMInvData[ cnt ].sY + gSMInvData[ cnt ].sHeight), ( INT8 )( fSetHighestPrioity ? MSYS_PRIORITY_HIGHEST : MSYS_PRIORITY_HIGH ),
MSYS_NO_CURSOR, INVMoveCallback, INVClickCallback );
// Add region
MSYS_AddRegion( &gSMInvRegion[ cnt ] );
MSYS_SetRegionUserData( &gSMInvRegion[ cnt ], 0, cnt );
}
}
// CHRISL: Function to recreate inventory mouse regions
void InitInventorySoldier(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCallback, MOUSE_CALLBACK INVClickCallback, BOOLEAN fSetHighestPrioity, BOOLEAN fNIVmode)
{
@@ -1778,6 +1794,8 @@ INT16 pocketTypeInSlot(SOLDIERTYPE *pSoldier, INT16 sPocket){
return lbePocket;
if((pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && UsingNewInventorySystem() == true && !vehicleInv[sPocket])
return lbePocket;
if(pSoldier && AM_A_ROBOT(pSoldier) && !robotInv[sPocket])
return lbePocket;
switch (icClass[sPocket])
{
@@ -2542,6 +2560,10 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
if((pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && UsingNewInventorySystem() == true && !vehicleInv[sPocket])
return;
if(pSoldier && AM_A_ROBOT(pSoldier) && !robotInv[sPocket] && UsingNewInventorySystem() && sPocket != HANDPOS)
return;
INT16 sX, sY, newX, newY;
INT16 sBarX, sBarY;
OBJECTTYPE *pObject;
@@ -2559,7 +2581,7 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
sX = gSMInvData[ sPocket ].sX;
sY = gSMInvData[ sPocket ].sY;
if ( UsingNewInventorySystem() && !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE))
if ( UsingNewInventorySystem() && !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !(AM_A_ROBOT(pSoldier)) )
{
// If sPocket is not an equiped pocket, gather pocket information
if(icClass[sPocket] != ITEM_NOT_FOUND)
@@ -2758,6 +2780,9 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
}
#endif
if (AM_A_ROBOT(pSoldier) && sPocket == HANDPOS)
fHatchItOut = FALSE;
if ( fHatchItOut )
{
//shadooow: hatch all pockets that we cannot put item into due to insufficient action points with red
@@ -14478,6 +14503,8 @@ BOOLEAN CheckPocketEmpty( SOLDIERTYPE *pSoldier, INT16 sPocket )
return FALSE;
if((pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && UsingNewInventorySystem() == true && !vehicleInv[sPocket])
return FALSE;
if(pSoldier && AM_A_ROBOT(pSoldier) && !robotInv[sPocket] && UsingNewInventorySystem())
return FALSE;
BOOLEAN bResult = FALSE;
INT16 lbePocket = ITEM_NOT_FOUND;
+1
View File
@@ -241,6 +241,7 @@ void InitInvData(INV_REGIONS &InvData, BOOLEAN fBigPocket, INT16 sBarDx, INT16 s
void InitInventoryOld();
void InitInventoryNew();
void InitInventoryVehicle(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCallback, MOUSE_CALLBACK INVClickCallback, BOOLEAN fSetHighestPrioity);
void InitInventoryRobot(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCallback, MOUSE_CALLBACK INVClickCallback, BOOLEAN fSetHighestPrioity);
void InitInventorySoldier(INV_REGION_DESC *pRegionDesc, MOUSE_CALLBACK INVMoveCallback, MOUSE_CALLBACK INVClickCallback, BOOLEAN fSetHighestPrioity, BOOLEAN fNIVmode);
+20
View File
@@ -1202,6 +1202,18 @@ typedef struct
// 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;
} INVTYPE;
@@ -1724,6 +1736,14 @@ const INT8 oldInv[NUM_INV_SLOTS] = { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
// Determines which pockets to use for vehicles in the new inventory system.
const INT8 vehicleInv[NUM_INV_SLOTS]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0};
// Determines which pockets to use for Madlab's Robot in the new inventory system.
const INT8 robotInv[NUM_INV_SLOTS]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#define ROBOT_AMMO_SLOT 14
#define ROBOT_TARGETING_SLOT 15
#define ROBOT_CHASSIS_SLOT 16
#define ROBOT_UTILITY_SLOT 17
#define ROBOT_INVENTORY_SLOT 18
// Determines the default pocket
const INT16 icDefault[NUM_INV_SLOTS] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,//0-13
+334 -126
View File
@@ -1493,6 +1493,12 @@ UINT8 ItemSlotLimit( OBJECTTYPE * pObject, INT16 bSlot, SOLDIERTYPE *pSoldier, B
if (pSoldier != NULL && (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE)) {
pIndex = VEHICLE_POCKET_TYPE;
}
else if (pSoldier && AM_A_ROBOT(pSoldier)) {
if (bSlot != ROBOT_AMMO_SLOT)
return 1;
pIndex = VEHICLE_POCKET_TYPE;
}
// IC Group Slots
else if (bSlot == GUNSLINGPOCKPOS) {
pIndex = GUNSLING_POCKET_TYPE;
@@ -1637,6 +1643,12 @@ INT8 FindMetalDetectorInHand( SOLDIERTYPE * pSoldier )
return( SECONDHANDPOS );
}
// rftr: a metal detector can be installed into the robot
if ( pSoldier && AM_A_ROBOT(pSoldier) && (&(pSoldier->inv[ROBOT_UTILITY_SLOT]))->exists() && Item[pSoldier->inv[ROBOT_UTILITY_SLOT].usItem].metaldetector )
{
return( ROBOT_UTILITY_SLOT );
}
return( NO_SLOT );
}
@@ -1822,6 +1834,8 @@ INT8 FindEmptySlotWithin( SOLDIERTYPE * pSoldier, INT8 bLower, INT8 bUpper )
continue;
if((pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) && !vehicleInv[bLoop])
continue;
if(AM_A_ROBOT(pSoldier) && !robotInv[bLoop])
continue;
if (pSoldier->inv[bLoop].exists() == false)
{
if (bLoop == SECONDHANDPOS && Item[pSoldier->inv[HANDPOS].usItem].twohanded )
@@ -6273,6 +6287,77 @@ BOOLEAN CanItemFitInVehicle( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos,
return( TRUE );
}
BOOLEAN CanItemFitInRobot(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, INT8 bPos, BOOLEAN fDoingPlacement)
{
if((UsingNewInventorySystem() == false) || !(AM_A_ROBOT(pSoldier)))
return(FALSE);
if(!robotInv[bPos])
return(FALSE);
switch (bPos)
{
case ROBOT_AMMO_SLOT:
// no ammo boxes or ammo crates, and calibre has to match equipped gun
return
(Item[pObj->usItem].usItemClass & IC_AMMO) &&
(Magazine[Item[pObj->usItem].ubClassIndex].ubMagType != AMMO_BOX) &&
(Magazine[Item[pObj->usItem].ubClassIndex].ubMagType != AMMO_CRATE) &&
(Magazine[Item[pObj->usItem].ubClassIndex].ubCalibre == Weapon[pSoldier->inv[HANDPOS].usItem].ubCalibre);
case ROBOT_TARGETING_SLOT:
if (Item[pObj->usItem].fProvidesRobotLaserBonus)
return(TRUE);
if (Item[pObj->usItem].fProvidesRobotNightVision)
return(TRUE);
if (Item[pObj->usItem].bRobotTargetingSkillGrant > 0)
return(TRUE);
return(FALSE);
case ROBOT_CHASSIS_SLOT:
if (Item[pObj->usItem].bRobotStrBonus > 0 || Item[pObj->usItem].bRobotAgiBonus > 0 || Item[pObj->usItem].bRobotDexBonus > 0)
return(TRUE);
if (Item[pObj->usItem].fProvidesRobotCamo)
return(TRUE);
if (Item[pObj->usItem].fRobotDamageReductionModifier > 0.0f && Item[pObj->usItem].fRobotDamageReductionModifier < 1.0f)
return(TRUE);
if (Item[pObj->usItem].bRobotChassisSkillGrant > 0)
return(TRUE);
return(FALSE);
case ROBOT_UTILITY_SLOT:
if (HasItemFlag(pObj->usItem, CLEANING_KIT))
return(TRUE);
if (HasItemFlag( pObj->usItem, RADIO_SET ))
return(TRUE);
if (Item[pObj->usItem].metaldetector == 1)
return(TRUE);
if (Item[pObj->usItem].xray == 1)
return(TRUE);
if (Item[pObj->usItem].bRobotUtilitySkillGrant > 0)
return(TRUE);
return(FALSE);
// anything except ammo goes in the inventory, but has no effect on the robot
case ROBOT_INVENTORY_SLOT:
return (Item[pObj->usItem].usItemClass & IC_AMMO) == 0;
// item doesn't fall into any of the above categories
default:
return(FALSE);
}
}
BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos, BOOLEAN fDoingPlacement )
{
@@ -6285,6 +6370,8 @@ BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos
{
if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
return ( CanItemFitInVehicle( pSoldier, pObj, bPos, fDoingPlacement ) );
else if ( AM_A_ROBOT(pSoldier) && bPos != HANDPOS)
return ( CanItemFitInRobot( pSoldier, pObj, bPos, fDoingPlacement ) );
}
else if ( !oldInv[bPos] )
return(FALSE);
@@ -6654,6 +6741,67 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
return( FALSE );
}
if (AM_A_ROBOT(pSoldier))
{
if (bPos == ROBOT_AMMO_SLOT)
{
PlayJA2Sample( ATTACH_TO_GUN, RATE_11025, SoundVolume( MIDVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
}
else if (bPos == ROBOT_TARGETING_SLOT || bPos == ROBOT_CHASSIS_SLOT || bPos == ROBOT_UTILITY_SLOT)
{
PlayJA2Sample(REMOVING_TEXT, RATE_11025, SoundVolume(MIDVOLUME, pSoldier->sGridNo), 1, SoundDir(pSoldier->sGridNo));
const INT8 targetingSkill = Item[pObj->usItem].bRobotTargetingSkillGrant;
const INT8 chassisSkill = Item[pObj->usItem].bRobotChassisSkillGrant;
const INT8 utilitySkill = Item[pObj->usItem].bRobotUtilitySkillGrant;
if (gGameOptions.fNewTraitSystem && (targetingSkill > 0 || chassisSkill > 0 || utilitySkill > 0))
{
BOOLEAN profileSet = FALSE;
BOOLEAN soldierSet = FALSE;
for (int a = 0; a < 30; ++a)
{
if (!profileSet && gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] == 0)
{
profileSet = TRUE;
switch (bPos)
{
case ROBOT_TARGETING_SLOT:
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = targetingSkill;
break;
case ROBOT_CHASSIS_SLOT:
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = chassisSkill;
break;
case ROBOT_UTILITY_SLOT:
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = utilitySkill;
break;
}
}
if (!soldierSet && pSoldier->stats.ubSkillTraits[a] == 0)
{
soldierSet = TRUE;
switch (bPos)
{
case ROBOT_TARGETING_SLOT:
pSoldier->stats.ubSkillTraits[a] = targetingSkill;
break;
case ROBOT_CHASSIS_SLOT:
pSoldier->stats.ubSkillTraits[a] = chassisSkill;
break;
case ROBOT_UTILITY_SLOT:
pSoldier->stats.ubSkillTraits[a] = utilitySkill;
break;
}
}
}
}
}
}
// If the position is either head slot, then the item must be IC_FACE (checked in
// CanItemFitInPosition).
if ( bPos == HEAD1POS )
@@ -6695,7 +6843,7 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
}
// Lesh: bugfix - replacing weapon in auto with another weapon w/o auto-mode
if (bPos == HANDPOS && Item[ pObj->usItem ].usItemClass == IC_GUN)
if (bPos == HANDPOS && Item[ pObj->usItem ].usItemClass == IC_GUN && !AM_A_ROBOT(pSoldier))
{
//Madd: added code for nosemiauto tag
if (!Weapon[ Item[pObj->usItem].ubClassIndex ].NoSemiAuto)
@@ -6872,6 +7020,12 @@ BOOLEAN PlaceObject( SOLDIERTYPE * pSoldier, INT8 bPos, OBJECTTYPE * pObj )
}
//if we didn't reload, then we know we are stacking or swapping!
if (bPos == HANDPOS && AM_A_ROBOT(pSoldier))
{
DoMessageBox(MSG_BOX_BASIC_STYLE, szRobotText[ROBOT_TEXT_CANNOT_CHANGE_INSTALLED_WEAPON], guiCurrentScreen, (UINT8)MSG_BOX_FLAG_OK, NULL, NULL);
return FALSE;
}
if (IsSlotASmallPocket(bPos) == true && FitsInSmallPocket(pObj) == false) {
//there is nothing we can do, just return
return FALSE;
@@ -10082,7 +10236,7 @@ void ActivateXRayDevice( SOLDIERTYPE * pSoldier )
SOLDIERTYPE * pSoldier2;
UINT32 uiSlot;
if ( Item[pSoldier->inv[ HANDPOS ].usItem].needsbatteries && pSoldier->inv[ HANDPOS ].exists() == true)
if ( Item[pSoldier->inv[ HANDPOS ].usItem].needsbatteries && pSoldier->inv[ HANDPOS ].exists() == true && !AM_A_ROBOT(pSoldier) )
{
// check for batteries
OBJECTTYPE* pBatteries = FindAttachedBatteries( &(pSoldier->inv[HANDPOS]) );
@@ -11281,6 +11435,13 @@ INT16 GetNightVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
UINT16 usItem;
INVTYPE *pItem;
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotNightVision)
{
return bonus += BonusReduceMore(
NightBonusScale( Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].nightvisionrangebonus, bLightLevel ),
(pSoldier->inv[ROBOT_TARGETING_SLOT])[0]->data.objectStatus );
}
//ADB and AXP 28.03.2007: CtH bug fix: We also want to check on a firing weapon, "raised" alone is not enough ;)
bool usingGunScope = WeaponReady(pSoldier);
// CHRISL:
@@ -11379,6 +11540,13 @@ INT16 GetCaveVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
UINT16 usItem;
INVTYPE *pItem;
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotNightVision)
{
return bonus += BonusReduceMore(
NightBonusScale( Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].cavevisionrangebonus, bLightLevel ),
(pSoldier->inv[ROBOT_TARGETING_SLOT])[0]->data.objectStatus );
}
//ADB and AXP 28.03.2007: CtH bug fix: We also want to check on a firing weapon, "raised" alone is not enough ;)
bool usingGunScope = WeaponReady(pSoldier);
// CHRISL:
@@ -12615,46 +12783,56 @@ INT16 GetWornCamo( SOLDIERTYPE * pSoldier )
INT8 bLoop;
INT16 ttl=0;
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
if (AM_A_ROBOT(pSoldier))
{
if ( pSoldier->inv[bLoop].exists() )
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].fProvidesRobotCamo)
{
ttl += GetCamoBonus(&pSoldier->inv[bLoop]);
if ( UsingNewInventorySystem() )
if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() )
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus );
}
else if ( bLoop == LEGPOS )
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if ( fLegPenalty > 0 )
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus * fLegPenalty / 2 );
}
ttl += GetCamoBonus(&pSoldier->inv[ROBOT_CHASSIS_SLOT]);
}
}
// CHRISL: Add additional loop for LBE items while using new inventory system
if( UsingNewInventorySystem() )
else
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; ++bLoop)
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
{
if ( pSoldier->inv[bLoop].exists() == true )
if ( pSoldier->inv[bLoop].exists() )
{
ttl += GetCamoBonus(&pSoldier->inv[bLoop]);
if ( UsingNewInventorySystem() )
if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() )
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus );
}
else if ( bLoop == LEGPOS )
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if ( fLegPenalty > 0 )
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].camobonus * fLegPenalty / 2 );
}
}
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
// CHRISL: Add additional loop for LBE items while using new inventory system
if( UsingNewInventorySystem() )
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; ++bLoop)
{
if ( pSoldier->inv[bLoop].exists() == true )
ttl += GetCamoBonus(&pSoldier->inv[bLoop]);
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
}
}
return __max(0, __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ) );
@@ -12664,46 +12842,56 @@ INT16 GetWornUrbanCamo( SOLDIERTYPE * pSoldier )
INT8 bLoop;
INT16 ttl=0;
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
if (AM_A_ROBOT(pSoldier))
{
if ( pSoldier->inv[bLoop].exists() )
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].fProvidesRobotCamo)
{
ttl += GetUrbanCamoBonus(&pSoldier->inv[bLoop]);
if ( UsingNewInventorySystem() )
if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() )
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].urbanCamobonus );
}
else if ( bLoop == LEGPOS )
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if ( fLegPenalty > 0 )
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].urbanCamobonus * fLegPenalty / 2 );
}
ttl += GetUrbanCamoBonus(&pSoldier->inv[ROBOT_CHASSIS_SLOT]);
}
}
// CHRISL: Add additional loop for LBE items while using new inventory system
if( UsingNewInventorySystem() )
else
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; ++bLoop)
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
{
if ( pSoldier->inv[bLoop].exists() == true )
if (pSoldier->inv[bLoop].exists())
{
ttl += GetUrbanCamoBonus(&pSoldier->inv[bLoop]);
if (UsingNewInventorySystem())
if (bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists())
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverVestModifier) * Item[pSoldier->inv[bLoop].usItem].urbanCamobonus);
}
else if (bLoop == LEGPOS)
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if (fLegPenalty > 0)
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverPantsModifier) * Item[pSoldier->inv[bLoop].usItem].urbanCamobonus * fLegPenalty / 2);
}
}
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
// CHRISL: Add additional loop for LBE items while using new inventory system
if (UsingNewInventorySystem())
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; ++bLoop)
{
if (pSoldier->inv[bLoop].exists() == true)
ttl += GetUrbanCamoBonus(&pSoldier->inv[bLoop]);
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetUrbanCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
}
}
return __max(0, __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ) );
@@ -12713,46 +12901,56 @@ INT16 GetWornDesertCamo( SOLDIERTYPE * pSoldier )
INT8 bLoop;
INT16 ttl=0;
for (bLoop = HELMETPOS; bLoop <= LEGPOS; bLoop++)
if (AM_A_ROBOT(pSoldier))
{
if ( pSoldier->inv[bLoop].exists() == true )
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].fProvidesRobotCamo)
{
ttl += GetDesertCamoBonus(&pSoldier->inv[bLoop]);
if ( UsingNewInventorySystem() )
if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() )
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].desertCamobonus );
}
else if ( bLoop == LEGPOS )
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if ( fLegPenalty > 0 )
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].desertCamobonus * fLegPenalty / 2 );
}
ttl += GetDesertCamoBonus(&pSoldier->inv[ROBOT_CHASSIS_SLOT]);
}
}
// CHRISL: Add additional loop for LBE items while using new inventory system
if((UsingNewInventorySystem() == true))
else
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; bLoop++)
for (bLoop = HELMETPOS; bLoop <= LEGPOS; bLoop++)
{
if ( pSoldier->inv[bLoop].exists() == true )
if (pSoldier->inv[bLoop].exists() == true)
{
ttl += GetDesertCamoBonus(&pSoldier->inv[bLoop]);
if (UsingNewInventorySystem())
if (bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists())
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverVestModifier) * Item[pSoldier->inv[bLoop].usItem].desertCamobonus);
}
else if (bLoop == LEGPOS)
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if (fLegPenalty > 0)
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverPantsModifier) * Item[pSoldier->inv[bLoop].usItem].desertCamobonus * fLegPenalty / 2);
}
}
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
// CHRISL: Add additional loop for LBE items while using new inventory system
if ((UsingNewInventorySystem() == true))
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; bLoop++)
{
if (pSoldier->inv[bLoop].exists() == true)
ttl += GetDesertCamoBonus(&pSoldier->inv[bLoop]);
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetDesertCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
}
}
return __max(0, __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ) );
}
@@ -12761,46 +12959,56 @@ INT16 GetWornSnowCamo( SOLDIERTYPE * pSoldier )
INT8 bLoop;
INT16 ttl=0;
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
if (AM_A_ROBOT(pSoldier))
{
if ( pSoldier->inv[bLoop].exists() == true )
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].fProvidesRobotCamo)
{
ttl += GetSnowCamoBonus(&pSoldier->inv[bLoop]);
if ( UsingNewInventorySystem() )
if ( bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists() )
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverVestModifier ) * Item[ pSoldier->inv[bLoop].usItem ].snowCamobonus );
}
else if ( bLoop == LEGPOS )
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if ( fLegPenalty > 0 )
ttl -= (INT16)( ( 1.0 - gItemSettings.fCamoLBEoverPantsModifier ) * Item[ pSoldier->inv[bLoop].usItem ].snowCamobonus * fLegPenalty / 2 );
}
ttl += GetSnowCamoBonus(&pSoldier->inv[ROBOT_CHASSIS_SLOT]);
}
}
// CHRISL: Add additional loop for LBE items while using new inventory system
if((UsingNewInventorySystem() == true))
else
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; bLoop++)
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
{
if ( pSoldier->inv[bLoop].exists() == true )
if (pSoldier->inv[bLoop].exists() == true)
{
ttl += GetSnowCamoBonus(&pSoldier->inv[bLoop]);
if (UsingNewInventorySystem())
if (bLoop == VESTPOS && pSoldier->inv[VESTPOCKPOS].exists())
{
// silversurfer: Using LBE vest. Only apply partial bonus from armor vest.
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverVestModifier) * Item[pSoldier->inv[bLoop].usItem].snowCamobonus);
}
else if (bLoop == LEGPOS)
{
FLOAT fLegPenalty = 0;
// depending on how many leg LBE we use the camo effect of the armor pants is higher or lower
fLegPenalty += pSoldier->inv[LTHIGHPOCKPOS].exists();
fLegPenalty += pSoldier->inv[RTHIGHPOCKPOS].exists();
// Using thigh rigs. Only apply partial bonus from armor pants.
if (fLegPenalty > 0)
ttl -= (INT16)((1.0 - gItemSettings.fCamoLBEoverPantsModifier) * Item[pSoldier->inv[bLoop].usItem].snowCamobonus * fLegPenalty / 2);
}
}
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
// CHRISL: Add additional loop for LBE items while using new inventory system
if ((UsingNewInventorySystem() == true))
{
for (bLoop = VESTPOCKPOS; bLoop <= BPACKPOCKPOS; bLoop++)
{
if (pSoldier->inv[bLoop].exists() == true)
ttl += GetSnowCamoBonus(&pSoldier->inv[bLoop]);
}
//tais: guns can be camouflaged, this will make gun camo have effect when in main/second hand or on gunsling, did a check for guns and nothing else, hope that's enough.
if (pSoldier->inv[HANDPOS].exists() == true && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[HANDPOS]);
if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pSoldier->inv[SECONDHANDPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[SECONDHANDPOS]);
if (pSoldier->inv[GUNSLINGPOCKPOS].exists() == true && Item[pSoldier->inv[GUNSLINGPOCKPOS].usItem].usItemClass & IC_WEAPON)
ttl += GetSnowCamoBonus(&pSoldier->inv[GUNSLINGPOCKPOS]);
}
}
return __max(0, __min( ttl, ( 100 - gGameExternalOptions.bCamoKitArea ) ) );
}
+1
View File
@@ -131,6 +131,7 @@ attachmentList ReInitMergedItem(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT16
void EjectAmmoAndPlace(SOLDIERTYPE* pSoldier, OBJECTTYPE* pObj, UINT8 subObject = 0);
BOOLEAN CanItemFitInVehicle( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos, BOOLEAN fDoingPlacement );
BOOLEAN CanItemFitInRobot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos, BOOLEAN fDoingPlacement );
BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos, BOOLEAN fDoingPlacement );
void DistributeStatus(OBJECTTYPE* pSourceObject, OBJECTTYPE* pTargetObject, INT16 bMaxPoints);
+4
View File
@@ -8640,6 +8640,10 @@ 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)
{
sLaserRange = max(sLaserRange, GetBestLaserRange(&pShooter->inv[ROBOT_TARGETING_SLOT]));
}
// laser pointers can provide a percentage bonus to base aperture
if (sLaserRange > 0
&& ( gGameCTHConstants.LASER_PERFORMANCE_BONUS_HIP + gGameCTHConstants.LASER_PERFORMANCE_BONUS_IRON + gGameCTHConstants.LASER_PERFORMANCE_BONUS_SCOPE != 0) )
+24
View File
@@ -50,6 +50,14 @@ INT16 EffectiveStrength( SOLDIERTYPE *pSoldier, BOOLEAN fTrainer )
iEffStrength = 0;
}
if (AM_A_ROBOT(pSoldier))
{
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotStrBonus > 0)
{
iEffStrength += Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotStrBonus;
}
}
// Flugente: diseases can affect stat effectivity
INT16 diseaseeffect = 0;
if ( gGameExternalOptions.fDisease )
@@ -93,6 +101,14 @@ INT16 EffectiveAgility( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer )
iEffAgility = pSoldier->stats.bAgility;
if (AM_A_ROBOT(pSoldier))
{
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotAgiBonus > 0)
{
iEffAgility += Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotAgiBonus;
}
}
if ( !fTrainer )
iEffAgility += pSoldier->bExtraAgility;
@@ -266,6 +282,14 @@ INT16 EffectiveDexterity( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer )
iEffDexterity = pSoldier->stats.bDexterity;
if (AM_A_ROBOT(pSoldier))
{
if (Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotDexBonus > 0)
{
iEffDexterity += Item[pSoldier->inv[ROBOT_CHASSIS_SLOT].usItem].bRobotDexBonus;
}
}
if ( !fTrainer )
iEffDexterity += pSoldier->bExtraDexterity;
+39 -1
View File
@@ -1993,7 +1993,7 @@ INT16 SOLDIERTYPE::CalcActionPoints( void )
}
// If tired, reduce action points accordingly (by up to 1/2)
if ( this->bBreath < 100 && !(this->flags.uiStatusFlags & SOLDIER_VEHICLE) )
if ( this->bBreath < 100 && !(this->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT(this))
ubPoints -= (ubPoints * (100 - this->bBreath)) / 200;
if ( this->sWeightCarriedAtTurnStart > 100 )
@@ -18078,6 +18078,32 @@ 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 (this->usSkillCooldown[SOLDIER_COOLDOWN_ROBOT_XRAY])
this->usSkillCooldown[SOLDIER_COOLDOWN_ROBOT_XRAY]--;
else if(this->bInSector)
{
// this allows the robot to do an x-ray ping if there are enemies in sector
SOLDIERTYPE* pTeamSoldier = Menptr;
INT32 cnt = 0;
for (; cnt < TOTAL_SOLDIERS; pTeamSoldier++, cnt++)
{
if (pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->stats.bLife > 0)
{
if (!pTeamSoldier->aiData.bNeutral && (pTeamSoldier->bSide != 0))
{
this->usSkillCooldown[SOLDIER_COOLDOWN_ROBOT_XRAY] += 2;
ActivateXRayDevice(this);
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szRobotText[ROBOT_TEXT_XRAY_ACTIVATED] );
break;
}
}
}
}
}
// if soldier was seen this turn, increase his observed counter
if ( this->usSoldierFlagMask & SOLDIER_ENEMY_OBSERVEDTHISTURN )
{
@@ -18589,6 +18615,15 @@ STR16 SOLDIERTYPE::PrintSkillDesc( INT8 iSkill, INT32 sGridNo )
BOOLEAN SOLDIERTYPE::CanUseRadio( BOOLEAN fCheckForAP )
{
// special case: robot upgraded with a radio set
if (AM_A_ROBOT(this))
{
if (HasItemFlag(this->inv[ROBOT_UTILITY_SLOT].usItem, RADIO_SET))
return !fCheckForAP || EnoughPoints(this, APBPConstants[AP_RADIO], 0, FALSE);
return FALSE;
}
// only radio operators can use this equipment
if ( !NUM_SKILL_TRAITS( this, RADIO_OPERATOR_NT ) )
return FALSE;
@@ -18620,6 +18655,9 @@ BOOLEAN SOLDIERTYPE::UseRadio( )
else
pObj = GetObjectWithFlag( RADIO_SET );
if (AM_A_ROBOT(this))
pObj = &(inv[ROBOT_UTILITY_SLOT]);
if ( pObj && HasItemFlag( pObj->usItem, RADIO_SET ) )
{
// status % chance of success
+1
View File
@@ -644,6 +644,7 @@ enum {
SOLDIER_COOLDOWN_CRYO, // counts how many turns character will be frozen
SOLDIER_COOLDOWN_INTEL_PENALTY, // after being discovered, we can't gain intel from the assignment for this many hours
SOLDIER_COOLDOWN_DRUGUSER_COMBAT, // after a drug user deliberately took drugs, he will not do so on his own for a while
SOLDIER_COOLDOWN_ROBOT_XRAY, // rftr: robot can use x-ray detector
SOLDIER_COOLDOWN_MAX = 20, // enough space for fillers
};
+19 -16
View File
@@ -246,28 +246,31 @@ void HandleTacticalEndTurn( )
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++)
{
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) && !( AM_A_ROBOT( pSoldier ) ) )
if ( pSoldier->bActive && pSoldier->stats.bLife > 0 && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
{
// Handle everything from getting breath back, to bleeding, etc
pSoldier->EVENT_BeginMercTurn( TRUE, 0 );
// Handle Player services
HandlePlayerServices( pSoldier );
// if time is up, turn off xray
if ( pSoldier->uiXRayActivatedTime && uiTime > pSoldier->uiXRayActivatedTime + XRAY_TIME )
if (!AM_A_ROBOT(pSoldier))
{
TurnOffXRayEffects( pSoldier );
}
// Handle Player services
HandlePlayerServices( pSoldier );
// Handle stat changes if ness.
//if ( fCheckStats )
//{
//// UpdateStats( pSoldier );
//}
// Flugente: update multi-turn actions
pSoldier->UpdateMultiTurnAction();
// if time is up, turn off xray
if ( pSoldier->uiXRayActivatedTime && uiTime > pSoldier->uiXRayActivatedTime + XRAY_TIME )
{
TurnOffXRayEffects( pSoldier );
}
// Handle stat changes if ness.
//if ( fCheckStats )
//{
//// UpdateStats( pSoldier );
//}
// Flugente: update multi-turn actions
pSoldier->UpdateMultiTurnAction();
}
}
}
+112 -5
View File
@@ -3085,7 +3085,27 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
if ( !PreRandom( uiDepreciateTest ) && ( (*pObjAttHand)[0]->data.objectStatus > 1) )
{
(*pObjAttHand)[0]->data.objectStatus--;
if (AM_A_ROBOT(pSoldier) && HasItemFlag(pSoldier->inv[ROBOT_UTILITY_SLOT].usItem, CLEANING_KIT))
{
OBJECTTYPE* pRobotCleaningKit = &pSoldier->inv[ROBOT_UTILITY_SLOT];
if ((*pRobotCleaningKit)[0]->data.objectStatus > 0)
{
(*pRobotCleaningKit)[0]->data.objectStatus--;
if ((*pRobotCleaningKit)[0]->data.objectStatus <= 0)
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szRobotText[ROBOT_TEXT_CLEANING_KIT_DEPLETED] );
pRobotCleaningKit->RemoveObjectsFromStack(1);
}
}
else
{
(*pObjAttHand)[0]->data.objectStatus--;
}
}
else
{
(*pObjAttHand)[0]->data.objectStatus--;
}
}
// reduce monster smell (gunpowder smell)
@@ -3881,7 +3901,27 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
if ( !PreRandom( uiDepreciateTest ) && ( (*pObjUsed)[0]->data.objectStatus > 1) )
{
(*pObjUsed)[0]->data.objectStatus--;
if (AM_A_ROBOT(pSoldier) && HasItemFlag(pSoldier->inv[ROBOT_UTILITY_SLOT].usItem, CLEANING_KIT))
{
OBJECTTYPE* pRobotCleaningKit = &pSoldier->inv[ROBOT_UTILITY_SLOT];
if ((*pRobotCleaningKit)[0]->data.objectStatus > 0)
{
(*pRobotCleaningKit)[0]->data.objectStatus--;
if ((*pRobotCleaningKit)[0]->data.objectStatus <= 0)
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szRobotText[ROBOT_TEXT_CLEANING_KIT_DEPLETED] );
pRobotCleaningKit->RemoveObjectsFromStack(1);
}
}
else
{
(*pObjUsed)[0]->data.objectStatus--;
}
}
else
{
(*pObjUsed)[0]->data.objectStatus--;
}
}
// reduce monster smell (gunpowder smell)
@@ -7431,9 +7471,17 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// Equipment Modifiers
iChance += GetGearToHitBonus ( pSoldier );
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 );
iChance += (INT32)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100);
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotLaserBonus)
{
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);
iChance += (INT32)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb) / 100);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
@@ -8071,6 +8119,24 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
}
}
// robot plating damage resistance
if (AM_A_ROBOT(pTarget))
{
FLOAT robotDamageReduction = Item[pTarget->inv[ROBOT_CHASSIS_SLOT].usItem].fRobotDamageReductionModifier;
if (robotDamageReduction > 0.0f && robotDamageReduction < 1.0f)
{
// apply damage reduction, then degrade armour plate based on original damage
damagefactor *= Item[pTarget->inv[ROBOT_CHASSIS_SLOT].usItem].fRobotDamageReductionModifier;
OBJECTTYPE* pRobotPlate = &(pTarget->inv[ROBOT_CHASSIS_SLOT]);
(*pRobotPlate)[0]->data.objectStatus -= max(1, iOrigImpact/12);
if((*pRobotPlate)[0]->data.objectStatus <= 0)
{
ScreenMsg(FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szRobotText[ROBOT_TEXT_PLATE_DESTROYED]);
pRobotPlate->RemoveObjectsFromStack(1);
}
}
}
iOrigImpact = iOrigImpact * damagefactor;
// plus/minus up to 25% due to "random" factors (major organs hit or missed,
@@ -9940,6 +10006,42 @@ void HandleTacticalEffectsOfEquipmentChange( SOLDIERTYPE *pSoldier, UINT32 uiInv
}
}
}
if (AM_A_ROBOT(pSoldier) && gGameOptions.fNewTraitSystem )
{
const INT8 targetingSkill = Item[usOldItem].bRobotTargetingSkillGrant;
const INT8 chassisSkill = Item[usOldItem].bRobotChassisSkillGrant;
const INT8 utilitySkill = Item[usOldItem].bRobotUtilitySkillGrant;
for (int a = 0; a < 30; ++a)
{
if (targetingSkill > 0)
{
if (pSoldier->stats.ubSkillTraits[a] == targetingSkill)
pSoldier->stats.ubSkillTraits[a] = 0;
if (gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] == targetingSkill)
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = 0;
}
if (chassisSkill > 0)
{
if (pSoldier->stats.ubSkillTraits[a] == chassisSkill)
pSoldier->stats.ubSkillTraits[a] = 0;
if (gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] == chassisSkill)
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = 0;
}
if (utilitySkill > 0)
{
if (pSoldier->stats.ubSkillTraits[a] == utilitySkill)
pSoldier->stats.ubSkillTraits[a] = 0;
if (gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] == utilitySkill)
gMercProfiles[pSoldier->ubProfile].bSkillTraits[a] = 0;
}
}
}
}
@@ -11064,6 +11166,11 @@ void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTi
iHighestMagFactor = 1.0;
}
if (AM_A_ROBOT(pSoldier) && Item[pSoldier->inv[ROBOT_TARGETING_SLOT].usItem].fProvidesRobotLaserBonus)
{
gCTHDisplay.iBestLaserRange = max(gCTHDisplay.iBestLaserRange, GetBestLaserRange(&pSoldier->inv[ROBOT_TARGETING_SLOT]));
}
gCTHDisplay.FinalMagFactor = iHighestMagFactor;
}