From 09ad70f868c7df618b8eaba85f231e4eee0b348b Mon Sep 17 00:00:00 2001 From: Wanne Date: Sun, 7 Mar 2010 11:37:32 +0000 Subject: [PATCH] ************************************************************************* ** Merged source code from development (MP+BMP) trunk (Revision: 3352) ** ** https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP ** ************************************************************************* 1 (Rev. 3343) Changes: Control hardcoded list of unclickable ("bad") sectors via XML file. (by Realist) On the strategic map, the player cannot click or highlight specific sectors (e.g. A4, A5). Introduce a tag in MovementCosts.xml that flags a sector as "bad". (1) Files: /branches/Wanne/JA2 1.13 MP/Build/Strategic/Map Screen Interface Map.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic Movement Costs.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/mapscreen.cpp /branches/Wanne/JA2 1.13 MP/GameDir/Data/TableData/Map /branches/Wanne/JA2 1.13 MP/GameDir/Data/TableData/Map/MovementCosts.xml /branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/TableData/Map /branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/TableData/Map/MovementCosts.xml 2 (Rev. 3344) Changes: Move hardcoded underground sectors initialization to Lua script file. (by Realist) Locate "initunderground.lua" at data-xyz\scripts ("xyz" subject to change). Lua script allows easily adding underground sectors at arbitrary locations and defining enemy garrisons and creature population. Also enables underground bloodcat population. Files: /branches/Wanne/JA2 1.13 MP/Build/Strategic/Campaign Init.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Campaign Types.h /branches/Wanne/JA2 1.13 MP/Build/Strategic/Queen Command.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic AI.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic_2005Express.vcproj /branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic_VS2008.vcproj /branches/Wanne/JA2 1.13 MP/Build/Strategic/UndergroundInit.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/UndergroundInit.h /branches/Wanne/JA2 1.13 MP/Build/Strategic/strategicmap.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Init List.cpp /branches/Wanne/JA2 1.13 MP/GameDir/Data/Scripts /branches/Wanne/JA2 1.13 MP/GameDir/Data/Scripts/initunderground.lua /branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Scripts /branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Scripts/initunderground.lua 3 (Rev. 3345) Changes: Bugfix: In Method CreateDestroyMouseRegionsForFacilityAssignmentMenu() (by Headrock) Files: /branches/Wanne/JA2 1.13 MP/Build/Strategic/Assignments.cpp 4 (Rev. 3346) Changes: Changed order of properties in GameSettings.cpp (by Headrock) HAM 3.6 fixes (by Headrock) Sorted Data-1.13\ja2_options.ini (by Headrock) Files: /branches/Wanne/JA2 1.13 MP/Build/GameSettings.cpp /branches/Wanne/JA2 1.13 MP/Build/GameSettings.h /branches/Wanne/JA2 1.13 MP/Build/Laptop/BobbyRGuns.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Assignments.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/MilitiaSquads.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Strategic Mines.cpp /branches/Wanne/JA2 1.13 MP/Build/Strategic/Town Militia.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Campaign.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Interface Enhanced.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Interface Items.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Items.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Items.h /branches/Wanne/JA2 1.13 MP/Build/Tactical/Overhead.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Control.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Soldier Profile.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Weapons.cpp /branches/Wanne/JA2 1.13 MP/Build/TileEngine/Explosion Control.cpp /branches/Wanne/JA2 1.13 MP/GameDir/Data-1.13/Ja2_Options.INI /branches/Wanne/JA2 1.13 MP/GameDir/INIEditorJA2Options.xml 5 (Rev. 3347) Changes: Bugfix: Turns out that the program is saving the number of used Placement Slots to the temp file fine, but if that number is equal to the limit of how many enemies/civvies are allowed in a sector by the INI settings, it leads to an assertion error instead when trying to re-load that sector. (by Headrock) Re-ordered Data/Ja2_Options.INI (by Headrock) Files: /branches/Wanne/JA2 1.13 MP/Build/Tactical/Enemy Soldier Save.cpp /branches/Wanne/JA2 1.13 MP/GameDir/Data/Ja2_Options.INI 6 (Rev. 3348) Changes: Translated missing HAM 3.6 German Texts (by systemfehler) Files: /branches/Wanne/JA2 1.13 MP/Build/Utils/_GermanText.cpp 7 (Rev. 3351) Changes: PlusAI 1.0 Patch (by Headrock) Files: /branches/Wanne/JA2 1.13 MP/Build/Tactical/Points.cpp /branches/Wanne/JA2 1.13 MP/Build/Tactical/Points.h /branches/Wanne/JA2 1.13 MP/Build/TacticalAI/Attacks.cpp /branches/Wanne/JA2 1.13 MP/Build/TacticalAI/DecideAction.cpp /branches/Wanne/JA2 1.13 MP/Build/TacticalAI/FindLocations.cpp /branches/Wanne/JA2 1.13 MP/Build/TacticalAI/ai.h 8 (Rev. 3352) Changes: Bugfix: The DEBUG only setting "fEnableInventoryPoolQ" is now only enabled in a DEBUG version. In all other builds it is set to FALSE. Files: /branches/Wanne/JA2 1.13 MP/Build/GameSettings.cpp git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@3354 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 1301 +++++++++++++----------- GameSettings.h | 36 +- GameVersion.cpp | 8 +- Laptop/BobbyRGuns.cpp | 28 +- Strategic/Assignments.cpp | 9 +- Strategic/Campaign Init.cpp | 66 +- Strategic/Campaign Types.h | 3 +- Strategic/Map Screen Interface Map.cpp | 43 - Strategic/MilitiaSquads.cpp | 2 +- Strategic/Queen Command.cpp | 64 +- Strategic/Strategic AI.cpp | 14 - Strategic/Strategic Mines.cpp | 20 +- Strategic/Strategic Movement Costs.cpp | 13 + Strategic/Strategic_2005Express.vcproj | 8 + Strategic/Strategic_VS2008.vcproj | 8 + Strategic/Town Militia.cpp | 4 +- Strategic/UndergroundInit.cpp | 161 +++ Strategic/UndergroundInit.h | 8 + Strategic/mapscreen.cpp | 2 - Strategic/strategicmap.cpp | 5 +- Tactical/Campaign.cpp | 5 +- Tactical/Enemy Soldier Save.cpp | 10 +- Tactical/Interface Enhanced.cpp | 14 +- Tactical/Interface Items.cpp | 7 +- Tactical/Items.cpp | 30 + Tactical/Items.h | 5 + Tactical/Overhead.cpp | 13 +- Tactical/Points.cpp | 93 ++ Tactical/Points.h | 2 + Tactical/Soldier Control.cpp | 16 +- Tactical/Soldier Init List.cpp | 27 +- Tactical/Soldier Profile.cpp | 2 +- Tactical/Weapons.cpp | 16 +- TacticalAI/Attacks.cpp | 14 +- TacticalAI/DecideAction.cpp | 26 +- TacticalAI/FindLocations.cpp | 6 +- TacticalAI/ai.h | 6 + TileEngine/Explosion Control.cpp | 9 +- Utils/_GermanText.cpp | 268 +++-- Utils/_RussianText.cpp | 2 +- ja2_2005Express.vcproj | 10 +- ja2_VS2008.vcproj | 16 +- 42 files changed, 1414 insertions(+), 986 deletions(-) create mode 100644 Strategic/UndergroundInit.cpp create mode 100644 Strategic/UndergroundInit.h diff --git a/GameSettings.cpp b/GameSettings.cpp index 6e3a9177..57bae578 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -558,13 +558,40 @@ void LoadGameExternalOptions() #endif } - //################# Laptop Settings ################# + //################# System Limit Settings ################# + + // WDS - make number of mercenaries, etc. be configurable. Note: Changing one of these can render savegames unloadable. + gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_PLAYER_MERCS", 24, 1, CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS); + gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_PLAYER_VEHICLES", 2, 2, CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES); + + gGameExternalOptions.ubGameMaximumNumberOfEnemies = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_ENEMIES_IN_TACTICAL", 32, 16, CODE_MAXIMUM_NUMBER_OF_ENEMIES); + gGameExternalOptions.ubGameMaximumNumberOfCreatures = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_CREATURES_IN_TACTICAL", 32, 0, CODE_MAXIMUM_NUMBER_OF_CREATURES); + gGameExternalOptions.ubGameMaximumNumberOfRebels = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_MILITIA_IN_TACTICAL", 32, 16, CODE_MAXIMUM_NUMBER_OF_REBELS); + gGameExternalOptions.ubGameMaximumNumberOfCivilians = iniReader.ReadInteger("System Limit Settings","MAX_NUMBER_CIVS_IN_TACTICAL", 32, 16, CODE_MAXIMUM_NUMBER_OF_CIVS); + + gGameExternalOptions.iMaxEnemyGroupSize = iniReader.ReadInteger("System Limit Settings","MAX_STRATEGIC_ENEMY_GROUP_SIZE",20, 10, 100); + + //################# Data File Settings ################# + + // WANNE: Always use prof.dat?? + gGameExternalOptions.fUseDifficultyBasedProfDat = iniReader.ReadBoolean("Data File Settings", "USE_DIFFICULTY_BASED_PROF_DAT", TRUE); + + // HEADROCK PROFEX/3.6: Activate this to read Profile data from MercProfiles.XML and MercOpinions.XML + gGameExternalOptions.fReadProfileDataFromXML = iniReader.ReadBoolean("Data File Settings","READ_PROFILE_DATA_FROM_XML", FALSE); + + // HEADROCK PROFEX/3.6: Activate this to write Profile data to MercProfiles Out.XML and MercOpinions Out.XML. This can be used to convert PROF.DAT to XML format. + gGameExternalOptions.fWriteProfileDataToXML = iniReader.ReadBoolean("Data File Settings","WRITE_PROFILE_DATA_TO_XML", FALSE); + + // Use "EnemyWeaponDrop.XML" etc. for determining which items are dropped? + gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("Data File Settings","USE_EXTERNALIZED_ENEMY_ITEM_DROPS", 0, 0, 1); + + //################# Merc Recruitment Settings ################# // WDS: Allow flexible numbers of IMPs of each sex - gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("JA2 Laptop Settings","MAX_IMP_CHARACTERS",1, 1, NUM_PROFILES); + gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("Recruitment Settings","MAX_IMP_CHARACTERS",1, 1, NUM_PROFILES); - gGameExternalOptions.iIMPMaleCharacterCount = iniReader.ReadInteger("JA2 Laptop Settings","IMP_MALE_CHARACTER_COUNT", COUNT_STANDARD_MALE_SLOTS, 1, NUM_PROFILES); - gGameExternalOptions.iIMPFemaleCharacterCount = iniReader.ReadInteger("JA2 Laptop Settings","IMP_FEMALE_CHARACTER_COUNT", COUNT_STANDARD_FEMALE_SLOTS, 1, NUM_PROFILES); + gGameExternalOptions.iIMPMaleCharacterCount = iniReader.ReadInteger("Recruitment Settings","IMP_MALE_CHARACTER_COUNT", COUNT_STANDARD_MALE_SLOTS, 1, NUM_PROFILES); + gGameExternalOptions.iIMPFemaleCharacterCount = iniReader.ReadInteger("Recruitment Settings","IMP_FEMALE_CHARACTER_COUNT", COUNT_STANDARD_FEMALE_SLOTS, 1, NUM_PROFILES); if (gGameExternalOptions.iIMPMaleCharacterCount + gGameExternalOptions.iIMPFemaleCharacterCount > NUM_PROFILES) { gGameExternalOptions.iIMPMaleCharacterCount = COUNT_STANDARD_MALE_SLOTS; @@ -588,7 +615,7 @@ void LoadGameExternalOptions() for (idx = 0; idx < gGameExternalOptions.iIMPMaleCharacterCount; ++idx) { sprintf( caCountStr, caMaleCountStr, idx+1); - gGameExternalOptions.iaIMPSlots[idx] = iniReader.ReadInteger("JA2 Laptop Settings",caCountStr, -1, -1, NUM_PROFILES-1); + gGameExternalOptions.iaIMPSlots[idx] = iniReader.ReadInteger("Recruitment Settings",caCountStr, -1, -1, NUM_PROFILES-1); if (gGameExternalOptions.iaIMPSlots[idx] < 0) { if (idx < COUNT_STANDARD_MALE_SLOTS) @@ -606,7 +633,7 @@ void LoadGameExternalOptions() for (idx = 0; idx < gGameExternalOptions.iIMPFemaleCharacterCount; ++idx) { sprintf( caCountStr, caFemaleCountStr, idx+1); - gGameExternalOptions.iaIMPSlots[idx+gGameExternalOptions.iIMPMaleCharacterCount+1] = iniReader.ReadInteger("JA2 Laptop Settings",caCountStr, -1, -1, NUM_PROFILES-1); + gGameExternalOptions.iaIMPSlots[idx+gGameExternalOptions.iIMPMaleCharacterCount+1] = iniReader.ReadInteger("Recruitment Settings",caCountStr, -1, -1, NUM_PROFILES-1); if (gGameExternalOptions.iaIMPSlots[idx+gGameExternalOptions.iIMPMaleCharacterCount+1] < 0) { if (idx < COUNT_STANDARD_FEMALE_SLOTS) @@ -622,194 +649,412 @@ void LoadGameExternalOptions() } gGameExternalOptions.iaIMPSlots[gGameExternalOptions.iIMPFemaleCharacterCount+gGameExternalOptions.iIMPMaleCharacterCount+1] = -1; - //Character generation - gGameExternalOptions.iMinAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MIN_ATTRIBUTE_POINT",35, 1, 99); - gGameExternalOptions.iMaxAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ATTRIBUTE_POINT",90, gGameExternalOptions.iMinAttribute+1, 100); - gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("JA2 Laptop Settings","IMPATTRIBUTEPOINTS",40, 1, 100); - gGameExternalOptions.iMaxZeroBonus = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ZERO_BONUS",15, 0, 100); - gGameExternalOptions.iStartAttribute = iniReader.ReadInteger("JA2 Laptop Settings","START_ATTRIBUTE",55, 1, 100); - - //gGameExternalOptions.fPers_att = iniReader.ReadBoolean("JA2 Laptop Settings","USE_RANDOM_PERSONALITY",FALSE); - // These two removed - SANDRO - //gGameExternalOptions.iCustomPersonality = (INT8) iniReader.ReadInteger("JA2 Laptop Settings","CUSTOM_PERSONALITY",0, 0, NUM_PERSONALITYTRAIT-1); - //gGameExternalOptions.iCustomAttitude = (INT8) iniReader.ReadInteger("JA2 Laptop Settings","CUSTOM_ATTITUDE",0, 0, NUM_ATTITUDES-1); - // These three added - SANDRO - gGameExternalOptions.iIMPStartingLevelCostMultiplier = iniReader.ReadInteger("JA2 Laptop Settings","IMP_STARTING_LEVEL_COST_MULTIPLIER", 5, 0, 100); - gGameExternalOptions.iBonusPointsForDisability = iniReader.ReadInteger("JA2 Laptop Settings","IMP_BONUS_POINTS_FOR_DISABILITY",20, 0, 500); - gGameExternalOptions.iBonusPointsPerSkillNotTaken = iniReader.ReadInteger("JA2 Laptop Settings","IMP_BONUS_POINTS_PER_SKILL_NOT_TAKEN",25, 0, 500); + //I.M.P Character generation + gGameExternalOptions.iStartAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_INITIAL_ATTRIBUTES",55, 1, 100); + gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("Recruitment Settings","IMP_INITIAL_POINTS",40, 1, 100); + gGameExternalOptions.iMinAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_MIN_ATTRIBUTE",35, 1, 99); + gGameExternalOptions.iMaxZeroBonus = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_FOR_ZERO_ATTRIBUTE",15, 0, 100); + gGameExternalOptions.iMaxAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_MAX_ATTRIBUTE",90, gGameExternalOptions.iMinAttribute+1, 100); + gGameExternalOptions.iIMPStartingLevelCostMultiplier = iniReader.ReadInteger("Recruitment Settings","IMP_STARTING_LEVEL_COST_MULTIPLIER", 5, 0, 100); + gGameExternalOptions.iBonusPointsForDisability = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_FOR_DISABILITY",20, 0, 500); + gGameExternalOptions.iBonusPointsPerSkillNotTaken = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_PER_SKILL_NOT_TAKEN",25, 0, 500); //Merc settings - gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("JA2 Laptop Settings","MERC_AVAILABLE_DAY_ONE",FALSE); - gGameExternalOptions.fAllMercsAvailable = iniReader.ReadBoolean("JA2 Laptop Settings","ALL_MERCS_AT_MERC",FALSE); + gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_IMMEDIATELY_AVAILABLE",FALSE); + gGameExternalOptions.fAllMercsAvailable = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_ALL_MERCS_AVAILABLE",FALSE); //Merc Death Settings: - gGameExternalOptions.gfMercsDieOnAssignment = iniReader.ReadBoolean("JA2 Laptop Settings","MERCS_DIE_ON_ASSIGNMENT",TRUE); - gGameExternalOptions.giEasyMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EASY_MERC_DEATHS",1, 0, 10); - gGameExternalOptions.giExperiencedMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERIENCED_MERC_DEATHS",2, 0, 10); - gGameExternalOptions.giExpertMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERT_MERC_DEATHS",3, 0, 10); - gGameExternalOptions.giInsaneMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","INSANE_MERC_DEATHS",4, 0, 10); + gGameExternalOptions.gfMercsDieOnAssignment = iniReader.ReadBoolean("Recruitment Settings","MERCS_CAN_DIE_ON_ASSIGNMENT",TRUE); + gGameExternalOptions.giEasyMercDeaths = iniReader.ReadInteger("Recruitment Settings","MAX_MERC_DEATHS_EASY",1, 0, 10); + gGameExternalOptions.giExperiencedMercDeaths = iniReader.ReadInteger("Recruitment Settings","MAX_MERC_DEATHS_EXPERIENCED",2, 0, 10); + gGameExternalOptions.giExpertMercDeaths = iniReader.ReadInteger("Recruitment Settings","MAX_MERC_DEATHS_EXPERT",3, 0, 10); + gGameExternalOptions.giInsaneMercDeaths = iniReader.ReadInteger("Recruitment Settings","MAX_MERC_DEATHS_INSANE",4, 0, 10); - //################# System Settings ################# - gGameExternalOptions.gubDeadLockDelay = (UINT8) iniReader.ReadInteger("JA2 System Settings","DEAD_LOCK_DELAY",15, 5, 50); - gGameExternalOptions.gfEnableEmergencyButton_SkipStrategicEvents = iniReader.ReadBoolean("JA2 System Settings","ENABLE_EMERGENCY_BUTTON_NUMLOCK_TO_SKIP_STRATEGIC_EVENTS",0); + // CHRISL: New setting to allow Slay to remain as a hired PC + gGameExternalOptions.fEnableSlayForever = iniReader.ReadBoolean("Recruitment Settings", "SLAY_STAYS_FOREVER", FALSE); + + //################# Financial Settings ################# + + gGameExternalOptions.iStartingCashNovice = iniReader.ReadInteger("Financial Settings", "STARTING_CASH_NOVICE",45000, 2000, 0x0FFFFFFF); + gGameExternalOptions.iStartingCashExperienced = iniReader.ReadInteger("Financial Settings", "STARTING_CASH_EXPERIENCED",35000, 2000, 0x0FFFFFFF); + gGameExternalOptions.iStartingCashExpert = iniReader.ReadInteger("Financial Settings", "STARTING_CASH_EXPERT",30000, 2000, 0x0FFFFFFF); + gGameExternalOptions.iStartingCashInsane = iniReader.ReadInteger("Financial Settings", "STARTING_CASH_INSANE",15000, 2000, 0x0FFFFFFF); + + // HEADROCK HAM B1: Set % of mine income, where 100% = normal + gGameExternalOptions.usMineIncomePercentage = iniReader.ReadInteger("Financial Settings","MINE_INCOME_PERCENTAGE", 100, 1, 1000); + + // ALT+LMB item selling + gGameExternalOptions.fSellAll = iniReader.ReadBoolean("Financial Settings","SELL_ITEMS_WITH_ALT_LMB",FALSE); + gGameExternalOptions.iPriceModifier = iniReader.ReadInteger("Financial Settings","SELL_ITEMS_PRICE_MODIFIER",10, -1, 100); + + gGameExternalOptions.iMilitiaTrainingCost = iniReader.ReadInteger("Financial Settings","MILITIA_BASE_TRAINING_COST",750, 10, 10000); + gGameExternalOptions.iRegularCostModifier = iniReader.ReadInteger("Financial Settings","MILITIA_COST_MULTIPLIER_REGULAR",1, 1, 10); + gGameExternalOptions.iVeteranCostModifier = iniReader.ReadInteger("Financial Settings","MILITIA_COST_MULTIPLIER_ELITE",2, 1, 10); + gGameExternalOptions.iMilitiaCostModifier = iniReader.ReadInteger("Financial Settings","MILITIA_COST_MULTIPLIER_MOBILE",3, 1, 10); + + // HEADROCK HAM 3.6: Daily upkeep costs for militia + gGameExternalOptions.usDailyCostTownGreen = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_TOWN_GREEN", 0, 0, 10000); + gGameExternalOptions.usDailyCostTownRegular = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_TOWN_REGULAR", 0, 0, 10000); + gGameExternalOptions.usDailyCostTownElite = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_TOWN_ELITE", 0, 0, 10000); + gGameExternalOptions.usDailyCostMobileGreen = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_MOBILE_GREEN", 0, 0, 10000); + gGameExternalOptions.usDailyCostMobileRegular = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_MOBILE_REGULAR", 0, 0, 10000); + gGameExternalOptions.usDailyCostMobileElite = iniReader.ReadInteger("Financial Settings","DAILY_MILITIA_UPKEEP_MOBILE_ELITE", 0, 0, 10000); + + // HEADROCK HAM 3.5: Helicopter - Base cost per sector. GREEN = Free airspace, RED = Enemy-controlled airspace. + gGameExternalOptions.usHelicopterBaseCostPerGreenTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_GREEN_TILE", 100, 0, 60000); + gGameExternalOptions.usHelicopterBaseCostPerRedTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_RED_TILE", 1000, 0, 60000); + + //################# Troubleshooting Settings ################# + + gGameExternalOptions.gubDeadLockDelay = (UINT8) iniReader.ReadInteger("Troubleshooting Settings","DEAD_LOCK_DELAY",15, 5, 50); + gGameExternalOptions.gfEnableEmergencyButton_SkipStrategicEvents = iniReader.ReadBoolean("Troubleshooting Settings","ENABLE_EMERGENCY_BUTTON_NUMLOCK_TO_SKIP_STRATEGIC_EVENTS",0); // WDS - Automatically try to save when an assertion failure occurs - gGameExternalOptions.autoSaveOnAssertionFailure = iniReader.ReadBoolean("JA2 System Settings","AUTO_SAVE_ON_ASSERTION_FAILURE", FALSE); - gGameExternalOptions.autoSaveTime = iniReader.ReadInteger("JA2 System Settings","AUTO_SAVE_TIME", 6, 0, 24); + gGameExternalOptions.autoSaveOnAssertionFailure = iniReader.ReadBoolean("Troubleshooting Settings","AUTO_SAVE_ON_ASSERTION_FAILURE", FALSE); + gGameExternalOptions.autoSaveTime = iniReader.ReadInteger("Troubleshooting Settings","AUTO_SAVE_EVERY_N_HOURS", 6, 0, 24); - //################# Video Settings ################# - gGameExternalOptions.gfVSync = iniReader.ReadBoolean("JA2 Video Settings","VERTICAL_SYNC",0); + //################# Graphics Settings ################# + gGameExternalOptions.gfVSync = iniReader.ReadBoolean("Graphics Settings","VERTICAL_SYNC",0); + gGameExternalOptions.giPlayerTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","PLAYER_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); + gGameExternalOptions.giEnemyTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","ENEMY_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); + gGameExternalOptions.giCreatureTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","CREATURE_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); + gGameExternalOptions.giMilitiaTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","MILITIA_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); + gGameExternalOptions.giCivilianTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","CIVILIAN_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); - //################# Animation Settings ################# - gGameExternalOptions.gubPlayerTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","PLAYER_TURN_SPEED_UP_FACTOR",1, 0, 100); - gGameExternalOptions.gubEnemyTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","ENEMY_TURN_SPEED_UP_FACTOR",1, 0, 100); - gGameExternalOptions.gubCreatureTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","CREATURE_TURN_SPEED_UP_FACTOR",1, 0, 100); - gGameExternalOptions.gubMilitiaTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","MILITIA_TURN_SPEED_UP_FACTOR",1, 0, 100); - gGameExternalOptions.gubCivilianTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","CIVILIAN_TURN_SPEED_UP_FACTOR",1, 0, 100); + gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("Graphics Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE); + //afp - use a different graphic for bullets? + gGameExternalOptions.gbBulletTracer = iniReader.ReadBoolean("Graphics Settings","ALTERNATE_BULLET_GRAPHICS",FALSE); + // Are enemy females restricted to Blackshirts only? + gGameExternalOptions.fRestrictFemaleEnemiesExceptElite = iniReader.ReadBoolean("Graphics Settings","RESTRICT_FEMALE_ENEMIES_EXCEPT_ELITE",FALSE); + + //################# Sound Settings ################# - gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("JA2 Sound Settings","WEAPON_SOUND_EFFECTS_VOLUME",0, 0, 1000 /*1000 = 10x?*/); + + gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("Sound Settings","WEAPON_SOUND_EFFECTS_VOLUME",0, 0, 1000 /*1000 = 10x?*/); - //################# Tactical Settings ################# + //################# Tactical Interface Settings ################# - gGameExternalOptions.gfRevealItems = iniReader.ReadBoolean("JA2 Tactical Settings","REVEAL_ITEMS_AFTER_COMBAT",TRUE); - - // Militia Settings - gGameExternalOptions.fAllowTacticalMilitiaCommand = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_TACTICAL_MILITIA_COMMAND",0); - - // Enemy AP settings - gGameExternalOptions.iEasyAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","NOVICE_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); - gGameExternalOptions.iExperiencedAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","EXPERIENCED_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); - gGameExternalOptions.iExpertAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","EXPERT_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); - gGameExternalOptions.iInsaneAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","INSANE_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); - gGameExternalOptions.iPlayerAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","PLAYER_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); - - // Sight range - gGameExternalOptions.ubStraightSightRange = iniReader.ReadInteger("JA2 Tactical Settings","BASE_SIGHT_RANGE",13, 5, 100); - gGameExternalOptions.ubVisDistDecreasePerRainIntensity = iniReader.ReadInteger("JA2 Tactical Settings","VISUAL_DISTANCE_DECREASE_PER_RAIN_INTENSITY",30, 0, 100); - gGameExternalOptions.gfAllowLimitedVision = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_LIMITED_VISION",0); - - // Maximal search distance for grenades - //gGameExternalOptions.guiMaxTossSearchDist = iniReader.ReadInteger("JA2 Tactical Settings","MaxTossSearchDist",3); - - // Soldier tool tips - removed from here, placed into preferences - SANDRO - //gGameExternalOptions.gfAllowSoldierToolTips = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_SOLDIER_TOOL_TIPS",0); - //SCORE: Settings for UDT - gGameExternalOptions.gfAllowUDTRange = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_UDT_RANGE",0); - gGameExternalOptions.gfAllowUDTDetail = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_UDT_DETAIL",0); - gGameExternalOptions.ubUDTModifier = (UINT8) iniReader.ReadInteger("JA2 Tactical Settings", "UDT_MODIFIER", 50); - - // ShadoWarrior: Tooltip changes (start) - gGameExternalOptions.ubSoldierTooltipDetailLevel = (UINT8) iniReader.ReadInteger("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DETAIL_LEVEL", 1, 0, 4); - - gGameExternalOptions.fEnableDynamicSoldierTooltips = iniReader.ReadBoolean("JA2 Tactical Settings", "DYNAMIC_SOLDIER_TOOLTIPS", TRUE); - gGameExternalOptions.fEnableSoldierTooltipLocation = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_LOCATION", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBrightness = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BRIGHTNESS", TRUE); - gGameExternalOptions.fEnableSoldierTooltipRangeToTarget = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_RANGE_TO_TARGET", TRUE); - gGameExternalOptions.fEnableSoldierTooltipID = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_ID", TRUE); - gGameExternalOptions.fEnableSoldierTooltipOrders = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_ORDERS", TRUE); - gGameExternalOptions.fEnableSoldierTooltipAttitude = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_ATTITUDE", TRUE); - gGameExternalOptions.fEnableSoldierTooltipActionPoints = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_ACTIONPOINTS", TRUE); - gGameExternalOptions.fEnableSoldierTooltipHealth = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_HEALTH", TRUE); - gGameExternalOptions.fEnableSoldierTooltipHelmet = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_HELMET", TRUE); - gGameExternalOptions.fEnableSoldierTooltipVest = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_VEST", TRUE); - gGameExternalOptions.fEnableSoldierTooltipLeggings = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_LEGGINGS", TRUE); - gGameExternalOptions.fEnableSoldierTooltipHeadItem1 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_HEAD_SLOT_1", TRUE); - gGameExternalOptions.fEnableSoldierTooltipHeadItem2 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_HEAD_SLOT_2", TRUE); - gGameExternalOptions.fEnableSoldierTooltipWeapon = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_WEAPON", TRUE); - gGameExternalOptions.fEnableSoldierTooltipSecondHand = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_OFF_HAND", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot1 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_1", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot2 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_2", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot3 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_3", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot4 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_4", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot5 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_5", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot6 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_6", TRUE); - gGameExternalOptions.fEnableSoldierTooltipBigSlot7 = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_7", TRUE); - // ShadoWarrior: Tooltip changes (end) + gGameExternalOptions.gfRevealItems = iniReader.ReadBoolean("Tactical Interface Settings","REVEAL_DROPPED_ENEMY_ITEMS_AFTER_COMBAT",TRUE); // Unload weapons & remove attachments - gGameExternalOptions.gfShiftFUnloadWeapons = iniReader.ReadBoolean("JA2 Tactical Settings","SHIFT_F_UNLOAD_WEAPONS",1); - gGameExternalOptions.gfShiftFRemoveAttachments = iniReader.ReadBoolean("JA2 Tactical Settings","SHIFT_F_REMOVE_ATTACHMENTS",1); + gGameExternalOptions.gfShiftFUnloadWeapons = iniReader.ReadBoolean("Tactical Interface Settings","SHIFT_F_UNLOAD_WEAPONS",1); + gGameExternalOptions.gfShiftFRemoveAttachments = iniReader.ReadBoolean("Tactical Interface Settings","SHIFT_F_REMOVE_ATTACHMENTS",1); + + // WDS - Smart goggle switching + gGameExternalOptions.smartGoggleSwitch = iniReader.ReadBoolean("Tactical Interface Settings","SMART_GOGGLE_SWAP", FALSE); + + // HEADROCK HAM 3.5: When enabled, goggle-switching affects every merc in the sector, not just those belonging to the current squad. + gGameExternalOptions.fGoggleSwapAffectsAllMercsInSector = iniReader.ReadBoolean("Tactical Interface Settings","GOGGLE_SWAP_AFFECTS_ALL_MERCS_IN_SECTOR", FALSE); + + // WDS - Automatically flag mines + gGameExternalOptions.automaticallyFlagMines = iniReader.ReadBoolean("Tactical Interface Settings","AUTOMATICALLY_FLAG_MINES_WHEN_SPOTTED", FALSE); + + // Tactical militia command + gGameExternalOptions.fAllowTacticalMilitiaCommand = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_TACTICAL_MILITIA_COMMAND",0); + + // Determines where to use the Enhanced Description Box. Turn on/off via in-game options menu. + gGameExternalOptions.iEnhancedDescriptionBox = iniReader.ReadInteger("Tactical Interface Settings","USE_ENHANCED_DESCRIPTION_BOX",0, 0, 2); + + // HEADROCK HAM B2.6/2/1: Toggle new Burst/Auto Targeting Cursors: 0=neither, 1=both, 2=Burst, 3=Auto + gGameExternalOptions.ubNewCTHBars = iniReader.ReadInteger("Tactical Interface Settings","USE_NEW_BURST-AUTO_TARGETING_CURSORS", 0, 0, 3); + + // HEADROCK HAM B2.7: When turned on, this will give a CTH approximation instead of an exact value, on CTH Bars and "F" key feedback. + gGameExternalOptions.fApproximateCTH = iniReader.ReadBoolean("Tactical Interface Settings","INACCURATE_CTH_READOUT", FALSE); + + // HEADROCK HAM 3.4: This controls the intensity of Hiding the Bullet Count during combat. The higher it is, the more intense the effect. Negative values reduce the effect. + gGameExternalOptions.usBulletHideIntensity = iniReader.ReadInteger("Tactical Interface Settings","HIDE_BULLET_COUNT_INTENSITY", 100, 0, 1000); + + // HEADROCK HAM 3.6: Maximum number of messages displayed in Tactical view + gGameExternalOptions.ubMaxMessagesTactical = iniReader.ReadInteger("Tactical Interface Settings","MAXIMUM_MESSAGES_IN_TACTICAL", 6, 1, 36); + // Apply a resolution-based limit. + switch (iResolution) + { + case 0: + // Max 20 lines in 640x480 + gGameExternalOptions.ubMaxMessagesTactical = __max(20, gGameExternalOptions.ubMaxMessagesTactical); + break; + case 1: + // Max 26 lines in 800x600 + gGameExternalOptions.ubMaxMessagesTactical = __max(26, gGameExternalOptions.ubMaxMessagesTactical); + break; + } + + // HEADROCK HAM 3.6: If activated, the game does not switch focus to a merc who spots an enemy in real-time mode. This fixes issues with Real-Time Sneak. + gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak = iniReader.ReadBoolean("Tactical Interface Settings","NO_AUTO_FOCUS_CHANGE_IN_REALTIME_SNEAK", FALSE); + + //################# Tactical Difficulty Settings ################# + + // Enemy AP settings + gGameExternalOptions.iEasyAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AP_BONUS_NOVICE",0,__max(-APBPConstants[AP_MINIMUM],-128),127); + gGameExternalOptions.iExperiencedAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AP_BONUS_EXPERIENCED",0,__max(-APBPConstants[AP_MINIMUM],-128),127); + gGameExternalOptions.iExpertAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AP_BONUS_EXPERT",0,__max(-APBPConstants[AP_MINIMUM],-128),127); + gGameExternalOptions.iInsaneAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AP_BONUS_INSANE",0,__max(-APBPConstants[AP_MINIMUM],-128),127); + + gGameExternalOptions.iPlayerAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","PLAYER_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127); + + // HEADROCK HAM B2.8: At "1", Militia will drop their equipment similar to enemies, IF killed by non-player character. At "2" they drop whenever killed. + gGameExternalOptions.ubMilitiaDropEquipment = iniReader.ReadInteger("Tactical Difficulty Settings","MILITIA_DROP_EQUIPMENT", 0, 0, 2 ); + + // HEADROCK HAM B2.7: Change the speed of skill progression. (defaults set to JA2 normal) + gGameExternalOptions.usHealthSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","HEALTH_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); + gGameExternalOptions.usStrengthSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","STRENGTH_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); + gGameExternalOptions.usDexteritySubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","DEXTERITY_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); + gGameExternalOptions.usAgilitySubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","AGILITY_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); + gGameExternalOptions.usWisdomSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","WISDOM_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); + gGameExternalOptions.usMarksmanshipSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","MARKSMANSHIP_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); + gGameExternalOptions.usMedicalSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","MEDICAL_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); + gGameExternalOptions.usMechanicalSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","MECHANICAL_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); + gGameExternalOptions.usExplosivesSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","EXPLOSIVES_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); + gGameExternalOptions.usLeadershipSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","LEADERSHIP_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); + gGameExternalOptions.usLevelSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","LEVEL_SUBPOINTS_TO_IMPROVE", 350, 1, 6500); + + // Alternate algorithm for choosing equipment level. Mostly disregards soldier's class and puts less emphasis on distance from Sector P3. + gGameExternalOptions.fSlowProgressForEnemyItemsChoice = iniReader.ReadBoolean("Tactical Difficulty Settings", "SLOW_PROGRESS_FOR_ENEMY_ITEMS_CHOICE", TRUE); - gGameExternalOptions.fEnableArmorCoverage = iniReader.ReadBoolean("JA2 Tactical Settings", "ENABLE_ARMOR_COVERAGE", FALSE); // ShadoWarrior for Captain J's armor coverage // The_Bob - real time sneaking code 01/06/09 // Suport disabling real time sneaking via external .ini file - gGameExternalOptions.fAllowRealTimeSneak = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_REAL_TIME_SNEAK", FALSE); + gGameExternalOptions.fAllowRealTimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","ALLOW_REAL_TIME_SNEAK", FALSE); // Silence the RT sneaking messages - gGameExternalOptions.fQuietRealTimeSneak = iniReader.ReadBoolean("JA2 Tactical Settings","QUIET_REAL_TIME_SNEAK", FALSE); + gGameExternalOptions.fQuietRealTimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","QUIET_REAL_TIME_SNEAK", FALSE); + + // HEADROCK HAM 3.2: If activated, reinforcements (militia/enemy) arrive in the battle with 0 APs. This makes them less of a diablo-ex-machina. 0 = Diabled. 2 = Enemies. 3 = Militia. 1 = both + gGameExternalOptions.ubReinforcementsFirstTurnFreeze = iniReader.ReadInteger("Tactical Difficulty Settings","REINFORCEMENTS_ARRIVE_WITH_ZERO_AP", 0, 0, 3); + + // HEADROCK HAM 3.6: Militia can now place blue flags when they spot a landmine. + gGameExternalOptions.fMilitiaPlaceBlueFlags = iniReader.ReadBoolean("Tactical Difficulty Settings","MILITIA_CAN_PLACE_FLAGS_ON_MINES", FALSE); + + // WANNE: Added INI file Option for enemy ambushes, so we also have the option to play vanilla ja2 ambush settings + gGameExternalOptions.fEnableChanceOfEnemyAmbushesOnInsaneDifficult = iniReader.ReadBoolean("Tactical Difficulty Settings", "ENABLE_CHANCE_OF_ENEMY_AMBUSHES_ON_INSANE_DIFFICULT", TRUE); + + // HEADROCK HAM 3.6: Non-Combat Bodytypes shouldn't become hostile + gGameExternalOptions.fCanTrueCiviliansBecomeHostile = iniReader.ReadBoolean("Tactical Difficulty Settings","CAN_TRUE_CIVILIANS_BECOME_HOSTILE", TRUE); + + // HEADROCK HAM 3.6: Militia become hostile when attacked. 0 = No. 1 = If killed. 2 = If attacked (JA2 Default) + gGameExternalOptions.ubCanMilitiaBecomeHostile = iniReader.ReadInteger("Tactical Difficulty Settings","CAN_MILITIA_BECOME_HOSTILE", 2, 0, 2); + + + //################# Tactical Vision Settings ################# + + // Sight range + gGameExternalOptions.ubStraightSightRange = iniReader.ReadInteger("Tactical Vision Settings","BASE_SIGHT_RANGE",13, 5, 100); + + // Tunnel Vision + gGameExternalOptions.gfAllowLimitedVision = iniReader.ReadBoolean("Tactical Vision Settings","ALLOW_TUNNEL_VISION",0); + + + + //################# Tactical Tooltip Settings ################# + + // ShadoWarrior: Tooltip changes (start) + gGameExternalOptions.ubSoldierTooltipDetailLevel = (UINT8) iniReader.ReadInteger("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DETAIL_LEVEL", 1, 0, 4); + + gGameExternalOptions.fEnableDynamicSoldierTooltips = iniReader.ReadBoolean("Tactical Tooltip Settings", "DYNAMIC_SOLDIER_TOOLTIPS", TRUE); + gGameExternalOptions.fEnableSoldierTooltipLocation = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_LOCATION", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBrightness = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BRIGHTNESS", TRUE); + gGameExternalOptions.fEnableSoldierTooltipRangeToTarget = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_RANGE_TO_TARGET", TRUE); + gGameExternalOptions.fEnableSoldierTooltipID = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ID", TRUE); + gGameExternalOptions.fEnableSoldierTooltipOrders = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ORDERS", TRUE); + gGameExternalOptions.fEnableSoldierTooltipAttitude = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ATTITUDE", TRUE); + gGameExternalOptions.fEnableSoldierTooltipActionPoints = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ACTIONPOINTS", TRUE); + gGameExternalOptions.fEnableSoldierTooltipHealth = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HEALTH", TRUE); + gGameExternalOptions.fEnableSoldierTooltipHelmet = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HELMET", TRUE); + gGameExternalOptions.fEnableSoldierTooltipVest = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_VEST", TRUE); + gGameExternalOptions.fEnableSoldierTooltipLeggings = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_LEGGINGS", TRUE); + gGameExternalOptions.fEnableSoldierTooltipHeadItem1 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HEAD_SLOT_1", TRUE); + gGameExternalOptions.fEnableSoldierTooltipHeadItem2 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HEAD_SLOT_2", TRUE); + gGameExternalOptions.fEnableSoldierTooltipWeapon = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_WEAPON", TRUE); + gGameExternalOptions.fEnableSoldierTooltipSecondHand = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_OFF_HAND", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot1 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_1", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot2 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_2", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot3 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_3", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot4 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_4", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot5 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_5", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot6 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_6", TRUE); + gGameExternalOptions.fEnableSoldierTooltipBigSlot7 = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_BIG_SLOT_7", TRUE); + // ShadoWarrior: Tooltip changes (end) + + //SCORE: Settings for UDT + gGameExternalOptions.gfAllowUDTRange = iniReader.ReadBoolean("Tactical Tooltip Settings","ALLOW_DYNAMIC_TOOLTIP_RANGE",0); + gGameExternalOptions.ubUDTModifier = (UINT8) iniReader.ReadInteger("Tactical Tooltip Settings", "DYNAMIC_TOOLTIP_RANGE_MODIFIER", 50); + gGameExternalOptions.gfAllowUDTDetail = iniReader.ReadBoolean("Tactical Tooltip Settings","ALLOW_DYNAMIC_TOOLTIP_DETAIL_LEVEL",0); + + //################# Tactical Gameplay Settings ################## + + // HEADROCK HAM B1: Set minimum and maximum CTH + gGameExternalOptions.ubMaximumCTH = iniReader.ReadInteger("Tactical Gameplay Settings","MAXIMUM_POSSIBLE_CTH", 99, 1, 100); + + gGameExternalOptions.ubMinimumCTH = iniReader.ReadInteger("Tactical Gameplay Settings","MINIMUM_POSSIBLE_CTH", 1, 0, 99); + + // HEADROCK HAM B1: Set minimum CTH at fraction between 0 and 1 ( MINCTH = 1/(100*divisor) ) Note Minimum above must be 0. + gGameExternalOptions.usMinimumCTHDivisor = iniReader.ReadInteger("Tactical Gameplay Settings","MINIMUM_CTH_DIVISOR", 100, 1, 250); + + // HEADROCK HAM B2.5: Turn on Realistic Tracers. 0 = off (regular tracers). 1 = Fully realistic tracers. 2 = Tracer Bump + 1.13 Autofire Penalty Reduction + gGameExternalOptions.ubRealisticTracers = iniReader.ReadInteger("Tactical Gameplay Settings","REALISTIC_TRACERS", 0, 0, 2); + + // HEADROCK HAM B2.5: Realistic tracers - one of every X bullets in a tracer magazines will be a tracer bullet. 0 = off (JA2 normal) + gGameExternalOptions.ubNumBulletsPerTracer = __max(iniReader.ReadInteger("Tactical Gameplay Settings","NUM_BULLETS_PER_TRACER", 5, 1, 255),1); + + // HEADROCK HAM B2.5: Realistic tracers - CTH increased by this amount whenever a tracer is fired. 0 = off. + gGameExternalOptions.ubCTHBumpPerTracer = iniReader.ReadInteger("Tactical Gameplay Settings","CTH_BUMP_PER_TRACER", 30, 0, 100 ); + + // HEADROCK HAM 3.5: Limit bonus from tracers based on range to target. This is a multiplier factor - higher means harder to aim with tracers. + gGameExternalOptions.ubRangeDifficultyAimingWithTracers = iniReader.ReadInteger("Tactical Gameplay Settings","RANGE_EFFECT_ON_MAX_TRACER_CTH_BONUS", 3, 1, 10); + + // HEADROCK HAM B2.6: Increased aiming costs? + gGameExternalOptions.fIncreasedAimingCost = iniReader.ReadBoolean("Tactical Gameplay Settings","INCREASE_AIMING_COSTS", FALSE); + + // HEADROCK HAM 3.1: Divisor for the AP-to-Ready cost charge on first aiming click, when extra aiming costs are enabled. 0 = No ready-time-based charge. + gGameExternalOptions.ubFirstAimReadyCostDivisor = iniReader.ReadInteger("Tactical Gameplay Settings","FIRST_AIM_READY_COST_DIVISOR", 0, 0, 255); + + // HEADROCK HAM B2.6: Dynamically determine Max-Aiming based also on weapon, bipod, etc? + gGameExternalOptions.fDynamicAimingTime = iniReader.ReadBoolean("Tactical Gameplay Settings","DYNAMIC_AIMING_LIMITS", FALSE); + + // HEADROCK HAM B2.6: Controls how much effect target movement has on aiming + gGameExternalOptions.iMovementEffectOnAiming = (float)iniReader.ReadDouble("Tactical Gameplay Settings","CTH_PENALTY_FOR_TARGET_MOVEMENT", 1.5, 0.0, 255.0); + + // HEADROCK HAM 3.3: Externalized maximum possible penalty for hitting a moving target. JA2 Default = 30. + gGameExternalOptions.usMaxCTHPenaltyForMovingTarget = iniReader.ReadInteger("Tactical Gameplay Settings","MAX_CTH_PENALTY_FOR_TARGET_MOVEMENT", 30, 0, 300); + + // HEADROCK HAM 3.2: Critical Headshots may cause blindness. Rolls 1 to X change of being blinded. 0 = disabled. + gGameExternalOptions.ubChanceBlindedByHeadshot = iniReader.ReadInteger("Tactical Gameplay Settings","CHANCE_BLINDED_BY_HEADSHOT", 0, 0, 10); + + // HEADROCK HAM 3.2: Critical Legshots cause additional AP loss + gGameExternalOptions.fCriticalLegshotCausesAPLoss = iniReader.ReadBoolean("Tactical Gameplay Settings","CRITICAL_LEGSHOT_CAUSES_AP_LOSS", FALSE); + + //################# Tactical Cover System Settings ################## // CPT: Cover System Settings - gGameExternalOptions.ubStealthTraitCoverValue = iniReader.ReadInteger("JA2 Tactical Settings","STEALTH_TRAIT_COVER_VALUE", 15, 0, 100); - gGameExternalOptions.ubStealthEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings", "STEALTH_EFFECTIVENESS", 50, 0, 100); - gGameExternalOptions.ubTreeCoverEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings","TREE_COVER_EFFECTIVENESS", 50, 0, 100); - gGameExternalOptions.ubCamouflageEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings", "CAMOUFLAGE_EFFECTIVENESS", 50, 0, 100); - gGameExternalOptions.ubStanceEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings", "STANCE_EFFECTIVENESS", 10, 0, 100); - gGameExternalOptions.ubLBEEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings", "LBE_EFFECTIVENESS", 50, 0, 100); - gGameExternalOptions.ubMovementEffectiveness = iniReader.ReadInteger("JA2 Tactical Settings", "MOVEMENT_EFFECTIVENESS", 50, 0, 100); - gGameExternalOptions.ubCoverDisplayUpdateWait = iniReader.ReadInteger("JA2 Tactical Settings", "COVER_DISPLAY_UPDATE_WAIT", 500, -1, 10000); + gGameExternalOptions.ubStealthTraitCoverValue = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_STEALTH_TRAIT_VALUE", 15, 0, 100); + gGameExternalOptions.ubStealthEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_STEALTH_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubCamouflageEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_CAMOUFLAGE_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubStanceEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_STANCE_EFFECTIVENESS", 10, 0, 100); + gGameExternalOptions.ubLBEEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_LBE_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubMovementEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_MOVEMENT_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubTreeCoverEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_TREE_EFFECTIVENESS", 50, 0, 100); + gGameExternalOptions.ubCoverDisplayUpdateWait = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_UPDATE_DELAY", 500, -1, 10000); - //################# Rain Settings ################## + //################# Tactical Suppression Fire Settings ################## + // These settings control the behavior of Suppression Fire, its severity, and its side-effects. + + // HEADROCK HAM B2.1: This controls how effective suppression is, by increasing the number of ubSuppressionPoints accumulated by combatants (percentage); + gGameExternalOptions.sSuppressionEffectiveness = iniReader.ReadInteger("Tactical Suppression Fire Settings","SUPPRESSION_EFFECTIVENESS", 0, 0, 1000); + + // Min/max Suppression Tolerance values. Maximum system limit is 24! + gGameExternalOptions.ubSuppressionToleranceMax = iniReader.ReadInteger("Tactical Suppression Fire Settings","SUPPRESSION_TOLERANCE_MAX", 18, 1, 24); + gGameExternalOptions.ubSuppressionToleranceMin = iniReader.ReadInteger("Tactical Suppression Fire Settings","SUPPRESSION_TOLERANCE_MIN", 1, 0, 24); + + // HEADROCK HAM 3.2: This feature allows the status, leadership and experience of nearby friendlies help/hinder a character's tolerance, based on their distance from him. + gGameExternalOptions.fFriendliesAffectTolerance = iniReader.ReadBoolean("Tactical Suppression Fire Settings","NEARBY_FRIENDLIES_AFFECT_TOLERANCE", FALSE); + + // HEADROCK HAM 3.3: Increases tolerance while moving. + gGameExternalOptions.ubTilesMovedPerBonusTolerancePoint = iniReader.ReadInteger("Tactical Suppression Fire Settings","TILES_MOVED_PER_BONUS_TOLERANCE_POINT", 5, 0, 20); + + // HEADROCK HAM B2: Suppression Shock effectiveness (percentage, 100 = "normal", 0 = deactivated. Range 0-65535) + gGameExternalOptions.usSuppressionShockEffect = iniReader.ReadInteger("Tactical Suppression Fire Settings","SUPPRESSION_SHOCK_INTENSITY", 100, 0, 1000); + + // HEADROCK HAM B2.6: Adjustable maximum for Suppression Shock effect. This has the added effect of reducing overall susceptibility to shock and may render some enemies unshockable. + gGameExternalOptions.ubMaxSuppressionShock = iniReader.ReadInteger("Tactical Suppression Fire Settings","MAX_SUPPRESSION_SHOCK", 30, 0, 200 ); + + // HEADROCK HAM B2.1: CTH penalty given by a "Cowering" target to any enemy shooter. + gGameExternalOptions.ubAimPenaltyPerTargetShock = iniReader.ReadInteger("Tactical Suppression Fire Settings","CTH_PENALTY_PER_TARGET_SHOCK", 5, 0, 100 ); + + // HEADROCK HAM B2.8: Absolute maximum CTH penalty from target's shock value. + gGameExternalOptions.usMaxShooterCoweringPenalty = iniReader.ReadInteger("Tactical Suppression Fire Settings","MAX_CTH_PENALTY_FOR_TARGET_SHOCK", 0, 0, 250 ); + + // HEADROCK HAM B2.8: These are new cowering penalty divisors that help us determine how effective cowering is in different stances and when the shooter is targetting different bodyparts + gGameExternalOptions.ubCoweringPenaltyDivisorProne = iniReader.ReadInteger("Tactical Suppression Fire Settings","CTH_PENALTY_DIVISOR_FOR_PRONE_SHOCKED_TARGET", 1, 1, 100 ); + gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedHead = iniReader.ReadInteger("Tactical Suppression Fire Settings","CTH_PENALTY_DIVISOR_FOR_CROUCHED_SHOCKED_TARGET_HEAD", 3, 1, 100); + gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedTorso = iniReader.ReadInteger("Tactical Suppression Fire Settings","CTH_PENALTY_DIVISOR_FOR_CROUCHED_SHOCKED_TARGET_TORSO", 4, 1, 100); + gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedLegs = iniReader.ReadInteger("Tactical Suppression Fire Settings","CTH_PENALTY_DIVISOR_FOR_CROUCHED_SHOCKED_TARGET_LEGS_DIVISOR", 5, 1, 100); + + // HEADROCK HAM B2.8: This is the maximum range at which a target gives out the full CTH penalty for cowering. At lower range, it'll give proportionally less penalty. + gGameExternalOptions.usMinRangeForFullCoweringPenalty = iniReader.ReadInteger("Tactical Suppression Fire Settings","MIN_RANGE_FOR_FULL_TARGET_SHOCK_PENALTY", 300, 10, 10000 ); + + gGameExternalOptions.usMaxTargetCoweringPenalty = iniReader.ReadInteger("Tactical Suppression Fire Settings","MAX_CTH_PENALTY_FROM_SHOCK", 0, 0, 250 ); + + // HEADROCK HAM 3.2: This enabled reduced sight for cowering characters. 0 = disabled. 2 = Reduced Sightrange. 3 = Tunnel-vision. 1 = Both. + gGameExternalOptions.ubCoweringReducesSightRange = iniReader.ReadInteger("Tactical Suppression Fire Settings","SHOCK_REDUCES_SIGHTRANGE", 0, 0, 3); + + // HEADROCK HAM B2.3: A "cowering" soldier is twice as susceptible to suppression. + gGameExternalOptions.ubCowerEffectOnSuppression = iniReader.ReadInteger("Tactical Suppression Fire Settings","COWERING_PENALTY_TO_SUPPRESSION_TOLERANCE", 4, 0, 24 ); + + // HEADROCK HAM B2.6: Toggle whether AI checks for larger magazine when wanting to use burst/auto or suppress from beyond sight range. Also makes enemies less prone to fleeing. + gGameExternalOptions.fIncreaseAISuppressionFire = iniReader.ReadBoolean("Tactical Suppression Fire Settings","INCREASE_AI_WILLINGNESS_TO_SUPPRESS", FALSE); + + // HEADROCK HAM 3.5: Explosive Suppression Effectiveness alters the amount of Suppression Points you get from nearby blasts. + gGameExternalOptions.usExplosionSuppressionEffect = iniReader.ReadInteger("Tactical Suppression Fire Settings","EXPLOSIVE_SUPPRESSION_EFFECTIVENESS", 100, 0, 1000); + + // HEADROCK HAM 3.1: This is a suppression tool that not everyone will like. It gives an on-screen message when any character has been suppressed so much he's lost his next turn completely! + gGameExternalOptions.fShowSuppressionShutdown = iniReader.ReadBoolean("Tactical Suppression Fire Settings","NOTIFY_WHEN_PINNED_DOWN", FALSE); + + // HEADROCK HAM 3.3: Minimum distance (in METERS) at which character suffer from friendly suppression. + gGameExternalOptions.usMinDistanceFriendlySuppression = iniReader.ReadInteger("Tactical Suppression Fire Settings","MIN_DISTANCE_FRIENDLY_SUPPRESSION", 30, 0, 65000); + + + //################# Tactical Weather Settings ################## + + gGameExternalOptions.ubVisDistDecreasePerRainIntensity = iniReader.ReadInteger("Tactical Weather Settings","VISUAL_DISTANCE_DECREASE_PER_RAIN_INTENSITY",30, 0, 100); // Rain settings - gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("JA2 Rain Settings","ALLOW_RAIN",0); - gGameExternalOptions.gusRainChancePerDay = iniReader.ReadInteger("JA2 Rain Settings","RAIN_CHANCE_PER_DAY",100, 0, 100); - gGameExternalOptions.gusRainMinLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MIN_LENGTH_IN_MINUTES",60, 1, 1438 /* 24 hrs - 2 minutes */); - gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MAX_LENGTH_IN_MINUTES",300, gGameExternalOptions.gusRainMinLength+1, 1439); - gGameExternalOptions.guiMaxRainDrops = iniReader.ReadInteger("JA2 Rain Settings","MAX_RAIN_DROPS",80, 1, 800); - gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity = iniReader.ReadInteger("JA2 Rain Settings","WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY",0, 0, 10); - gGameExternalOptions.ubBreathGainReductionPerRainIntensity = iniReader.ReadDouble("JA2 Rain Settings","BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY",25, 1, 100); + gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("Tactical Weather Settings","ALLOW_RAIN",0); + gGameExternalOptions.gusRainChancePerDay = iniReader.ReadInteger("Tactical Weather Settings","RAIN_CHANCE_PER_DAY",100, 0, 100); + gGameExternalOptions.gusRainMinLength = iniReader.ReadInteger("Tactical Weather Settings","RAIN_MIN_LENGTH_IN_MINUTES",60, 1, 1438 /* 24 hrs - 2 minutes */); + gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("Tactical Weather Settings","RAIN_MAX_LENGTH_IN_MINUTES",300, gGameExternalOptions.gusRainMinLength+1, 1439); + gGameExternalOptions.guiMaxRainDrops = iniReader.ReadInteger("Tactical Weather Settings","MAX_RAIN_DROPS",80, 1, 800); + gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity = iniReader.ReadInteger("Tactical Weather Settings","WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY",0, 0, 10); + gGameExternalOptions.ubBreathGainReductionPerRainIntensity = iniReader.ReadDouble("Tactical Weather Settings","BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY",25, 1, 100); // Thunder settings - gGameExternalOptions.gfAllowLightning = iniReader.ReadBoolean("JA2 Thunder Settings","ALLOW_LIGHTNING",TRUE); - gGameExternalOptions.guiMinLightningInterval = iniReader.ReadInteger("JA2 Thunder Settings","MIN_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",5, 1, 100); - gGameExternalOptions.guiMaxLightningInterval = iniReader.ReadInteger("JA2 Thunder Settings","MAX_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",15, 2, 600); - gGameExternalOptions.guiMinDLInterval = iniReader.ReadInteger("JA2 Thunder Settings","MIN_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",1, 1, 100); - gGameExternalOptions.guiMaxDLInterval = iniReader.ReadInteger("JA2 Thunder Settings","MAX_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",5, 2, 600); - gGameExternalOptions.guiProlongLightningIfSeenSomeone = iniReader.ReadInteger("JA2 Thunder Settings","PROLOGNE_DELAY_IF_SEEN_SOMEONE_DURING_LIGHTNING_IN_TURNBASED_IN_SECONDS",5, 1, 60); - gGameExternalOptions.guiChanceToDoLightningBetweenTurns = iniReader.ReadInteger("JA2 Thunder Settings","CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS",35, 0, 100); + gGameExternalOptions.gfAllowLightning = iniReader.ReadBoolean("Tactical Weather Settings","ALLOW_LIGHTNING",TRUE); + gGameExternalOptions.guiMinLightningInterval = iniReader.ReadInteger("Tactical Weather Settings","MIN_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",5, 1, 100); + gGameExternalOptions.guiMaxLightningInterval = iniReader.ReadInteger("Tactical Weather Settings","MAX_INTERVAL_BETWEEN_LIGHTNINGS_IN_REAL_TIME_SECONDS",15, 2, 600); + gGameExternalOptions.guiMinDLInterval = iniReader.ReadInteger("Tactical Weather Settings","MIN_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",1, 1, 100); + gGameExternalOptions.guiMaxDLInterval = iniReader.ReadInteger("Tactical Weather Settings","MAX_INTERVAL_BETWEEN_LIGHTNING_AND_THUNDERCLAPS_IN_SECONDS",5, 2, 600); + gGameExternalOptions.guiProlongLightningIfSeenSomeone = iniReader.ReadInteger("Tactical Weather Settings","DELAY_IN_SECONDS_IF_SEEN_SOMEONE_DURING_LIGHTNING_IN_TURNBASED",5, 1, 60); + gGameExternalOptions.guiChanceToDoLightningBetweenTurns = iniReader.ReadInteger("Tactical Weather Settings","CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS",35, 0, 100); - //################# Gameplay Settings ################## - //################# Settings valid on game start only ################## - //Money settings - gGameExternalOptions.iStartingCashNovice = iniReader.ReadInteger("JA2 Gameplay Settings", "NOVICE_CASH",45000, 2000, 0x0FFFFFFF); - gGameExternalOptions.iStartingCashExperienced = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERIENCED_CASH",35000, 2000, 0x0FFFFFFF); - gGameExternalOptions.iStartingCashExpert = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERT_CASH",30000, 2000, 0x0FFFFFFF); - gGameExternalOptions.iStartingCashInsane = iniReader.ReadInteger("JA2 Gameplay Settings", "INSANE_CASH",15000, 2000, 0x0FFFFFFF); + //################# Strategic Gamestart Settings ################## - //Lalien: Game starting time - gGameExternalOptions.iGameStartingTime = iniReader.ReadInteger("JA2 Gameplay Settings", "GAME_STARTING_TIME", NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY-1); + gGameExternalOptions.iGameStartingTime = iniReader.ReadInteger("Strategic Gamestart Settings", "GAME_STARTING_TIME", NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY-1); gGameExternalOptions.iGameStartingTime += NUM_SEC_IN_DAY; - gGameExternalOptions.iFirstArrivalDelay = iniReader.ReadInteger("JA2 Gameplay Settings", "FIRST_ARRIVAL_DELAY", 6 * NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY); + gGameExternalOptions.iFirstArrivalDelay = iniReader.ReadInteger("Strategic Gamestart Settings", "FIRST_ARRIVAL_DELAY", 6 * NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY); - //################# Settings valid on game start only end ################## + // HEADROCK HAM 3.5: Arrival sectorX/Y. + gGameExternalOptions.ubDefaultArrivalSectorX = iniReader.ReadInteger("Strategic Gamestart Settings","DEFAULT_ARRIVAL_SECTOR_X", 9, 1, 16); + gGameExternalOptions.ubDefaultArrivalSectorY = iniReader.ReadInteger("Strategic Gamestart Settings","DEFAULT_ARRIVAL_SECTOR_Y", 1, 1, 16); - gGameExternalOptions.fSellAll = iniReader.ReadBoolean("JA2 Gameplay Settings","CAN_SELL_ALT_LMB",FALSE); - gGameExternalOptions.iPriceModifier = (INT16) iniReader.ReadInteger("JA2 Gameplay Settings","PRICE_MODIFIER",10, -1, 100); + //################# Strategic Interface Settings ################## + + // CHRISL: Setting to turn off the description and stack popup options from the sector inventory panel + gGameExternalOptions.fSectorDesc = iniReader.ReadBoolean("Strategic Interface Settings","ALLOW_DESCRIPTION_BOX_FOR_ITEMS_IN_SECTOR_INVENTORY",TRUE); + + // HEADROCK HAM 3.6: Progress bars for each stat, displayed behind the stat value on the merc panel. INI settings give RGB color, Menu setting toggles on/off. + gGameExternalOptions.ubStatProgressBarsRed = iniReader.ReadInteger("Strategic Interface Settings","STAT_PROGRESS_BARS_RED", 200, 0, 255); + gGameExternalOptions.ubStatProgressBarsGreen = iniReader.ReadInteger("Strategic Interface Settings","STAT_PROGRESS_BARS_GREEN", 0, 0, 255); + gGameExternalOptions.ubStatProgressBarsBlue = iniReader.ReadInteger("Strategic Interface Settings","STAT_PROGRESS_BARS_BLUE", 0, 0, 255); + + // HEADROCK HAM 3.6: Determines whether the extrapolated daily costs of mercs are figured into the "Daily Expenses" display. 0 = No, just facility costs. 1 = Only mercs with a fixed daily rate. 2 = All mercs, including AIM contracts. + gGameExternalOptions.ubIncludeContractsInExpenses = iniReader.ReadInteger("Strategic Interface Settings","INCLUDE_CONTRACTS_IN_PROJECTED_EXPENSES_WINDOW", 1, 0, 2); - // WDS - Option to turn off stealing - gGameExternalOptions.fStealingDisabled = iniReader.ReadBoolean("JA2 Gameplay Settings","STEALING_FROM_SHIPMENTS_DISABLED",FALSE); - - // WANNE - Chance of shipment lost - gGameExternalOptions.gubChanceOfShipmentLost = iniReader.ReadInteger("JA2 Gameplay Settings","CHANCE_OF_SHIPMENT_LOST", 10); + //################# Strategic Progress Settings ################## // WDS: Game progress - gGameExternalOptions.ubGameProgressPortionKills = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_KILLS", 25, 0, 100); - gGameExternalOptions.ubGameProgressPortionControl = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_CONTROL", 25, 0, 100); - gGameExternalOptions.ubGameProgressPortionIncome = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_INCOME", 50, 0, 100); - gGameExternalOptions.ubGameProgressPortionVisited = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_VISITED", 0, 0, 100); - gGameExternalOptions.ubGameProgressMinimum = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_MINIMUM", 0, 0, 100); - gGameExternalOptions.ubGameProgressIncrement = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_INCREMENT", 0, 0, 100); + gGameExternalOptions.ubGameProgressPortionKills = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MAX_POINTS_FROM_KILLS", 25, 0, 100); + gGameExternalOptions.ubGameProgressPortionControl = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MAX_POINTS_FROM_SECTOR_CONTROL", 25, 0, 100); + gGameExternalOptions.ubGameProgressPortionIncome = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MAX_POINTS_FROM_MINE_INCOME", 50, 0, 100); + gGameExternalOptions.ubGameProgressPortionVisited = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MAX_POINTS_FROM_EXPLORED_SECTORS", 0, 0, 100); // Any way to warn on this? if (gGameExternalOptions.ubGameProgressPortionKills + @@ -821,508 +1066,320 @@ void LoadGameExternalOptions() gGameExternalOptions.ubGameProgressPortionControl = 25; gGameExternalOptions.ubGameProgressPortionIncome = 50; gGameExternalOptions.ubGameProgressPortionVisited = 0; + + // Yes, there is! + std::stringstream errMessage; + errMessage << "The values of the four ''MAX_PROGRESS_POINTS'' INI settings do not add up to 100! Using default values instead..."; + iniErrorMessages.push(errMessage.str()); } - // WDS: Advanced start - removed - SANDRO - //gGameExternalOptions.ubIMPStartingLevel = iniReader.ReadInteger("JA2 Gameplay Settings","IMP_STARTING_LEVEL", 1, 1, 7); - - // WDS - make number of mercenaries, etc. be configurable - gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_PLAYER_MERCS", 24, 1, CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS); - gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_PLAYER_VEHICLES", 2, 2, CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES); - gGameExternalOptions.ubGameMaximumNumberOfEnemies = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_ENEMIES", 32, 16, CODE_MAXIMUM_NUMBER_OF_ENEMIES); - gGameExternalOptions.ubGameMaximumNumberOfCreatures = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_CREATURES", 32, 0, CODE_MAXIMUM_NUMBER_OF_CREATURES); - gGameExternalOptions.ubGameMaximumNumberOfRebels = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_REBELS", 32, 16, CODE_MAXIMUM_NUMBER_OF_REBELS); - gGameExternalOptions.ubGameMaximumNumberOfCivilians = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_NUMBER_CIVS", 32, 16, CODE_MAXIMUM_NUMBER_OF_CIVS); - - //Global game events - gGameExternalOptions.ubGameProgressStartMadlabQuest = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_START_MADLAB_QUEST",35, 1, 100); - gGameExternalOptions.ubGameProgressMikeAvailable = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_MIKE_AVAILABLE",50, 1, 100); - gGameExternalOptions.ubGameProgressIggyAvaliable = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_IGGY_AVAILABLE",70, 1, 100); - gGameExternalOptions.ubSendTroopsToDrassen = iniReader.ReadBoolean("JA2 Gameplay Settings","STRATEGIC_EVENT_SEND_TROOPS_TO_DRASSEN",TRUE); - - //Weapons modification - gGameExternalOptions.ubExplosivesDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","EXPLOSIVES_DAMAGE_MULTIPLIER",0, 0, 100); - gGameExternalOptions.ubMeleeDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","MELEE_DAMAGE_MULTIPLIER",0, 0, 100); - gGameExternalOptions.ubGunDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_DAMAGE_MULTIPLIER",0, 0, 100); - - - //Strategic AI settings - gGameExternalOptions.iMaxEnemyGroupSize = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_STRATEGIC_TEAM_SIZE",20, 10, 100); - - gGameExternalOptions.iReinforcementPoolNovice = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_QUEENS_POOL_OF_TROOPS",150, 25, 1000000); - gGameExternalOptions.iReinforcementPoolExperienced = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_QUEENS_POOL_OF_TROOPS",200, 25, 1000000); - gGameExternalOptions.iReinforcementPoolExpert = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_QUEENS_POOL_OF_TROOPS",400, 25, 1000000); - gGameExternalOptions.iReinforcementPoolInsane = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_QUEENS_POOL_OF_TROOPS",8000, 25, 1000000); - - gGameExternalOptions.iForcePercentageNovice = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_INITIAL_GARRISON_PERCENTAGES",70, 1, 200); - gGameExternalOptions.iForcePercentageExperienced = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_INITIAL_GARRISON_PERCENTAGES",100, 1, 300); - gGameExternalOptions.iForcePercentageExpert = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_INITIAL_GARRISON_PERCENTAGES",150, 1, 400); - gGameExternalOptions.iForcePercentageInsane = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_INITIAL_GARRISON_PERCENTAGES",200, 1, 600); - - gGameExternalOptions.iPercentElitesBonusExperienced = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_ELITE_BONUS",0, 0, 100); - gGameExternalOptions.iPercentElitesBonusExpert = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_ELITE_BONUS",25, 0, 100); - gGameExternalOptions.iPercentElitesBonusInsane = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_ELITE_BONUS",50, 0, 100); - - gGameExternalOptions.ubMinEnemyGroupSizeNovice = (UINT8) iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_MIN_ENEMY_GROUP_SIZE",3, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); - gGameExternalOptions.ubMinEnemyGroupSizeExperienced = (UINT8) iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_MIN_ENEMY_GROUP_SIZE",4, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); - gGameExternalOptions.ubMinEnemyGroupSizeExpert = (UINT8) iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_MIN_ENEMY_GROUP_SIZE",6, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); - gGameExternalOptions.ubMinEnemyGroupSizeInsane = (UINT8) iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_MIN_ENEMY_GROUP_SIZE",12, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); - - gGameExternalOptions.ubEasyEnemyStartingAlertLevel = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_ENEMY_STARTING_ALERT_LEVEL", 5, 1, 100); - gGameExternalOptions.ubNormalEnemyStartingAlertLevel = iniReader.ReadInteger("JA2 Gameplay Settings","NORMAL_ENEMY_STARTING_ALERT_LEVEL", 20, 1, 100); - gGameExternalOptions.ubHardEnemyStartingAlertLevel = iniReader.ReadInteger("JA2 Gameplay Settings","HARD_ENEMY_STARTING_ALERT_LEVEL", 60, 1, 100); - gGameExternalOptions.ubInsaneEnemyStartingAlertLevel = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_ENEMY_STARTING_ALERT_LEVEL", 80, 1, 100); - - gGameExternalOptions.ubEasyEnemyStartingAlertDecay = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_ENEMY_STARTING_ALERT_DECAY", 75, 1, 100); - gGameExternalOptions.ubNormalEnemyStartingAlertDecay = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_ENEMY_STARTING_ALERT_DECAY", 50, 1, 100); - gGameExternalOptions.ubHardEnemyStartingAlertDecay = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_ENEMY_STARTING_ALERT_DECAY", 25, 1, 100); - gGameExternalOptions.ubInsaneEnemyStartingAlertDecay = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_ENEMY_STARTING_ALERT_DECAY", 10, 1, 100); - - gGameExternalOptions.ubEasyTimeEvaluateInMinutes = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_TIME_EVALUATE_IN_MINUTES", 480, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubNormalTimeEvaluateInMinutes = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_TIME_EVALUATE_IN_MINUTES", 360, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubHardTimeEvaluateInMinutes = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_TIME_EVALUATE_IN_MINUTES", 180, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubInsaneTimeEvaluateInMinutes = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_TIME_EVALUATE_IN_MINUTES", 90, 10, NUM_MIN_IN_DAY); - - gGameExternalOptions.ubEasyTimeEvaluateVariance = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_TIME_EVALUATE_VARIANCE", 240, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubNormalTimeEvaluateVariance = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_TIME_EVALUATE_VARIANCE", 180, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubHardTimeEvaluateVariance = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_TIME_EVALUATE_VARIANCE", 120, 10, NUM_MIN_IN_DAY); - gGameExternalOptions.ubInsaneTimeEvaluateVariance = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_TIME_EVALUATE_VARIANCE", 60, 10, NUM_MIN_IN_DAY); - - gGameExternalOptions.ubEasyGracePeriodInHours = iniReader.ReadInteger("JA2 Gameplay Settings","EASY_GRACE_PERIOD_IN_HOURS", 144, 1, 288); - gGameExternalOptions.ubNormalGracePeriodInHours = iniReader.ReadInteger("JA2 Gameplay Settings","NORMAL_GRACE_PERIOD_IN_HOURS", 96, 1, 288); - gGameExternalOptions.ubHardGracePeriodInHours = iniReader.ReadInteger("JA2 Gameplay Settings","HARD_GRACE_PERIOD_IN_HOURS", 48, 1, 288); - gGameExternalOptions.ubInsaneGracePeriodInHours = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_GRACE_PERIOD_IN_HOURS", 6, 1, 288); - - gGameExternalOptions.ubEasyPatrolGracePeriodInDays = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_PATROL_GRACE_PERIOD_IN_DAYS", 16, 1, 100); - gGameExternalOptions.ubNormalPatrolGracePeriodInDays = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_PATROL_GRACE_PERIOD_IN_DAYS", 12, 1, 100); - gGameExternalOptions.ubHardPatrolGracePeriodInDays = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_PATROL_GRACE_PERIOD_IN_DAYS", 8, 1, 100); - gGameExternalOptions.ubInsanePatrolGracePeriodInDays = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_PATROL_GRACE_PERIOD_IN_DAYS", 2, 1, 100); - - gGameExternalOptions.ubEasyNumAwareBattles = iniReader.ReadInteger("JA2 Gameplay Settings","NOVICE_NUM_AWARE_BATTLES", 1, 1, 10); - gGameExternalOptions.ubNormalNumAwareBattles = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_NUM_AWARE_BATTLES", 2, 1, 10); - gGameExternalOptions.ubHardNumAwareBattles = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_NUM_AWARE_BATTLES", 3, 1, 10); - gGameExternalOptions.ubInsaneNumAwareBattles = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_NUM_AWARE_BATTLES", 4, 1, 10); - - //New v1.13 settings - gGameExternalOptions.gfEasyUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","NOVICE_UNLIMITED_POOL_OF_TROOPS",FALSE); - gGameExternalOptions.gfNormalUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERIENCED_UNLIMITED_POOL_OF_TROOPS",FALSE); - gGameExternalOptions.gfHardUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERT_UNLIMITED_POOL_OF_TROOPS",FALSE); - gGameExternalOptions.gfInsaneUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","INSANE_UNLIMITED_POOL_OF_TROOPS",TRUE); - - gGameExternalOptions.gfEasyAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","NOVICE_QUEEN_AGGRESSIVE",FALSE); - gGameExternalOptions.gfNormalAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERIENCED_QUEEN_AGGRESSIVE",FALSE); - gGameExternalOptions.gfHardAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERT_QUEEN_AGGRESSIVE",FALSE); - gGameExternalOptions.gfInsaneAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","INSANE_QUEEN_AGGRESSIVE",TRUE); - - // WDS - New AI - gGameExternalOptions.useNewAI = iniReader.ReadBoolean("JA2 Gameplay Settings","NEW_AGGRESSIVE_AI",FALSE); - - gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("JA2 Gameplay Settings","ENEMY_INVESTIGATE_SECTOR",FALSE); - gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE); - - gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("JA2 Gameplay Settings","ENEMIES_ITEM_DROP", 0, 0, 1); - - gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("JA2 Gameplay Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE); - - // Militia settings - gGameExternalOptions.guiAllowMilitiaGroupsDelay = iniReader.ReadInteger("JA2 Gameplay Settings","ALLOW_MILITIA_MOBILE_DELAY",1, 0, 30); - gGameExternalOptions.guiTrainVeteranMilitiaDelay = iniReader.ReadInteger("JA2 Gameplay Settings","TRAIN_VETERAN_MILITIA_DELAY",1, 0, 30); - gGameExternalOptions.gfTrainVeteranMilitia = iniReader.ReadBoolean("JA2 Gameplay Settings","TRAIN_VETERAN_MILITIA",FALSE); - gGameExternalOptions.gfAllowMilitiaGroups = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_MILITIA_MOBILE_GROUPS",FALSE); - gGameExternalOptions.gfmusttrainroaming = iniReader.ReadBoolean("JA2 Gameplay Settings","MUST_TRAIN_MOBILE_MILITIA",FALSE); - gGameExternalOptions.gfAllowReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_REINFORCEMENTS",FALSE); - gGameExternalOptions.gfAllowReinforcementsOnlyInCity = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_REINFORCEMENTS_ONLY_IN_CITIES",FALSE); - gGameExternalOptions.guiBaseQueenPoolIncrement = iniReader.ReadInteger("JA2 Gameplay Settings","QUEEN_POOL_INCREMENT_PER_DIFFICULTY_LEVEL",60, 1, 100); - - gGameExternalOptions.guiCreateEachNHours = iniReader.ReadInteger("JA2 Gameplay Settings","CREATE_EACH_N_HOURS",24, 1, 96); - gGameExternalOptions.guiDivOfOriginalMilitia = iniReader.ReadInteger("JA2 Gameplay Settings","DIV_OF_ORIGINAL_MILITIA",4, 1, 100); - // HEADROCK HAM 3.6: These settings are REDUNDANT. - //gGameExternalOptions.guiMinMilitiaSquadSize = iniReader.ReadInteger("JA2 Gameplay Settings","MINIMUM_MILITIA_SQUAD_SIZE",5, 1, CODE_MAXIMUM_NUMBER_OF_REBELS); - //gGameExternalOptions.guiMaxMilitiaSquadSize = iniReader.ReadInteger("JA2 Gameplay Settings","MAXIMUM_MILITIA_SQUAD_SIZE",20, gGameExternalOptions.guiMinMilitiaSquadSize, CODE_MAXIMUM_NUMBER_OF_REBELS); - //gGameExternalOptions.guiMaxMilitiaSquadSizeBattle = gGameExternalOptions.guiMaxMilitiaSquadSize; - - gGameExternalOptions.iMaxMilitiaPerSector = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_MILITIA_PER_SECTOR",20, 1, CODE_MAXIMUM_NUMBER_OF_REBELS); - gGameExternalOptions.iTrainingSquadSize = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_TRAINING_SQUAD_SIZE",10, 1, CODE_MAXIMUM_NUMBER_OF_REBELS); - gGameExternalOptions.iMilitiaTrainingCost = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_TRAINING_COST",750, 10, 10000); - gGameExternalOptions.iMilitiaCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_COST_MODIFIER",3, 1, 10); - gGameExternalOptions.iRegularCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","REGULAR_COST_MODIFIER",1, 1, 10); - gGameExternalOptions.iVeteranCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","VETERAN_COST_MODIFIER",2, 1, 10); - gGameExternalOptions.iMinLoyaltyToTrain = iniReader.ReadInteger("JA2 Gameplay Settings","MIN_LOYALTY_TO_TRAIN",20, 0, 100); - gGameExternalOptions.gflimitedRoaming = iniReader.ReadBoolean("JA2 Gameplay Settings","RESTRICT_ROAMING",FALSE); - - // WDS - Improve Tony's and Devin's inventory like BR's - gGameExternalOptions.tonyUsesBRSetting = iniReader.ReadBoolean("JA2 Gameplay Settings","TONY_USES_BR_SETTING", FALSE); - gGameExternalOptions.devinUsesBRSetting = iniReader.ReadBoolean("JA2 Gameplay Settings","DEVIN_USES_BR_SETTING", FALSE); - - // WDS - Smart goggle switching - gGameExternalOptions.smartGoggleSwitch = iniReader.ReadBoolean("JA2 Gameplay Settings","SMART_GOGGLE_SWITCH", FALSE); - - // WDS - Automatically flag mines - gGameExternalOptions.automaticallyFlagMines = iniReader.ReadBoolean("JA2 Gameplay Settings","AUTOMATICALLY_FLAG_MINES", FALSE); - - //Assignment Settings (training, repairing, doctoring, etc) - gGameExternalOptions.ubAssignmentUnitsPerDay = iniReader.ReadInteger("JA2 Gameplay Settings","ASSIGNMENT_UNITS_PER_DAY",24, 1, 96); - gGameExternalOptions.ubMinutesForAssignmentToCount = iniReader.ReadInteger("JA2 Gameplay Settings","MINUTES_FOR_ASSIGNMENT_TO_COUNT",45, 1, NUM_MIN_IN_DAY); - - - gGameExternalOptions.ubTrainingSkillMin = iniReader.ReadInteger("JA2 Gameplay Settings","TRAINING_SKILL_MIN",0, 0, 100); - gGameExternalOptions.ubTrainingSkillMax = iniReader.ReadInteger("JA2 Gameplay Settings","TRAINING_SKILL_MAX",100, 0, 100); - gGameExternalOptions.ubSelfTrainingDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","SELF_TRAINING_DIVISOR",1000, 1, 10000); - gGameExternalOptions.ubInstructedTrainingDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","INSTRUCTED_TRAINING_DIVISOR",3000, 1, 10000); - // HEADROCK HAM 3.5: No longer necessary - //gGameExternalOptions.ubGunRangeTrainingBonus = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_RANGE_TRAINING_BONUS",25, 0, 100); - gGameExternalOptions.ubTownMilitiaTrainingRate = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_TRAINING_RATE",4, 1, 10); - // HEADROCK HAM 3.5: No longer necessary - //gGameExternalOptions.ubMaxMilitiaTrainersPerSector = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_MILITIA_TRAINERS_PER_SECTOR",2, 1, gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs); - gGameExternalOptions.ubTeachBonusToTrain = iniReader.ReadInteger("JA2 Gameplay Settings","TEACH_BONUS_TO_TRAIN",30, 0, 100); - gGameExternalOptions.ubRpcBonusToTrainMilitia = iniReader.ReadInteger("JA2 Gameplay Settings","RPC_BONUS_TO_TRAIN_MILITIA",10, 0, 100); - gGameExternalOptions.ubMinSkillToTeach = iniReader.ReadInteger("JA2 Gameplay Settings","MIN_RATING_TO_TEACH",25, 0, 100); - - gGameExternalOptions.ubLowActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","LOW_ACTIVITY_LEVEL",1, 1, 100); - gGameExternalOptions.ubMediumActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","MEDIUM_ACTIVITY_LEVEL",4, 1, 100); - gGameExternalOptions.ubHighActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","HIGH_ACTIVITY_LEVEL",12, 1, 100); - gGameExternalOptions.ubDoctoringRateDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","DOCTORING_RATE_DIVISOR",2400, 1200, 24000); - gGameExternalOptions.ubHospitalHealingRate = iniReader.ReadInteger("JA2 Gameplay Settings","HOSPITAL_HEALING_RATE",5, 1, 10); - gGameExternalOptions.ubBaseMedicalSkillToDealWithEmergency = iniReader.ReadInteger("JA2 Gameplay Settings","BASE_MEDICAL_SKILL_TO_DEAL_WITH_EMERGENCY",20, 0, 100); - gGameExternalOptions.ubMultiplierForDifferenceInLifeValueForEmergency = iniReader.ReadInteger("JA2 Gameplay Settings","MULTIPLIER_FOR_DIFFERENCE_IN_LIFE_VALUE_FOR_EMERGENCY",4, 1, 10); - gGameExternalOptions.ubPointCostPerHealthBelowOkLife = iniReader.ReadInteger("JA2 Gameplay Settings","POINT_COST_PER_HEALTH_BELOW_OKLIFE",2, 1, 5);//OKLIFE = 15 - - gGameExternalOptions.ubRepairCostPerJam = iniReader.ReadInteger("JA2 Gameplay Settings","REPAIR_COST_PER_JAM",2, 1, 10); - gGameExternalOptions.ubRepairRateDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","REPAIR_RATE_DIVISOR",2500, 1250, 25000); - - - //Misc - gGameExternalOptions.fAmmoDynamicWeight = iniReader.ReadBoolean("JA2 Gameplay Settings", "DYNAMIC_AMMO_WEIGHT", TRUE); //Pulmu - gGameExternalOptions.fEnableCrepitus = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_CREPITUS", TRUE); - - gGameExternalOptions.fEnableAllTerrorists = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_ALL_TERRORISTS", FALSE); - gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE); - - gGameExternalOptions.fSlowProgressForEnemyItemsChoice = iniReader.ReadBoolean("JA2 Gameplay Settings", "SLOW_PROGRESS_FOR_ENEMY_ITEMS_CHOICE", TRUE); - - // Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY - gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("JA2 Gameplay Settings", "VEHICLE_INVENTORY", TRUE); - - // WANNE: Added INI file Option for enemy ambushes, so we also have the option to play vanilla ja2 ambush settings - gGameExternalOptions.fEnableChanceOfEnemyAmbushesOnInsaneDifficult = iniReader.ReadBoolean("JA2 Gameplay Settings", "ENABLE_CHANCE_OF_ENEMY_AMBUSHES_ON_INSANE_DIFFICULT", TRUE); - - // CHRISL: New setting to allow Slay to remain as a hired PC - gGameExternalOptions.fEnableSlayForever = iniReader.ReadBoolean("JA2 Gameplay Settings", "SLAY_FOREVER", FALSE); - - // CHRISL: Setting to turn off the description and stack popup options from the sector inventory panel - gGameExternalOptions.fSectorDesc = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_SECTOR_DESCRIPTION_WINDOW",TRUE); - - //afp - use bullet tracers? - gGameExternalOptions.gbBulletTracer = iniReader.ReadBoolean("JA2 Gameplay Settings","USE_BULLET_TRACERS",FALSE); - - gGameExternalOptions.fRestrictFemaleEnemiesExceptElite = iniReader.ReadBoolean("JA2 Gameplay Settings","RESTRICT_FEMALE_ENEMIES_EXCEPT_ELITE",FALSE); - - // HEADROCK: Use Enhanced Item Description Box? - gGameExternalOptions.iEnhancedDescriptionBox = iniReader.ReadInteger("JA2 Gameplay Settings","USE_ENHANCED_DESCRIPTION_BOX",0, 0, 2); - - // WANNE: Always use prof.dat?? - gGameExternalOptions.fAlwaysUseProfDat = iniReader.ReadBoolean("JA2 Gameplay Settings", "ALWAYS_USE_PROF_DAT", FALSE); - - ///////////////////////////////////////////////////////////////////////// - // JA2 HAM Settings - ///////////////////////////////////////////////////////////////////////// - - // HEADROCK HAM B1: Set % of mine income, where 100% = normal - gGameExternalOptions.usMineIncomePercentage = iniReader.ReadInteger("JA2 HAM Settings","MINE_INCOME_PERCENTAGE", 100, 1, 1000); - - // HEADROCK HAM B1: Set minimum and maximum CTH - gGameExternalOptions.ubMaximumCTH = iniReader.ReadInteger("JA2 HAM Settings","MAXIMUM_POSSIBLE_CTH", 99, 1, 100); - - gGameExternalOptions.ubMinimumCTH = iniReader.ReadInteger("JA2 HAM Settings","MINIMUM_POSSIBLE_CTH", 1, 0, 99); - - // HEADROCK HAM B1: Set minimum CTH at fraction between 0 and 1 ( MINCTH = 1/(100*divisor) ) Note Minimum above must be 0. - gGameExternalOptions.usMinimumCTHDivisor = iniReader.ReadInteger("JA2 HAM Settings","MINIMUM_CTH_DIVISOR", 100, 1, 250); - - // HEADROCK HAM B1: Allow restricted militia to move through visited sectors? - gGameExternalOptions.fUnrestrictVisited = iniReader.ReadBoolean("JA2 HAM Settings","ALLOW_RESTRICTED_MILITIA_THROUGH_VISITED_SECTORS", FALSE); - - // HEADROCK HAM B1: Allow dynamic restrictions? - gGameExternalOptions.fDynamicRestrictRoaming = iniReader.ReadBoolean("JA2 HAM Settings","ALLOW_DYNAMIC_RESTRICTED_ROAMING", TRUE); - - // HEADROCK HAM B2.1: This controls how effective suppression is, by increasing the number of ubSuppressionPoints accumulated by combatants (percentage); - gGameExternalOptions.sSuppressionEffectiveness = iniReader.ReadInteger("JA2 HAM Settings","SUPPRESSION_EFFECTIVENESS", 0, 0, 1000); - - gGameExternalOptions.ubSuppressionToleranceMax = iniReader.ReadInteger("JA2 HAM Settings","SUPPRESSION_TOLERANCE_MAX", 18, 1, 24); - gGameExternalOptions.ubSuppressionToleranceMin = iniReader.ReadInteger("JA2 HAM Settings","SUPPRESSION_TOLERANCE_MIN", 1, 0, 24); - - // HEADROCK HAM B2: Suppression Shock effectiveness (percentage, 100 = "normal", 0 = deactivated. Range 0-65535) - gGameExternalOptions.usSuppressionShockEffect = iniReader.ReadInteger("JA2 HAM Settings","SUPPRESSION_SHOCK_EFFECTIVENESS", 100, 0, 1000); - - // HEADROCK HAM B2.1: CTH penalty given by a "Cowering" target to any enemy shooter. - gGameExternalOptions.ubAimPenaltyPerTargetShock = iniReader.ReadInteger("JA2 HAM Settings","AIM_PENALTY_PER_TARGET_SHOCK", 5, 0, 100 ); - - // HEADROCK HAM B2.3: A "cowering" soldier is twice as susceptible to suppression. - gGameExternalOptions.usCowerEffectOnSuppression = iniReader.ReadInteger("JA2 HAM Settings","COWER_EFFECT_ON_SUPPRESSION", 150, 0, 1000 ); - - // HEADROCK HAM B2.5: Turn on Realistic Tracers. 0 = off (regular tracers). 1 = Fully realistic tracers. 2 = Tracer Bump + 1.13 Autofire Penalty Reduction - gGameExternalOptions.ubRealisticTracers = iniReader.ReadInteger("JA2 HAM Settings","REALISTIC_TRACERS", 0, 0, 2); - - // HEADROCK HAM B2.5: Realistic tracers - one of every X bullets in a tracer magazines will be a tracer bullet. 0 = off (JA2 normal) - gGameExternalOptions.ubNumBulletsPerTracer = __max(iniReader.ReadInteger("JA2 HAM Settings","NUM_BULLETS_PER_TRACER", 5, 1, 255),1); - - // HEADROCK HAM B2.5: Realistic tracers - CTH increased by this amount whenever a tracer is fired. 0 = off. - gGameExternalOptions.ubCTHBumpPerTracer = iniReader.ReadInteger("JA2 HAM Settings","CTH_BUMP_PER_TRACER", 30, 0, 100 ); - - // HEADROCK HAM B2.6: Increased aiming costs? - gGameExternalOptions.fIncreasedAimingCost = iniReader.ReadBoolean("JA2 HAM Settings","INCREASED_AIM_COST", FALSE); - - // HEADROCK HAM B2.6: Dynamically determine Max-Aiming based also on weapon, bipod, etc? - gGameExternalOptions.fDynamicAimingTime = iniReader.ReadBoolean("JA2 HAM Settings","DYNAMIC_AIM_LIMITS", FALSE); - - // HEADROCK HAM B2.6: Controls how much effect target movement has on aiming - //gGameExternalOptions.iMovementEffectOnAiming = iniReader.ReadFloat("JA2 HAM Settings","MOVEMENT_EFFECT_ON_AIMING", 1.5); - gGameExternalOptions.iMovementEffectOnAiming = (float)iniReader.ReadDouble("JA2 HAM Settings","MOVEMENT_EFFECT_ON_AIMING", 1.5, 0.0, 255.0); - - // HEADROCK HAM B2.6: Autofire Bullets/5AP modifier - gGameExternalOptions.bAutofireBulletsPer5APModifier = iniReader.ReadInteger("JA2 HAM Settings","AUTOFIRE_BULLETS_PER_5AP_MODIFIER", 0, -100, 100 ); - - // HEADROCK HAM B2.6/B1: Adjustable "luck" factor in Auto-Resolve - //gGameExternalOptions.iAutoResolveLuckFactor = (float)(__max(iniReader.ReadFloat("JA2 HAM Settings","AUTORESOLVE_LUCK_FACTOR", 2.0),1.0)); - gGameExternalOptions.iAutoResolveLuckFactor = (float)(__max(iniReader.ReadDouble("JA2 HAM Settings","AUTORESOLVE_LUCK_FACTOR", 2.0, 0.0, 255.0),1.0)); - - // HEADROCK HAM B2.6: Adjustable maximum for Suppression Shock effect. This has the added effect of reducing overall susceptibility to shock and may render some enemies unshockable. - gGameExternalOptions.ubMaxSuppressionShock = iniReader.ReadInteger("JA2 HAM Settings","MAXIMUM_SUPPRESSION_SHOCK", 30, 0, 200 ); - - // HEADROCK HAM B2.6/2/1: Toggle new Burst/Auto CTH bars: 0=neither, 1=both, 2=Burst, 3=Auto - gGameExternalOptions.ubNewCTHBars = iniReader.ReadInteger("JA2 HAM Settings","NEW_BURST-AUTO_CTH_BARS", 0, 0, 3); - - // HEADROCK HAM B2.6: Toggle whether AI checks for larger magazine when wanting to suppress at a distance - gGameExternalOptions.fIncreaseAISuppressionFire = iniReader.ReadBoolean("JA2 HAM Settings","INCREASE_AI_WILLINGNESS_TO_SUPPRESS", FALSE); - - // HEADROCK HAM B2.7: Change the speed of skill progression. (defaults set to JA2 normal) - gGameExternalOptions.usHealthSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","HEALTH_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); - gGameExternalOptions.usStrengthSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","STRENGTH_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); - gGameExternalOptions.usDexteritySubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","DEXTERITY_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); - gGameExternalOptions.usAgilitySubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","AGILITY_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); - gGameExternalOptions.usWisdomSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","WISDOM_SUBPOINTS_TO_IMPROVE", 50, 1, 1000 ); - gGameExternalOptions.usMarksmanshipSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","MARKSMANSHIP_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); - gGameExternalOptions.usMedicalSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","MEDICAL_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); - gGameExternalOptions.usMechanicalSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","MECHANICAL_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); - gGameExternalOptions.usExplosivesSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","EXPLOSIVES_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); - gGameExternalOptions.usLeadershipSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","LEADERSHIP_SUBPOINTS_TO_IMPROVE", 25, 1, 1000 ); - gGameExternalOptions.usLevelSubpointsToImprove = iniReader.ReadInteger("JA2 HAM Settings","LEVEL_SUBPOINTS_TO_IMPROVE", 350, 1, 6500); - - // HEADROCK HAM B2.7: When turned on, this will give a CTH approximation instead of an exact value, on CTH Bars and "F" key feedback. - gGameExternalOptions.fApproximateCTH = iniReader.ReadBoolean("JA2 HAM Settings","APPROXIMATE_CTH", FALSE); - - // HEADROCK HAM B2.7: Augmented Roaming Militia code - turn this to TRUE to allow militia free travel through San Mona, Tixa, Orta, Omerta, and Estoni. - gGameExternalOptions.fAllowMilitiaMoveThroughMinorCities = iniReader.ReadBoolean("JA2 HAM Settings","ALLOW_MILITIA_MOVE_THROUGH_MINOR_CITIES", FALSE); - - // HEADROCK HAM B2.8: These are new cowering penalty divisors that help us determine how effective cowering is in different stances and when the shooter is targetting different bodyparts - gGameExternalOptions.ubCoweringPenaltyDivisorProne = iniReader.ReadInteger("JA2 HAM Settings","CTH_PENALTY_FOR_COWERING_PRONE_TARGET_DIVISOR", 1, 1, 100 ); - gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedHead = iniReader.ReadInteger("JA2 HAM Settings","CTH_PENALTY_FOR_COWERING_CROUCHED_TARGET_HEAD_DIVISOR", 3, 1, 100); - gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedTorso = iniReader.ReadInteger("JA2 HAM Settings","CTH_PENALTY_FOR_COWERING_CROUCHED_TARGET_TORSO_DIVISOR", 4, 1, 100); - gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedLegs = iniReader.ReadInteger("JA2 HAM Settings","CTH_PENALTY_FOR_COWERING_CROUCHED_TARGET_LEGS_DIVISOR", 5, 1, 100); - - // HEADROCK HAM B2.8: This is the maximum range at which a target gives out the full CTH penalty for cowering. At lower range, it'll give proportionally less penalty. - gGameExternalOptions.usMinRangeForFullCoweringPenalty = iniReader.ReadInteger("JA2 HAM Settings","MIN_RANGE_FOR_FULL_COWERING_TARGET_PENALTY", 300, 10, 10000 ); - - // HEADROCK HAM B2.8: Absolute maximum CTH penalty from target/shooter cowering - gGameExternalOptions.usMaxShooterCoweringPenalty = iniReader.ReadInteger("JA2 HAM Settings","MAX_SHOOTER_COWERING_PENALTY", 0, 0, 250 ); - gGameExternalOptions.usMaxTargetCoweringPenalty = iniReader.ReadInteger("JA2 HAM Settings","MAX_TARGET_COWERING_PENALTY", 0, 0, 250 ); - - // HEADROCK HAM B2.8: If this is turned on, Militia will drop their equipment similar to enemies, IF killed by non-player character. - gGameExternalOptions.ubMilitiaDropEquipment = iniReader.ReadInteger("JA2 HAM Settings","MILITIA_DROP_EQUIPMENT", 0, 0, 2 ); - - // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainees will go to sleep when their trainer goes to sleep. 3 = Trainer will go to sleep if all trainees are asleep. 1 = Both. 0 = Neither. - gGameExternalOptions.ubSmartTrainingSleep = iniReader.ReadInteger("JA2 HAM Settings","SMART_TRAINING-SLEEP_HANDLER", 0, 0, 3); - - // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainees will wake up when their trainer wakes up. 3 = Trainer will wake up if all trainees wake up. 1 = Both. 0 = Neither. - gGameExternalOptions.ubSmartTrainingWake = iniReader.ReadInteger("JA2 HAM Settings","SMART_TRAINING-WAKE_HANDLER", 0, 0, 3); - - // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainers will rest if no trainees available. 3 = Trainees will rest if no trainers available (not recommended). 1 = Both. 0 = Neither. - gGameExternalOptions.ubSmartTrainingRest = iniReader.ReadInteger("JA2 HAM Settings","SMART_TRAINING_REST", 0, 0, 3); - - // HEADROCK HAM 3: Externalized ratio between Weight and Strength. This value determines how many strength points we need to lift 0.5kg with no encumberance. - gGameExternalOptions.iStrengthToLiftHalfKilo = (float)iniReader.ReadDouble("JA2 HAM Settings","STRENGTH_TO_LIFT_HALF_KILO", 1.0, 0.1, 100.0); - - // HEADROCK HAM 3: Define minimum leadership required for training militia. Set to 0 for "no limit". - gGameExternalOptions.ubMinimumLeadershipToTrainMilitia = iniReader.ReadInteger("JA2 HAM Settings","MINIMUM_LEADERSHIP_TO_TRAIN_MILITIA", 0, 0, 99); - - // HEADROCK HAM 3: Define effect of "TEACHER" trait in increasing effective leadership, for purposes of eligibility for training militia. This is a percentage value. HAM Default would be 200 = double effective leadership for each TEACHING level. - gGameExternalOptions.usTeacherTraitEffectOnLeadership = iniReader.ReadInteger("JA2 HAM Settings","TEACHER_TRAIT_EFFECT_ON_LEADERSHIP", 100, 1, 10000); - - // HEADROCK HAM 3: If enabled, the trainer's "effective" leadership skill determines HOW MANY militia he/she creates per session. - gGameExternalOptions.fLeadershipAffectsMilitiaQuantity = iniReader.ReadBoolean("JA2 HAM Settings","LEADERSHIP_AFFECTS_MILITIA_QUANTITY", FALSE); - - // HEADROCK HAM 3: If "LEADERSHIP_AFFECTS_MILITIA_QUANTITY" is true, this value determines the lowest leadership required to train a full (default size 10) squad of town militia in one training session. - gGameExternalOptions.ubReqLeadershipForFullTraining = iniReader.ReadInteger("JA2 HAM Settings","REQ_LEADERSHIP_FOR_MAX_MILITIA", 100, 1, 100); - - // HEADROCK HAM 3: Four INI settings to control the number of kills you must accumulate to win one progress point, one setting per difficulty level - gGameExternalOptions.usNumKillsPerProgressPointNovice = iniReader.ReadInteger("JA2 HAM Settings","NUM_KILLS_PER_PROGRESS_POINT_NOVICE", 7, 1, 1000); - gGameExternalOptions.usNumKillsPerProgressPointExperienced = iniReader.ReadInteger("JA2 HAM Settings","NUM_KILLS_PER_PROGRESS_POINT_EXPERIENCED", 10, 1, 1000); - gGameExternalOptions.usNumKillsPerProgressPointExpert = iniReader.ReadInteger("JA2 HAM Settings","NUM_KILLS_PER_PROGRESS_POINT_EXPERT", 15, 1, 1000); - gGameExternalOptions.usNumKillsPerProgressPointInsane = iniReader.ReadInteger("JA2 HAM Settings","NUM_KILLS_PER_PROGRESS_POINT_INSANE", 60, 1, 1000); - // HEADROCK HAM 3: If enabled, changes the way the game calculates progress. It will look at each progress control separately (Kills/Income/Control/Visited) and set the progress to the HIGHEST scoring control. - gGameExternalOptions.fAlternateProgressCalculation = iniReader.ReadBoolean("JA2 HAM Settings","ALTERNATE_PROGRESS_CALCULATION", FALSE); + gGameExternalOptions.fAlternateProgressCalculation = iniReader.ReadBoolean("Strategic Progress Settings","ALTERNATE_PROGRESS_CALCULATION", FALSE); - // HEADROCK HAM 3: If enabled, tooltipping over Bobby Ray's weapons will show a list of possible attachments to those weapons. - gGameExternalOptions.fBobbyRayTooltipsShowAttachments = iniReader.ReadBoolean("JA2 HAM Settings","BOBBY_RAY_TOOLTIPS_SHOW_POSSIBLE_ATTACHMENTS", FALSE); + // Minimum progress value. + gGameExternalOptions.ubGameProgressMinimum = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MINIMUM", 0, 0, 100); + // Flat modifier to Current Progress. + gGameExternalOptions.bGameProgressModifier = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MODIFIER", 0, -100, 100); - // HEADROCK HAM 3.1: Divisor for the AP-to-Ready cost charge on first aiming click, when extra aiming costs are enabled. 0 = No ready-time-based charge. - gGameExternalOptions.ubFirstAimReadyCostDivisor = iniReader.ReadInteger("JA2 HAM Settings","FIRST_AIM_READY_COST_DIVISOR", 0, 0, 255); + // HEADROCK HAM 3: Four INI settings to control the number of kills you must accumulate to win one progress point, one setting per difficulty level + gGameExternalOptions.usNumKillsPerProgressPointNovice = iniReader.ReadInteger("Strategic Progress Settings","NUM_KILLS_PER_PROGRESS_POINT_NOVICE", 7, 1, 1000); + gGameExternalOptions.usNumKillsPerProgressPointExperienced = iniReader.ReadInteger("Strategic Progress Settings","NUM_KILLS_PER_PROGRESS_POINT_EXPERIENCED", 10, 1, 1000); + gGameExternalOptions.usNumKillsPerProgressPointExpert = iniReader.ReadInteger("Strategic Progress Settings","NUM_KILLS_PER_PROGRESS_POINT_EXPERT", 15, 1, 1000); + gGameExternalOptions.usNumKillsPerProgressPointInsane = iniReader.ReadInteger("Strategic Progress Settings","NUM_KILLS_PER_PROGRESS_POINT_INSANE", 60, 1, 1000); - // HEADROCK HAM 3.1: This is a suppression tool that not everyone will like. It gives an on-screen message when any character has been suppressed so much he's lost his next turn completely! - gGameExternalOptions.fShowSuppressionShutdown = iniReader.ReadBoolean("JA2 HAM Settings","SHOW_MSG_FULLY_SUPPRESSED", FALSE); + //Global game events + gGameExternalOptions.ubGameProgressStartMadlabQuest = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_START_MADLAB_QUEST",35, 1, 100); + gGameExternalOptions.ubGameProgressMikeAvailable = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_MIKE_AVAILABLE",50, 1, 100); + gGameExternalOptions.ubGameProgressIggyAvaliable = iniReader.ReadInteger("Strategic Progress Settings","GAME_PROGRESS_IGGY_AVAILABLE",70, 1, 100); - // HEADROCK HAM 3.1: Set whether you'd like to determine yourself which mine (if any) will shut down during the campaign. - gGameExternalOptions.fManuallySelectMineShutdown = iniReader.ReadBoolean("JA2 HAM Settings","MANUALLY_SELECT_MINE_TO_RUN_OUT", FALSE); + + //################# Strategic Event Settings ################## + + // Drassen counterattack + gGameExternalOptions.ubSendTroopsToDrassen = iniReader.ReadBoolean("Strategic Event Settings","TRIGGER_MASSIVE_ENEMY_COUNTERATTACK_AT_DRASSEN",TRUE); + + // Enable/Disable crepitus completely in SCI-FI mode. + gGameExternalOptions.fEnableCrepitus = iniReader.ReadBoolean("Strategic Event Settings", "ENABLE_CREPITUS", TRUE); // HEADROCK HAM 3.1: Select which mine will run out. 0 = no mine. 1 = San Mona (unused), 2 = Drassen, 3 = Alma, 4 = Cambria, 5 = Chitzena, 6 = Grumm. - gGameExternalOptions.ubWhichMineRunsOut = iniReader.ReadInteger("JA2 HAM Settings","WHICH_MINE_RUNS_OUT", 0, 0, 6); + gGameExternalOptions.bWhichMineRunsOut = iniReader.ReadInteger("Strategic Event Settings","WHICH_MINE_SHUTS_DOWN", -1, -1, 6); + + + //################# Strategic Gameplay Settings ################## + + // Allow enemy and militia Strategic Groups to reinforce one another for battles? + gGameExternalOptions.gfAllowReinforcements = iniReader.ReadBoolean("Strategic Gameplay Settings","ALLOW_REINFORCEMENTS",FALSE); + // Allow reinforcements only between City sectors? + gGameExternalOptions.gfAllowReinforcementsOnlyInCity = iniReader.ReadBoolean("Strategic Gameplay Settings","ALLOW_REINFORCEMENTS_ONLY_IN_CITIES",FALSE); + + gGameExternalOptions.fEnableAllTerrorists = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_TERRORISTS", FALSE); + gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE); + + // Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY + gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("Strategic Gameplay Settings", "VEHICLE_INVENTORY", TRUE); // HEADROCK HAM 3.1: Can the Humvee go off-road? - gGameExternalOptions.fHumveeOffroad = iniReader.ReadBoolean("JA2 HAM Settings","HUMVEE_OFFROAD", FALSE); + gGameExternalOptions.fHumveeOffroad = iniReader.ReadBoolean("Strategic Gameplay Settings","HUMVEE_OFFROAD", FALSE); - // HEADROCK HAM 3.2: If activated, reinforcements (militia/enemy) arrive in the battle with 0 APs. This makes them less of a diablo-ex-machina. 0 = Diabled. 2 = Enemies. 3 = Militia. 1 = both - gGameExternalOptions.ubReinforcementsFirstTurnFreeze = iniReader.ReadInteger("JA2 HAM Settings","REINFORCEMENTS_ARRIVE_WITH_NO_AP", 0, 0, 3); - - // HEADROCK HAM 3.2: This feature allows the status, leadership and experience of nearby friendlies help/hinder a character's tolerance, based on their distance from him. - gGameExternalOptions.fFriendliesAffectTolerance = iniReader.ReadBoolean("JA2 HAM Settings","FRIENDLIES_AFFECT_TOLERANCE", FALSE); - - // HEADROCK HAM 3.2: Set a divisor for the CtH of Mortar weapons. - gGameExternalOptions.ubMortarCTHDivisor = iniReader.ReadInteger("JA2 HAM Settings","MORTAR_CTH_DIVISOR", 1, 1, 255); - - // HEADROCK HAM 3.2: This enabled reduced sight for cowering characters. 0 = disabled. 2 = Reduced Sightrange. 3 = Tunnel-vision. 1 = Both. - gGameExternalOptions.ubCoweringReducesSightRange = iniReader.ReadInteger("JA2 HAM Settings","COWERING_REDUCES_SIGHTRANGE", 0, 0, 3); - - // HEADROCK HAM 3.2: Critical Headshots may cause blindness. Rolls 1 to X change of being blinded. 0 = disabled. - gGameExternalOptions.ubChanceBlindedByHeadshot = iniReader.ReadInteger("JA2 HAM Settings","CHANCE_BLINDED_BY_HEADSHOT", 0, 0, 10); - - // HEADROCK HAM 3.2: Critical Legshots cause additional AP loss - gGameExternalOptions.fCriticalLegshotCausesAPLoss = iniReader.ReadBoolean("JA2 HAM Settings","CRITICAL_LEGSHOT_CAUSES_AP_LOSS", FALSE); + // HEADROCK HAM B2.6/B1: Adjustable "luck" factor in Auto-Resolve + gGameExternalOptions.iAutoResolveLuckFactor = (float)(__max(iniReader.ReadDouble("Strategic Gameplay Settings","AUTORESOLVE_LUCK_FACTOR", 2.0, 0.0, 255.0),1.0)); // HEADROCK HAM 3.2: When enabled, this setting removes the player's omniscience inside his own sectors. The player will no longer see the movement of enemy groups unless someone is nearby to scout them. - gGameExternalOptions.fNoEnemyDetectionWithoutRecon = iniReader.ReadBoolean("JA2 HAM Settings","NO_ENEMY_DETECTION_WITHOUT_RECON", FALSE); - - // HEADROCK HAM 3.2: Determines the training bonus for the Medical skill, when training in "hospital" sectors - gGameExternalOptions.ubHospitalTrainingBonus = iniReader.ReadInteger("JA2 HAM Settings","HOSPITAL_TRAINING_BONUS", 0, 0, 100); - - // HEADROCK HAM 3.2: Determines the repaid bonus when training in factory ("industrial") sectors - in percentage of the character's original repair points! - gGameExternalOptions.ubFactoryRepairBonus = iniReader.ReadInteger("JA2 HAM Settings","FACTORY_REPAIR_BONUS", 0, 0, 100); - - // HEADROCK HAM 3.2: How much MECHANICAL skill do we need to gain a repair bonus from a factory? - gGameExternalOptions.ubMinMechanicalForFactoryRepairBonus = iniReader.ReadInteger("JA2 HAM Settings","MIN_MECHANICAL_FOR_FACTORY_REPAIR_BONUS", 0, 0, 100); - - // HEADROCK HAM 3.3: Externalized maximum possible penalty for hitting a moving target. JA2 Default = 30. - gGameExternalOptions.usMaxCTHPenaltyForMovingTarget = iniReader.ReadInteger("JA2 HAM Settings","MAX_CTH_PENALTY_FOR_MOVING_TARGET", 30, 0, 300); - - // HEADROCK HAM 3.3: Increases tolerance while moving. - gGameExternalOptions.ubTilesMovedPerBonusTolerancePoint = iniReader.ReadInteger("JA2 HAM Settings","TILES_MOVED_PER_BONUS_TOLERANCE_POINT", 5, 0, 20); - - // HEADROCK HAM 3.3: New militia feature, Minimum Leadership required to train Roaming Militia - gGameExternalOptions.ubMinimumLeadershipToTrainMobileMilitia = iniReader.ReadInteger("JA2 HAM Settings","MIN_LEADERSHIP_TO_TRAIN_MOBILE_MILITIA", 0, 0, 100); - - // HEADROCK HAM 3.3: If enabled, the trainer's "effective" leadership skill determines HOW MANY Mobile Militia he/she creates per session. - gGameExternalOptions.fLeadershipAffectsMobileMilitiaQuantity = iniReader.ReadBoolean("JA2 HAM Settings","LEADERSHIP_AFFECTS_MOBILE_MILITIA_QUANTITY", FALSE); - - // HEADROCK HAM 3.3: If "LEADERSHIP_AFFECTS_MILITIA_QUANTITY" is true, this value determines the lowest leadership required to train a full (default size 5) squad of Mobile Militia in one training session. - gGameExternalOptions.ubReqLeadershipForFullMobileTraining = iniReader.ReadInteger("JA2 HAM Settings","REQ_LEADERSHIP_FOR_MAX_MOBILE_MILITIA", 1, 1, 100); - - // HEADROCK HAM 3.3: Minimum distance (in METERS) at which character suffer from friendly suppression. - gGameExternalOptions.usMinDistanceFriendlySuppression = iniReader.ReadInteger("JA2 HAM Settings","MIN_DISTANCE_FRIENDLY_SUPPRESSION", 30, 0, 65000); - - // HEADROCK HAM 3.3: If enabled, Roaming Militia can automatically reinforce city garrisons. - gGameExternalOptions.fAllowMobileReinforceCities = iniReader.ReadBoolean("JA2 HAM Settings","ALLOW_MOBILE_MILITIA_REINFORCE_TOWN_GARRISONS", FALSE); - - // HEADROCK HAM 3.3: If enabled, Roaming Militia can automatically reinforce city garrisons. - gGameExternalOptions.fAllowMobileReinforceSAM = iniReader.ReadBoolean("JA2 HAM Settings","ALLOW_MOBILE_MILITIA_REINFORCE_SAM_GARRISONS", FALSE); - - // HEADROCK HAM 3.4: This controls the intensity of Hiding the Bullet Count during combat. The higher it is, the more intense the effect. Negative values reduce the effect. - gGameExternalOptions.usBulletHideIntensity = iniReader.ReadInteger("JA2 HAM Settings","BULLET_HIDE_INTENSITY", 100, 0, 1000); - - // HEADROCK HAM 3.4: What percentage of a new Mobile Militia group will be made of Elites? If >0, then at least one of every new group will be an Elite. 100 = All Elites. - gGameExternalOptions.ubPercentRoamingMilitiaElites = iniReader.ReadInteger("JA2 HAM Settings","PERCENT_ROAMING_MILITIA_ELITES", 100, 0, 100); - - // HEADROCK HAM 3.4: What percentage of a new Mobile Militia group will be made of Regulars? If >0, then at least one of every new group will be a Regular. 100 = All Regulars. - gGameExternalOptions.ubPercentRoamingMilitiaRegulars = iniReader.ReadInteger("JA2 HAM Settings","PERCENT_ROAMING_MILITIA_REGULARS", 0, 0, 100); - - // HEADROCK HAM 3.5: Does leadership affect the Quality of new Mobile Militia groups? - gGameExternalOptions.fLeadershipAffectsMobileMilitiaQuality = iniReader.ReadBoolean("JA2 HAM Settings","LEADERSHIP_AFFECTS_MOBILE_MILITIA_QUALITY", FALSE); - - // HEADROCK HAM 3.5: Explosive Suppression Effectiveness alters the amount of Suppression Points you get from nearby blasts. - gGameExternalOptions.usExplosionSuppressionEffect = iniReader.ReadInteger("JA2 HAM Settings","EXPLOSIVE_SUPPRESSION_EFFECTIVENESS", 100, 0, 1000); - - // HEADROCK HAM 3.5: When enabled, goggle-switching affects every merc in the sector, not just those belonging to the current squad. - gGameExternalOptions.fGoggleSwapAffectsAllMercsInSector = iniReader.ReadBoolean("JA2 HAM Settings","GOGGLE_SWAP_AFFECTS_ALL_MERCS_IN_SECTOR", FALSE); - - // HEADROCK HAM 3.5: Helicopter - Base cost per tile in "GREEN" airspace - gGameExternalOptions.usHelicopterBaseCostPerGreenTile = iniReader.ReadInteger("JA2 HAM Settings","HELICOPTER_BASE_COST_PER_GREEN_TILE", 100, 0, 60000); - - // HEADROCK HAM 3.5: Helicopter - Base cost per tile in "RED" airspace - gGameExternalOptions.usHelicopterBaseCostPerRedTile = iniReader.ReadInteger("JA2 HAM Settings","HELICOPTER_BASE_COST_PER_RED_TILE", 1000, 0, 60000); - - // HEADROCK HAM 3.5: Experimental, arrival sectorX/Y. - gGameExternalOptions.ubDefaultArrivalSectorX = iniReader.ReadInteger("JA2 HAM Settings","DEFAULT_ARRIVAL_SECTOR_X", 9, 1, 16); - gGameExternalOptions.ubDefaultArrivalSectorY = iniReader.ReadInteger("JA2 HAM Settings","DEFAULT_ARRIVAL_SECTOR_Y", 1, 1, 16); - - // HEADROCK HAM 3.5: Limit bonus from tracers based on range to target. This is a multiplier factor - higher means harder to aim with tracers. - gGameExternalOptions.ubRangeDifficultyAimingWithTracers = iniReader.ReadInteger("JA2 HAM Settings","RANGE_EFFECT_ON_MAX_TRACER_CTH_BONUS", 3, 1, 10); - - // HEADROCK HAM 3.6: Militia can now place blue flags when they spot a landmine. - gGameExternalOptions.fMilitiaPlaceBlueFlags = iniReader.ReadBoolean("JA2 HAM Settings","MILITIA_PLACE_FLAGS_ON_MINES", FALSE); - - // HEADROCK PROFEX/3.6: Activate this to read Profile data from MercProfiles.XML and MercOpinions.XML - gGameExternalOptions.fReadProfileDataFromXML = iniReader.ReadBoolean("JA2 HAM Settings","READ_PROFILE_DATA_FROM_XML", FALSE); - - // HEADROCK PROFEX/3.6: Activate this to write Profile data to MercProfiles Out.XML and MercOpinions Out.XML. This can be used to convert PROF.DAT to XML format. - gGameExternalOptions.fWriteProfileDataToXML = iniReader.ReadBoolean("JA2 HAM Settings","WRITE_PROFILE_DATA_TO_XML", FALSE); - - // HEADROCK HAM 3.6: Progress bars for each stat, displayed behind the stat value on the merc panel. INI settings give RGB color, Menu setting toggles on/off. - gGameExternalOptions.ubStatProgressBarsRed = iniReader.ReadInteger("JA2 HAM Settings","STAT_PROGRESS_BARS_RED", 200, 0, 255); - gGameExternalOptions.ubStatProgressBarsGreen = iniReader.ReadInteger("JA2 HAM Settings","STAT_PROGRESS_BARS_GREEN", 0, 0, 255); - gGameExternalOptions.ubStatProgressBarsBlue = iniReader.ReadInteger("JA2 HAM Settings","STAT_PROGRESS_BARS_BLUE", 0, 0, 255); + gGameExternalOptions.fNoEnemyDetectionWithoutRecon = iniReader.ReadBoolean("Strategic Gameplay Settings","NO_ENEMY_DETECTION_WITHOUT_RECON", FALSE); // HEADROCK HAM 3.6: Determines how likely a character is, every hour, to trigger a facility event. The actual chance is X in every Y attempts, where X is facility-specific, and Y is the value adjusted here. - gGameExternalOptions.usFacilityEventRarity = iniReader.ReadInteger("JA2 HAM Settings","FACILITY_EVENT_RARITY", 1000, 0, 50000); + gGameExternalOptions.usFacilityEventRarity = iniReader.ReadInteger("Strategic Gameplay Settings","FACILITY_EVENT_RARITY", 1000, 0, 50000); // HEADROCK HAM 3.6: Controls how important the character's stats are, in insuring he/she gets better results (or smaller damage) from using facilities. The higher this is, the more dangerous all facilities are. - gGameExternalOptions.ubFacilityDangerRate = iniReader.ReadInteger("JA2 HAM Settings","FACILITY_DANGER_RATE", 50, 0, 100); + gGameExternalOptions.ubFacilityDangerRate = iniReader.ReadInteger("Strategic Gameplay Settings","FACILITY_DANGER_RATE", 50, 0, 100); - // HEADROCK HAM 3.6: Determines whether the extrapolated daily costs of mercs are figured into the "Daily Expenses" display. 0 = No, just facility costs. 1 = Only mercs with a fixed daily rate. 2 = All mercs, including AIM contracts. - gGameExternalOptions.ubIncludeContractsInExpenses = iniReader.ReadInteger("JA2 HAM Settings","INCLUDE_CONTRACTS_IN_EXPENSES_DISPLAY", 1, 0, 2); - // HEADROCK HAM 3.6: Maximum number of messages displayed in Tactical view - gGameExternalOptions.ubMaxMessagesTactical = iniReader.ReadInteger("JA2 HAM Settings","MAXIMUM_MESSAGES_IN_TACTICAL", 6, 1, 36); - switch (iResolution) - { - case 0: - gGameExternalOptions.ubMaxMessagesTactical = __max(20, gGameExternalOptions.ubMaxMessagesTactical); - break; - case 1: - gGameExternalOptions.ubMaxMessagesTactical = __max(26, gGameExternalOptions.ubMaxMessagesTactical); - break; - } + //################# Bobby Ray Settings ################## - // HEADROCK HAM 3.6: Daily upkeep costs for militia - gGameExternalOptions.usDailyCostTownGreen = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_TOWN_GREEN", 0, 0, 10000); - gGameExternalOptions.usDailyCostTownRegular = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_TOWN_REGULAR", 0, 0, 10000); - gGameExternalOptions.usDailyCostTownElite = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_TOWN_ELITE", 0, 0, 10000); - gGameExternalOptions.usDailyCostMobileGreen = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_MOBILE_GREEN", 0, 0, 10000); - gGameExternalOptions.usDailyCostMobileRegular = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_MOBILE_REGULAR", 0, 0, 10000); - gGameExternalOptions.usDailyCostMobileElite = iniReader.ReadInteger("JA2 HAM Settings","DAILY_MILITIA_UPKEEP_MOBILE_ELITE", 0, 0, 10000); - // HEADROCK HAM 3.6: Non-Combat Bodytypes shouldn't become hostile - gGameExternalOptions.fCanTrueCiviliansBecomeHostile = iniReader.ReadBoolean("JA2 HAM Settings","CAN_TRUE_CIVILIANS_BECOME_HOSTILE", TRUE); + // HEADROCK HAM 3: If enabled, tooltipping over Bobby Ray's weapons will show a list of possible attachments to those weapons. + gGameExternalOptions.fBobbyRayTooltipsShowAttachments = iniReader.ReadBoolean("Bobby Ray Settings","BOBBY_RAY_TOOLTIPS_SHOW_POSSIBLE_ATTACHMENTS", FALSE); - // HEADROCK HAM 3.6: Militia become hostile when attacked. 0 = No. 1 = If killed. 2 = If attacked (JA2 Default) - gGameExternalOptions.ubCanMilitiaBecomeHostile = iniReader.ReadInteger("JA2 HAM Settings","CAN_MILITIA_BECOME_HOSTILE", 2, 0, 2); + // WDS - Option to turn off stealing + gGameExternalOptions.fStealingDisabled = iniReader.ReadBoolean("Bobby Ray Settings","STEALING_FROM_SHIPMENTS_DISABLED",FALSE); - // HEADROCK HAM 3.6: If activated, the game does not switch focus to a merc who spots an enemy in real-time mode. This fixes issues with Real-Time Sneak. - gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak = iniReader.ReadBoolean("JA2 HAM Settings","NO_AUTO_FOCUS_CHANGE_IN_REALTIME_SNEAK", FALSE); + // WANNE - Chance of shipment lost + gGameExternalOptions.gubChanceOfShipmentLost = iniReader.ReadInteger("Bobby Ray Settings","CHANCE_OF_SHIPMENT_LOSS", 10); + + + //################# Item Property Settings ################## + + //Weapons modification + gGameExternalOptions.iExplosivesDamageModifier = iniReader.ReadInteger("Item Property Settings","EXPLOSIVES_DAMAGE_MODIFIER",100, 0, 1000); + gGameExternalOptions.iMeleeDamageModifier = iniReader.ReadInteger("Item Property Settings","MELEE_DAMAGE_MODIFIER",100, 0, 1000); + gGameExternalOptions.iGunDamageModifier = iniReader.ReadInteger("Item Property Settings","GUN_DAMAGE_MODIFIER",100, 0, 1000); + + // Enables the "Coverage" value of armor items. + gGameExternalOptions.fEnableArmorCoverage = iniReader.ReadBoolean("Item Property Settings", "ENABLE_ARMOR_COVERAGE", FALSE); // ShadoWarrior for Captain J's armor coverage + + gGameExternalOptions.fAmmoDynamicWeight = iniReader.ReadBoolean("Item Property Settings", "DYNAMIC_AMMO_WEIGHT", TRUE); //Pulmu + + // HEADROCK HAM B2.6: Autofire Bullets/5AP modifier + gGameExternalOptions.bAutofireBulletsPer5APModifier = iniReader.ReadInteger("Item Property Settings","AUTOFIRE_BULLETS_PER_5AP_MODIFIER", 0, -100, 100 ); + + // HEADROCK HAM 3: Externalized ratio between Weight and Strength. This value determines how many strength points we need to lift 0.5kg with no encumberance. + gGameExternalOptions.iStrengthToLiftHalfKilo = (float)iniReader.ReadDouble("Item Property Settings","STRENGTH_TO_LIFT_HALF_KILO", 1.0, 0.1, 100.0); + + // HEADROCK HAM 3.2: Set a divisor for the CtH of Mortar weapons. + gGameExternalOptions.ubMortarCTHDivisor = iniReader.ReadInteger("Item Property Settings","MORTAR_CTH_DIVISOR", 1, 1, 255); + + + + //################# Strategic Enemy AI Settings ################## + + // WDS - New AI + gGameExternalOptions.useNewAI = iniReader.ReadBoolean("Strategic Enemy AI Settings","NEW_AGGRESSIVE_AI",FALSE); + + gGameExternalOptions.iForcePercentageNovice = iniReader.ReadInteger("Strategic Enemy AI Settings","INITIAL_GARRISON_PERCENTAGES_NOVICE",70, 1, 200); + gGameExternalOptions.iForcePercentageExperienced = iniReader.ReadInteger("Strategic Enemy AI Settings","INITIAL_GARRISON_PERCENTAGES_EXPERIENCED",100, 1, 300); + gGameExternalOptions.iForcePercentageExpert = iniReader.ReadInteger("Strategic Enemy AI Settings","INITIAL_GARRISON_PERCENTAGES_EXPERT",150, 1, 400); + gGameExternalOptions.iForcePercentageInsane = iniReader.ReadInteger("Strategic Enemy AI Settings","INITIAL_GARRISON_PERCENTAGES_INSANE",200, 1, 600); + + gGameExternalOptions.ubMinEnemyGroupSizeNovice = (UINT8) iniReader.ReadInteger("Strategic Enemy AI Settings","MIN_ENEMY_GROUP_SIZE_NOVICE",3, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); + gGameExternalOptions.ubMinEnemyGroupSizeExperienced = (UINT8) iniReader.ReadInteger("Strategic Enemy AI Settings","MIN_ENEMY_GROUP_SIZE_EXPERIENCED",4, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); + gGameExternalOptions.ubMinEnemyGroupSizeExpert = (UINT8) iniReader.ReadInteger("Strategic Enemy AI Settings","MIN_ENEMY_GROUP_SIZE_EXPERT",6, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); + gGameExternalOptions.ubMinEnemyGroupSizeInsane = (UINT8) iniReader.ReadInteger("Strategic Enemy AI Settings","MIN_ENEMY_GROUP_SIZE_INSANE",12, 1, CODE_MAXIMUM_NUMBER_OF_ENEMIES); + + gGameExternalOptions.iPercentElitesBonusExperienced = iniReader.ReadInteger("Strategic Enemy AI Settings","PERCENT_EXTRA_ELITES_EXPERIENCED",0, 0, 100); + gGameExternalOptions.iPercentElitesBonusExpert = iniReader.ReadInteger("Strategic Enemy AI Settings","PERCENT_EXTRA_ELITES_EXPERT",25, 0, 100); + gGameExternalOptions.iPercentElitesBonusInsane = iniReader.ReadInteger("Strategic Enemy AI Settings","PERCENT_EXTRA_ELITES_INSANE",50, 0, 100); + + gGameExternalOptions.gfEasyUnlimitedTroops = iniReader.ReadBoolean("Strategic Enemy AI Settings","UNLIMITED_POOL_OF_TROOPS_NOVICE",FALSE); + gGameExternalOptions.gfNormalUnlimitedTroops = iniReader.ReadBoolean("Strategic Enemy AI Settings","UNLIMITED_POOL_OF_TROOPS_EXPERIENCED",FALSE); + gGameExternalOptions.gfHardUnlimitedTroops = iniReader.ReadBoolean("Strategic Enemy AI Settings","UNLIMITED_POOL_OF_TROOPS_EXPERT",FALSE); + gGameExternalOptions.gfInsaneUnlimitedTroops = iniReader.ReadBoolean("Strategic Enemy AI Settings","UNLIMITED_POOL_OF_TROOPS_INSANE",TRUE); + + gGameExternalOptions.iReinforcementPoolNovice = iniReader.ReadInteger("Strategic Enemy AI Settings","QUEENS_INITIAL_POOL_OF_TROOPS_NOVICE",150, 25, 1000000); + gGameExternalOptions.iReinforcementPoolExperienced = iniReader.ReadInteger("Strategic Enemy AI Settings","QUEENS_INITIAL_POOL_OF_TROOPS_EXPERIENCED",200, 25, 1000000); + gGameExternalOptions.iReinforcementPoolExpert = iniReader.ReadInteger("Strategic Enemy AI Settings","QUEENS_INITIAL_POOL_OF_TROOPS_EXPERT",400, 25, 1000000); + gGameExternalOptions.iReinforcementPoolInsane = iniReader.ReadInteger("Strategic Enemy AI Settings","QUEENS_INITIAL_POOL_OF_TROOPS_INSANE",8000, 25, 1000000); + + gGameExternalOptions.guiBaseQueenPoolIncrement = iniReader.ReadInteger("Strategic Enemy AI Settings","QUEEN_POOL_INCREMENT_PER_DIFFICULTY_LEVEL",60, 1, 100); + + gGameExternalOptions.ubEasyEnemyStartingAlertLevel = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_STARTING_ALERT_LEVEL_NOVICE", 5, 1, 100); + gGameExternalOptions.ubNormalEnemyStartingAlertLevel = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_STARTING_ALERT_LEVEL_EXPERIENCED", 20, 1, 100); + gGameExternalOptions.ubHardEnemyStartingAlertLevel = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_STARTING_ALERT_LEVEL_EXPERT", 60, 1, 100); + gGameExternalOptions.ubInsaneEnemyStartingAlertLevel = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_STARTING_ALERT_LEVEL_INSANE", 80, 1, 100); + + gGameExternalOptions.ubEasyEnemyStartingAlertDecay = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_ALERT_DECAY_NOVICE", 75, 1, 100); + gGameExternalOptions.ubNormalEnemyStartingAlertDecay = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_ALERT_DECAY_EXPERIENCED", 50, 1, 100); + gGameExternalOptions.ubHardEnemyStartingAlertDecay = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_ALERT_DECAY_EXPERT", 25, 1, 100); + gGameExternalOptions.ubInsaneEnemyStartingAlertDecay = iniReader.ReadInteger("Strategic Enemy AI Settings","ENEMY_ALERT_DECAY_INSANE", 10, 1, 100); + + gGameExternalOptions.ubEasyNumAwareBattles = iniReader.ReadInteger("Strategic Enemy AI Settings","NUM_AWARE_BATTLES_NOVICE", 1, 1, 10); + gGameExternalOptions.ubNormalNumAwareBattles = iniReader.ReadInteger("Strategic Enemy AI Settings","NUM_AWARE_BATTLES_EXPERIENCED", 2, 1, 10); + gGameExternalOptions.ubHardNumAwareBattles = iniReader.ReadInteger("Strategic Enemy AI Settings","NUM_AWARE_BATTLES_EXPERT", 3, 1, 10); + gGameExternalOptions.ubInsaneNumAwareBattles = iniReader.ReadInteger("Strategic Enemy AI Settings","NUM_AWARE_BATTLES_INSANE", 4, 1, 10); + + gGameExternalOptions.ubEasyTimeEvaluateInMinutes = iniReader.ReadInteger("Strategic Enemy AI Settings","BASE_DELAY_IN_MINUTES_BETWEEN_EVALUATIONS_NOVICE", 480, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubNormalTimeEvaluateInMinutes = iniReader.ReadInteger("Strategic Enemy AI Settings","BASE_DELAY_IN_MINUTES_BETWEEN_EVALUATIONS_EXPERIENCED", 360, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubHardTimeEvaluateInMinutes = iniReader.ReadInteger("Strategic Enemy AI Settings","BASE_DELAY_IN_MINUTES_BETWEEN_EVALUATIONS_EXPERT", 180, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubInsaneTimeEvaluateInMinutes = iniReader.ReadInteger("Strategic Enemy AI Settings","BASE_DELAY_IN_MINUTES_BETWEEN_EVALUATIONS_INSANE", 90, 10, NUM_MIN_IN_DAY); + + gGameExternalOptions.ubEasyTimeEvaluateVariance = iniReader.ReadInteger("Strategic Enemy AI Settings","EVALUATION_DELAY_VARIANCE_NOVICE", 240, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubNormalTimeEvaluateVariance = iniReader.ReadInteger("Strategic Enemy AI Settings","EXPERIENCED_TIME_EVALUATE_VARIANCE", 180, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubHardTimeEvaluateVariance = iniReader.ReadInteger("Strategic Enemy AI Settings","EXPERT_TIME_EVALUATE_VARIANCE", 120, 10, NUM_MIN_IN_DAY); + gGameExternalOptions.ubInsaneTimeEvaluateVariance = iniReader.ReadInteger("Strategic Enemy AI Settings","INSANE_TIME_EVALUATE_VARIANCE", 60, 10, NUM_MIN_IN_DAY); + + gGameExternalOptions.ubEasyGracePeriodInHours = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_HOURS_AFTER_SECTOR_LIBERATION_NOVICE", 144, 1, 288); + gGameExternalOptions.ubNormalGracePeriodInHours = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_HOURS_AFTER_SECTOR_LIBERATION_EXPERIENCED", 96, 1, 288); + gGameExternalOptions.ubHardGracePeriodInHours = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_HOURS_AFTER_SECTOR_LIBERATION_EXPERT", 48, 1, 288); + gGameExternalOptions.ubInsaneGracePeriodInHours = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_HOURS_AFTER_SECTOR_LIBERATION_INSANE", 6, 1, 288); + + gGameExternalOptions.ubEasyPatrolGracePeriodInDays = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_DAYS_AFTER_PATROL_DESTROYED_NOVICE", 16, 1, 100); + gGameExternalOptions.ubNormalPatrolGracePeriodInDays = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_DAYS_AFTER_PATROL_DESTROYED_EXPERIENCED", 12, 1, 100); + gGameExternalOptions.ubHardPatrolGracePeriodInDays = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_DAYS_AFTER_PATROL_DESTROYED_EXPERT", 8, 1, 100); + gGameExternalOptions.ubInsanePatrolGracePeriodInDays = iniReader.ReadInteger("Strategic Enemy AI Settings","GRACE_PERIOD_IN_DAYS_AFTER_PATROL_DESTROYED_INSANE", 2, 1, 100); + + gGameExternalOptions.gfEasyAggressiveQueen = iniReader.ReadBoolean("Strategic Enemy AI Settings","AGGRESSIVE_QUEEN_AI_NOVICE",FALSE); + gGameExternalOptions.gfNormalAggressiveQueen = iniReader.ReadBoolean("Strategic Enemy AI Settings","AGGRESSIVE_QUEEN_AI_EXPERIENCED",FALSE); + gGameExternalOptions.gfHardAggressiveQueen = iniReader.ReadBoolean("Strategic Enemy AI Settings","AGGRESSIVE_QUEEN_AI_EXPERT",FALSE); + gGameExternalOptions.gfInsaneAggressiveQueen = iniReader.ReadBoolean("Strategic Enemy AI Settings","AGGRESSIVE_QUEEN_AI_INSANE",TRUE); + + gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("Strategic Enemy AI Settings","ENEMY_INVESTIGATE_SECTOR",FALSE); + gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("Strategic Enemy AI Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE); + + + //################# Militia Training Settings ################## + + gGameExternalOptions.iMaxMilitiaPerSector = iniReader.ReadInteger("Militia Training Settings","MAX_MILITIA_PER_SECTOR",20, 1, CODE_MAXIMUM_NUMBER_OF_REBELS); + + gGameExternalOptions.iTrainingSquadSize = iniReader.ReadInteger("Militia Training Settings","NUM_MILITIA_TRAINED_PER_SESSION",10, 1, CODE_MAXIMUM_NUMBER_OF_REBELS); + + gGameExternalOptions.iMinLoyaltyToTrain = iniReader.ReadInteger("Militia Training Settings","MIN_LOYALTY_TO_TRAIN_MILITIA",20, 0, 100); + + gGameExternalOptions.ubTownMilitiaTrainingRate = iniReader.ReadInteger("Militia Training Settings","MILITIA_TRAINING_RATE",4, 1, 10); + + gGameExternalOptions.gfTrainVeteranMilitia = iniReader.ReadBoolean("Militia Training Settings","ALLOW_TRAINING_ELITE_MILITIA",FALSE); + gGameExternalOptions.guiTrainVeteranMilitiaDelay = iniReader.ReadInteger("Militia Training Settings","ELITE_MILITIA_TRAINING_DELAY",1, 0, 30); + + gGameExternalOptions.ubRpcBonusToTrainMilitia = iniReader.ReadInteger("Militia Training Settings","RPC_BONUS_TO_MILITIA_TRAINING_RATE",10, 0, 100); + + // HEADROCK HAM 3: Define minimum leadership required for training militia. Set to 0 for "no limit". + gGameExternalOptions.ubMinimumLeadershipToTrainMilitia = iniReader.ReadInteger("Militia Training Settings","MINIMUM_LEADERSHIP_TO_TRAIN_MILITIA", 0, 0, 99); + + // HEADROCK HAM 3: If enabled, the trainer's "effective" leadership skill determines HOW MANY militia he/she creates per session. + gGameExternalOptions.fLeadershipAffectsMilitiaQuantity = iniReader.ReadBoolean("Militia Training Settings","LEADERSHIP_AFFECTS_MILITIA_QUANTITY", FALSE); + + // HEADROCK HAM 3: If "LEADERSHIP_AFFECTS_MILITIA_QUANTITY" is true, this value determines the lowest leadership required to train a full (default size 10) squad of town militia in one training session. + gGameExternalOptions.ubReqLeadershipForFullTraining = iniReader.ReadInteger("Militia Training Settings","REQ_LEADERSHIP_FOR_MAX_MILITIA", 100, 1, 100); + + // HEADROCK HAM 3: Define effect of "TEACHER" trait in increasing effective leadership, for purposes of eligibility for training militia. This is a percentage value. HAM Default would be 200 = double effective leadership for each TEACHING level. + gGameExternalOptions.usTeacherTraitEffectOnLeadership = iniReader.ReadInteger("Militia Training Settings","TEACHER_TRAIT_EFFECT_ON_LEADERSHIP", 100, 1, 10000); + + + //################# Mobile Militia Training Settings ################## + + gGameExternalOptions.gfAllowMilitiaGroups = iniReader.ReadBoolean("Mobile Militia Training Settings","ALLOW_MOBILE_MILITIA",FALSE); + gGameExternalOptions.guiAllowMilitiaGroupsDelay = iniReader.ReadInteger("Mobile Militia Training Settings","MOBILE_MILITIA_TRAINING_DELAY",1, 0, 30); + + gGameExternalOptions.guiNumMobileMilitiaTrained = iniReader.ReadInteger("Mobile Militia Training Settings","NUM_MOBILE_MILITIA_TRAINED_PER_SESSION",4, 1, 100); + + gGameExternalOptions.gfmusttrainroaming = iniReader.ReadBoolean("Mobile Militia Training Settings","MUST_TRAIN_MOBILE_MILITIA",FALSE); + + gGameExternalOptions.guiCreateEachNHours = iniReader.ReadInteger("Mobile Militia Training Settings","CREATE_MOBILE_MILITIA_SQUAD_EACH_N_HOURS",24, 1, 96); + + // HEADROCK HAM 3.3: New militia feature, Minimum Leadership required to train Roaming Militia + gGameExternalOptions.ubMinimumLeadershipToTrainMobileMilitia = iniReader.ReadInteger("Mobile Militia Training Settings","MIN_LEADERSHIP_TO_TRAIN_MOBILE_MILITIA", 0, 0, 100); + + // HEADROCK HAM 3.3: If enabled, the trainer's "effective" leadership skill determines HOW MANY Mobile Militia he/she creates per session. + gGameExternalOptions.fLeadershipAffectsMobileMilitiaQuantity = iniReader.ReadBoolean("Mobile Militia Training Settings","LEADERSHIP_AFFECTS_MOBILE_MILITIA_QUANTITY", FALSE); + + // HEADROCK HAM 3.3: If "LEADERSHIP_AFFECTS_MILITIA_QUANTITY" is true, this value determines the lowest leadership required to train a full (default size 5) squad of Mobile Militia in one training session. + gGameExternalOptions.ubReqLeadershipForFullMobileTraining = iniReader.ReadInteger("Mobile Militia Training Settings","REQ_LEADERSHIP_FOR_MAX_MOBILE_MILITIA", 1, 1, 100); + + // HEADROCK HAM 3.5: Does leadership affect the Quality of new Mobile Militia groups? + gGameExternalOptions.fLeadershipAffectsMobileMilitiaQuality = iniReader.ReadBoolean("Mobile Militia Training Settings","LEADERSHIP_AFFECTS_MOBILE_MILITIA_QUALITY", FALSE); + + // HEADROCK HAM 3.4: What percentage of a new Mobile Militia group will be made of Elites? If >0, then at least one of every new group will be an Elite. 100 = All Elites. + gGameExternalOptions.ubPercentRoamingMilitiaElites = iniReader.ReadInteger("Mobile Militia Training Settings","PERCENT_MOBILE_MILITIA_ELITES", 100, 0, 100); + + // HEADROCK HAM 3.4: What percentage of a new Mobile Militia group will be made of Regulars? If >0, then at least one of every new group will be a Regular. 100 = All Regulars. + gGameExternalOptions.ubPercentRoamingMilitiaRegulars = iniReader.ReadInteger("Mobile Militia Training Settings","PERCENT_MOBILE_MILITIA_REGULARS", 0, 0, 100); + + + //################# Mobile Militia Movement Settings ################## + + gGameExternalOptions.gflimitedRoaming = iniReader.ReadBoolean("Mobile Militia Movement Settings","RESTRICT_ROAMING",FALSE); + + // HEADROCK HAM B1: Allow restricted militia to move through visited sectors? + gGameExternalOptions.fUnrestrictVisited = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MILITIA_MOVEMENT_THROUGH_EXPLORED_SECTORS", FALSE); + + // HEADROCK HAM B1: Allow dynamic restrictions? + gGameExternalOptions.fDynamicRestrictRoaming = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_DYNAMIC_RESTRICTED_ROAMING", TRUE); + + // HEADROCK HAM B2.7: Augmented Roaming Militia code - turn this to TRUE to allow militia free travel through San Mona, Tixa, Orta, Omerta, and Estoni. + gGameExternalOptions.fAllowMilitiaMoveThroughMinorCities = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MILITIA_MOVEMENT_THROUGH_MINOR_CITIES", FALSE); + + // HEADROCK HAM 3.3: If enabled, Roaming Militia can automatically reinforce city garrisons. + gGameExternalOptions.fAllowMobileReinforceCities = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MOBILE_MILITIA_REINFORCE_TOWN_GARRISONS", FALSE); + + // HEADROCK HAM 3.3: If enabled, Roaming Militia can automatically reinforce city garrisons. + gGameExternalOptions.fAllowMobileReinforceSAM = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MOBILE_MILITIA_REINFORCE_SAM_GARRISONS", FALSE); + + + //################# Shopkeeper Inventory Settings ################## + + // WDS - Improve Tony's and Devin's inventory like BR's + gGameExternalOptions.tonyUsesBRSetting = iniReader.ReadBoolean("Shopkeeper Inventory Settings","TONY_USES_BOBBY_RAYS_SETTING", FALSE); + gGameExternalOptions.devinUsesBRSetting = iniReader.ReadBoolean("Shopkeeper Inventory Settings","DEVIN_USES_BOBBY_RAYS_SETTING", FALSE); + + + //################# Strategic Assignment Settings ################## + + ////////// ALL ASSIGNMENTS ////////// + + gGameExternalOptions.ubMinutesForAssignmentToCount = iniReader.ReadInteger("Strategic Assignment Settings","MINUTES_FOR_ASSIGNMENT_TO_COUNT",45, 1, NUM_MIN_IN_DAY); + + ////////// PRACTICE/TRAIN/STUDY ////////// + + gGameExternalOptions.ubTrainingSkillMin = iniReader.ReadInteger("Strategic Assignment Settings","MIN_REQUIRED_SKILL_TO_BEGIN_TRAINING",0, 0, 100); + gGameExternalOptions.ubTrainingSkillMax = iniReader.ReadInteger("Strategic Assignment Settings","MAX_SKILL_ACHIEVABLE_BY_TRAINING",100, 0, 100); + gGameExternalOptions.ubSelfTrainingDivisor = iniReader.ReadInteger("Strategic Assignment Settings","TRAINING_RATE_DIVISOR",1000, 1, 10000); + gGameExternalOptions.ubInstructedTrainingDivisor = iniReader.ReadInteger("Strategic Assignment Settings","INSTRUCTED_TRAINING_BONUS_DIVISOR",3000, 1, 10000); + + gGameExternalOptions.ubTeachBonusToTrain = iniReader.ReadInteger("Strategic Assignment Settings","TEACHER_TRAIT_BONUS_TO_TEACHING_EFFICIENCY",30, 0, 100); + gGameExternalOptions.ubMinSkillToTeach = iniReader.ReadInteger("Strategic Assignment Settings","MIN_SKILL_REQUIRED_TO_TEACH_OTHER",25, 0, 100); + + // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainees will go to sleep when their trainer goes to sleep. 3 = Trainer will go to sleep if all trainees are asleep. 1 = Both. 0 = Neither. + gGameExternalOptions.ubSmartTrainingSleep = iniReader.ReadInteger("Strategic Assignment Settings","SYNCHRONIZED_SLEEPING_HOURS_WHEN_TRAINING_TOGETHER", 0, 0, 3); + + // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainees will wake up when their trainer wakes up. 3 = Trainer will wake up if all trainees wake up. 1 = Both. 0 = Neither. + gGameExternalOptions.ubSmartTrainingWake = iniReader.ReadInteger("Strategic Assignment Settings","SYNCHRONIZED_WAKING_HOURS_WHEN_TRAINING_TOGETHER", 0, 0, 3); + + // HEADROCK HAM B2.8: New Trainer Relations: 2 = Trainers will rest if no trainees available. 3 = Trainees will rest if no trainers available (not recommended). 1 = Both. 0 = Neither. + gGameExternalOptions.ubSmartTrainingRest = iniReader.ReadInteger("Strategic Assignment Settings","REST_IF_NO_TRAINING_PARTNER_AVAILABLE", 0, 0, 3); + + ////////// DOCTOR ////////// + + gGameExternalOptions.ubLowActivityLevel = iniReader.ReadInteger("Strategic Assignment Settings","NATURAL_HEALING_SPEED_DIVISOR_AT_LOW_ACTIVITY_LEVEL",1, 1, 100); + gGameExternalOptions.ubMediumActivityLevel = iniReader.ReadInteger("Strategic Assignment Settings","NATURAL_HEALING_SPEED_DIVISOR_AT_MEDIUM_ACTIVITY_LEVEL",4, 1, 100); + gGameExternalOptions.ubHighActivityLevel = iniReader.ReadInteger("Strategic Assignment Settings","NATURAL_HEALING_SPEED_DIVISOR_AT_HIGH_ACTIVITY_LEVEL",12, 1, 100); + + gGameExternalOptions.ubDoctoringRateDivisor = iniReader.ReadInteger("Strategic Assignment Settings","DOCTORING_RATE_DIVISOR",2400, 1200, 24000); + gGameExternalOptions.ubHospitalHealingRate = iniReader.ReadInteger("Strategic Assignment Settings","HOSPITAL_HEALING_RATE",5, 1, 10); + gGameExternalOptions.ubBaseMedicalSkillToDealWithEmergency = iniReader.ReadInteger("Strategic Assignment Settings","BASE_MEDICAL_SKILL_TO_DEAL_WITH_EMERGENCY",20, 0, 100); + gGameExternalOptions.ubMultiplierForDifferenceInLifeValueForEmergency = iniReader.ReadInteger("Strategic Assignment Settings","MULTIPLIER_FOR_DIFFERENCE_IN_LIFE_VALUE_FOR_EMERGENCY",4, 1, 10); + gGameExternalOptions.ubPointCostPerHealthBelowOkLife = iniReader.ReadInteger("Strategic Assignment Settings","POINT_COST_PER_HEALTH_BELOW_OKLIFE",2, 1, 5);//OKLIFE = 15 + + ////////// REPAIR ////////// + + gGameExternalOptions.ubRepairCostPerJam = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_POINT_COST_TO_FIX_WEAPON_JAM",2, 1, 10); + gGameExternalOptions.ubRepairRateDivisor = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_RATE_DIVISOR",2500, 1250, 25000); + gGameExternalOptions.ubAssignmentUnitsPerDay = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_SESSIONS_PER_DAY",24, 1, 96); // WANNE: This is just a debug setting. Only in debug version we should check if propert is set in the ja2_options.ini, // In Release version this should always be set to FALSE //dnl ch51 081009 JA2 Debug Settings #ifdef _DEBUG - gGameExternalOptions.fEnableInventoryPoolQ = iniReader.ReadBoolean("JA2 Debug Settings", "ENABLE_INVENTORY_POOL_Q", FALSE); -#endif + gGameExternalOptions.fEnableInventoryPoolQ = TRUE; +#else gGameExternalOptions.fEnableInventoryPoolQ = FALSE; +#endif } INT16 DynamicAdjustAPConstants(INT16 iniReadValue, INT16 iniDefaultValue, BOOLEAN reverse) diff --git a/GameSettings.h b/GameSettings.h index 79d88d3c..30a4bdb2 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -54,9 +54,9 @@ enum TOPTION_SILENT_SKYRIDER, TOPTION_LOW_CPU_USAGE, TOPTION_ENHANCED_DESC_BOX, - + // arynn - TOPTION_TOGGLE_TURN_MODE, + TOPTION_TOGGLE_TURN_MODE, // HEADROCK HAM 3.6: TOPTION_STAT_PROGRESS_BARS, @@ -85,7 +85,6 @@ enum TOPTION_HIDE_BULLETS, TOPTION_TRACKING_MODE, - NUM_ALL_GAME_OPTIONS, }; @@ -252,11 +251,11 @@ typedef struct BOOLEAN gfVSync; //Animation settings - UINT32 gubPlayerTurnSpeedUpFactor; - UINT32 gubEnemyTurnSpeedUpFactor; - UINT32 gubCreatureTurnSpeedUpFactor; - UINT32 gubMilitiaTurnSpeedUpFactor; - UINT32 gubCivilianTurnSpeedUpFactor; + FLOAT giPlayerTurnSpeedUpFactor; + FLOAT giEnemyTurnSpeedUpFactor; + FLOAT giCreatureTurnSpeedUpFactor; + FLOAT giMilitiaTurnSpeedUpFactor; + FLOAT giCivilianTurnSpeedUpFactor; //Sound settings UINT32 guiWeaponSoundEffectsVolume; @@ -280,7 +279,7 @@ typedef struct UINT32 guiAllowMilitiaGroupsDelay; UINT32 guiTrainVeteranMilitiaDelay; UINT32 guiCreateEachNHours; - UINT32 guiDivOfOriginalMilitia; + UINT32 guiNumMobileMilitiaTrained; // HEADROCK HAM 3.6: These settings are REDUNDANT. //UINT32 guiMinMilitiaSquadSize; //UINT32 guiMaxMilitiaSquadSize; @@ -334,7 +333,7 @@ typedef struct UINT32 ubGameProgressPortionIncome; UINT32 ubGameProgressPortionVisited; UINT32 ubGameProgressMinimum; - UINT32 ubGameProgressIncrement; + INT32 bGameProgressModifier; // WDS - Advanced start //UINT32 ubIMPStartingLevel; // removed - SANDRO @@ -356,9 +355,9 @@ typedef struct //Gameplay settings - UINT32 ubExplosivesDamageMultiplier; - UINT32 ubGunDamageMultiplier; - UINT32 ubMeleeDamageMultiplier; + INT32 iExplosivesDamageModifier; + INT32 iGunDamageModifier; + INT32 iMeleeDamageModifier; UINT32 ubEasyEnemyStartingAlertLevel; UINT32 ubNormalEnemyStartingAlertLevel; @@ -513,7 +512,7 @@ BOOLEAN gbBulletTracer; INT32 iEnhancedDescriptionBox; // WANNE: Always use "prof.dat". - BOOLEAN fAlwaysUseProfDat; + BOOLEAN fUseDifficultyBasedProfDat; // CPT: Cover System Settings UINT8 ubStealthTraitCoverValue; @@ -556,7 +555,7 @@ BOOLEAN gbBulletTracer; UINT8 ubAimPenaltyPerTargetShock; // HEADROCK HAM B2.3: It is now possible for "cowering" to increase a target's suppression. - UINT16 usCowerEffectOnSuppression; + UINT8 ubCowerEffectOnSuppression; // HEADROCK HAM B2.5: Turn on Realistic Tracers. 0 = off (regular tracers). 1 = Fully realistic tracers. 2 = Tracer Bump + 1.13 Autofire Penalty Reduction UINT8 ubRealisticTracers; @@ -668,11 +667,8 @@ BOOLEAN gbBulletTracer; // HEADROCK HAM 3.1: This is a suppression tool that not everyone will like. It gives an on-screen message when any character has been suppressed so much he's lost his next turn completely! BOOLEAN fShowSuppressionShutdown; - // HEADROCK HAM 3.1: Set whether you'd like to determine yourself which mine (if any) will shut down during the campaign. - BOOLEAN fManuallySelectMineShutdown; - - // HEADROCK HAM 3.1: Select which mine will run out. 0 = no mine. 1 = San Mona (unused), 2 = Drassen, 3 = Alma, 4 = Cambria, 5 = Chitzena, 6 = Grumm. - UINT8 ubWhichMineRunsOut; + // HEADROCK HAM 3.1: Select which mine will run out. -1 = Random selection. 0 = no mine. 1 = San Mona (unused), 2 = Drassen, 3 = Alma, 4 = Cambria, 5 = Chitzena, 6 = Grumm. + INT8 bWhichMineRunsOut; // HEADROCK HAM 3.1: Can the Humvee go off-road? BOOLEAN fHumveeOffroad; diff --git a/GameVersion.cpp b/GameVersion.cpp index 5f10b973..ed7a997d 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -13,12 +13,12 @@ #ifdef JA2EDITOR //MAP EDITOR BUILD VERSION -CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.3342" }; +CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.3353" }; #elif defined JA2BETAVERSION //BETA/TEST BUILD VERSION -CHAR16 zVersionLabel[256] = { L"Debug v1.13.3342" }; +CHAR16 zVersionLabel[256] = { L"Debug v1.13.3353" }; #elif defined CRIPPLED_VERSION @@ -28,11 +28,11 @@ CHAR16 zVersionLabel[256] = { L"Beta v. 0.98" }; #else //RELEASE BUILD VERSION - CHAR16 zVersionLabel[256] = { L"Release v1.13.3342" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.3353" }; #endif -CHAR8 czVersionNumber[16] = { "Build 10.03.01" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 10.03.07" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; diff --git a/Laptop/BobbyRGuns.cpp b/Laptop/BobbyRGuns.cpp index 10ce45c1..4858231a 100644 --- a/Laptop/BobbyRGuns.cpp +++ b/Laptop/BobbyRGuns.cpp @@ -1901,11 +1901,15 @@ UINT16 DisplayDamage(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight) if ( Item[ usIndex ].usItemClass == IC_GUN || Item[ usIndex ].usItemClass == IC_LAUNCHER ) { - gunDamage = (UINT16)( Weapon[ usIndex ].ubImpact + ( (double) Weapon[ usIndex ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); + // HEADROCK HAM 3.6: Can now take a negative modifier + gunDamage = (UINT16)GetModifiedGunDamage( Weapon[ usIndex ].ubImpact ); + //gunDamage = (UINT16)( Weapon[ usIndex ].ubImpact + ( (double) Weapon[ usIndex ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); } else { - gunDamage = (UINT16)( Weapon[ usIndex ].ubImpact + ( (double) Weapon[ usIndex ].ubImpact / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ); + // HEADROCK HAM 3.6: Can now take a negative modifier + gunDamage = (UINT16)GetModifiedMeleeDamage( Weapon[ usIndex ].ubImpact ); + //gunDamage = (UINT16)( Weapon[ usIndex ].ubImpact + ( (double) Weapon[ usIndex ].ubImpact / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ); } DrawTextToScreen(BobbyRText[BOBBYR_GUNS_DAMAGE], BOBBYR_ITEM_WEIGHT_TEXT_X, (UINT16)usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED); @@ -2409,7 +2413,9 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum //Info for weapons //if ( Item[ pItemNumbers[ i ] ].usItemClass == IC_GUN ) { - UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); + // HEADROCK HAM 3.6: Can now take a negative modifier. + //UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); + UINT16 gunDamage = (UINT16)GetModifiedGunDamage( Weapon[ pItemNumbers[ i ] ].ubImpact ); UINT16 readyAPs = (UINT16)(( Weapon[ pItemNumbers[ i ] ].ubReadyTime * (100 - Item[ pItemNumbers[ i ] ].percentreadytimeapreduction)) / 100); //Calculate AP's @@ -2563,7 +2569,9 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum //Info for weapons //if ( Item[ pItemNumbers[ i ] ].usItemClass == IC_GUN ) { - UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); + // HEADROCK HAM 3.6: Can now take a negative modifier. + UINT16 gunDamage = (UINT16)GetModifiedGunDamage( Weapon[ pItemNumbers[ i ] ].ubImpact ); + //UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier ); swprintf( pStr, L"%s\n%s %d\n%s %d\n%s %d\n%s %s\n%s %1.1f %s", ItemNames[ pItemNumbers[ i ] ], @@ -2587,7 +2595,9 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum case IC_THROWING_KNIFE: case IC_PUNCH: { - UINT16 meleeDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ); + // HEADROCK HAM 3.6: Can now take a negative modifier + //UINT16 meleeDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ); + UINT16 meleeDamage = (UINT16)GetModifiedMeleeDamage( Weapon[ pItemNumbers[ i ] ].ubImpact ); swprintf( pStr, L"%s\n%s %d\n%s %s\n%s %1.1f %s", ItemNames[ pItemNumbers[ i ] ], @@ -2640,8 +2650,12 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum // explosives //if ( (Item[ pItemNumbers[ i ] ].usItemClass == IC_GRENADE)||(Item[ pItemNumbers[ i ] ].usItemClass == IC_BOMB) ) { - UINT16 explDamage = (UINT16)( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubDamage + ( (double) Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); - UINT16 explStunDamage = (UINT16)( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubStunDamage + ( (double) Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubStunDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); + // HEADROCK HAM 3.6: Can now use negative modifier. + //UINT16 explDamage = (UINT16)( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubDamage + ( (double) Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubDamage / 100) * gGameExternalOptions.bExplosivesDamageModifier ); + //UINT16 explStunDamage = (UINT16)( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubStunDamage + ( (double) Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubStunDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); + UINT16 explDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubDamage ); + UINT16 explStunDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ pItemNumbers[ i ] ].ubClassIndex].ubStunDamage ); + swprintf( pStr, L"%s\n%s %d\n%s %d\n%s %1.1f %s", ItemNames[ pItemNumbers[ i ] ], diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 8f5baf2c..1bf18042 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -14828,7 +14828,8 @@ void CreateDestroyMouseRegionsForFacilityAssignmentMenu( void ) } if (!fFoundVehicle) { - uiMenuLine++; // Skip this line, it'll always be shaded anyway. + // WANNE: This is a fix by Headrock + //uiMenuLine++; // Skip this line, it'll always be shaded anyway. } } else if ( iCounter == FAC_REPAIR_ROBOT ) @@ -15032,21 +15033,21 @@ void FacilityAssignmentMenuBtnCallback ( MOUSE_REGION * pRegion, INT32 iReason ) break; case FAC_REPAIR_ITEMS: MakeSureToolKitIsInHand( pSoldier ); + ChangeSoldiersAssignment( pSoldier, REPAIR ); pSoldier->flags.fFixingRobot = FALSE; pSoldier->bVehicleUnderRepairID = -1; - ChangeSoldiersAssignment( pSoldier, REPAIR ); break; case FAC_REPAIR_VEHICLE: MakeSureToolKitIsInHand( pSoldier ); + ChangeSoldiersAssignment( pSoldier, REPAIR ); pSoldier->flags.fFixingRobot = FALSE; pSoldier->bVehicleUnderRepairID = (INT8)ubVehicleID; - ChangeSoldiersAssignment( pSoldier, REPAIR ); break; case FAC_REPAIR_ROBOT: MakeSureToolKitIsInHand( pSoldier ); + ChangeSoldiersAssignment( pSoldier, REPAIR ); pSoldier->flags.fFixingRobot = TRUE; pSoldier->bVehicleUnderRepairID = -1; - ChangeSoldiersAssignment( pSoldier, REPAIR ); break; case FAC_DOCTOR: MakeSureMedKitIsInHand( pSoldier ); diff --git a/Strategic/Campaign Init.cpp b/Strategic/Campaign Init.cpp index 64894ef6..872fcbfb 100644 --- a/Strategic/Campaign Init.cpp +++ b/Strategic/Campaign Init.cpp @@ -23,6 +23,8 @@ #include "VFS/vfs.h" #include "XMLWriter.h" +#include "UndergroundInit.h" + extern BOOLEAN InitStrategicMovementCosts(); void InitKnowFacilitiesFlags( ); @@ -432,6 +434,15 @@ void BuildUndergroundSectorInfoList() TrashUndergroundSectorInfo(); + if (LetLuaBuildUndergroundSectorInfoList()) + // lua script succeeded + return; + + // If lua script had any errors + // reset whatever the script may have done + // and use hardcoded underground initialization. + TrashUndergroundSectorInfo(); + //******************** //* BASEMENT LEVEL 1 * //******************** @@ -476,7 +487,6 @@ void BuildUndergroundSectorInfoList() curr = NewUndergroundNode( 3, 15, 1 ); curr->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel*2 + Random( 3 )); curr->ubNumElites = (UINT8)(4 + gGameOptions.ubDifficultyLevel + Random( 2 )); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; //P3 curr = NewUndergroundNode( 3, 16, 1 ); @@ -495,99 +505,97 @@ void BuildUndergroundSectorInfoList() curr->ubNumElites = 20; break; } - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; //Do all of the mandatory underground mine sectors //Drassen's mine //D13_B1 curr = NewUndergroundNode( 13, 4, 1 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //E13_B1 curr = NewUndergroundNode( 13, 5, 1 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //E13_B2 curr = NewUndergroundNode( 13, 5, 2 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //F13_B2 curr = NewUndergroundNode( 13, 6, 2 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR | SOUTH_ADJACENT_SECTOR; + //G13_B2 curr = NewUndergroundNode( 13, 7, 2 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //G13_B3 curr = NewUndergroundNode( 13, 7, 3 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //F13_B3 curr = NewUndergroundNode( 13, 6, 3 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //Cambria's mine //H8_B1 curr = NewUndergroundNode( 8, 8, 1 ); - curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR; + //H9_B1 curr = NewUndergroundNode( 9, 8, 1 ); - curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR; + //H9_B2 curr = NewUndergroundNode( 9, 8, 2 ); - curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR; + //H8_B2 curr = NewUndergroundNode( 8, 8, 2 ); - curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR; + //H8_B3 curr = NewUndergroundNode( 8, 8, 3 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //I8_B3 curr = NewUndergroundNode( 8, 9, 3 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR | SOUTH_ADJACENT_SECTOR; + //J8_B3 curr = NewUndergroundNode( 8, 10, 3 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //Alma's mine //I14_B1 curr = NewUndergroundNode( 14, 9, 1 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //J14_B1 curr = NewUndergroundNode( 14, 10, 1 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //J14_B2 curr = NewUndergroundNode( 14, 10, 2 ); - curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR; + //J13_B2 curr = NewUndergroundNode( 13, 10, 2 ); - curr->ubAdjacentSectors |= EAST_ADJACENT_SECTOR; + //J13_B3 curr = NewUndergroundNode( 13, 10, 3 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //K13_B3 curr = NewUndergroundNode( 13, 11, 3 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //Grumm's mine //H3_B1 curr = NewUndergroundNode( 3, 8, 1 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; + //I3_B1 curr = NewUndergroundNode( 3, 9, 1 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //I3_B2 curr = NewUndergroundNode( 3, 9, 2 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //H3_B2 curr = NewUndergroundNode( 3, 8, 2 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR | EAST_ADJACENT_SECTOR; + //H4_B2 curr = NewUndergroundNode( 4, 8, 2 ); - curr->ubAdjacentSectors |= WEST_ADJACENT_SECTOR; curr->uiFlags |= SF_PENDING_ALTERNATE_MAP; + //H4_B3 curr = NewUndergroundNode( 4, 8, 3 ); - curr->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; + //G4_B3 curr = NewUndergroundNode( 4, 7, 3 ); - curr->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; } // Lesh: this function creates randomized world diff --git a/Strategic/Campaign Types.h b/Strategic/Campaign Types.h index 8783dd56..6e21924d 100644 --- a/Strategic/Campaign Types.h +++ b/Strategic/Campaign Types.h @@ -475,7 +475,8 @@ typedef struct UNDERGROUND_SECTORINFO //a sector. UINT32 uiTimeCurrentSectorWasLastLoaded; //Specifies the last time the player was in the sector struct UNDERGROUND_SECTORINFO *next; - UINT8 ubAdjacentSectors; //mask containing which sectors are adjacent + + UINT8 ubNumBloodcats; // Bloodcat population UINT8 ubCreatureHabitat; //determines how creatures live in this sector (see creature spreading.c) UINT8 ubElitesInBattle, ubTroopsInBattle, ubAdminsInBattle, ubCreaturesInBattle; diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 4538c7cb..5cfc87cb 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -3871,49 +3871,6 @@ BOOLEAN IsTheCursorAllowedToHighLightThisSector( INT16 sSectorX, INT16 sSectorY } } -void SetUpBadSectorsList( void ) -{ - // initalizes all sectors to highlighable and then the ones non highlightable are marked as such - INT8 bY; - - memset( &sBadSectorsList, 0, sizeof( sBadSectorsList ) ); - - // the border regions - for( bY = 0; bY < WORLD_MAP_X; bY++ ) - { - sBadSectorsList[ 0 ][ bY ] = sBadSectorsList[ WORLD_MAP_X - 1 ][ bY ] = sBadSectorsList[ bY ][ 0 ] = sBadSectorsList[ bY ][ WORLD_MAP_X - 1 ] = TRUE; - } - - - sBadSectorsList[ 4 ][ 1 ] = TRUE; - sBadSectorsList[ 5 ][ 1 ] = TRUE; - sBadSectorsList[ 16 ][ 1 ] = TRUE; - sBadSectorsList[ 16 ][ 5 ] = TRUE; - sBadSectorsList[ 16 ][ 6 ] = TRUE; - - - sBadSectorsList[ 16 ][ 10 ] = TRUE; - sBadSectorsList[ 16 ][ 11 ] = TRUE; - sBadSectorsList[ 16 ][ 12 ] = TRUE; - sBadSectorsList[ 16 ][ 13 ] = TRUE; - sBadSectorsList[ 16 ][ 14 ] = TRUE; - sBadSectorsList[ 16 ][ 15 ] = TRUE; - sBadSectorsList[ 16 ][ 16 ] = TRUE; - - sBadSectorsList[ 15 ][ 13 ] = TRUE; - sBadSectorsList[ 15 ][ 14 ] = TRUE; - sBadSectorsList[ 15 ][ 15 ] = TRUE; - sBadSectorsList[ 15 ][ 16 ] = TRUE; - - sBadSectorsList[ 14 ][ 14 ] = TRUE; - sBadSectorsList[ 14 ][ 15 ] = TRUE; - sBadSectorsList[ 14 ][ 16 ] = TRUE; - - sBadSectorsList[ 13 ][ 14 ] = TRUE; - return; -} - - void RestoreBackgroundForMapGrid( INT16 sMapX, INT16 sMapY ) { diff --git a/Strategic/MilitiaSquads.cpp b/Strategic/MilitiaSquads.cpp index eafdc9ff..807f7029 100644 --- a/Strategic/MilitiaSquads.cpp +++ b/Strategic/MilitiaSquads.cpp @@ -167,7 +167,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, // Upgrade points for replacing militia with better ones. UINT8 ubUpgradePoints; // Calculate default number of militia to place in Target Sector. - UINT8 ubMilitiaToTrain = gGameExternalOptions.iMaxMilitiaPerSector / gGameExternalOptions.guiDivOfOriginalMilitia; + UINT8 ubMilitiaToTrain = gGameExternalOptions.guiNumMobileMilitiaTrained; // Percentage of troops that should be of any one type: UINT8 ubTargetElitePercent = 0; UINT8 ubTargetRegularPercent = 0; diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index 792c6911..e7ca1b2c 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -1224,40 +1224,48 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier ) } break; case SOLDIER_CLASS_CREATURE: - #ifdef JA2BETAVERSION - if( ubTotalEnemies <= (UINT32)iMaxEnemyGroupSize && pSector->ubNumCreatures != pSector->ubCreaturesInBattle || - !pSector->ubNumCreatures || !pSector->ubCreaturesInBattle || - pSector->ubNumCreatures > gGameExternalOptions.ubGameMaximumNumberOfCreatures || pSector->ubCreaturesInBattle > gGameExternalOptions.ubGameMaximumNumberOfCreatures ) + if (pSoldier->ubBodyType == BLOODCAT) { - DoScreenIndependantMessageBox( L"Underground sector creature counters are bad. What were the last 2-3 things to die, and how? Save game and send to KM with info!!!", MSG_BOX_FLAG_OK, NULL ); + if( pSector->ubNumBloodcats > 0 ) + pSector->ubNumBloodcats--; } - #endif - if( pSector->ubNumCreatures ) + else { - pSector->ubNumCreatures--; - } - if( pSector->ubCreaturesInBattle ) - { - pSector->ubCreaturesInBattle--; - } + #ifdef JA2BETAVERSION + if( ubTotalEnemies <= (UINT32)iMaxEnemyGroupSize && pSector->ubNumCreatures != pSector->ubCreaturesInBattle || + !pSector->ubNumCreatures || !pSector->ubCreaturesInBattle || + pSector->ubNumCreatures > gGameExternalOptions.ubGameMaximumNumberOfCreatures || pSector->ubCreaturesInBattle > gGameExternalOptions.ubGameMaximumNumberOfCreatures ) + { + DoScreenIndependantMessageBox( L"Underground sector creature counters are bad. What were the last 2-3 things to die, and how? Save game and send to KM with info!!!", MSG_BOX_FLAG_OK, NULL ); + } + #endif + if( pSector->ubNumCreatures ) + { + pSector->ubNumCreatures--; + } + if( pSector->ubCreaturesInBattle ) + { + pSector->ubCreaturesInBattle--; + } - if( !pSector->ubNumCreatures && gWorldSectorX != 9 && gWorldSectorY != 10 ) - { //If the player has successfully killed all creatures in ANY underground sector except J9 - //then cancel any pending creature town attack. - DeleteAllStrategicEventsOfType( EVENT_CREATURE_ATTACK ); - } + if( !pSector->ubNumCreatures && gWorldSectorX != 9 && gWorldSectorY != 10 ) + { //If the player has successfully killed all creatures in ANY underground sector except J9 + //then cancel any pending creature town attack. + DeleteAllStrategicEventsOfType( EVENT_CREATURE_ATTACK ); + } - // a monster has died. Post an event to immediately check whether a mine has been cleared. - AddStrategicEventUsingSeconds( EVENT_CHECK_IF_MINE_CLEARED, GetWorldTotalSeconds() + 15, 0); + // a monster has died. Post an event to immediately check whether a mine has been cleared. + AddStrategicEventUsingSeconds( EVENT_CHECK_IF_MINE_CLEARED, GetWorldTotalSeconds() + 15, 0); - if( pSoldier->ubBodyType == QUEENMONSTER ) - { - //Need to call this, as the queen is really big, and killing her leaves a bunch - //of bad tiles in behind her. Calling this function cleans it up. - InvalidateWorldRedundency(); - //Now that the queen is dead, turn off the creature quest. - EndCreatureQuest(); - EndQuest( QUEST_CREATURES, gWorldSectorX, gWorldSectorY ); + if( pSoldier->ubBodyType == QUEENMONSTER ) + { + //Need to call this, as the queen is really big, and killing her leaves a bunch + //of bad tiles in behind her. Calling this function cleans it up. + InvalidateWorldRedundency(); + //Now that the queen is dead, turn off the creature quest. + EndCreatureQuest(); + EndQuest( QUEST_CREATURES, gWorldSectorX, gWorldSectorY ); + } } break; } diff --git a/Strategic/Strategic AI.cpp b/Strategic/Strategic AI.cpp index 9f715ef5..85624224 100644 --- a/Strategic/Strategic AI.cpp +++ b/Strategic/Strategic AI.cpp @@ -3673,20 +3673,6 @@ BOOLEAN LoadStrategicAI( HWFILE hFile ) pSector->ubNumTroops -= 2; } } - if( ubSAIVersion < 16 ) - { - UNDERGROUND_SECTORINFO *pSector; - pSector = FindUnderGroundSector( 3, 15, 1 ); - if( pSector ) - { - pSector->ubAdjacentSectors |= SOUTH_ADJACENT_SECTOR; - } - pSector = FindUnderGroundSector( 3, 16, 1 ); - if( pSector ) - { - pSector->ubAdjacentSectors |= NORTH_ADJACENT_SECTOR; - } - } if( ubSAIVersion < 17 ) { //Patch all groups that have this flag set gubNumGroupsArrivedSimultaneously = 0; diff --git a/Strategic/Strategic Mines.cpp b/Strategic/Strategic Mines.cpp index 0504fcf3..86a146a5 100644 --- a/Strategic/Strategic Mines.cpp +++ b/Strategic/Strategic Mines.cpp @@ -204,17 +204,14 @@ void InitializeMines( void ) } while (gMineStatus[ubDepletedMineIndex].fEmpty || (ubDepletedMineIndex == MINE_ALMA)); // HEADROCK HAM 3.1: We can now select which mine runs out, or disable mine shutdown. - if (gGameExternalOptions.fManuallySelectMineShutdown) + // Make sure selection isn't 0 (no mine runs out) or invalid (San Mona, Alma) + if (gGameExternalOptions.bWhichMineRunsOut > 0 && + gGameExternalOptions.bWhichMineRunsOut < MAX_NUMBER_OF_MINES && + gGameExternalOptions.bWhichMineRunsOut-1 != MINE_SAN_MONA && + gGameExternalOptions.bWhichMineRunsOut-1 != MINE_ALMA ) { - // Make sure selection isn't 0 (no mine runs out) or invalid (San Mona, Alma) - if (gGameExternalOptions.ubWhichMineRunsOut > 0 && - gGameExternalOptions.ubWhichMineRunsOut < MAX_NUMBER_OF_MINES && - gGameExternalOptions.ubWhichMineRunsOut-1 != MINE_SAN_MONA && - gGameExternalOptions.ubWhichMineRunsOut-1 != MINE_ALMA ) - { - // Set depleted mine index. - ubDepletedMineIndex = (gGameExternalOptions.ubWhichMineRunsOut-1); - } + // Set depleted mine index. + ubDepletedMineIndex = (gGameExternalOptions.bWhichMineRunsOut-1); } for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ ) @@ -222,8 +219,7 @@ void InitializeMines( void ) pMineStatus = &(gMineStatus[ ubMineIndex ]); // HEADROCK HAM 3.1: We can disable mine shutdown, so make sure the settings aren't telling us to do so. - if (!(gGameExternalOptions.fManuallySelectMineShutdown && gGameExternalOptions.ubWhichMineRunsOut == 0) && - (ubMineIndex == ubDepletedMineIndex)) + if (gGameExternalOptions.bWhichMineRunsOut != 0 && ubMineIndex == ubDepletedMineIndex) { if ( ubDepletedMineIndex == MINE_DRASSEN ) { diff --git a/Strategic/Strategic Movement Costs.cpp b/Strategic/Strategic Movement Costs.cpp index 650cec37..514f69bb 100644 --- a/Strategic/Strategic Movement Costs.cpp +++ b/Strategic/Strategic Movement Costs.cpp @@ -11,6 +11,9 @@ #include "Debug Control.h" #include "Tactical Save.h" #endif +#include "Map Screen Interface Map.h" + +extern BOOLEAN sBadSectorsList[ WORLD_MAP_X ][ WORLD_MAP_X ]; typedef enum { @@ -115,6 +118,11 @@ smctableStartElementHandle(void *userData, const XML_Char *name, const XML_Char pData->maxReadDepth++; //we are not skipping this element //fprintf (outfile, "Entering Traversal Rating\n"); } + else if(strcmp(name, "BadSector") == 0 && pData->curElement == SMCTABLE_ELEMENT_SECTOR) + { + pData->curElement = SMCTABLE_ELEMENT_TRAVELTYPE; + pData->maxReadDepth++; //we are not skipping this element + } pData->szCharData[0] = '\0'; } pData->currentDepth++; @@ -317,6 +325,11 @@ smctableEndElementHandle(void *userData, const XML_Char *name) { pData->travHere = trav_type; } + else if(strcmp(name, "BadSector") == 0) + { + bool fBadSector = atoi(pData->szCharData) > 0; + sBadSectorsList[pData->uiColNumber][pData->uiRowNumber] = fBadSector; + } else { // Bogus Traversal Reference diff --git a/Strategic/Strategic_2005Express.vcproj b/Strategic/Strategic_2005Express.vcproj index f4630d34..fb336436 100644 --- a/Strategic/Strategic_2005Express.vcproj +++ b/Strategic/Strategic_2005Express.vcproj @@ -510,6 +510,10 @@ RelativePath=".\Town Militia.h" > + + + + diff --git a/Strategic/Strategic_VS2008.vcproj b/Strategic/Strategic_VS2008.vcproj index 5ed7befa..5e1a57c6 100644 --- a/Strategic/Strategic_VS2008.vcproj +++ b/Strategic/Strategic_VS2008.vcproj @@ -511,6 +511,10 @@ RelativePath="Town Militia.h" > + + + + diff --git a/Strategic/Town Militia.cpp b/Strategic/Town Militia.cpp index db0a8daf..104fe038 100644 --- a/Strategic/Town Militia.cpp +++ b/Strategic/Town Militia.cpp @@ -1965,7 +1965,7 @@ UINT8 CalcNumMilitiaTrained(UINT8 ubBestLeadership, BOOLEAN fMobile) else { // Default Squad Size for Mobiles, read from INI. - ubMilitiaToTrain = (gGameExternalOptions.iMaxMilitiaPerSector / gGameExternalOptions.guiDivOfOriginalMilitia); + ubMilitiaToTrain = gGameExternalOptions.guiNumMobileMilitiaTrained; // Is affected by Leadership? if (gGameExternalOptions.fLeadershipAffectsMobileMilitiaQuantity && @@ -1993,7 +1993,7 @@ UINT8 CalcNumMilitiaTrained(UINT8 ubBestLeadership, BOOLEAN fMobile) // exceeding the range (latter shouldn't happen) will train a full squad. Others will train less. If // leadership was the minimum required, only 3 militia are trained. ubMilitiaToTrain = ((ubBestLeadership * ubMilitiaToTrain) / ubLeadershipRange) + 1; - ubMilitiaToTrain = __min(ubMilitiaToTrain, gGameExternalOptions.iMaxMilitiaPerSector / gGameExternalOptions.guiDivOfOriginalMilitia); + ubMilitiaToTrain = __min(ubMilitiaToTrain, gGameExternalOptions.guiNumMobileMilitiaTrained); ubMilitiaToTrain = __max(3, ubMilitiaToTrain); } } diff --git a/Strategic/UndergroundInit.cpp b/Strategic/UndergroundInit.cpp new file mode 100644 index 00000000..031f2cd5 --- /dev/null +++ b/Strategic/UndergroundInit.cpp @@ -0,0 +1,161 @@ +#include +#include +#include + +#include "UndergroundInit.h" +#include "Campaign Init.h" +#include "Campaign Types.h" +#include "FileMan.h" +#include "GameSettings.h" + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +} + + +extern UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ); + +static int l_addSector(lua_State *L); +static int lh_getIntegerFromTable(lua_State *L, char * fieldname); +static std::string lh_getStringFromTable(lua_State *L, char * fieldname); +static std::wstring lh_getWStringFromTable(lua_State *L, char * fieldname); +static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z); + +using namespace std; + + +BOOLEAN LetLuaBuildUndergroundSectorInfoList() +{ + char * filename = "scripts\\initunderground.lua"; + UINT32 size, bytesRead; + char* buffer; + + HWFILE file = FileOpen(filename, FILE_ACCESS_READ, FALSE); + + if (!file) + return false; + + size = FileSize(filename); + buffer = new char[size+1]; + buffer[size] = 0; + FileRead(file, buffer, size, &bytesRead); + FileClose(file); + + + lua_State *L = lua_open(); + luaL_openlibs(L); + + lua_register(L, "addSector", l_addSector); + + lua_pushinteger(L, gGameOptions.ubDifficultyLevel); + lua_setglobal(L, "difficultyLevel"); + + lua_pushinteger(L, gGameOptions.ubGameStyle); + lua_setglobal(L, "gameStyle"); + + if (luaL_dostring(L, buffer)) + { + // oh noes, error + // TODO: write to log or something + return false; + } + + lua_close(L); + + delete[] buffer; + + return true; +} + + +static int l_addSector(lua_State *L) +{ + UNDERGROUND_SECTORINFO* curr = NULL; + + std::string sector_id = lh_getStringFromTable(L, "location"); + + UINT8 x, y, z; + if (locationStringToCoordinates(sector_id, &x, &y, &z)) + { + curr = NewUndergroundNode(x, y, z); + + curr->ubNumAdmins = lh_getIntegerFromTable(L, "numAdmins"); + curr->ubNumTroops = lh_getIntegerFromTable(L, "numTroops"); + curr->ubNumElites = lh_getIntegerFromTable(L, "numElites"); + + curr->ubCreatureHabitat = lh_getIntegerFromTable(L, "creatureHabitat"); + curr->ubNumCreatures = lh_getIntegerFromTable(L, "numCreatures"); + + curr->ubNumBloodcats = lh_getIntegerFromTable(L, "numBloodcats"); + } + + return 0; // number of results +} + + +static int lh_getIntegerFromTable(lua_State *L, char * fieldname) +{ + lua_getfield(L, -1, fieldname); + int i = lua_tointeger(L, -1); + lua_pop(L, 1); + return i; +} + + +static std::string lh_getStringFromTable(lua_State *L, char * fieldname) +{ + lua_getfield(L, -1, fieldname); + string s = lua_tostring(L, -1); + lua_pop(L, 1); + return s; +} + + +// extract x,y,z from strings like "D13-1" +static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z) +{ + int length = loc.length(); + + // gather row + if (length < 4 || length > 5) + return false; + + char row = loc[0]; + if (row >= 'A' && row <= 'P') + *y = row - 'A' + 1; + else if (row >= 'a' && row <= 'p') + *y = row - 'a' + 1; + else + return false; + + // gather column + loc = loc.substr(1); + stringstream ss = stringstream(); + if (loc[0] >= '0' && loc[0] <= '9') + { + ss << loc[0]; + loc = loc.substr(1); + } + if (loc[0] >= '0' && loc[0] <= '9') + { + ss << loc[0]; + loc = loc.substr(1); + } + int col; + ss >> col; + if (col >= 1 && col <= 16) + *x = col; + else + return false; + + // gather level + char lvl = loc[loc.length() - 1]; + if (lvl >= '1' && lvl <= '3') + *z = lvl - '0'; + else + return false; + + return true; +} diff --git a/Strategic/UndergroundInit.h b/Strategic/UndergroundInit.h new file mode 100644 index 00000000..b9de6c64 --- /dev/null +++ b/Strategic/UndergroundInit.h @@ -0,0 +1,8 @@ +#ifndef _UNDERGROUNDINIT_H +#define _UNDERGROUNDINIT_H + +#include "Types.h" + +extern BOOLEAN LetLuaBuildUndergroundSectorInfoList(); + +#endif diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index beeadd70..ce0d6946 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -4448,8 +4448,6 @@ UINT32 MapScreenInit(void) { VOBJECT_DESC VObjectDesc; - SetUpBadSectorsList( ); - // setup message box system InitGlobalMessageList( ); diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index 9ea03277..9e88d07f 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -3035,7 +3035,10 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS swprintf( zString, L"P3: %s", pLandTypeStrings[ SHELTER ] ); break; default: - swprintf( zString, L"%c%d: %s", 'A' + sSectorY - 1, sSectorX, pLandTypeStrings[ CREATURE_LAIR ] ); + if (pUnderground->ubNumCreatures) + swprintf( zString, L"%c%d: %s", 'A' + sSectorY - 1, sSectorX, pLandTypeStrings[ CREATURE_LAIR ] ); + else + swprintf( zString, L"%c%d-%d", 'A' + sSectorY - 1, sSectorX, bSectorZ ); break; } } diff --git a/Tactical/Campaign.cpp b/Tactical/Campaign.cpp index cddc2b60..15bbbcd1 100644 --- a/Tactical/Campaign.cpp +++ b/Tactical/Campaign.cpp @@ -1447,7 +1447,8 @@ UINT8 CurrentPlayerProgressPercentage(void) } // Add a static amount of points, as declared in the INI file. - usCurrentProgress += gGameExternalOptions.ubGameProgressIncrement; + // HEADROCK HAM 3.6: Allow negative modifiers! + usCurrentProgress = __max(0, (INT16)(usCurrentProgress + gGameExternalOptions.bGameProgressModifier)); // And failsafes here. I'm not 100% sure about these though: I've never personally seen progress // values go over 100, and I don't think they SHOULD... Can the game handle values > 100? Should it? @@ -1457,6 +1458,7 @@ UINT8 CurrentPlayerProgressPercentage(void) return((UINT8)usCurrentProgress); } + UINT8 HighestPlayerProgressPercentage(void) { if( gfEditMode ) @@ -1465,7 +1467,6 @@ UINT8 HighestPlayerProgressPercentage(void) return(gStrategicStatus.ubHighestProgress); } - // monitors the highest level of progress that player has achieved so far (checking hourly), // as opposed to his immediate situation (which may be worse if he's suffered a setback). void HourlyProgressUpdate(void) diff --git a/Tactical/Enemy Soldier Save.cpp b/Tactical/Enemy Soldier Save.cpp index 0695b69d..5e47cefd 100644 --- a/Tactical/Enemy Soldier Save.cpp +++ b/Tactical/Enemy Soldier Save.cpp @@ -822,8 +822,9 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile() return TRUE; } - - if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfEnemies ) +// // WANNE: Fix by Headrock: + // Turns out that the program is saving the number of used Placement Slots to the temp file fine, but if that number is equal to the limit of how many enemies/civvies are allowed in a sector by the INI settings, it leads to an assertion error instead when trying to re-load that sector. + if( slots < 0 || slots > (int)gGameExternalOptions.ubGameMaximumNumberOfEnemies ) { //bad IO! #ifdef JA2TESTVERSION sprintf( zReason, "EnemySoldier -- illegal slot value of %d. KM", slots ); @@ -1161,7 +1162,10 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile() FileClose( hfile ); return TRUE; } - if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfCivilians ) + + // WANNE: Fix by Headrock: + // Turns out that the program is saving the number of used Placement Slots to the temp file fine, but if that number is equal to the limit of how many enemies/civvies are allowed in a sector by the INI settings, it leads to an assertion error instead when trying to re-load that sector. + if( slots < 0 || slots > (int)gGameExternalOptions.ubGameMaximumNumberOfCivilians ) { //bad IO! #ifdef JA2TESTVERSION diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index a6acf488..a131ee46 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -5161,7 +5161,12 @@ void DrawExplosiveValues( OBJECTTYPE * gpItemDescObject ) // print value SetFontForeground( 5 ); - swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 )); + + // HEADROCK HAM 3.6: Can now use negative modifier. + UINT16 explDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage ); + + //swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 )); + swprintf( pStr, L"%2d", explDamage ); uiStringLength=StringPixLength(pStr, ITEMDESC_FONT ); FindFontRightCoordinates( (INT16)(gWeaponStats[ 2 ].sX + gsInvDescX + gWeaponStats[ 2 ].sValDx), (INT16)(gWeaponStats[ 2 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY); mprintf( sStrX, gWeaponStats[ 2 ].sY + gsInvDescY, pStr ); @@ -5176,7 +5181,12 @@ void DrawExplosiveValues( OBJECTTYPE * gpItemDescObject ) // print value SetFontForeground( 5 ); - swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 )); + + // HEADROCK HAM 3.6: Can now use negative modifier. + UINT16 explStunDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage ); + + //swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 )); + swprintf( pStr, L"%2d", explStunDamage ); uiStringLength=StringPixLength(pStr, ITEMDESC_FONT ); FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX + gWeaponStats[ 3 ].sValDx), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY); mprintf( sStrX, gWeaponStats[ 3 ].sY + gsInvDescY, pStr ); diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 7a94d161..8766bec7 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -8528,8 +8528,11 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier case IC_BOMB: // explosives { - UINT16 explDamage = (UINT16)( Explosive[Item[ usItem ].ubClassIndex].ubDamage + ( (double) Explosive[Item[ usItem ].ubClassIndex].ubDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); - UINT16 explStunDamage = (UINT16)( Explosive[Item[ usItem ].ubClassIndex].ubStunDamage + ( (double) Explosive[Item[ usItem ].ubClassIndex].ubStunDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); + // HEADROCK HAM 3.6: Can now use negative modifier. + //UINT16 explDamage = (UINT16)( Explosive[Item[ usItem ].ubClassIndex].ubDamage + ( (double) Explosive[Item[ usItem ].ubClassIndex].ubDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); + //UINT16 explStunDamage = (UINT16)( Explosive[Item[ usItem ].ubClassIndex].ubStunDamage + ( (double) Explosive[Item[ usItem ].ubClassIndex].ubStunDamage / 100) * gGameExternalOptions.ubExplosivesDamageMultiplier ); + UINT16 explDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ usItem ].ubClassIndex].ubDamage ); + UINT16 explStunDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ usItem ].ubClassIndex].ubStunDamage ); #ifdef CHINESE swprintf( pStr, ChineseSpecString5, diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index a4c9de43..354958d9 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -8967,3 +8967,33 @@ INT8 FindBackpackOnSoldier( SOLDIERTYPE * pSoldier ) } return( ITEM_NOT_FOUND ); } + +// HEADROCK HAM 3.6: This applies the INI modifier to explosives +UINT8 GetModifiedExplosiveDamage( UINT16 sDamage ) +{ + sDamage = (INT16)(( sDamage * gGameExternalOptions.iExplosivesDamageModifier ) / 100); + sDamage = __max(1, sDamage); + sDamage = __min(255, sDamage); + + return (UINT8)sDamage; +} + +UINT8 GetModifiedMeleeDamage( UINT16 sDamage ) +{ + sDamage = (INT16)(( sDamage * gGameExternalOptions.iMeleeDamageModifier ) / 100); + sDamage = __max(1, sDamage); + sDamage = __min(255, sDamage); + + return (UINT8)sDamage; +} + +UINT8 GetModifiedGunDamage( UINT16 sDamage ) +{ + sDamage = (INT16)(( sDamage * gGameExternalOptions.iGunDamageModifier ) / 100); + sDamage = __max(1, sDamage); + sDamage = __min(255, sDamage); + + return (UINT8)sDamage; +} + + diff --git a/Tactical/Items.h b/Tactical/Items.h index bce3b257..1e8aa699 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -346,6 +346,11 @@ INT16 GetSnowCamoBonus( OBJECTTYPE * pObj ); // HEADROCK HAM 3.6: Looks for a backpack anywhere on this character. INT8 FindBackpackOnSoldier( SOLDIERTYPE * pSoldier ); +// HEADROCK HAM 3.6: Handler functions to get modified damage with INI parameter. +UINT8 GetModifiedExplosiveDamage( UINT16 ubDamage ); +UINT8 GetModifiedMeleeDamage( UINT16 ubDamage ); +UINT8 GetModifiedGunDamage( UINT16 ubDamage ); + #endif diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 5cf26191..ed7180fc 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -7281,6 +7281,14 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier ) { bTolerance += pSoldier->bTilesMoved / gGameExternalOptions.ubTilesMovedPerBonusTolerancePoint; } + // HEADROCK HAM 3.6: This value has moved here. It reduces tolerance if the character is massively shocked. + if (gGameExternalOptions.ubCowerEffectOnSuppression != 0) + { + if (pSoldier->aiData.bShock > bTolerance) + { + bTolerance -= gGameExternalOptions.ubCowerEffectOnSuppression; + } + } bTolerance = __max(bTolerance, gGameExternalOptions.ubSuppressionToleranceMin); bTolerance = __min(bTolerance, gGameExternalOptions.ubSuppressionToleranceMax); @@ -7428,11 +7436,6 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) { fCower = true; - // If cowering, increase suppression effectiveness by external percentage. If the setting is - // over 100%, then the condition of cowering makes the character even MORE susceptible to suppression. - if (gGameExternalOptions.usCowerEffectOnSuppression > 0) - ubPointsLost = (ubPointsLost * gGameExternalOptions.usCowerEffectOnSuppression) / 100; - // If soldier is visible on-screen, report to player that they are cowering. if ( pSoldier->bVisible != -1 ) ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113HAMMessage[0], pSoldier->name ); diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 852cd854..eb60ad77 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -2646,3 +2646,96 @@ INT16 GetAPsToJumpOver( SOLDIERTYPE *pSoldier ) { return( GetAPsToChangeStance( pSoldier, ANIM_STAND ) + APBPConstants[AP_JUMP_OVER] ); } + +// HEADROCK HAM 3.6: Calculate the actual AP cost to add this many Extra Aiming levels, taking into account +// APBP Constants and extra game features. +INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime ) +{ + INT16 sAPCost = 0; + UINT16 usItemNum = pSoldier->inv[HANDPOS].usItem; + + Assert(pSoldier != NULL); + Assert(&pSoldier->inv[HANDPOS] != NULL); + + if (gGameExternalOptions.fIncreasedAimingCost ) + { + // HEADROCK HAM B2.6: Changed the number of APs to attack when aiming. + // HEADROCK HAM 3.1: Externalized the entire function to allow customization of each detail. + if (bAimTime > 0) + { + // HEADROCK HAM 3: One-time penalty: Add part of the weapon's Ready AP cost. Reinstated because + // it's now externalized. + if (gGameExternalOptions.ubFirstAimReadyCostDivisor > 0) + { + UINT16 usWeaponReadyTime; + UINT8 ubReadyTimeDivisor; + + usWeaponReadyTime = Weapon[ usItemNum ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(&pSoldier->inv[HANDPOS])) / 100; + ubReadyTimeDivisor = gGameExternalOptions.ubFirstAimReadyCostDivisor; + sAPCost += usWeaponReadyTime / ubReadyTimeDivisor; + } + + // If the weapon has a scope, and the target is within eligible range for scope use + + if ( IsScoped(&pSoldier->inv[HANDPOS]) + && GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sTargetGridNo ) >= GetMinRangeForAimBonus(&pSoldier->inv[HANDPOS]) ) + { + // Add an individual cost for EACH click, as necessary. + + sAPCost += APBPConstants[AP_FIRST_CLICK_AIM_SCOPE]; + + if (bAimTime > 1) + sAPCost += APBPConstants[AP_SECOND_CLICK_AIM_SCOPE]; + if (bAimTime > 2) + sAPCost += APBPConstants[AP_THIRD_CLICK_AIM_SCOPE]; + if (bAimTime > 3) + sAPCost += APBPConstants[AP_FOURTH_CLICK_AIM_SCOPE]; + if (bAimTime > 4) + sAPCost += APBPConstants[AP_FIFTH_CLICK_AIM_SCOPE]; + if (bAimTime > 5) + sAPCost += APBPConstants[AP_SIXTH_CLICK_AIM_SCOPE]; + if (bAimTime > 6) + sAPCost += APBPConstants[AP_SEVENTH_CLICK_AIM_SCOPE]; + if (bAimTime > 7) + sAPCost += APBPConstants[AP_EIGHTTH_CLICK_AIM_SCOPE]; + } + + // Weapon has no scope or not within requried range. Apply regular AP costs. + else + { + sAPCost += bAimTime * APBPConstants[AP_CLICK_AIM]; + } + } + else + { + return(0); + } + } + + // Regular cost system + else + { + sAPCost += bAimTime * APBPConstants[AP_CLICK_AIM]; + } + + return sAPCost; +} + +// HEADROCK HAM 3.6: Calculate how many Aiming Levels we can get with a given amount of APs. +INT8 CalcAimingLevelsAvailableWithAP( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAPsLeft ) +{ + INT8 bAllowedLevels = 0; + + for (INT16 x = APBPConstants[AP_MIN_AIM_ATTACK]; x <= AllowedAimingLevels(pSoldier); x++) + { + if (CalcAPCostForAiming( pSoldier, sTargetGridNo, x ) <= (INT16)bAPsLeft) + { + bAllowedLevels = x; + } + else + { + break; + } + } + return (bAllowedLevels); +} diff --git a/Tactical/Points.h b/Tactical/Points.h index 67c8d9fe..7a3d0df8 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -347,5 +347,7 @@ UINT16 GetAPsToReloadRobot( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pRobot ); INT16 GetAPsToReloadGunWithAmmo( SOLDIERTYPE *pSoldier, OBJECTTYPE * pGun, OBJECTTYPE * pAmmo, BOOLEAN usAllAPs = TRUE ); INT16 GetAPsToAutoReload( SOLDIERTYPE * pSoldier ); +INT32 CalcAPCostForAiming( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAimTime ); +INT8 CalcAimingLevelsAvailableWithAP( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, INT8 bAPsLeft ); #endif diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 6e804bfb..70d371ab 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -7611,23 +7611,23 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier } -UINT8 GetSpeedUpFactor( ) +FLOAT GetSpeedUpFactor( ) { switch( gTacticalStatus.ubCurrentTeam ) { case OUR_TEAM: - return gGameExternalOptions.gubPlayerTurnSpeedUpFactor; + return gGameExternalOptions.giPlayerTurnSpeedUpFactor; case ENEMY_TEAM: - return gGameExternalOptions.gubEnemyTurnSpeedUpFactor; + return gGameExternalOptions.giEnemyTurnSpeedUpFactor; case CREATURE_TEAM: - return gGameExternalOptions.gubCreatureTurnSpeedUpFactor; + return gGameExternalOptions.giCreatureTurnSpeedUpFactor; case MILITIA_TEAM: - return gGameExternalOptions.gubMilitiaTurnSpeedUpFactor; + return gGameExternalOptions.giMilitiaTurnSpeedUpFactor; case CIV_TEAM: - return gGameExternalOptions.gubCivilianTurnSpeedUpFactor; + return gGameExternalOptions.giCivilianTurnSpeedUpFactor; } - return 1; + return 1.0; } void SetSoldierAniSpeed( SOLDIERTYPE *pSoldier ) @@ -7681,7 +7681,7 @@ void SetSoldierAniSpeed( SOLDIERTYPE *pSoldier ) if ( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT ) if( GetSpeedUpFactor() ) - pSoldier->sAniDelay /= GetSpeedUpFactor(); + pSoldier->sAniDelay = (INT16)((FLOAT)pSoldier->sAniDelay * GetSpeedUpFactor()); else pSoldier->sAniDelay = 0; } diff --git a/Tactical/Soldier Init List.cpp b/Tactical/Soldier Init List.cpp index be2d8d14..3259f6b9 100644 --- a/Tactical/Soldier Init List.cpp +++ b/Tactical/Soldier Init List.cpp @@ -50,8 +50,9 @@ #endif #include "connect.h" - #include "Map Edgepoints.h" +#include "Queen Command.h" + BOOLEAN gfOriginalList = TRUE; SOLDIERINITNODE *gSoldierInitHead = NULL; @@ -1942,16 +1943,30 @@ void AddSoldierInitListBloodcats() { SECTORINFO *pSector; SOLDIERINITNODE *curr; - UINT8 ubSectorID; + UINT8 ubSectorID = 0; DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("AddSoldierInitListBloodcats")); + SECTORINFO dummy; + if( gbWorldSectorZ ) { - return; //no bloodcats underground. - } + // This function can only cope with regular SECTORINFO objects. + // So let's fake a sector above ground and copy over data from UNDERGROUND_SECTORINFO. + UNDERGROUND_SECTORINFO *pUndergroundSector + = FindUnderGroundSector(gWorldSectorX, gWorldSectorY, gbWorldSectorZ); - ubSectorID = (UINT8)SECTOR( gWorldSectorX, gWorldSectorY ); - pSector = &SectorInfo[ ubSectorID ]; + if (!pUndergroundSector) + return; + + pSector = &dummy; + pSector->bBloodCats = pUndergroundSector->ubNumBloodcats; + pSector->bBloodCatPlacements = pUndergroundSector->ubNumBloodcats; + } + else + { + ubSectorID = (UINT8)SECTOR( gWorldSectorX, gWorldSectorY ); + pSector = &SectorInfo[ ubSectorID ]; + } if( !pSector->bBloodCatPlacements ) { //This map has no bloodcat placements, so don't waste CPU time. diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 7dfe64e9..bb62f0dc 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -246,7 +246,7 @@ BOOLEAN LoadMercProfiles(void) UINT32 uiLoop, uiLoop2;//, uiLoop3; UINT16 usItem;//, usNewGun, usAmmo, usNewAmmo; - if (gGameExternalOptions.fAlwaysUseProfDat == FALSE) + if (gGameExternalOptions.fUseDifficultyBasedProfDat == TRUE) { switch ( gGameOptions.ubDifficultyLevel) { diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index f9232e9e..e6436c08 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -4976,7 +4976,7 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat // HEADROCK HAM 3.2: Critical headshots may now cause blindness, based on shot damage. if (gGameExternalOptions.ubChanceBlindedByHeadshot) { - if (PreRandom(gGameExternalOptions.ubChanceBlindedByHeadshot) == 0) + if (__min(100,(PreRandom(100)+1 + iImpact)) <= gGameExternalOptions.ubChanceBlindedByHeadshot) { if (pTarget->bBlindedCounter < iImpact / 10 ) pTarget->bBlindedCounter = iImpact / 10; @@ -6181,17 +6181,23 @@ UINT8 GetDamage ( OBJECTTYPE *pObj ) if ( Item[pObj->usItem].usItemClass == IC_BLADE || Item[pObj->usItem].usItemClass == IC_PUNCH || Item[pObj->usItem].usItemClass == IC_TENTACLES ) { - UINT8 ubDamage = Weapon[ pObj->usItem ].ubImpact + GetMeleeDamageBonus(pObj); - return min(255, (UINT8)( (ubDamage) + ( (double)ubDamage / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ) ); + // HEADROCK HAM 3.6: Can now take a negative modifier + UINT8 ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact ); + ubDamage += GetMeleeDamageBonus(pObj); + //return min(255, (UINT8)( (ubDamage) + ( (double)ubDamage / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ) ); + return min(255, (UINT8)ubDamage); } else { - UINT8 ubDamage = Weapon[ pObj->usItem ].ubImpact; + // HEADROCK HAM 3.6: Can now take a negative modifier + UINT8 ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact ); + + // WTF? Why do only small weapons get their damage bonus?! if (FitsInSmallPocket(pObj) == true) { ubDamage += GetDamageBonus(pObj); } - return min(255, (UINT8)( (ubDamage) + ( (double)ubDamage / 100) * gGameExternalOptions.ubGunDamageMultiplier ) ); + return min(255, (UINT8)ubDamage ); } } diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index eefa83f7..a60b864d 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -254,7 +254,9 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns if ( TANK( pSoldier ) ) { - ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost; + // HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications! + INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost; + ubMaxPossibleAimTime = CalcAimingLevelsAvailableWithAP( pSoldier, pOpponent->sGridNo, bAPsLeft ); // always burst if ( ubMaxPossibleAimTime < ubBurstAPs ) @@ -268,7 +270,9 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns } else { - ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPcost); + // HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications! + INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost; + ubMaxPossibleAimTime = CalcAimingLevelsAvailableWithAP( pSoldier, pOpponent->sGridNo, bAPsLeft ); } // consider the various aiming times @@ -287,7 +291,11 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns //sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit); //PopMessage(tempstr); - iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime); + // HEADROCK HAM 3.6: Actual aiming time is no longer 1AP per level... Failure to take this into account + // may yield skewed results in favour of high-aim targets. + INT16 sActualAimTime = CalcAPCostForAiming( pSoldier, pOpponent->sGridNo, (INT8)ubAimTime ); + + iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + sActualAimTime); //NumMessage("hitRate = ",iHitRate); // if aiming for this amount of time produces a better hit rate diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 3b0079d8..d4c0add4 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -4377,6 +4377,9 @@ INT16 ubMinAPCost; pSoldier->aiData.bAimTime = BestAttack.ubAimTime; pSoldier->bDoBurst = 0; + // HEADROCK HAM 3.6: bAimTime represents how MANY aiming levels are used, not how much APs they cost necessarily. + INT16 sActualAimTime = CalcAPCostForAiming( pSoldier, BestAttack.sTarget, (INT8)pSoldier->aiData.bAimTime ); + if (ubBestAttackAction == AI_ACTION_FIRE_GUN) { // Do we need to change stance? NB We'll have to ready our gun again @@ -4438,10 +4441,12 @@ INT16 ubMinAPCost; BestAttack.ubAPCost = MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1) + ubStanceCost; // Clip the aim time if necessary - if ( BestAttack.ubAPCost + BestAttack.ubAimTime > pSoldier->bActionPoints ) + // HEADROCK HAM 3.6: Use Actual Aiming Costs, without assuming that each aim level = 1 AP. + if ( BestAttack.ubAPCost + sActualAimTime > pSoldier->bActionPoints ) { // AP cost would balance (plus X, minus X) but aim time is reduced - BestAttack.ubAimTime = pSoldier->bActionPoints - BestAttack.ubAPCost - ubStanceCost; + // HEADROCK HAM 3.6: Use actual Aiming Costs. + BestAttack.ubAimTime = CalcAimingLevelsAvailableWithAP( pSoldier, BestAttack.sTarget, (pSoldier->bActionPoints - BestAttack.ubAPCost - ubStanceCost) ); if (BestAttack.ubAimTime < 0 ) { // This is actually a logic error situation. The ChangeStance section is supposed @@ -4466,7 +4471,8 @@ INT16 ubMinAPCost; ubBurstAPs = CalcAPsToBurst( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]) ); - if (pSoldier->bActionPoints >= BestAttack.ubAPCost + BestAttack.ubAimTime + ubBurstAPs ) + // HEADROCK HAM 3.6: Use Actual Aiming Time. + if (pSoldier->bActionPoints >= BestAttack.ubAPCost + sActualAimTime + ubBurstAPs ) { // Base chance of bursting is 25% if best shot was +0 aim, down to 8% at +4 if ( TANK( pSoldier ) ) @@ -4504,7 +4510,10 @@ INT16 ubMinAPCost; iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); } } - else if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY ) + // HEADROCK HAM 3.6: due to the "else", this part of the formula is NEVER hit. Removing. + //else if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY ) + if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY ) + { iChance += 100; } @@ -4588,6 +4597,11 @@ INT16 ubMinAPCost; iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) ); } } + // HEADROCK HAM 3.6: Forcing enemies to autofire at close range if possible, similar to forced burst (see above) + if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY ) + { + iChance += 100; + } } if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) @@ -4599,7 +4613,9 @@ INT16 ubMinAPCost; } else { - pSoldier->aiData.bAimTime = 0; + // HEADROCK HAM 3.6: No no no! This line removes all aiming from a potentially deadly single-shot! Commenting out. + //pSoldier->aiData.bAimTime = 0; + pSoldier->aiData.bAimTime = BestAttack.ubAimTime; pSoldier->bDoBurst = 0; pSoldier->bDoAutofire = 0; // not enough aps - do somthing else diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index 168d311b..02a4d30f 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -642,7 +642,11 @@ INT32 FindBestNearbyCover(SOLDIERTYPE *pSoldier, INT32 morale, INT32 *piPercentB // must be able to reach the cover, so it can't possibly be more than // action points left (rounded down) tiles away, since minimum // cost to move per tile is 1 points. - iMaxMoveTilesLeft = __max( 0, pSoldier->bActionPoints - MinAPsToStartMovement( pSoldier, usMovementMode ) ); + // HEADROCK HAM 3.6: This doesn't take into account the 100AP system. Adjusting. + // Please note, I used a calculation that may have a better representation in some global variable. + //iMaxMoveTilesLeft = __max( 0, pSoldier->bActionPoints - MinAPsToStartMovement( pSoldier, usMovementMode ) ); + iMaxMoveTilesLeft = __max( 0, (pSoldier->bActionPoints - MinAPsToStartMovement( pSoldier, usMovementMode ) / (APBPConstants[AP_MAXIMUM]/25)) ); + //NumMessage("In BLACK, maximum tiles to move left = ",maxMoveTilesLeft); // if we can't go as far as the usual full search range diff --git a/TacticalAI/ai.h b/TacticalAI/ai.h index 4f024ce3..773e77e9 100644 --- a/TacticalAI/ai.h +++ b/TacticalAI/ai.h @@ -245,4 +245,10 @@ INT32 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp ); INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction ); BOOLEAN CanClimbFromHere (SOLDIERTYPE * pSoldier, BOOLEAN fUp ); +// HEADROCK HAM 3.6: Adding includes for A* cover calculations +INT8 CalcWorstCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); +INT8 CalcBestCTGT( SOLDIERTYPE *pSoldier, UINT8 ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); +INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sOppGridNo, INT8 bLevel, INT32 iMyAPsLeft ); +UINT8 NumberOfTeamMatesAdjacent( SOLDIERTYPE * pSoldier, INT32 sGridNo ); + #endif diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index 60116e6b..e825fb04 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -1813,14 +1813,15 @@ BOOLEAN ExpAffect( INT32 sBombGridNo, INT32 sGridNo, UINT32 uiDist, UINT16 usIte uiRoll = PreRandom( 100 ); // Calculate wound amount - INT16 newDamage = pExplosive->ubDamage + (INT16)(( pExplosive->ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal + // HEADROCK HAM 3.6: Can now use negative modifier. + INT16 newDamage = (INT16)GetModifiedExplosiveDamage( pExplosive->ubDamage ); + //INT16 newDamage = pExplosive->ubDamage + (INT16)(( pExplosive->ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal sWoundAmt = newDamage + (INT16) ( (newDamage * uiRoll) / 100 ); - - // Calculate breath amount ( if stun damage applicable ) - INT16 newBreath = pExplosive->ubStunDamage + (INT16)(( pExplosive->ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal + INT16 newBreath = (INT16)GetModifiedExplosiveDamage( pExplosive->ubStunDamage ); + //INT16 newBreath = pExplosive->ubStunDamage + (INT16)(( pExplosive->ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier) / 100); //lal sBreathAmt = ( newBreath * 100 ) + (INT16) ( ( ( newBreath / 2 ) * 100 * uiRoll ) / 100 ) ; diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 9d2377c4..158c597e 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -376,11 +376,11 @@ STR16 pAssignmentStrings[] = L"Repar.", // repairing L"Üben", // training themselves L"Miliz", // training a town to revolt - L"M.Militia", //training moving militia units // TODO.Translate + L"M.Miliz", //training moving militia units L"Trainer", // training a teammate L"Rekrut", // being trained by someone else - L"Staff", // operating a strategic facility // TODO.Translate - L"Rest", // Resting at a facility // TODO.Translate + L"Betrieb", // operating a strategic facility + L"Pause", // Resting at a facility L"Tot", // dead L"Unfähig", // abbreviation for incapacitated L"Gefangen", // Prisoner of war - captured @@ -393,14 +393,14 @@ STR16 pMilitiaString[] = L"Miliz", // the title of the militia box L"Ohne Aufgabe", //the number of unassigned militia troops L"Mit Feinden im Sektor können Sie keine Miliz einsetzen!", - L"Some militia were not assigned to a sector. Would you like to disband them?", // TODO.Translate + L"Einige Milizen wurden keinem Sektor zugewiesen. Möchten Sie diese Einheiten auflösen?", }; STR16 pMilitiaButtonString[] = { L"Autom.", // auto place the militia troops for the player L"Fertig", // done placing militia troops - L"Disband", // HEADROCK HAM 3.6: Disband militia // TODO.Translate + L"Auflösen", // HEADROCK HAM 3.6: Disband militia }; STR16 pConditionStrings[] = @@ -615,7 +615,7 @@ STR16 pAssignMenuStrings[] = L"Fahrzeug", // the merc is in a vehicle L"Repar.", // the merc is repairing items L"Training", // the merc is training - L"Facility", // the merc is using/staffing a facility // TODO.Translate + L"Betrieb", // the merc is using/staffing a facility L"Abbrechen", // cancel this menu }; @@ -672,7 +672,7 @@ STR16 pTrainingMenuStrings[] = { L"Üben", // train yourself L"Miliz", // train the town - L"Mobile Militia", // TODO.Translate + L"Mobile Miliz", L"Trainer", // train your teammates L"Rekrut", // be trained by an instructor L"Abbrechen", // cancel this menu @@ -1082,7 +1082,7 @@ CHAR16 gWeaponStatsDesc[][ 16 ] = L"Gewicht:", //12 L"Bet. Schaden:", //13 // HEADROCK: Added new strings for extended description ** REDUNDANT ** - L"Attachments:", //14 // TODO.Translate + L"Zubehör:", //14 // Attachments L"AUTO/5:", //15 L"Menge:", //16 @@ -1701,7 +1701,7 @@ STR16 sFacilitiesStrings[] = { L"Keine", L"Hospital", - L"Factory", // TODO.Translate + L"Fabrik", // Factory L"Gefängnis", L"Militär", L"Flughafen", @@ -1730,7 +1730,7 @@ STR16 pwTownInfoStrings[] = L"Level", // the training level of civilians in this town L"Zivilistentraining", // 10 // state of civilian training in town L"Miliz", // the state of the trained civilians in the town - L"Mobile Training", // HEADROCK HAM 3.6: The stat of Mobile militia training in town // TODO.Translate + L"Mobile. M. Training", // HEADROCK HAM 3.6: The stat of Mobile militia training in town }; // Mine strings @@ -1990,7 +1990,7 @@ STR16 pTransactionText[] = L"Kauf bei Bobby Rays", // Bobby Ray is the name of an arms dealer L"Ausgeglichene Konten bei M.E.R.C.", L"Krankenversicherung für %s", // medical deposit for merc - L"B.S.E-Profilanalyse", // IMP is the acronym for International Mercenary Profiling + L"B.S.E.-Profilanalyse", // IMP is the acronym for International Mercenary Profiling L"Versicherung für %s abgeschlossen", L"Versicherung für %s verringert", L"Versicherung für %s verlängert", // johnny contract extended @@ -2011,8 +2011,8 @@ STR16 pTransactionText[] = L"Miliz in %s ausbilden", // initial cost to equip a town's militia L"Gegenstände von %s gekauft.", //is used for the Shop keeper interface. The dealers name will be appended to the end of the string. L"%s hat Geld angelegt.", - L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate - L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate + L"Betriebskosten", // HEADROCK HAM 3.6 + L"Unterhaltskosten für Miliz", // HEADROCK HAM 3.6 }; STR16 pTransactionAlternateText[] = @@ -2216,7 +2216,7 @@ STR16 pImpPopUpStrings[] = L"Fehler beim Laden des B.S.E. Charakters.", L"Sie haben bereits die maximale Anzahl an B.S.E. Charakteren.", L"Sie haben bereits drei B.S.E. Charaktere mit dem gleichen Geschlecht.", - L"Sie können sich den I.M.P. Charakter nicht leisten.", + L"Sie können sich den B.S.E. Charakter nicht leisten.", L"Der neue B.S.E. Charakter ist nun in ihrem Team.", }; @@ -2268,12 +2268,12 @@ STR16 pFilesTitle[] = STR16 pFilesSenderList[] = { L"Aufklärungsbericht", // the recon report sent to the player. Recon is an abbreviation for reconissance - L"Intercept #1", // first intercept file .. Intercept is the title of the organization sending the file...similar in function to INTERPOL/CIA/KGB..refer to fist record in files.txt for the translated title - L"Intercept #2", // second intercept file - L"Intercept #3", // third intercept file - L"Intercept #4", // fourth intercept file - L"Intercept #5", // fifth intercept file - L"Intercept #6", // sixth intercept file + L"Abschnitt #1", // first intercept file .. Intercept is the title of the organization sending the file...similar in function to INTERPOL/CIA/KGB..refer to fist record in files.txt for the translated title + L"Abschnitt #2", // second intercept file + L"Abschnitt #3", // third intercept file + L"Abschnitt #4", // fourth intercept file + L"Abschnitt #5", // fifth intercept file + L"Abschnitt #6", // sixth intercept file }; // Text having to do with the History Log @@ -2307,7 +2307,7 @@ STR16 pHistoryStrings[] = L"Rechnung an M.E.R.C. bezahlt", // paid outstanding bills at MERC L"Enrico Chivaldoris Auftrag akzeptiert", //6-10 - L"B.S.E-Profil erstellt", + L"B.S.E.-Profil erstellt", L"Versicherung abgeschlossen für %s.", // insurance contract purchased L"Versicherung gekündigt für %s.", // insurance contract canceled L"Versicherung ausgezahlt für %s.", // insurance claim payout for merc @@ -2418,7 +2418,7 @@ STR16 pBookMarkStrings[] = { L"A.I.M.", L"Bobby Rays", - L"B.S.E", + L"B.S.E.", L"M.E.R.C.", L"Bestattungsinst.", L"Florist", @@ -2511,8 +2511,8 @@ STR16 pWebPagesTitles[] = L"Bobby Rays - Sonst.", //misc is an abbreviation for miscellaneous L"Bobby Rays - Gebraucht", L"Bobby Rays - Versandauftrag", - L"B.S.E", - L"B.S.E", + L"B.S.E.", + L"B.S.E.", L"Fleuropa", L"Fleuropa - Gestecke", L"Fleuropa - Bestellformular", @@ -3196,7 +3196,7 @@ STR16 AimFiText[] = // The title of the page, the above text gets added at the end of this text L"A.I.M.-Mitglieder ansteigend sortiert nach %s", - L"A.I.M. Mitglieder absteigend sortiert nach %s", + L"A.I.M.-Mitglieder absteigend sortiert nach %s", // Instructions to the players on what to do @@ -3462,10 +3462,10 @@ STR16 pMilitiaConfirmStrings[] = L"Sie können sich keine $%d für die Miliz hier leisten.", L"%s benötigt eine Loyalität von %d Prozent, um mit dem Milizen-Training fortzufahren.", L"Sie können die Miliz in %s nicht mehr trainieren.", - L"You cannot afford the $%d to train mobile militia here.", // HEADROCK HAM 3.6: Mobile Militia TODO.Translate - L"Continue training mobile militia in %s (%s %d)?", // HEADROCK HAM 3.6: Mobile Militia TODO.Translate - L"Training mobile militia in %d sectors will cost $ %d. %s", // HEADROCK HAM 3.6: Mobile Militia TODO.Translate - L"Training a squad of mobile militia will cost $", // HEADROCK HAM 3.6: Mobile Militia TODO.Translate + L"Sie können sich keine $%d für mobile Miliz hier leisten.", // HEADROCK HAM 3.6: Mobile Militia + L"Mobile Milizen in %s (%s %d) weitertrainieren?", // HEADROCK HAM 3.6: Mobile Militia + L"Mobile Milizen in %d Sektoren zu trainieren kostet $ %d. %s", // HEADROCK HAM 3.6: Mobile Militia + L"Eine mobile Milizeinheit für diese Stadt zu trainieren kostet $", // HEADROCK HAM 3.6: Mobile Militia }; //Strings used in the popup box when withdrawing, or depositing money from the $ sign at the bottom of the single merc panel @@ -3520,7 +3520,7 @@ STR16 zOptionsToggleText[] = L"Niedrige CPU Belastung", L"Erw. Gegenstandsinfo (EDB)", L"Erzwungener Runden-Modus", // add forced turn mode - L"Stat Progress Bars", // Show progress towards stat increase + L"Status Trainingsfortschritt", // Show progress towards stat increase L"--Cheat Mode Optionen--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Erzwinge Bobby Ray Lieferungen", // force all pending Bobby Ray shipments L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END @@ -3616,7 +3616,7 @@ STR16 zOptionsScreenHelpText[] = L"Wenn diese Funktion aktiviert ist, wird das Spiel mit viel geringerer CPU Belastung laufen.", L"Wenn diese Funktion aktiviert ist, werden erweiterte Beschreibungen zu den Waffen und Gegenständen angezeigt.", L"Wenn diese Funktion aktiviert ist und noch Gegner im Sektor sind, bleibt das Spiel im Runden-Modus, bis alle Feinde tot sind (|C|T|R|L+|S|H|I|F|T+|A|L|T+|T).", - L"When ON, shows character progress towards gaining levels.", + L"Wenn diese Funktion aktiviert ist, wird der Trainingsfortschritt für die Söldner angezeigt.", L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_HEADER", L"Force all pending Bobby Ray shipments", L"(text not rendered)TOPTION_CHEAT_MODE_OPTIONS_END", @@ -4234,7 +4234,7 @@ STR16 gzLateLocalizedString[] = //46-48 L"%ss Gewehrlauf-Verlängerung fällt ab!", - L"No more than %d militia trainers are permitted in this sector.", // TODO.Translate + L"Es sind nicht mehr als %d Milizenausbilder in diesem Sektor erlaubt.", L"Sind Sie sicher?", // //49-50 @@ -4274,7 +4274,7 @@ STR16 gzLateLocalizedString[] = STR16 gzCWStrings[] = { - L"Call reinforcements to %s from adjacent sectors?", // TODO.Translate + L"Verstärkung aus benachbarten Sektoren nach %s rufen?", }; // WANNE: Tooltips @@ -4351,36 +4351,36 @@ STR16 New113Message[] = L"Gegner gesichtet! (Ctrl + x für Rundenmodus)", }; -// TODO.Translate STR16 New113HAMMessage[] = { // 0 - 5 - L"%s cowers in fear!", - L"%s is pinned down!", - L"%s fires more rounds than intended!", - L"You cannot train militia in this sector.", - L"Militia picks up %s.", - L"Cannot train militia with enemies present!", + L"%s zittert vor Angst!", + L"%s is festgenagelt!", + L"%s feuert mehr Schüsse mehr als beabsichtigt!", + L"Sie können keine Miliz in diesem Sektor ausbilden.", + L"Miliz hebt %s auf.", + L"Wenn Feinde im Sektor sind können Sie keine Miliz ausbilden!", // 6 - 10 - L"%s lacks sufficient Leadership score to train militia.", - L"No more than %d Mobile Militia trainers are permitted in this sector.", - L"No room in %s or around it for new Mobile Militia!", - L"You need to have %d Town Militia in each of %s's liberated sectors before you can train Mobile Militia here.", - L"Can't staff a facility while enemies are present!", + L"%s hat nicht genug Führungsqualität um Milizen auszubilden.", + L"Pro Sektor sind nicht mehr als %d Milizausbilder erlaubt.", + L"Kein Platz für mobile Milizen in oder rund um %s!", + L"Sie benötigen %d Stadtmilizen in jedem von %ss befreiten Sektoren bevor Sie hier mobile Milizen ausbilden können.", + L"Anlage nicht nutzbar wenn Feinde in der Gegend sind!", // 11 - 15 - L"%s lacks sufficient Wisdom to staff this facility.", - L"The %s is already fully-staffed.", - L"It will cost $%d per hour to staff this facility. Do you wish to continue?", - L"You have insufficient funds to pay for all Facility work today. $%d have been paid, but you still owe $%d. The locals are not pleased.", - L"You have insufficient funds to pay for all Facility work today. You owe $%d. The locals are not pleased.", + L"%s hat nicht genügend Weisheit um diese Anlage betreiben zu können.", + L"%s ist schon voll besetzt.", + L"Diese Anlage zu betreiben kostet $%d pro Stunde. Weitermachen?", + L"Sie haben nicht genug Geld um alle heutigen Betriebskosten zu zahlen. $%d wurden bezahlt, Sie schulden weiterhin $%d. Die Einwohner sind nicht erfreut.", + L"Sie haben nicht genug Geld um alle heutigen Betriebskosten zu zahlen. Sie schulden $%d. Die Einwohner sind nicht erfreut.", // 16 - 20 - L"You have an outstanding debt of $%d for Facility Operation, and no money to pay it off!", - L"You have an outstanding debt of $%d for Facility Operation. You can't assign this merc to facility duty until you have enough money to pay off the entire debt.", - L"You have an outstanding debt of $%d for Facility Operation. Would you like to pay it all back?", - L"N/A in this sector", - L"Daily Expenses", + L"Sie haben eine ausstehende Forderung von $%d für Betriebskosen und kein Geld um zu bezahlen!", + L"Sie haben eine ausstehende Forderung von $%d für Betriebskosen. Dieser Anlage können Sie keinen Söldner zuweisen bis Sie Ihre gesamten Schulden beglichen haben.", + L"Sie haben eine ausstehende Forderung von $%d für Betriebskosen. Möchten Sie diese Schuld begleichen?", + L"Nicht möglich in diesem Sektor", + L"Tagesausgaben", // 21 - 25 - L"Insufficient funds to pay all enlisted militia! %d militia have disbanded and returned home.", + L"Nicht genug Geld für alle angeworbenen Milzen! %d Milzen wurden entlassen und sind heimgekehrt.", + }; // WANNE: This are the email texts, when one of the 4 new 1.13 MERC mercs have levelled up, that Speck sends @@ -4693,112 +4693,110 @@ STR16 gzIMPDisabilityTraitText[]= L"Ihre größte Schwäche", }; -// TODO.Translate // HEADROCK HAM 3.6: Error strings for assigning a merc to a facility STR16 gzFacilityErrorMessage[]= { - L"%s lacks sufficient Strength to perform this task.", - L"%s lacks sufficient Dexterity to perform this task.", - L"%s lacks sufficient Agility to perform this task.", - L"%s is not Healthy enough to perform this task.", - L"%s lacks sufficient Wisdom to perform this task.", - L"%s lacks sufficient Marksmanship to perform this task.", + L"%s hat nicht genug Kraft um diese Aufgabe zu erledigen.", + L"%s ist nicht geschickt genug um diese Aufgabe zu erledigen.", + L"%s ist nicht beweglich genug um diese Aufgabe zu erledigen.", + L"%s hat keine ausreichende Gesundheit um diese Aufgabe zu erledigen.", + L"%s mangelt es an ausreichender Weisheit um diese Aufgabe zu erledigen.", + L"%s mangelt es an ausreichender Treffsicherheit um diese Aufgabe zu erledigen.", // 6 - 10 - L"%s lacks sufficient Medical Skill to perform this task.", - L"%s lacks sufficient Mechanical Skill to perform this task.", - L"%s lacks sufficient Leadership to perform this task.", - L"%s lacks sufficient Explosives Skill to perform this task.", - L"%s lacks sufficient Experience to perform this task.", + L"%s hat nicht genug Medizinkenntnis um diese Aufgabe zu erledigen.", + L"%s hat zu wenig technisches Verständnis um diese Aufgabe zu erledigen.", + L"%s mangelt es an ausreichender Führungsqualität um diese Aufgabe zu erledigen.", + L"%s hat nicht genug Sprengstoffkenntnis um diese Aufgabe zu erledigen.", + L"%s mangelt es an ausreichender Erfahrung um diese Aufgabe zu erledigen.", // 11 - 15 - L"%s lacks sufficient Morale to perform this task.", - L"%s is too exhausted to perform this task.", - L"Insufficient loyalty in %s. The locals refuse to allow you to perform this task.", - L"Too many people are already working at the %s.", - L"Too many people are already performing this task at the %s.", + L"%s hat nicht genug Moral um diese Aufgabe zu erledigen.", + L"%s ist zu erschöpft um diese Aufgabe zu erledigen.", + L"Zu wenig Loyalität in %s. Die Einwohner lassen Sie diese Aufgabe nicht verrichten.", + L"Es arbeiten bereits zu viele Personen in %s.", + L"Zu viele Personen verrichten diese Aufgabe schon in %s.", // 16 - 20 - L"%s can find no items to repair.", - L"%s has lost some %s while working in sector %s!", - L"%s has lost some %s while working at the %s in %s!", - L"%s was injured while working in sector %s, and requires immediate medical attention!", - L"%s was injured while working at the %s in %s, and requires immediate medical attention!", + L"%s findet nichts mehr zum Reparieren.", + L"%s verliert %s beim Arbeiten in %s.", + L"%s hat ein paar %s verloren beim Arbeiten in der %s in %s !", + L"%s wurde verletzt beim Arbeiten in Sektor %s und benötigt dringend medizinische Versorgung!", + L"%s wurde verletzt beim Arbeiten in der %s in %s und benötigt dringend medizinische Versorgung!", // 21 - 25 - L"%s was injured while working in sector %s. It doesn't seem too bad though.", - L"%s was injured while working at the %s in %s. It doesn't seem too bad though.", - L"The residents of %s seem upset about %s's presence.", - L"The residents of %s seem upset about %s's work at the %s.", - L"%s's actions in sector %s have caused loyalty loss throughout the region!", + L"%s wurde verletzt beim Arbeiten in Sektor %s. Es scheint aber nichts Ernstes zu sein.", + L"%s wurde verletzt beim Arbeiten in der %s in %s. Es scheint aber nichts Ernstes zu sein.", + L"Die Einwohner von %s scheinen sich über die Anwesenheit von %s aufzuregen." + L"Die Einwohner von %s scheinen sich über die Arbeit von %s in der %s aufzuregen." + L"%ss Handeln im Sektor %s hat einen Loyalitätsverlust in der gesamten Region bewirkt!", // 26 - 30 - L"%s's actions at the %s in %s have caused loyalty loss throughout the region!", - L"%s is drunk.", // <--- This is a log message string. - L"%s has become severely ill in sector %s, and has been taken off duty.", - L"%s has become severely ill and cannot continue his work at the %s in %s.", - L"%s was injured in sector %s.", // <--- This is a log message string. + L"%ss Handeln in der %s in %s hat einen Loyalitätsverlust in der gesamten Region bewirkt!", + L"%s ist betrunken.", // <--- This is a log message string. + L"%s ist ernsthaft krank geworden in Sektor %s und wurde vom Dienst freigestellt.", + L"%s ist ernsthaft krank geworden und kann keine seine Arbeiten in der %s in %s fortsetzen.", + L"%s wurde veletzt in Sektor %s.", // <--- This is a log message string. // 31 - 35 - L"%s was severely injured in sector %s.", //<--- This is a log message string. + L"%s wurde ernsthaft im Sektor %s verletzt.", //<--- This is a log message string. }; -// TODO.Translate STR16 gzFacilityRiskResultStrings[]= { - L"Strength", - L"Agility", - L"Dexterity", - L"Wisdom", - L"Health", - L"Marksmanship", + L"Kraft", + L"Beweglichkeit", + L"Geschicklichkeit", + L"Weisheit", + L"Gesundheit", + L"Treffsicherheit", // 5-10 - L"Leadership", - L"Mechanical skill", - L"Medical skill", - L"Explosives skill", + L"Führungsqualität", + L"Technik", + L"Medizin", + L"Sprengstoffe", }; -// TODO.Translate STR16 gzFacilityAssignmentStrings[]= { - L"AMBIENT", - L"Staff", - L"Rest", - L"Repair Items", - L"Repair %s", // Vehicle name inserted here - L"Repair Robot", + + L"UMGEBUNG", + L"Betrieb", + L"Pause", + L"Repariere Gegenstände", + L"Repariere %s", + L"Repariere Roboter", // 6-10 - L"Doctor", + L"Arzt", L"Patient", - L"Practice Strength", - L"Practice Dexterity", - L"Practice Agility", - L"Practice Health", + L"Üben Kraft", + L"Üben Geschicklichkeit", + L"Üben Beweglichkeit", + L"Üben Gesundheit", // 11-15 - L"Practice Marksmanship", - L"Practice Medical", - L"Practice Mechanical", - L"Practice Leadership", - L"Practice Explosives", + L"Üben Treffsicherheit", + L"Üben Medizin", + L"Üben Technik", + L"Üben Führungsqualität", + L"Üben Sprengstoff", // 16-20 - L"Student Strength", - L"Student Dexterity", - L"Student Agility", - L"Student Health", - L"Student Marksmanship", + L"Rekrut Kraft", + L"Rekrut Geschicklichkeit", + L"Rekrut Beweglichkeit", + L"Rekrut Gesundheit", + L"Rekrut Treffsicherheit", // 21-25 - L"Student Medical", - L"Student Mechanical", - L"Student Leadership", - L"Student Explosives", - L"Trainer Strength", + L"Rekrut Medizin", + L"Rekrut Technik", + L"Rekrut Führungsqualität.", + L"Rekrut Sprengstoff", + L"Trainer Kraft", // 26-30 - L"Trainer Dexterity", - L"Trainer Agility", - L"Trainer Health", - L"Trainer Marksmanship", - L"Trainer Medical", + L"Trainer Geschicklichkeit", + L"Trainer Beweglichkeit", + L"Trainer Gesundheit", + L"Trainer Treffsicherheit", + L"Trainer Medizin", // 30-35 - L"Trainer Mechanical", - L"Trainer Leadership", - L"Trainer Explosives", + L"Trainer Technik", + L"Trainer Führungsqualität", + L"Trainer Sprengstoff", }; STR16 Additional113Text[]= diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index ea406e36..ab05f71d 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -3709,7 +3709,7 @@ STR16 zOptionsToggleText[] = L"Íèçêàÿ çàãðóçêà ïðîöåññîðà", L"Ïîäðîáíîå îïèñàíèå ïðåäìåòîâ", //Enhanced Description Box L"Òîëüêî ïîøàãîâûé ðåæèì", // add forced turn mode - L"Ñòàòèñòèêà ïðîäâèæåíèÿ íàâûêîâ", //Stat Progress Bars // Show progress towards stat increase // TODO.Translate + L"Ñòàòèñòèêà ïðîäâèæåíèÿ íàâûêîâ", //Stat Progress Bars // Show progress towards stat increase L"--Cheat Mode Options--", // TOPTION_CHEAT_MODE_OPTIONS_HEADER, L"Óñêîðèòü äîñòàâêó Áîááè Ðýÿ", // force all pending Bobby Ray shipments L"-----------------", // TOPTION_CHEAT_MODE_OPTIONS_END diff --git a/ja2_2005Express.vcproj b/ja2_2005Express.vcproj index 5cb884b2..50d23ecd 100644 --- a/ja2_2005Express.vcproj +++ b/ja2_2005Express.vcproj @@ -66,7 +66,7 @@