From 80c1b65494e4df9cf71b11824eeaaaa754a4edc9 Mon Sep 17 00:00:00 2001 From: Flugente Date: Thu, 19 Dec 2013 20:03:48 +0000 Subject: [PATCH] - New Feature: Spotter skill (available to every merc) allows a merc to be spotter for other snipers. Spotter items have to be in hands, spending APs cancels action. - renamed GetObjectNCTHModifier to GetObjectModifier, as function is no longer used exclusively for NCTH Warning: GameDir >= r1896 is required. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6694 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 7 +- GameSettings.h | 5 + Init.h | 1 + Tactical/DisplayCover.cpp | 7 + Tactical/Faces.cpp | 15 ++ Tactical/Interface Enhanced.cpp | 214 ++++++++++----------- Tactical/Interface.h | 1 + Tactical/Item Types.h | 7 +- Tactical/Items.cpp | 46 ++--- Tactical/Items.h | 33 ++-- Tactical/LOS.cpp | 18 +- Tactical/Morale.cpp | 318 ++++++++++++++++---------------- Tactical/Morale.h | 3 + Tactical/Points.cpp | 3 + Tactical/SkillMenu.cpp | 28 ++- Tactical/Soldier Control.cpp | 176 +++++++++++++++++- Tactical/Soldier Control.h | 12 ++ Tactical/Weapons.cpp | 82 ++++---- Tactical/XML_Background.cpp | 6 + Tactical/soldier profile type.h | 3 + Utils/XML_Items.cpp | 12 +- Utils/_ChineseText.cpp | 18 +- Utils/_DutchText.cpp | 20 +- Utils/_EnglishText.cpp | 20 +- Utils/_FrenchText.cpp | 18 +- Utils/_GermanText.cpp | 19 +- Utils/_ItalianText.cpp | 19 +- Utils/_PolishText.cpp | 19 +- Utils/_RussianText.cpp | 19 +- Utils/_TaiwaneseText.cpp | 19 +- 30 files changed, 723 insertions(+), 445 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 65a0ce1f..6d97b934 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1229,6 +1229,10 @@ void LoadGameExternalOptions() gGameExternalOptions.fScopeModes = iniReader.ReadBoolean("Tactical Gameplay Settings","USE_SCOPE_MODES", FALSE); gGameExternalOptions.fDisplayScopeModes = iniReader.ReadBoolean("Tactical Gameplay Settings","DISPLAY_SCOPE_MODES", FALSE); + gGameExternalOptions.usSpotterPreparationTurns = iniReader.ReadInteger("Tactical Gameplay Settings","SPOTTER_PREPARATIONTURNS", 3, 3, 10); + gGameExternalOptions.usSpotterRange = iniReader.ReadInteger("Tactical Gameplay Settings","SPOTTER_RANGE", 10, 0, 30); + gGameExternalOptions.usSpotterMaxCTHBoost = iniReader.ReadInteger("Tactical Gameplay Settings","SPOTTER_MAX_CTHBOOST", 50, 0, 100); + gGameExternalOptions.ubExternalFeeding = iniReader.ReadInteger("Tactical Gameplay Settings","EXTERNAL_FEEDING", 2, 0, 2); // WANNE: Externalized grid number of new merc when they arrive with the helicopter (by Jazz) @@ -3012,7 +3016,8 @@ void LoadGameAPBPConstants() APBPConstants[AP_HANDCUFF] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_HANDCUFF",50),50); APBPConstants[AP_APPLYITEM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_APPLYITEM",50),50); APBPConstants[AP_INVENTORY_ARM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_INVENTORY_ARM",50),50); - + APBPConstants[AP_SPOTTER] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_SPOTTER",20),20); + APBPConstants[DEFAULT_APS] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","DEFAULT_APS",80),80); APBPConstants[DEFAULT_AIMSKILL] = iniReader.ReadInteger("APConstants","DEFAULT_AIMSKILL",80); diff --git a/GameSettings.h b/GameSettings.h index 3cec3b7b..3872fa6e 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1271,6 +1271,11 @@ typedef struct BOOLEAN fScopeModes; // allow the player to toggle between existing scopes/sights BOOLEAN fDisplayScopeModes; // allow display of scope modes + // Flugente: Spotter skill + UINT8 usSpotterPreparationTurns; + UINT16 usSpotterRange; + UINT16 usSpotterMaxCTHBoost; + // Flugente: External Feeding UINT8 ubExternalFeeding; // allow external feeding of guns (0 = no, 1 = only for others, 2 = we can also fed ourselves) diff --git a/Init.h b/Init.h index 212f1543..d3f40eba 100644 --- a/Init.h +++ b/Init.h @@ -154,6 +154,7 @@ AP_DISGUISE, AP_HANDCUFF, AP_APPLYITEM, AP_INVENTORY_ARM, +AP_SPOTTER, DEFAULT_APS, DEFAULT_AIMSKILL, diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp index 2c075f9c..1f0e4b00 100644 --- a/Tactical/DisplayCover.cpp +++ b/Tactical/DisplayCover.cpp @@ -1358,6 +1358,13 @@ void CalculateTraitRange() } break; + case VARIOUSSKILLS: + { + range1 = gGameExternalOptions.usSpotterRange; + range2 = gGameExternalOptions.usSpotterRange * 2; + } + break; + default: return; } diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp index 2e501bc2..08028aba 100644 --- a/Tactical/Faces.cpp +++ b/Tactical/Faces.cpp @@ -2212,6 +2212,21 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE } } + // Flugente: spotter + if ( MercPtrs[ pFace->ubSoldierID ]->usSkillCounter[SOLDIER_COUNTER_SPOTTER] > 0 ) + { + if ( MercPtrs[ pFace->ubSoldierID ]->IsSpotting() ) + { + DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 24 ); + bNumRightIcons++; + } + else + { + DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 23 ); + bNumRightIcons++; + } + } + switch( pSoldier->bAssignment ) { case DOCTOR: diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 36085633..bff82a46 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -2747,9 +2747,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } } ///////////////////// FLAT BASE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATBASE ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATBASE ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2771,9 +2771,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// PERCENT BASE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTBASE ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTBASE ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2795,9 +2795,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// FLAT AIM MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATAIM ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATAIM ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2819,9 +2819,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// PERCENT AIM MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTAIM ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTAIM ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2843,9 +2843,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// AIMING LEVELS MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_AIMLEVELS ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_AIMLEVELS ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_AIMLEVELS ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_AIMLEVELS ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_AIMLEVELS ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_AIMLEVELS ) != 0 ) { if (cnt >= sFirstLine && cnt < sLastLine) { @@ -2921,9 +2921,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// CTH CAP MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTCAP ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTCAP ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTCAP ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTCAP ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTCAP ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTCAP ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2945,9 +2945,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// GUN HANDLING MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTHANDLING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTHANDLING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTHANDLING ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTHANDLING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTHANDLING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTHANDLING ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2969,9 +2969,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// DROP COMPENSATION MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_DROPCOMPENSATION ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_DROPCOMPENSATION ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_DROPCOMPENSATION ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_DROPCOMPENSATION ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_DROPCOMPENSATION ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_DROPCOMPENSATION ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -2993,9 +2993,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// TARGET TRACKING MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_TRACKING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_TRACKING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_TRACKING ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_TRACKING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_TRACKING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_TRACKING ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -3246,9 +3246,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// MAX COUNTER FORCE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 ) { if( UsingNewCTHSystem() == true && Item[gpItemDescObject->usItem].usItemClass == IC_GUN ) { @@ -3270,9 +3270,9 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr } ///////////////////// COUNTER FORCE ACCURACY MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4852,9 +4852,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// FLAT BASE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATBASE ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATBASE ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4867,9 +4867,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// PERCENT BASE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTBASE ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTBASE ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTBASE ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTBASE ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4882,9 +4882,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// FLAT AIM MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATAIM ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATAIM ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4897,9 +4897,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// PERCENT AIM MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTAIM ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTAIM ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTAIM ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTAIM ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4912,9 +4912,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// AIMING LEVELS MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_AIMLEVELS ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_AIMLEVELS ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_AIMLEVELS ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_AIMLEVELS ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_AIMLEVELS ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_AIMLEVELS ) != 0 ) { if (cnt >= sFirstLine && cnt < sLastLine) { @@ -4951,9 +4951,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// CTH CAP MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTCAP ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTCAP ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTCAP ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTCAP ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTCAP ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTCAP ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4966,9 +4966,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// GUN HANDLING MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTHANDLING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTHANDLING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTHANDLING ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTHANDLING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTHANDLING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTHANDLING ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4981,9 +4981,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// DROP COMPENSATION MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_DROPCOMPENSATION ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_DROPCOMPENSATION ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_DROPCOMPENSATION ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_DROPCOMPENSATION ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_DROPCOMPENSATION ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_DROPCOMPENSATION ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -4995,9 +4995,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } } ///////////////////// TARGET TRACKING MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_TRACKING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_TRACKING ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_TRACKING ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_TRACKING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_TRACKING ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_TRACKING ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -5128,9 +5128,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// MAX COUNTER FORCE MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEMAX ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEMAX ) != 0 ) { if( UsingNewCTHSystem() == true && Item[gpItemDescObject->usItem].usItemClass == IC_GUN ) { @@ -5143,9 +5143,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// COUNTER FORCE ACCURACY MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEACCURACY ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEACCURACY ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -5158,9 +5158,9 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } ///////////////////// COUNTER FORCE FREQUENCY MODIFIER - if ( GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEFREQUENCY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEFREQUENCY ) != 0 - || GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEFREQUENCY ) != 0 ) + if ( GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEFREQUENCY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEFREQUENCY ) != 0 + || GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEFREQUENCY ) != 0 ) { if( UsingNewCTHSystem() == true ) { @@ -6265,7 +6265,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject ) iHandlingValue *= gItemSettings.fHandlingModifierLauncher; // Get modifier - INT16 iHandlingModifier = (iHandlingValue * GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject , ANIM_STAND, NCTHMODIFIER_PERCENTHANDLING )) / 100; + INT16 iHandlingModifier = (iHandlingValue * GetObjectModifier( gpItemDescSoldier, gpItemDescObject , ANIM_STAND, ITEMMODIFIER_PERCENTHANDLING )) / 100; // Get Final Gun Handling value UINT16 iFinalHandlingValue = iHandlingValue + iHandlingModifier; @@ -6338,7 +6338,7 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject ) UINT16 iFinalAimLevelsValue = GetAllowedAimingLevelsForItem( gpItemDescSoldier, gpItemDescObject, ANIM_STAND ); // Get modifier - INT16 iAimLevelsModifier = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_AIMLEVELS ); + INT16 iAimLevelsModifier = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_AIMLEVELS ); iAimLevelsModifier += GetAimLevelsTraitModifier( gpItemDescSoldier, gpItemDescObject ); // Get Base Value @@ -9238,9 +9238,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// FLAT BASE MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATBASE ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATBASE ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATBASE ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATBASE ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATBASE ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATBASE ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9279,9 +9279,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// PERCENT BASE MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTBASE ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTBASE ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTBASE ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTBASE ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTBASE ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTBASE ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9332,9 +9332,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// FLAT AIM MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_FLATAIM ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_FLATAIM ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_FLATAIM ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_FLATAIM ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_FLATAIM ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_FLATAIM ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9373,9 +9373,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// PERCENT AIM MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTAIM ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTAIM ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTAIM ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTAIM ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTAIM ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTAIM ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9426,9 +9426,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// AIMING LEVELS MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_AIMLEVELS ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_AIMLEVELS ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_AIMLEVELS ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_AIMLEVELS ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_AIMLEVELS ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_AIMLEVELS ); if (iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0 ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9586,9 +9586,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// CTH CAP MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTCAP ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTCAP ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTCAP ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTCAP ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTCAP ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTCAP ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9639,9 +9639,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// GUN HANDLING MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_PERCENTHANDLING ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_PERCENTHANDLING ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_PERCENTHANDLING ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_PERCENTHANDLING ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_PERCENTHANDLING ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_PERCENTHANDLING ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9692,9 +9692,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// DROP COMPENSATION MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_DROPCOMPENSATION ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_DROPCOMPENSATION ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_DROPCOMPENSATION ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_DROPCOMPENSATION ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_DROPCOMPENSATION ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_DROPCOMPENSATION ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -9745,9 +9745,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// TARGET TRACKING MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_TRACKING ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_TRACKING ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_TRACKING ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_TRACKING ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_TRACKING ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_TRACKING ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -10199,9 +10199,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// MAX COUNTER FORCE MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEMAX ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEMAX ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEMAX ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEMAX ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEMAX ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEMAX ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true && Item[gpItemDescObject->usItem].usItemClass == IC_GUN ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -10252,9 +10252,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// COUNTER FORCE ACCURACY MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEACCURACY ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEACCURACY ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEACCURACY ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEACCURACY ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEACCURACY ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEACCURACY ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) @@ -10305,9 +10305,9 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) } ///////////////////// COUNTER FORCE FREQUENCY MODIFIER - iModifier[0] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, NCTHMODIFIER_COUNTERFORCEFREQUENCY ); - iModifier[1] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, NCTHMODIFIER_COUNTERFORCEFREQUENCY ); - iModifier[2] = GetObjectNCTHModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, NCTHMODIFIER_COUNTERFORCEFREQUENCY ); + iModifier[0] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_STAND, ITEMMODIFIER_COUNTERFORCEFREQUENCY ); + iModifier[1] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_CROUCH, ITEMMODIFIER_COUNTERFORCEFREQUENCY ); + iModifier[2] = GetObjectModifier( gpItemDescSoldier, gpItemDescObject, ANIM_PRONE, ITEMMODIFIER_COUNTERFORCEFREQUENCY ); if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true ) { if (cnt >= sFirstLine && cnt < sLastLine) diff --git a/Tactical/Interface.h b/Tactical/Interface.h index a021d610..edf39249 100644 --- a/Tactical/Interface.h +++ b/Tactical/Interface.h @@ -184,6 +184,7 @@ enum { BG_BONUS_BREACHINGCHARGE, BG_PERC_CTH_CREATURE, BG_PERC_INSURANCE, + BG_PERC_SPOTTER, BG_MAX, }; diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 0ae8a766..29d92cbc 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -765,8 +765,8 @@ extern OBJECTTYPE gTempObject; #define SIGNAL_SHELL 0x04000000 //67108864 // this is a signal shell that precedes artillery barrages #define POWER_PACK 0x08000000 //134217728 // item continously powers an item it is attached to -#define PLAYER_NET_1_LVL_4 0x10000000 //268435456 -#define PLAYER_NET_2_LVL_4 0x20000000 //536870912 +#define SPOTTERITEM 0x10000000 //268435456 // binocular +/*#define PLAYER_NET_2_LVL_4 0x20000000 //536870912 #define PLAYER_NET_3_LVL_4 0x40000000 //1073741824 #define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/ // ---------------------------------------------------------------- @@ -1165,6 +1165,9 @@ typedef struct // silversurfer: item provides breath regeneration bonus while resting UINT8 ubSleepModifier; + // Flugente: spoting effectiveness + INT16 usSpotting; + } INVTYPE; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index eec73795..194695d9 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -10179,34 +10179,34 @@ INT16 GetToHitBonus( OBJECTTYPE * pObj, INT32 iRange, UINT8 bLightLevel, BOOLEAN // For a "default" value, feed the function a value of ubStance=ANIM_STAND. -INT32 GetItemNCTHModifier(OBJECTTYPE* pObj, UINT8 ubRef, UINT8 usType) +INT32 GetItemModifier(OBJECTTYPE* pObj, UINT8 ubRef, UINT8 usType) { INT32 iModifier = 0; switch( usType ) { - case NCTHMODIFIER_FLATBASE: + case ITEMMODIFIER_FLATBASE: iModifier += BonusReduceMore( Item[pObj->usItem].flatbasemodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_PERCENTBASE: + case ITEMMODIFIER_PERCENTBASE: iModifier += BonusReduceMore( Item[pObj->usItem].percentbasemodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_FLATAIM: + case ITEMMODIFIER_FLATAIM: iModifier += BonusReduceMore( Item[pObj->usItem].flataimmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_PERCENTAIM: + case ITEMMODIFIER_PERCENTAIM: iModifier += BonusReduceMore( Item[pObj->usItem].percentaimmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_PERCENTCAP: + case ITEMMODIFIER_PERCENTCAP: iModifier += BonusReduceMore( Item[pObj->usItem].percentcapmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_PERCENTHANDLING: + case ITEMMODIFIER_PERCENTHANDLING: iModifier += BonusReduceMore( Item[pObj->usItem].percenthandlingmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_DROPCOMPENSATION: + case ITEMMODIFIER_DROPCOMPENSATION: iModifier += BonusReduceMore( Item[pObj->usItem].percentdropcompensationmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_COUNTERFORCEMAX: + case ITEMMODIFIER_COUNTERFORCEMAX: iModifier += BonusReduceMore( Item[pObj->usItem].maxcounterforcemodifier[ubRef], (*pObj)[0]->data.objectStatus ); if(ubRef == 1) @@ -10215,33 +10215,37 @@ INT32 GetItemNCTHModifier(OBJECTTYPE* pObj, UINT8 ubRef, UINT8 usType) iModifier += (INT32)gGameCTHConstants.RECOIL_MAX_COUNTER_PRONE; break; - case NCTHMODIFIER_COUNTERFORCEACCURACY: + case ITEMMODIFIER_COUNTERFORCEACCURACY: iModifier += BonusReduceMore( Item[pObj->usItem].counterforceaccuracymodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_COUNTERFORCEFREQUENCY: + case ITEMMODIFIER_COUNTERFORCEFREQUENCY: iModifier += BonusReduceMore( Item[pObj->usItem].counterforcefrequencymodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_TRACKING: + case ITEMMODIFIER_TRACKING: iModifier += BonusReduceMore( Item[pObj->usItem].targettrackingmodifier[ubRef], (*pObj)[0]->data.objectStatus ); break; - case NCTHMODIFIER_AIMLEVELS: + case ITEMMODIFIER_AIMLEVELS: iModifier += Item[pObj->usItem].aimlevelsmodifier[ubRef]; break; + + case ITEMMODIFIER_SPOTTER: + iModifier += BonusReduceMore( Item[pObj->usItem].usSpotting, (*pObj)[0]->data.objectStatus ); + break; } return iModifier; } // Flugente: unified function (no need to have 12 functions that all do the same thing and clutter the code) -INT32 GetObjectNCTHModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubStance, UINT8 usType ) +INT32 GetObjectModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubStance, UINT8 usType ) { INT32 iModifier=0; UINT8 ubRef = GetStanceModifierRef( ubStance ); - if (pObj->exists() == true && UsingNewCTHSystem() == true) + if (pObj->exists() )//&& UsingNewCTHSystem() == true) { - iModifier += Item[pObj->usItem].aimlevelsmodifier[ubRef]; + iModifier += GetItemModifier( pObj, ubRef, usType); for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) { @@ -10251,7 +10255,7 @@ INT32 GetObjectNCTHModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubSt if ( gGameExternalOptions.fScopeModes && pSoldier && Item[pObj->usItem].usItemClass == IC_GUN && IsAttachmentClass(iter->usItem, (AC_SCOPE|AC_SIGHT|AC_IRONSIGHT) ) ) continue; - iModifier += GetItemNCTHModifier( (&(*iter)), ubRef, usType); + iModifier += GetItemModifier( (&(*iter)), ubRef, usType); } } @@ -10263,7 +10267,7 @@ INT32 GetObjectNCTHModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubSt // only use scope mode if gun is in hand, otherwise an error might occur! if ( (&pSoldier->inv[HANDPOS]) == pObj && ObjList[pSoldier->bScopeMode] != NULL && pSoldier->bScopeMode != USE_ALT_WEAPON_HOLD ) - iModifier += GetItemNCTHModifier(ObjList[pSoldier->bScopeMode], ubRef, usType); + iModifier += GetItemModifier(ObjList[pSoldier->bScopeMode], ubRef, usType); } } @@ -12999,8 +13003,8 @@ UINT8 AllowedAimingLevelsNCTH( SOLDIERTYPE *pSoldier, INT32 sGridNo ) if ( gGameExternalOptions.fWeaponResting && pSoldier->IsWeaponMounted() ) stance = ANIM_PRONE; - INT32 moda = GetObjectNCTHModifier( pSoldier, &pSoldier->inv[pSoldier->ubAttackingHand], stance, NCTHMODIFIER_AIMLEVELS ); - INT32 modb = GetObjectNCTHModifier( pSoldier, &pSoldier->inv[pSoldier->ubAttackingHand], gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_AIMLEVELS ); + INT32 moda = GetObjectModifier( pSoldier, &pSoldier->inv[pSoldier->ubAttackingHand], stance, ITEMMODIFIER_AIMLEVELS ); + INT32 modb = GetObjectModifier( pSoldier, &pSoldier->inv[pSoldier->ubAttackingHand], gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_AIMLEVELS ); aimLevels += (INT32) ((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); } @@ -13381,7 +13385,7 @@ UINT8 GetAllowedAimingLevelsForItem( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, UI } // HEADROCK HAM 4: This modifier from the weapon and its attachments replaces the generic bipod bonus. - aimLevels += GetObjectNCTHModifier( pSoldier, pObj, ubStance, NCTHMODIFIER_AIMLEVELS ); + aimLevels += GetObjectModifier( pSoldier, pObj, ubStance, ITEMMODIFIER_AIMLEVELS ); aimLevels += GetAimLevelsTraitModifier( pSoldier, pObj ); diff --git a/Tactical/Items.h b/Tactical/Items.h index d4ee9ccd..77686044 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -277,24 +277,27 @@ INT16 GetRangeBonus( OBJECTTYPE * pObj ); // Flugente: unified function (no need to have 12 functions that all do the same thing and clutter the code) enum { - NCTHMODIFIER_FLATBASE = 0, - NCTHMODIFIER_PERCENTBASE, - NCTHMODIFIER_FLATAIM, - NCTHMODIFIER_PERCENTAIM, - NCTHMODIFIER_PERCENTCAP, - NCTHMODIFIER_PERCENTHANDLING, - NCTHMODIFIER_DROPCOMPENSATION, - NCTHMODIFIER_COUNTERFORCEMAX, - NCTHMODIFIER_COUNTERFORCEACCURACY, - NCTHMODIFIER_COUNTERFORCEFREQUENCY, - NCTHMODIFIER_TRACKING, - NCTHMODIFIER_AIMLEVELS, + ITEMMODIFIER_FLATBASE = 0, + ITEMMODIFIER_PERCENTBASE, + ITEMMODIFIER_FLATAIM, + ITEMMODIFIER_PERCENTAIM, + ITEMMODIFIER_PERCENTCAP, + ITEMMODIFIER_PERCENTHANDLING, + ITEMMODIFIER_DROPCOMPENSATION, + ITEMMODIFIER_COUNTERFORCEMAX, + ITEMMODIFIER_COUNTERFORCEACCURACY, + ITEMMODIFIER_COUNTERFORCEFREQUENCY, + ITEMMODIFIER_TRACKING, + ITEMMODIFIER_AIMLEVELS, - NCTHMODIFIER_MAX, + // not NCTH, but works the same way... + ITEMMODIFIER_SPOTTER, + + ITEMMODIFIER_MAX, }; -INT32 GetItemNCTHModifier(OBJECTTYPE* pObj, UINT8 ubRef, UINT8 usType); -INT32 GetObjectNCTHModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubStance, UINT8 type ); +INT32 GetItemModifier(OBJECTTYPE* pObj, UINT8 ubRef, UINT8 usType); +INT32 GetObjectModifier( SOLDIERTYPE* pSoldier, OBJECTTYPE *pObj, UINT8 ubStance, UINT8 type ); INT32 GetAimLevelsTraitModifier( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj ); diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 0af02293..19f329ed 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -8092,8 +8092,8 @@ void CalcTargetMovementOffset( SOLDIERTYPE *pShooter, SOLDIERTYPE *pTarget, OBJE // after the target moves a smaller number of tiles. // silversurfer: uiTilesForMaxPenalty is supposed to be small to allow for fast compensation, right? Why do we ADD the tracking modifier then? // According to the description of the tracking modifier: "Higher is better". So we better subtract and also make the modifiers a FLOAT for better precision. - FLOAT moda = (FLOAT)(uiTilesForMaxPenalty * GetObjectNCTHModifier( pShooter, pWeapon, stance, NCTHMODIFIER_TRACKING ) ) / 100; - FLOAT modb = (FLOAT)(uiTilesForMaxPenalty * GetObjectNCTHModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, NCTHMODIFIER_TRACKING ) ) / 100; + FLOAT moda = (FLOAT)(uiTilesForMaxPenalty * GetObjectModifier( pShooter, pWeapon, stance, ITEMMODIFIER_TRACKING ) ) / 100; + FLOAT modb = (FLOAT)(uiTilesForMaxPenalty * GetObjectModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, ITEMMODIFIER_TRACKING ) ) / 100; // uiTilesForMaxPenalty += (INT16)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); uiTilesForMaxPenalty -= (INT16)(((FLOAT)gGameExternalOptions.ubProneModifierPercentage * moda + (100 - (FLOAT)gGameExternalOptions.ubProneModifierPercentage) * modb)/100); @@ -8258,8 +8258,8 @@ void CalcRangeCompensationOffset( SOLDIERTYPE *pShooter, FLOAT *dMuzzleOffsetY, if ( gGameExternalOptions.fWeaponResting && pShooter->IsWeaponMounted() ) stance = ANIM_PRONE; - FLOAT moda = (iCombinedSkill * GetObjectNCTHModifier( pShooter, pWeapon, stance, NCTHMODIFIER_DROPCOMPENSATION )) / 100; - FLOAT modb = (iCombinedSkill * GetObjectNCTHModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, NCTHMODIFIER_DROPCOMPENSATION )) / 100; + FLOAT moda = (iCombinedSkill * GetObjectModifier( pShooter, pWeapon, stance, ITEMMODIFIER_DROPCOMPENSATION )) / 100; + FLOAT modb = (iCombinedSkill * GetObjectModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, ITEMMODIFIER_DROPCOMPENSATION )) / 100; iCombinedSkill += ((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); // Limit this to a scale of 0-100. @@ -8611,8 +8611,8 @@ UINT32 CalcCounterForceFrequency(SOLDIERTYPE *pShooter, OBJECTTYPE *pWeapon) stance = ANIM_PRONE; // Percent Modifier from weapon and its attachments - FLOAT moda = (iCounterForceFrequency * GetObjectNCTHModifier( pShooter, pWeapon, stance, NCTHMODIFIER_COUNTERFORCEFREQUENCY )) / 100; - FLOAT modb = (iCounterForceFrequency * GetObjectNCTHModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, NCTHMODIFIER_COUNTERFORCEFREQUENCY )) / 100; + FLOAT moda = (iCounterForceFrequency * GetObjectModifier( pShooter, pWeapon, stance, ITEMMODIFIER_COUNTERFORCEFREQUENCY )) / 100; + FLOAT modb = (iCounterForceFrequency * GetObjectModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, ITEMMODIFIER_COUNTERFORCEFREQUENCY )) / 100; iCounterForceFrequency += ((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); // Limit to 1-100. @@ -8650,7 +8650,7 @@ FLOAT CalcCounterForceMax(SOLDIERTYPE *pShooter, OBJECTTYPE *pWeapon, UINT8 uiSt iCounterForceMax /= iDivisor; // Add the effects from the weapon and its attachments (foregrip, for instance). This is applied as a percentage. - INT32 iModifier = GetObjectNCTHModifier( pShooter, pWeapon, uiStance, NCTHMODIFIER_COUNTERFORCEMAX ); + INT32 iModifier = GetObjectModifier( pShooter, pWeapon, uiStance, ITEMMODIFIER_COUNTERFORCEMAX ); iCounterForceMax += (iCounterForceMax * iModifier) / 100; // Limit to 0-100. @@ -8686,8 +8686,8 @@ UINT32 CalcCounterForceAccuracy(SOLDIERTYPE *pShooter, OBJECTTYPE *pWeapon, UINT if ( gGameExternalOptions.fWeaponResting && pShooter->IsWeaponMounted() ) stance = ANIM_PRONE; - INT32 moda = GetObjectNCTHModifier( pShooter, pWeapon, stance, NCTHMODIFIER_COUNTERFORCEACCURACY ); - INT32 modb = GetObjectNCTHModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, NCTHMODIFIER_COUNTERFORCEACCURACY ); + INT32 moda = GetObjectModifier( pShooter, pWeapon, stance, ITEMMODIFIER_COUNTERFORCEACCURACY ); + INT32 modb = GetObjectModifier( pShooter, pWeapon, gAnimControl[ pShooter->usAnimState ].ubEndHeight, ITEMMODIFIER_COUNTERFORCEACCURACY ); INT32 iModifier = (INT32)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); UINT32 uiCounterForceAccuracy = (UINT32)(iCounterForceAccuracy + ((iCounterForceAccuracy * iModifier) / 100)); diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index 3ff650d9..eebed70e 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -1085,162 +1085,8 @@ void HourlyMoraleUpdate( void ) } } - // WANNE: Fix by Headrock: Morale and the ice-cream truck. - if (OKToCheckOpinion(pOtherSoldier->ubProfile)) - { - bOpinion = pProfile->bMercOpinion[ pOtherSoldier->ubProfile ]; - } - else - { - bOpinion = 0; - } - - // Flugente: evaluate appearance/refinement/hated nationalities - - // some people loathe ugly people and like beautiful people. It's a mean world. - // we also handle sexism here - switch ( gMercProfiles[ pOtherSoldier->ubProfile ].bAppearance ) - { - case APPEARANCE_UGLY: - { - if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModAppearance * 2; - else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModAppearance * 4; - - // some people are sexists - if ( pProfile->bSexist && gMercProfiles[ pOtherSoldier->ubProfile ].bSex != pProfile->bSex ) - { - if ( pProfile->bSexist == SOMEWHAT_SEXIST ) - bOpinion -= gGameExternalOptions.sMoraleModSexism * 2; - else if ( pProfile->bSexist == VERY_SEXIST ) - bOpinion -= gGameExternalOptions.sMoraleModSexism * 4; - } - } - break; - case APPEARANCE_HOMELY: - { - if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModAppearance; - else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModAppearance * 2; - - // some people are sexists - if ( pProfile->bSexist && gMercProfiles[ pOtherSoldier->ubProfile ].bSex != pProfile->bSex ) - { - if ( pProfile->bSexist == SOMEWHAT_SEXIST ) - bOpinion -= gGameExternalOptions.sMoraleModSexism; - else if ( pProfile->bSexist == VERY_SEXIST ) - bOpinion -= gGameExternalOptions.sMoraleModSexism * 2; - } - } - break; - case APPEARANCE_ATTRACTIVE: - { - if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) - bOpinion += gGameExternalOptions.sMoraleModAppearance; - else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) - bOpinion += gGameExternalOptions.sMoraleModAppearance * 2; - - // some people are sexists - if ( pProfile->bSexist && gMercProfiles[ pOtherSoldier->ubProfile ].bSex != pProfile->bSex ) - { - if ( pProfile->bSexist == SOMEWHAT_SEXIST ) - bOpinion += gGameExternalOptions.sMoraleModSexism; - else if ( pProfile->bSexist == VERY_SEXIST ) - bOpinion += gGameExternalOptions.sMoraleModSexism * 2; - } - } - break; - case APPEARANCE_BABE: - { - if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) - bOpinion += gGameExternalOptions.sMoraleModAppearance * 2; - else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) - bOpinion += gGameExternalOptions.sMoraleModAppearance * 4; - - // some people are sexists - if ( pProfile->bSexist && gMercProfiles[ pOtherSoldier->ubProfile ].bSex != pProfile->bSex ) - { - if ( pProfile->bSexist == SOMEWHAT_SEXIST ) - bOpinion += gGameExternalOptions.sMoraleModSexism * 2; - else if ( pProfile->bSexist == VERY_SEXIST ) - bOpinion += gGameExternalOptions.sMoraleModSexism * 4; - } - } - break; - } - - // some people care about how distuingished other people are. Malus if on different ends of the spectrum, a small bonus if on the same and its really important to the person - // also give a malus if the other person is a slob or snob and we are average but care extremely (we don't like people who behave differently) - switch ( gMercProfiles[ pOtherSoldier->ubProfile ].bRefinement ) - { - case REFINEMENT_SLOB: - { - if ( pProfile->bRefinement == REFINEMENT_AVERAGE ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement; - } - if ( pProfile->bRefinement == REFINEMENT_SLOB ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion += gGameExternalOptions.sMoraleModRefinement; - } - else if ( pProfile->bRefinement == REFINEMENT_SNOB ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement; - else if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement * 2; - } - } - break; - case REFINEMENT_SNOB: - { - if ( pProfile->bRefinement == REFINEMENT_AVERAGE ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement; - } - if ( pProfile->bRefinement == REFINEMENT_SNOB ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion += gGameExternalOptions.sMoraleModRefinement; - } - else if ( pProfile->bRefinement == REFINEMENT_SLOB ) - { - if ( pProfile->bRefinementCareLevel == CARELEVEL_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement; - else if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModRefinement * 2; - } - } - break; - } - - // some people hate other nationalities (do not mix up with racism, which uses bRace) - if ( pProfile->bHatedNationality > -1 && gMercProfiles[ pOtherSoldier->ubProfile ].bNationality == pProfile->bHatedNationality ) - { - if ( pProfile->bHatedNationalityCareLevel == CARELEVEL_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModHatedNationality; - else if ( pProfile->bHatedNationalityCareLevel == CARELEVEL_EXTREME ) - bOpinion -= gGameExternalOptions.sMoraleModHatedNationality * 2; - } - - // some people are racists - if ( pProfile->bRacist && gMercProfiles[ pOtherSoldier->ubProfile ].bRace != pProfile->bRace ) - { - if ( pProfile->bRacist == RACIST_SOME ) - bOpinion -= gGameExternalOptions.sMoraleModRacism; - else if ( pProfile->bRacist == RACIST_VERY ) - bOpinion -= gGameExternalOptions.sMoraleModRacism * 2; - } + bOpinion = SoldierRelation( pSoldier, pOtherSoldier); - // Flugente: backgrounds - if ( pSoldier->HasBackgroundFlag( BACKGROUND_XENOPHOBIC ) && pOtherSoldier->ubProfile != NO_PROFILE && gMercProfiles[pSoldier->ubProfile].usBackground != gMercProfiles[pOtherSoldier->ubProfile].usBackground ) - bOpinion -= gGameExternalOptions.sMoraleModXenophobicBackGround; - if (bOpinion == HATED_OPINION) { bHated = WhichHated( pSoldier->ubProfile, pOtherSoldier->ubProfile ); @@ -1450,4 +1296,166 @@ BOOLEAN IsShowOffNearBy( SOLDIERTYPE * pSoldier ) } return( fYesHeIs ); +} + +// Flugente: calculate A's opinion of B +INT8 SoldierRelation( SOLDIERTYPE* pSoldierA, SOLDIERTYPE* pSoldierB) +{ + INT8 bOpinion = 0; + + // WANNE: Fix by Headrock: Morale and the ice-cream truck. + if ( !OKToCheckOpinion(pSoldierB->ubProfile)) + return 0; + + MERCPROFILESTRUCT* pProfile = &(gMercProfiles[ pSoldierA->ubProfile ]); + + bOpinion = pProfile->bMercOpinion[ pSoldierB->ubProfile ]; + + // Flugente: evaluate appearance/refinement/hated nationalities + + // some people loathe ugly people and like beautiful people. It's a mean world. + // we also handle sexism here + switch ( gMercProfiles[ pSoldierB->ubProfile ].bAppearance ) + { + case APPEARANCE_UGLY: + { + if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModAppearance * 2; + else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModAppearance * 4; + + // some people are sexists + if ( pProfile->bSexist && gMercProfiles[ pSoldierB->ubProfile ].bSex != pProfile->bSex ) + { + if ( pProfile->bSexist == SOMEWHAT_SEXIST ) + bOpinion -= gGameExternalOptions.sMoraleModSexism * 2; + else if ( pProfile->bSexist == VERY_SEXIST ) + bOpinion -= gGameExternalOptions.sMoraleModSexism * 4; + } + } + break; + case APPEARANCE_HOMELY: + { + if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModAppearance; + else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModAppearance * 2; + + // some people are sexists + if ( pProfile->bSexist && gMercProfiles[ pSoldierB->ubProfile ].bSex != pProfile->bSex ) + { + if ( pProfile->bSexist == SOMEWHAT_SEXIST ) + bOpinion -= gGameExternalOptions.sMoraleModSexism; + else if ( pProfile->bSexist == VERY_SEXIST ) + bOpinion -= gGameExternalOptions.sMoraleModSexism * 2; + } + } + break; + case APPEARANCE_ATTRACTIVE: + { + if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) + bOpinion += gGameExternalOptions.sMoraleModAppearance; + else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) + bOpinion += gGameExternalOptions.sMoraleModAppearance * 2; + + // some people are sexists + if ( pProfile->bSexist && gMercProfiles[ pSoldierB->ubProfile ].bSex != pProfile->bSex ) + { + if ( pProfile->bSexist == SOMEWHAT_SEXIST ) + bOpinion += gGameExternalOptions.sMoraleModSexism; + else if ( pProfile->bSexist == VERY_SEXIST ) + bOpinion += gGameExternalOptions.sMoraleModSexism * 2; + } + } + break; + case APPEARANCE_BABE: + { + if ( pProfile->bAppearanceCareLevel == CARELEVEL_SOME ) + bOpinion += gGameExternalOptions.sMoraleModAppearance * 2; + else if ( pProfile->bAppearanceCareLevel == CARELEVEL_EXTREME ) + bOpinion += gGameExternalOptions.sMoraleModAppearance * 4; + + // some people are sexists + if ( pProfile->bSexist && gMercProfiles[ pSoldierB->ubProfile ].bSex != pProfile->bSex ) + { + if ( pProfile->bSexist == SOMEWHAT_SEXIST ) + bOpinion += gGameExternalOptions.sMoraleModSexism * 2; + else if ( pProfile->bSexist == VERY_SEXIST ) + bOpinion += gGameExternalOptions.sMoraleModSexism * 4; + } + } + break; + } + + // some people care about how distuingished other people are. Malus if on different ends of the spectrum, a small bonus if on the same and its really important to the person + // also give a malus if the other person is a slob or snob and we are average but care extremely (we don't like people who behave differently) + switch ( gMercProfiles[ pSoldierB->ubProfile ].bRefinement ) + { + case REFINEMENT_SLOB: + { + if ( pProfile->bRefinement == REFINEMENT_AVERAGE ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement; + } + if ( pProfile->bRefinement == REFINEMENT_SLOB ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion += gGameExternalOptions.sMoraleModRefinement; + } + else if ( pProfile->bRefinement == REFINEMENT_SNOB ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement; + else if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement * 2; + } + } + break; + case REFINEMENT_SNOB: + { + if ( pProfile->bRefinement == REFINEMENT_AVERAGE ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement; + } + if ( pProfile->bRefinement == REFINEMENT_SNOB ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion += gGameExternalOptions.sMoraleModRefinement; + } + else if ( pProfile->bRefinement == REFINEMENT_SLOB ) + { + if ( pProfile->bRefinementCareLevel == CARELEVEL_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement; + else if ( pProfile->bRefinementCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModRefinement * 2; + } + } + break; + } + + // some people hate other nationalities (do not mix up with racism, which uses bRace) + if ( pProfile->bHatedNationality > -1 && gMercProfiles[ pSoldierB->ubProfile ].bNationality == pProfile->bHatedNationality ) + { + if ( pProfile->bHatedNationalityCareLevel == CARELEVEL_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModHatedNationality; + else if ( pProfile->bHatedNationalityCareLevel == CARELEVEL_EXTREME ) + bOpinion -= gGameExternalOptions.sMoraleModHatedNationality * 2; + } + + // some people are racists + if ( pProfile->bRacist && gMercProfiles[ pSoldierB->ubProfile ].bRace != pProfile->bRace ) + { + if ( pProfile->bRacist == RACIST_SOME ) + bOpinion -= gGameExternalOptions.sMoraleModRacism; + else if ( pProfile->bRacist == RACIST_VERY ) + bOpinion -= gGameExternalOptions.sMoraleModRacism * 2; + } + + // Flugente: backgrounds + if ( pSoldierA->HasBackgroundFlag( BACKGROUND_XENOPHOBIC ) && pSoldierB->ubProfile != NO_PROFILE && gMercProfiles[pSoldierA->ubProfile].usBackground != gMercProfiles[pSoldierB->ubProfile].usBackground ) + bOpinion -= gGameExternalOptions.sMoraleModXenophobicBackGround; + + return bOpinion; } \ No newline at end of file diff --git a/Tactical/Morale.h b/Tactical/Morale.h index e644a640..88532d4d 100644 --- a/Tactical/Morale.h +++ b/Tactical/Morale.h @@ -80,4 +80,7 @@ void DailyMoraleUpdate( SOLDIERTYPE *pSoldier ); void DecayTacticalMoraleModifiers( void ); +// Flugente: calculate A's opinion of B +INT8 SoldierRelation( SOLDIERTYPE* pSoldierA, SOLDIERTYPE* pSoldierB); + #endif \ No newline at end of file diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 3527be6a..87f23194 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -869,6 +869,9 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ub INT16 sNewAP = 0; INT8 bNewBreath; + // Flugente: if we spend AP, then spotter status ends + if ( sAPCost > 0) + pSoldier->usSkillCounter[SOLDIER_COUNTER_SPOTTER] = 0; // in real time, there IS no AP cost, (only breath cost) if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) diff --git a/Tactical/SkillMenu.cpp b/Tactical/SkillMenu.cpp index d1733c6b..4cbaa739 100644 --- a/Tactical/SkillMenu.cpp +++ b/Tactical/SkillMenu.cpp @@ -43,7 +43,6 @@ SkillMenuItem::SetupPopup(CHAR* name) /////////////////////////////// Trait Selection //////////////////////////////////////////// TraitSelection gTraitSelection; -//void Wrapper_Function_TraitSelection( UINT32 aVal) { gTraitSelection.Functions(aVal); } void Wrapper_Setup_TraitSelection( UINT32 aVal) { gTraitSelection.Setup(aVal); } void Wrapper_Cancel_TraitSelection( UINT32 aVal ) { gTraitSelection.Cancel(); } /////////////////////////////// Trait Selection //////////////////////////////////////////// @@ -117,9 +116,10 @@ TraitSelection::Setup( UINT32 aVal ) CHAR16 pStr[300]; // create entries for the sub-menus for each trait - const UINT8 num = 1; + const UINT8 num = 2; UINT8 traitarray[num]; traitarray[0] = RADIO_OPERATOR_NT; + traitarray[1] = VARIOUSSKILLS; for ( int i = 0; i < num; ++i) { swprintf( pStr, gzMercSkillTextNew[traitarray[i]] ); @@ -213,6 +213,30 @@ SkillSelection::Setup( UINT32 aVal ) } } break; + + case VARIOUSSKILLS: + { + for(UINT32 uiCounter = SKILLS_VARIOUS_FIRST; uiCounter <= SKILLS_VARIOUS_LAST; ++uiCounter) + { + swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] ); + + pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction( &Wrapper_Function_SkillSelection, uiCounter ) ); + + // if we cannot perform this skill, grey it out + if ( !(pSoldier->CanUseSkill(uiCounter, TRUE)) ) + { + // Set this option off. + pOption->setAvail(new popupCallbackFunction( &Popup_OptionOff, NULL )); + } + + GetPopup()->addOption( *pOption ); + } + + SetTraitToDisplay(VARIOUSSKILLS); + SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo); + ToggleTraitRangeView(TRUE); + } + break; default: break; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index da9cb55d..ee5ed91d 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -17039,7 +17039,10 @@ void SOLDIERTYPE::SoldierPropertyUpkeep() // effects eventually run out for (UINT8 counter = 0; counter < SOLDIER_COUNTER_MAX; ++counter) { - usSkillCounter[counter] = max(0, usSkillCounter[counter] - 1 ); + if ( counter == SOLDIER_COUNTER_SPOTTER && usSkillCounter[counter] > 0 ) + usSkillCounter[counter] = min(255, usSkillCounter[counter] + 1 ); + else + usSkillCounter[counter] = max(0, usSkillCounter[counter] - 1 ); } } @@ -17070,6 +17073,11 @@ BOOLEAN SOLDIERTYPE::CanUseSkill( INT8 iSkill, BOOLEAN fAPCheck ) if ( (!fAPCheck || EnoughPoints( this, APBPConstants[AP_RADIO], APBPConstants[BP_RADIO], FALSE ) ) && (IsJamming() || IsScanning() || IsRadioListening()) ) canuse = TRUE; break; + + case SKILLS_SPOTTER: + if ( (!fAPCheck || EnoughPoints( this, APBPConstants[AP_SPOTTER], 0, FALSE ) ) && CanSpot() ) + canuse = TRUE; + break; default: break; @@ -17122,6 +17130,10 @@ BOOLEAN SOLDIERTYPE::UseSkill( UINT8 iSkill, INT32 usMapPos, UINT8 ID ) return SwitchOffRadio(); break; + case SKILLS_SPOTTER: + return BecomeSpotter(usMapPos); + break; + default: break; } @@ -17177,6 +17189,17 @@ STR16 SOLDIERTYPE::PrintSkillDesc( INT8 iSkill ) wcscat( skilldescarray, atStr ); break; + + case SKILLS_SPOTTER: + swprintf(atStr, pTraitSkillsDenialStrings[TEXT_SKILL_DENIAL_X_AP], APBPConstants[AP_SPOTTER] ); + wcscat( skilldescarray, atStr ); + + swprintf(atStr, pTraitSkillsDenialStrings[TEXT_SKILL_DENIAL_X_TXT], L"a binocular" ); + wcscat( skilldescarray, atStr ); + + swprintf(atStr, pTraitSkillsDenialStrings[TEXT_SKILL_DENIAL_X_TXT], L"patience" ); + wcscat( skilldescarray, atStr ); + break; default: break; @@ -18035,6 +18058,81 @@ void SOLDIERTYPE::DepleteActiveRadioSetEnergy(BOOLEAN fActivation, BOOLEAN fAssi } } +// Flugente: spotter +BOOLEAN SOLDIERTYPE::IsSpotting() +{ + if ( this->usSkillCounter[SOLDIER_COUNTER_SPOTTER] > 0 ) + { + // do we still fulfil the requirements? + if ( CanSpot() ) + { + // we are only a spotter if we did this long enough + if ( this->usSkillCounter[SOLDIER_COUNTER_SPOTTER] >= gGameExternalOptions.usSpotterPreparationTurns ) + return TRUE; + else + return FALSE; + } + + // no item -> lose status + this->usSkillCounter[SOLDIER_COUNTER_SPOTTER] = 0; + } + + return FALSE; +} + +BOOLEAN SOLDIERTYPE::CanSpot( INT32 sTargetGridNo ) +{ + if ( this->stats.bLife < OKLIFE || this->flags.fMercAsleep || this->bCollapsed || (this->bSoldierFlagMask & SOLDIER_POW) ) + return FALSE; + + // additional checks if we want to know wether we can target a specific location + if ( sTargetGridNo != NOWHERE && PythSpacesAway(this->sGridNo, sTargetGridNo) >= 2 * gGameExternalOptions.usSpotterRange ) + { + UINT16 usSightLimit = this->GetMaxDistanceVisible(sTargetGridNo, this->pathing.bLevel, CALC_FROM_WANTED_DIR); + + INT32 val = SoldierToVirtualSoldierLineOfSightTest( this, sTargetGridNo, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE, usSightLimit ); + + // error if we cannot see the target + if ( !val ) + return FALSE; + } + + // no item -> no spotting + if ( !( this->inv[HANDPOS].exists() && GetObjectModifier( this, &(this->inv[ HANDPOS ]), gAnimControl[ this->usAnimState ].ubEndHeight, ITEMMODIFIER_SPOTTER ) ) + && !( this->inv[SECONDHANDPOS].exists() && GetObjectModifier( this, &(this->inv[ SECONDHANDPOS ]), gAnimControl[ this->usAnimState ].ubEndHeight, ITEMMODIFIER_SPOTTER ) ) ) + return FALSE; + + return TRUE; +} + +BOOLEAN SOLDIERTYPE::BecomeSpotter( INT32 sTargetGridNo ) +{ + // not possible if already scanning + if ( this->usSkillCounter[SOLDIER_COUNTER_SPOTTER] ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Already trying to spot, no need to do so again!"); + return FALSE; + } + + if ( !CanSpot( sTargetGridNo ) ) + { + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Cannot spot that location!"); + return FALSE; + } + + // deduct APs + DeductPoints(this, APBPConstants[AP_SPOTTER], 0, 0); + + // add to counter + this->usSkillCounter[SOLDIER_COUNTER_SPOTTER] = 1; + + // stop any multi-turn action + CancelMultiTurnAction(FALSE); + + return TRUE; +} + + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; @@ -20345,6 +20443,10 @@ BOOLEAN HAS_SKILL_TRAIT( SOLDIERTYPE * pSoldier, UINT8 uiSkillTraitNumber ) if ( pSoldier == NULL ) return( FALSE ); + // Flugente: compatibility with skills + if ( uiSkillTraitNumber == VARIOUSSKILLS ) + return TRUE; + INT8 bNumMajorTraitsCounted = 0; INT8 bMaxTraits = gSkillTraitValues.ubMaxNumberOfTraits; INT8 bMaxMajorTraits = gSkillTraitValues.ubNumberOfMajorTraitsAllowed; @@ -21271,6 +21373,78 @@ BOOLEAN PlayerTeamIsScanning() return FALSE; } +// bonus for snipers firing at this location (we get this if there are spotters) +UINT16 GridNoSpotterCTHBonus( SOLDIERTYPE* pSniper, INT32 sGridNo, UINT bTeam) +{ + INT16 bestvalue = 0; + + SOLDIERTYPE* pSoldier = NULL; + INT32 cnt = gTacticalStatus.Team[ bTeam ].bFirstID; + INT32 lastid = gTacticalStatus.Team[ bTeam ].bLastID; + for ( pSoldier = MercPtrs[ cnt ]; cnt < lastid; ++cnt, ++pSoldier) + { + if ( pSoldier != pSniper && pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ + && pSoldier->IsSpotting() + && PythSpacesAway(pSoldier->sGridNo, pSniper->sGridNo) <= gGameExternalOptions.usSpotterRange + && PythSpacesAway(pSoldier->sGridNo, sGridNo) >= 2 * gGameExternalOptions.usSpotterRange ) + { + BOOLEAN targetseen = FALSE; + + UINT usID = WhoIsThere2( sGridNo, pSniper->bTargetLevel ); + + if ( usID != NOBODY && SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[usID], 0, NO_DISTANCE_LIMIT, AIM_SHOT_HEAD ) > 0 ) + targetseen = TRUE; + else if ( SoldierToVirtualSoldierLineOfSightTest( pSoldier, sGridNo, pSoldier->pathing.bLevel, ANIM_PRONE, FALSE, NO_DISTANCE_LIMIT ) > 0 ) + targetseen = TRUE; + + if ( targetseen ) + { + // spotter items are used to determine effectiveness + UINT16 itembonus = 0; + if ( pSoldier->inv[HANDPOS].exists() ) + itembonus += GetObjectModifier( pSoldier, &(pSoldier->inv[ HANDPOS ]), gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_SPOTTER ); + + if ( pSoldier->inv[SECONDHANDPOS].exists() ) + itembonus += GetObjectModifier( pSoldier, &(pSoldier->inv[ SECONDHANDPOS ]), gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_SPOTTER ); + + // cap itembonus to prohibit exploit behaviour by adding dozens of attachments on a gun + itembonus = min(itembonus, 200); + + // base spotter effectivity depends on 40% items, 30% experience, 20% marksmanship an 10% leadership -> value between 0 and 1000 + UINT32 value = 2 * itembonus + 30 * EffectiveExpLevel( pSoldier ) + 2 * EffectiveMarksmanship( pSoldier) + EffectiveLeadership( pSoldier); + + // lowered effectivity if we're fatigued + ReducePointsForFatigue( pSoldier, &value ); + + // lowered effectivity if we're wounded + value = (value * pSoldier->stats.bLife / pSoldier->stats.bLifeMax); + + // relation between sniper and spotter is important - they need to trust each other + INT8 relation = min( 2*BUDDY_OPINION, max( 2*HATED_OPINION, SoldierRelation(pSoldier, pSniper) + SoldierRelation(pSniper, pSoldier) ) ); + + // a good relation boosts value tremendously - a bad relation makes spotting useless + // the spotter background also alters effectiveness + // -> value between 0 and 2300 + value = (value * ( max(0, 100 + 2 * relation + pSoldier->GetBackgroundValue(BG_PERC_SPOTTER)) )) / 100; + + // longer spotting gives a linear bonus - up to 100% -> value between 0 and 4600 + value = (value * min(pSoldier->usSkillCounter[SOLDIER_COUNTER_SPOTTER], 2 * gGameExternalOptions.usSpotterPreparationTurns)) / gGameExternalOptions.usSpotterPreparationTurns; + + // reasonable values: 0 to gGameExternalOptions.usSpotterMaxCTHBoost + value = (value * gGameExternalOptions.usSpotterMaxCTHBoost) / 4600; + + if ( value > bestvalue ) + bestvalue = value; + } + } + } + + // limit value + bestvalue = min( gGameExternalOptions.usSpotterMaxCTHBoost, max(0, bestvalue ) ); + + return bestvalue; +} + void SetDamageDisplayCounter(SOLDIERTYPE* pSoldier) { INT16 sOffsetX, sOffsetY; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 02434bd6..450d51bf 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -548,12 +548,18 @@ enum{ SKILLS_RADIO_TURNOFF, SKILLS_RADIO_LAST = SKILLS_RADIO_TURNOFF, + // various + SKILLS_VARIOUS_FIRST, + SKILLS_SPOTTER = SKILLS_VARIOUS_FIRST, + SKILLS_VARIOUS_LAST = SKILLS_SPOTTER, + SKILLS_MAX, }; // Flugente: certain skills/traits/taints add effects that require a counter, here are enums for these enum { SOLDIER_COUNTER_RADIO_ARTILLERY, // there is actually no need for an artillery timer, but we use one to forbid the same AI guy ordering multiple strikes at once + SOLDIER_COUNTER_SPOTTER, // used to determine wether we are a spotter SOLDIER_COUNTER_MAX = 20, // enough space for fillers }; @@ -1800,6 +1806,11 @@ public: void RadioFail(); // display and error sound used either when the radio set fails or the sector is jammed - the player knows of the error, but cannot be sure of the cause void DepleteActiveRadioSetEnergy(BOOLEAN fActivation = FALSE, BOOLEAN fAssignment = FALSE); + // Flugente: spotter + BOOLEAN IsSpotting(); + BOOLEAN CanSpot( INT32 sTargetGridNo = -1 ); + BOOLEAN BecomeSpotter( INT32 sTargetGridNo ); + ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; @@ -1933,6 +1944,7 @@ BOOLEAN GetRadioOperatorSignal(UINT8 usOwner, INT32* psTargetGridNo); // retriev BOOLEAN IsValidArtilleryOrderSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 bTeam ); // can an artillery strike be ordered FROM this sector BOOLEAN SectorJammed(); BOOLEAN PlayerTeamIsScanning(); +UINT16 GridNoSpotterCTHBonus( SOLDIERTYPE* pSniper, INT32 sGridNo, UINT bTeam); // bonus for snipers firing at this location (we get this if there are spotters) //typedef struct class OLDSOLDIERTYPE_101 diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index 0495fad1..68969aec 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -5249,8 +5249,8 @@ if (gGameExternalOptions.fUseNewCTHCalculation) return gGameExternalOptions.ubMinimumCTH; // Add a flat Base bonus from the item and its attachments. - INT32 imoda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_FLATBASE ); - INT32 imodb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_FLATBASE ); + INT32 imoda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_FLATBASE ); + INT32 imodb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_FLATBASE ); fBaseChance += (FLOAT)((gGameExternalOptions.ubProneModifierPercentage * imoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * imodb)/100); // get bonus from effects lasting on the shooter (morale, injury, shock etc.) @@ -5351,8 +5351,8 @@ if (gGameExternalOptions.fUseNewCTHCalculation) fAimChance += CalcNewChanceToHitAimTraitBonus(pSoldier, fAimChance, fDifference, sGridNo, ubAimTime, fScopeMagFactor, uiBestScopeRange); // Add percent-based modifier from the gun and its attachments - FLOAT moda = (FLOAT)(fAimChance * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTCAP ) / 100); - FLOAT modb = (FLOAT)(fAimChance * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTCAP ) / 100); + FLOAT moda = (FLOAT)(fAimChance * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTCAP ) / 100); + FLOAT modb = (FLOAT)(fAimChance * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTCAP ) / 100); fAimChance += (FLOAT)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); // get aimbonus from effects lasting on the shooter @@ -5366,16 +5366,22 @@ if (gGameExternalOptions.fUseNewCTHCalculation) // apply bonus from traits // Flugente: moved trait modifiers into a member function - UINT8 targetprofile = NOBODY; - if ( pTarget && pTarget->ubProfile != NOBODY ) - targetprofile = pTarget->ubProfile; + UINT8 targetprofile = NOBODY; + if ( pTarget && pTarget->ubProfile != NOBODY ) + targetprofile = pTarget->ubProfile; - fAimModifier += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, targetprofile ); + fAimModifier += pSoldier->GetTraitCTHModifier( usInHand, ubAimTime, targetprofile ); // Flugente: backgrounds if ( pTarget && pTarget->bTeam == CREATURE_TEAM ) fAimModifier += pSoldier->GetBackgroundValue(BG_PERC_CTH_CREATURE); + // Flugente: if we are a sniper and a spotter from our team spots the targetted location, we receive a powerful cth bonus + if ( gGameOptions.fNewTraitSystem && Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE ) + { + fAimModifier += GridNoSpotterCTHBonus( pSoldier, sGridNo, pSoldier->bTeam); + } + // get aimbonus from target fAimModifier += CalcNewChanceToHitAimTargetBonus(pSoldier, pTarget, sGridNo, iRange, ubAimPos, fCantSeeTarget); @@ -5435,8 +5441,8 @@ if (gGameExternalOptions.fUseNewCTHCalculation) { fAimPoints += fAimPointFraction * (ubAllowedAimingLevels-x); // Add Flat Modifier from the weapon and its attachments - INT32 moda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_FLATAIM ); - INT32 modb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_FLATAIM ); + INT32 moda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_FLATAIM ); + INT32 modb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_FLATAIM ); fAimPoints += (FLOAT)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); } @@ -5521,8 +5527,8 @@ else iChance = (INT32)iCombinedSkill; // Add a flat Base bonus from the item and its attachments. - INT32 moda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_FLATBASE ); - INT32 modb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_FLATBASE ); + INT32 moda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_FLATBASE ); + INT32 modb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_FLATBASE ); iChance += (INT32)((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); // We now begin adding up factors that may increase or decrease Base CTH. They are pooled together to form a percentage @@ -5556,6 +5562,12 @@ else if ( pTarget && pTarget->bTeam == CREATURE_TEAM ) iTraitModifier += pSoldier->GetBackgroundValue(BG_PERC_CTH_CREATURE); + // Flugente: if we are a sniper and a spotter from our team spots the targetted location, we receive a powerful cth bonus + if ( gGameOptions.fNewTraitSystem && Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE ) + { + iTraitModifier += (INT8)(GridNoSpotterCTHBonus( pSoldier, sGridNo, pSoldier->bTeam)); + } + // SHOOTING AT SAME TARGET AGAIN if (sGridNo == pSoldier->sLastTarget ) iBaseModifier += (FLOAT)gGameCTHConstants.BASE_SAME_TARGET; @@ -5666,8 +5678,8 @@ else } // Percent based modifier from the gun and its attachments - FLOAT umoda = (iGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTHANDLING )) / 100; - FLOAT umodb = (iGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTHANDLING )) / 100; + FLOAT umoda = (iGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTHANDLING )) / 100; + FLOAT umodb = (iGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTHANDLING )) / 100; iGunBaseDifficulty += ((gGameExternalOptions.ubProneModifierPercentage * umoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * umodb)/100); // End gun difficulty modifiers @@ -5826,8 +5838,8 @@ else } // Percentage based-modifier from the weapon and its attachments - umoda = (iGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTBASE )) / 100; - umodb = (iGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTBASE )) / 100; + umoda = (iGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTBASE )) / 100; + umodb = (iGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTBASE )) / 100; iBaseModifier += ((gGameExternalOptions.ubProneModifierPercentage * umoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * umodb)/100); @@ -6000,8 +6012,8 @@ else iGunAimDifficulty += iTempPenalty; } - FLOAT umoda = (iGunAimDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTHANDLING )) / 100; - FLOAT umodb = (iGunAimDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTHANDLING )) / 100; + FLOAT umoda = (iGunAimDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTHANDLING )) / 100; + FLOAT umodb = (iGunAimDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTHANDLING )) / 100; iGunAimDifficulty += (gGameExternalOptions.ubProneModifierPercentage * umoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * umodb)/100; // End Gun Handling modifiers @@ -6159,8 +6171,8 @@ else } // Percent modifier from the weapon and its attachments - INT32 moda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTAIM ); - INT32 modb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTAIM ); + INT32 moda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTAIM ); + INT32 modb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTAIM ); iAimModifier += (gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100; // Calculate final max aiming @@ -6177,8 +6189,8 @@ else INT32 uiCap = (INT32)iCombinedSkill; // Add percent-based modifier from the gun and its attachments - INT32 uimoda = (INT32)(uiCap * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTCAP )) / 100; - INT32 uimodb = (INT32)(uiCap * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTCAP )) / 100; + INT32 uimoda = (INT32)(uiCap * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTCAP )) / 100; + INT32 uimodb = (INT32)(uiCap * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTCAP )) / 100; uiCap += (INT32)((gGameExternalOptions.ubProneModifierPercentage * uimoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * uimodb)/100); // Add bonuses from Sniper Skill. Applies only when using a scope at or above its "best" range. @@ -6275,8 +6287,8 @@ else { iAimPoints += iAimPointFraction * (ubAllowedAimingLevels-x); // Add Flat Modifier from the weapon and its attachments - INT32 moda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_FLATAIM ); - INT32 modb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_FLATAIM ); + INT32 moda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_FLATAIM ); + INT32 modb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_FLATAIM ); iAimPoints += (gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100; } @@ -7130,6 +7142,12 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, // Flugente: backgrounds if ( pTarget && pTarget->bTeam == CREATURE_TEAM ) iChance += pSoldier->GetBackgroundValue(BG_PERC_CTH_CREATURE); + + // Flugente: if we are a sniper and a spotter from our team spots the targetted location, we receive a powerful cth bonus + if ( gGameOptions.fNewTraitSystem && Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE ) + { + iChance += (INT32)(GridNoSpotterCTHBonus( pSoldier, sGridNo, pSoldier->bTeam)); + } ///////////////////////////////////////////////////////////////////////////////////// @@ -12579,16 +12597,16 @@ FLOAT CalcNewChanceToHitBaseWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, IN } // Percentage based handling modifier from the gun and its attachments - FLOAT moda = (fGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTHANDLING )) / 100; - FLOAT modb = (fGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTHANDLING )) / 100; + FLOAT moda = (fGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTHANDLING )) / 100; + FLOAT modb = (fGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTHANDLING )) / 100; fGunBaseDifficulty += ((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); // Now apply Gun Difficulty to the Base Modifier. fBaseModifier -= fGunBaseDifficulty * gGameCTHConstants.BASE_DRAW_COST; // Percentage based modifier from the weapon and its attachments - moda = (fGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTBASE )) / 100; - modb = (fGunBaseDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTBASE )) / 100; + moda = (fGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTBASE )) / 100; + modb = (fGunBaseDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTBASE )) / 100; fBaseModifier += ((gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100); return fBaseModifier; @@ -12921,16 +12939,16 @@ FLOAT CalcNewChanceToHitAimWeaponBonus(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT } // Percentage based handling modifier from the gun and its attachments - FLOAT moda = (fGunAimDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTHANDLING )) / 100; - FLOAT modb = (fGunAimDifficulty * GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTHANDLING )) / 100; + FLOAT moda = (fGunAimDifficulty * GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTHANDLING )) / 100; + FLOAT modb = (fGunAimDifficulty * GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTHANDLING )) / 100; fGunAimDifficulty += (gGameExternalOptions.ubProneModifierPercentage * moda + (100 - gGameExternalOptions.ubProneModifierPercentage) * modb)/100; // Now apply Gun Difficulty to the Aim Modifier fAimModifier -= gGameCTHConstants.AIM_DRAW_COST * fGunAimDifficulty; // Percent modifier from the weapon and its attachments - INT32 imoda = GetObjectNCTHModifier( pSoldier, pInHand, stance, NCTHMODIFIER_PERCENTAIM ); - INT32 imodb = GetObjectNCTHModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, NCTHMODIFIER_PERCENTAIM ); + INT32 imoda = GetObjectModifier( pSoldier, pInHand, stance, ITEMMODIFIER_PERCENTAIM ); + INT32 imodb = GetObjectModifier( pSoldier, pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight, ITEMMODIFIER_PERCENTAIM ); fAimModifier += (FLOAT)(gGameExternalOptions.ubProneModifierPercentage * imoda + (100 - gGameExternalOptions.ubProneModifierPercentage) * imodb)/100; return fAimModifier; diff --git a/Tactical/XML_Background.cpp b/Tactical/XML_Background.cpp index cb53c2b0..631f3dba 100644 --- a/Tactical/XML_Background.cpp +++ b/Tactical/XML_Background.cpp @@ -123,6 +123,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha strcmp(name, "breachingcharge") == 0 || strcmp(name, "cth_vs_creatures") == 0 || strcmp(name, "insurance") == 0 || + strcmp(name, "spotter") == 0 || strcmp(name, "druguse") == 0 || strcmp(name, "xenophobic") == 0 || strcmp(name, "corruptionspread") == 0 || @@ -505,6 +506,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curBackground.value[BG_PERC_INSURANCE] = min(200, max(-50, (INT16) atol(pData->szCharData) )); } + else if(strcmp(name, "spotter") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_SPOTTER] = min(30, max(-30, (INT16) atol(pData->szCharData) )); + } else if(strcmp(name, "druguse") == 0) { pData->curElement = ELEMENT; diff --git a/Tactical/soldier profile type.h b/Tactical/soldier profile type.h index 935eda3f..638db447 100644 --- a/Tactical/soldier profile type.h +++ b/Tactical/soldier profile type.h @@ -176,6 +176,9 @@ typedef enum #define NEWTRAIT_MERCSKILL_EXPERTOFFSET (NUM_MAJOR_TRAITS + NUM_MINOR_TRAITS) #define NEWTRAIT_MERCSKILL_OFFSET_ALL (NEWTRAIT_MERCSKILL_EXPERTOFFSET + NUM_MAJOR_TRAITS) +// Flugente: various skills that do not need a trait still need a number +#define VARIOUSSKILLS (2 * NEWTRAIT_MERCSKILL_EXPERTOFFSET + 2) + // SANDRO - new set of character traits typedef enum { diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index 7281ae87..bc153f29 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -278,7 +278,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "FlashLightRange") == 0 || strcmp(name, "ItemChoiceTimeSetting") == 0 || strcmp(name, "buddyitem") == 0 || - strcmp(name, "SleepModifier") == 0)) + strcmp(name, "SleepModifier") == 0 || + strcmp(name, "usSpotting") == 0)) { pData->curElement = ELEMENT_PROPERTY; //DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) ); @@ -1438,6 +1439,12 @@ itemEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curItem.ubSleepModifier = (UINT8) atol(pData->szCharData); } + else if(strcmp(name, "usSpotting") == 0) + { + pData->curElement = ELEMENT; + // values between 0 and 100 only + pData->curItem.usSpotting = min(100, max(0, (INT16) atol(pData->szCharData) ) ); + } pData->maxReadDepth--; } @@ -2080,7 +2087,8 @@ BOOLEAN WriteItemStats() FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usItemChoiceTimeSetting ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usBuddyItem ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].ubSleepModifier ); - + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usSpotting ); + FilePrintf(hFile,"\t\r\n"); } FilePrintf(hFile,"\r\n"); diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index ccd59685..1674d39b 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -2128,6 +2128,9 @@ STR16 pTraitSkillsMenuStrings[] = L"监听", //L"Eavesdrop", L"呼叫支援", //L"Call reinforcements", L"关闭接收器", //L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2140,6 +2143,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"使用无线电设备持续监听敌军动向。", //L"Use your radio equipment to continously listen for enemy movement", L"从邻区呼叫支援。", //L"Call in reinforcements from neighbouring sectors.", L"关闭无线电设备以节约电池。", //L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2155,16 +2161,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - 恶魔的财产", //L" - posession by a demon" }; -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"移除佣兵", // remove dead merc from current team @@ -2398,6 +2394,7 @@ STR16 gzMercSkillTextNew[] = L"间谍", // 41 L"Placeholder", // for radio operator (minor trait) L"更多...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7969,6 +7966,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%%暴力开门成功率\n", //L" %s%d%% chance of success with door breaching charges\n", L" %s%d%%射击生物准确率(CTH)\n", //L" %s%d%% cth with firearms against creatures\n", L" %s%d%%医疗保证金\n", //L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 9addfb7a..d470d0a0 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -2124,6 +2124,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2136,6 +2139,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2151,18 +2157,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - - STR16 pRemoveMercStrings[] = { L"Verw.Huurl.", // remove dead merc from current team @@ -2393,6 +2387,7 @@ STR16 gzMercSkillTextNew[] = L"Spy", // 41 L"Placeholder", // for radio operator (minor trait) L"More...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7985,6 +7980,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index b78d60c6..09f08208 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -2128,6 +2128,9 @@ STR16 pTraitSkillsMenuStrings[] = L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", }; //Flugente: short description of the above skills for the skill selection menu @@ -2140,6 +2143,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", }; STR16 pTraitSkillsDenialStrings[] = @@ -2155,16 +2161,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Remove Merc", // remove dead merc from current team @@ -2397,7 +2393,8 @@ STR16 gzMercSkillTextNew[] = L"Placeholder", // 40 L"Spy", // 41 L"Placeholder", // for radio operator (minor trait) - L"More...", + L"More...", // 43 + L"various", // for VARIOUSSKILLS }; ////////////////////////////////////////////////////////// @@ -7967,6 +7964,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", }; STR16 szBackgroundTitleText[] = diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 3a3905ea..3c23788f 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -2131,6 +2131,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2143,6 +2146,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2158,16 +2164,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attaquez", // set militia to aggresive -// L"Tenez la Position", // set militia to stationary -// L"Retraite", // retreat militia -// L"Rejoignez-moi", // retreat militia -// L"Couchez-vous", // retreat militia -// L"Annuler", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Enlever Merc", // remove dead merc from current team @@ -2401,6 +2397,7 @@ STR16 gzMercSkillTextNew[] = L"Espion", // 41 L"Placeholder", // for radio operator (minor trait) L"Plus...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7970,6 +7967,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index b5ae7552..4fb1e516 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -2126,6 +2126,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2138,6 +2141,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2153,17 +2159,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - STR16 pRemoveMercStrings[] ={ L"Söldner entfernen", // remove dead merc from current team L"Abbrechen", @@ -2407,6 +2402,7 @@ STR16 gzMercSkillTextNew[] = L"Spion", // 41 L"Placeholder", // for radio operator (minor trait) L"Mehr...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; // This is pop up help text for the options that are available to the merc @@ -7793,6 +7789,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 0256894f..a2b55d60 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -2120,6 +2120,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2132,6 +2135,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2147,17 +2153,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Rimuovi Mercenario", // remove dead merc from current team @@ -2389,6 +2384,7 @@ STR16 gzMercSkillTextNew[] = L"Spy", // 41 L"Placeholder", // for radio operator (minor trait) L"More...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7972,6 +7968,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index f759fa58..321fba98 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -2136,6 +2136,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2148,6 +2151,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2163,17 +2169,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Atak", // set militia to aggresive -// L"Utrzymaj pozycję", // set militia to stationary -// L"Odwrót", // retreat militia -// L"Za mną", // retreat militia -// L"Padnij", // retreat militia -// L"Anuluj", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Usuń najemnika", // remove dead merc from current team @@ -2404,6 +2399,7 @@ STR16 gzMercSkillTextNew[] = L"Spy", // 41 // TODO.Translate L"Placeholder", // for radio operator (minor trait) L"Więcej...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7996,6 +7992,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index f927c7c1..01aed04f 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -2128,6 +2128,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2140,6 +2143,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2155,17 +2161,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"В атаку", // set militia to aggresive -// L"Держать оборону", // set militia to stationary -// L"Отступать", // retreat militia -// L"За мной", // retreat militia -// L"Ложись", // retreat militia -// L"Отмена", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Убрать бойца", // remove dead merc from current team @@ -2396,6 +2391,7 @@ STR16 gzMercSkillTextNew[] = L"Шпион", // 41 L"Placeholder", // for radio operator (minor trait) L"Ещё...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7970,6 +7966,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index ec14353a..eca32101 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -2128,6 +2128,9 @@ STR16 pTraitSkillsMenuStrings[] = // TODO.Translate L"Eavesdrop", L"Call reinforcements", L"Switch off radio set", + + // various + L"Spotter", // TODO.Translate }; //Flugente: short description of the above skills for the skill selection menu @@ -2140,6 +2143,9 @@ STR16 pTraitSkillsMenuDescStrings[] = L"Use your radio equipment to continously listen for enemy movement", L"Call in reinforcements from neighbouring sectors.", L"Turn off radio set to save batteries.", + + // various + L"Observe an area, granting allied snipers a bonus to cth on anything you see.", // TODO.Translate }; STR16 pTraitSkillsDenialStrings[] = @@ -2155,17 +2161,6 @@ STR16 pTraitSkillsDenialStrings[] = L" - posession by a demon", }; - -//STR16 pTalkToAllMenuStrings[] = -//{ -// L"Attack", // set militia to aggresive -// L"Hold Position", // set militia to stationary -// L"Retreat", // retreat militia -// L"Come to me", // retreat militia -// L"Get down", // retreat militia -// L"Cancel", // cancel this menu -//}; - STR16 pRemoveMercStrings[] = { L"Remove Merc", // remove dead merc from current team @@ -2398,6 +2393,7 @@ STR16 gzMercSkillTextNew[] = L"Spy", // 41 L"Placeholder", // for radio operator (minor trait) L"More...", + L"various", // for VARIOUSSKILLS // TODO.Translate }; ////////////////////////////////////////////////////////// @@ -7988,6 +7984,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% chance of success with door breaching charges\n", L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", + L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate }; STR16 szBackgroundTitleText[] = // TODO.Translate