From e8399bb7c8a78b5d30ab4c71217a57bc892eca79 Mon Sep 17 00:00:00 2001 From: BeatAroundTheBuscher <81776525+BeatAroundTheBuscher@users.noreply.github.com> Date: Fri, 15 Aug 2025 22:52:43 +0200 Subject: [PATCH] Make backpack AP stance costs depend on actual weight instead of a bool checking if a backpack is equipped or not (#486) * Externalize the Divisor for usBackPackWeight A new ini value BACKPACK_WEIGHT_FACTOR is introduced to replace the hard coded 50. The value goes from 1 to 250 and its default value is 50 as before. * Refactor usBPPenalty into its own function GetBackbackAPPenaltyFromBackpack The same code is also used in GetAPsCrouch as well as GetAPsProne The intent of the change is to make sure that backpacks including their content do not add an additional AP cost of +1. Now it checks if the backpack weight is > ubBackPackWeightFactorForAPPenalty (default value 50). The min exists to make sure that the AP cost does not become higher than previously. Previously the bool fBackpackCheck was used to add +1 if there is any backpack. But this also includes an empty tactical sling (backpack with 0.2 kg) and therefore makes the item much less interesting to use. --- Ja2/GameSettings.cpp | 3 +++ Ja2/GameSettings.h | 3 +++ Tactical/Points.cpp | 46 +++++++++++++++++++++++++++++--------------- Tactical/Points.h | 3 +++ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/Ja2/GameSettings.cpp b/Ja2/GameSettings.cpp index cd796702..6f31793b 100644 --- a/Ja2/GameSettings.cpp +++ b/Ja2/GameSettings.cpp @@ -1679,6 +1679,9 @@ void LoadGameExternalOptions() //JMich.BackpackClimb gGameExternalOptions.sBackpackWeightToClimb = iniReader.ReadInteger("Tactical Gameplay Settings", "MAX_BACKPACK_WEIGHT_TO_CLIMB", -1); gGameExternalOptions.fUseGlobalBackpackSettings = iniReader.ReadBoolean("Tactical Gameplay Settings", "USE_GLOBAL_BACKPACK_SETTINGS", TRUE); + + // Buscher + gGameExternalOptions.ubBackPackWeightFactorForAPPenalty = iniReader.ReadInteger("Tactical Gameplay Settings", "BACKPACK_WEIGHT_FACTOR", 50, 1, 250); // sevenfm gGameExternalOptions.fShowEnemyWeapon = iniReader.ReadBoolean("Tactical Gameplay Settings","SHOW_ENEMY_WEAPON", FALSE); diff --git a/Ja2/GameSettings.h b/Ja2/GameSettings.h index 6148086c..74fba2dd 100644 --- a/Ja2/GameSettings.h +++ b/Ja2/GameSettings.h @@ -1361,6 +1361,9 @@ typedef struct INT16 sBackpackWeightToClimb; BOOLEAN fUseGlobalBackpackSettings; + // Buscher + UINT8 ubBackPackWeightFactorForAPPenalty; + // sevenfm: show enemy weapon above soldier in tactical BOOLEAN fShowEnemyWeapon; BOOLEAN fShowEnemyExtendedInfo; diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index ee07e3f0..927425f9 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -604,19 +604,7 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u UINT16 usBPPenalty = APBPConstants[AP_MODIFIER_PACK]; if ( bSlot == BPACKPOCKPOS ) //Backpack caried on back { - OBJECTTYPE * pObj = &( pSoldier->inv[ BPACKPOCKPOS ] ); - UINT16 usBackPackWeight = CalculateObjectWeight( pObj ); - // CalculateObjectWeight checks for active LBE gear. Unfortunatly our backpack is not active since we are carying it. - // Sounds not intuitive at all, active means the LBE caries items (marked with blue *), but when put on the LBE adittional slots of our soldier - // are activated where something can be carried. So we have to add the weights of those slots as well. - std::vector vbLBESlots; - GetLBESlots( BPACKPOCKPOS, vbLBESlots ); - for ( UINT8 i = 0; i < vbLBESlots.size() ; i++ ) - { - pObj = &( pSoldier->inv[ vbLBESlots[ i ] ] ); - usBackPackWeight += CalculateObjectWeight( pObj ); - } - usBPPenalty = min( ( usBackPackWeight / 50 ), usBPPenalty ); //1 AP penalty for each 5kg of weight up to the penalty defined by AP_MODIFIER_PACK (default = 4) + usBPPenalty = GetBackbackAPPenaltyFromBackpack(pSoldier); } else //Backpack caried not on back (maybe somewhere inside another LBE or in Hand?) { @@ -3979,7 +3967,8 @@ INT16 GetAPsCrouch( SOLDIERTYPE *pSoldier, BOOLEAN fBackpackCheck ) // if backpack and new inventory if ( fBackpackCheck && (UsingNewInventorySystem() == true) && pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag) - iFinalAPsToCrouch += fBackpackCheck;//dnl ch70 160913 was 1 + // min was added to stick with the behaviour above (+1) assuming the backpack is heavier than BACKPACK_WEIGHT_FACTOR + iFinalAPsToCrouch += min(1, GetBackbackAPPenaltyFromBackpack(pSoldier)); // -x% APs needed to change stance for MA trait if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem )) @@ -3999,7 +3988,8 @@ INT16 GetAPsProne( SOLDIERTYPE *pSoldier, BOOLEAN fBackpackCheck ) // if backpack and new inventory if ( fBackpackCheck && (UsingNewInventorySystem() == true) && pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag) - iFinalAPsToLieDown += fBackpackCheck;//dnl ch70 160913 was 1 + // min was added to stick with the behaviour above (+1) assuming the backpack is heavier than BACKPACK_WEIGHT_FACTOR + iFinalAPsToLieDown += min(1, GetBackbackAPPenaltyFromBackpack(pSoldier)); // -x% APs needed to change stance for MA trait if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem )) @@ -4403,3 +4393,29 @@ INT16 GetAPsToStartDrag(SOLDIERTYPE *pSoldier, BOOLEAN fStance) return sAPCost; } +INT16 GetBackbackAPPenaltyFromBackpack(SOLDIERTYPE *pSoldier) +{ + UINT16 usBPPenalty = 0; + OBJECTTYPE * pObj = &( pSoldier->inv[ BPACKPOCKPOS ] ); + + if ((UsingNewInventorySystem() == true) && pSoldier->inv[BPACKPOCKPOS].exists() && pObj != NULL) + { + UINT16 usBackPackWeight = CalculateObjectWeight( pObj ); + // CalculateObjectWeight checks for active LBE gear. Unfortunatly our backpack is not active since we are carying it. + // Sounds not intuitive at all, active means the LBE caries items (marked with blue *), but when put on the LBE adittional slots of our soldier + // are activated where something can be carried. So we have to add the weights of those slots as well. + std::vector vbLBESlots; + GetLBESlots( BPACKPOCKPOS, vbLBESlots ); + for ( UINT8 i = 0; i < vbLBESlots.size() ; i++ ) + { + pObj = &( pSoldier->inv[ vbLBESlots[ i ] ] ); + usBackPackWeight += CalculateObjectWeight( pObj ); + } + //1 AP penalty for each 5kg of weight up to the penalty defined by AP_MODIFIER_PACK (default = 4) + // BUSCHER: Externalized the weight factor (previously 50 = 5.0 kg) + // usBPPenalty = min( ( usBackPackWeight / 50 ), usBPPenalty ); + usBPPenalty = min( ( usBackPackWeight / gGameExternalOptions.ubBackPackWeightFactorForAPPenalty), APBPConstants[AP_MODIFIER_PACK] ); + + } + return usBPPenalty; +} \ No newline at end of file diff --git a/Tactical/Points.h b/Tactical/Points.h index 7ca66c9d..9bf9dec9 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -391,4 +391,7 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier ); INT16 GetAPsToBreakWindow(SOLDIERTYPE *pSoldier, BOOLEAN fStance); INT16 GetAPsToStartDrag(SOLDIERTYPE *pSoldier, BOOLEAN fStance); +// Buscher +INT16 GetBackbackAPPenaltyFromBackpack(SOLDIERTYPE *pSoldier); + #endif