From a466e7348a171871bef0af281c0ac76bd6b6b740 Mon Sep 17 00:00:00 2001 From: Flugente Date: Mon, 8 Apr 2013 21:13:54 +0000 Subject: [PATCH] - cleaned up drug code - moved trait cth modifiers into a SOLDIERTYPE member function git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5989 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Facilities.cpp | 20 +- Tactical/Drugs And Alcohol.cpp | 81 ++------ Tactical/Drugs And Alcohol.h | 5 - Tactical/Soldier Control.cpp | 198 ++++++++++++++++++- Tactical/Soldier Control.h | 18 +- Tactical/Weapons.cpp | 345 +-------------------------------- 6 files changed, 231 insertions(+), 436 deletions(-) diff --git a/Strategic/Facilities.cpp b/Strategic/Facilities.cpp index 7e4f1652a..27ec18d56 100644 --- a/Strategic/Facilities.cpp +++ b/Strategic/Facilities.cpp @@ -1812,25 +1812,7 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac } // Add effects - if ( ( pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] + Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect ) < 127 ) - { - pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] += Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect; - } - pSoldier->drugs.bDrugEffectRate[ DRUG_TYPE_ALCOHOL ] = Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate; - - // Reset once we sleep... - pSoldier->drugs.bTimesDrugUsedSinceSleep[ DRUG_TYPE_ALCOHOL ]++; - - // Increment side effects.. - if ( ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] + Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect ) < 127 ) - { - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] += ( Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect ); - } - // Stop side effects until were done.... - pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] = 0; - - // Flugente: set flag: we are on drugs - otherwise the game wont decay the effects - pSoldier->bSoldierFlagMask |= SOLDIER_DRUGGED; + pSoldier->AddDrugValues( DRUG_TYPE_ALCOHOL, Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect, Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate, Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect ); // ATE: Make guy collapse from heart attack if too much stuff taken.... if ( pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] > ( Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect * 3 ) ) diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index f0f86e8a6..933550ef3 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -74,10 +74,7 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) // if not a food item, nothing to see here if ( gGameOptions.fFoodSystem && foodtype > 0 ) consumeitem = FALSE; - - // set flag: we are on drugs - pSoldier->bSoldierFlagMask |= SOLDIER_DRUGGED; - + // Flugente: we have to check for every single type of drug ( a drug applied may consist of several 'pure' drug types) for (UINT8 i = DRUG_TYPE_ADRENALINE; i < DRUG_TYPE_MAX; ++i) { @@ -90,22 +87,7 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) if ( (ubDrugType & drugtestflag) != 0 ) { // Add effects - if ( ( pSoldier->drugs.bFutureDrugEffect[ i ] + Drug[i].ubDrugEffect ) < 127 ) - { - pSoldier->drugs.bFutureDrugEffect[ i ] += Drug[i].ubDrugEffect; - } - pSoldier->drugs.bDrugEffectRate[ i ] = Drug[i].ubDrugTravelRate; - - // Reset once we sleep... - pSoldier->drugs.bTimesDrugUsedSinceSleep[ i ]++; - - // Increment side effects.. - if ( ( pSoldier->drugs.bDrugSideEffect[ i ] + Drug[i].ubDrugSideEffect ) < 127 ) - { - pSoldier->drugs.bDrugSideEffect[ i ] += ( Drug[i].ubDrugSideEffect ); - } - // Stop side effects until were done.... - pSoldier->drugs.bDrugSideEffectRate[ i ] = 0; + pSoldier->AddDrugValues( i, Drug[i].ubDrugEffect, Drug[i].ubDrugTravelRate, Drug[i].ubDrugSideEffect ); // ATE: Make guy collapse from heart attack if too much stuff taken.... if ( pSoldier->drugs.bDrugSideEffectRate[ i ] > ( Drug[i].ubDrugSideEffect * 3 ) ) @@ -205,7 +187,7 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) // chance of an extra point if ( PreRandom( 100 / REGEN_POINTS_PER_BOOSTER ) < (UINT32) ( (*pObject)[0]->data.objectStatus % (100 / REGEN_POINTS_PER_BOOSTER ) ) ) { - bRegenPointsGained++; + ++bRegenPointsGained; } } @@ -216,6 +198,9 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) pSoldier->bRegenerationCounter = __min( pSoldier->bRegenerationCounter + bRegenPointsGained, REGEN_POINTS_PER_BOOSTER ); } pSoldier->bRegenBoostersUsedToday++; + + // set flag: we are on drugs + pSoldier->bSoldierFlagMask |= SOLDIER_DRUGGED; } // increase drug counter if not alcoholic drug @@ -357,8 +342,6 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier ) if ( pSoldier->bRegenerationCounter > 0) { -// bBandaged = BANDAGED( pSoldier ); - // increase life pSoldier->bPoisonLife = max(pSoldier->bPoisonSum, pSoldier->bPoisonLife + pSoldier->stats.bLife - __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax ) ); pSoldier->stats.bLife = __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax ); @@ -441,25 +424,6 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier ) pSoldier->bSoldierFlagMask &= ~SOLDIER_DRUGGED; } -INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType ) -{ - return( pSoldier->drugs.bDrugEffect[ ubDrugType ] ); -} - - -INT8 GetDrugSideEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType ) -{ - // If we have a o-positive effect - if ( pSoldier->drugs.bDrugEffect[ ubDrugType ] > 0 ) - { - return( 0 ); - } - else - { - return( pSoldier->drugs.bDrugSideEffect[ ubDrugType ] ); - } -} - void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints ) { INT8 bDrunkLevel; @@ -476,9 +440,9 @@ void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints ) // Adjust! sPoints -= pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ]; - if ( sPoints < APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]] ) + if ( sPoints < APBPConstants[AP_MINIMUM] ) { - sPoints = APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]]; + sPoints = APBPConstants[AP_MINIMUM]; } } @@ -489,16 +453,15 @@ void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints ) // Reduce.... sPoints -= HANGOVER_AP_REDUCE; - if ( sPoints < APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]] ) + if ( sPoints < APBPConstants[AP_MINIMUM] ) { - sPoints = APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]]; + sPoints = APBPConstants[AP_MINIMUM]; } } (*pubPoints) = sPoints; } - void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction ) { INT8 bDrunkLevel; @@ -539,7 +502,6 @@ void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoi } } - INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier ) { INT8 bNumDrinks; @@ -572,26 +534,17 @@ INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier ) } } - INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat ) { return( ( iStat * giDrunkModifier[ GetDrunkLevel( pSoldier ) ] / 100 ) ); } - BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier ) { for (UINT8 cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt) { - // Are we in a side effect or good effect? - if ( pSoldier->drugs.bDrugEffect[ cnt ] ) - return( TRUE ); - - if ( pSoldier->drugs.bDrugSideEffect[ cnt ] ) - return( TRUE ); - - if ( pSoldier->bRegenerationCounter > 0) - return( TRUE ); + if ( MercUnderTheInfluence(pSoldier, cnt) ) + return TRUE; } return( FALSE ); @@ -605,13 +558,13 @@ BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType ) // Are we in a side effect or good effect? if ( pSoldier->drugs.bDrugEffect[ aDrugType ] ) - { return( TRUE ); - } - else if ( pSoldier->drugs.bDrugSideEffect[ aDrugType ] ) - { + + if ( pSoldier->drugs.bDrugSideEffect[ aDrugType ] ) + return( TRUE ); + + if ( pSoldier->bRegenerationCounter > 0) return( TRUE ); - } return( FALSE ); } diff --git a/Tactical/Drugs And Alcohol.h b/Tactical/Drugs And Alcohol.h index 102ab86ae..a983f70b9 100644 --- a/Tactical/Drugs And Alcohol.h +++ b/Tactical/Drugs And Alcohol.h @@ -95,14 +95,9 @@ void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints ); void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPoints ); void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoints ); - -INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType ); -INT8 GetDrugSideEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType ); -INT8 GetDrugAllEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType ); INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier ); INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat ); BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier ); BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType ); - #endif diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 4f4043821..a6896ca44 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -2164,7 +2164,7 @@ void SOLDIERTYPE::CalcNewActionPoints( void ) this->bActionPoints = APBPConstants[AP_MIN_LIMIT]; // Don't max out if we are drugged.... - if ( !GetDrugEffect( this, DRUG_TYPE_ADRENALINE ) && !!GetDrugEffect( this, DRUG_TYPE_AGILITY ) ) + if ( !MercUnderTheInfluence( this, DRUG_TYPE_ADRENALINE ) && !MercUnderTheInfluence( this, DRUG_TYPE_AGILITY ) ) { /////////////////////////////////////////////////////////////////////////////////////////// // SANDRO - following code messed a bit @@ -8515,7 +8515,7 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier // If a moving animation and w/re on drugs, increase speed.... if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_MOVING ) { - if ( GetDrugEffect( pSoldier, DRUG_TYPE_ADRENALINE ) ) + if ( MercUnderTheInfluence( pSoldier, DRUG_TYPE_ADRENALINE ) ) { pSoldier->sAniDelay = pSoldier->sAniDelay / 2; } @@ -15985,6 +15985,200 @@ STR16 SOLDIERTYPE::GetName() return tmpname[tmpuser]; } +INT8 SOLDIERTYPE::GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubTargetProfile ) +{ + INT8 modifier = 0; + + // Modify for traits + if( gGameOptions.fNewTraitSystem ) + { + // 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) + { + modifier += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!! + + if (HAS_SKILL_TRAIT( this, HEAVY_WEAPONS_NT )) + modifier += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( this, HEAVY_WEAPONS_NT ); // +25% per trait + } + // Added CtH bonus for Gunslinger trait on pistols and machine-pistols + else if ( Weapon[usItem].ubWeaponType == GUN_PISTOL ) + { + modifier += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs. + + // this bonus is applied only on single shots! + if ( HAS_SKILL_TRAIT( this, GUNSLINGER_NT ) && this->bDoBurst == 0 && this->bDoAutofire == 0 ) + modifier += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( this, GUNSLINGER_NT ); // +10% per trait + } + else if ( Weapon[usItem].ubWeaponType == GUN_M_PISTOL ) + { + modifier += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs. + + // this bonus is applied only on single shots! + if ( HAS_SKILL_TRAIT( this, GUNSLINGER_NT ) && ((this->bDoBurst == 0 && this->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto)) + modifier += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( this, GUNSLINGER_NT ); // +5% per trait + } + // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs + else if ( Weapon[usItem].ubWeaponType == GUN_AS_RIFLE ) + { + modifier += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs. + + if ( HAS_SKILL_TRAIT( this, AUTO_WEAPONS_NT ) ) + modifier += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( this, AUTO_WEAPONS_NT ); // +5% per trait + } + else if ( Weapon[usItem].ubWeaponType == GUN_SMG ) + { + modifier += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs. + + if ( HAS_SKILL_TRAIT( this, AUTO_WEAPONS_NT ) ) + modifier += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( this, AUTO_WEAPONS_NT ); // +5% per trait + } + else if ( Weapon[usItem].ubWeaponType == GUN_LMG ) + { + modifier += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs. + + if ( HAS_SKILL_TRAIT( this, AUTO_WEAPONS_NT ) ) + modifier += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( this, AUTO_WEAPONS_NT ); // +5% per trait + } + // Added CtH bonus for Gunslinger trait on pistols and machine-pistols + else if ( Weapon[usItem].ubWeaponType == GUN_SN_RIFLE ) + { + modifier += gSkillTraitValues.bCtHModifierSniperRifles; // -5% for untrained mercs. + + // this bonus is applied only on single shots! + if ( HAS_SKILL_TRAIT( this, SNIPER_NT ) && this->bDoBurst == 0 && this->bDoAutofire == 0 ) + modifier += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( this, SNIPER_NT ); // +5% per trait + } + // Added CtH bonus for Ranger skill on rifles and shotguns + else if ( Weapon[usItem].ubWeaponType == GUN_RIFLE ) + { + modifier += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs. + + // this bonus is applied only on single shots! + if ( HAS_SKILL_TRAIT( this, RANGER_NT ) && this->bDoBurst == 0 && this->bDoAutofire == 0 ) + modifier += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( this, RANGER_NT ); // +5% per trait + //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles" + // this bonus is applied only on single shots! + if ( HAS_SKILL_TRAIT( this, SNIPER_NT ) && this->bDoBurst == 0 && this->bDoAutofire == 0 ) + modifier += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( this, SNIPER_NT ); // +5% per trait + } + else if ( Weapon[usItem].ubWeaponType == GUN_SHOTGUN ) + { + modifier += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs. + + if ( HAS_SKILL_TRAIT( this, RANGER_NT ) ) + modifier += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( this, RANGER_NT ); // +10% per trait + } + + // Added small CtH penalty for robot if controller hasn't the Technician trait + if( AM_A_ROBOT( this ) ) + { + modifier += gSkillTraitValues.bCtHModifierRobot; // -10% + + if ( HAS_SKILL_TRAIT( this->GetRobotController(), TECHNICIAN_NT ) ) + modifier += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( this->GetRobotController(), TECHNICIAN_NT ); // +10% per trait + } + + // Added character traits influence + if ( this->ubProfile != NO_PROFILE ) + { + // Sociable - better performance in groups + if ( gMercProfiles[ this->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE ) + { + INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_SOCIABLE ); + if ( bNumMercs > 2 ) + modifier += 5; + else if ( bNumMercs > 0 ) + modifier += 2; + } + // Loner - better performance when alone + else if ( gMercProfiles[ this->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER ) + { + INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_LONER ); + if ( bNumMercs == 0 ) + modifier += 5; + else if ( bNumMercs <= 1 ) + modifier += 2; + } + // Aggressive - bonus on bursts/autofire + else if ( gMercProfiles[ this->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE ) + { + if (( this->bDoBurst || this->bDoAutofire ) && !ubAimTime ) + modifier += 10; + } + // Show-off - better performance if some babes around to impress + else if ( gMercProfiles[ this->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF ) + { + INT8 bNumMercs = CheckMercsNearForCharTraits( this->ubProfile, CHAR_TRAIT_SHOWOFF ); + if ( bNumMercs > 1 ) + modifier += 5; + else if ( bNumMercs > 0 ) + modifier += 2; + } + // Added disabilities + if ( this->ubProfile != NO_PROFILE ) + { + // Heat intolerant penalty + if ( MercIsHot( this ) ) + { + modifier -= 15; + } + // Small penalty for fear of insects in tropical sectors + // Flugente: drugs can temporarily cause a merc get a new disability + else if ( ( (gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(this, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( this ) ) + { + // fear of insects, and we are in tropical sector + modifier -= 5; + } + } + } + // Dauntless - penalty for not taking proper cover + if ( ubTargetProfile != NOBODY ) + { + if ( gMercProfiles[ ubTargetProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS ) + modifier += 5; + } + } + else + { + // this rather unlogical bonus for psychotic characters applies only with old traits + if ( this->ubProfile != NO_PROFILE && gMercProfiles[ this->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(this, DRUG_TYPE_PSYCHO)) + { + modifier += AIM_BONUS_PSYCHO; + } + } + + return modifier; +} + +void SOLDIERTYPE::AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect ) +{ + // in case of wrong inout, stay safe + if ( uDrugType >= DRUG_TYPE_MAX ) + return; + + // Add effects + if ( ( this->drugs.bFutureDrugEffect[ uDrugType ] + usEffect ) < 127 ) + { + this->drugs.bFutureDrugEffect[ uDrugType ] += usEffect; + } + this->drugs.bDrugEffectRate[ uDrugType ] = usTravelRate; + + // Reset once we sleep... + this->drugs.bTimesDrugUsedSinceSleep[ uDrugType ]++; + + // Increment side effects.. + if ( ( this->drugs.bDrugSideEffect[ uDrugType ] + usSideEffect ) < 127 ) + { + this->drugs.bDrugSideEffect[ uDrugType ] += usSideEffect; + } + // Stop side effects until were done.... + this->drugs.bDrugSideEffectRate[ uDrugType ] = 0; + + // set flag: we are on drugs + this->bSoldierFlagMask |= SOLDIER_DRUGGED; +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index b60456a18..e30f84a53 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1534,18 +1534,22 @@ public: BOOLEAN IsAssassin(); // Flugente: multi-turn actions - UINT8 GetMultiTurnAction(); - void StartMultiTurnAction(UINT8 usActionType); - void CancelMultiTurnAction(BOOLEAN fFinished); - BOOLEAN UpdateMultiTurnAction(); + UINT8 GetMultiTurnAction(); + void StartMultiTurnAction(UINT8 usActionType); + void CancelMultiTurnAction(BOOLEAN fFinished); + BOOLEAN UpdateMultiTurnAction(); - void DropSectorEquipment(); + void DropSectorEquipment(); // Flugente: switch hand item for gunsling weapon, or pistol, or knife - void SwitchWeapons( BOOLEAN fKnife = FALSE, BOOLEAN fSideArm = FALSE ); + void SwitchWeapons( BOOLEAN fKnife = FALSE, BOOLEAN fSideArm = FALSE ); // Flugente: return a soldier's name. This allows for very easy manipulation of a soldier's name with pre- an suffixes, ranks etc. - STR16 GetName(); + STR16 GetName(); + + INT8 GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubTargetProfile ); + + void AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect ); ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 02198ac28..7e76b358d 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -4989,179 +4989,8 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi iBaseModifier += (FLOAT)(iCurrentMorale * gGameCTHConstants.BASE_LOW_MORALE); } - if ( gGameOptions.fNewTraitSystem ) - { - iTraitModifier = 0; - // 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[usInHand].rocketlauncher || Item[usInHand].singleshotrocketlauncher) - { - iTraitModifier += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!! - - if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT )) - iTraitModifier += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait - } - // Added CtH bonus for Gunslinger trait on pistols and machine-pistols - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_PISTOL ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iTraitModifier += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +10% per trait - } - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_M_PISTOL ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && ((pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto)) - iTraitModifier += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +5% per trait - } - // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_AS_RIFLE ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iTraitModifier += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_SMG ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iTraitModifier += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_LMG ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iTraitModifier += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - // Added CtH bonus for Gunslinger trait on pistols and machine-pistols - else if ( Weapon[usItemAttHand].ubWeaponType == GUN_SN_RIFLE ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierSniperRifles; // -10% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iTraitModifier += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait - } - // Added CtH bonus for Ranger skill on rifles and shotguns - else if ( Weapon[usInHand].ubWeaponType == GUN_RIFLE ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iTraitModifier += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +5% per trait - //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles" - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iTraitModifier += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait - } - else if ( Weapon[usInHand].ubWeaponType == GUN_SHOTGUN ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) ) - iTraitModifier += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +10% per trait - } - // SANDRO - added Throwing trait support on knives - if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierThrowingKnives; // -15% for untrained mercs - - if ( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) ) - iTraitModifier += gSkillTraitValues.ubTHBladesCtHBonus * 2; - //+ (gSkillTraitValues.ubTHBladesCtHBonusPerClick * pSoldier->aiData.bAimTime) ); - } - - // Added small CtH penalty for robot if controller hasn't the Technician trait - if( AM_A_ROBOT( pSoldier ) ) - { - iTraitModifier += gSkillTraitValues.bCtHModifierRobot; // -10% - - if ( HAS_SKILL_TRAIT( pSoldier->GetRobotController(), TECHNICIAN_NT ) ) - iTraitModifier += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( pSoldier->GetRobotController(), TECHNICIAN_NT ); // +10% per trait - } - - // Added character traits influence - if ( pSoldier->ubProfile != NO_PROFILE ) - { - // Sociable - better performance in groups - if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE ); - if ( bNumMercs > 2 ) - iTraitModifier += 5; - else if ( bNumMercs > 0 ) - iTraitModifier += 2; - } - // Loner - better performance when alone - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER ); - if ( bNumMercs == 0 ) - iTraitModifier += 5; - else if ( bNumMercs <= 1 ) - iTraitModifier += 2; - } - // Aggressive - bonus on bursts/autofire - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE ) - { - if (( pSoldier->bDoBurst || pSoldier->bDoAutofire ) && !ubAimTime ) - iTraitModifier += 10; - } - // Show-off - better performance if some babes around to impress - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF ); - if ( bNumMercs > 1 ) - iTraitModifier += 5; - else if ( bNumMercs > 0 ) - iTraitModifier += 2; - } - // Added disabilities - if ( pSoldier->ubProfile != NO_PROFILE ) - { - // Heat intolerant penalty - if ( MercIsHot( pSoldier ) ) - { - iTraitModifier -= 15; - } - // Small penalty for fear of insects in tropical sectors - // Flugente: drugs can temporarily cause a merc get a new disability - else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) ) - { - // fear of insects, and we are in tropical sector - iTraitModifier -= 5; - } - } - } - // Dauntless - penalty for not taking proper cover - if (pTarget != NULL) - { - if ( pTarget->ubProfile != NO_PROFILE ) - { - if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS ) - iTraitModifier += 5; - } - } - //Give 40% the normal stomp modifier as a base mod - iBaseModifier += (FLOAT)iTraitModifier * 0.4f; - } - else - { - // PSYCHO - // Flugente: drugs can temporarily cause a merc to go psycho - if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) ) - { - iBaseModifier += (FLOAT)gGameCTHConstants.BASE_PSYCHO; - } - } + // Flugente: moved trait modifiers into a member function + iTraitModifier = pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, pTarget->ubProfile ); // SHOOTING AT SAME TARGET AGAIN if (sGridNo == pSoldier->sLastTarget ) @@ -6629,166 +6458,9 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, ///////////////////////////////////////////////////////////////////////////////////// // Modify for traits - if( gGameOptions.fNewTraitSystem ) - { - // 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[usInHand].rocketlauncher || Item[usInHand].singleshotrocketlauncher) - { - iChance += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!! - - if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT )) - iChance += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait - } - // Added CtH bonus for Gunslinger trait on pistols and machine-pistols - else if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL ) - { - iChance += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iChance += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +10% per trait - } - else if ( Weapon[usInHand].ubWeaponType == GUN_M_PISTOL ) - { - iChance += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && ((pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto)) - iChance += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +5% per trait - } - // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs - else if ( Weapon[usInHand].ubWeaponType == GUN_AS_RIFLE ) - { - iChance += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iChance += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - else if ( Weapon[usInHand].ubWeaponType == GUN_SMG ) - { - iChance += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iChance += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - else if ( Weapon[usInHand].ubWeaponType == GUN_LMG ) - { - iChance += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) ) - iChance += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait - } - // Added CtH bonus for Gunslinger trait on pistols and machine-pistols - else if ( Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE ) - { - iChance += gSkillTraitValues.bCtHModifierSniperRifles; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iChance += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait - } - // Added CtH bonus for Ranger skill on rifles and shotguns - else if ( Weapon[usInHand].ubWeaponType == GUN_RIFLE ) - { - iChance += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs. - - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iChance += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +5% per trait - //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles" - // this bonus is applied only on single shots! - if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 ) - iChance += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait - } - else if ( Weapon[usInHand].ubWeaponType == GUN_SHOTGUN ) - { - iChance += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs. - - if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) ) - iChance += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +10% per trait - } - - // Added small CtH penalty for robot if controller hasn't the Technician trait - if( AM_A_ROBOT( pSoldier ) ) - { - iChance += gSkillTraitValues.bCtHModifierRobot; // -10% - - if ( HAS_SKILL_TRAIT( pSoldier->GetRobotController(), TECHNICIAN_NT ) ) - iChance += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( pSoldier->GetRobotController(), TECHNICIAN_NT ); // +10% per trait - } - - // Added character traits influence - if ( pSoldier->ubProfile != NO_PROFILE ) - { - // Sociable - better performance in groups - if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE ); - if ( bNumMercs > 2 ) - iChance += 5; - else if ( bNumMercs > 0 ) - iChance += 2; - } - // Loner - better performance when alone - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER ); - if ( bNumMercs == 0 ) - iChance += 5; - else if ( bNumMercs <= 1 ) - iChance += 2; - } - // Aggressive - bonus on bursts/autofire - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE ) - { - if (( pSoldier->bDoBurst || pSoldier->bDoAutofire ) && !ubAimTime ) - iChance += 10; - } - // Show-off - better performance if some babes around to impress - else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF ) - { - INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF ); - if ( bNumMercs > 1 ) - iChance += 5; - else if ( bNumMercs > 0 ) - iChance += 2; - } - // Added disabilities - if ( pSoldier->ubProfile != NO_PROFILE ) - { - // Heat intolerant penalty - if ( MercIsHot( pSoldier ) ) - { - iChance -= 15; - } - // Small penalty for fear of insects in tropical sectors - // Flugente: drugs can temporarily cause a merc get a new disability - else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) ) - { - // fear of insects, and we are in tropical sector - iChance -= 5; - } - } - } - // Dauntless - penalty for not taking proper cover - if (pTarget != NULL) - { - if ( pTarget->ubProfile != NO_PROFILE ) - { - if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS ) - iChance += 5; - } - } - } - else - { - // this rather unlogical bonus for psychotic characters applies only with old traits - if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO ) - { - iChance += AIM_BONUS_PSYCHO; - } - } + // Flugente: moved trait modifiers into a member function + iChance += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, pTarget->ubProfile ); + ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// @@ -9021,12 +8693,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, pTarget->bSoldierFlagMask |= SOLDIER_DRUGGED; // Add lifedamage effects - pTarget->drugs.bFutureDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] = min(pTarget->drugs.bFutureDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] + 3, 127); - pTarget->drugs.bDrugEffectRate[DRUG_TYPE_LIFEDAMAGE] = 1; - pTarget->drugs.bDrugEffect[DRUG_TYPE_LIFEDAMAGE] = 0; - pTarget->drugs.bDrugSideEffectRate[DRUG_TYPE_LIFEDAMAGE] = 0; - pTarget->drugs.bDrugSideEffect[DRUG_TYPE_LIFEDAMAGE] = 127; - pTarget->drugs.bTimesDrugUsedSinceSleep[ DRUG_TYPE_LIFEDAMAGE ]++; + pTarget->AddDrugValues( DRUG_TYPE_LIFEDAMAGE, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugEffect, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugTravelRate, Drug[DRUG_TYPE_LIFEDAMAGE].ubDrugSideEffect ); } else if ( AmmoTypes[ubAmmoType].dart && sHitBy > 20 ) {