Space Viking's many mercs changes plus numerous generic bug fixes

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@2498 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
SpaceViking
2009-01-15 01:26:13 +00:00
parent f64f58fbf8
commit f26095d86f
138 changed files with 3493 additions and 3265 deletions
+181 -149
View File
@@ -355,9 +355,9 @@ void InitGameOptions()
// WDS: These HAVE to total 100% at all times!!! // WDS: These HAVE to total 100% at all times!!!
#define PROGRESS_PORTION_KILLS 25 //#define PROGRESS_PORTION_KILLS 25
#define PROGRESS_PORTION_CONTROL 25 //#define PROGRESS_PORTION_CONTROL 25
#define PROGRESS_PORTION_INCOME 50 //#define PROGRESS_PORTION_INCOME 50
// The following are for fixing problems when reading the .ini file // The following are for fixing problems when reading the .ini file
@@ -385,7 +385,7 @@ void LoadGameExternalOptions()
//################# Laptop Settings ################# //################# Laptop Settings #################
// WDS: Allow flexible numbers of IMPs of each sex // WDS: Allow flexible numbers of IMPs of each sex
gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("JA2 Laptop Settings","MAX_IMP_CHARACTERS",1); gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("JA2 Laptop 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.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.iIMPFemaleCharacterCount = iniReader.ReadInteger("JA2 Laptop Settings","IMP_FEMALE_CHARACTER_COUNT", COUNT_STANDARD_FEMALE_SLOTS, 1, NUM_PROFILES);
@@ -439,15 +439,15 @@ void LoadGameExternalOptions()
gGameExternalOptions.iaIMPSlots[gGameExternalOptions.iIMPFemaleCharacterCount+gGameExternalOptions.iIMPMaleCharacterCount+1] = -1; gGameExternalOptions.iaIMPSlots[gGameExternalOptions.iIMPFemaleCharacterCount+gGameExternalOptions.iIMPMaleCharacterCount+1] = -1;
//Character generation //Character generation
gGameExternalOptions.iMinAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MIN_ATTRIBUTE_POINT",35); gGameExternalOptions.iMinAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MIN_ATTRIBUTE_POINT",35, 10, 100);
gGameExternalOptions.iMaxAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ATTRIBUTE_POINT",90); gGameExternalOptions.iMaxAttribute = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ATTRIBUTE_POINT",90, 10, 100);
gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("JA2 Laptop Settings","IMPATTRIBUTEPOINTS",40); gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("JA2 Laptop Settings","IMPATTRIBUTEPOINTS",40, 10, 100);
gGameExternalOptions.iMaxZeroBonus = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ZERO_BONUS",15); gGameExternalOptions.iMaxZeroBonus = iniReader.ReadInteger("JA2 Laptop Settings","MAX_ZERO_BONUS",15, 10, 100);
gGameExternalOptions.iStartAttribute = iniReader.ReadInteger("JA2 Laptop Settings","START_ATTRIBUTE",55); gGameExternalOptions.iStartAttribute = iniReader.ReadInteger("JA2 Laptop Settings","START_ATTRIBUTE",55, 10, 100);
//gGameExternalOptions.fPers_att = iniReader.ReadBoolean("JA2 Laptop Settings","USE_RANDOM_PERSONALITY",FALSE); //gGameExternalOptions.fPers_att = iniReader.ReadBoolean("JA2 Laptop Settings","USE_RANDOM_PERSONALITY",FALSE);
gGameExternalOptions.iCustomPersonality = (INT8) iniReader.ReadInteger("JA2 Laptop Settings","CUSTOM_PERSONALITY",0); 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); gGameExternalOptions.iCustomAttitude = (INT8) iniReader.ReadInteger("JA2 Laptop Settings","CUSTOM_ATTITUDE",0, 0, NUM_ATTITUDES-1);
//Merc settings //Merc settings
gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("JA2 Laptop Settings","MERC_AVAILABLE_DAY_ONE",FALSE); gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("JA2 Laptop Settings","MERC_AVAILABLE_DAY_ONE",FALSE);
@@ -455,30 +455,33 @@ void LoadGameExternalOptions()
//Merc Death Settings: //Merc Death Settings:
gGameExternalOptions.gfMercsDieOnAssignment = iniReader.ReadBoolean("JA2 Laptop Settings","MERCS_DIE_ON_ASSIGNMENT",TRUE); gGameExternalOptions.gfMercsDieOnAssignment = iniReader.ReadBoolean("JA2 Laptop Settings","MERCS_DIE_ON_ASSIGNMENT",TRUE);
gGameExternalOptions.giEasyMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EASY_MERC_DEATHS",1); gGameExternalOptions.giEasyMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EASY_MERC_DEATHS",1, 0, 10);
gGameExternalOptions.giExperiencedMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERIENCED_MERC_DEATHS",2); gGameExternalOptions.giExperiencedMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERIENCED_MERC_DEATHS",2, 0, 10);
gGameExternalOptions.giExpertMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERT_MERC_DEATHS",3); gGameExternalOptions.giExpertMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","EXPERT_MERC_DEATHS",3, 0, 10);
gGameExternalOptions.giInsaneMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","INSANE_MERC_DEATHS",4); gGameExternalOptions.giInsaneMercDeaths = iniReader.ReadInteger("JA2 Laptop Settings","INSANE_MERC_DEATHS",4, 0, 10);
//################# System Settings ################# //################# System Settings #################
gGameExternalOptions.gubDeadLockDelay = (UINT8) iniReader.ReadInteger("JA2 System Settings","DEAD_LOCK_DELAY",15); 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); gGameExternalOptions.gfEnableEmergencyButton_SkipStrategicEvents = iniReader.ReadBoolean("JA2 System 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);
//################# Video Settings ################# //################# Video Settings #################
gGameExternalOptions.gfVSync = iniReader.ReadBoolean("JA2 Video Settings","VERTICAL_SYNC",0); gGameExternalOptions.gfVSync = iniReader.ReadBoolean("JA2 Video Settings","VERTICAL_SYNC",0);
//################# Animation Settings ################# //################# Animation Settings #################
gGameExternalOptions.gubPlayerTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","PLAYER_TURN_SPEED_UP_FACTOR",1); 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); 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); 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); 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); gGameExternalOptions.gubCivilianTurnSpeedUpFactor = iniReader.ReadInteger("JA2 Turnbased Animation Speed Settings","CIVILIAN_TURN_SPEED_UP_FACTOR",1, 0, 100);
//################# Sound Settings ################# //################# Sound Settings #################
gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("JA2 Sound Settings","WEAPON_SOUND_EFFECTS_VOLUME",0); gGameExternalOptions.guiWeaponSoundEffectsVolume = iniReader.ReadInteger("JA2 Sound Settings","WEAPON_SOUND_EFFECTS_VOLUME",0, 0, 1000 /*1000 = 10x?*/);
@@ -497,8 +500,8 @@ void LoadGameExternalOptions()
gGameExternalOptions.iPlayerAPBonus = (INT8) iniReader.ReadInteger("JA2 Tactical Settings","PLAYER_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 // Sight range
gGameExternalOptions.ubStraightSightRange = iniReader.ReadInteger("JA2 Tactical Settings","BASE_SIGHT_RANGE",13); 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); 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); gGameExternalOptions.gfAllowLimitedVision = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_LIMITED_VISION",0);
// Maximal search distance for grenades // Maximal search distance for grenades
@@ -508,7 +511,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfAllowSoldierToolTips = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_SOLDIER_TOOL_TIPS",0); gGameExternalOptions.gfAllowSoldierToolTips = iniReader.ReadBoolean("JA2 Tactical Settings","ALLOW_SOLDIER_TOOL_TIPS",0);
// ShadoWarrior: Tooltip changes (start) // ShadoWarrior: Tooltip changes (start)
gGameExternalOptions.ubSoldierTooltipDetailLevel = (UINT8) iniReader.ReadInteger("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DETAIL_LEVEL", 1); 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.fEnableDynamicSoldierTooltips = iniReader.ReadBoolean("JA2 Tactical Settings", "DYNAMIC_SOLDIER_TOOLTIPS", TRUE);
gGameExternalOptions.fEnableSoldierTooltipLocation = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_LOCATION", TRUE); gGameExternalOptions.fEnableSoldierTooltipLocation = iniReader.ReadBoolean("JA2 Tactical Settings", "SOLDIER_TOOLTIP_DISPLAY_LOCATION", TRUE);
@@ -545,21 +548,21 @@ void LoadGameExternalOptions()
// Rain settings // Rain settings
gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("JA2 Rain Settings","ALLOW_RAIN",0); gGameExternalOptions.gfAllowRain = iniReader.ReadBoolean("JA2 Rain Settings","ALLOW_RAIN",0);
gGameExternalOptions.gusRainChancePerDay = iniReader.ReadInteger("JA2 Rain Settings","RAIN_CHANCE_PER_DAY",100); 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); gGameExternalOptions.gusRainMinLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MIN_LENGTH_IN_MINUTES",60, 1, 300);
gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MAX_LENGTH_IN_MINUTES",300); gGameExternalOptions.gusRainMaxLength = iniReader.ReadInteger("JA2 Rain Settings","RAIN_MAX_LENGTH_IN_MINUTES",300, 10, 600);
gGameExternalOptions.guiMaxRainDrops = iniReader.ReadInteger("JA2 Rain Settings","MAX_RAIN_DROPS",80); 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); gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity = iniReader.ReadInteger("JA2 Rain Settings","WEAPON_RELIABILITY_REDUCTION_PER_RAIN_INTENSITY",0, 0, 10);
gGameExternalOptions.ubBreathGainReductionPerRainIntensity = iniReader.ReadFloat("JA2 Rain Settings","BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY",25); gGameExternalOptions.ubBreathGainReductionPerRainIntensity = iniReader.ReadDouble("JA2 Rain Settings","BREATH_GAIN_REDUCTION_PER_RAIN_INTENSITY",25, 1, 100);
// Thunder settings // Thunder settings
gGameExternalOptions.gfAllowLightning = iniReader.ReadBoolean("JA2 Thunder Settings","ALLOW_LIGHTNING",TRUE); 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); 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); 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); 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); 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); 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); gGameExternalOptions.guiChanceToDoLightningBetweenTurns = iniReader.ReadInteger("JA2 Thunder Settings","CHANCE_TO_DO_LIGHTNING_BETWEEN_TURNS",35, 0, 100);
@@ -567,46 +570,41 @@ void LoadGameExternalOptions()
//################# Settings valid on game start only ################## //################# Settings valid on game start only ##################
//Money settings //Money settings
gGameExternalOptions.iStartingCashNovice = iniReader.ReadInteger("JA2 Gameplay Settings", "NOVICE_CASH",45000); gGameExternalOptions.iStartingCashNovice = iniReader.ReadInteger("JA2 Gameplay Settings", "NOVICE_CASH",45000, 2000, 0x0FFFFFFF);
gGameExternalOptions.iStartingCashExperienced = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERIENCED_CASH",35000); gGameExternalOptions.iStartingCashExperienced = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERIENCED_CASH",35000, 2000, 0x0FFFFFFF);
gGameExternalOptions.iStartingCashExpert = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERT_CASH",30000); gGameExternalOptions.iStartingCashExpert = iniReader.ReadInteger("JA2 Gameplay Settings", "EXPERT_CASH",30000, 2000, 0x0FFFFFFF);
gGameExternalOptions.iStartingCashInsane = iniReader.ReadInteger("JA2 Gameplay Settings", "INSANE_CASH",15000); gGameExternalOptions.iStartingCashInsane = iniReader.ReadInteger("JA2 Gameplay Settings", "INSANE_CASH",15000, 2000, 0x0FFFFFFF);
//Lalien: Game starting time //Lalien: Game starting time
gGameExternalOptions.iGameStartingTime = iniReader.ReadInteger("JA2 Gameplay Settings", "GAME_STARTING_TIME", NUM_SEC_IN_HOUR); gGameExternalOptions.iGameStartingTime = iniReader.ReadInteger("JA2 Gameplay Settings", "GAME_STARTING_TIME", NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY-1);
gGameExternalOptions.iGameStartingTime += NUM_SEC_IN_DAY;
// WANNE: Check for invalid starting time
if (gGameExternalOptions.iGameStartingTime < 0 || gGameExternalOptions.iGameStartingTime >= NUM_SEC_IN_DAY)
{
gGameExternalOptions.iGameStartingTime = NUM_SEC_IN_HOUR + NUM_SEC_IN_DAY;
}
else
{
gGameExternalOptions.iGameStartingTime += NUM_SEC_IN_DAY;
}
gGameExternalOptions.iFirstArrivalDelay = iniReader.ReadInteger("JA2 Gameplay Settings", "FIRST_ARRIVAL_DELAY", 6 * NUM_SEC_IN_HOUR); gGameExternalOptions.iFirstArrivalDelay = iniReader.ReadInteger("JA2 Gameplay Settings", "FIRST_ARRIVAL_DELAY", 6 * NUM_SEC_IN_HOUR, 0, NUM_SEC_IN_DAY);
//################# Settings valid on game start only end ################## //################# Settings valid on game start only end ##################
gGameExternalOptions.fSellAll = iniReader.ReadBoolean("JA2 Gameplay Settings","CAN_SELL_ALT_LMB",FALSE); gGameExternalOptions.fSellAll = iniReader.ReadBoolean("JA2 Gameplay Settings","CAN_SELL_ALT_LMB",FALSE);
gGameExternalOptions.iPriceModifier = (INT16) iniReader.ReadInteger("JA2 Gameplay Settings","PRICE_MODIFIER",10); gGameExternalOptions.iPriceModifier = (INT16) iniReader.ReadInteger("JA2 Gameplay Settings","PRICE_MODIFIER",10, 1, 100);
// WDS - Option to turn off stealing // WDS - Option to turn off stealing
gGameExternalOptions.fStealingDisabled = iniReader.ReadBoolean("JA2 Gameplay Settings","STEALING_FROM_SHIPMENTS_DISABLED",FALSE); gGameExternalOptions.fStealingDisabled = iniReader.ReadBoolean("JA2 Gameplay Settings","STEALING_FROM_SHIPMENTS_DISABLED",FALSE);
// WDS: Game progress // WDS: Game progress
gGameExternalOptions.ubGameProgressPortionKills = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_KILLS",25); gGameExternalOptions.ubGameProgressPortionKills = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_KILLS", 25, 0, 100);
gGameExternalOptions.ubGameProgressPortionControl = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_CONTROL",25); gGameExternalOptions.ubGameProgressPortionControl = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_CONTROL", 25, 0, 100);
gGameExternalOptions.ubGameProgressPortionIncome = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_INCOME",50); gGameExternalOptions.ubGameProgressPortionIncome = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_INCOME", 50, 0, 100);
gGameExternalOptions.ubGameProgressPortionVisited = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_VISITED",0); 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);
// Any way to warn on this? // Any way to warn on this?
if (gGameExternalOptions.ubGameProgressPortionKills + gGameExternalOptions.ubGameProgressPortionControl + gGameExternalOptions.ubGameProgressPortionIncome + gGameExternalOptions.ubGameProgressPortionVisited != 100) if (gGameExternalOptions.ubGameProgressPortionKills +
gGameExternalOptions.ubGameProgressPortionControl +
gGameExternalOptions.ubGameProgressPortionIncome +
gGameExternalOptions.ubGameProgressPortionVisited != 100)
{ {
gGameExternalOptions.ubGameProgressPortionKills = 25; gGameExternalOptions.ubGameProgressPortionKills = 25;
gGameExternalOptions.ubGameProgressPortionControl = 25; gGameExternalOptions.ubGameProgressPortionControl = 25;
@@ -614,75 +612,86 @@ void LoadGameExternalOptions()
gGameExternalOptions.ubGameProgressPortionVisited = 0; gGameExternalOptions.ubGameProgressPortionVisited = 0;
} }
// WDS: Advanced start
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 //Global game events
gGameExternalOptions.ubGameProgressStartMadlabQuest = iniReader.ReadInteger("JA2 Gameplay Settings","GAME_PROGRESS_START_MADLAB_QUEST",35); 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); 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); 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); gGameExternalOptions.ubSendTroopsToDrassen = iniReader.ReadBoolean("JA2 Gameplay Settings","STRATEGIC_EVENT_SEND_TROOPS_TO_DRASSEN",TRUE);
//Weapons modification //Weapons modification
gGameExternalOptions.ubExplosivesDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","EXPLOSIVES_DAMAGE_MULTIPLIER",0); gGameExternalOptions.ubExplosivesDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","EXPLOSIVES_DAMAGE_MULTIPLIER",0, 0, 100);
gGameExternalOptions.ubMeleeDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","MELEE_DAMAGE_MULTIPLIER",0); gGameExternalOptions.ubMeleeDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","MELEE_DAMAGE_MULTIPLIER",0, 0, 100);
gGameExternalOptions.ubGunDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_DAMAGE_MULTIPLIER",0); gGameExternalOptions.ubGunDamageMultiplier = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_DAMAGE_MULTIPLIER",0, 0, 100);
//Strategic AI settings //Strategic AI settings
gGameExternalOptions.iMaxEnemyGroupSize = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_STRATEGIC_TEAM_SIZE",20); 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); 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); 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); 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); 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); 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); 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); 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); 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); gGameExternalOptions.iPercentElitesBonusExperienced = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERIENCED_ELITE_BONUS",0, 0, 100);
gGameExternalOptions.iPercentElitesBonusExpert = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_ELITE_BONUS",25); gGameExternalOptions.iPercentElitesBonusExpert = iniReader.ReadInteger("JA2 Gameplay Settings","EXPERT_ELITE_BONUS",25, 0, 100);
gGameExternalOptions.iPercentElitesBonusInsane = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_ELITE_BONUS",50); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); gGameExternalOptions.ubInsaneNumAwareBattles = iniReader.ReadInteger("JA2 Gameplay Settings","INSANE_NUM_AWARE_BATTLES", 4, 1, 10);
//New v1.13 settings //New v1.13 settings
gGameExternalOptions.gfEasyUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","NOVICE_UNLIMITED_POOL_OF_TROOPS",FALSE); gGameExternalOptions.gfEasyUnlimitedTroops = iniReader.ReadBoolean("JA2 Gameplay Settings","NOVICE_UNLIMITED_POOL_OF_TROOPS",FALSE);
@@ -695,64 +704,79 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfHardAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","EXPERT_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); gGameExternalOptions.gfInsaneAggressiveQueen = iniReader.ReadBoolean("JA2 Gameplay Settings","INSANE_QUEEN_AGGRESSIVE",TRUE);
// WDS - New AI
// Not ready yet...
// gGameExternalOptions.useNewAI = iniReader.ReadBoolean("JA2 Gameplay Settings","NEW_AGGRESSIVE_AI",FALSE);
gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("JA2 Gameplay Settings","ENEMY_INVESTIGATE_SECTOR",FALSE); gGameExternalOptions.gfInvestigateSector = iniReader.ReadBoolean("JA2 Gameplay Settings","ENEMY_INVESTIGATE_SECTOR",FALSE);
gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE); gGameExternalOptions.gfReassignPendingReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","REASSIGN_PENDING_REINFORCEMENTS",TRUE);
gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("JA2 Gameplay Settings","ENEMIES_ITEM_DROP", 0); gGameExternalOptions.ubEnemiesItemDrop = iniReader.ReadInteger("JA2 Gameplay Settings","ENEMIES_ITEM_DROP", 0, 0, 1);
gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("JA2 Gameplay Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE); gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("JA2 Gameplay Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE);
// Militia settings // Militia settings
gGameExternalOptions.guiAllowMilitiaGroupsDelay = iniReader.ReadInteger("JA2 Gameplay Settings","ALLOW_MILITIA_MOBILE_DELAY",1); 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); 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.gfTrainVeteranMilitia = iniReader.ReadBoolean("JA2 Gameplay Settings","TRAIN_VETERAN_MILITIA",FALSE);
gGameExternalOptions.gfAllowMilitiaGroups = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_MILITIA_MOBILE_GROUPS",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.gfmusttrainroaming = iniReader.ReadBoolean("JA2 Gameplay Settings","MUST_TRAIN_MOBILE_MILITIA",FALSE);
gGameExternalOptions.gfAllowReinforcements = iniReader.ReadBoolean("JA2 Gameplay Settings","ALLOW_REINFORCEMENTS",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.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); 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); 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); gGameExternalOptions.guiDivOfOriginalMilitia = iniReader.ReadInteger("JA2 Gameplay Settings","DIV_OF_ORIGINAL_MILITIA",4, 1, 100);
gGameExternalOptions.guiMinMilitiaSquadSize = iniReader.ReadInteger("JA2 Gameplay Settings","MINIMUM_MILITIA_SQUAD_SIZE",5); 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.guiMaxMilitiaSquadSize = iniReader.ReadInteger("JA2 Gameplay Settings","MAXIMUM_MILITIA_SQUAD_SIZE",20, gGameExternalOptions.guiMinMilitiaSquadSize, CODE_MAXIMUM_NUMBER_OF_REBELS);
gGameExternalOptions.guiMaxMilitiaSquadSizeBattle = iniReader.ReadInteger("JA2 Gameplay Settings","MAXIMUM_MILITIA_SQUAD_SIZE",20); //lal: this have to be the same value as MAXIMUM_MILITIA_SQUAD_SIZE!! do not change!! gGameExternalOptions.guiMaxMilitiaSquadSizeBattle = gGameExternalOptions.guiMaxMilitiaSquadSize;
gGameExternalOptions.iMaxMilitiaPerSector = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_MILITIA_PER_SECTOR",20); 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); 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); gGameExternalOptions.iMilitiaTrainingCost = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_TRAINING_COST",750, 10, 10000);
gGameExternalOptions.iMilitiaCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_COST_MODIFIER",3); gGameExternalOptions.iMilitiaCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_COST_MODIFIER",3, 1, 10);
gGameExternalOptions.iRegularCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","REGULAR_COST_MODIFIER",1); gGameExternalOptions.iRegularCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","REGULAR_COST_MODIFIER",1, 1, 10);
gGameExternalOptions.iVeteranCostModifier = iniReader.ReadInteger("JA2 Gameplay Settings","VETERAN_COST_MODIFIER",2); 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); gGameExternalOptions.iMinLoyaltyToTrain = iniReader.ReadInteger("JA2 Gameplay Settings","MIN_LOYALTY_TO_TRAIN",20, 0, 100);
gGameExternalOptions.gflimitedRoaming = iniReader.ReadBoolean("JA2 Gameplay Settings","RESTRICT_ROAMING",FALSE); 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) //Assignment Settings (training, repairing, doctoring, etc)
gGameExternalOptions.ubAssignmentUnitsPerDay = iniReader.ReadInteger("JA2 Gameplay Settings","ASSIGNMENT_UNITS_PER_DAY",24); 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); 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); gGameExternalOptions.ubTrainingSkillMin = iniReader.ReadInteger("JA2 Gameplay Settings","TRAINING_SKILL_MIN",0, 0, 100);
gGameExternalOptions.ubTrainingSkillMax = iniReader.ReadInteger("JA2 Gameplay Settings","TRAINING_SKILL_MAX",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); gGameExternalOptions.ubSelfTrainingDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","SELF_TRAINING_DIVISOR",1000, 1, 10000);
gGameExternalOptions.ubInstructedTrainingDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","INSTRUCTED_TRAINING_DIVISOR",3000); gGameExternalOptions.ubInstructedTrainingDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","INSTRUCTED_TRAINING_DIVISOR",3000, 1, 10000);
gGameExternalOptions.ubGunRangeTrainingBonus = iniReader.ReadInteger("JA2 Gameplay Settings","GUN_RANGE_TRAINING_BONUS",25); 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); gGameExternalOptions.ubTownMilitiaTrainingRate = iniReader.ReadInteger("JA2 Gameplay Settings","MILITIA_TRAINING_RATE",4, 1, 10);
gGameExternalOptions.ubMaxMilitiaTrainersPerSector = iniReader.ReadInteger("JA2 Gameplay Settings","MAX_MILITIA_TRAINERS_PER_SECTOR",2); 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); 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); 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); 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); gGameExternalOptions.ubLowActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","LOW_ACTIVITY_LEVEL",1, 1, 100);
gGameExternalOptions.ubMediumActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","MEDIUM_ACTIVITY_LEVEL",4); gGameExternalOptions.ubMediumActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","MEDIUM_ACTIVITY_LEVEL",4, 1, 100);
gGameExternalOptions.ubHighActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","HIGH_ACTIVITY_LEVEL",12); gGameExternalOptions.ubHighActivityLevel = iniReader.ReadInteger("JA2 Gameplay Settings","HIGH_ACTIVITY_LEVEL",12, 1, 100);
gGameExternalOptions.ubDoctoringRateDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","DOCTORING_RATE_DIVISOR",2400); gGameExternalOptions.ubDoctoringRateDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","DOCTORING_RATE_DIVISOR",2400, 1200, 24000);
gGameExternalOptions.ubHospitalHealingRate = iniReader.ReadInteger("JA2 Gameplay Settings","HOSPITAL_HEALING_RATE",5); 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); 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); 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);//OKLIFE = 15 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); 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); gGameExternalOptions.ubRepairRateDivisor = iniReader.ReadInteger("JA2 Gameplay Settings","REPAIR_RATE_DIVISOR",2500, 1250, 25000);
//Misc //Misc
@@ -782,7 +806,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.fRestrictFemaleEnemiesExceptElite = iniReader.ReadBoolean("JA2 Gameplay Settings","RESTRICT_FEMALE_ENEMIES_EXCEPT_ELITE",FALSE); gGameExternalOptions.fRestrictFemaleEnemiesExceptElite = iniReader.ReadBoolean("JA2 Gameplay Settings","RESTRICT_FEMALE_ENEMIES_EXCEPT_ELITE",FALSE);
// HEADROCK: Use Enhanced Item Description Box? // HEADROCK: Use Enhanced Item Description Box?
gGameExternalOptions.fEnhancedDescriptionBox = iniReader.ReadInteger("JA2 Gameplay Settings","USE_ENHANCED_DESCRIPTION_BOX",0); gGameExternalOptions.fEnhancedDescriptionBox = iniReader.ReadInteger("JA2 Gameplay Settings","USE_ENHANCED_DESCRIPTION_BOX",0, 0, 2);
// WANNE: Always use prof.dat?? // WANNE: Always use prof.dat??
gGameExternalOptions.fAlwaysUseProfDat = iniReader.ReadBoolean("JA2 Gameplay Settings", "ALWAYS_USE_PROF_DAT", FALSE); gGameExternalOptions.fAlwaysUseProfDat = iniReader.ReadBoolean("JA2 Gameplay Settings", "ALWAYS_USE_PROF_DAT", FALSE);
@@ -807,6 +831,8 @@ INT16 DynamicAdjustAPConstants(INT16 iniReadValue, INT16 iniDefaultValue, BOOLEA
void LoadGameAPBPConstants() void LoadGameAPBPConstants()
{ {
// WDS - Chris you should fix up the ReadIntegers below to have valid min/max values.
CIniReader iniReader(AP_BP_CONSTANTS_FILE); CIniReader iniReader(AP_BP_CONSTANTS_FILE);
//CHRISL: To allow for dynamic settings, we need to switch AP_MAXIMUM and AP_MINIMUM so that only the max value needs //CHRISL: To allow for dynamic settings, we need to switch AP_MAXIMUM and AP_MINIMUM so that only the max value needs
// to be changed to effect the entire system. This will require a change in the ENUM so that we can use a loop to // to be changed to effect the entire system. This will require a change in the ENUM so that we can use a loop to
@@ -949,6 +975,7 @@ void LoadGameAPBPConstants()
APBPConstants[BP_UNJAM] = iniReader.ReadInteger("APConstants","BP_WORK_ZIPPER",0); APBPConstants[BP_UNJAM] = iniReader.ReadInteger("APConstants","BP_WORK_ZIPPER",0);
SetupMaxActionPointsAnimation(); SetupMaxActionPointsAnimation();
#undef ReadInteger
} }
void FreeGameExternalOptions() void FreeGameExternalOptions()
@@ -1289,6 +1316,11 @@ void DisplayGameSettings( )
if (!is_networked) if (!is_networked)
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() );
#ifdef _DEBUG
// WDS - Add debug output here
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() );
#endif
////if( CHEATER_CHEAT_LEVEL() ) ////if( CHEATER_CHEAT_LEVEL() )
//{ //{
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() ); // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() );
+34 -3
View File
@@ -1,6 +1,8 @@
#ifndef _GAME_SETTINGS__H_ #ifndef _GAME_SETTINGS__H_
#define _GAME_SETTINGS__H_ #define _GAME_SETTINGS__H_
#include "Types.h"
//If you add any options, MAKE sure you add the corresponding string to the Options Screen string array //If you add any options, MAKE sure you add the corresponding string to the Options Screen string array
enum enum
@@ -263,7 +265,20 @@ typedef struct
BOOLEAN gfAllowSoldierToolTips; BOOLEAN gfAllowSoldierToolTips;
// WDS - Improve Tony's and Devin's inventory like BR's
BOOLEAN tonyUsesBRSetting;
BOOLEAN devinUsesBRSetting;
// WDS - Smart goggle switching
BOOLEAN smartGoggleSwitch;
// WDS - Automatically flag mines
BOOLEAN automaticallyFlagMines;
// WDS - Automatically try to save when an assertion failure occurs
BOOLEAN autoSaveOnAssertionFailure;
UINT32 autoSaveTime;
//Sight range //Sight range
UINT32 ubStraightSightRange; UINT32 ubStraightSightRange;
UINT32 ubVisDistDecreasePerRainIntensity; UINT32 ubVisDistDecreasePerRainIntensity;
@@ -290,20 +305,31 @@ typedef struct
UINT32 guiProlongLightningIfSeenSomeone; UINT32 guiProlongLightningIfSeenSomeone;
UINT32 guiChanceToDoLightningBetweenTurns; UINT32 guiChanceToDoLightningBetweenTurns;
// WDS: Progress settings // WDS - Progress settings
UINT32 ubGameProgressPortionKills; UINT32 ubGameProgressPortionKills;
UINT32 ubGameProgressPortionControl; UINT32 ubGameProgressPortionControl;
UINT32 ubGameProgressPortionIncome; UINT32 ubGameProgressPortionIncome;
UINT32 ubGameProgressPortionVisited; UINT32 ubGameProgressPortionVisited;
UINT32 ubGameProgressMinimum;
UINT32 ubGameProgressIncrement;
// WDS - Advanced start
UINT32 ubIMPStartingLevel;
// Event settings // Event settings
UINT32 ubGameProgressStartMadlabQuest; UINT32 ubGameProgressStartMadlabQuest;
UINT32 ubGameProgressMikeAvailable; UINT32 ubGameProgressMikeAvailable;
UINT32 ubGameProgressIggyAvaliable; UINT32 ubGameProgressIggyAvaliable;
BOOLEAN ubSendTroopsToDrassen; BOOLEAN ubSendTroopsToDrassen;
// WDS - make number of mercenaries, etc. be configurable
// group sizes
UINT32 ubGameMaximumNumberOfPlayerMercs;
UINT32 ubGameMaximumNumberOfPlayerVehicles;
UINT32 ubGameMaximumNumberOfEnemies;
UINT32 ubGameMaximumNumberOfCreatures;
UINT32 ubGameMaximumNumberOfRebels;
UINT32 ubGameMaximumNumberOfCivilians;
//Gameplay settings //Gameplay settings
@@ -346,6 +372,8 @@ typedef struct
UINT32 ubHardNumAwareBattles; UINT32 ubHardNumAwareBattles;
UINT32 ubInsaneNumAwareBattles; UINT32 ubInsaneNumAwareBattles;
// WDS - New AI
BOOLEAN useNewAI;
BOOLEAN gfEasyUnlimitedTroops; BOOLEAN gfEasyUnlimitedTroops;
BOOLEAN gfNormalUnlimitedTroops; BOOLEAN gfNormalUnlimitedTroops;
@@ -469,6 +497,9 @@ extern GAME_OPTIONS gGameOptions;
// Snap: Options read from an INI file in the default of custom Data directory // Snap: Options read from an INI file in the default of custom Data directory
extern GAME_EXTERNAL_OPTIONS gGameExternalOptions; extern GAME_EXTERNAL_OPTIONS gGameExternalOptions;
// WDS - Automatically try to save when an assertion failure occurs
extern bool alreadySaving;
BOOLEAN SaveGameSettings(); BOOLEAN SaveGameSettings();
BOOLEAN LoadGameSettings(); BOOLEAN LoadGameSettings();
// Snap: Read options from an INI file in the default of custom Data directory // Snap: Read options from an INI file in the default of custom Data directory
+18 -5
View File
@@ -1668,6 +1668,19 @@ void BtnBuyEquipmentButtonCallback(GUI_BUTTON *btn,INT32 reason)
//Transfer funds button callback //Transfer funds button callback
void BtnAuthorizeButtonCallback(GUI_BUTTON *btn,INT32 reason) void BtnAuthorizeButtonCallback(GUI_BUTTON *btn,INT32 reason)
{ {
// WDS - make number of mercenaries, etc. be configurable
// WDS DEBUG
if (LaptopSaveInfo.iCurrentBalance == 4500001) {
unsigned hired = 0;
while (hired < gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs) {
if (AimMemberHireMerc()) {
giIdOfLastHiredMerc = AimMercArray[gbCurrentIndex];
++hired;
}
++gbCurrentIndex;
}
return;
}
if (!(btn->uiFlags & BUTTON_ENABLED)) if (!(btn->uiFlags & BUTTON_ENABLED))
return; return;
@@ -1804,10 +1817,10 @@ INT8 AimMemberHireMerc()
//if we succesfully hired the merc //if we succesfully hired the merc
bReturnCode = HireMerc( &HireMercStruct ); bReturnCode = HireMerc( &HireMercStruct );
if( bReturnCode == MERC_HIRE_OVER_18_MERCS_HIRED ) if( bReturnCode == MERC_HIRE_OVER_PLAYER_LIMIT )
{ {
//display a warning saying u cant hire more than 18 mercs //display a warning saying u cant hire more than the max mercs
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_18_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL); DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_MAX_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
return(FALSE); return(FALSE);
} }
else if( bReturnCode == MERC_HIRE_FAILED ) else if( bReturnCode == MERC_HIRE_FAILED )
@@ -4204,10 +4217,10 @@ BOOLEAN QuickHireMerc()
SetFlagToForceHireMerc( TRUE ); SetFlagToForceHireMerc( TRUE );
bReturnCode = HireMerc( &HireMercStruct ); bReturnCode = HireMerc( &HireMercStruct );
SetFlagToForceHireMerc( FALSE ); SetFlagToForceHireMerc( FALSE );
if( bReturnCode == MERC_HIRE_OVER_18_MERCS_HIRED ) if( bReturnCode == MERC_HIRE_OVER_PLAYER_LIMIT )
{ {
//display a warning saying u cant hire more than 18 mercs //display a warning saying u cant hire more than 18 mercs
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_18_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL); DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_MAX_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
return(FALSE); return(FALSE);
} }
else if( bReturnCode == MERC_HIRE_FAILED ) else if( bReturnCode == MERC_HIRE_FAILED )
+5 -4
View File
@@ -142,13 +142,13 @@ void CreateACharacterFromPlayerEnteredStats( void )
// gender // gender
if ( fCharacterIsMale == TRUE ) if ( fCharacterIsMale == TRUE )
{ {
// male // male
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = MALE; gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = MALE;
} }
else else
{ {
// female // female
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = FEMALE; gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = FEMALE;
} }
@@ -175,7 +175,8 @@ void CreateACharacterFromPlayerEnteredStats( void )
// attitude // attitude
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bAttitude = ( INT8 )iAttitude; gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bAttitude = ( INT8 )iAttitude;
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bExpLevel = 1; // WDS: Advanced start
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bExpLevel = gGameExternalOptions.ubIMPStartingLevel;
// set time away // set time away
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMercStatus = 0; gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMercStatus = 0;
+6 -4
View File
@@ -26,6 +26,8 @@
#include "IMP MainPage.h" #include "IMP MainPage.h"
#include "IMP Confirm.h" #include "IMP Confirm.h"
#include "Game Clock.h" #include "Game Clock.h"
// WDS - make number of mercenaries, etc. be configurable
#include "Squads.h"
#endif #endif
void GetPlayerKeyBoardInputForIMPHomePage( void ); void GetPlayerKeyBoardInputForIMPHomePage( void );
@@ -396,7 +398,7 @@ void ProcessPlayerInputActivationString( void )
BOOLEAN freeMercSlot = TRUE; BOOLEAN freeMercSlot = TRUE;
// WANNE: Check total number of hired mercs // WANNE: Check total number of hired mercs
if( NumberOfMercsOnPlayerTeam() >= 18 ) if( NumberOfMercsOnPlayerTeam() >= gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs )
{ {
freeMercSlot = FALSE; freeMercSlot = FALSE;
} }
@@ -407,7 +409,7 @@ void ProcessPlayerInputActivationString( void )
// WANNE: Check total number of hired mercs // WANNE: Check total number of hired mercs
if( freeMercSlot == FALSE ) if( freeMercSlot == FALSE )
{ {
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_18_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL); DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_MAX_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
return; return;
} }
@@ -429,7 +431,7 @@ void ProcessPlayerInputActivationString( void )
// WANNE: Check total number of hired mercs // WANNE: Check total number of hired mercs
if( freeMercSlot == FALSE ) if( freeMercSlot == FALSE )
{ {
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_18_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL); DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_MAX_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
return; return;
} }
@@ -455,7 +457,7 @@ void ProcessPlayerInputActivationString( void )
// WANNE: Check total number of hired mercs // WANNE: Check total number of hired mercs
if( freeMercSlot == FALSE ) if( freeMercSlot == FALSE )
{ {
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_18_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL); DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, AimPopUpText[ AIM_MEMBER_ALREADY_HAVE_MAX_MERCS ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
return; return;
} }
+2 -1
View File
@@ -24,6 +24,7 @@
#include "soldier profile type.h" #include "soldier profile type.h"
#include "GameSettings.h" #include "GameSettings.h"
#include "Soldier Profile.h" #include "Soldier Profile.h"
#include "Squads.h"
#endif #endif
@@ -602,7 +603,7 @@ void BtnIMPMainPageBeginCallback(GUI_BUTTON *btn,INT32 reason)
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 3 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, BeginMessageBoxCallBack); DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 3 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, BeginMessageBoxCallBack);
} }
else if( NumberOfMercsOnPlayerTeam() >= 18 ) else if( NumberOfMercsOnPlayerTeam() >= gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs )
{ {
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 5 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, BeginMessageBoxCallBack); DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 5 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, BeginMessageBoxCallBack);
} }
+3 -1
View File
@@ -26,6 +26,7 @@
#include "Assignments.h" #include "Assignments.h"
#include "Map Screen Interface.h" #include "Map Screen Interface.h"
#endif #endif
#include <vector>
#define INS_CTRCT_ORDER_GRID_WIDTH 132 #define INS_CTRCT_ORDER_GRID_WIDTH 132
#define INS_CTRCT_ORDER_GRID_HEIGHT 216 #define INS_CTRCT_ORDER_GRID_HEIGHT 216
@@ -118,7 +119,8 @@ UINT8 gubNumberofDisplayedInsuranceGrids;
BOOLEAN gfChangeInsuranceFormButtons = FALSE; BOOLEAN gfChangeInsuranceFormButtons = FALSE;
UINT8 gubInsuranceMercArray[ 20 ]; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> gubInsuranceMercArray (CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS, 0);
INT16 gsCurrentInsuranceMercIndex; INT16 gsCurrentInsuranceMercIndex;
INT16 gsMaxPlayersOnTeam; INT16 gsMaxPlayersOnTeam;
Binary file not shown.
+669 -1409
View File
File diff suppressed because it is too large Load Diff
-4
View File
@@ -658,10 +658,6 @@ BOOLEAN CreateDestroyMainMenuButtons( BOOLEAN fCreate )
SGPFILENAME filename; SGPFILENAME filename;
SGPFILENAME filenameMP; SGPFILENAME filenameMP;
INT16 sSlot; INT16 sSlot;
#ifndef _DEBUG
CHAR16 zText[512];
#endif
if( fCreate ) if( fCreate )
{ {
+1 -1
View File
@@ -3017,4 +3017,4 @@ void client_disconnect (void)
{ {
ScreenMsg( FONT_LTGREEN, MSG_CHAT, L"client is not running"); ScreenMsg( FONT_LTGREEN, MSG_CHAT, L"client is not running");
} }
} }
+1 -1
View File
@@ -700,4 +700,4 @@ void server_disconnect (void)
{ {
ScreenMsg( FONT_LTBLUE, MSG_CHAT, MPServerMessage[7]); ScreenMsg( FONT_LTBLUE, MSG_CHAT, MPServerMessage[7]);
} }
} }
+1 -1
View File
@@ -400,4 +400,4 @@ pSoldier->EVENT_InternalSetSoldierPosition( sCellX, sCellY ,FALSE, FALSE, FALSE
// stage=1; // stage=1;
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"0" ); // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"0" );
// FireBulletGivenTarget( MercPtrs[0], 875, 995, 1, 11, -74, 0, 0 ); // FireBulletGivenTarget( MercPtrs[0], 875, 995, 1, 11, -74, 0, 0 );
//} //}
+116 -173
View File
@@ -476,7 +476,7 @@ void HandleOldBobbyRMailOrders();
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode ); extern BOOLEAN ValidateSoldierInitLinks( UINT8 ubCode );
#endif #endif
void TruncateStrategicGroupSizes(); void ValidateStrategicGroups();
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
// //
@@ -566,7 +566,7 @@ BOOLEAN LBENODE::Load( HWFILE hFile )
else else
{ {
//we shouldn't be loading from anything before the first change //we shouldn't be loading from anything before the first change
Assert(guiCurrentSaveGameVersion >= NIV_SAVEGAME_DATATYPE_CHANGE); AssertGE(guiCurrentSaveGameVersion, NIV_SAVEGAME_DATATYPE_CHANGE);
} }
return TRUE; return TRUE;
} }
@@ -588,7 +588,7 @@ BOOLEAN LBENODE::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapV
} }
} }
else { else {
Assert(guiCurrentSaveGameVersion >= NIV_SAVEGAME_DATATYPE_CHANGE); AssertGE(guiCurrentSaveGameVersion, NIV_SAVEGAME_DATATYPE_CHANGE);
} }
return TRUE; return TRUE;
} }
@@ -806,7 +806,7 @@ BOOLEAN DEALER_SPECIAL_ITEM::Load(HWFILE hFile)
else else
{ {
//this will never be loaded from sometime before the first change //this will never be loaded from sometime before the first change
Assert(guiCurrentSaveGameVersion >= NIV_SAVEGAME_DATATYPE_CHANGE); AssertGE(guiCurrentSaveGameVersion, NIV_SAVEGAME_DATATYPE_CHANGE);
} }
return TRUE; return TRUE;
} }
@@ -1618,7 +1618,7 @@ BOOLEAN StackedObjectData::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 u
} }
else { else {
//we shouldn't be loading this //we shouldn't be loading this
Assert(false); AssertMsg(false, "we shouldn't be loading this");
} }
return TRUE; return TRUE;
} }
@@ -1944,8 +1944,11 @@ BOOLEAN InitSaveDir()
return TRUE; return TRUE;
} }
// WDS - Automatically try to save when an assertion failure occurs
extern bool alreadySaving = false;
BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc )
BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
{ {
UINT32 uiNumBytesWritten=0; UINT32 uiNumBytesWritten=0;
HWFILE hFile=0; HWFILE hFile=0;
@@ -1968,8 +1971,9 @@ BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc )
#endif #endif
#endif #endif
if( ubSaveGameID >= NUM_SAVE_GAMES && ubSaveGameID != SAVE__ERROR_NUM && ubSaveGameID != SAVE__END_TURN_NUM ) if( ubSaveGameID >= NUM_SAVE_GAMES && ubSaveGameID < EARLIST_SPECIAL_SAVE )
return( FALSE ); //ddd return( FALSE ); //ddd
alreadySaving = true;
//clear out the save game header //clear out the save game header
memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) ); memset( &SaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) );
@@ -2808,7 +2812,7 @@ BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc )
//if we succesfully saved the game, mark this entry as the last saved game file //if we succesfully saved the game, mark this entry as the last saved game file
if( ubSaveGameID != SAVE__ERROR_NUM && ubSaveGameID != SAVE__END_TURN_NUM ) if( ubSaveGameID < EARLIST_SPECIAL_SAVE)
{ {
gGameSettings.bLastSavedGameSlot = ubSaveGameID; gGameSettings.bLastSavedGameSlot = ubSaveGameID;
} }
@@ -2855,6 +2859,8 @@ BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc )
//Check for enough free hard drive space //Check for enough free hard drive space
NextLoopCheckForEnoughFreeHardDriveSpace(); NextLoopCheckForEnoughFreeHardDriveSpace();
alreadySaving = false;
return( TRUE ); return( TRUE );
//if there is an error saving the game //if there is an error saving the game
@@ -2897,6 +2903,7 @@ FAILED_TO_SAVE:
Assert(guiCurrentSaveGameVersion == SAVE_GAME_VERSION); Assert(guiCurrentSaveGameVersion == SAVE_GAME_VERSION);
guiCurrentSaveGameVersion = SAVE_GAME_VERSION; guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
alreadySaving = false;
return( FALSE ); return( FALSE );
} }
@@ -2906,7 +2913,7 @@ UINT32 guiBrokenSaveGameVersion = 0;
extern int gEnemyPreservedTempFileVersion[256]; extern int gEnemyPreservedTempFileVersion[256];
extern int gCivPreservedTempFileVersion[256]; extern int gCivPreservedTempFileVersion[256];
BOOLEAN LoadSavedGame( UINT8 ubSavedGameID ) BOOLEAN LoadSavedGame( int ubSavedGameID )
{ {
HWFILE hFile; HWFILE hFile;
SAVED_GAME_HEADER SaveGameHeader; SAVED_GAME_HEADER SaveGameHeader;
@@ -3402,6 +3409,8 @@ BOOLEAN LoadSavedGame( UINT8 ubSavedGameID )
LoadGameFilePosition( FileGetPos( hFile ), "Strategic Movement Groups" ); LoadGameFilePosition( FileGetPos( hFile ), "Strategic Movement Groups" );
#endif #endif
ValidateStrategicGroups();
uiRelEndPerc += 30; uiRelEndPerc += 30;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"All the Map Temp files..." ); SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"All the Map Temp files..." );
@@ -4055,7 +4064,7 @@ BOOLEAN LoadSavedGame( UINT8 ubSavedGameID )
} }
uiRelEndPerc += 1; uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Contract renweal sequence stuff..." ); SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Contract renewal sequence stuff..." );
RenderProgressBar( 0, 100 ); RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc; uiRelStartPerc = uiRelEndPerc;
@@ -4076,7 +4085,7 @@ BOOLEAN LoadSavedGame( UINT8 ubSavedGameID )
return( FALSE ); return( FALSE );
} }
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
LoadGameFilePosition( FileGetPos( hFile ), "Contract renweal sequence stuff" ); LoadGameFilePosition( FileGetPos( hFile ), "Contract renewal sequence stuff" );
#endif #endif
} }
@@ -4273,13 +4282,6 @@ BOOLEAN LoadSavedGame( UINT8 ubSavedGameID )
gTacticalStatus.ubAttackBusyCount = 0; gTacticalStatus.ubAttackBusyCount = 0;
} }
if( guiCurrentSaveGameVersion < 64 )
{ //Militia/enemies/creature team sizes have been changed from 32 to 20. This function
//will simply kill off the excess. This will allow the ability to load previous saves, though
//there will still be problems, though a LOT less than there would be without this call.
TruncateStrategicGroupSizes();
}
// ATE: if we are within this window where skyridder was foobared, fix! // ATE: if we are within this window where skyridder was foobared, fix!
if ( guiCurrentSaveGameVersion >= 61 && guiCurrentSaveGameVersion <= 65 ) if ( guiCurrentSaveGameVersion >= 61 && guiCurrentSaveGameVersion <= 65 )
{ {
@@ -5233,19 +5235,79 @@ BOOLEAN SaveTacticalStatusToSavedGame( HWFILE hFile )
return( TRUE ); return( TRUE );
} }
void FailedLoadingGameCallBack( UINT8 bExitValue );
// WDS
// This was going to be used to allow for increasing the sizes of teams once a game started but it is unfinished
//TacticalTeamType savedTeamSettings[MAXTEAMS];
BOOLEAN LoadTacticalStatusFromSavedGame( HWFILE hFile ) BOOLEAN LoadTacticalStatusFromSavedGame( HWFILE hFile )
{ {
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
// for (unsigned idx=0; idx <= MAXTEAMS; ++idx) {
// savedTeamSettings[idx] = gTacticalStatus.Team[idx];
// }
//Read the gTacticalStatus to the saved game file //Read the gTacticalStatus to the saved game file
FileRead( hFile, &gTacticalStatus, sizeof( TacticalStatusType ), &uiNumBytesRead ); FileRead( hFile, &gTacticalStatus, sizeof( TacticalStatusType ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( TacticalStatusType ) ) if( uiNumBytesRead != sizeof( TacticalStatusType ) ) {
{
return(FALSE); return(FALSE);
} }
// for (unsigned idx=0; idx <= MAXTEAMS; ++idx) {
// gTacticalStatus.Team[idx] = savedTeamSettings[idx];
// }
// WDS - make number of mercenaries, etc. be configurable
// Check that the team lists match what we expect given the .ini settings
int cntFromFile = gTacticalStatus.Team[ OUR_TEAM ].bLastID - gTacticalStatus.Team[ OUR_TEAM ].bFirstID + 1;
int cntFromIni = gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs + gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles;
if (cntFromFile != cntFromIni) {
CHAR16 errorMessage[512];
swprintf(errorMessage, L"Internal error in reading mercenary/vehicle slots from save file: number of slots in save file (%d) differs from number of slots in .ini (%d)", cntFromFile, cntFromIni);
DoScreenIndependantMessageBox(errorMessage, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack );
return FALSE;
}
cntFromFile = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID - gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID + 1;
cntFromIni = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
if (cntFromFile != cntFromIni) {
CHAR16 errorMessage[512];
swprintf(errorMessage, L"Internal error in reading enemy slots from save file: number of slots in save file (%d) differs from number of slots in .ini (%d)", cntFromFile, cntFromIni);
DoScreenIndependantMessageBox(errorMessage, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack );
return FALSE;
}
cntFromFile = gTacticalStatus.Team[ CREATURE_TEAM ].bLastID - gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID + 1;
cntFromIni = gGameExternalOptions.ubGameMaximumNumberOfCreatures;
if (cntFromFile != cntFromIni) {
CHAR16 errorMessage[512];
swprintf(errorMessage, L"Internal error in reading creature slots from save file: number of slots in save file (%d) differs from number of slots in .ini (%d)", cntFromFile, cntFromIni);
DoScreenIndependantMessageBox(errorMessage, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack );
return FALSE;
}
cntFromFile = gTacticalStatus.Team[ MILITIA_TEAM ].bLastID - gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID + 1;
cntFromIni = gGameExternalOptions.ubGameMaximumNumberOfRebels;
if (cntFromFile != cntFromIni) {
CHAR16 errorMessage[512];
swprintf(errorMessage, L"Internal error in reading militia slots from save file: number of slots in save file (%d) differs from number of slots in .ini (%d)", cntFromFile, cntFromIni);
DoScreenIndependantMessageBox(errorMessage, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack );
return FALSE;
}
cntFromFile = gTacticalStatus.Team[ CIV_TEAM ].bLastID - gTacticalStatus.Team[ CIV_TEAM ].bFirstID + 1;
cntFromIni = gGameExternalOptions.ubGameMaximumNumberOfCivilians;
if (cntFromFile != cntFromIni) {
CHAR16 errorMessage[512];
swprintf(errorMessage, L"Internal error in reading civilian slots from save file: number of slots in save file (%d) differs from number of slots in .ini (%d)", cntFromFile, cntFromIni);
DoScreenIndependantMessageBox(errorMessage, MSG_BOX_FLAG_OK, FailedLoadingGameCallBack );
return FALSE;
}
// //
//Load the current sector location to the saved game file //Load the current sector location to the saved game file
// //
@@ -6590,173 +6652,54 @@ void UnPauseAfterSaveGame( void )
} }
} }
void TruncateStrategicGroupSizes()
void ValidateStrategicGroups()
{ {
GROUP *pGroup;
SECTORINFO *pSector; SECTORINFO *pSector;
INT32 i; INT32 i;
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
for( i = SEC_A1; i < SEC_P16; i++ ) for( i = SEC_A1; i < SEC_P16; i++ )
{ {
pSector = &SectorInfo[ i ]; pSector = &SectorInfo[ i ];
if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites > iMaxEnemyGroupSize ) if( pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites > gGameExternalOptions.iMaxEnemyGroupSize )
{ {
if( pSector->ubNumAdmins > pSector->ubNumTroops )
{
if( pSector->ubNumAdmins > pSector->ubNumElites )
{
pSector->ubNumAdmins = 20;
pSector->ubNumTroops = 0;
pSector->ubNumElites = 0;
}
else
{
pSector->ubNumAdmins = 0;
pSector->ubNumTroops = 0;
pSector->ubNumElites = 20;
}
}
else if( pSector->ubNumTroops > pSector->ubNumElites )
{
if( pSector->ubNumTroops > pSector->ubNumAdmins )
{
pSector->ubNumAdmins = 0;
pSector->ubNumTroops = 20;
pSector->ubNumElites = 0;
}
else
{
pSector->ubNumAdmins = 20;
pSector->ubNumTroops = 0;
pSector->ubNumElites = 0;
}
}
else
{
if( pSector->ubNumElites > pSector->ubNumTroops )
{
pSector->ubNumAdmins = 0;
pSector->ubNumTroops = 0;
pSector->ubNumElites = 20;
}
else
{
pSector->ubNumAdmins = 0;
pSector->ubNumTroops = 20;
pSector->ubNumElites = 0;
}
}
} }
//militia //militia
if( pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2] > iMaxEnemyGroupSize ) if( pSector->ubNumberOfCivsAtLevel[0] + pSector->ubNumberOfCivsAtLevel[1] + pSector->ubNumberOfCivsAtLevel[2] > gGameExternalOptions.iMaxEnemyGroupSize )
{ {
if( pSector->ubNumberOfCivsAtLevel[0] > pSector->ubNumberOfCivsAtLevel[1] )
{
if( pSector->ubNumberOfCivsAtLevel[0] > pSector->ubNumberOfCivsAtLevel[2] )
{
pSector->ubNumberOfCivsAtLevel[0] = 20;
pSector->ubNumberOfCivsAtLevel[1] = 0;
pSector->ubNumberOfCivsAtLevel[2] = 0;
}
else
{
pSector->ubNumberOfCivsAtLevel[0] = 0;
pSector->ubNumberOfCivsAtLevel[1] = 0;
pSector->ubNumberOfCivsAtLevel[2] = 20;
}
}
else if( pSector->ubNumberOfCivsAtLevel[1] > pSector->ubNumberOfCivsAtLevel[2] )
{
if( pSector->ubNumberOfCivsAtLevel[1] > pSector->ubNumberOfCivsAtLevel[0] )
{
pSector->ubNumberOfCivsAtLevel[0] = 0;
pSector->ubNumberOfCivsAtLevel[1] = 20;
pSector->ubNumberOfCivsAtLevel[2] = 0;
}
else
{
pSector->ubNumberOfCivsAtLevel[0] = 20;
pSector->ubNumberOfCivsAtLevel[1] = 0;
pSector->ubNumberOfCivsAtLevel[2] = 0;
}
}
else
{
if( pSector->ubNumberOfCivsAtLevel[2] > pSector->ubNumberOfCivsAtLevel[1] )
{
pSector->ubNumberOfCivsAtLevel[0] = 0;
pSector->ubNumberOfCivsAtLevel[1] = 0;
pSector->ubNumberOfCivsAtLevel[2] = 20;
}
else
{
pSector->ubNumberOfCivsAtLevel[0] = 0;
pSector->ubNumberOfCivsAtLevel[1] = 20;
pSector->ubNumberOfCivsAtLevel[2] = 0;
}
}
} }
} }
//Enemy groups
pGroup = gpGroupList; GROUP *pGroup = gpGroupList;
while( pGroup ) GROUP *next;
{ while( pGroup ) {
if( !pGroup->fPlayer ) next = pGroup->next;
{ if (pGroup->ubSectorX < MINIMUM_VALID_X_COORDINATE) {
if( pGroup->pEnemyGroup->ubNumAdmins + pGroup->pEnemyGroup->ubNumTroops + pGroup->pEnemyGroup->ubNumElites > iMaxEnemyGroupSize ) //ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
{
pGroup->ubGroupSize = 20;
if( pGroup->pEnemyGroup->ubNumAdmins > pGroup->pEnemyGroup->ubNumTroops )
{
if( pGroup->pEnemyGroup->ubNumAdmins > pGroup->pEnemyGroup->ubNumElites )
{
pGroup->pEnemyGroup->ubNumAdmins = 20;
pGroup->pEnemyGroup->ubNumTroops = 0;
pGroup->pEnemyGroup->ubNumElites = 0;
}
else
{
pGroup->pEnemyGroup->ubNumAdmins = 0;
pGroup->pEnemyGroup->ubNumTroops = 0;
pGroup->pEnemyGroup->ubNumElites = 20;
}
}
else if( pGroup->pEnemyGroup->ubNumTroops > pGroup->pEnemyGroup->ubNumElites )
{
if( pGroup->pEnemyGroup->ubNumTroops > pGroup->pEnemyGroup->ubNumAdmins )
{
pGroup->pEnemyGroup->ubNumAdmins = 0;
pGroup->pEnemyGroup->ubNumTroops = 20;
pGroup->pEnemyGroup->ubNumElites = 0;
}
else
{
pGroup->pEnemyGroup->ubNumAdmins = 20;
pGroup->pEnemyGroup->ubNumTroops = 0;
pGroup->pEnemyGroup->ubNumElites = 0;
}
}
else
{
if( pGroup->pEnemyGroup->ubNumElites > pGroup->pEnemyGroup->ubNumTroops )
{
pGroup->pEnemyGroup->ubNumAdmins = 0;
pGroup->pEnemyGroup->ubNumTroops = 0;
pGroup->pEnemyGroup->ubNumElites = 20;
}
else
{
pGroup->pEnemyGroup->ubNumAdmins = 0;
pGroup->pEnemyGroup->ubNumTroops = 20;
pGroup->pEnemyGroup->ubNumElites = 0;
}
}
}
} }
pGroup = pGroup->next; else if (pGroup->ubSectorX > MAXIMUM_VALID_X_COORDINATE) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
// RemoveGroupFromList( pGroup );
}
else if (pGroup->ubSectorY < MINIMUM_VALID_Y_COORDINATE) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
}
else if (pGroup->ubSectorY > MAXIMUM_VALID_Y_COORDINATE) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
// RemoveGroupFromList( pGroup );
}
else if (pGroup->ubSectorZ < MINIMUM_VALID_Z_COORDINATE) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
// RemoveGroupFromList( pGroup );
}
else if (pGroup->ubSectorZ > MAXIMUM_VALID_Z_COORDINATE) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
// RemoveGroupFromList( pGroup );
}
else if (pGroup->ubGroupSize == 0) {
//ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"...");
}
pGroup = next;
} }
} }
+12 -4
View File
@@ -13,10 +13,18 @@ class SOLDIERTYPE;
#define SIZE_OF_SAVE_GAME_DESC 128 #define SIZE_OF_SAVE_GAME_DESC 128
#define GAME_VERSION_LENGTH 16 #define GAME_VERSION_LENGTH 16
#define SAVE__ERROR_NUM 99 #define SAVE__ERROR_NUM 99
#define SAVE__END_TURN_NUM 98 #define SAVE__END_TURN_NUM 98
// WDS - Automatically try to save when an assertion failure occurs
#define SAVE__ASSERTION_FAILURE 97
#define SAVE__TIMED_AUTOSAVE 11
#define EARLIST_SPECIAL_SAVE 97
typedef struct typedef struct
{ {
@@ -71,8 +79,8 @@ void CreateSavedGameFileNameFromNumber( UINT8 ubSaveGameID, STR pzNewFileName
BOOLEAN InitSaveDir(); BOOLEAN InitSaveDir();
BOOLEAN SaveGame( UINT8 ubSaveGameID, STR16 pGameDesc ); BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc );
BOOLEAN LoadSavedGame( UINT8 ubSavedGameID ); BOOLEAN LoadSavedGame( int ubSavedGameID );
BOOLEAN CopySavedSoldierInfoToNewSoldier( SOLDIERTYPE *pDestSourceInfo, SOLDIERTYPE *pSourceInfo ); BOOLEAN CopySavedSoldierInfoToNewSoldier( SOLDIERTYPE *pDestSourceInfo, SOLDIERTYPE *pSourceInfo );
+5 -2
View File
@@ -36,6 +36,7 @@
#include "video2.h" #include "video2.h"
#endif #endif
#endif #endif
#include <vector>
//ATE: Added to let Wiz default creating mouse regions with no cursor, JA2 default to a cursor ( first one ) //ATE: Added to let Wiz default creating mouse regions with no cursor, JA2 default to a cursor ( first one )
@@ -133,14 +134,16 @@ GUI_BUTTON *gpCurrentFastHelpButton;
BOOLEAN gfRenderHilights = TRUE; BOOLEAN gfRenderHilights = TRUE;
BUTTON_PICS ButtonPictures[MAX_BUTTON_PICS]; //BUTTON_PICS ButtonPictures[MAX_BUTTON_PICS];
std::vector<BUTTON_PICS> ButtonPictures(MAX_BUTTON_PICS);
INT32 ButtonPicsLoaded; INT32 ButtonPicsLoaded;
UINT32 ButtonDestBuffer = BACKBUFFER; UINT32 ButtonDestBuffer = BACKBUFFER;
UINT32 ButtonDestPitch = 640*2; UINT32 ButtonDestPitch = 640*2;
UINT32 ButtonDestBPP = 16; UINT32 ButtonDestBPP = 16;
GUI_BUTTON *ButtonList[MAX_BUTTONS]; //GUI_BUTTON *ButtonList[MAX_BUTTONS];
std::vector<GUI_BUTTON *> ButtonList(MAX_BUTTONS);
INT32 ButtonsInList=0; INT32 ButtonsInList=0;
+4 -2
View File
@@ -149,7 +149,8 @@ typedef struct _GUI_BUTTON {
#define MAX_BUTTONS 400 #define MAX_BUTTONS 400
extern GUI_BUTTON *ButtonList[MAX_BUTTONS]; // Button System's Main Button List //extern GUI_BUTTON *ButtonList[MAX_BUTTONS]; // Button System's Main Button List
extern std::vector<GUI_BUTTON *> ButtonList;
#define GetButtonPtr(x) (((x>=0) && (x<MAX_BUTTONS))? ButtonList[x] : NULL) #define GetButtonPtr(x) (((x>=0) && (x<MAX_BUTTONS))? ButtonList[x] : NULL)
@@ -168,7 +169,8 @@ typedef struct {
#define MAX_BUTTON_PICS 256 #define MAX_BUTTON_PICS 256
extern BUTTON_PICS ButtonPictures[MAX_BUTTON_PICS]; //extern BUTTON_PICS ButtonPictures[MAX_BUTTON_PICS];
extern std::vector<BUTTON_PICS> ButtonPictures;
// Function protos for button system // Function protos for button system
+71 -37
View File
@@ -25,36 +25,44 @@
extern "C" { extern "C" {
#endif #endif
*/ */
#define INVALID_TOPIC 0xffff
#define MAX_TOPICS_ALLOTED 1024 #define MAX_TOPICS_ALLOTED 1024
extern BOOLEAN gfRecordToFile; extern BOOLEAN gfRecordToFile;
extern BOOLEAN gfRecordToDebugger; extern BOOLEAN gfRecordToDebugger;
extern UINT32 guiProfileStart, guiExecutions, guiProfileTime; extern UINT32 guiProfileStart, guiExecutions, guiProfileTime;
extern INT32 giProfileCount; extern INT32 giProfileCount;
#define PROFILE(x) guiProfileStart=GetTickCount(); \ #define PROFILE(x) guiProfileStart=GetTickCount(); \
guiExecutions=x; \ guiExecutions=x; \
for(giProfileCount=0; giProfileCount < x; giProfileCount++) for(giProfileCount=0; giProfileCount < x; giProfileCount++)
#define PROFILE_REPORT() guiProfileTime=(GetTickCount()-guiProfileStart); \ #define PROFILE_REPORT() guiProfileTime=(GetTickCount()-guiProfileStart); \
_RPT3(_CRT_WARN, "*** PROFILE REPORT: %d executions took %dms, average of %.2fms per iteration.\n", guiExecutions, guiProfileTime, (FLOAT)guiProfileTime/guiExecutions); _RPT3(_CRT_WARN, "*** PROFILE REPORT: %d executions took %dms, average of %.2fms per iteration.\n", guiExecutions, guiProfileTime, (FLOAT)guiProfileTime/guiExecutions);
extern void _Null(void); extern STR8 String(const STR8 String, ...);
extern STR8 String(const STR8 String, ...);
// This func is used by Assert()
inline void _Null() { }
#ifdef _DEBUG
#ifndef FORCE_ASSERTS_ON
#define FORCE_ASSERTS_ON
#endif
#endif
#if defined ( _DEBUG ) || defined ( FORCE_ASSERTS_ON ) #ifdef FORCE_ASSERTS_ON
// If DEBUG_ is defined, we need to initialize all the debug macros. Otherwise all the // If FORCE_ASSERTS_ON is defined, we need to initialize all the debug macros. Otherwise all the
// debug macros will be substituted by blank lines at compile time // debug macros will be substituted by blank lines at compile time
//******************************************************************************************* //*******************************************************************************************
// Debug Mode // Debug Mode
//******************************************************************************************* //*******************************************************************************************
// *****************************************************
// OLD ASSERT CODE. USE THE NEW ONES FURTHER DOWN BELOW
// *****************************************************
//Modified the Assertion code. As of the writing of this code, there are no other functions that //Modified the Assertion code. As of the writing of this code, there are no other functions that
//make use of _FailMessage. With that assumption made, we can then make two functions, the first Assert, taking //make use of _FailMessage. With that assumption made, we can then make two functions, the first Assert, taking
//one argument, and passing a NULL string. The second one, AssertMsg(), accepts a string as the second parameter. //one argument, and passing a NULL string. The second one, AssertMsg(), accepts a string as the second parameter.
@@ -64,7 +72,10 @@ extern STR8 String(const STR8 String, ...);
//Assert( pointer, "This pointer is null and you tried to access it in function A "); //Assert( pointer, "This pointer is null and you tried to access it in function A ");
//It'll make debugging a little simpler. In anal cases, you could build the string first, then assert //It'll make debugging a little simpler. In anal cases, you could build the string first, then assert
//with it. //with it.
extern void _FailMessage(STR8 pString, UINT32 uiLineNum, STR8 pSourceFile ); extern void _FailMessage(const char* message, unsigned lineNum, const char * functionName, const char* sourceFileName);
inline void _FailMessage(const char* message, unsigned lineNum, const char* sourceFileName) {
_FailMessage(message, lineNum, 0, sourceFileName );
}
#define Assert(a) (a) ? _Null() : _FailMessage( NULL, __LINE__, __FILE__ ) #define Assert(a) (a) ? _Null() : _FailMessage( NULL, __LINE__, __FILE__ )
#define AssertMsg(a,b) (a) ? _Null() : _FailMessage( b, __LINE__, __FILE__ ) #define AssertMsg(a,b) (a) ? _Null() : _FailMessage( b, __LINE__, __FILE__ )
@@ -72,6 +83,40 @@ extern void _FailMessage(STR8 pString, UINT32 uiLineNum, STR8 pSourceFile );
extern CHAR8 gubAssertString[512];//for long filenames extern CHAR8 gubAssertString[512];//for long filenames
// WDS - Enhanced debugging
// These provide more information than the original assertions. Assertions test their condition and
// if it fails they generate a message, try to save the game, then terminate the program.
// (a) is not NIL or generate a message and terminate
#define AssertNotNIL(a) ((a)!=0 ? _Null() : _FailMessage ("("#a" is a null pointer", __LINE__, __FUNCTION__, __FILE__))
// (a) is true or generate a message and terminate
#define AssertT(a) ((a) ? _Null() : _FailMessage ("("#a" is false but should be true", __LINE__, __FUNCTION__, __FILE__))
// (a) is false
#define AssertF(a) ((a) ? _Null() : _FailMessage ("("#a" is true but should be false", __LINE__, __FUNCTION__, __FILE__))
// (a == b)
//#define AssertEQs(a,as,b,bs) (((a)==(b)) ? _Null() : _FailMessage ("("#a" "#as") != ("#b" "#bs") but they should be equal", __LINE__, __FUNCTION__, __FILE__))
//#define AssertEQ(a,b) (AssertEQs(a,#a,b,#b))
#define AssertEQ(a,b) (((a)==(b)) ? _Null() : _FailMessage ("("#a") != ("#b") but they should be equal", __LINE__, __FUNCTION__, __FILE__))
// (a != b)
#define AssertNE(a,b) (((a)!=(b)) ? _Null() : _FailMessage ("("#a") == ("#b") but they should not be equal", __LINE__, __FUNCTION__, __FILE__))
// (a < b)
#define AssertLT(a,b) (((a)<(b)) ? _Null() : _FailMessage ("("#a") >= ("#b") but should be less than", __LINE__, __FUNCTION__, __FILE__))
// (a <= b)
#define AssertLE(a,b) (((a)<=(b)) ? _Null() : _FailMessage ("("#a") > ("#b") but should be less than or equal", __LINE__, __FUNCTION__, __FILE__))
// (a > b)
#define AssertGT(a,b) (((a)>(b)) ? _Null() : _FailMessage ("("#a") <= ("#b") but should be greater than", __LINE__, __FUNCTION__, __FILE__))
// (a >= b)
#define AssertGE(a,b) (((a)>=(b)) ? _Null() : _FailMessage ("("#a") < ("#b") but should be greater than or equal", __LINE__, __FUNCTION__, __FILE__))
#else #else
#define Assert(a) ((void *)0) #define Assert(a) ((void *)0)
@@ -90,8 +135,8 @@ extern CHAR8 gubAssertString[512];//for long filenames
#define InitializeDebugManager() DbgInitialize() #define InitializeDebugManager() DbgInitialize()
#define ShutdownDebugManager() DbgShutdown() #define ShutdownDebugManager() DbgShutdown()
extern BOOLEAN DbgInitialize(void); extern bool DbgInitialize();
extern void DbgShutdown(void); extern void DbgShutdown();
#ifdef SGP_DEBUG #ifdef SGP_DEBUG
@@ -101,7 +146,7 @@ extern void DbgShutdown(void);
// Debug Mode // Debug Mode
//******************************************************************************************* //*******************************************************************************************
extern BOOLEAN gfDebugTopics[MAX_TOPICS_ALLOTED]; extern bool gfDebugTopics[MAX_TOPICS_ALLOTED];
// These are the debug macros (the ones the use will use). The user should never call // These are the debug macros (the ones the use will use). The user should never call
// the actual debug functions directly // the actual debug functions directly
@@ -109,36 +154,25 @@ extern BOOLEAN gfDebugTopics[MAX_TOPICS_ALLOTED];
#define DebugBreakpoint() __asm { int 3 } #define DebugBreakpoint() __asm { int 3 }
#define DbgMessage(a, b, c) DbgMessageReal( (UINT16)(a), (UINT8)(TOPIC_MESSAGE), (UINT8)(b), (CHAR8 *)(c) ) #define DbgMessage(a, b, c) (gfDebugTopics[(a)] ? DbgMessageReal((a), TOPIC_MESSAGE, (b), (c) ) : _Null())
#define FastDebugMsg(a) _DebugMessage( (UINT8 *)(a), (UINT32)(__LINE__), (UINT8 *)(__FILE__) ) #define FastDebugMsg(a) _DebugMessage((a), __LINE__, __FILE__)
#define UnRegisterDebugTopic(a, b) DbgTopicRegistration( (UINT8)TOPIC_UNREGISTER, (UINT16 *)(&(a)), (CHAR8 *)(b) ) #define UnRegisterDebugTopic(a, b) DbgTopicRegistration( TOPIC_UNREGISTER, (a), (b) )
#define ClearAllDebugTopics( ) DbgClearAllTopics( ) #define ClearAllDebugTopics( ) DbgClearAllTopics( )
#define ErrorMsg(a) _DebugMessage( (UINT8 *)(a), (UINT32)(__LINE__), (UINT8 *)(__FILE__)) #define ErrorMsg(a) _DebugMessage( (a), __LINE__, __FILE__)
// Enable the debug topic we want #define RegisterJA2DebugTopic(a, b) DbgTopicRegistration( TOPIC_REGISTER, (a), (b) )
#if defined( JA2 ) || defined( UTIL )
#define RegisterJA2DebugTopic(a, b) DbgTopicRegistration( TOPIC_REGISTER, &(a), (b) )
#define RegisterDebugTopic(a, b) ((void *)0) #define RegisterDebugTopic(a, b) ((void *)0)
#define DebugMsg(a, b, c) DbgMessageReal( (a), TOPIC_MESSAGE, (b), (c) ) #define DebugMsg(a, b, c) DbgMessageReal( (a), TOPIC_MESSAGE, (b), (c) )
#else
#define RegisterJA2DebugTopic(a, b) ((void *)0)
#define RegisterDebugTopic(a, b) DbgTopicRegistration( (UINT8)TOPIC_REGISTER, (UINT16 *)(&(a)), (CHAR8 *)(b) )
#define DebugMsg(a) _DebugMessage((UINT8 *)(a), (UINT32)(__LINE__), (UINT8 *)(__FILE__))
#endif
// public interface to debug methods: // public interface to debug methods:
extern void DbgMessageReal(UINT16 uiTopicId, UINT8 uiCommand, UINT8 uiDebugLevel, STR8 strMessage); extern void DbgMessageReal(unsigned uiTopicId, unsigned uiCommand, unsigned uiDebugLevel, const char *strMessage);
extern BOOLEAN DbgSetDebugLevel(UINT16 TopicId, UINT8 uiDebugLevel); extern bool DbgSetDebugLevel(unsigned TopicId, unsigned uiDebugLevel);
extern void DbgFailedAssertion( BOOLEAN fExpression, STR8 szFile, int nLine ); extern void DbgTopicRegistration( unsigned ubCmd, const unsigned usTopicID, const char *zMessage );
#if _MSC_VER <= 1200 extern void DbgClearAllTopics( void );
extern void _FailMessage(UINT8 *pString, UINT32 uiLineNum, UINT8 *pSourceFile ); extern void _DebugMessage(const char *pSourceFile, unsigned uiLineNum, const char *pString);
#endif
extern void DbgTopicRegistration( UINT8 ubCmd, UINT16 *usTopicID, CHAR8 *zMessage );
extern void DbgClearAllTopics( void );
extern void _DebugMessage(UINT8 *pSourceFile, UINT32 uiLineNum, UINT8 *pString);
//******************************************************************************************* //*******************************************************************************************
+90 -235
View File
@@ -23,15 +23,12 @@
// undefine _DEBUG or you get linker errors. // undefine _DEBUG or you get linker errors.
#ifdef JA2_PRECOMPILED_HEADERS
#include "JA2 SGP ALL.H"
#elif defined( WIZ8_PRECOMPILED_HEADERS )
#include "WIZ8 SGP ALL.H"
#else
#include "types.h" #include "types.h"
#include <windows.h> #include <windows.h>
#include <ddeml.h> #include <ddeml.h>
#include <stdio.h> #include <stdio.h>
#include <string>
#include <sstream>
#include "debug.h" #include "debug.h"
#include "WCheck.h" #include "WCheck.h"
#include "TopicIDs.h" #include "TopicIDs.h"
@@ -51,7 +48,8 @@
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
#include "fileman.h" #include "fileman.h"
#endif #endif
#endif #include "GameSettings.h"
#include "SaveLoadGame.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -68,7 +66,7 @@ INT32 giProfileCount;
// they are required for the String() function, which is NOT a // they are required for the String() function, which is NOT a
// debug-mode only function, it's used in release-mode as well! -- DB // debug-mode only function, it's used in release-mode as well! -- DB
CHAR8 gubAssertString[512];//for long filenames CHAR8 gubAssertString[512];
#define MAX_MSG_LENGTH2 512 #define MAX_MSG_LENGTH2 512
CHAR8 gbTmpDebugString[8][MAX_MSG_LENGTH2]; CHAR8 gbTmpDebugString[8][MAX_MSG_LENGTH2];
@@ -99,43 +97,16 @@ extern "C" {
// //
//************************************************************************** //**************************************************************************
UINT16 TOPIC_MEMORY_MANAGER = INVALID_TOPIC;
UINT16 TOPIC_FILE_MANAGER = INVALID_TOPIC;
UINT16 TOPIC_DATABASE_MANAGER = INVALID_TOPIC;
UINT16 TOPIC_GAME = INVALID_TOPIC;
UINT16 TOPIC_SGP = INVALID_TOPIC;
UINT16 TOPIC_VIDEO = INVALID_TOPIC;
UINT16 TOPIC_INPUT = INVALID_TOPIC;
UINT16 TOPIC_STACK_CONTAINERS = INVALID_TOPIC;
UINT16 TOPIC_LIST_CONTAINERS = INVALID_TOPIC;
UINT16 TOPIC_QUEUE_CONTAINERS = INVALID_TOPIC;
UINT16 TOPIC_PRILIST_CONTAINERS = INVALID_TOPIC;
UINT16 TOPIC_HIMAGE = INVALID_TOPIC;
UINT16 TOPIC_ORDLIST_CONTAINERS = INVALID_TOPIC;
UINT16 TOPIC_3DENGINE = INVALID_TOPIC;
UINT16 TOPIC_VIDEOOBJECT = INVALID_TOPIC;
UINT16 TOPIC_FONT_HANDLER = INVALID_TOPIC;
UINT16 TOPIC_VIDEOSURFACE = INVALID_TOPIC;
UINT16 TOPIC_MOUSE_SYSTEM = INVALID_TOPIC;
UINT16 TOPIC_BUTTON_HANDLER = INVALID_TOPIC;
UINT16 TOPIC_MUTEX = INVALID_TOPIC;
UINT16 TOPIC_JA2 = 3;
UINT16 TOPIC_BLIT_QUEUE = INVALID_TOPIC;
UINT16 TOPIC_JA2OPPLIST = 2;
UINT16 TOPIC_JA2AI = 1;
UINT32 guiTimerID = 0; UINT32 guiTimerID = 0;
UINT8 guiDebugLevels[NUM_TOPIC_IDS]; // don't change this, Luis!!!!
BOOLEAN gfDebugTopics[MAX_TOPICS_ALLOTED];
UINT16 *gpDbgTopicPtrs[MAX_TOPICS_ALLOTED];
bool gfDebugTopics[MAX_TOPICS_ALLOTED];
// remove debug .txt file // remove debug .txt file
void RemoveDebugText( void ); void RemoveDebugText( void );
STRING512 gpcDebugLogFileName; STRING512 debugLogFileName;
FILE * debugLogFile = 0;
#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -161,26 +132,26 @@ STRING512 gpcDebugLogFileName;
// xxjun98:CJC ->creation // xxjun98:CJC ->creation
// //
//************************************************************************** //**************************************************************************
BOOLEAN DbgGetLogFileName( STRING512 pcName ) bool DbgGetLogFileName( STRING512 pcName )
{ {
// use the provided buffer to get the directory name, then tack on // use the provided buffer to get the directory name, then tack on
// "\debug.txt" // "\debug.txt"
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
if ( ! GetExecutableDirectory( pcName ) ) if ( ! GetExecutableDirectory( pcName ) )
{ {
return( FALSE ); return false;
} }
if ( strlen( pcName ) > (512 - strlen( "\\debug.txt" ) - 1 ) ) if ( strlen( pcName ) > (512 - strlen( "\\debug.txt" ) - 1 ) )
{ {
// no room! // no room!
return( FALSE ); return false;
} }
strcat( pcName, "\\debug.txt" ); strcat( pcName, "\\debug.txt" );
#endif #endif
return( TRUE ); return true;
} }
@@ -198,15 +169,8 @@ BOOLEAN DbgGetLogFileName( STRING512 pcName )
// //
//************************************************************************** //**************************************************************************
BOOLEAN DbgInitialize(void) bool DbgInitialize()
{ {
INT32 iX;
for( iX = 0; iX < MAX_TOPICS_ALLOTED; iX++ )
{
gpDbgTopicPtrs[iX] = NULL;
}
DbgClearAllTopics(); DbgClearAllTopics();
gfRecordToFile = TRUE; gfRecordToFile = TRUE;
@@ -214,15 +178,14 @@ BOOLEAN DbgInitialize(void)
gubAssertString[0] = '\0'; gubAssertString[0] = '\0';
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
if (! DbgGetLogFileName( gpcDebugLogFileName ) ) if (! DbgGetLogFileName( debugLogFileName ) ) {
{ return false;
return( FALSE );
} }
// clear debug text file out // clear debug text file out
RemoveDebugText( ); RemoveDebugText( );
#endif #endif
return(TRUE); return true;
} }
//************************************************************************** //**************************************************************************
@@ -239,9 +202,9 @@ BOOLEAN DbgInitialize(void)
// //
//************************************************************************** //**************************************************************************
void DbgShutdown(void) void DbgShutdown()
{ {
DbgMessageReal( (UINT16)(-1), CLIENT_SHUTDOWN, 0, "SGP Going Down" ); DbgMessageReal( -1, CLIENT_SHUTDOWN, 0, "SGP Going Down" );
} }
@@ -258,47 +221,26 @@ void DbgShutdown(void)
// //
//************************************************************************** //**************************************************************************
void DbgTopicRegistration( UINT8 ubCmd, UINT16 *usTopicID, CHAR8 *zMessage ) void DbgTopicRegistration( unsigned ubCmd, const unsigned usTopicID, const char *zMessage )
{ {
UINT16 usIndex,usUse;
BOOLEAN fFound;
if ( usTopicID == NULL ) if ( usTopicID == NULL )
return; return;
AssertGE(ubCmd, TOPIC_REGISTER);
AssertLE(ubCmd, TOPIC_UNREGISTER);
if( ubCmd == TOPIC_REGISTER ) if( ubCmd == TOPIC_REGISTER )
{ {
usUse = INVALID_TOPIC; gfDebugTopics[ usTopicID ] = true;
fFound = FALSE; DbgMessageReal(usTopicID, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage );
for( usIndex = 0; usIndex < MAX_TOPICS_ALLOTED && !fFound; usIndex++)
{
if ( !gfDebugTopics[usIndex] )
{
fFound = TRUE;
usUse = usIndex;
}
}
gfDebugTopics[ usUse ] = TRUE;
*usTopicID = usUse;
gpDbgTopicPtrs[usUse] = usTopicID;
DbgMessageReal(usUse, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage );
} }
else if( ubCmd == TOPIC_UNREGISTER ) else if( ubCmd == TOPIC_UNREGISTER )
{ {
if ( *usTopicID >= MAX_TOPICS_ALLOTED ) if ( usTopicID >= MAX_TOPICS_ALLOTED )
return; return;
DbgMessageReal( *usTopicID, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage ); DbgMessageReal( usTopicID, TOPIC_MESSAGE, DBG_LEVEL_0, zMessage );
gfDebugTopics[ *usTopicID ] = FALSE; gfDebugTopics[ usTopicID ] = false;
if (gpDbgTopicPtrs[ *usTopicID ] != NULL )
{
gpDbgTopicPtrs[ *usTopicID ] = NULL;
}
*usTopicID = INVALID_TOPIC;
} }
} }
@@ -309,9 +251,10 @@ void DbgTopicRegistration( UINT8 ubCmd, UINT16 *usTopicID, CHAR8 *zMessage )
// //
// ************************************************************************* // *************************************************************************
void RemoveDebugText( void ) void RemoveDebugText()
{ {
DeleteFile( gpcDebugLogFileName ); DeleteFile( debugLogFileName );
debugLogFile = 0;
} }
@@ -330,16 +273,9 @@ void RemoveDebugText( void )
void DbgClearAllTopics( void ) void DbgClearAllTopics( void )
{ {
UINT16 usIndex; for( unsigned usIndex = 0; usIndex < MAX_TOPICS_ALLOTED; usIndex++)
for( usIndex = 0; usIndex < MAX_TOPICS_ALLOTED; usIndex++)
{ {
gfDebugTopics[ usIndex ] = FALSE; gfDebugTopics[ usIndex ] = false;
if ( gpDbgTopicPtrs[ usIndex ] != NULL )
{
*gpDbgTopicPtrs[usIndex] = INVALID_TOPIC;
gpDbgTopicPtrs[usIndex] = NULL;
}
} }
} }
@@ -356,13 +292,13 @@ void DbgClearAllTopics( void )
// xxnov96:HJH ->creation // xxnov96:HJH ->creation
// //
//************************************************************************** //**************************************************************************
void DbgMessageReal(UINT16 uiTopicId, UINT8 uiCommand, UINT8 uiDebugLevel, STR8 strMessage) void DbgMessageReal(unsigned uiTopicId, unsigned uiCommand, unsigned uiDebugLevel, const char* strMessage)
{ {
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
FILE *OutFile; static FILE *OutFile = 0;
#endif #endif
// Check for a registered topic ID // Check for a registered topic ID
if ( uiTopicId < MAX_TOPICS_ALLOTED )//&& gfDebugTopics[uiTopicId] ) if ( (uiTopicId < MAX_TOPICS_ALLOTED) && (gfDebugTopics[uiTopicId]) )
{ {
OutputDebugString ( strMessage ); OutputDebugString ( strMessage );
OutputDebugString ( "\n" ); OutputDebugString ( "\n" );
@@ -370,10 +306,11 @@ void DbgMessageReal(UINT16 uiTopicId, UINT8 uiCommand, UINT8 uiDebugLevel, STR8
//add _NO_DEBUG_TXT to your SGP preprocessor definitions to avoid this f**king huge file from //add _NO_DEBUG_TXT to your SGP preprocessor definitions to avoid this f**king huge file from
//slowly growing behind the scenes!!!! //slowly growing behind the scenes!!!!
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
if ((OutFile = fopen(gpcDebugLogFileName, "a+t")) != NULL) if (!debugLogFile)
{ debugLogFile = fopen(debugLogFileName, "a+t");
fprintf(OutFile, "%s\n", strMessage); if (debugLogFile) {
fclose(OutFile); fprintf(debugLogFile, "%s\n", strMessage);
fflush( debugLogFile );
} }
#endif #endif
} }
@@ -393,39 +330,9 @@ void DbgMessageReal(UINT16 uiTopicId, UINT8 uiCommand, UINT8 uiDebugLevel, STR8
// //
//************************************************************************** //**************************************************************************
BOOLEAN DbgSetDebugLevel(UINT16 uiTopicId, UINT8 uiDebugLevel) bool DbgSetDebugLevel(unsigned uiTopicId, unsigned uiDebugLevel)
{ {
return(TRUE); return true;
}
//**************************************************************************
//
// DbgFailedAssertion
//
//
//
// Parameter List :
// Return Value :
// Modification history :
//
// xxnov96:HJH ->creation
//
//**************************************************************************
void DbgFailedAssertion( BOOLEAN fExpression, STR8 szFile, int nLine )
{
#ifndef _NO_DEBUG_TXT
FILE *OutFile;
if ( fExpression == FALSE )
{
if ((OutFile = fopen(gpcDebugLogFileName, "a+t")) != NULL)
{
fprintf(OutFile, "Assertion Failed at:\n line %i\n %s\n", nLine, szFile);
fclose(OutFile);
}
}
#endif
} }
@@ -447,12 +354,9 @@ void _DebugRecordToDebugger(BOOLEAN gfState)
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Wiz8 compatible debug messaging // Wiz8 compatible debug messaging
void _DebugMessage(UINT8 *pString, UINT32 uiLineNum, UINT8 *pSourceFile) void _DebugMessage(const char *pString, unsigned uiLineNum, const char *pSourceFile)
{ {
CHAR8 ubOutputString[512]; CHAR8 ubOutputString[512];
#ifndef _NO_DEBUG_TXT
FILE *DebugFile;
#endif
// //
// Build the output string // Build the output string
@@ -476,83 +380,78 @@ void _DebugMessage(UINT8 *pString, UINT32 uiLineNum, UINT8 *pSourceFile)
#ifndef _NO_DEBUG_TXT #ifndef _NO_DEBUG_TXT
if (gfRecordToFile) if (gfRecordToFile)
{ {
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL) if (!debugLogFile)
{ debugLogFile = fopen( debugLogFileName, "a+t" );
fputs( ubOutputString, DebugFile ); if (debugLogFile) {
fclose( DebugFile ); fputs( ubOutputString, debugLogFile );
fflush( debugLogFile );
} }
} }
#endif #endif
} }
#else #else
BOOLEAN DbgInitialize(void) { return true; }; bool DbgInitialize() { return true; };
void DbgShutdown(void) {}; void DbgShutdown() {};
#endif #endif
#if defined ( _DEBUG ) || defined ( FORCE_ASSERTS_ON ) #ifdef FORCE_ASSERTS_ON
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// This func is used by Assert()
void _Null(void)
{
}
extern HVOBJECT FontObjs[25]; extern HVOBJECT FontObjs[25];
#ifdef JA2 //JAGGED ALLIANCE 2 VERSION ONLY
void _FailMessage( STR8 pString, UINT32 uiLineNum, STR8 pSourceFile ) void _FailMessage(const char* message, unsigned lineNum, const char * functionName, const char* sourceFileName)
{ {
CHAR8 ubOutputString[512]; // This function shouldn't recurse
#ifndef _NO_DEBUG_TXT static bool alreadyInThisFunction = false;
MSG Message; if (alreadyInThisFunction)
// FILE *DebugFile; return;
#endif alreadyInThisFunction = true;
std::stringstream basicInformation;
basicInformation << "Assertion Failure [Line " << lineNum;
if (functionName) {
basicInformation << " in function " << functionName;
}
basicInformation << " in file " << sourceFileName << "]";
std::stringstream outputString;
outputString << "{ " << GetTickCount() << " } " << basicInformation;
//Build the output strings //Build the output strings
sprintf( ubOutputString, "{ %ld } Assertion Failure [Line %d in \n%c %s]\n", GetTickCount(), uiLineNum, '\n', pSourceFile ); if( message )
if( pString ) sprintf( gubAssertString, message );
sprintf( gubAssertString, pString );
else else
sprintf( gubAssertString, "" ); sprintf( gubAssertString, "" );
//Output to debugger //Output to debugger
if (gfRecordToDebugger) if (gfRecordToDebugger)
OutputDebugString( ubOutputString ); OutputDebugString( outputString.str().c_str() );
//Record to file if required DbgMessage( TOPIC_GAME, DBG_LEVEL_1, outputString.str().c_str());
#ifndef _NO_DEBUG_TXT
#if 0
if (gfRecordToFile)
{
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL)
{
fputs( ubOutputString, DebugFile );
fclose( DebugFile );
}
}
#endif
// 0verhaul: Replacement for the above. More consistent.
DbgMessage( TOPIC_GAME, DBG_LEVEL_1, ubOutputString);
#if 0
if( !FontObjs[0] )
{ //Font manager hasn't yet been initialized so use the windows error system
sprintf( gubErrorText, "Assertion Failure -- Line %d in %s", uiLineNum, pSourceFile );
MessageBox( NULL, gubErrorText, "Jagged Alliance 2 v1.13", MB_OK );
gfProgramIsRunning = FALSE;
return;
}
#endif
//Kris:
//NASTY HACK, THE GAME IS GOING TO DIE ANYWAY, SO WHO CARES WHAT WE DO.
//This will actually bring up a screen that prints out the assert message //This will actually bring up a screen that prints out the assert message
//until the user hits esc or alt-x. //until the user hits esc or alt-x.
sprintf( gubErrorText, "Assertion Failure -- Line %d in %s %s", uiLineNum, std::string("\n").c_str(), pSourceFile ); // WDS - Automatically try to save when an assertion failure occurs
if (gGameExternalOptions.autoSaveOnAssertionFailure &&
!alreadySaving) {
sprintf( gubErrorText, "%s. Attempting to do a debug save as SaveGame%d.sav (this may fail)", basicInformation.str().c_str(), SAVE__ASSERTION_FAILURE );
} else {
sprintf( gubErrorText, "%s", basicInformation.str().c_str());
}
SetPendingNewScreen( ERROR_SCREEN ); SetPendingNewScreen( ERROR_SCREEN );
SetCurrentScreen( ERROR_SCREEN ); SetCurrentScreen( ERROR_SCREEN );
// WDS - Automatically try to save when an assertion failure occurs
if (gGameExternalOptions.autoSaveOnAssertionFailure &&
!alreadySaving) {
SaveGame( SAVE__ASSERTION_FAILURE, L"Assertion Failure Auto Save" );
}
MSG Message;
while (gfProgramIsRunning) while (gfProgramIsRunning)
{ {
if (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE)) if (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE))
@@ -571,55 +470,11 @@ void _FailMessage( STR8 pString, UINT32 uiLineNum, STR8 pSourceFile )
gfSGPInputReceived = FALSE; gfSGPInputReceived = FALSE;
} }
} }
#endif
alreadyInThisFunction = false;
exit(0); exit(0);
} }
#else //NOT JAGGED ALLIANCE 2
void _FailMessage(STR8 pString, UINT32 uiLineNum, STR8 pSourceFile)
{
CHAR8 ubOutputString[512];
BOOLEAN fDone = FALSE;
#ifndef _NO_DEBUG_TXT
FILE *DebugFile;
#endif
// Build the output string
sprintf( ubOutputString, "{ %ld } Assertion Failure: %s [Line %d in %s]\n", GetTickCount(), pString, uiLineNum, pSourceFile );
if( pString )
sprintf( gubAssertString, pString );
// Output to debugger
if (gfRecordToDebugger)
{
OutputDebugString( ubOutputString );
if( pString )
{ //tag on the assert message
OutputDebugString( gubAssertString );
}
}
// Record to file if required
#ifndef _NO_DEBUG_TXT
if (gfRecordToFile)
{
if ((DebugFile = fopen( gpcDebugLogFileName, "a+t" )) != NULL)
{
fputs( ubOutputString, DebugFile );
if( pString )
{ //tag on the assert message
fputs( gubAssertString, DebugFile );
}
fclose( DebugFile );
}
}
#endif
exit( 0 );
}
#endif
#endif #endif
// This is NOT a _DEBUG only function! It is also needed in // This is NOT a _DEBUG only function! It is also needed in
+11 -57
View File
@@ -1,23 +1,11 @@
#ifdef JA2_PRECOMPILED_HEADERS #ifdef JA2_PRECOMPILED_HEADERS
#include "JA2 SGP ALL.H" #include "JA2 SGP ALL.H"
#elif defined( WIZ8_PRECOMPILED_HEADERS )
#include "WIZ8 SGP ALL.H"
#else #else
#include "Random.h" #include "Random.h"
#endif #endif
#ifdef PRERANDOM_GENERATOR UINT32 guiPreRandomIndex = 0;
UINT32 guiPreRandomNums[ MAX_PREGENERATED_NUMS ];
UINT32 guiPreRandomIndex = 0;
UINT32 guiPreRandomNums[ MAX_PREGENERATED_NUMS ];
#ifdef JA2BETAVERSION
UINT32 guiRandoms = 0;
UINT32 guiPreRandoms = 0;
BOOLEAN gfCountRandoms = FALSE;
#endif
#endif
void InitializeRandom() void InitializeRandom()
@@ -25,27 +13,19 @@ void InitializeRandom()
// Seed the random-number generator with current time so that // Seed the random-number generator with current time so that
// the numbers will be different every time we run. // the numbers will be different every time we run.
srand( (unsigned) time(NULL) ); srand( (unsigned) time(NULL) );
#ifdef PRERANDOM_GENERATOR
//Pregenerate all of the random numbers. //Pregenerate all of the random numbers.
for( guiPreRandomIndex = 0; guiPreRandomIndex < MAX_PREGENERATED_NUMS; guiPreRandomIndex++ ) for( guiPreRandomIndex = 0; guiPreRandomIndex < MAX_PREGENERATED_NUMS; guiPreRandomIndex++ )
{ {
guiPreRandomNums[ guiPreRandomIndex ] = rand(); guiPreRandomNums[ guiPreRandomIndex ] = rand();
} }
guiPreRandomIndex = 0; guiPreRandomIndex = 0;
#endif
} }
// Returns a pseudo-random integer between 0 and uiRange // Returns a pseudo-random integer between 0 and uiRange
UINT32 Random(UINT32 uiRange) UINT32 Random(UINT32 uiRange)
{ {
// Always return 0, if no range given (it's not an error) // Always return 0, if no range given (it's not an error)
#ifdef JA2BETAVERSION
if( gfCountRandoms )
{
guiRandoms++;
}
#endif
if (uiRange == 0) if (uiRange == 0)
return(0); return(0);
return rand() * uiRange / RAND_MAX % uiRange; return rand() * uiRange / RAND_MAX % uiRange;
@@ -53,20 +33,13 @@ UINT32 Random(UINT32 uiRange)
BOOLEAN Chance( UINT32 uiChance ) BOOLEAN Chance( UINT32 uiChance )
{ {
AssertLE(uiChance, 100);
return (BOOLEAN)(Random( 100 ) < uiChance); return (BOOLEAN)(Random( 100 ) < uiChance);
} }
#ifdef PRERANDOM_GENERATOR
UINT32 PreRandom( UINT32 uiRange ) UINT32 PreRandom( UINT32 uiRange )
{ {
UINT32 uiNum; UINT32 uiNum;
#ifdef JA2BETAVERSION
if( gfCountRandoms )
{
guiPreRandoms++;
}
#endif
if( !uiRange ) if( !uiRange )
return 0; return 0;
//Extract the current pregenerated number //Extract the current pregenerated number
@@ -98,25 +71,6 @@ UINT32 PreRandom( UINT32 uiRange )
BOOLEAN PreChance( UINT32 uiChance ) BOOLEAN PreChance( UINT32 uiChance )
{ {
AssertLE(uiChance, 100);
return (BOOLEAN)(PreRandom( 100 ) < uiChance); return (BOOLEAN)(PreRandom( 100 ) < uiChance);
} }
#ifdef JA2BETAVERSION
void CountRandomCalls( BOOLEAN fStart )
{
gfCountRandoms = fStart;
if( fStart )
{
guiRandoms = 0;
guiPreRandoms = 0;
}
}
void GetRandomCalls( UINT32 *puiRandoms, UINT32 *puiPreRandoms )
{
*puiRandoms = guiRandoms;
*puiPreRandoms = guiPreRandoms;
}
#endif
#endif
+26 -60
View File
@@ -1,66 +1,32 @@
#ifndef _TOPICIDS_H #ifndef _TOPICIDS_H
#define _TOPICIDS_H #define _TOPICIDS_H
// YOU MUST KEEP THIS VARIABLE UP TO DATE !!!! const unsigned INVALID_TOPIC = 0xffff;
#define NUM_TOPIC_IDS 23 const unsigned TOPIC_MEMORY_MANAGER = 24;
const unsigned TOPIC_FILE_MANAGER = 23;
/* #define TOPIC_MEMORY_MANAGER 0 const unsigned TOPIC_DATABASE_MANAGER = 22;
#define TOPIC_FILE_MANAGER 1 const unsigned TOPIC_GAME = 21;
#define TOPIC_DATABASE_MANAGER 2 const unsigned TOPIC_SGP = 20;
#define TOPIC_GAME 3 const unsigned TOPIC_VIDEO = 19;
#define TOPIC_SGP 4 const unsigned TOPIC_INPUT = 18;
#define TOPIC_VIDEO 5 const unsigned TOPIC_STACK_CONTAINERS = 17;
#define TOPIC_INPUT 6 const unsigned TOPIC_LIST_CONTAINERS = 16;
#define TOPIC_STACK_CONTAINERS 7 const unsigned TOPIC_QUEUE_CONTAINERS = 15;
#define TOPIC_LIST_CONTAINERS 8 const unsigned TOPIC_PRILIST_CONTAINERS = 14;
#define TOPIC_QUEUE_CONTAINERS 9 const unsigned TOPIC_HIMAGE = 13;
#define TOPIC_PRILIST_CONTAINERS 10 const unsigned TOPIC_ORDLIST_CONTAINERS = 12;
#define TOPIC_HIMAGE 11 const unsigned TOPIC_3DENGINE = 11;
#define TOPIC_ORDLIST_CONTAINERS 12 const unsigned TOPIC_VIDEOOBJECT = 10;
#define TOPIC_3DENGINE 13 const unsigned TOPIC_FONT_HANDLER = 9;
#define TOPIC_VIDEOOBJECT 14 const unsigned TOPIC_VIDEOSURFACE = 8;
#define TOPIC_FONT_HANDLER 15 const unsigned TOPIC_MOUSE_SYSTEM = 7;
#define TOPIC_VIDEOSURFACE 16 const unsigned TOPIC_BUTTON_HANDLER = 6;
#define TOPIC_MOUSE_SYSTEM 17 const unsigned TOPIC_MUTEX = 5;
#define TOPIC_BUTTON_HANDLER 18 const unsigned TOPIC_JA2INTERRUPT = 4;
#define TOPIC_MUTEX 19 const unsigned TOPIC_JA2 = 3;
#define TOPIC_JA2 20 const unsigned TOPIC_BLIT_QUEUE = INVALID_TOPIC;
#define TOPIC_BLIT_QUEUE 21 const unsigned TOPIC_JA2OPPLIST = 2;
#define TOPIC_JA2OPPLIST 22 const unsigned TOPIC_JA2AI = 1;
*/
#ifdef __cplusplus
extern "C" {
#endif
extern UINT16 TOPIC_MEMORY_MANAGER;
extern UINT16 TOPIC_FILE_MANAGER;
extern UINT16 TOPIC_DATABASE_MANAGER;
extern UINT16 TOPIC_GAME;
extern UINT16 TOPIC_SGP;
extern UINT16 TOPIC_VIDEO;
extern UINT16 TOPIC_INPUT;
extern UINT16 TOPIC_STACK_CONTAINERS;
extern UINT16 TOPIC_LIST_CONTAINERS;
extern UINT16 TOPIC_QUEUE_CONTAINERS;
extern UINT16 TOPIC_PRILIST_CONTAINERS;
extern UINT16 TOPIC_HIMAGE;
extern UINT16 TOPIC_ORDLIST_CONTAINERS;
extern UINT16 TOPIC_3DENGINE;
extern UINT16 TOPIC_VIDEOOBJECT;
extern UINT16 TOPIC_FONT_HANDLER;
extern UINT16 TOPIC_VIDEOSURFACE;
extern UINT16 TOPIC_MOUSE_SYSTEM;
extern UINT16 TOPIC_BUTTON_HANDLER;
extern UINT16 TOPIC_MUTEX;
extern UINT16 TOPIC_JA2;
extern UINT16 TOPIC_BLIT_QUEUE;
extern UINT16 TOPIC_JA2OPPLIST;
extern UINT16 TOPIC_JA2AI;
#ifdef __cplusplus
}
#endif
#endif // NUM_TOPICS_IDS #endif // NUM_TOPICS_IDS
-15
View File
@@ -6,23 +6,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void InitializeRandom(void); extern void InitializeRandom(void);
extern UINT32 Random( UINT32 uiRange ); extern UINT32 Random( UINT32 uiRange );
//Chance( 74 ) returns TRUE 74% of the time. If uiChance >= 100, then it will always return TRUE. //Chance( 74 ) returns TRUE 74% of the time. If uiChance >= 100, then it will always return TRUE.
extern BOOLEAN Chance( UINT32 uiChance ); extern BOOLEAN Chance( UINT32 uiChance );
//Wizardry can use it too, but I'm saving them a K in the meantime...
//If Wizardry wants it, then removing the #ifdef JA2 will make it work.
#ifdef JA2
#define PRERANDOM_GENERATOR
#endif
#ifdef PRERANDOM_GENERATOR
//Returns a pregenerated random number. //Returns a pregenerated random number.
//Used to deter Ian's tactic of shoot, miss, restore saved game :) //Used to deter Ian's tactic of shoot, miss, restore saved game :)
extern UINT32 PreRandom( UINT32 uiRange ); extern UINT32 PreRandom( UINT32 uiRange );
@@ -33,10 +22,6 @@ extern BOOLEAN Chance( UINT32 uiChance );
#define MAX_PREGENERATED_NUMS 256 #define MAX_PREGENERATED_NUMS 256
extern UINT32 guiPreRandomIndex; extern UINT32 guiPreRandomIndex;
extern UINT32 guiPreRandomNums[ MAX_PREGENERATED_NUMS ]; extern UINT32 guiPreRandomNums[ MAX_PREGENERATED_NUMS ];
#endif
#ifdef __cplusplus
}
#endif
#endif #endif
+2 -2
View File
@@ -387,7 +387,7 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP
break; break;
case FALSE: // We are suspending direct draw case FALSE: // We are suspending direct draw
if (iScreenMode == 0)//hayden if (iScreenMode == 0)
{ {
#ifdef JA2 #ifdef JA2
// pause the JA2 Global clock // pause the JA2 Global clock
@@ -1183,4 +1183,4 @@ void ProcessJa2CommandLineBeforeInitialization(CHAR8 *pCommandLine)
} }
MemFree(pCopy); MemFree(pCopy);
} }
+89 -21
View File
@@ -61,6 +61,7 @@
#include "Map Screen Interface Map Inventory.h" #include "Map Screen Interface Map Inventory.h"
#include "interface dialogue.h" #include "interface dialogue.h"
#endif #endif
#include <vector>
//forward declarations of common classes to eliminate includes //forward declarations of common classes to eliminate includes
class OBJECTTYPE; class OBJECTTYPE;
@@ -197,7 +198,7 @@ BOOLEAN gfAddDisplayBoxToWaitingQueue = FALSE;
// redraw character list // redraw character list
extern BOOLEAN fDrawCharacterList; extern BOOLEAN fDrawCharacterList;
extern BOOLEAN fSelectedListOfMercsForMapScreen[ MAX_CHARACTER_COUNT ]; extern BOOLEAN fSelectedListOfMercsForMapScreen[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
SOLDIERTYPE *gpDismissSoldier = NULL; SOLDIERTYPE *gpDismissSoldier = NULL;
@@ -517,6 +518,8 @@ void ChangeSoldiersAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment )
// values like fFixingRobot. It will clear all subsidiary values so we don't leave the merc in a messed // values like fFixingRobot. It will clear all subsidiary values so we don't leave the merc in a messed
// up state! // up state!
AssertNotNIL(pSoldier);
pSoldier->bAssignment = bAssignment; pSoldier->bAssignment = bAssignment;
/// don't kill iVehicleId, though, 'cause militia training tries to put guys back in their vehicles when it's done(!) /// don't kill iVehicleId, though, 'cause militia training tries to put guys back in their vehicles when it's done(!)
@@ -540,6 +543,7 @@ void ChangeSoldiersAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment )
BOOLEAN BasicCanCharacterAssignment( SOLDIERTYPE * pSoldier, BOOLEAN fNotInCombat ) BOOLEAN BasicCanCharacterAssignment( SOLDIERTYPE * pSoldier, BOOLEAN fNotInCombat )
{ {
AssertNotNIL(pSoldier);
// global conditions restricting all assignment changes // global conditions restricting all assignment changes
if ( SectorIsImpassable( (INT16) SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ) ) if ( SectorIsImpassable( (INT16) SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ) )
{ {
@@ -559,6 +563,7 @@ BOOLEAN BasicCanCharacterAssignment( SOLDIERTYPE * pSoldier, BOOLEAN fNotInComba
/* /*
BOOLEAN CanSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment ) BOOLEAN CanSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment )
{ {
AssertNotNIL(pSoldier);
switch( bAssignment ) switch( bAssignment )
{ {
case( DOCTOR ): case( DOCTOR ):
@@ -596,6 +601,7 @@ BOOLEAN CanSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment )
BOOLEAN CanCharacterDoctorButDoesntHaveMedKit( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterDoctorButDoesntHaveMedKit( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -656,6 +662,8 @@ BOOLEAN CanCharacterDoctor( SOLDIERTYPE *pSoldier )
BOOLEAN fFoundMedKit = FALSE; BOOLEAN fFoundMedKit = FALSE;
INT8 bPocket = 0; INT8 bPocket = 0;
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -694,6 +702,7 @@ BOOLEAN IsAnythingAroundForSoldierToRepair( SOLDIERTYPE * pSoldier )
{ {
INT32 iCounter; INT32 iCounter;
AssertNotNIL(pSoldier);
// items? // items?
if ( DoesCharacterHaveAnyItemsToRepair( pSoldier, FINAL_REPAIR_PASS ) ) if ( DoesCharacterHaveAnyItemsToRepair( pSoldier, FINAL_REPAIR_PASS ) )
@@ -739,6 +748,8 @@ BOOLEAN HasCharacterFinishedRepairing( SOLDIERTYPE * pSoldier )
{ {
BOOLEAN fCanStillRepair; BOOLEAN fCanStillRepair;
AssertNotNIL(pSoldier);
// NOTE: This must detect situations where the vehicle/robot has left the sector, in which case we want the // NOTE: This must detect situations where the vehicle/robot has left the sector, in which case we want the
// guy to say "assignment done", so we return that he can no longer repair // guy to say "assignment done", so we return that he can no longer repair
@@ -772,6 +783,7 @@ BOOLEAN DoesCharacterHaveAnyItemsToRepair( SOLDIERTYPE *pSoldier, INT8 bHighestP
OBJECTTYPE * pObj; OBJECTTYPE * pObj;
UINT8 ubPassType; UINT8 ubPassType;
AssertNotNIL(pSoldier);
// check for jams // check for jams
// CHRISL: Changed to dynamically determine max inventory locations. // CHRISL: Changed to dynamically determine max inventory locations.
@@ -852,6 +864,8 @@ BOOLEAN DoesCharacterHaveAnyItemsToRepair( SOLDIERTYPE *pSoldier, INT8 bHighestP
BOOLEAN BasicCanCharacterRepair( SOLDIERTYPE * pSoldier ) BOOLEAN BasicCanCharacterRepair( SOLDIERTYPE * pSoldier )
{ {
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -907,6 +921,8 @@ BOOLEAN BasicCanCharacterRepair( SOLDIERTYPE * pSoldier )
BOOLEAN CanCharacterRepairButDoesntHaveARepairkit( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterRepairButDoesntHaveARepairkit( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
if ( BasicCanCharacterRepair( pSoldier ) == FALSE ) if ( BasicCanCharacterRepair( pSoldier ) == FALSE )
{ {
return( FALSE ); return( FALSE );
@@ -925,6 +941,7 @@ BOOLEAN CanCharacterRepairButDoesntHaveARepairkit( SOLDIERTYPE *pSoldier )
// check that character is alive, oklife, has repair skill, and equipment, etc. // check that character is alive, oklife, has repair skill, and equipment, etc.
BOOLEAN CanCharacterRepair( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterRepair( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
@@ -959,6 +976,8 @@ BOOLEAN CanCharacterRepair( SOLDIERTYPE *pSoldier )
// can character be set to patient? // can character be set to patient?
BOOLEAN CanCharacterPatient( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterPatient( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -1019,6 +1038,8 @@ BOOLEAN BasicCanCharacterTrainMilitia( SOLDIERTYPE *pSoldier )
// they must be alive/conscious and in the sector with the town // they must be alive/conscious and in the sector with the town
BOOLEAN fSamSitePresent = FALSE; BOOLEAN fSamSitePresent = FALSE;
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -1111,6 +1132,7 @@ BOOLEAN BasicCanCharacterTrainMilitia( SOLDIERTYPE *pSoldier )
BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
if (gGameExternalOptions.gfmusttrainroaming if (gGameExternalOptions.gfmusttrainroaming
&& (GetWorldDay( ) >= gGameExternalOptions.guiAllowMilitiaGroupsDelay) && (GetWorldDay( ) >= gGameExternalOptions.guiAllowMilitiaGroupsDelay)
@@ -1150,7 +1172,6 @@ BOOLEAN CanCharacterTrainMilitia( SOLDIERTYPE *pSoldier )
BOOLEAN DoesTownHaveRatingToTrainMilitia( INT8 bTownId ) BOOLEAN DoesTownHaveRatingToTrainMilitia( INT8 bTownId )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Assignments1");
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Assignments1"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Assignments1");
// min loyalty rating? // min loyalty rating?
if( ( gTownLoyalty[ bTownId ].ubRating < gGameExternalOptions.iMinLoyaltyToTrain ) ) if( ( gTownLoyalty[ bTownId ].ubRating < gGameExternalOptions.iMinLoyaltyToTrain ) )
@@ -1169,6 +1190,7 @@ BOOLEAN DoesSectorMercIsInHaveSufficientLoyaltyToTrainMilitia( SOLDIERTYPE *pSol
INT8 bTownId = 0; INT8 bTownId = 0;
BOOLEAN fSamSitePresent = FALSE; BOOLEAN fSamSitePresent = FALSE;
AssertNotNIL(pSoldier);
// underground training is not allowed (code doesn't support and it's a reasonable enough limitation) // underground training is not allowed (code doesn't support and it's a reasonable enough limitation)
if( pSoldier->bSectorZ != 0 ) if( pSoldier->bSectorZ != 0 )
@@ -1209,6 +1231,8 @@ INT8 CountMilitiaTrainersInSoldiersSector( SOLDIERTYPE * pSoldier )
SOLDIERTYPE * pOtherSoldier; SOLDIERTYPE * pOtherSoldier;
INT8 bCount = 0; INT8 bCount = 0;
AssertNotNIL(pSoldier);
for ( bLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; bLoop++ ) for ( bLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; bLoop++ )
{ {
pOtherSoldier = MercPtrs[ bLoop ]; pOtherSoldier = MercPtrs[ bLoop ];
@@ -1230,6 +1254,7 @@ BOOLEAN IsMilitiaTrainableFromSoldiersSectorMaxed( SOLDIERTYPE *pSoldier, INT8 i
INT8 bTownId = 0; INT8 bTownId = 0;
BOOLEAN fSamSitePresent = FALSE; BOOLEAN fSamSitePresent = FALSE;
AssertNotNIL(pSoldier);
if( pSoldier->bSectorZ != 0 ) if( pSoldier->bSectorZ != 0 )
{ {
@@ -1269,6 +1294,8 @@ BOOLEAN CanCharacterTrainStat( SOLDIERTYPE *pSoldier, INT8 bStat, BOOLEAN fTrain
{ {
// is the character capable of training this stat? either self or as trainer // is the character capable of training this stat? either self or as trainer
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -1453,6 +1480,8 @@ BOOLEAN CanCharacterOnDuty( SOLDIERTYPE *pSoldier )
{ {
// can character commit themselves to on duty? // can character commit themselves to on duty?
AssertNotNIL(pSoldier);
// only need to be alive and well to do so right now // only need to be alive and well to do so right now
// alive and conscious // alive and conscious
if( pSoldier->stats.bLife < OKLIFE ) if( pSoldier->stats.bLife < OKLIFE )
@@ -1514,6 +1543,8 @@ BOOLEAN CanCharacterPractise( SOLDIERTYPE *pSoldier )
{ {
// can character practise right now? // can character practise right now?
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -1571,6 +1602,7 @@ BOOLEAN CanCharacterPractise( SOLDIERTYPE *pSoldier )
BOOLEAN CanCharacterTrainTeammates( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterTrainTeammates( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
// can character train at all // can character train at all
if( CanCharacterPractise( pSoldier ) == FALSE ) if( CanCharacterPractise( pSoldier ) == FALSE )
@@ -1592,6 +1624,7 @@ BOOLEAN CanCharacterTrainTeammates( SOLDIERTYPE *pSoldier )
BOOLEAN CanCharacterBeTrainedByOther( SOLDIERTYPE *pSoldier ) BOOLEAN CanCharacterBeTrainedByOther( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
// can character train at all // can character train at all
if( CanCharacterPractise( pSoldier ) == FALSE ) if( CanCharacterPractise( pSoldier ) == FALSE )
@@ -1616,6 +1649,8 @@ BOOLEAN CanCharacterSleep( SOLDIERTYPE *pSoldier, BOOLEAN fExplainWhyNot )
{ {
CHAR16 sString[ 128 ]; CHAR16 sString[ 128 ];
AssertNotNIL(pSoldier);
// dead or dying? // dead or dying?
if( pSoldier->stats.bLife < OKLIFE ) if( pSoldier->stats.bLife < OKLIFE )
{ {
@@ -1726,6 +1761,8 @@ BOOLEAN CanCharacterBeAwakened( SOLDIERTYPE *pSoldier, BOOLEAN fExplainWhyNot )
{ {
CHAR16 sString[ 128 ]; CHAR16 sString[ 128 ];
AssertNotNIL(pSoldier);
// if dead tired // if dead tired
if( ( pSoldier->bBreathMax <= BREATHMAX_ABSOLUTE_MINIMUM ) && !pSoldier->flags.fMercCollapsedFlag ) if( ( pSoldier->bBreathMax <= BREATHMAX_ABSOLUTE_MINIMUM ) && !pSoldier->flags.fMercCollapsedFlag )
{ {
@@ -1754,6 +1791,8 @@ BOOLEAN CanCharacterVehicle( SOLDIERTYPE *pSoldier )
{ {
// can character enter/leave vehicle? // can character enter/leave vehicle?
AssertNotNIL(pSoldier);
if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) )
{ {
return( FALSE ); return( FALSE );
@@ -1828,8 +1867,8 @@ INT8 CanCharacterSquad( SOLDIERTYPE *pSoldier, INT8 bSquadValue )
// can character join this squad? // can character join this squad?
INT16 sX, sY, sZ; INT16 sX, sY, sZ;
AssertLT( bSquadValue, ON_DUTY );
Assert( bSquadValue < ON_DUTY ); AssertNotNIL(pSoldier);
if ( pSoldier->bAssignment == bSquadValue ) if ( pSoldier->bAssignment == bSquadValue )
{ {
@@ -1904,6 +1943,7 @@ INT8 CanCharacterSquad( SOLDIERTYPE *pSoldier, INT8 bSquadValue )
BOOLEAN IsCharacterInTransit( SOLDIERTYPE *pSoldier ) BOOLEAN IsCharacterInTransit( SOLDIERTYPE *pSoldier )
{ {
AssertNotNIL(pSoldier);
// valid character? // valid character?
if( pSoldier == NULL ) if( pSoldier == NULL )
@@ -2014,7 +2054,7 @@ void VerifyTownTrainingIsPaidFor( void )
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// valid character? // valid character?
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
@@ -2080,6 +2120,7 @@ UINT8 GetNumberThatCanBeDoctored( SOLDIERTYPE *pDoctor, BOOLEAN fThisHour, BOOLE
SOLDIERTYPE *pSoldier = MercPtrs[0], *pTeamSoldier = NULL; SOLDIERTYPE *pSoldier = MercPtrs[0], *pTeamSoldier = NULL;
UINT8 ubNumberOfPeople = 0; UINT8 ubNumberOfPeople = 0;
AssertNotNIL(pDoctor);
// go through list of characters, find all who are patients/doctors healable by this doctor // go through list of characters, find all who are patients/doctors healable by this doctor
for ( cnt = 0, pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++) for ( cnt = 0, pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++)
@@ -2103,6 +2144,8 @@ SOLDIERTYPE *AnyDoctorWhoCanHealThisPatient( SOLDIERTYPE *pPatient, BOOLEAN fThi
int cnt; int cnt;
SOLDIERTYPE *pSoldier = MercPtrs[0], *pTeamSoldier = NULL; SOLDIERTYPE *pSoldier = MercPtrs[0], *pTeamSoldier = NULL;
AssertNotNIL(pPatient);
AssertNotNIL(pSoldier);
// go through list of characters, find all who are patients/doctors healable by this doctor // go through list of characters, find all who are patients/doctors healable by this doctor
for ( cnt = 0, pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++) for ( cnt = 0, pTeamSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID; cnt++,pTeamSoldier++)
@@ -2129,6 +2172,9 @@ UINT16 CalculateHealingPointsForDoctor(SOLDIERTYPE *pDoctor, UINT16 *pusMaxPts,
UINT16 usKitPts = 0; UINT16 usKitPts = 0;
INT8 bMedFactor; INT8 bMedFactor;
AssertNotNIL(pDoctor);
AssertNotNIL(pusMaxPts);
// make sure he has a medkit in his hand, and preferably make it a medical bag, not a first aid kit // make sure he has a medkit in his hand, and preferably make it a medical bag, not a first aid kit
if( fMakeSureKitIsInHand ) if( fMakeSureKitIsInHand )
{ {
@@ -2487,7 +2533,7 @@ BOOLEAN IsSoldierCloseEnoughToADoctor( SOLDIERTYPE *pPatient )
return( TRUE ); return( TRUE );
} }
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
pSoldier = &Menptr[ iCounter ]; pSoldier = &Menptr[ iCounter ];
@@ -2971,8 +3017,8 @@ OBJECTTYPE* FindRepairableItemOnOtherSoldier( SOLDIERTYPE * pSoldier, UINT8 ubPa
INT8 bSlotToCheck; INT8 bSlotToCheck;
OBJECTTYPE * pObj; OBJECTTYPE * pObj;
AssertLT( ubPassType, NUM_REPAIR_PASS_TYPES );
Assert( ubPassType < NUM_REPAIR_PASS_TYPES ); AssertNotNIL(pSoldier);
pPassList = &( gRepairPassSlotList[ ubPassType ] ); pPassList = &( gRepairPassSlotList[ ubPassType ] );
@@ -2980,7 +3026,7 @@ OBJECTTYPE* FindRepairableItemOnOtherSoldier( SOLDIERTYPE * pSoldier, UINT8 ubPa
for ( bLoop = 0; bLoop < pPassList->ubChoices[UsingNewInventorySystem()]; bLoop++ ) for ( bLoop = 0; bLoop < pPassList->ubChoices[UsingNewInventorySystem()]; bLoop++ )
{ {
bSlotToCheck = pPassList->bSlot[ bLoop ]; bSlotToCheck = pPassList->bSlot[ bLoop ];
Assert( bSlotToCheck != -1 ); AssertNE( bSlotToCheck, -1 );
for ( bLoop2 = 0; bLoop2 < pSoldier->inv[ bSlotToCheck ].ubNumberOfObjects; bLoop2++ ) for ( bLoop2 = 0; bLoop2 < pSoldier->inv[ bSlotToCheck ].ubNumberOfObjects; bLoop2++ )
{ {
@@ -3008,6 +3054,8 @@ OBJECTTYPE* FindRepairableItemInLBENODE( OBJECTTYPE * pObj, UINT8 subObject)
{ {
OBJECTTYPE * pObject; OBJECTTYPE * pObject;
AssertNotNIL(pObj);
if(UsingNewInventorySystem() == false) if(UsingNewInventorySystem() == false)
return( 0 ); return( 0 );
@@ -3039,6 +3087,7 @@ OBJECTTYPE* FindRepairableItemInLBENODE( OBJECTTYPE * pObj, UINT8 subObject)
OBJECTTYPE* FindRepairableItemInSpecificPocket( OBJECTTYPE * pObj, UINT8 subObject) OBJECTTYPE* FindRepairableItemInSpecificPocket( OBJECTTYPE * pObj, UINT8 subObject)
{ {
AssertNotNIL(pObj);
if ( IsItemRepairable( pObj->usItem, (*pObj)[subObject]->data.objectStatus ) ) if ( IsItemRepairable( pObj->usItem, (*pObj)[subObject]->data.objectStatus ) )
{ {
return( pObj ); return( pObj );
@@ -3060,6 +3109,10 @@ void DoActualRepair( SOLDIERTYPE * pSoldier, UINT16 usItem, INT16 * pbStatus, UI
{ {
INT16 sRepairCostAdj; INT16 sRepairCostAdj;
UINT16 usDamagePts, usPtsFixed; UINT16 usDamagePts, usPtsFixed;
AssertNotNIL (pSoldier);
AssertNotNIL (pbStatus);
AssertNotNIL (pubRepairPtsLeft);
// get item's repair ease, for each + point is 10% easier, each - point is 10% harder to repair // get item's repair ease, for each + point is 10% easier, each - point is 10% harder to repair
sRepairCostAdj = 100 - ( 10 * Item[ usItem ].bRepairEase ); sRepairCostAdj = 100 - ( 10 * Item[ usItem ].bRepairEase );
@@ -3528,7 +3581,9 @@ void HandleTrainingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
SOLDIERTYPE *pStatTrainerList[ NUM_TRAINABLE_STATS ]; // can't have more "best" trainers than trainable stats SOLDIERTYPE *pStatTrainerList[ NUM_TRAINABLE_STATS ]; // can't have more "best" trainers than trainable stats
INT16 sBestTrainingPts; INT16 sBestTrainingPts;
INT16 sTownTrainingPts; INT16 sTownTrainingPts;
TOWN_TRAINER_TYPE TownTrainer[ MAX_CHARACTER_COUNT ]; // WDS - make number of mercenaries, etc. be configurable
TOWN_TRAINER_TYPE TownTrainer[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// std::vector<TOWN_TRAINER_TYPE> TownTrainer (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS);
UINT8 ubTownTrainers; UINT8 ubTownTrainers;
UINT16 usMaxPts; UINT16 usMaxPts;
BOOLEAN fSamSiteInSector = FALSE; BOOLEAN fSamSiteInSector = FALSE;
@@ -3649,7 +3704,7 @@ void HandleTrainingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
if( ( (StrategicMap[ sMapX + ( sMapY * MAP_WORLD_X ) ].bNameId != BLANK_SECTOR ) || ( fSamSiteInSector == TRUE ) ) && (bZ == 0) ) if( ( (StrategicMap[ sMapX + ( sMapY * MAP_WORLD_X ) ].bNameId != BLANK_SECTOR ) || ( fSamSiteInSector == TRUE ) ) && (bZ == 0) )
{ {
// init town trainer list // init town trainer list
memset( TownTrainer, 0, sizeof( TownTrainer ) ); memset( TownTrainer, 0, sizeof( TownTrainer ) );
ubTownTrainers = 0; ubTownTrainers = 0;
// build list of all the town trainers in this sector and their training pts // build list of all the town trainers in this sector and their training pts
@@ -4184,7 +4239,7 @@ BOOLEAN TrainTownInSector( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMapY, INT1
ubTownId = StrategicMap[ pTrainer->sSectorX + pTrainer->sSectorY * MAP_WORLD_X ].bNameId; ubTownId = StrategicMap[ pTrainer->sSectorX + pTrainer->sSectorY * MAP_WORLD_X ].bNameId;
if( fSamSiteInSector == FALSE ) if( fSamSiteInSector == FALSE )
{ {
Assert(ubTownId != BLANK_SECTOR); AssertNE(ubTownId, BLANK_SECTOR);
} }
// trainer gains leadership - training argument is FALSE, because the trainer is not the one training! // trainer gains leadership - training argument is FALSE, because the trainer is not the one training!
@@ -4267,7 +4322,7 @@ INT16 GetTownTrainPtsForCharacter( SOLDIERTYPE *pTrainer, UINT16 *pusMaxPts )
/* ARM: Decided this didn't make much sense - the guys I'm training damn well BETTER be loyal - and screw the rest! /* ARM: Decided this didn't make much sense - the guys I'm training damn well BETTER be loyal - and screw the rest!
// get town index // get town index
ubTownId = StrategicMap[ pTrainer->sSectorX + pTrainer->sSectorY * MAP_WORLD_X ].bNameId; ubTownId = StrategicMap[ pTrainer->sSectorX + pTrainer->sSectorY * MAP_WORLD_X ].bNameId;
Assert(ubTownId != BLANK_SECTOR); AssertNE(ubTownId, BLANK_SECTOR);
// adjust for town loyalty // adjust for town loyalty
sTotalTrainingPts = (sTotalTrainingPts * gTownLoyalty[ ubTownId ].ubRating) / 100; sTotalTrainingPts = (sTotalTrainingPts * gTownLoyalty[ ubTownId ].ubRating) / 100;
@@ -4310,7 +4365,7 @@ void MakeSoldiersTacticalAnimationReflectAssignment( SOLDIERTYPE *pSoldier )
void AssignmentAborted( SOLDIERTYPE *pSoldier, UINT8 ubReason ) void AssignmentAborted( SOLDIERTYPE *pSoldier, UINT8 ubReason )
{ {
Assert( ubReason < NUM_ASSIGN_ABORT_REASONS ); AssertLT( ubReason, NUM_ASSIGN_ABORT_REASONS );
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ ubReason ], pSoldier->name ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ ubReason ], pSoldier->name );
@@ -4952,7 +5007,7 @@ void VehicleMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason )
iVehicleID = MSYS_GetRegionUserData( pRegion, 1 ); iVehicleID = MSYS_GetRegionUserData( pRegion, 1 );
// inaccessible vehicles shouldn't be listed in the menu! // inaccessible vehicles shouldn't be listed in the menu!
Assert( IsThisVehicleAccessibleToSoldier( pSoldier, iVehicleID ) ); // AssertT( IsThisVehicleAccessibleToSoldier( pSoldier, iVehicleID ) );
if ( IsEnoughSpaceInVehicle( iVehicleID ) ) if ( IsEnoughSpaceInVehicle( iVehicleID ) )
{ {
@@ -5532,6 +5587,12 @@ void MakeSureToolKitIsInHand( SOLDIERTYPE *pSoldier )
{ {
if( Item[pSoldier->inv[ bPocket ].usItem].toolkit ) if( Item[pSoldier->inv[ bPocket ].usItem].toolkit )
{ {
// If the second hand is empty, swap item in first hand there
if (pSoldier->inv[HANDPOS].exists() &&
!pSoldier->inv[SECONDHANDPOS].exists() &&
CanItemFitInPosition(pSoldier, &pSoldier->inv[SECONDHANDPOS], HANDPOS, FALSE)) {
SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE );
}
if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE)) if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE); SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
SwapObjs( pSoldier, HANDPOS, bPocket, TRUE ); SwapObjs( pSoldier, HANDPOS, bPocket, TRUE );
@@ -5562,6 +5623,12 @@ BOOLEAN MakeSureMedKitIsInHand( SOLDIERTYPE *pSoldier )
if ( Item[pSoldier->inv[ bPocket ].usItem].medicalkit ) if ( Item[pSoldier->inv[ bPocket ].usItem].medicalkit )
{ {
fCharacterInfoPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE;
// If the second hand is empty, swap item in first hand there
if (pSoldier->inv[HANDPOS].exists() &&
!pSoldier->inv[SECONDHANDPOS].exists() &&
CanItemFitInPosition(pSoldier, &pSoldier->inv[SECONDHANDPOS], HANDPOS, FALSE)) {
SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE );
}
if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE)) if(!CanItemFitInPosition(pSoldier, &pSoldier->inv[HANDPOS], bPocket, FALSE))
SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE); SwapObjs(pSoldier, HANDPOS, SECONDHANDPOS, TRUE);
SwapObjs( pSoldier, HANDPOS, bPocket, TRUE ); SwapObjs( pSoldier, HANDPOS, bPocket, TRUE );
@@ -7057,7 +7124,8 @@ void ContractMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason )
// can't renew contracts from tactical! // can't renew contracts from tactical!
} }
Assert( pSoldier && pSoldier->bActive ); AssertNotNIL( pSoldier );
AssertT( pSoldier->bActive );
iValue = MSYS_GetRegionUserData( pRegion, 0 ); iValue = MSYS_GetRegionUserData( pRegion, 0 );
@@ -10399,8 +10467,8 @@ BOOLEAN AnyMercInGroupCantContinueMoving( GROUP *pGroup )
BOOLEAN fGroupMustStop = FALSE; BOOLEAN fGroupMustStop = FALSE;
Assert( pGroup ); AssertNotNIL( pGroup );
Assert( pGroup->fPlayer ); AssertT( pGroup->fPlayer );
pPlayer = pGroup->pPlayerList; pPlayer = pGroup->pPlayerList;
@@ -10546,7 +10614,7 @@ BOOLEAN HandleSelectedMercsBeingPutAsleep( BOOLEAN fWakeUp, BOOLEAN fDisplayWarn
CHAR16 sString[ 128 ]; CHAR16 sString[ 128 ];
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
pSoldier = NULL; pSoldier = NULL;
@@ -10865,7 +10933,7 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam )
// sets assignment for the list // sets assignment for the list
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( ( gCharactersList[ iCounter ].fValid ) && if( ( gCharactersList[ iCounter ].fValid ) &&
( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) && ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) &&
@@ -11425,7 +11493,7 @@ SOLDIERTYPE *GetSelectedAssignSoldier( BOOLEAN fNullOK )
if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) ) if ( (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) )
{ {
// mapscreen version // mapscreen version
if( ( bSelectedAssignChar >= 0 ) && ( bSelectedAssignChar < MAX_CHARACTER_COUNT ) && if( ( bSelectedAssignChar >= 0 ) && ( bSelectedAssignChar < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) &&
( gCharactersList[ bSelectedAssignChar ].fValid ) ) ( gCharactersList[ bSelectedAssignChar ].fValid ) )
{ {
pSoldier = &Menptr[ gCharactersList[ bSelectedAssignChar ].usSolID ]; pSoldier = &Menptr[ gCharactersList[ bSelectedAssignChar ].usSolID ];
+62 -33
View File
@@ -1,4 +1,3 @@
// MAXIMUM NUMBER OF ENEMIES: 32
#ifdef PRECOMPILEDHEADERS #ifdef PRECOMPILEDHEADERS
#include "Strategic All.h" #include "Strategic All.h"
#include "GameSettings.h" #include "GameSettings.h"
@@ -66,6 +65,8 @@
#include "cheats.h" #include "cheats.h"
#include "Map Information.h" #include "Map Information.h"
#include "MilitiaSquads.h" #include "MilitiaSquads.h"
// #include "Strategic AI.h"
#include "interface Dialogue.h"
#endif #endif
#include "Reinforcement.h" #include "Reinforcement.h"
@@ -134,7 +135,8 @@ typedef struct AUTORESOLVE_STRUCT
INT32 iButton[ NUM_AR_BUTTONS ]; INT32 iButton[ NUM_AR_BUTTONS ];
INT32 iButtonImage[ NUM_AR_BUTTONS ]; INT32 iButtonImage[ NUM_AR_BUTTONS ];
INT32 iFaces; //for generic civs and enemies INT32 iFaces; //for generic civs and enemies
INT32 iMercFaces[20]; //for each merc face // WDS - make number of mercenaries, etc. be configurable
INT32 iMercFaces[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS]; //for each merc face
INT32 iIndent; INT32 iIndent;
INT32 iInterfaceBuffer; INT32 iInterfaceBuffer;
INT32 iNumMercFaces; INT32 iNumMercFaces;
@@ -337,11 +339,6 @@ void RenderSoldierCellHealth( SOLDIERCELL *pCell );
void RenderSoldierCell( SOLDIERCELL *pCell ); void RenderSoldierCell( SOLDIERCELL *pCell );
void RenderSoldierCellBars( SOLDIERCELL *pCell ); void RenderSoldierCellBars( SOLDIERCELL *pCell );
#ifdef JA2BETAVERSION
extern void CountRandomCalls( BOOLEAN fStart );
extern void GetRandomCalls( UINT32 *puiRandoms, UINT32 *puiPreRandoms );
#endif
void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors ); void GenerateDirectionInfos( INT16 sMapX, INT16 sMapY, UINT8* uiDirNumber, UINT16 pMoveDir[4][3], BOOLEAN fWithCities, BOOLEAN fForBattle, BOOLEAN fOnlyCitySectors );
@@ -586,11 +583,6 @@ extern UINT8 guiDirNumber;
void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY ) void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY )
{ {
#ifdef JA2BETAVERSION
CountRandomCalls( TRUE );
#endif
guiDirNumber = 0; guiDirNumber = 0;
//Set up mapscreen for removal //Set up mapscreen for removal
@@ -599,19 +591,20 @@ void EnterAutoResolveMode( UINT8 ubSectorX, UINT8 ubSectorY )
RenderButtons(); RenderButtons();
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve1"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve1");
// WDS - make number of mercenaries, etc. be configurable
//Allocate memory for all the globals while we are in this mode. //Allocate memory for all the globals while we are in this mode.
gpAR = (AUTORESOLVE_STRUCT*)MemAlloc( sizeof( AUTORESOLVE_STRUCT ) ); gpAR = (AUTORESOLVE_STRUCT*)MemAlloc( sizeof( AUTORESOLVE_STRUCT ) );
Assert( gpAR ); Assert( gpAR );
memset( gpAR, 0, sizeof( AUTORESOLVE_STRUCT ) ); memset( gpAR, 0, sizeof( AUTORESOLVE_STRUCT ) );
//Mercs -- 20 max //Mercs
gpMercs = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * 20 ); gpMercs = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * MAX_AR_TEAM_SIZE );
Assert( gpMercs ); Assert( gpMercs );
memset( gpMercs, 0, sizeof( SOLDIERCELL ) * 20 ); memset( gpMercs, 0, sizeof( SOLDIERCELL ) * MAX_AR_TEAM_SIZE );
//Militia -- MAX_ALLOWABLE_MILITIA_PER_SECTOR max //Militia
gpCivs = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * MAX_AR_TEAM_SIZE ); gpCivs = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * MAX_AR_TEAM_SIZE );
Assert( gpCivs ); Assert( gpCivs );
memset( gpCivs, 0, sizeof( SOLDIERCELL ) * MAX_AR_TEAM_SIZE ); memset( gpCivs, 0, sizeof( SOLDIERCELL ) * MAX_AR_TEAM_SIZE );
//Enemies -- 32 max //Enemies
gpEnemies = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * MAX_AR_TEAM_SIZE ); gpEnemies = (SOLDIERCELL*)MemAlloc( sizeof( SOLDIERCELL) * MAX_AR_TEAM_SIZE );
Assert( gpEnemies ); Assert( gpEnemies );
memset( gpEnemies, 0, sizeof( SOLDIERCELL ) * MAX_AR_TEAM_SIZE ); memset( gpEnemies, 0, sizeof( SOLDIERCELL ) * MAX_AR_TEAM_SIZE );
@@ -706,12 +699,6 @@ UINT32 AutoResolveScreenHandle()
{ {
gfEnteringMapScreen = TRUE; gfEnteringMapScreen = TRUE;
RemoveAutoResolveInterface( TRUE ); RemoveAutoResolveInterface( TRUE );
#ifdef JA2BETAVERSION
{
UINT32 uiRandoms, uiPreRandoms;
GetRandomCalls( &uiRandoms, &uiPreRandoms );
}
#endif
return MAP_SCREEN; return MAP_SCREEN;
} }
if( gpAR->fPendingSurrender ) if( gpAR->fPendingSurrender )
@@ -948,6 +935,8 @@ void CalculateSoldierCells( BOOLEAN fReset )
gpAR->ubAliveCivs = gpAR->ubCivs; gpAR->ubAliveCivs = gpAR->ubCivs;
gpAR->ubAliveEnemies = gpAR->ubEnemies; gpAR->ubAliveEnemies = gpAR->ubEnemies;
// WDS - make number of mercenaries, etc. be configurable
// WDS TO BE FIXED -- Why is this 40 here? (18 April 2008)
//iMaxTeamSize = max( gpAR->ubMercs + gpAR->ubCivs, gpAR->ubEnemies ); //iMaxTeamSize = max( gpAR->ubMercs + gpAR->ubCivs, gpAR->ubEnemies );
iMaxTeamSize = max( min( 40, gpAR->ubMercs + gpAR->ubCivs ), min( 40, gpAR->ubEnemies ) ); iMaxTeamSize = max( min( 40, gpAR->ubMercs + gpAR->ubCivs ), min( 40, gpAR->ubEnemies ) );
@@ -2495,14 +2484,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
} }
} }
} }
//Eliminate all excess soldiers (as more than 32 can exist in the same battle. //Eliminate all excess soldiers
//Autoresolve only processes 32, so the excess is slaughtered as the player never
//knew they existed.
if( fDeleteForGood ) if( fDeleteForGood )
{ //Warp the game time accordingly { //Warp the game time accordingly
if( gpAR->ubBattleStatus == BATTLE_VICTORY ) if( gpAR->ubBattleStatus == BATTLE_VICTORY )
{ //Get rid of any extra enemies that could be here. It is possible for the number of total enemies to exceed 32, but { //Get rid of any extra enemies that could be here.
//autoresolve can only process 32. We basically cheat by eliminating the rest of them.
EliminateAllEnemies( gpAR->ubSectorX, gpAR->ubSectorY ); EliminateAllEnemies( gpAR->ubSectorX, gpAR->ubSectorY );
} }
else else
@@ -3043,7 +3029,7 @@ void CalculateRowsAndColumns()
gpAR->ubEnemyRows = (gpAR->ubEnemies+2)/3; gpAR->ubEnemyRows = (gpAR->ubEnemies+2)/3;
} }
else else
{ //16-32 { //16+
gpAR->ubEnemyCols = 4; gpAR->ubEnemyCols = 4;
gpAR->ubEnemyRows = (gpAR->ubEnemies+3)/4; gpAR->ubEnemyRows = (gpAR->ubEnemies+3)/4;
} }
@@ -3187,6 +3173,19 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve3");
gpAR->fInstantFinish ^= TRUE; gpAR->fInstantFinish ^= TRUE;
} }
break; break;
// WDS - Debug "Drassen" battles
case F12:
if( CHEATER_CHEAT_LEVEL() )
{
UINT8 ubMapX, ubMapY;
for ( ubMapX = 1; ubMapX < MAP_WORLD_X - 1; ubMapX++ ) {
for ( ubMapY = 1; ubMapY < MAP_WORLD_Y - 1; ubMapY++ ) {
SetSectorFlag( ubMapX, ubMapY, 0, SF_ALREADY_VISITED ); //hayden
}
}
ExecuteStrategicAIAction( NPC_ACTION_SEND_SOLDIERS_TO_DRASSEN, 13, 4 );
}
break;
case BACKSPACE: case BACKSPACE:
if( CHEATER_CHEAT_LEVEL() ) if( CHEATER_CHEAT_LEVEL() )
{ {
@@ -3318,7 +3317,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve3");
case '>': case '>':
if( CHEATER_CHEAT_LEVEL() ) if( CHEATER_CHEAT_LEVEL() )
{ {
gpAR->ubEnemies = 32; gpAR->ubEnemies = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
fResetAutoResolve = TRUE; fResetAutoResolve = TRUE;
} }
break; break;
@@ -3335,7 +3334,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve3");
case '.': case '.':
if( CHEATER_CHEAT_LEVEL() ) if( CHEATER_CHEAT_LEVEL() )
{ {
if( gpAR->ubEnemies < 32 ) if( gpAR->ubEnemies < gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ {
gpAR->ubEnemies++; gpAR->ubEnemies++;
fResetAutoResolve = TRUE; fResetAutoResolve = TRUE;
@@ -3354,9 +3353,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve3");
case '?': case '?':
if( CHEATER_CHEAT_LEVEL() ) if( CHEATER_CHEAT_LEVEL() )
{ {
gpAR->ubMercs = 20; gpAR->ubMercs = gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs;
gpAR->ubCivs = MAX_AR_TEAM_SIZE; gpAR->ubCivs = MAX_AR_TEAM_SIZE;
gpAR->ubEnemies = 32; gpAR->ubEnemies = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
fResetAutoResolve = TRUE; fResetAutoResolve = TRUE;
} }
break; break;
@@ -4139,6 +4138,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
pAttacker->pSoldier->usAttackingWeapon = pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ].usItem; pAttacker->pSoldier->usAttackingWeapon = pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ].usItem;
} }
// WDS - make number of mercenaries, etc. be configurable
// WANNE: Does this lead to a CTD -> no I did not get any CTD, so I reenabled it // WANNE: Does this lead to a CTD -> no I did not get any CTD, so I reenabled it
if( pAttacker->bWeaponSlot != HANDPOS && pAttacker->bWeaponSlot != -1) if( pAttacker->bWeaponSlot != HANDPOS && pAttacker->bWeaponSlot != -1)
{ {
@@ -4153,12 +4153,14 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
{ {
iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife || fClaw) ); iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife || fClaw) );
} }
// WANNE: Why is impact here always set to 0? The impact was calculated a few lines before! // WANNE: Why is impact here always set to 0? The impact was calculated a few lines before!
//iImpact = 0; //iImpact = 0;
// WANNE: Just for safty. // WANNE: Just for safty.
if (iImpact < 0) if (iImpact < 0)
iImpact = 0; iImpact = 0;
iNewLife = pTarget->pSoldier->stats.bLife - iImpact; iNewLife = pTarget->pSoldier->stats.bLife - iImpact;
if( pAttacker->uiFlags & CELL_MERC ) if( pAttacker->uiFlags & CELL_MERC )
@@ -5027,3 +5029,30 @@ BOOLEAN ProcessLoyalty()
return FALSE; return FALSE;
} }
void CheckForSoldiersWhoRetreatedIntoMilitiaHeldSectors()
{
for(int sX = 1; sX < ( MAP_WORLD_X - 1 ); sX++ ) {
for(int sY = 1; sY < ( MAP_WORLD_Y - 1); sY++ ) {
// Check if there is a sector where enemies retreated to and there are also militia present
if ((NumEnemiesInSector(sX, sY) > 0) &&
(CountAllMilitiaInSector(sX, sY) > 0) &&
(!gTacticalStatus.fEnemyInSector)) {
unsigned mercCnt = 0;
for( int i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ ) {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) && !AM_A_ROBOT( MercPtrs[ i ] ) )
{ //Merc is active and alive, and not a vehicle or robot
if ((MercPtrs[ i ]->sSectorX == sX) &&(MercPtrs[ i ]->sSectorY == sY) && (MercPtrs[ i ]->bSectorZ == 0)) {
++mercCnt;
}
}
}
// If there are PC mercs here the player will have to handle the battle
if (mercCnt == 0) {
// EnterAutoResolveMode ((UINT8)sX, (UINT8)sY);
}
}
}
}
}
+2
View File
@@ -19,4 +19,6 @@ extern BOOLEAN gfTransferTacticalOppositionToAutoResolve;
//Returns TRUE if autoresolve is active or a sector is loaded. //Returns TRUE if autoresolve is active or a sector is loaded.
BOOLEAN GetCurrentBattleSectorXYZ( INT16 *psSectorX, INT16 *psSectorY, INT16 *psSectorZ ); BOOLEAN GetCurrentBattleSectorXYZ( INT16 *psSectorX, INT16 *psSectorY, INT16 *psSectorZ );
void CheckForSoldiersWhoRetreatedIntoMilitiaHeldSectors();
#endif #endif
+5 -2
View File
@@ -575,7 +575,10 @@ void InitNewCampaign()
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewCampaign"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewCampaign");
//First clear all the sector information of all enemy existance. Conveniently, the //First clear all the sector information of all enemy existance. Conveniently, the
//ubGroupType is also cleared, which is perceived to be an empty group. //ubGroupType is also cleared, which is perceived to be an empty group.
memset( &SectorInfo, 0, sizeof( SECTORINFO ) * 256 ); //memset( &SectorInfo, 0, sizeof( SECTORINFO ) * 256 );
for (std::vector<SECTORINFO>::iterator secIter = SectorInfo.begin(); secIter != SectorInfo.end(); ++secIter) {
memset( &(*secIter), 0, sizeof( SECTORINFO ) );
}
InitStrategicMovementCosts(); InitStrategicMovementCosts();
RemoveAllGroups(); RemoveAllGroups();
@@ -587,7 +590,7 @@ void InitNewCampaign()
if (!is_networked) if (!is_networked)
// allow overhead view of omerta A9 on game onset // allow overhead view of omerta A9 on game onset
SetSectorFlag( 9, 1, 0, SF_ALREADY_VISITED ); //hayden SetSectorFlag( startingX, startingY, startingZ, SF_ALREADY_VISITED ); //hayden
//Generates the initial forces in a new campaign. The idea is to randomize numbers and sectors //Generates the initial forces in a new campaign. The idea is to randomize numbers and sectors
//so that no two games are the same. //so that no two games are the same.
+20 -4
View File
@@ -2,11 +2,25 @@
#define __CAMPAIGN_TYPES_H #define __CAMPAIGN_TYPES_H
#include "types.h" #include "types.h"
#include "DEBUG.H"
const int MAXIMUM_VALID_X_COORDINATE = 16;
const int MINIMUM_VALID_X_COORDINATE = 1;
const int MAXIMUM_VALID_Y_COORDINATE = 16;
const int MINIMUM_VALID_Y_COORDINATE = 1;
const int MAXIMUM_VALID_Z_COORDINATE = 3;
const int MINIMUM_VALID_Z_COORDINATE = 0;
//Macro to convert sector coordinates (1-16,1-16) to 0-255 //Macro to convert sector coordinates (1-16,1-16) to 0-255
#define SECTOR(x,y) (UINT8)((y-1)*16+x-1) #define SECTOR(x,y) (UINT8)(AssertGE(x, MINIMUM_VALID_X_COORDINATE), \
#define SECTORX(SectorID) (UINT8)((SectorID % 16) + 1) AssertLE(x, MAXIMUM_VALID_X_COORDINATE), \
#define SECTORY(SectorID) (UINT8)((SectorID / 16) + 1) AssertGE(y, MINIMUM_VALID_Y_COORDINATE), \
AssertLE(y, MAXIMUM_VALID_Y_COORDINATE), \
((y-1)*16+x-1))
#define SECTORX(SectorID) (UINT8)(AssertLE(SectorID, MAXIMUM_VALID_X_COORDINATE*MAXIMUM_VALID_Y_COORDINATE), \
((SectorID % 16) + 1))
#define SECTORY(SectorID) (UINT8)(AssertLE(SectorID, MAXIMUM_VALID_X_COORDINATE*MAXIMUM_VALID_Y_COORDINATE), \
((SectorID / 16) + 1))
//Sector enumerations //Sector enumerations
// //
@@ -264,7 +278,9 @@ typedef struct UNDERGROUND_SECTORINFO
//The sector information required for the strategic AI. Contains the number of enemy troops, //The sector information required for the strategic AI. Contains the number of enemy troops,
//as well as intentions, etc. //as well as intentions, etc.
extern SECTORINFO SectorInfo[256]; //extern SECTORINFO SectorInfo[256];
extern std::vector<SECTORINFO> SectorInfo;
extern UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead; extern UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead;
#endif #endif
+5 -3
View File
@@ -496,10 +496,12 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CreatureSpreading1");
} }
} }
else if( giHabitatedDistance > iDistance ) else if( giHabitatedDistance > iDistance )
{ //we are within the "safe" habitated area of the creature's area of influence. The chance of {
// WDS - make number of mercenaries, etc. be configurable
//we are within the "safe" habitated area of the creature's area of influence. The chance of
//increasing the population inside this sector depends on how deep we are within the sector. //increasing the population inside this sector depends on how deep we are within the sector.
if( node->pLevel->ubNumCreatures < gGameExternalOptions.iMaxEnemyGroupSize || if( node->pLevel->ubNumCreatures < gGameExternalOptions.iMaxEnemyGroupSize ||
node->pLevel->ubNumCreatures < 32 && node->pLevel->ubCreatureHabitat == QUEEN_LAIR ) node->pLevel->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures && node->pLevel->ubCreatureHabitat == QUEEN_LAIR )
{ //there is ALWAYS a chance to habitate an interior sector, though the chances are slim for { //there is ALWAYS a chance to habitate an interior sector, though the chances are slim for
//highly occupied sectors. This chance is modified by the type of area we are in. //highly occupied sectors. This chance is modified by the type of area we are in.
INT32 iAbsoluteMaxPopulation; INT32 iAbsoluteMaxPopulation;
@@ -508,7 +510,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CreatureSpreading1");
switch( node->pLevel->ubCreatureHabitat ) switch( node->pLevel->ubCreatureHabitat )
{ {
case QUEEN_LAIR: //Defend the queen bonus case QUEEN_LAIR: //Defend the queen bonus
iAbsoluteMaxPopulation = 32; iAbsoluteMaxPopulation = gGameExternalOptions.ubGameMaximumNumberOfCreatures;
break; break;
case LAIR: //Smaller defend the queen bonus case LAIR: //Smaller defend the queen bonus
iAbsoluteMaxPopulation = 18; iAbsoluteMaxPopulation = 18;
+1 -1
View File
@@ -412,7 +412,7 @@ void StartTimeCompression( void )
// check that we can start compressing // check that we can start compressing
if ( !AllowedToTimeCompress( ) ) if ( !AllowedToTimeCompress( ) )
{ {
// not allowed to compress time // not allowed to compress time
TellPlayerWhyHeCantCompressTime(); TellPlayerWhyHeCantCompressTime();
return; return;
+6 -4
View File
@@ -63,6 +63,7 @@
#include "Interface Panels.h" #include "Interface Panels.h"
#endif #endif
#include "Vehicles.h"
#include "text.h" #include "text.h"
#include "connect.h" #include "connect.h"
class OBJECTTYPE; class OBJECTTYPE;
@@ -76,7 +77,6 @@ extern UINT32 uiMeanWhileFlags;
extern BOOLEAN gfGamePaused; extern BOOLEAN gfGamePaused;
extern UNDERGROUND_SECTORINFO* FindUnderGroundSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ ); extern UNDERGROUND_SECTORINFO* FindUnderGroundSector( INT16 sMapX, INT16 sMapY, UINT8 bMapZ );
extern void InitVehicles( );
UINT8 gubScreenCount=0; UINT8 gubScreenCount=0;
@@ -109,6 +109,8 @@ void InitNPCs( void )
pProfile->sSectorY = MAP_ROW_C; pProfile->sSectorY = MAP_ROW_C;
pProfile->bSectorZ = 0; pProfile->bSectorZ = 0;
break; break;
default:
AssertMsg(false, "Skyrider was not set up properly");
} }
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
@@ -311,7 +313,7 @@ void InitStrategicLayer( void )
// Init Squad Lists // Init Squad Lists
InitSquads(); InitSquads();
// Init vehicles // Init vehicles
InitVehicles( ); InitAllVehicles( );
// init town loyalty // init town loyalty
InitTownLoyalty(); InitTownLoyalty();
// init the mine management system // init the mine management system
@@ -342,7 +344,7 @@ void InitStrategicLayer( void )
SetGameTimeCompressionLevel( TIME_COMPRESS_X0 ); SetGameTimeCompressionLevel( TIME_COMPRESS_X0 );
// select A9 Omerta as the initial selected sector // select A9 Omerta as the initial selected sector
ChangeSelectedMapSector( 9, 1, 0 ); ChangeSelectedMapSector( startingX, startingY, startingZ );
// Reset these flags or mapscreen could be disabled and cause major headache. // Reset these flags or mapscreen could be disabled and cause major headache.
fDisableDueToBattleRoster = FALSE; fDisableDueToBattleRoster = FALSE;
@@ -559,7 +561,7 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
if ( gubScreenCount == 2 ) if ( gubScreenCount == 2 )
{ {
if ( !SetCurrentWorldSector( 9, 1, 0 ) ) if ( !SetCurrentWorldSector( startingX, startingY, startingZ ) )
{ {
} }
+12 -1
View File
@@ -18,9 +18,13 @@
#include "finances.h" #include "finances.h"
#include "history.h" #include "history.h"
#include "Dialogue Control.h" #include "Dialogue Control.h"
#include "Strategic AI.h"
#endif #endif
#include "SaveLoadGame.h"
#include "GameSettings.h"
#include "connect.h" #include "connect.h"
void HourlyQuestUpdate( void ); void HourlyQuestUpdate( void );
void HourlyLarryUpdate( void ); void HourlyLarryUpdate( void );
@@ -74,13 +78,20 @@ void HandleHourlyUpdate()
HourlyCheckIfSlayAloneSoHeCanLeave(); HourlyCheckIfSlayAloneSoHeCanLeave();
PayOffSkyriderDebtIfAny(); // WDS - New AI
HourlyCheckStrategicAI();
PayOffSkyriderDebtIfAny();
if ( GetWorldHour() % 6 == 0 ) // 4 times a day if ( GetWorldHour() % 6 == 0 ) // 4 times a day
{ {
UpdateRegenCounters(); UpdateRegenCounters();
} }
if ((gGameExternalOptions.autoSaveTime != 0) &&
(GetWorldHour() % gGameExternalOptions.autoSaveTime == 0)) {
SaveGame( SAVE__TIMED_AUTOSAVE, L"Auto Save" );
}
} }
void UpdateRegenCounters( void ) void UpdateRegenCounters( void )
+2 -2
View File
@@ -314,7 +314,7 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY )
if ( DoesSkyriderNoticeEnemiesInSector( ubNumEnemies ) == TRUE ) if ( DoesSkyriderNoticeEnemiesInSector( ubNumEnemies ) == TRUE )
{ {
// if just passing through (different quotes are used below if it's his final destination) // if just passing through (different quotes are used below if it's his final destination)
if( !EndOfHelicoptersPath( ) ) if( !EndOfHelicoptersPath( ) && gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE )
{ {
// stop time compression and inform player that there are enemies in the sector below // stop time compression and inform player that there are enemies in the sector below
StopTimeCompression(); StopTimeCompression();
@@ -358,7 +358,7 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY )
{ {
// if he has passengers, or he's not going straight to base, tell player he's arrived // if he has passengers, or he's not going straight to base, tell player he's arrived
// (i.e. don't say anything nor stop time compression if he's empty and just returning to base) // (i.e. don't say anything nor stop time compression if he's empty and just returning to base)
if ( ( GetNumberOfPassengersInHelicopter() > 0 ) || !fHeliReturnStraightToBase ) if ( ( GetNumberOfPassengersInHelicopter() > 0 ) /*|| !fHeliReturnStraightToBase*/ )
{ {
// arrived at destination // arrived at destination
if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE) HeliCharacterDialogue( pSkyRider, ARRIVED_IN_NON_HOSTILE_SECTOR ); if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE) HeliCharacterDialogue( pSkyRider, ARRIVED_IN_NON_HOSTILE_SECTOR );
@@ -2267,10 +2267,9 @@ INT32 MapScreenSectorInventoryCompare( const void *pNum1, const void *pNum2)
BOOLEAN CanPlayerUseSectorInventory( SOLDIERTYPE *pSelectedSoldier ) BOOLEAN CanPlayerUseSectorInventory( SOLDIERTYPE *pSelectedSoldier )
{ {
INT16 sSectorX, sSectorY, sSectorZ; INT16 sSectorX, sSectorY, sSectorZ;
BOOLEAN fInCombat;
//Get the sector that has a battle //Get the sector that has a battle
fInCombat = GetCurrentBattleSectorXYZAndReturnTRUEIfThereIsABattle( &sSectorX, &sSectorY, &sSectorZ ); BOOLEAN fInCombat = GetCurrentBattleSectorXYZAndReturnTRUEIfThereIsABattle( &sSectorX, &sSectorY, &sSectorZ );
//if there is a battle going on //if there is a battle going on
if( fInCombat ) if( fInCombat )
+55 -80
View File
@@ -43,8 +43,10 @@
#include "Tactical Save.h" #include "Tactical Save.h"
#include "Map Information.h" #include "Map Information.h"
#include "Air Raid.h" #include "Air Raid.h"
#include "Auto Resolve.h"
#endif #endif
#include "Quests.h"
#include "connect.h" #include "connect.h"
// zoom x and y coords for map scrolling // zoom x and y coords for map scrolling
@@ -901,6 +903,8 @@ UINT32 DrawMap( void )
RestoreClipRegionToFullScreen( ); RestoreClipRegionToFullScreen( );
CheckForSoldiersWhoRetreatedIntoMilitiaHeldSectors();
return( TRUE ); return( TRUE );
} }
@@ -4067,19 +4071,19 @@ void ShowPeopleInMotion( INT16 sX, INT16 sY )
sDest = sSource; sDest = sSource;
if( ( iCounter == 0 ) && sY > 1 ) if( ( iCounter == 0 ) && sY > MINIMUM_VALID_Y_COORDINATE )
{ {
sDest += NORTH_MOVE; sDest += NORTH_MOVE;
} }
else if( ( iCounter == 1 ) && ( sX < MAP_WORLD_X - 1 ) ) else if( ( iCounter == 1 ) && ( sX < MAXIMUM_VALID_X_COORDINATE ) )
{ {
sDest += EAST_MOVE; sDest += EAST_MOVE;
} }
else if( ( iCounter == 2 ) && ( sY < MAP_WORLD_Y - 1 ) ) else if( ( iCounter == 2 ) && ( sY < MAXIMUM_VALID_Y_COORDINATE ) )
{ {
sDest += SOUTH_MOVE; sDest += SOUTH_MOVE;
} }
else if( ( iCounter == 3 ) && ( sX > 1 ) ) else if( ( iCounter == 3 ) && ( sX > MINIMUM_VALID_X_COORDINATE ) )
{ {
sDest += WEST_MOVE; sDest += WEST_MOVE;
} }
@@ -4087,7 +4091,11 @@ void ShowPeopleInMotion( INT16 sX, INT16 sY )
// if not at edge of map // if not at edge of map
if ( sDest != sSource ) if ( sDest != sSource )
{ {
if( PlayersBetweenTheseSectors( ( INT16 ) SECTOR( sSource % MAP_WORLD_X, sSource / MAP_WORLD_X ) , ( INT16 ) SECTOR( sDest % MAP_WORLD_X, sDest / MAP_WORLD_X ), &sExiting, &sEntering, &fAboutToEnter ) ) int tXS = sSource % MAP_WORLD_X;
int tYS = sSource / MAP_WORLD_X;
int tXD = sDest % MAP_WORLD_X;
int tYD = sDest / MAP_WORLD_X;
if( PlayersBetweenTheseSectors( ( INT16 ) SECTOR(tXS, tYS) , ( INT16 ) SECTOR(tXD, tYD), &sExiting, &sEntering, &fAboutToEnter ) )
{ {
// someone is leaving // someone is leaving
@@ -4307,7 +4315,6 @@ void DisplayDistancesForHelicopter( void )
// sTotalCanTravel = ( INT16 )GetTotalDistanceHelicopterCanTravel( ); // sTotalCanTravel = ( INT16 )GetTotalDistanceHelicopterCanTravel( );
sDistanceToGo = ( INT16 )DistanceOfIntendedHelicopterPath( ); sDistanceToGo = ( INT16 )DistanceOfIntendedHelicopterPath( );
sTotalOfTrip = sDistanceToGo; // + ( INT16 ) ( DistanceToNearestRefuelPoint( ( INT16 )( LastSectorInHelicoptersPath() % MAP_WORLD_X ), ( INT16 ) ( LastSectorInHelicoptersPath() / MAP_WORLD_X ) ) ); sTotalOfTrip = sDistanceToGo; // + ( INT16 ) ( DistanceToNearestRefuelPoint( ( INT16 )( LastSectorInHelicoptersPath() % MAP_WORLD_X ), ( INT16 ) ( LastSectorInHelicoptersPath() / MAP_WORLD_X ) ) );
sNumSafeSectors = GetNumSafeSectorsInPath( ); sNumSafeSectors = GetNumSafeSectorsInPath( );
sNumUnSafeSectors = GetNumUnSafeSectorsInPath( ); sNumUnSafeSectors = GetNumUnSafeSectorsInPath( );
@@ -4411,81 +4418,59 @@ void DisplayPositionOfHelicopter( void )
INT32 iNumberOfPeopleInHelicopter = 0; INT32 iNumberOfPeopleInHelicopter = 0;
CHAR16 sString[ 4 ]; CHAR16 sString[ 4 ];
AssertMsg( ( sOldMapX >= 0 ) && ( sOldMapX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid sOldMapX = %d", sOldMapX ) ); AssertMsg( ( sOldMapX >= 0 ) && ( sOldMapX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid sOldMapX = %d", sOldMapX ) );
AssertMsg( ( sOldMapY >= 0 ) && ( sOldMapY < SCREEN_HEIGHT ), String( "DisplayPositionOfHelicopter: Invalid sOldMapY = %d", sOldMapY ) ); AssertMsg( ( sOldMapY >= 0 ) && ( sOldMapY < SCREEN_HEIGHT ), String( "DisplayPositionOfHelicopter: Invalid sOldMapY = %d", sOldMapY ) );
// restore background on map where it is // restore background on map where it is
if( sOldMapX != 0 ) if( sOldMapX != 0 ) {
{
RestoreExternBackgroundRect( sOldMapX, sOldMapY, HELI_ICON_WIDTH, HELI_ICON_HEIGHT ); RestoreExternBackgroundRect( sOldMapX, sOldMapY, HELI_ICON_WIDTH, HELI_ICON_HEIGHT );
sOldMapX = 0; sOldMapX = 0;
} }
if( iHelicopterVehicleId != -1 ) {
if( iHelicopterVehicleId != -1 )
{
// draw the destination icon first, so when they overlap, the real one is on top! // draw the destination icon first, so when they overlap, the real one is on top!
DisplayDestinationOfHelicopter( ); DisplayDestinationOfHelicopter( );
// check if mvt group // check if mvt group
if( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup != 0 ) if( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup != 0 ) {
{
pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup );
// this came up in one bug report! if (!pGroup) {
Assert( pGroup->uiTraverseTime != -1 ); // Something is really goofed up, there's no group for the helicopter. Re-create it.
static bool heliMsg1Given = false;
if( ( pGroup->uiTraverseTime > 0 ) && ( pGroup->uiTraverseTime != 0xffffffff ) ) if (!heliMsg1Given) {
{ DoScreenIndependantMessageBox( L"The helicopter data is corrupted. Attempting to repair it...", MSG_BOX_FLAG_OK, NULL );
heliMsg1Given = true;
}
RemoveVehicleFromList (iHelicopterVehicleId);
InitAVehicle (iHelicopterVehicleId, 13, MAP_ROW_B);
fSkyRiderSetUp = FALSE;
SetUpHelicopterForPlayer( 13, MAP_ROW_B );
pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup );
if (!pGroup) {
static bool heliMsg2Given = false;
if (!heliMsg2Given) {
DoScreenIndependantMessageBox( L"The helicopter data is corrupted beyond repair. Please report this and send a save file and your .ini file. You can continue playing but the helicopter will not work properly.", MSG_BOX_FLAG_OK, NULL );
heliMsg2Given = true;
}
return;
}
}
if( ( pGroup->uiTraverseTime > 0 ) && ( pGroup->uiTraverseTime != 0xffffffff ) ) {
flRatio = ( ( pGroup->uiTraverseTime + GetWorldTotalMin() ) - pGroup->uiArrivalTime ) / ( float ) pGroup->uiTraverseTime; flRatio = ( ( pGroup->uiTraverseTime + GetWorldTotalMin() ) - pGroup->uiArrivalTime ) / ( float ) pGroup->uiTraverseTime;
} }
/* if ( flRatio < 0 ) {
AssertMsg( ( flRatio >= 0 ) && ( flRatio <= 100 ), String( "DisplayPositionOfHelicopter: Invalid flRatio = %6.2f, trav %d, arr %d, time %d",
flRatio, pGroup->uiTraverseTime, pGroup->uiArrivalTime, GetWorldTotalMin() ) );
*/
if ( flRatio < 0 )
{
flRatio = 0; flRatio = 0;
} } else if ( flRatio > 100 ) {
else if ( flRatio > 100 )
{
flRatio = 100; flRatio = 100;
} }
// if( !fZoomFlag ) // grab min and max locations to interpolate sub sector position
{ minX = MAP_VIEW_START_X + MAP_GRID_X * ( pGroup->ubSectorX );
// grab min and max locations to interpolate sub sector position maxX = MAP_VIEW_START_X + MAP_GRID_X * ( pGroup->ubNextX );
minX = MAP_VIEW_START_X + MAP_GRID_X * ( pGroup->ubSectorX ); minY = MAP_VIEW_START_Y + MAP_GRID_Y * ( pGroup->ubSectorY );
maxX = MAP_VIEW_START_X + MAP_GRID_X * ( pGroup->ubNextX ); maxY = MAP_VIEW_START_Y + MAP_GRID_Y * ( pGroup->ubNextY );
minY = MAP_VIEW_START_Y + MAP_GRID_Y * ( pGroup->ubSectorY );
maxY = MAP_VIEW_START_Y + MAP_GRID_Y * ( pGroup->ubNextY );
}
/*
else
{
// grab coords for nextx,y and current x,y
// zoomed in, takes a little more work
GetScreenXYFromMapXYStationary( ((UINT16)(pGroup->ubSectorX)),((UINT16)(pGroup->ubSectorY)) , &sX, &sY );
sY=sY-MAP_GRID_Y;
sX=sX-MAP_GRID_X;
minX = ( sX );
minY = ( sY );
GetScreenXYFromMapXYStationary( ((UINT16)(pGroup->ubNextX)),((UINT16)(pGroup->ubNextY)) , &sX, &sY );
sY=sY-MAP_GRID_Y;
sX=sX-MAP_GRID_X;
maxX = ( sX );
maxY = ( sY );
}
*/
AssertMsg( ( minX >= 0 ) && ( minX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid minX = %d", minX ) ); AssertMsg( ( minX >= 0 ) && ( minX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid minX = %d", minX ) );
AssertMsg( ( maxX >= 0 ) && ( maxX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid maxX = %d", maxX ) ); AssertMsg( ( maxX >= 0 ) && ( maxX < SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid maxX = %d", maxX ) );
@@ -4496,25 +4481,13 @@ void DisplayPositionOfHelicopter( void )
x = ( UINT32 )( minX + flRatio * ( ( INT16 ) maxX - ( INT16 ) minX ) ); x = ( UINT32 )( minX + flRatio * ( ( INT16 ) maxX - ( INT16 ) minX ) );
y = ( UINT32 )( minY + flRatio * ( ( INT16 ) maxY - ( INT16 ) minY ) ); y = ( UINT32 )( minY + flRatio * ( ( INT16 ) maxY - ( INT16 ) minY ) );
/* x += 1;
if( fZoomFlag ) y += 3;
{
x += 13;
y += 8;
}
else
*/
{
x += 1;
y += 3;
}
AssertMsg( ( x >= 0 ) && ( x < (UINT32)SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid x = %d. At %d,%d. Next %d,%d. Min/Max X = %d/%d", AssertMsg( ( x >= 0 ) && ( x < (UINT32)SCREEN_WIDTH ), String( "DisplayPositionOfHelicopter: Invalid x = %d. At %d,%d. Next %d,%d. Min/Max X = %d/%d",
x, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, minX, maxX ) ); x, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, minX, maxX ) );
AssertMsg( ( y >= 0 ) && ( y < (UINT32)SCREEN_HEIGHT ), String( "DisplayPositionOfHelicopter: Invalid y = %d. At %d,%d. Next %d,%d. Min/Max Y = %d/%d", AssertMsg( ( y >= 0 ) && ( y < (UINT32)SCREEN_HEIGHT ), String( "DisplayPositionOfHelicopter: Invalid y = %d. At %d,%d. Next %d,%d. Min/Max Y = %d/%d",
y, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, minY, maxY ) ); y, pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, minY, maxY ) );
// clip blits to mapscreen region // clip blits to mapscreen region
ClipBlitsToMapViewRegion( ); ClipBlitsToMapViewRegion( );
@@ -5985,7 +5958,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Map Screen4");
} }
// if this sector is currently loaded // if this sector is currently loaded
if( sSector == SECTOR( gWorldSectorX, gWorldSectorY ) && gWorldSectorY != 0 ) if( (gWorldSectorX != 0) &&
(gWorldSectorY != 0) &&
(sSector == SECTOR( gWorldSectorX, gWorldSectorY )) )
{ {
gfStrategicMilitiaChangesMade = TRUE; gfStrategicMilitiaChangesMade = TRUE;
} }
@@ -6212,8 +6187,8 @@ void DrawTownMilitiaForcesOnMap( void )
}*/ }*/
// now handle militia for sam sectors // now handle militia for sam sectors
for( sSectorX = 0; sSectorX < 16 ; ++sSectorX ) for( sSectorX = MINIMUM_VALID_X_COORDINATE; sSectorX <= MAXIMUM_VALID_X_COORDINATE ; ++sSectorX )
for( sSectorY = 0; sSectorY < 16 ; ++sSectorY ) for( sSectorY = MINIMUM_VALID_Y_COORDINATE; sSectorY <= MAXIMUM_VALID_Y_COORDINATE ; ++sSectorY )
//for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ ) //for( iCounter = 0; iCounter < NUMBER_OF_SAMS; iCounter++ )
{ {
// sSectorX = SECTORX( pSamList[ iCounter ] ); // sSectorX = SECTORX( pSamList[ iCounter ] );
@@ -6623,7 +6598,7 @@ UINT8 NumActiveCharactersInSector( INT16 sSectorX, INT16 sSectorY, INT16 bSector
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
UINT8 ubNumberOnTeam = 0; UINT8 ubNumberOnTeam = 0;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid ) if( gCharactersList[ iCounter ].fValid )
{ {
@@ -26,6 +26,8 @@
#include "HelpScreen.h" #include "HelpScreen.h"
#include "Map Screen Helicopter.h" #include "Map Screen Helicopter.h"
#include "Tactical Save.h" #include "Tactical Save.h"
#include "GameSettings.h"
#include "debug.h"
#endif #endif
@@ -94,6 +96,12 @@ void MinWidthOfTownMineInfoBox( void );
void DisplayTownInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) void DisplayTownInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{ {
// will display town info for a particular town // will display town info for a particular town
AssertGE( sMapX, MINIMUM_VALID_X_COORDINATE);
AssertLE( sMapX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sMapY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sMapY, MAXIMUM_VALID_Y_COORDINATE );
AssertGE( bMapZ, bMapZ );
AssertLE( bMapZ, bMapZ );
// set current sector // set current sector
if( ( bCurrentTownMineSectorX != sMapX ) || ( bCurrentTownMineSectorY != sMapY ) || ( bCurrentTownMineSectorZ != bMapZ ) ) if( ( bCurrentTownMineSectorX != sMapX ) || ( bCurrentTownMineSectorY != sMapY ) || ( bCurrentTownMineSectorZ != bMapZ ) )
@@ -646,6 +654,8 @@ void AddCommonInfoToBox(void)
// how many are there, really? // how many are there, really?
ubNumEnemies = NumEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ); ubNumEnemies = NumEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY );
AssertGE(gGameExternalOptions.ubGameMaximumNumberOfEnemies, NumFreeEnemySlots());
unsigned numEnemiesOnMap = gGameExternalOptions.ubGameMaximumNumberOfEnemies - NumFreeEnemySlots();
switch ( WhatPlayerKnowsAboutEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) ) switch ( WhatPlayerKnowsAboutEnemiesInSector( bCurrentTownMineSectorX, bCurrentTownMineSectorY ) )
{ {
@@ -670,7 +680,10 @@ void AddCommonInfoToBox(void)
case KNOWS_HOW_MANY: case KNOWS_HOW_MANY:
// show exactly how many // show exactly how many
swprintf( wString, L"%d", ubNumEnemies ); if (numEnemiesOnMap != ubNumEnemies)
swprintf( wString, L"%d (%d)", numEnemiesOnMap, ubNumEnemies );
else
swprintf( wString, L"%d", ubNumEnemies );
break; break;
} }
+59 -52
View File
@@ -69,8 +69,9 @@ class SOLDIERTYPE;
// the number of help region messages // the number of help region messages
#define NUMBER_OF_MAPSCREEN_HELP_MESSAGES 5 #define NUMBER_OF_MAPSCREEN_HELP_MESSAGES 5
// WDS - make number of mercenaries, etc. be configurable
// number of LINKED LISTS for sets of leave items (each slot holds an unlimited # of items) // number of LINKED LISTS for sets of leave items (each slot holds an unlimited # of items)
#define NUM_LEAVE_LIST_SLOTS 20 #define NUM_LEAVE_LIST_SLOTS CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS
#define SELECTED_CHAR_ARROW_X 1 //8 #define SELECTED_CHAR_ARROW_X 1 //8
@@ -115,7 +116,7 @@ enum{
UINT16 usVehicleY = 0; UINT16 usVehicleY = 0;
// waiting list for update box // waiting list for update box
INT32 iUpdateBoxWaitingList[ MAX_CHARACTER_COUNT ]; INT32 iUpdateBoxWaitingList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
FASTHELPREGION pFastHelpMapScreenList[ MAX_MAPSCREEN_FAST_HELP ]; FASTHELPREGION pFastHelpMapScreenList[ MAX_MAPSCREEN_FAST_HELP ];
@@ -194,8 +195,8 @@ extern INT32 giCharInfoButton[];
extern STR16 pUpdatePanelButtons[]; extern STR16 pUpdatePanelButtons[];
// the list of soldiers that are moving // the list of soldiers that are moving
SOLDIERTYPE * pSoldierMovingList[ MAX_CHARACTER_COUNT ]; SOLDIERTYPE * pSoldierMovingList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
BOOLEAN fSoldierIsMoving[ MAX_CHARACTER_COUNT ]; BOOLEAN fSoldierIsMoving[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
SOLDIERTYPE *pUpdateSoldierBox[ SIZE_OF_UPDATE_BOX ]; SOLDIERTYPE *pUpdateSoldierBox[ SIZE_OF_UPDATE_BOX ];
@@ -226,7 +227,7 @@ BOOLEAN fMapInventoryPoolInited = FALSE;
BOOLEAN fShowMapScreenMovementList = FALSE; BOOLEAN fShowMapScreenMovementList = FALSE;
MapScreenCharacterSt gCharactersList[ MAX_CHARACTER_COUNT+1]; MapScreenCharacterSt gCharactersList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS+1];
extern MOUSE_REGION gCharInfoHandRegion; extern MOUSE_REGION gCharInfoHandRegion;
MOUSE_REGION gMapStatusBarsRegion; MOUSE_REGION gMapStatusBarsRegion;
@@ -234,7 +235,7 @@ MOUSE_REGION gMapStatusBarsRegion;
SGPPoint MovePosition={450, 100 }; SGPPoint MovePosition={450, 100 };
// which lines are selected? .. for assigning groups of mercs to the same thing // which lines are selected? .. for assigning groups of mercs to the same thing
BOOLEAN fSelectedListOfMercsForMapScreen[ MAX_CHARACTER_COUNT ]; BOOLEAN fSelectedListOfMercsForMapScreen[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
BOOLEAN fResetTimerForFirstEntryIntoMapScreen = FALSE; BOOLEAN fResetTimerForFirstEntryIntoMapScreen = FALSE;
INT32 iReasonForSoldierUpDate = NO_REASON_FOR_UPDATE; INT32 iReasonForSoldierUpDate = NO_REASON_FOR_UPDATE;
@@ -246,7 +247,7 @@ UINT32 guiSAMICON;
BOOLEAN fDisableDueToBattleRoster = FALSE; BOOLEAN fDisableDueToBattleRoster = FALSE;
// track old contract times // track old contract times
INT32 iOldContractTimes[ MAX_CHARACTER_COUNT ]; INT32 iOldContractTimes[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// position of pop up box // position of pop up box
INT32 giBoxY = 0; INT32 giBoxY = 0;
@@ -431,7 +432,7 @@ void InitalizeVehicleAndCharacterList( void )
void SetEntryInSelectedCharacterList( INT8 bEntry ) void SetEntryInSelectedCharacterList( INT8 bEntry )
{ {
Assert( ( bEntry >= 0 ) && ( bEntry < MAX_CHARACTER_COUNT ) ); Assert( ( bEntry >= 0 ) && ( bEntry < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) );
// set this entry to selected // set this entry to selected
fSelectedListOfMercsForMapScreen[ bEntry ] = TRUE ; fSelectedListOfMercsForMapScreen[ bEntry ] = TRUE ;
@@ -441,7 +442,7 @@ void SetEntryInSelectedCharacterList( INT8 bEntry )
void ResetEntryForSelectedList( INT8 bEntry ) void ResetEntryForSelectedList( INT8 bEntry )
{ {
Assert( ( bEntry >= 0 ) && ( bEntry < MAX_CHARACTER_COUNT ) ); Assert( ( bEntry >= 0 ) && ( bEntry < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) );
// set this entry to selected // set this entry to selected
fSelectedListOfMercsForMapScreen[ bEntry ] = FALSE; fSelectedListOfMercsForMapScreen[ bEntry ] = FALSE;
@@ -451,8 +452,9 @@ void ResetEntryForSelectedList( INT8 bEntry )
void ResetSelectedListForMapScreen( void ) void ResetSelectedListForMapScreen( void )
{ {
// WDS - make number of mercenaries, etc. be configurable
// set all the entries int he selected list to false // set all the entries int he selected list to false
memset( &fSelectedListOfMercsForMapScreen, FALSE, MAX_CHARACTER_COUNT * sizeof( BOOLEAN ) ); memset( fSelectedListOfMercsForMapScreen, FALSE, sizeof(fSelectedListOfMercsForMapScreen) );
// if we still have a valid dude selected // if we still have a valid dude selected
if ( ( bSelectedInfoChar != -1 ) && ( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) ) if ( ( bSelectedInfoChar != -1 ) && ( gCharactersList[ bSelectedInfoChar ].fValid == TRUE ) )
@@ -467,7 +469,7 @@ void ResetSelectedListForMapScreen( void )
BOOLEAN IsEntryInSelectedListSet( INT8 bEntry ) BOOLEAN IsEntryInSelectedListSet( INT8 bEntry )
{ {
Assert( ( bEntry >= 0 ) && ( bEntry < MAX_CHARACTER_COUNT ) ); Assert( ( bEntry >= 0 ) && ( bEntry < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) );
// is this entry in the selected list set? // is this entry in the selected list set?
@@ -478,7 +480,7 @@ BOOLEAN IsEntryInSelectedListSet( INT8 bEntry )
void ToggleEntryInSelectedList( INT8 bEntry ) void ToggleEntryInSelectedList( INT8 bEntry )
{ {
Assert( ( bEntry >= 0 ) && ( bEntry < MAX_CHARACTER_COUNT ) ); Assert( ( bEntry >= 0 ) && ( bEntry < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) );
// toggle the value in the selected list // toggle the value in the selected list
fSelectedListOfMercsForMapScreen[ bEntry ] = !( fSelectedListOfMercsForMapScreen[ bEntry ] ); fSelectedListOfMercsForMapScreen[ bEntry ] = !( fSelectedListOfMercsForMapScreen[ bEntry ] );
@@ -520,7 +522,7 @@ BOOLEAN MultipleCharacterListEntriesSelected( void )
INT32 iCounter = 0; INT32 iCounter = 0;
// check if more than one person is selected in the selected list // check if more than one person is selected in the selected list
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( fSelectedListOfMercsForMapScreen[iCounter] == TRUE ) if( fSelectedListOfMercsForMapScreen[iCounter] == TRUE )
{ {
@@ -545,7 +547,7 @@ void ResetAssignmentsForMercsTrainingUnpaidSectorsInSelectedList( INT8 bAssignme
INT32 iCounter = 0; INT32 iCounter = 0;
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// valid character? // valid character?
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
@@ -577,7 +579,7 @@ void ResetAssignmentOfMercsThatWereTrainingMilitiaInThisSector( INT16 sSectorX,
INT32 iCounter = 0; INT32 iCounter = 0;
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// valid character? // valid character?
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
@@ -610,7 +612,7 @@ void PlotPathForSelectedCharacterList( INT16 sX, INT16 sY )
{ {
INT32 iCounter = 0; INT32 iCounter = 0;
// run through list and build paths for each character // run through list and build paths for each character
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )&&( bSelectedDestChar != iCounter ) ) if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )&&( bSelectedDestChar != iCounter ) )
{ {
@@ -630,7 +632,7 @@ void DeselectSelectedListMercsWhoCantMoveWithThisGuy( SOLDIERTYPE *pSoldier )
// deselect any other selected mercs that can't travel together with pSoldier // deselect any other selected mercs that can't travel together with pSoldier
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -725,7 +727,7 @@ void SelectUnselectedMercsWhoMustMoveWithThisGuy( void )
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -757,7 +759,7 @@ BOOLEAN AnyMercInSameSquadOrVehicleIsSelected( SOLDIERTYPE *pSoldier )
SOLDIERTYPE *pSoldier2 = NULL; SOLDIERTYPE *pSoldier2 = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -836,7 +838,7 @@ void RestoreBackgroundForAssignmentGlowRegionList( void )
if( iOldAssignmentLine != giAssignHighLine ) if( iOldAssignmentLine != giAssignHighLine )
{ {
// restore background // restore background
RestoreExternBackgroundRect( 66, Y_START - 1, 118 + 1 - 67, ( INT16 )( ( ( MAX_CHARACTER_COUNT + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ); RestoreExternBackgroundRect( 66, Y_START - 1, 118 + 1 - 67, ( INT16 )( ( ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) );
// ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!! // ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!!
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
@@ -864,7 +866,7 @@ void RestoreBackgroundForDestinationGlowRegionList( void )
if( iOldDestinationLine != giDestHighLine ) if( iOldDestinationLine != giDestHighLine )
{ {
// restore background // restore background
RestoreExternBackgroundRect( 182, Y_START - 1, 217 + 1 - 182, ( INT16 )( ( ( MAX_CHARACTER_COUNT + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ); RestoreExternBackgroundRect( 182, Y_START - 1, 217 + 1 - 182, ( INT16 )( ( ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) );
// ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!! // ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!!
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
@@ -892,7 +894,7 @@ void RestoreBackgroundForContractGlowRegionList( void )
if( iOldContractLine != giContractHighLine ) if( iOldContractLine != giContractHighLine )
{ {
// restore background // restore background
RestoreExternBackgroundRect( 222, Y_START - 1, 250 + 1 - 222, ( INT16 )( ( ( MAX_CHARACTER_COUNT + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ) ; RestoreExternBackgroundRect( 222, Y_START - 1, 250 + 1 - 222, ( INT16 )( ( ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ) ;
// ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!! // ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!!
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
@@ -924,7 +926,7 @@ void RestoreBackgroundForSleepGlowRegionList( void )
if( iOldSleepHighLine != giSleepHighLine ) if( iOldSleepHighLine != giSleepHighLine )
{ {
// restore background // restore background
RestoreExternBackgroundRect( 123, Y_START - 1, 142 + 1 - 123, ( INT16 )( ( ( MAX_CHARACTER_COUNT + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ) ; RestoreExternBackgroundRect( 123, Y_START - 1, 142 + 1 - 123, ( INT16 )( ( ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1 ) * ( Y_SIZE + 2 ) ) + 1 ) ) ;
// ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!! // ARM: not good enough! must reblit the whole panel to erase glow chunk restored by help text disappearing!!!
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
@@ -965,7 +967,7 @@ void PlayGlowRegionSound( void )
INT16 CharacterIsGettingPathPlotted( INT16 sCharNumber ) INT16 CharacterIsGettingPathPlotted( INT16 sCharNumber )
{ {
// valid character number? // valid character number?
if( ( sCharNumber < 0 ) || ( sCharNumber >= MAX_CHARACTER_COUNT ) ) if( ( sCharNumber < 0 ) || ( sCharNumber >= CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) )
{ {
return( FALSE ); return( FALSE );
} }
@@ -1007,7 +1009,7 @@ INT16 CharacterIsGettingPathPlotted( INT16 sCharNumber )
BOOLEAN IsCharacterSelectedForAssignment( INT16 sCharNumber ) BOOLEAN IsCharacterSelectedForAssignment( INT16 sCharNumber )
{ {
// valid character number? // valid character number?
if( ( sCharNumber < 0 ) || ( sCharNumber >= MAX_CHARACTER_COUNT ) ) if( ( sCharNumber < 0 ) || ( sCharNumber >= CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) )
{ {
return( FALSE ); return( FALSE );
} }
@@ -1044,7 +1046,7 @@ BOOLEAN IsCharacterSelectedForAssignment( INT16 sCharNumber )
BOOLEAN IsCharacterSelectedForSleep( INT16 sCharNumber ) BOOLEAN IsCharacterSelectedForSleep( INT16 sCharNumber )
{ {
// valid character number? // valid character number?
if( ( sCharNumber < 0 ) || ( sCharNumber >= MAX_CHARACTER_COUNT ) ) if( ( sCharNumber < 0 ) || ( sCharNumber >= CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) )
{ {
return( FALSE ); return( FALSE );
} }
@@ -1104,7 +1106,7 @@ void ActivateSoldierPopup( SOLDIERTYPE *pSoldier, UINT8 ubPopupType, INT16 xp, I
INT8 bCharacter = -1; INT8 bCharacter = -1;
for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) for( bCounter = 0; bCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCounter++ )
{ {
if( gCharactersList[ bCounter ].fValid == TRUE ) if( gCharactersList[ bCounter ].fValid == TRUE )
{ {
@@ -1247,7 +1249,7 @@ void CheckAndUpdateBasedOnContractTimes( void )
INT32 iCounter = 0; INT32 iCounter = 0;
INT32 iTimeRemaining = 0; INT32 iTimeRemaining = 0;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[iCounter].fValid == TRUE ) if( gCharactersList[iCounter].fValid == TRUE )
{ {
@@ -1343,7 +1345,7 @@ void HandleDisplayOfSelectedMercArrows( void )
BltVideoObject( guiSAVEBUFFER , hHandle, 0,SELECTED_CHAR_ARROW_X, sYPosition , VO_BLT_SRCTRANSPARENCY,NULL ); BltVideoObject( guiSAVEBUFFER , hHandle, 0,SELECTED_CHAR_ARROW_X, sYPosition , VO_BLT_SRCTRANSPARENCY,NULL );
// now run through the selected list of guys, an arrow for each // now run through the selected list of guys, an arrow for each
for( ubCount = 0; ubCount < MAX_CHARACTER_COUNT; ubCount++ ) for( ubCount = 0; ubCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; ubCount++ )
{ {
if( gCharactersList[ ubCount ].fValid == TRUE ) if( gCharactersList[ ubCount ].fValid == TRUE )
{ {
@@ -1974,7 +1976,7 @@ INT32 GetNumberOfCharactersOnPlayersTeam( void )
{ {
INT32 iNumberOfPeople = 0, iCounter = 0; INT32 iNumberOfPeople = 0, iCounter = 0;
for(iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for(iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -2109,7 +2111,7 @@ void FindAndSetThisContractSoldier( SOLDIERTYPE *pSoldier )
fShowContractMenu = FALSE; fShowContractMenu = FALSE;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter].fValid == TRUE ) if( gCharactersList[ iCounter].fValid == TRUE )
{ {
@@ -2297,7 +2299,7 @@ void RandomMercInGroupSaysQuote( GROUP *pGroup, UINT16 usQuoteNum )
{ {
PLAYERGROUP *pPlayer; PLAYERGROUP *pPlayer;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
UINT8 ubMercsInGroup[ 20 ]; UINT8 ubMercsInGroup[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
@@ -2343,7 +2345,7 @@ INT32 GetNumberOfPeopleInCharacterList( void )
INT32 iCounter = 0, iCount = 0; INT32 iCounter = 0, iCount = 0;
// get the number of valid mercs in the mapscreen character list // get the number of valid mercs in the mapscreen character list
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter].fValid == TRUE ) if( gCharactersList[ iCounter].fValid == TRUE )
{ {
@@ -2511,7 +2513,7 @@ void GoToNextCharacterInList( void )
} }
// is the current guy invalid or the first one? // is the current guy invalid or the first one?
if( ( bSelectedInfoChar == -1 )|| ( bSelectedInfoChar == MAX_CHARACTER_COUNT ) ) if( ( bSelectedInfoChar == -1 )|| ( bSelectedInfoChar == CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) )
{ {
iCount = 0; iCount = 0;
} }
@@ -2520,9 +2522,9 @@ void GoToNextCharacterInList( void )
iCount = bSelectedInfoChar + 1; iCount = bSelectedInfoChar + 1;
} }
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < MAX_CHARACTER_COUNT ) && ValidSelectableCharForNextOrPrev( iCount ) ) if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) && ValidSelectableCharForNextOrPrev( iCount ) )
{ {
ChangeSelectedInfoChar( ( INT8 )iCount, TRUE ); ChangeSelectedInfoChar( ( INT8 )iCount, TRUE );
break; break;
@@ -2531,7 +2533,7 @@ void GoToNextCharacterInList( void )
{ {
iCount++; iCount++;
if( iCount >= MAX_CHARACTER_COUNT ) if( iCount >= CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS )
{ {
iCount = 0; iCount = 0;
} }
@@ -2558,7 +2560,7 @@ void GoToPrevCharacterInList( void )
// is the current guy invalid or the first one? // is the current guy invalid or the first one?
if( ( bSelectedInfoChar == -1 ) || ( bSelectedInfoChar == 0 ) ) if( ( bSelectedInfoChar == -1 ) || ( bSelectedInfoChar == 0 ) )
{ {
iCount = MAX_CHARACTER_COUNT; iCount = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS;
} }
else else
{ {
@@ -2566,9 +2568,9 @@ void GoToPrevCharacterInList( void )
} }
// now run through the list and find first prev guy // now run through the list and find first prev guy
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < MAX_CHARACTER_COUNT ) && ValidSelectableCharForNextOrPrev( iCount ) ) if ( ( gCharactersList[ iCount ].fValid ) && ( iCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) && ValidSelectableCharForNextOrPrev( iCount ) )
{ {
ChangeSelectedInfoChar( ( INT8 )iCount, TRUE ); ChangeSelectedInfoChar( ( INT8 )iCount, TRUE );
break; break;
@@ -2580,7 +2582,7 @@ void GoToPrevCharacterInList( void )
if( iCount < 0 ) if( iCount < 0 )
{ {
// was FIRST_VEHICLE // was FIRST_VEHICLE
iCount = MAX_CHARACTER_COUNT; iCount = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS;
} }
} }
} }
@@ -3297,7 +3299,7 @@ void DeselectVehicleForMovement( INT32 iVehicleId )
fVehicleIsMoving[ iCounter ] = FALSE; fVehicleIsMoving[ iCounter ] = FALSE;
// now deselect everyone in vehicle // now deselect everyone in vehicle
for( iCount = 0; iCount < 10 ; iCount++ ) for( iCount = 0; iCount < MAXPASSENGERS ; iCount++ )
{ {
pPassenger = pVehicleList[ iVehicleId ].pPassengers[ iCount ]; pPassenger = pVehicleList[ iVehicleId ].pPassengers[ iCount ];
@@ -3361,7 +3363,7 @@ void AddSoldierToMovingLists( SOLDIERTYPE *pSoldier )
{ {
INT32 iCounter = 0; INT32 iCounter = 0;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( pSoldierMovingList[ iCounter ] == pSoldier ) if( pSoldierMovingList[ iCounter ] == pSoldier )
{ {
@@ -3457,7 +3459,7 @@ void InitializeMovingLists( void )
giNumberOfVehiclesInSectorMoving = 0; giNumberOfVehiclesInSectorMoving = 0;
// init the soldiers // init the soldiers
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// soldier is NOT moving // soldier is NOT moving
pSoldierMovingList[ iCounter ] = NULL; pSoldierMovingList[ iCounter ] = NULL;
@@ -3495,7 +3497,7 @@ BOOLEAN IsAnythingSelectedForMoving( void )
// check soldiers // check soldiers
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if ( ( pSoldierMovingList[ iCounter ] != NULL ) && fSoldierIsMoving[ iCounter ] ) if ( ( pSoldierMovingList[ iCounter ] != NULL ) && fSoldierIsMoving[ iCounter ] )
{ {
@@ -3578,7 +3580,7 @@ void SetUpMovingListsForSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
// note that Skyrider can't be moved using the move box, and won't appear because the helicoprer is not in the char list // note that Skyrider can't be moved using the move box, and won't appear because the helicoprer is not in the char list
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid ) if( gCharactersList[ iCounter ].fValid )
{ {
@@ -4440,7 +4442,7 @@ void HandleSettingTheSelectedListOfMercs( void )
bSelectedDestChar = -1; bSelectedDestChar = -1;
// run through the list of grunts // run through the list of grunts
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// is the current guy a valid character? // is the current guy a valid character?
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
@@ -5597,7 +5599,7 @@ BOOLEAN HandleTimeCompressWithTeamJackedInAndGearedToGo( void )
if (!is_networked) if (!is_networked)
// select starting sector (A9 - Omerta) // select starting sector (A9 - Omerta)
ChangeSelectedMapSector( 9, 1, 0 ); ChangeSelectedMapSector( startingX, startingY, startingZ );
if (is_networked) if (is_networked)
{ {
@@ -5613,13 +5615,13 @@ BOOLEAN HandleTimeCompressWithTeamJackedInAndGearedToGo( void )
else else
{ {
// load starting sector // load starting sector
if ( !SetCurrentWorldSector( 9, 1, 0 ) ) if ( !SetCurrentWorldSector( startingX, startingY, startingZ ) )
{ {
return( FALSE ); return( FALSE );
} }
gubPBSectorX = 9; gubPBSectorX = startingX;
gubPBSectorY = 1; gubPBSectorY = startingY;
} }
@@ -6105,7 +6107,7 @@ BOOLEAN CanEntireMovementGroupMercIsInMove( SOLDIERTYPE *pSoldier, INT8 *pbError
// even if group is 0 (not that that should happen, should it?) still loop through for other mercs selected to move // even if group is 0 (not that that should happen, should it?) still loop through for other mercs selected to move
// if anyone in the merc's group or also selected cannot move for whatever reason return false // if anyone in the merc's group or also selected cannot move for whatever reason return false
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -6423,6 +6425,11 @@ BOOLEAN LoadLeaveItemList( HWFILE hFile )
return(FALSE); return(FALSE);
} }
// Sanity check
if (uiCount > 1000) {
return(FALSE);
}
// allocate space // allocate space
gpLeaveListHead[ iCounter ] = new MERC_LEAVE_ITEM; gpLeaveListHead[ iCounter ] = new MERC_LEAVE_ITEM;
if( gpLeaveListHead[ iCounter ] == NULL ) if( gpLeaveListHead[ iCounter ] == NULL )
+5 -7
View File
@@ -6,6 +6,8 @@
#include "Soldier Control.h" #include "Soldier Control.h"
#include "MessageBoxScreen.h" #include "MessageBoxScreen.h"
#include "Font Control.h" #include "Font Control.h"
// WDS - make number of mercenaries, etc. be configurable
#include "Squads.h"
typedef struct FASTHELPREGION { typedef struct FASTHELPREGION {
@@ -39,11 +41,6 @@ typedef struct FASTHELPREGION {
#define CHAR_ICON_HEIGHT 10 #define CHAR_ICON_HEIGHT 10
#define CHAR_ICON_SPACING 13 #define CHAR_ICON_SPACING 13
// max number of characters and vehicles
//Character List Length
#define MAX_CHARACTER_COUNT 20
#define MAX_VEHICLE_COUNT 20
// map screen font // map screen font
#define MAP_SCREEN_FONT BLOCKFONT2 #define MAP_SCREEN_FONT BLOCKFONT2
@@ -228,8 +225,9 @@ enum{
#define TACT_UPDATE_MERC_X_OFFSET 4 #define TACT_UPDATE_MERC_X_OFFSET 4
// the first vehicle slot int he list // WDS - make number of mercenaries, etc. be configurable
#define FIRST_VEHICLE 18 // the first vehicle slot in the list
#define FIRST_VEHICLE CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS
class OLD_MERC_LEAVE_ITEM_101 class OLD_MERC_LEAVE_ITEM_101
{ {
+26 -10
View File
@@ -78,8 +78,9 @@ SOLDIERTYPE *pContractReHireSoldier = NULL;
UINT8 gubContractLength = 0; //used when extending a mercs insurance contract UINT8 gubContractLength = 0; //used when extending a mercs insurance contract
SOLDIERTYPE *gpInsuranceSoldier=NULL; SOLDIERTYPE *gpInsuranceSoldier=NULL;
// WDS - make number of mercenaries, etc. be configurable
// The values need to be saved! // The values need to be saved!
CONTRACT_NEWAL_LIST_NODE ContractRenewalList[ 20 ]; std::vector<CONTRACT_NEWAL_LIST_NODE> ContractRenewalList (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS);
UINT8 ubNumContractRenewals = 0; UINT8 ubNumContractRenewals = 0;
// end // end
UINT8 ubCurrentContractRenewal = 0; UINT8 ubCurrentContractRenewal = 0;
@@ -97,11 +98,18 @@ BOOLEAN SaveContractRenewalDataToSaveGameFile( HWFILE hFile )
{ {
UINT32 uiNumBytesWritten; UINT32 uiNumBytesWritten;
FileWrite( hFile, ContractRenewalList, sizeof( ContractRenewalList ), &uiNumBytesWritten ); for (int idx=0; idx < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; idx++) {
if( uiNumBytesWritten != sizeof( ContractRenewalList ) ) FileWrite( hFile, &ContractRenewalList[idx], sizeof( CONTRACT_NEWAL_LIST_NODE ), &uiNumBytesWritten );
{ if( uiNumBytesWritten != sizeof( CONTRACT_NEWAL_LIST_NODE ) )
return( FALSE ); {
return( FALSE );
}
} }
//FileWrite( hFile, ContractRenewalList, sizeof( ContractRenewalList ), &uiNumBytesWritten );
//if( uiNumBytesWritten != sizeof( ContractRenewalList ) )
//{
// return( FALSE );
//}
FileWrite( hFile, &ubNumContractRenewals, sizeof( ubNumContractRenewals ), &uiNumBytesWritten ); FileWrite( hFile, &ubNumContractRenewals, sizeof( ubNumContractRenewals ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( ubNumContractRenewals ) ) if( uiNumBytesWritten != sizeof( ubNumContractRenewals ) )
@@ -118,11 +126,18 @@ BOOLEAN LoadContractRenewalDataFromSaveGameFile( HWFILE hFile )
{ {
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
FileRead( hFile, ContractRenewalList, sizeof( ContractRenewalList ), &uiNumBytesRead ); for (int idx=0; idx < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; idx++) {
if( uiNumBytesRead != sizeof( ContractRenewalList ) ) FileRead( hFile, &ContractRenewalList[idx], sizeof( CONTRACT_NEWAL_LIST_NODE ), &uiNumBytesRead );
{ if( uiNumBytesRead != sizeof( CONTRACT_NEWAL_LIST_NODE ) )
return( FALSE ); {
return( FALSE );
}
} }
//FileRead( hFile, ContractRenewalList, sizeof( ContractRenewalList ), &uiNumBytesRead );
//if( uiNumBytesRead != sizeof( ContractRenewalList ) )
//{
// return( FALSE );
//}
FileRead( hFile, &ubNumContractRenewals, sizeof( ubNumContractRenewals ), &uiNumBytesRead ); FileRead( hFile, &ubNumContractRenewals, sizeof( ubNumContractRenewals ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( ubNumContractRenewals ) ) if( uiNumBytesRead != sizeof( ubNumContractRenewals ) )
@@ -1323,7 +1338,8 @@ void FindOutIfAnyMercAboutToLeaveIsGonnaRenew( void )
// find out is something was said // find out is something was said
SOLDIERTYPE *pSoldier = NULL, *pSoldierWhoWillQuit = NULL; SOLDIERTYPE *pSoldier = NULL, *pSoldierWhoWillQuit = NULL;
INT32 iCounter= 0, iNumberOnTeam = 0; INT32 iCounter= 0, iNumberOnTeam = 0;
UINT8 ubPotentialMercs[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
UINT8 ubPotentialMercs[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
+4 -3
View File
@@ -22,10 +22,11 @@ typedef struct
} CONTRACT_NEWAL_LIST_NODE; } CONTRACT_NEWAL_LIST_NODE;
extern CONTRACT_NEWAL_LIST_NODE ContractRenewalList[ 20 ]; // WDS - make number of mercenaries, etc. be configurable
extern UINT8 ubNumContractRenewals; //extern CONTRACT_NEWAL_LIST_NODE ContractRenewalList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
//extern UINT8 ubNumContractRenewals;
extern BOOLEAN gfContractRenewalSquenceOn; extern BOOLEAN gfContractRenewalSquenceOn;
extern UINT8 ubCurrentContractRenewal; //extern UINT8 ubCurrentContractRenewal;
extern BOOLEAN gfInContractMenuFromRenewSequence; extern BOOLEAN gfInContractMenuFromRenewSequence;
+3 -3
View File
@@ -270,8 +270,8 @@ UINT16 CountDirectionEnemyRating( INT16 sMapX, INT16 sMapY, UINT8 uiDir )
} }
//for( uiSector = 0 ; uiSector < 256 ; ++uiSector ) //for( uiSector = 0 ; uiSector < 256 ; ++uiSector )
for( sLMX = 0; sLMX < 16 ; ++sLMX ) for( sLMX = MINIMUM_VALID_X_COORDINATE; sLMX <= MAXIMUM_VALID_X_COORDINATE ; ++sLMX )
for( sLMY = 0; sLMY < 16 ; ++sLMY ) for( sLMY = MINIMUM_VALID_Y_COORDINATE; sLMY <= MAXIMUM_VALID_Y_COORDINATE ; ++sLMY )
{ {
// SECTORINFO *pSectorInfo = &( SectorInfo[ uiSector ] ); // SECTORINFO *pSectorInfo = &( SectorInfo[ uiSector ] );
UINT8 uiSumOfEnemyTroops = NumEnemiesInSector( sLMX, sLMY ); UINT8 uiSumOfEnemyTroops = NumEnemiesInSector( sLMX, sLMY );
@@ -810,7 +810,7 @@ void MilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY )
sMSMapX = sMapX; sMSMapX = sMapX;
sMSMapY = sMapY; sMSMapY = sMapY;
if( !gGameExternalOptions.gfAllowMilitiaGroups ) if( !gGameExternalOptions.gfAllowReinforcements )
return; return;
gTacticalStatus.uiFlags &= (~WANT_MILITIA_REINFORCEMENTS); gTacticalStatus.uiFlags &= (~WANT_MILITIA_REINFORCEMENTS);
+5
View File
@@ -23,6 +23,8 @@
#include "PreBattle Interface.h" #include "PreBattle Interface.h"
#include "Map Screen Interface.h" #include "Map Screen Interface.h"
#include "Tactical Save.h" #include "Tactical Save.h"
#include "interface Dialogue.h"
#include "Random.h"
#endif #endif
@@ -173,6 +175,9 @@ BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, B
// if player took control away from enemy // if player took control away from enemy
if( fWasEnemyControlled && fContested ) if( fWasEnemyControlled && fContested )
{ {
// WDS - New AI
// Hook in here for some stuff
// and it's a town // and it's a town
if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS))
{ {
+22 -17
View File
@@ -82,16 +82,18 @@ enum //GraphicIDs for the panel
UNINVOLVED_HEADER UNINVOLVED_HEADER
}; };
// WDS - make number of mercenaries, etc. be configurable
//The height of each row
#define ROW_HEIGHT 10
//The start of the black space //The start of the black space
#define TOP_Y 113 #define TOP_Y 113
//The end of the black space //The end of the black space
#define BOTTOM_Y 349 #define BOTTOM_Y (349+(gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs-18)*ROW_HEIGHT)
//#define BOTTOM_Y 349
//The internal height of the uninvolved panel //The internal height of the uninvolved panel
#define INTERNAL_HEIGHT 27 #define INTERNAL_HEIGHT 27
//The actual height of the uninvolved panel //The actual height of the uninvolved panel
#define ACTUAL_HEIGHT 34 #define ACTUAL_HEIGHT 34
//The height of each row
#define ROW_HEIGHT 10
BOOLEAN gfDisplayPotentialRetreatPaths = FALSE; BOOLEAN gfDisplayPotentialRetreatPaths = FALSE;
UINT16 gusRetreatButtonLeft, gusRetreatButtonTop, gusRetreatButtonRight, gusRetreatButtonBottom; UINT16 gusRetreatButtonLeft, gusRetreatButtonTop, gusRetreatButtonRight, gusRetreatButtonBottom;
@@ -122,16 +124,17 @@ SOLDIERTYPE* UninvolvedSoldier( INT32 index );
MOUSE_REGION PBInterfaceBlanket; MOUSE_REGION PBInterfaceBlanket;
BOOLEAN gfPreBattleInterfaceActive = FALSE; BOOLEAN gfPreBattleInterfaceActive = FALSE;
UINT32 iPBButton[3]; UINT32 iPBButton[3] = {0,0,0};
UINT32 iPBButtonImage[3]; UINT32 iPBButtonImage[3] = {0,0,0};
UINT32 uiInterfaceImages; // WDS Graphics bug die to uninitialized variable
BOOLEAN gfRenderPBInterface; UINT32 uiInterfaceImages = 0;
BOOLEAN gfPBButtonsHidden; BOOLEAN gfRenderPBInterface = FALSE;
BOOLEAN gfPBButtonsHidden = FALSE;
BOOLEAN fDisableMapInterfaceDueToBattle = FALSE; BOOLEAN fDisableMapInterfaceDueToBattle = FALSE;
void DoTransitionFromMapscreenToPreBattleInterface(); void DoTransitionFromMapscreenToPreBattleInterface();
BOOLEAN gfBlinkHeader; BOOLEAN gfBlinkHeader = FALSE;
// mouse regions in mapscreen proper than must have thier help text disabled then re-enabled // mouse regions in mapscreen proper than must have thier help text disabled then re-enabled
extern MOUSE_REGION gMapStatusBarsRegion; extern MOUSE_REGION gMapStatusBarsRegion;
@@ -145,8 +148,8 @@ extern void UpdateTheStateOfTheNextPrevMapScreenCharacterButtons( void );
// were we showing the mapscreen inventory when the prebattle interface came up // were we showing the mapscreen inventory when the prebattle interface came up
extern BOOLEAN fShowInventoryFlag; extern BOOLEAN fShowInventoryFlag;
UINT32 guiNumInvolved; UINT32 guiNumInvolved = 0;
UINT32 guiNumUninvolved; UINT32 guiNumUninvolved = 0;
//SAVE START //SAVE START
@@ -177,9 +180,10 @@ extern UINT8 gubPBSectorZ = 0;
BOOLEAN gfCantRetreatInPBI = FALSE; BOOLEAN gfCantRetreatInPBI = FALSE;
//SAVE END //SAVE END
BOOLEAN gfUsePersistantPBI; BOOLEAN gfUsePersistantPBI = FALSE;
INT32 giHilitedInvolved, giHilitedUninvolved; INT32 giHilitedInvolved = 0;
INT32 giHilitedUninvolved = 0;
extern void CalculateGroupRetreatSector( GROUP *pGroup ); extern void CalculateGroupRetreatSector( GROUP *pGroup );
@@ -259,7 +263,6 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
BOOLEAN fRetreatAnOption = TRUE; BOOLEAN fRetreatAnOption = TRUE;
SECTORINFO *pSector; SECTORINFO *pSector;
// ARM: Feb01/98 - Cancel out of mapscreen movement plotting if PBI subscreen is coming up // ARM: Feb01/98 - Cancel out of mapscreen movement plotting if PBI subscreen is coming up
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) )
{ {
@@ -506,8 +509,9 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
} }
guiNumInvolved ++; guiNumInvolved ++;
} }
else else {
guiNumUninvolved++; guiNumUninvolved++;
}
} }
} }
@@ -999,7 +1003,7 @@ void RenderPreBattleInterface()
if( gusMouseXPos < gusRetreatButtonLeft || gusMouseXPos > gusRetreatButtonRight || if( gusMouseXPos < gusRetreatButtonLeft || gusMouseXPos > gusRetreatButtonRight ||
gusMouseYPos < gusRetreatButtonTop || gusMouseYPos > gusRetreatButtonBottom ) gusMouseYPos < gusRetreatButtonTop || gusMouseYPos > gusRetreatButtonBottom )
fMouseInRetreatButtonArea = FALSE; fMouseInRetreatButtonArea = FALSE;
else else
fMouseInRetreatButtonArea = TRUE; fMouseInRetreatButtonArea = TRUE;
if( fMouseInRetreatButtonArea != gfDisplayPotentialRetreatPaths ) if( fMouseInRetreatButtonArea != gfDisplayPotentialRetreatPaths )
{ {
@@ -1106,7 +1110,8 @@ void RenderPreBattleInterface()
BltVideoObject( guiSAVEBUFFER, hVObject, BOTTOM_COLUMN, 161, y, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObject( guiSAVEBUFFER, hVObject, BOTTOM_COLUMN, 161, y, VO_BLT_SRCTRANSPARENCY, NULL );
} }
for( i = 0; i < (INT32)(21 - max( guiNumUninvolved, 1 )); i++ ) // WDS - make number of mercenaries, etc. be configurable
for( i = 0; i < (INT32)(/*21*/3+gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs - max( guiNumUninvolved, 1 )); i++ )
{ {
y = TOP_Y + ROW_HEIGHT * i; y = TOP_Y + ROW_HEIGHT * i;
BltVideoObject( guiSAVEBUFFER, hVObject, TOP_COLUMN, 186, y, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObject( guiSAVEBUFFER, hVObject, TOP_COLUMN, 186, y, VO_BLT_SRCTRANSPARENCY, NULL );
+134 -76
View File
@@ -52,10 +52,13 @@
#include "connect.h" #include "connect.h"
#include "Reinforcement.h" #include "Reinforcement.h"
#include "MilitiaSquads.h" #include "MilitiaSquads.h"
#include <vector>
//The sector information required for the strategic AI. Contains the number of enemy troops, //The sector information required for the strategic AI. Contains the number of enemy troops,
//as well as intentions, etc. //as well as intentions, etc.
SECTORINFO SectorInfo[256]; //SECTORINFO SectorInfo[256];
std::vector<SECTORINFO> SectorInfo (256);
UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead = NULL; UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead = NULL;
extern UNDERGROUND_SECTORINFO* gpUndergroundSectorInfoTail; extern UNDERGROUND_SECTORINFO* gpUndergroundSectorInfoTail;
BOOLEAN gfPendingEnemies = FALSE; BOOLEAN gfPendingEnemies = FALSE;
@@ -95,6 +98,11 @@ void ValidateEnemiesHaveWeapons()
{ {
iNumInvalid++; iNumInvalid++;
} }
// WDS DEBUG
// Uncommenting the following two lines will cause all the PLACED soldiers to instantly drop dead,
// which is useful for debugging some things
//pSoldier->bBleeding = 10;
//pSoldier->stats.bLife = 1;
} }
// do message box and return // do message box and return
@@ -112,9 +120,12 @@ UINT8 NumHostilesInSector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
{ {
UINT8 ubNumHostiles = 0; UINT8 ubNumHostiles = 0;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
Assert( sSectorZ >= 0 && sSectorZ <= 3 ); AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
AssertGE( sSectorZ, MINIMUM_VALID_Z_COORDINATE );
AssertLE( sSectorZ, MAXIMUM_VALID_Z_COORDINATE );
if( sSectorZ ) if( sSectorZ )
{ {
@@ -153,9 +164,12 @@ UINT8 NumEnemiesInAnySector( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ )
{ {
UINT8 ubNumEnemies = 0; UINT8 ubNumEnemies = 0;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
Assert( sSectorZ >= 0 && sSectorZ <= 3 ); AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
AssertGE( sSectorZ, MINIMUM_VALID_Z_COORDINATE );
AssertLE( sSectorZ, MAXIMUM_VALID_Z_COORDINATE );
if( sSectorZ ) if( sSectorZ )
{ {
@@ -196,8 +210,10 @@ UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
GROUP *pGroup; GROUP *pGroup;
UINT8 ubNumTroops; UINT8 ubNumTroops;
//Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
//Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites); ubNumTroops = (UINT8)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
@@ -220,8 +236,10 @@ UINT8 NumEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY ) UINT8 NumStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
if( pSector->ubGarrisonID == NO_GARRISON ) if( pSector->ubGarrisonID == NO_GARRISON )
@@ -246,8 +264,10 @@ UINT8 NumMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
GROUP *pGroup; GROUP *pGroup;
SECTORINFO *pSector; SECTORINFO *pSector;
UINT8 ubNumTroops; UINT8 ubNumTroops;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
ubNumTroops = 0; ubNumTroops = 0;
pGroup = gpGroupList; pGroup = gpGroupList;
@@ -273,8 +293,10 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
{ {
GROUP *pGroup; GROUP *pGroup;
SECTORINFO *pSector; SECTORINFO *pSector;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector. //Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = 0; *pubNumTroops = *pubNumElites = *pubNumAdmins = 0;
@@ -303,8 +325,10 @@ void GetNumberOfMobileEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pu
void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites ) void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
{ {
GROUP *pGroup; GROUP *pGroup;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
//Now count the number of mobile groups in the sector. //Now count the number of mobile groups in the sector.
*pubNumTroops = *pubNumElites = *pubNumAdmins = 0; *pubNumTroops = *pubNumElites = *pubNumAdmins = 0;
@@ -325,8 +349,10 @@ void GetNumberOfMobileEnemiesInSectorWithoutRoadBlock( INT16 sSectorX, INT16 sSe
void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites ) void GetNumberOfStationaryEnemiesInSector( INT16 sSectorX, INT16 sSectorY, UINT8 *pubNumAdmins, UINT8 *pubNumTroops, UINT8 *pubNumElites )
{ {
SECTORINFO *pSector; SECTORINFO *pSector;
Assert( sSectorX >= 1 && sSectorX <= 16 ); AssertGE( sSectorX, MINIMUM_VALID_X_COORDINATE);
Assert( sSectorY >= 1 && sSectorY <= 16 ); AssertLE( sSectorX, MAXIMUM_VALID_X_COORDINATE );
AssertGE( sSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE( sSectorY, MAXIMUM_VALID_Y_COORDINATE );
pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ]; pSector = &SectorInfo[ SECTOR( sSectorX, sSectorY ) ];
//grab the number of each type in the stationary sector //grab the number of each type in the stationary sector
@@ -428,6 +454,7 @@ UINT8 NumFreeEnemySlots()
return ubNumFreeSlots; return ubNumFreeSlots;
} }
//Called when entering a sector so the campaign AI can automatically insert the //Called when entering a sector so the campaign AI can automatically insert the
//correct number of troops of each type based on the current number in the sector //correct number of troops of each type based on the current number in the sector
//in global focus (gWorldSectorX/Y) //in global focus (gWorldSectorX/Y)
@@ -436,11 +463,11 @@ BOOLEAN PrepareEnemyForSectorBattle()
SECTORINFO *pSector; SECTORINFO *pSector;
GROUP *pGroup; GROUP *pGroup;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
UINT8 ubNumAdmins, ubNumTroops, ubNumElites; unsigned ubNumAdmins, ubNumTroops, ubNumElites;
UINT8 ubTotalAdmins, ubTotalElites, ubTotalTroops; unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops;
UINT8 ubStationaryEnemies; unsigned totalCountOfStationaryEnemies = 0;
INT32 i, num; unsigned totalCountOfMobileEnemies = 0;
INT16 sNumSlots; int sNumSlots;
gfPendingEnemies = FALSE; gfPendingEnemies = FALSE;
@@ -459,7 +486,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
!( (GetTownIdForSector( gWorldSectorX, gWorldSectorY ) == OMERTA )&&( gGameOptions.ubDifficultyLevel != DIF_LEVEL_INSANE ) ) ) !( (GetTownIdForSector( gWorldSectorX, gWorldSectorY ) == OMERTA )&&( gGameOptions.ubDifficultyLevel != DIF_LEVEL_INSANE ) ) )
{ {
UINT16 pusMoveDir[4][3]; UINT16 pusMoveDir[4][3];
UINT8 ubDirNumber = 0, ubIndex; UINT8 ubDirNumber = 0;
GROUP *pGroup; GROUP *pGroup;
SECTORINFO *pThisSector; SECTORINFO *pThisSector;
@@ -469,7 +496,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
GenerateDirectionInfos( gWorldSectorX, gWorldSectorY, &ubDirNumber, pusMoveDir, GenerateDirectionInfos( gWorldSectorX, gWorldSectorY, &ubDirNumber, pusMoveDir,
( GetTownIdForSector( gWorldSectorX, gWorldSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES ); ( GetTownIdForSector( gWorldSectorX, gWorldSectorY ) != BLANK_SECTOR ? TRUE : FALSE ), TRUE, IS_ONLY_IN_CITIES );
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ ) for( unsigned ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
{ {
while ( NumMobileEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) && GetEnemyGroupInSector( SECTORX( pusMoveDir[ ubIndex][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) ) while ( NumMobileEnemiesInSector( SECTORX( pusMoveDir[ ubIndex ][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) && GetEnemyGroupInSector( SECTORX( pusMoveDir[ ubIndex][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) )
{ {
@@ -505,19 +532,27 @@ BOOLEAN PrepareEnemyForSectorBattle()
return ( ( BOOLEAN) ( gpBattleGroup->ubGroupSize > 0 ) ); return ( ( BOOLEAN) ( gpBattleGroup->ubGroupSize > 0 ) );
} }
if( !gbWorldSectorZ ) // WDS Count the number of placements. This will limit the maximum number of enemies we can place on the map
{ SOLDIERINITNODE *curr = gSoldierInitHead;
if( NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) > 32 ) unsigned mapMaximumNumberOfEnemies = 0;
{ while( curr ) {
gfPendingEnemies = TRUE; if( curr->pBasicPlacement->bTeam == ENEMY_TEAM ) {
++mapMaximumNumberOfEnemies;
} }
curr = curr->next;
} }
AssertGE (mapMaximumNumberOfEnemies, 0);
if (mapMaximumNumberOfEnemies > gGameExternalOptions.ubGameMaximumNumberOfEnemies)
mapMaximumNumberOfEnemies = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
gfPendingEnemies = (NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) > mapMaximumNumberOfEnemies );
pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ]; pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
if( pSector->uiFlags & SF_USE_MAP_SETTINGS ) if( pSector->uiFlags & SF_USE_MAP_SETTINGS )
{ //count the number of enemy placements in a map and use those { //count the number of enemy placements in a map and use those
SOLDIERINITNODE *curr; SOLDIERINITNODE *curr = gSoldierInitHead;
curr = gSoldierInitHead;
ubTotalAdmins = ubTotalTroops = ubTotalElites = 0; ubTotalAdmins = ubTotalTroops = ubTotalElites = 0;
while( curr ) while( curr )
{ {
@@ -526,8 +561,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
switch( curr->pBasicPlacement->ubSoldierClass ) switch( curr->pBasicPlacement->ubSoldierClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: ubTotalAdmins++; break; case SOLDIER_CLASS_ADMINISTRATOR: ubTotalAdmins++; break;
case SOLDIER_CLASS_ARMY: ubTotalTroops++; break; case SOLDIER_CLASS_ARMY: ubTotalTroops++; break;
case SOLDIER_CLASS_ELITE: ubTotalElites++; break; case SOLDIER_CLASS_ELITE: ubTotalElites++; break;
} }
} }
curr = curr->next; curr = curr->next;
@@ -541,23 +576,25 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
else else
{ {
ubTotalAdmins = (UINT8)(pSector->ubNumAdmins - pSector->ubAdminsInBattle); ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle;
ubTotalTroops = (UINT8)(pSector->ubNumTroops - pSector->ubTroopsInBattle); ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle;
ubTotalElites = (UINT8)(pSector->ubNumElites - pSector->ubElitesInBattle); ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle;
} }
ubStationaryEnemies = (UINT8)(ubTotalAdmins + ubTotalTroops + ubTotalElites); totalCountOfStationaryEnemies = ubTotalAdmins + ubTotalTroops + ubTotalElites;
if( ubStationaryEnemies > 32 ) if( totalCountOfStationaryEnemies > mapMaximumNumberOfEnemies )
{ {
/*
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
ScreenMsg( FONT_RED, MSG_ERROR, L"The total stationary enemy forces in sector %c%d is %d. (max %d)", ScreenMsg( FONT_RED, MSG_ERROR, L"The total stationary enemy forces in sector %c%d is %d. (max %d)",
gWorldSectorY + 'A' - 1, gWorldSectorX, ubTotalAdmins + ubTotalTroops + ubTotalElites, 32 ); gWorldSectorY + 'A' - 1, gWorldSectorX, ubTotalAdmins + ubTotalTroops + ubTotalElites, mapMaximumNumberOfEnemies );
#endif #endif
*/
ubTotalAdmins = min( 32, ubTotalAdmins ); ubTotalAdmins = min( mapMaximumNumberOfEnemies, ubTotalAdmins );
ubTotalTroops = min( 32-ubTotalAdmins, ubTotalTroops ); ubTotalTroops = min( mapMaximumNumberOfEnemies-ubTotalAdmins, ubTotalTroops );
ubTotalElites = min( 32-ubTotalAdmins+ubTotalTroops, ubTotalElites ); ubTotalElites = min( mapMaximumNumberOfEnemies-ubTotalAdmins-ubTotalTroops, ubTotalElites );
} }
pSector->ubAdminsInBattle += ubTotalAdmins; pSector->ubAdminsInBattle += ubTotalAdmins;
@@ -578,6 +615,11 @@ BOOLEAN PrepareEnemyForSectorBattle()
//Search for movement groups that happen to be in the sector. //Search for movement groups that happen to be in the sector.
sNumSlots = NumFreeEnemySlots(); sNumSlots = NumFreeEnemySlots();
if (sNumSlots > (int)mapMaximumNumberOfEnemies)
sNumSlots = mapMaximumNumberOfEnemies;
/*
* WDS - this test no longer valid with the above change
//Test: All slots should be free at this point! //Test: All slots should be free at this point!
if( sNumSlots != gTacticalStatus.Team[ENEMY_TEAM].bLastID - gTacticalStatus.Team[ENEMY_TEAM].bFirstID + 1 ) if( sNumSlots != gTacticalStatus.Team[ENEMY_TEAM].bLastID - gTacticalStatus.Team[ENEMY_TEAM].bFirstID + 1 )
{ {
@@ -587,6 +629,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubTotalAdmins, ubTotalTroops, ubTotalElites ); ubTotalAdmins, ubTotalTroops, ubTotalElites );
#endif #endif
} }
*/
//Subtract the total number of stationary enemies from the available slots, as stationary forces take //Subtract the total number of stationary enemies from the available slots, as stationary forces take
//precendence in combat. The mobile forces that could also be in the same sector are considered later if //precendence in combat. The mobile forces that could also be in the same sector are considered later if
@@ -606,7 +649,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
{ //Process enemy group in sector. { //Process enemy group in sector.
if( sNumSlots > 0 ) if( sNumSlots > 0 )
{ {
ubNumAdmins = (UINT8)(pGroup->pEnemyGroup->ubNumAdmins - pGroup->pEnemyGroup->ubAdminsInBattle); AssertGE(pGroup->pEnemyGroup->ubNumAdmins, pGroup->pEnemyGroup->ubAdminsInBattle);
ubNumAdmins = pGroup->pEnemyGroup->ubNumAdmins - pGroup->pEnemyGroup->ubAdminsInBattle;
sNumSlots -= ubNumAdmins; sNumSlots -= ubNumAdmins;
if( sNumSlots < 0 ) if( sNumSlots < 0 )
{ //adjust the value to zero { //adjust the value to zero
@@ -619,7 +663,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
if( sNumSlots > 0 ) if( sNumSlots > 0 )
{ //Add regular army forces. { //Add regular army forces.
ubNumTroops = (UINT8)(pGroup->pEnemyGroup->ubNumTroops - pGroup->pEnemyGroup->ubTroopsInBattle); AssertGE(pGroup->pEnemyGroup->ubNumTroops, pGroup->pEnemyGroup->ubTroopsInBattle);
ubNumTroops = pGroup->pEnemyGroup->ubNumTroops - pGroup->pEnemyGroup->ubTroopsInBattle;
sNumSlots -= ubNumTroops; sNumSlots -= ubNumTroops;
if( sNumSlots < 0 ) if( sNumSlots < 0 )
{ //adjust the value to zero { //adjust the value to zero
@@ -632,7 +677,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
if( sNumSlots > 0 ) if( sNumSlots > 0 )
{ //Add elite troops { //Add elite troops
ubNumElites = (UINT8)(pGroup->pEnemyGroup->ubNumElites - pGroup->pEnemyGroup->ubElitesInBattle); AssertGE(pGroup->pEnemyGroup->ubNumElites, pGroup->pEnemyGroup->ubElitesInBattle);
ubNumElites = pGroup->pEnemyGroup->ubNumElites - pGroup->pEnemyGroup->ubElitesInBattle;
sNumSlots -= ubNumElites; sNumSlots -= ubNumElites;
if( sNumSlots < 0 ) if( sNumSlots < 0 )
{ //adjust the value to zero { //adjust the value to zero
@@ -673,10 +719,10 @@ BOOLEAN PrepareEnemyForSectorBattle()
//Now, we have to go through all of the enemies in the new map, and assign their respective groups if //Now, we have to go through all of the enemies in the new map, and assign their respective groups if
//in a mobile group, but only for the ones that were assigned from the //in a mobile group, but only for the ones that were assigned from the
sNumSlots = 32 - ubStationaryEnemies; sNumSlots = mapMaximumNumberOfEnemies - totalCountOfStationaryEnemies;
pGroup = gpGroupList; pGroup = gpGroupList;
while( pGroup && sNumSlots ) while( pGroup && sNumSlots > 0 )
{ {
if( !pGroup->fPlayer && !pGroup->fVehicle && if( !pGroup->fPlayer && !pGroup->fVehicle &&
pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ ) pGroup->ubSectorX == gWorldSectorX && pGroup->ubSectorY == gWorldSectorY && !gbWorldSectorZ )
@@ -684,16 +730,18 @@ BOOLEAN PrepareEnemyForSectorBattle()
ubNumAdmins = pGroup->pEnemyGroup->ubAdminsInBattle; ubNumAdmins = pGroup->pEnemyGroup->ubAdminsInBattle;
ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle; ubNumTroops = pGroup->pEnemyGroup->ubTroopsInBattle;
ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle; ubNumElites = pGroup->pEnemyGroup->ubElitesInBattle;
num = ubNumAdmins + ubNumTroops + ubNumElites; unsigned num = ubNumAdmins + ubNumTroops + ubNumElites;
for (i= gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; unsigned firstSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
i<= gTacticalStatus.Team[ ENEMY_TEAM ].bLastID && num; unsigned lastSlot = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
i++) unsigned slotsAvailable = lastSlot-firstSlot+1;
AssertGE((int)slotsAvailable, sNumSlots);
for (unsigned slot = firstSlot;
(slot <= lastSlot) && (num > 0);
++slot)
{ {
// At this point we should not have added more soldiers than are in slots pSoldier = &Menptr[ slot ];
Assert( sNumSlots);
pSoldier = &Menptr[ i ];
// Skip inactive and already grouped soldiers // Skip inactive and already grouped soldiers
if (!pSoldier->bActive || pSoldier->ubGroupID) if (!pSoldier->bActive || pSoldier->ubGroupID)
@@ -701,6 +749,9 @@ BOOLEAN PrepareEnemyForSectorBattle()
continue; continue;
} }
// At this point we should not have added more soldiers than are in slots
AssertGT( sNumSlots, 0 );
switch( pSoldier->ubSoldierClass ) switch( pSoldier->ubSoldierClass )
{ {
case SOLDIER_CLASS_ADMINISTRATOR: case SOLDIER_CLASS_ADMINISTRATOR:
@@ -733,7 +784,10 @@ BOOLEAN PrepareEnemyForSectorBattle()
} }
} }
Assert( ubNumElites + ubNumTroops + ubNumAdmins + num == 0); AssertEQ( ubNumElites , 0);
AssertEQ( ubNumTroops , 0);
AssertEQ( ubNumAdmins , 0);
AssertEQ( num , 0);
} }
pGroup = pGroup->next; pGroup = pGroup->next;
} }
@@ -746,7 +800,8 @@ BOOLEAN PrepareEnemyForSectorBattle()
BOOLEAN PrepareEnemyForUndergroundBattle() BOOLEAN PrepareEnemyForUndergroundBattle()
{ {
UNDERGROUND_SECTORINFO *pUnderground; UNDERGROUND_SECTORINFO *pUnderground;
UINT8 ubTotalAdmins, ubTotalTroops, ubTotalElites; unsigned ubTotalAdmins, ubTotalTroops, ubTotalElites;
pUnderground = gpUndergroundSectorInfoHead; pUnderground = gpUndergroundSectorInfoHead;
while( pUnderground ) while( pUnderground )
{ {
@@ -780,9 +835,10 @@ void ProcessQueenCmdImplicationsOfDeath( SOLDIERTYPE *pSoldier )
{ {
INT32 iNumEnemiesInSector; INT32 iNumEnemiesInSector;
SECTORINFO *pSector; SECTORINFO *pSector;
// CHAR16 str[128];
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize; INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand"); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
AssertNotNIL (pSoldier);
EvaluateDeathEffectsToSoldierInitList( pSoldier ); EvaluateDeathEffectsToSoldierInitList( pSoldier );
@@ -861,7 +917,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumElites != pGroup->pEnemyGroup->ubElitesInBattle && !gfPendingEnemies || if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumElites != pGroup->pEnemyGroup->ubElitesInBattle && !gfPendingEnemies ||
pGroup->ubGroupSize > iMaxEnemyGroupSize || pGroup->pEnemyGroup->ubNumElites > 50 || pGroup->pEnemyGroup->ubElitesInBattle > 50 ) pGroup->ubGroupSize > iMaxEnemyGroupSize /* || pGroup->pEnemyGroup->ubNumElites > 50 || pGroup->pEnemyGroup->ubElitesInBattle > 50*/ )
{ {
DoScreenIndependantMessageBox( L"Group elite 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 ); DoScreenIndependantMessageBox( L"Group elite 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 );
} }
@@ -887,7 +943,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumTroops != pGroup->pEnemyGroup->ubTroopsInBattle && !gfPendingEnemies || if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumTroops != pGroup->pEnemyGroup->ubTroopsInBattle && !gfPendingEnemies ||
pGroup->ubGroupSize > iMaxEnemyGroupSize || pGroup->pEnemyGroup->ubNumTroops > 50 || pGroup->pEnemyGroup->ubTroopsInBattle > 50 ) pGroup->ubGroupSize > iMaxEnemyGroupSize /*|| pGroup->pEnemyGroup->ubNumTroops > 50 || pGroup->pEnemyGroup->ubTroopsInBattle > 50*/ )
{ {
// haydent // haydent
if (!is_client) if (!is_client)
@@ -918,7 +974,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumAdmins != pGroup->pEnemyGroup->ubAdminsInBattle && !gfPendingEnemies || if( pGroup->ubGroupSize <= iMaxEnemyGroupSize && pGroup->pEnemyGroup->ubNumAdmins != pGroup->pEnemyGroup->ubAdminsInBattle && !gfPendingEnemies ||
pGroup->ubGroupSize > iMaxEnemyGroupSize || pGroup->pEnemyGroup->ubNumAdmins > 50 || pGroup->pEnemyGroup->ubAdminsInBattle > 50 ) pGroup->ubGroupSize > iMaxEnemyGroupSize /*|| pGroup->pEnemyGroup->ubNumAdmins > 50 || pGroup->pEnemyGroup->ubAdminsInBattle > 50*/ )
{ {
DoScreenIndependantMessageBox( L"Group admin 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 ); DoScreenIndependantMessageBox( L"Group admin 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 );
} }
@@ -970,9 +1026,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( ubTotalEnemies <= 32 && pSector->ubNumAdmins != pSector->ubAdminsInBattle || if( ubTotalEnemies <= gGameExternalOptions.ubGameMaximumNumberOfEnemies && pSector->ubNumAdmins != pSector->ubAdminsInBattle ||
!pSector->ubNumAdmins || !pSector->ubAdminsInBattle || !pSector->ubNumAdmins || !pSector->ubAdminsInBattle ||
pSector->ubNumAdmins > 100 || pSector->ubAdminsInBattle > 32 ) pSector->ubNumAdmins > gGameExternalOptions.ubGameMaximumNumberOfEnemies || pSector->ubAdminsInBattle > gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ {
DoScreenIndependantMessageBox( L"Sector admin 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 ); DoScreenIndependantMessageBox( L"Sector admin 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 );
} }
@@ -991,9 +1047,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( ubTotalEnemies <= 32 && pSector->ubNumTroops != pSector->ubTroopsInBattle || if( ubTotalEnemies <= gGameExternalOptions.ubGameMaximumNumberOfEnemies && pSector->ubNumTroops != pSector->ubTroopsInBattle ||
!pSector->ubNumTroops || !pSector->ubTroopsInBattle || !pSector->ubNumTroops || !pSector->ubTroopsInBattle ||
pSector->ubNumTroops > 100 || pSector->ubTroopsInBattle > 32 ) pSector->ubNumTroops > gGameExternalOptions.ubGameMaximumNumberOfEnemies || pSector->ubTroopsInBattle > gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ {
if(!is_client)DoScreenIndependantMessageBox( L"Sector troop 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(!is_client)DoScreenIndependantMessageBox( L"Sector troop 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 );
//disabled: hayden. //disabled: hayden.
@@ -1013,9 +1069,9 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( guiCurrentScreen == GAME_SCREEN ) if( guiCurrentScreen == GAME_SCREEN )
{ {
if( ubTotalEnemies <= 32 && pSector->ubNumElites != pSector->ubElitesInBattle || if( ubTotalEnemies <= gGameExternalOptions.ubGameMaximumNumberOfEnemies && pSector->ubNumElites != pSector->ubElitesInBattle ||
!pSector->ubNumElites || !pSector->ubElitesInBattle || !pSector->ubNumElites || !pSector->ubElitesInBattle ||
pSector->ubNumElites > 100 || pSector->ubElitesInBattle > 32 ) pSector->ubNumElites > gGameExternalOptions.ubGameMaximumNumberOfEnemies || pSector->ubElitesInBattle > gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ {
DoScreenIndependantMessageBox( L"Sector elite 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 ); DoScreenIndependantMessageBox( L"Sector elite 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 );
} }
@@ -1133,7 +1189,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
if( ubTotalEnemies <= (UINT32)iMaxEnemyGroupSize && pSector->ubNumCreatures != pSector->ubCreaturesInBattle || if( ubTotalEnemies <= (UINT32)iMaxEnemyGroupSize && pSector->ubNumCreatures != pSector->ubCreaturesInBattle ||
!pSector->ubNumCreatures || !pSector->ubCreaturesInBattle || !pSector->ubNumCreatures || !pSector->ubCreaturesInBattle ||
pSector->ubNumCreatures > 50 || pSector->ubCreaturesInBattle > 50 ) 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 ); 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 );
} }
@@ -1191,11 +1247,15 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"QueenCommand");
//Well, not so rarely with mobile reinforcements! //Well, not so rarely with mobile reinforcements!
//Rarely, there will be more enemies than supported by the engine. In this case, these //Rarely, there will be more enemies than supported by the engine. In this case, these
//soldiers are waiting for a slot to be free so that they can enter the battle. This //soldiers are waiting for a slot to be free so that they can enter the battle. This
//essentially allows for an infinite number of troops, though only 32 at a time can fight. //essentially allows for an infinite number of troops, though only gGameExternalOptions.ubGameMaximumNumberOfEnemies at a time can fight.
//This is also called whenever an enemy group's reinforcements arrive because the code is //This is also called whenever an enemy group's reinforcements arrive because the code is
//identical, though it is highly likely that they will all be successfully added on the first call. //identical, though it is highly likely that they will all be successfully added on the first call.
void AddPossiblePendingEnemiesToBattle() void AddPossiblePendingEnemiesToBattle()
{ {
// check if no world is loaded
if ( !gWorldSectorX && !gWorldSectorY && (gbWorldSectorZ == -1) )
return;
UINT8 ubSlots, ubNumAvailable; UINT8 ubSlots, ubNumAvailable;
UINT8 ubNumElites, ubNumTroops, ubNumAdmins; UINT8 ubNumElites, ubNumTroops, ubNumAdmins;
UINT8 ubNumGroupsInSector; UINT8 ubNumGroupsInSector;
@@ -1214,10 +1274,6 @@ void AddPossiblePendingEnemiesToBattle()
} }
} }
// check if no world is loaded
if ( !gWorldSectorX && !gWorldSectorY && (gbWorldSectorZ == -1) )
return;
if( ( !PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) && !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ) ) if( ( !PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) && !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ) )
|| !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) return; || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) return;
@@ -1811,6 +1867,8 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
static INT16 sInterrogationItemGridNo[] = { 12089, 12089, 12089 }; static INT16 sInterrogationItemGridNo[] = { 12089, 12089, 12089 };
AssertNotNIL(pSoldier);
// ATE: Check first if ! in player captured sequence already // ATE: Check first if ! in player captured sequence already
// CJC Dec 1 2002: fixing multiple captures // CJC Dec 1 2002: fixing multiple captures
+3 -3
View File
@@ -332,7 +332,7 @@ UINT8 NumFreeMilitiaSlots()
if( !pSoldier->bActive ) if( !pSoldier->bActive )
ubNumFreeSlots++; ubNumFreeSlots++;
} }
return max( 0 , ubNumFreeSlots - ( 32 - gGameExternalOptions.guiMaxMilitiaSquadSize ) ); return max( 0 , ubNumFreeSlots - ( gGameExternalOptions.ubGameMaximumNumberOfRebels - gGameExternalOptions.guiMaxMilitiaSquadSize ) );
} }
UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank ) UINT8 DoReinforcementAsPendingMilitia( INT16 sMapX, INT16 sMapY, UINT8 *pubRank )
@@ -403,9 +403,9 @@ void AddPossiblePendingMilitiaToBattle()
// if( !PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) || !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ) // if( !PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) || !CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY )
// || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) return; // || !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) ) return;
if( !PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) if( (PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, 0 ) == 0)
|| !(gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS) || !(gTacticalStatus.uiFlags & WANT_MILITIA_REINFORCEMENTS)
|| !NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) || (NumEnemiesInSector( gWorldSectorX, gWorldSectorY ) == 0)
) )
return; return;
//gGameExternalOptions.guiMaxMilitiaSquadSize - CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY ); //gGameExternalOptions.guiMaxMilitiaSquadSize - CountAllMilitiaInSector( gWorldSectorX, gWorldSectorY );
+168 -9
View File
@@ -830,6 +830,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic2");
void ValidateLargeGroup( GROUP *pGroup ) void ValidateLargeGroup( GROUP *pGroup )
{ {
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
/* WDS - this code is no longer applicable with changes to group sizes
if( pGroup->ubGroupSize > 25 ) if( pGroup->ubGroupSize > 25 )
{ {
CHAR16 str[ 512 ]; CHAR16 str[ 512 ];
@@ -840,6 +841,7 @@ void ValidateLargeGroup( GROUP *pGroup )
pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX ); pGroup->ubSectorY + 'A' - 1, pGroup->ubSectorX );
SAIReportError( str ); SAIReportError( str );
} }
*/
#endif #endif
} }
@@ -2326,6 +2328,7 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
return FALSE; return FALSE;
if( !EnemyPermittedToAttackSector( NULL, (UINT8)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY ) ) ) if( !EnemyPermittedToAttackSector( NULL, (UINT8)SECTOR( pPlayerGroup->ubSectorX, pPlayerGroup->ubSectorY ) ) )
return FALSE; return FALSE;
// WDS BAD BUG FIX - 12/25/2008 - some of the +1/-1 in the following were goofed up
if( pPlayerGroup->ubSectorY > 1 ) if( pPlayerGroup->ubSectorY > 1 )
{ {
pEnemyGroup = FindMovementGroupInSector( pPlayerGroup->ubSectorX, (UINT8)(pPlayerGroup->ubSectorY-1), FALSE ); pEnemyGroup = FindMovementGroupInSector( pPlayerGroup->ubSectorX, (UINT8)(pPlayerGroup->ubSectorY-1), FALSE );
@@ -2350,11 +2353,11 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
HandlePlayerGroupNoticedByPatrolGroup( pPlayerGroup, pEnemyGroup ); HandlePlayerGroupNoticedByPatrolGroup( pPlayerGroup, pEnemyGroup );
return FALSE; return FALSE;
} }
pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) ]; pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX+1, pPlayerGroup->ubSectorY ) ];
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites; ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() ) if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() )
{ {
HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) ); HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX+1, pPlayerGroup->ubSectorY ) );
return FALSE; return FALSE;
} }
} }
@@ -2382,11 +2385,11 @@ BOOLEAN StrategicAILookForAdjacentGroups( GROUP *pGroup )
HandlePlayerGroupNoticedByPatrolGroup( pPlayerGroup, pEnemyGroup ); HandlePlayerGroupNoticedByPatrolGroup( pPlayerGroup, pEnemyGroup );
return FALSE; return FALSE;
} }
pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX+1, pPlayerGroup->ubSectorY ) ]; pSector = &SectorInfo[ SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) ];
ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites; ubNumEnemies = pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites;
if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() ) if( ubNumEnemies && pSector->ubGarrisonID != NO_GARRISON && AttemptToNoticeAdjacentGroupSucceeds() )
{ {
HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX+1, pPlayerGroup->ubSectorY ) ); HandlePlayerGroupNoticedByGarrison( pPlayerGroup, (UINT8)SECTOR( pPlayerGroup->ubSectorX-1, pPlayerGroup->ubSectorY ) );
return FALSE; return FALSE;
} }
} }
@@ -2790,7 +2793,7 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
UINT8 ubGroupSize; UINT8 ubGroupSize;
BOOLEAN fLimitMaxTroopsAllowable = FALSE; BOOLEAN fLimitMaxTroopsAllowable = FALSE;
Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */ Ensure_RepairedGarrisonGroup( &gGarrisonGroup, &giGarrisonArraySize ); /* added NULL fix, 2007-03-03, Sgt. Kolja */
ValidateWeights( 8 ); ValidateWeights( 8 );
if( gGarrisonGroup[ iDstGarrisonID ].ubSectorID == SEC_B13 || if( gGarrisonGroup[ iDstGarrisonID ].ubSectorID == SEC_B13 ||
@@ -2928,7 +2931,9 @@ void SendReinforcementsForGarrison( INT32 iDstGarrisonID, UINT16 usDefencePoints
else else
{ {
iSrcGarrisonID = ChooseSuitableGarrisonToProvideReinforcements( iDstGarrisonID, iReinforcementsRequested ); iSrcGarrisonID = ChooseSuitableGarrisonToProvideReinforcements( iDstGarrisonID, iReinforcementsRequested );
if( iSrcGarrisonID == -1 ) // WDS 08/01/2008 - Fix 0 reinforcement problem
iReinforcementsAvailable = ReinforcementsAvailable( iSrcGarrisonID );
if( (iSrcGarrisonID == -1) || (iReinforcementsAvailable == 0) )
{ {
ValidateWeights( 15 ); ValidateWeights( 15 );
goto QUEEN_POOL; goto QUEEN_POOL;
@@ -4154,14 +4159,15 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic7");
} }
} }
void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSectorY ) void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSectorY,
INT32 option1, INT32 option2 )
{ {
GROUP *pGroup, *pGroup0, *pGroup1, *pGroup2, *pGroup3, *pPendingGroup = NULL; GROUP *pGroup, *pGroup0, *pGroup1, *pGroup2, *pGroup3, *pPendingGroup = NULL;
SECTORINFO *pSector; SECTORINFO *pSector;
UINT8 ubSectorID; UINT8 ubSectorID;
UINT8 ubSourceSectorID; UINT8 ubSourceSectorID;
UINT8 ubTargetSectorID; UINT8 ubTargetSectorID;
UINT8 ubNumSoldiers; unsigned ubNumSoldiers;
switch( usActionCode ) switch( usActionCode )
{ {
@@ -4318,7 +4324,151 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
{ {
MoveSAIGroupToSector( &pGroup, ubSectorID, EVASIVE, PURSUIT ); MoveSAIGroupToSector( &pGroup, ubSectorID, EVASIVE, PURSUIT );
} }
break;
// WDS - New AI
case NPC_ACTION_SEND_WEIGHTED_ASSAULT_TO_LOCATION: // USES OPTIONAL PARAMETERS
if (gGameExternalOptions.useNewAI) {
// Send troops to assault the specified location.
// ** 1st optional parm is a "direness" rating from the queens point of view
// that ranges from 0 to 100. It it used to determine the number of troops and
// their composition
// ** If 2nd optional parm is specified that is used as the groups "intention"
unsigned direness = (unsigned) option1;
Assert(direness >= 0 && direness <= 100);
unsigned intention = (unsigned) option2;
Assert(intention < NUM_ENEMY_INTENTIONS);
ubNumSoldiers = ( gubMinEnemyGroupSize +
gGameOptions.ubDifficultyLevel * 3 +
Random(HighestPlayerProgressPercentage() / 5) +
Random(option1 / 5)
);
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
giReinforcementPool = max( giReinforcementPool, 0 );
ubSourceSectorID = SEC_H13;
ubTargetSectorID = (UINT8)SECTOR( sSectorX, sSectorY );
if ( !(SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
{
ubSourceSectorID = SEC_P3;
}
int groupCnt = 0;
while (ubNumSoldiers != 0) {
++groupCnt;
unsigned soldiersThisSquad = ubNumSoldiers;
if (soldiersThisSquad > (unsigned)gGameExternalOptions.iMaxEnemyGroupSize) {
soldiersThisSquad = (unsigned)gGameExternalOptions.iMaxEnemyGroupSize;
}
ubNumSoldiers -= soldiersThisSquad;
unsigned adminsThisSquad = 0;
unsigned troopsThisSquad = 0;
unsigned elitesThisSquad = 0;
if (direness < 25) {
adminsThisSquad = soldiersThisSquad * (40 + Random(20)) / 100; // 40-60% of total
troopsThisSquad = soldiersThisSquad - adminsThisSquad; // The rest
} else if (direness < 50) {
adminsThisSquad = soldiersThisSquad * (20 + Random(10)) / 100; // 20-30% of total
troopsThisSquad = soldiersThisSquad * (30 + Random(20)) / 100; // 30-50% of total
elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
} else if (direness < 75) {
adminsThisSquad = soldiersThisSquad * (10 + Random(10)) / 100; // 10-20% of total
troopsThisSquad = soldiersThisSquad * (20 + Random(20)) / 100; // 20-40% of total
elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
} else /* direness >=75 */ {
adminsThisSquad = 0; // 0% of total
troopsThisSquad = soldiersThisSquad * (30 + Random(20)) / 100; // 30-50% of total
elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
}
Assert(adminsThisSquad + troopsThisSquad + elitesThisSquad == soldiersThisSquad);
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID ) {
pGroup0->pEnemyGroup->ubIntention = STAGE;
if (groupCnt > 2) {
pGroup0->pEnemyGroup->ubIntention = REINFORCEMENTS;
gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID = pGroup0->ubGroupID;
}
} else {
pGroup0->pEnemyGroup->ubIntention = PURSUIT;
}
MoveSAIGroupToSector( &pGroup0, ubTargetSectorID, EVASIVE, pGroup0->pEnemyGroup->ubIntention );
} // while
} // if (gGameExternalOptions.useNewAI)
break;
// WDS - New AI
case NPC_ACTION_SEND_SPECIFIC_ASSAULT_TO_LOCATION: // USES OPTIONAL PARAMETERS
if (gGameExternalOptions.useNewAI) {
// Send specific troops to assauat the specified location.
// Note: 1st optional parm is a count of troops to send
// 2nd optional parm is the composition of troops
if (option1 > 0 && option1 < 256) {
ubNumSoldiers = (UINT8)(option1);
} else {
// Something is goofy, just send a default sized squad
ubNumSoldiers = gubMinEnemyGroupSize;
}
unsigned adminsPercentage = 0;
unsigned troopsPercentage = 0;
unsigned elitesPercentage = 0;
// option2: value is eettaa
if (option2 > 0 && option2 < 99+99*100+99*100*100) {
adminsPercentage = option2 % 100;
troopsPercentage = (option2 / 100) % 100;
elitesPercentage = (option2 / 10000) % 100;
} else {
// Something is goofy, just use a default composition
adminsPercentage = 25;
troopsPercentage = 50;
elitesPercentage = 25;
}
Assert(adminsPercentage + troopsPercentage + elitesPercentage == 100);
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
giReinforcementPool = max( giReinforcementPool, 0 );
ubSourceSectorID = SEC_H13;
ubTargetSectorID = (UINT8)SECTOR( sSectorX, sSectorY );
if ( !(SectorInfo[ ubSourceSectorID ].ubNumTroops > 0) )
{
ubSourceSectorID = SEC_P3;
}
int groupCnt = 0;
while (ubNumSoldiers != 0) {
++groupCnt;
unsigned soldiersThisSquad = ubNumSoldiers;
if (soldiersThisSquad > (unsigned)gGameExternalOptions.iMaxEnemyGroupSize) {
soldiersThisSquad = (unsigned)gGameExternalOptions.iMaxEnemyGroupSize;
}
ubNumSoldiers -= soldiersThisSquad;
unsigned adminsThisSquad = soldiersThisSquad * adminsPercentage / 100;
unsigned troopsThisSquad = soldiersThisSquad * troopsPercentage / 100;
unsigned elitesThisSquad = soldiersThisSquad - troopsThisSquad - adminsThisSquad; // The rest
Assert(adminsThisSquad + troopsThisSquad + elitesThisSquad == soldiersThisSquad);
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, adminsThisSquad, soldiersThisSquad, elitesThisSquad );
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID ) {
pGroup0->pEnemyGroup->ubIntention = STAGE;
if (groupCnt > 2) {
pGroup0->pEnemyGroup->ubIntention = REINFORCEMENTS;
gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID = pGroup0->ubGroupID;
}
} else {
pGroup0->pEnemyGroup->ubIntention = PURSUIT;
}
MoveSAIGroupToSector( &pGroup0, ubTargetSectorID, EVASIVE, pGroup0->pEnemyGroup->ubIntention );
} // while
} // if (gGameExternalOptions.useNewAI)
break; break;
case NPC_ACTION_SEND_SOLDIERS_TO_OMERTA: case NPC_ACTION_SEND_SOLDIERS_TO_OMERTA:
@@ -4403,6 +4553,14 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
} }
} }
// WDS - New AI
void HourlyCheckStrategicAI()
{
// Nothing (yet!)
}
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
void LogStrategicMsg( STR8 str, ... ) void LogStrategicMsg( STR8 str, ... )
@@ -5233,7 +5391,8 @@ void UpgradeAdminsToTroops()
for( i = 0; i < giGarrisonArraySize; i++ ) for( i = 0; i < giGarrisonArraySize; i++ )
{ {
// skip sector if it's currently loaded, we'll never upgrade guys in those // skip sector if it's currently loaded, we'll never upgrade guys in those
if ( SECTOR( gWorldSectorX, gWorldSectorY ) == gGarrisonGroup[ i ].ubSectorID ) if ( (gWorldSectorX != 0) && (gWorldSectorY != 0) &&
(SECTOR( gWorldSectorX, gWorldSectorY ) == gGarrisonGroup[ i ].ubSectorID) )
{ {
continue; continue;
} }
+11 -2
View File
@@ -19,8 +19,14 @@ enum
}; };
// WDS - New AI
void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSectorY ); void ExecuteStrategicAIAction(
UINT16 usActionCode, // See list in "interface Dialogue.h"
INT16 sSectorX, // Target X location of strategic action
INT16 sSectorY, // Target Y location of strategic action
INT32 option1 = 0, // Option 1, vaies with action
INT32 option2 = 0 // Option 2, vaies with action
);
void CheckEnemyControlledSector( UINT8 ubSectorID ); void CheckEnemyControlledSector( UINT8 ubSectorID );
void EvaluateQueenSituation(); void EvaluateQueenSituation();
@@ -40,6 +46,9 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
void InvestigateSector( UINT8 ubSectorID ); void InvestigateSector( UINT8 ubSectorID );
// WDS - New AI
void HourlyCheckStrategicAI();
void WakeUpQueen(); void WakeUpQueen();
void StrategicHandleMineThatRanOut( UINT8 ubSectorID ); void StrategicHandleMineThatRanOut( UINT8 ubSectorID );
+2 -1
View File
@@ -160,7 +160,8 @@ smctableEndElementHandle(void *userData, const XML_Char *name)
// We've read in a complete section. Process the contents of pData into the // We've read in a complete section. Process the contents of pData into the
// SectionInfo array // SectionInfo array
SECTORINFO *pSector; SECTORINFO *pSector;
pSector = &SectorInfo[ ((pData->uiRowNumber - 1) * 16) + (pData->uiColNumber - 1) ]; int sectorID = ((pData->uiRowNumber - 1) * 16) + (pData->uiColNumber - 1);
pSector = &SectorInfo[ sectorID ];
pSector->ubTravelRating = pData->travRating; pSector->ubTravelRating = pData->travRating;
pSector->ubTraversability[ NORTH_STRATEGIC_MOVE ] = pData->travNorth; pSector->ubTraversability[ NORTH_STRATEGIC_MOVE ] = pData->travNorth;
pSector->ubTraversability[ EAST_STRATEGIC_MOVE ] = pData->travEast; pSector->ubTraversability[ EAST_STRATEGIC_MOVE ] = pData->travEast;
+79 -57
View File
@@ -50,6 +50,8 @@
#endif #endif
#include "MilitiaSquads.h" #include "MilitiaSquads.h"
#include "Vehicles.h"
#include "connect.h" #include "connect.h"
//forward declarations of common classes to eliminate includes //forward declarations of common classes to eliminate includes
class OBJECTTYPE; class OBJECTTYPE;
@@ -76,7 +78,6 @@ extern BOOLEAN gfUsePersistantPBI;
extern BOOLEAN gubNumAwareBattles; extern BOOLEAN gubNumAwareBattles;
extern INT8 SquadMovementGroups[ ]; extern INT8 SquadMovementGroups[ ];
extern INT8 gubVehicleMovementGroups[ ];
BOOLEAN gfDelayAutoResolveStart = FALSE; BOOLEAN gfDelayAutoResolveStart = FALSE;
@@ -740,6 +741,8 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
L"with a save close to this event, that would really help me! -- KM:0" ); L"with a save close to this event, that would really help me! -- KM:0" );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
} }
/*
* Not valid
else if( pNew->ubGroupSize > 25 ) else if( pNew->ubGroupSize > 25 )
{ {
swprintf( str, L"Strategic AI warning: Creating an enemy group containing %d soldiers " swprintf( str, L"Strategic AI warning: Creating an enemy group containing %d soldiers "
@@ -749,6 +752,7 @@ GROUP* CreateNewEnemyGroupDepartingFromSector( UINT32 uiSector, UINT8 ubNumAdmin
pNew->ubSectorY + 'A' - 1, pNew->ubSectorX ); pNew->ubSectorY + 'A' - 1, pNew->ubSectorX );
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL ); DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
} }
*/
} }
#endif #endif
@@ -767,10 +771,22 @@ UINT8 AddGroupToList( GROUP *pGroup )
{ {
GROUP *curr; GROUP *curr;
UINT32 bit, index, mask; UINT32 bit, index, mask;
UINT8 ID = 0; unsigned ID = 0;
AssertNotNIL (pGroup);
AssertGE (pGroup->ubSectorX, MINIMUM_VALID_X_COORDINATE);
AssertLE (pGroup->ubSectorX, MAXIMUM_VALID_X_COORDINATE);
AssertGE (pGroup->ubSectorY, MINIMUM_VALID_Y_COORDINATE);
AssertLE (pGroup->ubSectorY, MAXIMUM_VALID_Y_COORDINATE);
AssertGE (pGroup->ubSectorZ, MINIMUM_VALID_Z_COORDINATE);
AssertLE (pGroup->ubSectorZ, MAXIMUM_VALID_Z_COORDINATE);
//AssertGT (pGroup->ubGroupSize, 0);
//First, find a unique ID //First, find a unique ID
while( ++ID ) while( ++ID )
{ {
AssertLT (ID, 256);
index = ID / 32; index = ID / 32;
bit = ID % 32; bit = ID % 32;
mask = 1 << bit; mask = 1 << bit;
@@ -898,15 +914,18 @@ void PrepareForPreBattleInterface( GROUP *pPlayerDialogGroup, GROUP *pInitiating
// ATE; Changed alogrithm here... // ATE; Changed alogrithm here...
// We first loop through the group and save ubID's ov valid guys to talk.... // We first loop through the group and save ubID's ov valid guys to talk....
// ( Can't if sleeping, unconscious, and EPC, etc.... // ( Can't if sleeping, unconscious, and EPC, etc....
UINT8 ubMercsInGroup[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
UINT8 ubNumMercs = 0; unsigned ubMercsInGroup[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
UINT8 ubChosenMerc; unsigned ubNumMercs = 0;
unsigned ubChosenMerc;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
PLAYERGROUP *pPlayer; PLAYERGROUP *pPlayer;
if( fDisableMapInterfaceDueToBattle ) if( fDisableMapInterfaceDueToBattle )
{ {
AssertMsg( 0, "fDisableMapInterfaceDueToBattle is set before attempting to bring up PBI. Please send PRIOR save if possible and details on anything that just happened before this battle." ); // WDS Note: This can validly happen when multiple teams retreat and then immediately return to a sector.
// Just returning causes no problems.
// AssertMsg( 0, "fDisableMapInterfaceDueToBattle is set before attempting to bring up PBI. Please send PRIOR save if possible and details on anything that just happened before this battle." );
return; return;
} }
@@ -1094,7 +1113,8 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
{ {
pPlayerDialogGroup = pGroup; pPlayerDialogGroup = pGroup;
if( NumEnemiesInSector( pGroup->ubSectorX, pGroup->ubSectorY ) ) if( NumEnemiesInSector( pGroup->ubSectorX, pGroup->ubSectorY ) &&
(!IsGroupTheHelicopterGroup( pGroup ) || (gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE)))
{ {
fBattlePending = TRUE; fBattlePending = TRUE;
StopTimeCompression(); StopTimeCompression();
@@ -1392,7 +1412,7 @@ BOOLEAN AttemptToMergeSeparatedGroups( GROUP *pGroup, BOOLEAN fDecrementTraversa
} }
pPlayer = pPlayer->next; pPlayer = pPlayer->next;
} }
while( pGroup->ubGroupSize && curr->ubGroupSize < 6 ) while( pGroup->ubGroupSize && curr->ubGroupSize < NUMBER_OF_SOLDIERS_PER_SQUAD )
{ //while there is room in the new group, move one soldier at a time automatically. { //while there is room in the new group, move one soldier at a time automatically.
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
counter++; counter++;
@@ -1425,7 +1445,7 @@ BOOLEAN AttemptToMergeSeparatedGroups( GROUP *pGroup, BOOLEAN fDecrementTraversa
curr = curr->next; curr = curr->next;
} }
} }
else if( pGroup->ubGroupSize < 6 ) else if( pGroup->ubGroupSize < NUMBER_OF_SOLDIERS_PER_SQUAD )
{ //Search for other groups looking to join our group. { //Search for other groups looking to join our group.
while( curr ) while( curr )
{ {
@@ -1449,7 +1469,7 @@ BOOLEAN AttemptToMergeSeparatedGroups( GROUP *pGroup, BOOLEAN fDecrementTraversa
} }
pPlayer = pPlayer->next; pPlayer = pPlayer->next;
} }
while( curr->ubGroupSize && pGroup->ubGroupSize < 6 ) while( curr->ubGroupSize && pGroup->ubGroupSize < NUMBER_OF_SOLDIERS_PER_SQUAD )
{ //while there is room in the new group, move one soldier at a time automatically. { //while there is room in the new group, move one soldier at a time automatically.
#ifdef JA2BETAVERSION #ifdef JA2BETAVERSION
counter++; counter++;
@@ -1969,15 +1989,18 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
// check if sector had been visited previously // check if sector had been visited previously
fFirstTimeInSector = !GetSectorFlagStatus( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ, SF_ALREADY_VISITED ); fFirstTimeInSector = !GetSectorFlagStatus( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ, SF_ALREADY_VISITED );
if (fFirstTimeInSector) {
AddExtraItems( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ );
}
// on foot, or in a vehicle other than the chopper // on foot, or in a vehicle other than the chopper
if ( !pGroup->fVehicle || !IsGroupTheHelicopterGroup( pGroup ) ) if ( !pGroup->fVehicle || !IsGroupTheHelicopterGroup( pGroup ) )
{ {
// ATE: Add a few corpse to the bloodcat lair...
// ATE: Add a few corpse to the bloodcat lair... if ( SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ) == SEC_I16 && fFirstTimeInSector )
if ( SECTOR( pGroup->ubSectorX, pGroup->ubSectorY ) == SEC_I16 && fFirstTimeInSector ) {
{ AddCorpsesToBloodcatLair( pGroup->ubSectorX, pGroup->ubSectorY );
AddCorpsesToBloodcatLair( pGroup->ubSectorX, pGroup->ubSectorY ); }
}
// mark the sector as visited already // mark the sector as visited already
SetSectorFlag( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ, SF_ALREADY_VISITED ); SetSectorFlag( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubSectorZ, SF_ALREADY_VISITED );
@@ -2005,7 +2028,8 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe
while( gubNumGroupsArrivedSimultaneously && pGroup ) while( gubNumGroupsArrivedSimultaneously && pGroup )
{ {
next = pGroup->next; next = pGroup->next;
if( pGroup->uiFlags & GROUPFLAG_GROUP_ARRIVED_SIMULTANEOUSLY ) // WDS - Fix bug with 0 size group arriving at 0,0,0
if( (pGroup->ubGroupSize > 0) && pGroup->uiFlags & GROUPFLAG_GROUP_ARRIVED_SIMULTANEOUSLY )
{ {
gubNumGroupsArrivedSimultaneously--; gubNumGroupsArrivedSimultaneously--;
HandleNonCombatGroupArrival( pGroup, FALSE, FALSE ); HandleNonCombatGroupArrival( pGroup, FALSE, FALSE );
@@ -2375,9 +2399,11 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup )
dx = wp->x - pGroup->ubSectorX; dx = wp->x - pGroup->ubSectorX;
dy = wp->y - pGroup->ubSectorY; dy = wp->y - pGroup->ubSectorY;
if( dx && dy ) if( dx && dy )
{ //Can't move diagonally! { //Shouldn't move diagonally!
AssertMsg( 0, String("Attempting to move to waypoint in a diagonal direction from sector %d,%d to sector %d,%d", DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("Attempting to move to waypoint in a diagonal direction from sector %d,%d to sector %d,%d",
pGroup->ubSectorX, pGroup->ubSectorY, wp->x, wp->y ) ); pGroup->ubSectorX, pGroup->ubSectorY, wp->x, wp->y ));
//AssertMsg( 0, String("Attempting to move to waypoint in a diagonal direction from sector %d,%d to sector %d,%d",
// pGroup->ubSectorX, pGroup->ubSectorY, wp->x, wp->y ) );
} }
if( !dx && !dy ) //Can't move to position currently at! if( !dx && !dy ) //Can't move to position currently at!
AssertMsg( 0, String("Attempting to move to waypoint %d, %d that you are already at!", wp->x, wp->y ) ); AssertMsg( 0, String("Attempting to move to waypoint %d, %d that you are already at!", wp->x, wp->y ) );
@@ -3317,48 +3343,44 @@ BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnt
fMayRetreatFromBattle = FALSE; fMayRetreatFromBattle = FALSE;
fRetreatingFromBattle = FALSE; fRetreatingFromBattle = FALSE;
if( ( sBattleSector == sSource ) && ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sSource ) && ( SECTOR( curr->ubPrevX, curr->ubPrevY ) == sDest ) ) if ((curr->ubSectorX != 0) && (curr->ubSectorY != 0) &&
{ (curr->ubNextX != 0) && (curr->ubNextY != 0)) {
fMayRetreatFromBattle = TRUE; if( ( sBattleSector == sSource ) && ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sSource ) && ( SECTOR( curr->ubPrevX, curr->ubPrevY ) == sDest ) ) {
} fMayRetreatFromBattle = TRUE;
}
if( ( sBattleSector == sDest ) && ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sDest ) && ( SECTOR( curr->ubPrevX, curr->ubPrevY ) == sSource ) ) if( ( sBattleSector == sDest ) && ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sDest ) && ( SECTOR( curr->ubPrevX, curr->ubPrevY ) == sSource ) ) {
{ fRetreatingFromBattle = TRUE;
fRetreatingFromBattle = TRUE;
}
ubMercsInGroup = curr->ubGroupSize;
if( ( ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sSource ) && ( SECTOR( curr->ubNextX, curr->ubNextY ) == sDest) ) || ( fMayRetreatFromBattle == TRUE ) )
{
// if it's a valid vehicle, but not the helicopter (which can fly empty)
if ( curr->fVehicle && !fHelicopterGroup && ( GivenMvtGroupIdFindVehicleId( curr->ubGroupID ) != -1 ) )
{
// make sure empty vehicles (besides helicopter) aren't in motion!
Assert( ubMercsInGroup > 0 );
// subtract 1, we don't wanna count the vehicle itself for purposes of showing a number on the map
ubMercsInGroup--;
} }
*iCountEnter += ubMercsInGroup; ubMercsInGroup = curr->ubGroupSize;
if( ( curr->uiArrivalTime - GetWorldTotalMin( ) <= ABOUT_TO_ARRIVE_DELAY ) || ( fMayRetreatFromBattle == TRUE ) ) if (((SECTOR(curr->ubSectorX, curr->ubSectorY) == sSource) &&
{ (SECTOR(curr->ubNextX, curr->ubNextY) == sDest)) ||
*fAboutToArriveEnter = TRUE; (fMayRetreatFromBattle)) {
// if it's a valid vehicle, but not the helicopter (which can fly empty)
if ( curr->fVehicle && !fHelicopterGroup && ( GivenMvtGroupIdFindVehicleId( curr->ubGroupID ) != -1 ) ) {
// make sure empty vehicles (besides helicopter) aren't in motion!
Assert( ubMercsInGroup > 0 );
// subtract 1, we don't wanna count the vehicle itself for purposes of showing a number on the map
ubMercsInGroup--;
}
*iCountEnter += ubMercsInGroup;
if( ( curr->uiArrivalTime - GetWorldTotalMin( ) <= ABOUT_TO_ARRIVE_DELAY ) || ( fMayRetreatFromBattle ) ) {
*fAboutToArriveEnter = TRUE;
}
} }
} else if ((SECTOR( curr->ubSectorX, curr->ubSectorY ) == sDest) &&
else if( ( SECTOR( curr->ubSectorX, curr->ubSectorY ) == sDest )&&( SECTOR( curr->ubNextX, curr->ubNextY ) == sSource) || ( fRetreatingFromBattle == TRUE ) ) (SECTOR( curr->ubNextX, curr->ubNextY ) == sSource) ||
{ (fRetreatingFromBattle)) {
// if it's a valid vehicle, but not the helicopter (which can fly empty) // if it's a valid vehicle, but not the helicopter (which can fly empty)
if ( curr->fVehicle && !fHelicopterGroup && ( GivenMvtGroupIdFindVehicleId( curr->ubGroupID ) != -1 ) ) if ( curr->fVehicle && !fHelicopterGroup && ( GivenMvtGroupIdFindVehicleId( curr->ubGroupID ) != -1 ) ) {
{ // make sure empty vehicles (besides helicopter) aren't in motion!
// make sure empty vehicles (besides helicopter) aren't in motion! Assert( ubMercsInGroup > 0 );
Assert( ubMercsInGroup > 0 ); // subtract 1, we don't wanna count the vehicle itself for purposes of showing a number on the map
// subtract 1, we don't wanna count the vehicle itself for purposes of showing a number on the map ubMercsInGroup--;
ubMercsInGroup--; }
*iCountExit += ubMercsInGroup;
} }
*iCountExit += ubMercsInGroup;
} }
} }
} }
+3 -1
View File
@@ -68,7 +68,9 @@ typedef struct ENEMYGROUP
UINT8 ubIntention; //the type of group this is: patrol, assault, spies, etc. UINT8 ubIntention; //the type of group this is: patrol, assault, spies, etc.
UINT8 ubTroopsInBattle; //number of soldiers currently in battle. UINT8 ubTroopsInBattle; //number of soldiers currently in battle.
UINT8 ubElitesInBattle; //number of elite soldiers currently in battle. UINT8 ubElitesInBattle; //number of elite soldiers currently in battle.
INT8 bPadding[20]; // WDS - New AI
UINT8 numTanks;
INT8 bPadding[19];
}ENEMYGROUP; }ENEMYGROUP;
//NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE //NOTE: ALL FLAGS ARE CLEARED WHENEVER A GROUP ARRIVES IN A SECTOR, OR ITS WAYPOINTS ARE
+2 -1
View File
@@ -284,7 +284,8 @@ void IncrementTownLoyalty( INT8 bTownId, UINT32 uiLoyaltyIncrease )
INT16 sThisIncrement; INT16 sThisIncrement;
Assert( ( bTownId >= FIRST_TOWN ) && ( bTownId < NUM_TOWNS ) ); AssertGE (bTownId, BLANK_SECTOR);
AssertLT (bTownId, NUM_TOWNS);
// doesn't affect towns where player hasn't established a "presence" yet // doesn't affect towns where player hasn't established a "presence" yet
if (!gTownLoyalty[ bTownId ].fStarted) if (!gTownLoyalty[ bTownId ].fStarted)
+12 -10
View File
@@ -51,10 +51,10 @@ INT32 giListOfMercsInSectorsCompletedMilitiaTraining[ SIZE_OF_MILITIA_COMPLETED_
SOLDIERTYPE *pMilitiaTrainerSoldier = NULL; SOLDIERTYPE *pMilitiaTrainerSoldier = NULL;
// note that these sector values are STRATEGIC INDEXES, not 0-255! // note that these sector values are STRATEGIC INDEXES, not 0-255!
INT16 gsUnpaidStrategicSector[ MAX_CHARACTER_COUNT ]; INT16 gsUnpaidStrategicSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// the selected list of mercs // the selected list of mercs
extern BOOLEAN fSelectedListOfMercsForMapScreen[ MAX_CHARACTER_COUNT ]; extern BOOLEAN fSelectedListOfMercsForMapScreen[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// towns with militia training allowed // towns with militia training allowed
BOOLEAN gfMilitiaAllowedInTown[MAX_TOWNS] = BOOLEAN gfMilitiaAllowedInTown[MAX_TOWNS] =
@@ -532,7 +532,8 @@ UINT8 CountAllMilitiaInSector(INT16 sMapX, INT16 sMapY)
UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank) UINT8 MilitiaInSectorOfRank(INT16 sMapX, INT16 sMapY, UINT8 ubRank)
{ {
return( SectorInfo[ SECTOR( sMapX, sMapY ) ].ubNumberOfCivsAtLevel[ ubRank ] ); unsigned count = SectorInfo[ SECTOR( sMapX, sMapY ) ].ubNumberOfCivsAtLevel[ ubRank ];
return count;
} }
@@ -1162,7 +1163,7 @@ void HandleCompletionOfTownTrainingByGroupWithTrainer( SOLDIERTYPE *pTrainer )
sSectorY = pTrainer->sSectorY; sSectorY = pTrainer->sSectorY;
bSectorZ = pTrainer->bSectorZ; bSectorZ = pTrainer->bSectorZ;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// valid character? // valid character?
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
@@ -1292,11 +1293,12 @@ void BuildListOfUnpaidTrainableSectors( void )
INT32 iCounter = 0, iCounterB = 0; INT32 iCounter = 0, iCounterB = 0;
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
memset( gsUnpaidStrategicSector, 0, sizeof( INT16 ) * MAX_CHARACTER_COUNT ); // WDS - make number of mercenaries, etc. be configurable
memset( gsUnpaidStrategicSector, 0, sizeof(gsUnpaidStrategicSector) );
if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN )
{ {
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// valid character? // valid character?
if( gCharactersList[ iCounter ].fValid ) if( gCharactersList[ iCounter ].fValid )
@@ -1335,11 +1337,11 @@ void BuildListOfUnpaidTrainableSectors( void )
} }
// now clean out repeated sectors // now clean out repeated sectors
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT - 1; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1; iCounter++ )
{ {
if( gsUnpaidStrategicSector[ iCounter ] > 0 ) if( gsUnpaidStrategicSector[ iCounter ] > 0 )
{ {
for( iCounterB = iCounter + 1 ; iCounterB < MAX_CHARACTER_COUNT; iCounterB++ ) for( iCounterB = iCounter + 1 ; iCounterB < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounterB++ )
{ {
if( gsUnpaidStrategicSector[ iCounterB ] == gsUnpaidStrategicSector[ iCounter ] ) if( gsUnpaidStrategicSector[ iCounterB ] == gsUnpaidStrategicSector[ iCounter ] )
{ {
@@ -1360,7 +1362,7 @@ INT32 GetNumberOfUnpaidTrainableSectors( void )
BuildListOfUnpaidTrainableSectors(); BuildListOfUnpaidTrainableSectors();
// now count up the results // now count up the results
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gsUnpaidStrategicSector[ iCounter ] > 0 ) if( gsUnpaidStrategicSector[ iCounter ] > 0 )
{ {
@@ -1385,7 +1387,7 @@ void StartTrainingInAllUnpaidTrainableSectors()
BuildListOfUnpaidTrainableSectors(); BuildListOfUnpaidTrainableSectors();
// pay up in each sector // pay up in each sector
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gsUnpaidStrategicSector[ iCounter ] > 0 ) if( gsUnpaidStrategicSector[ iCounter ] > 0 )
{ {
+246
View File
@@ -0,0 +1,246 @@
#include "builddefines.h"
#include <stdio.h>
#include "XML.h"
#include "expat.h"
#include "DEBUG.h"
#include "string.h"
#include "Tactical Save.h"
#include "FileMan.h"
#include "MemMan.h"
#include "Debug Control.h"
#include "GameSettings.h"
typedef enum
{
EXTRAITEMS_ELEMENT_NONE = 0,
EXTRAITEMS_ELEMENT_EXTRAITEMS,
EXTRAITEMS_ELEMENT_ITEM
} EXTRAITEMS_PARSE_STAGE;
typedef struct
{
EXTRAITEMS_PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
UINT32 currentDepth;
UINT32 maxReadDepth;
UINT32 item;
UINT32 quantity;
UINT32 condition;
UINT32 gridno;
} ExtraItemsParseData;
static bool gSectorIsLoaded = false;
static UINT8 gX = 0;
static UINT8 gY = 0;
static UINT8 gZ = 0;
/** Process the opening tag in this expat callback.
*/
static void XMLCALL
ExtraItemsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
ExtraItemsParseData * pData = (ExtraItemsParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "ExtraItems") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_NONE)
{
pData->curElement = EXTRAITEMS_ELEMENT_EXTRAITEMS;
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "Item") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_EXTRAITEMS)
{
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
pData->maxReadDepth++; //we are not skipping this element
// Extract the attributes
// defaults
pData->quantity = 1;
pData->condition = 100;
pData->gridno = 0;
for(unsigned uiAttrIndex = 0;atts[uiAttrIndex] != NULL;uiAttrIndex += 2)
{
if(strcmp(atts[uiAttrIndex], "quantity") == 0)
{
pData->quantity = atol(atts[uiAttrIndex+1]);
if (pData->quantity < 1 || pData->quantity > 100) {
pData->quantity = 1;
}
}
else if(strcmp(atts[uiAttrIndex], "condition") == 0)
{
pData->condition = atol(atts[uiAttrIndex+1]);
if (pData->condition < 1 || pData->condition > 100) {
pData->condition = 100;
}
}
else if(strcmp(atts[uiAttrIndex], "gridno") == 0)
{
pData->gridno = atol(atts[uiAttrIndex+1]);
//if (pData->gridno < ???? || pData->gridno > ????) {
// pData->gridno = 0;
//}
}
}
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
/** Process any text content in this callback.
*/
static void XMLCALL
ExtraItemsCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
ExtraItemsParseData * pData = (ExtraItemsParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth && strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
/** Process the closing tag in this expat callback.
*/
static void XMLCALL
ExtraItemsEndElementHandle(void *userData, const XML_Char *name)
{
ExtraItemsParseData * pData = (ExtraItemsParseData *) userData;
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "ExtraItems") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_EXTRAITEMS)
{
pData->curElement = EXTRAITEMS_ELEMENT_NONE;
}
else if(strcmp(name, "Item") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_ITEM)
{
pData->item = atol(pData->szCharData);
OBJECTTYPE object;
CreateItem(pData->item, pData->condition, &object);
for (unsigned cnt=1; cnt <= pData->quantity; ++cnt) {
if (gSectorIsLoaded) {
AddItemToPool( pData->gridno, &object, 1, 0, WORLD_ITEM_REACHABLE, 0 );
} else {
AddItemsToUnLoadedSector( gX, gY, gZ, pData->gridno, 1, &object, 0, WORLD_ITEM_REACHABLE, 0, 1, 0 );
}
}
pData->curElement = EXTRAITEMS_ELEMENT_EXTRAITEMS;
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
void AddExtraItems(UINT8 x, UINT8 y, UINT8 z, bool sectorIsLoaded)
{
char fileName[MAX_PATH];
strcpy(fileName, TABLEDATA_DIRECTORY);
if (x < 10) {
strcat(fileName, EXTRAITEMSFILENAME);
char* spot = strstr(fileName, "A9_0");
Assert(spot);
if (!spot)
return;
*spot = 'A' + y-1;
*(spot+1) = '0' + x;
*(spot+3) = '0' + z;
} else {
strcat(fileName, EXTRAITEMSFILENAME2);
char* spot = strstr(fileName, "A11_0");
Assert(spot);
if (!spot)
return;
*spot = 'A' + y-1;
*(spot+1) = '0' + x / 10;
*(spot+2) = '0' + x % 10;
*(spot+4) = '0' + z;
}
// Remember the base file name length
int baseFNLength = strlen(fileName);
// Append a suffix based on the difficulty
switch (gGameOptions.ubDifficultyLevel) {
case DIF_LEVEL_ZERO:
break;
case DIF_LEVEL_EASY:
strcat(fileName, "_Novice");
break;
case DIF_LEVEL_MEDIUM:
strcat(fileName, "_Experienced");
break;
case DIF_LEVEL_HARD:
strcat(fileName, "_Expert");
break;
case DIF_LEVEL_INSANE:
strcat(fileName, "_Insane");
break;
case DIF_LEVEL_FIVE:
break;
default:
break;
}
// Open extra items file
HWFILE hFile;
// Try "special" difficulty level file first
if (!(hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ))) {
// OK, that didn't work so try the "plain" file
fileName[baseFNLength] = '\0';
if (!(hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ))) {
// There isn't a file for this sector, just return
return;
}
}
gSectorIsLoaded = sectorIsLoaded;
gX = x;
gY = y;
gZ = z;
UINT32 uiBytesRead;
XML_Parser parser = XML_ParserCreate(NULL);
ExtraItemsParseData pData;
UINT32 uiFSize = FileGetSize(hFile);
CHAR8 * lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) {
MemFree(lpcBuffer);
XML_ParserFree(parser);
return;
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
// Setup expat callbacks
XML_SetElementHandler(parser, ExtraItemsStartElementHandle, ExtraItemsEndElementHandle);
XML_SetCharacterDataHandler(parser, ExtraItemsCharacterDataHandle);
memset(&pData,0,sizeof(pData));
XML_SetUserData(parser, &pData);
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in ExtraItems.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
XML_ParserFree(parser);
return;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return;
}
+99 -72
View File
@@ -643,18 +643,18 @@ MOUSE_REGION gMapScreenMaskRegion;
MOUSE_REGION gTrashCanRegion; MOUSE_REGION gTrashCanRegion;
// mouse regions for team info panel // mouse regions for team info panel
MOUSE_REGION gTeamListNameRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListNameRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
MOUSE_REGION gTeamListAssignmentRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListAssignmentRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
MOUSE_REGION gTeamListSleepRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListSleepRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
MOUSE_REGION gTeamListLocationRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListLocationRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
MOUSE_REGION gTeamListDestinationRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListDestinationRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
MOUSE_REGION gTeamListContractRegion[ MAX_CHARACTER_COUNT ]; MOUSE_REGION gTeamListContractRegion[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
OBJECTTYPE gItemPointer; OBJECTTYPE gItemPointer;
SOLDIERTYPE *gpItemPointerSoldier; SOLDIERTYPE *gpItemPointerSoldier;
PathStPtr gpCharacterPreviousMercPath[ MAX_CHARACTER_COUNT ]; PathStPtr gpCharacterPreviousMercPath[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
PathStPtr gpHelicopterPreviousMercPath = NULL; PathStPtr gpHelicopterPreviousMercPath = NULL;
@@ -673,7 +673,7 @@ extern BOOLEAN gfUsePersistantPBI;
extern BOOLEAN gfOneFramePauseOnExit; extern BOOLEAN gfOneFramePauseOnExit;
// the selected list of mercs // the selected list of mercs
extern BOOLEAN fSelectedListOfMercsForMapScreen[ MAX_CHARACTER_COUNT ]; extern BOOLEAN fSelectedListOfMercsForMapScreen[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
extern INT32 iDialogueBox; extern INT32 iDialogueBox;
extern INT32 giMapInvDescButton; extern INT32 giMapInvDescButton;
@@ -1764,7 +1764,7 @@ BOOLEAN SetInfoChar( UINT8 ubID )
{ {
INT8 bCounter; INT8 bCounter;
for ( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++) for ( bCounter = 0; bCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCounter++)
{ {
// skip invalid characters // skip invalid characters
if ( gCharactersList[ bCounter ].fValid == TRUE ) if ( gCharactersList[ bCounter ].fValid == TRUE )
@@ -3034,7 +3034,7 @@ BOOLEAN CharacterIsInTransitAndHasItemPickedUp( INT8 bCharacterNumber )
void DisplayCharacterInfo( void ) void DisplayCharacterInfo( void )
{ {
Assert( bSelectedInfoChar < MAX_CHARACTER_COUNT ); Assert( bSelectedInfoChar < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS );
Assert( gCharactersList[ bSelectedInfoChar ].fValid ); Assert( gCharactersList[ bSelectedInfoChar ].fValid );
// set font buffer // set font buffer
@@ -3098,6 +3098,7 @@ INT32 GetPathTravelTimeDuringPlotting( PathStPtr pPath )
// get vehicle id // get vehicle id
ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].iVehicleId ].ubMovementGroup; ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].iVehicleId ].ubMovementGroup;
pGroup = GetGroup( ubGroupId ); pGroup = GetGroup( ubGroupId );
AssertNotNIL(pGroup);
} }
} }
else if( Menptr[gCharactersList[bSelectedDestChar].usSolID].flags.uiStatusFlags & SOLDIER_VEHICLE ) else if( Menptr[gCharactersList[bSelectedDestChar].usSolID].flags.uiStatusFlags & SOLDIER_VEHICLE )
@@ -3112,23 +3113,23 @@ INT32 GetPathTravelTimeDuringPlotting( PathStPtr pPath )
// get vehicle id // get vehicle id
ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].bVehicleID ].ubMovementGroup; ubGroupId = pVehicleList[ Menptr[gCharactersList[bSelectedDestChar].usSolID].bVehicleID ].ubMovementGroup;
pGroup = GetGroup( ubGroupId ); pGroup = GetGroup( ubGroupId );
AssertNotNIL(pGroup);
} }
} }
else else
{ {
ubGroupId = Menptr[gCharactersList[bSelectedDestChar].usSolID].ubGroupID; ubGroupId = Menptr[gCharactersList[bSelectedDestChar].usSolID].ubGroupID;
pGroup = GetGroup( ( UINT8 )( ubGroupId ) ); pGroup = GetGroup( ( UINT8 )( ubGroupId ) );
AssertNotNIL(pGroup);
} }
} }
else else
{ {
ubGroupId = pVehicleList[ iHelicopterVehicleId ].ubMovementGroup; ubGroupId = pVehicleList[ iHelicopterVehicleId ].ubMovementGroup;
pGroup = GetGroup( ubGroupId ); pGroup = GetGroup( ubGroupId );
AssertNotNIL(pGroup);
} }
Assert(pGroup);
// if between sectors // if between sectors
if ( pGroup->fBetweenSectors ) if ( pGroup->fBetweenSectors )
{ {
@@ -3225,7 +3226,7 @@ void HighLightAssignLine()
UINT16 usColor; UINT16 usColor;
static INT32 iColorNum = STARTING_COLOR_NUM; static INT32 iColorNum = STARTING_COLOR_NUM;
static BOOLEAN fDelta=FALSE; static BOOLEAN fDelta=FALSE;
static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; static INT32 uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
INT16 usCount = 0; INT16 usCount = 0;
UINT16 usX; UINT16 usX;
UINT16 usY; UINT16 usY;
@@ -3235,7 +3236,7 @@ void HighLightAssignLine()
// is this a valid line? // is this a valid line?
if( ( giAssignHighLine == -1 ) || fShowInventoryFlag ) if( ( giAssignHighLine == -1 ) || fShowInventoryFlag )
{ {
uiOldHighlight = MAX_CHARACTER_COUNT + 1; uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
return; return;
} }
@@ -3266,7 +3267,7 @@ void HighLightAssignLine()
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) for( usCount = 0; usCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; usCount++ )
{ {
if( IsCharacterSelectedForAssignment( usCount ) == TRUE ) if( IsCharacterSelectedForAssignment( usCount ) == TRUE )
{ {
@@ -3289,7 +3290,7 @@ void HighLightAssignLine()
LineDraw( TRUE, usX, usY, usX+ASSIGN_WIDTH, usY, usColor,pDestBuf); LineDraw( TRUE, usX, usY, usX+ASSIGN_WIDTH, usY, usColor,pDestBuf);
} }
if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( IsCharacterSelectedForAssignment( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) if( ( ( usCount == CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ) || ( usCount != ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ? !( IsCharacterSelectedForAssignment( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) )
{ {
LineDraw(TRUE, usX, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+ASSIGN_WIDTH, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+ASSIGN_WIDTH, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf);
} }
@@ -3309,7 +3310,7 @@ void HighLightDestLine()
UINT16 usColor; UINT16 usColor;
static INT32 iColorNum = STARTING_COLOR_NUM; static INT32 iColorNum = STARTING_COLOR_NUM;
static BOOLEAN fDelta=FALSE; static BOOLEAN fDelta=FALSE;
static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; static INT32 uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
UINT16 usCount = 0; UINT16 usCount = 0;
UINT16 usX; UINT16 usX;
UINT16 usY; UINT16 usY;
@@ -3318,7 +3319,7 @@ void HighLightDestLine()
if( ( giDestHighLine == -1 ) || fShowInventoryFlag ) if( ( giDestHighLine == -1 ) || fShowInventoryFlag )
{ {
uiOldHighlight = MAX_CHARACTER_COUNT + 1; uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
return; return;
} }
@@ -3350,7 +3351,7 @@ void HighLightDestLine()
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) for( usCount = 0; usCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; usCount++ )
{ {
if( CharacterIsGettingPathPlotted( usCount ) == TRUE ) if( CharacterIsGettingPathPlotted( usCount ) == TRUE )
{ {
@@ -3369,7 +3370,7 @@ void HighLightDestLine()
{ {
LineDraw( TRUE, usX+4, usY, usX+DEST_ETA_WIDTH+4, usY, usColor,pDestBuf); LineDraw( TRUE, usX+4, usY, usX+DEST_ETA_WIDTH+4, usY, usColor,pDestBuf);
} }
if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( CharacterIsGettingPathPlotted( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) if( ( ( usCount == CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ) || ( usCount != ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ? !( CharacterIsGettingPathPlotted( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) )
{ {
LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+DEST_ETA_WIDTH+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX+DEST_ETA_WIDTH+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf);
} }
@@ -3395,7 +3396,7 @@ void HighLightSleepLine()
UINT16 usColor; UINT16 usColor;
static INT32 iColorNum = STARTING_COLOR_NUM; static INT32 iColorNum = STARTING_COLOR_NUM;
static BOOLEAN fDelta=FALSE; static BOOLEAN fDelta=FALSE;
static INT32 uiOldHighlight = MAX_CHARACTER_COUNT + 1; static INT32 uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
UINT16 usCount = 0; UINT16 usCount = 0;
UINT16 usX, usX2; UINT16 usX, usX2;
UINT16 usY; UINT16 usY;
@@ -3405,7 +3406,7 @@ void HighLightSleepLine()
// is this a valid line? // is this a valid line?
if( ( giSleepHighLine == -1 ) || fShowInventoryFlag ) if( ( giSleepHighLine == -1 ) || fShowInventoryFlag )
{ {
uiOldHighlight = MAX_CHARACTER_COUNT + 1; uiOldHighlight = CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS + 1;
return; return;
} }
@@ -3437,7 +3438,7 @@ void HighLightSleepLine()
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES ); pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
for( usCount = 0; usCount < MAX_CHARACTER_COUNT; usCount++ ) for( usCount = 0; usCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; usCount++ )
{ {
if( IsCharacterSelectedForSleep( usCount ) == TRUE ) if( IsCharacterSelectedForSleep( usCount ) == TRUE )
{ {
@@ -3458,7 +3459,7 @@ void HighLightSleepLine()
{ {
LineDraw( TRUE, usX+4, usY, usX2, usY, usColor,pDestBuf); LineDraw( TRUE, usX+4, usY, usX2, usY, usColor,pDestBuf);
} }
if( ( ( usCount == MAX_CHARACTER_COUNT - 1 ) ) || ( usCount != ( MAX_CHARACTER_COUNT - 1 ) ? !( IsCharacterSelectedForSleep( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) ) if( ( ( usCount == CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ) || ( usCount != ( CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS - 1 ) ? !( IsCharacterSelectedForSleep( ( UINT16 )( usCount + 1 ) ) ) : 0) || ( usCount == FIRST_VEHICLE - 1 ) )
{ {
LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX2, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf); LineDraw(TRUE, usX+4, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usX2, usY+GetFontHeight(MAP_SCREEN_FONT)+2, usColor, pDestBuf);
} }
@@ -3495,11 +3496,11 @@ void AddCharacter( SOLDIERTYPE *pCharacter )
// adding a vehicle? // adding a vehicle?
if( pCharacter->flags.uiStatusFlags & SOLDIER_VEHICLE ) if( pCharacter->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
while( usVehicleLoop < MAX_CHARACTER_COUNT ) while( usVehicleLoop < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS )
{ {
if ( gCharactersList[ usVehicleLoop ].fValid ) if ( gCharactersList[ usVehicleLoop ].fValid )
{ {
if ( Menptr[ usVehicleLoop ].flags.uiStatusFlags & SOLDIER_VEHICLE ) if ( Menptr[ gCharactersList[ usVehicleLoop ].usSolID ].flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
usVehicleCount++; usVehicleCount++;
} }
@@ -3512,15 +3513,15 @@ void AddCharacter( SOLDIERTYPE *pCharacter )
else else
{ {
// go through character list until a blank is reached // go through character list until a blank is reached
while( (gCharactersList[usCount].fValid)&&(usCount < MAX_CHARACTER_COUNT) ) while( (gCharactersList[usCount].fValid)&&(usCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS) )
{ {
usCount++; usCount++;
} }
} }
Assert( usCount < MAX_CHARACTER_COUNT ); Assert( usCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS );
if (usCount >= MAX_CHARACTER_COUNT ) if (usCount >= CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS )
{ {
return; return;
} }
@@ -3619,7 +3620,7 @@ void DisplayCharacterList()
SetFontBackground(FONT_BLACK); SetFontBackground(FONT_BLACK);
for (sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) for (sCount = 0; sCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; sCount++)
{ {
// skip invalid characters // skip invalid characters
if ( gCharactersList[sCount].fValid == TRUE ) if ( gCharactersList[sCount].fValid == TRUE )
@@ -4055,7 +4056,7 @@ UINT32 MapScreenHandle(void)
if( AnyMercsHired( ) == FALSE ) if( AnyMercsHired( ) == FALSE )
{ {
// select starting sector (A9 - Omerta) // select starting sector (A9 - Omerta)
ChangeSelectedMapSector( 9, 1, 0 ); ChangeSelectedMapSector( startingX, startingY, startingZ );
} }
else if( ( gWorldSectorX > 0 ) && ( gWorldSectorY > 0 ) && ( gbWorldSectorZ != -1 ) ) else if( ( gWorldSectorX > 0 ) && ( gWorldSectorY > 0 ) && ( gbWorldSectorZ != -1 ) )
{ {
@@ -4067,7 +4068,7 @@ UINT32 MapScreenHandle(void)
// only select A9 - Omerta IF there is no current selection, otherwise leave it as is // only select A9 - Omerta IF there is no current selection, otherwise leave it as is
if ( ( sSelMapX == 0 ) || ( sSelMapY == 0 ) || ( iCurrentMapSectorZ == -1 ) ) if ( ( sSelMapX == 0 ) || ( sSelMapY == 0 ) || ( iCurrentMapSectorZ == -1 ) )
{ {
ChangeSelectedMapSector( 9, 1, 0 ); ChangeSelectedMapSector( startingX, startingY, startingZ );
} }
} }
@@ -4589,7 +4590,7 @@ UINT32 MapScreenHandle(void)
// handle display of inventory pop up // handle display of inventory pop up
HandleDisplayOfItemPopUpForSector( 9, 1, 0 ); HandleDisplayOfItemPopUpForSector( startingX, startingY, startingZ );
// Display Framerate // Display Framerate
DisplayFrameRate( ); DisplayFrameRate( );
@@ -5726,11 +5727,11 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
{ {
StopMapScreenHelpText( ); StopMapScreenHelpText( );
} }
else if ( gpCurrentTalkingFace != NULL && gpCurrentTalkingFace->fTalking ) else if ( gpCurrentTalkingFace != NULL && gpCurrentTalkingFace->fTalking )
{ {
// ATE: We want to stop speech if somebody is talking... // ATE: We want to stop speech if somebody is talking...
StopAnyCurrentlyTalkingSpeech( ); StopAnyCurrentlyTalkingSpeech( );
} }
else if( fShowUpdateBox ) else if( fShowUpdateBox )
{ {
if( fShowUpdateBox ) if( fShowUpdateBox )
@@ -5903,7 +5904,7 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
break; break;
case BACKSPACE: case BACKSPACE:
StopAnyCurrentlyTalkingSpeech( ); StopAnyCurrentlyTalkingSpeech( );
break; break;
// multiplayer: Roman: Should be changed, because the keys are already bount to another feature // multiplayer: Roman: Should be changed, because the keys are already bount to another feature
@@ -8241,6 +8242,30 @@ void MAPBeginItemPointer( SOLDIERTYPE *pSoldier, UINT8 ubHandPos )
// Remove all from soldier's slot // Remove all from soldier's slot
numToMove = ALL_OBJECTS; numToMove = ALL_OBJECTS;
} }
/* This needs work
// WDS 08/17/2008 - Cntrl-Click drops all items
else if (_KeyDown( CTRL ))
{
// Remove all from soldier's slot
numToMove = ALL_OBJECTS;
pSoldier->inv[ubHandPos].MoveThisObjectTo(gItemPointer, numToMove, pSoldier, ubHandPos);
if ( gItemPointer.exists() == false )
{
//oops, the move failed. It might have failed because the object was force placed
//to a slot where the ItemSizeLimit is 0, try again
//this method won't work with LBEs in LBE pockets
pSoldier->inv[ubHandPos].MoveThisObjectTo(gItemPointer, numToMove);
}
if ( gItemPointer.exists() == true )
{
SoldierHandleDropItem (pSoldier);
// AddItemToPool( pSoldier->sGridNo, &gItemPointer, 1, pSoldier->pathing.bLevel, WORLD_ITEM_REACHABLE, -1 );
// InternalMAPBeginItemPointer( pSoldier );
}
return;
}
*/
else else
{ {
numToMove = 1; numToMove = 1;
@@ -8616,7 +8641,7 @@ void CreateMouseRegionsForTeamList( void )
// the info region...is the background for the list itself // the info region...is the background for the list itself
for( sCounter = 0; sCounter < MAX_CHARACTER_COUNT; sCounter++ ) for( sCounter = 0; sCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; sCounter++ )
{ {
if( sCounter >= FIRST_VEHICLE ) if( sCounter >= FIRST_VEHICLE )
{ {
@@ -8708,7 +8733,7 @@ void DestroyMouseRegionsForTeamList( void )
// will destroy mouse regions overlaying the team list area // will destroy mouse regions overlaying the team list area
INT32 sCounter = 0; INT32 sCounter = 0;
for( sCounter = 0; sCounter < MAX_CHARACTER_COUNT; sCounter++ ) for( sCounter = 0; sCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; sCounter++ )
{ {
MSYS_RemoveRegion( &gTeamListNameRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListNameRegion[ sCounter ]);
MSYS_RemoveRegion( &gTeamListAssignmentRegion[ sCounter ]); MSYS_RemoveRegion( &gTeamListAssignmentRegion[ sCounter ]);
@@ -10109,14 +10134,14 @@ void ReBuildCharactersList( void )
// add in characters // add in characters
for ( sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) for ( sCount = 0; sCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; sCount++)
{ {
// clear this slot // clear this slot
gCharactersList[ sCount ].fValid = FALSE; gCharactersList[ sCount ].fValid = FALSE;
gCharactersList[ sCount ].usSolID = 0; gCharactersList[ sCount ].usSolID = 0;
} }
for ( sCount = 0; sCount < MAX_CHARACTER_COUNT; sCount++) for ( sCount = 0; sCount < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; sCount++)
{ {
// add character into the cleared slot // add character into the cleared slot
AddCharacter( &Menptr[ gTacticalStatus.Team[ OUR_TEAM ].bFirstID + sCount ] ); AddCharacter( &Menptr[ gTacticalStatus.Team[ OUR_TEAM ].bFirstID + sCount ] );
@@ -10211,7 +10236,7 @@ void EnableDisableTeamListRegionsAndHelpText( void )
INT8 bCharNum; INT8 bCharNum;
for( bCharNum = 0; bCharNum < MAX_CHARACTER_COUNT; bCharNum++ ) for( bCharNum = 0; bCharNum < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCharNum++ )
{ {
if( gCharactersList[ bCharNum ].fValid == FALSE ) if( gCharactersList[ bCharNum ].fValid == FALSE )
{ {
@@ -10406,7 +10431,7 @@ BOOLEAN ContinueDialogue(SOLDIERTYPE *pSoldier, BOOLEAN fDone )
} }
// otherwise, find this character // otherwise, find this character
for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) for( bCounter = 0; bCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCounter++ )
{ {
if( gCharactersList[bCounter].fValid == TRUE ) if( gCharactersList[bCounter].fValid == TRUE )
{ {
@@ -10433,7 +10458,7 @@ void HandleSpontanousTalking( )
if( DialogueActive() == FALSE ) if( DialogueActive() == FALSE )
{ {
if( ( bSelectedInfoChar != -1 ) && ( bSelectedInfoChar < MAX_CHARACTER_COUNT ) ) if( ( bSelectedInfoChar != -1 ) && ( bSelectedInfoChar < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) )
{ {
ContinueDialogue( ( &Menptr[gCharactersList[bSelectedInfoChar].usSolID] ), TRUE ); ContinueDialogue( ( &Menptr[gCharactersList[bSelectedInfoChar].usSolID] ), TRUE );
} }
@@ -10569,7 +10594,7 @@ void RebuildWayPointsForAllSelectedCharsGroups( void )
memset( fGroupIDRebuilt, FALSE, sizeof( fGroupIDRebuilt ) ); memset( fGroupIDRebuilt, FALSE, sizeof( fGroupIDRebuilt ) );
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) )
{ {
@@ -10985,7 +11010,7 @@ INT8 GetLastValidCharacterInTeamPanelList( void )
INT8 iCounter = 0, iValue = 0; INT8 iCounter = 0, iValue = 0;
// run through the list and find the last valid guy in the list // run through the list and find the last valid guy in the list
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -11080,7 +11105,7 @@ INT8 GetNextValidCharacterInTeamPanelList( INT8 bCurrentIndex )
INT8 iCounter = bCurrentIndex, iValue = 0; INT8 iCounter = bCurrentIndex, iValue = 0;
// run through the list and find the last valid guy in the list // run through the list and find the last valid guy in the list
for( iCounter = bCurrentIndex; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = bCurrentIndex; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -11293,7 +11318,7 @@ void UpdateBadAssignments( void )
{ {
UINT32 iCounter; UINT32 iCounter;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -11351,7 +11376,7 @@ BOOLEAN AnyMercsLeavingRealSoon()
UINT32 uiTimeInMin = GetWorldTotalMin(); UINT32 uiTimeInMin = GetWorldTotalMin();
BOOLEAN fFoundOne = FALSE; BOOLEAN fFoundOne = FALSE;
for( uiCounter = 0; uiCounter < MAX_CHARACTER_COUNT; uiCounter++ ) for( uiCounter = 0; uiCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; uiCounter++ )
{ {
if( gCharactersList[ uiCounter ].fValid == TRUE ) if( gCharactersList[ uiCounter ].fValid == TRUE )
{ {
@@ -12057,7 +12082,7 @@ void SortListOfMercsInTeamPanel( BOOLEAN fRetainSelectedMercs, BOOLEAN fReverse
INT16 sEndSectorA, sEndSectorB; INT16 sEndSectorA, sEndSectorB;
INT32 iExpiryTime, iExpiryTimeA; INT32 iExpiryTime, iExpiryTimeA;
UINT8 uiID, uiIDA; UINT8 uiID, uiIDA;
SOLDIERTYPE *pSelectedSoldier[ MAX_CHARACTER_COUNT ]; SOLDIERTYPE *pSelectedSoldier[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
SOLDIERTYPE *pCurrentSoldier = NULL; SOLDIERTYPE *pCurrentSoldier = NULL;
SOLDIERTYPE *pPreviousSelectedInfoChar = NULL; SOLDIERTYPE *pPreviousSelectedInfoChar = NULL;
@@ -12071,7 +12096,7 @@ void SortListOfMercsInTeamPanel( BOOLEAN fRetainSelectedMercs, BOOLEAN fReverse
} }
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// set current entry to null // set current entry to null
pSelectedSoldier[ iCounter ] = NULL; pSelectedSoldier[ iCounter ] = NULL;
@@ -12308,11 +12333,11 @@ void SortListOfMercsInTeamPanel( BOOLEAN fRetainSelectedMercs, BOOLEAN fReverse
// now select all the soldiers that were selected before // now select all the soldiers that were selected before
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( pSelectedSoldier[ iCounter ] ) if( pSelectedSoldier[ iCounter ] )
{ {
for( iCounterA = 0; iCounterA < MAX_CHARACTER_COUNT; iCounterA++ ) for( iCounterA = 0; iCounterA < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounterA++ )
{ {
// is this entry even valid // is this entry even valid
if( gCharactersList[ iCounterA ].fValid == FALSE ) if( gCharactersList[ iCounterA ].fValid == FALSE )
@@ -12434,7 +12459,7 @@ void HandleAssignmentsDoneAndAwaitingFurtherOrders( void )
// update timer so that we only run check so often // update timer so that we only run check so often
giFlashAssignBaseTime = iCurrentTime; giFlashAssignBaseTime = iCurrentTime;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
{ {
@@ -12472,7 +12497,7 @@ void DisplayIconsForMercsAsleep( void )
GetVideoObject(&hHandle, guiSleepIcon ); GetVideoObject(&hHandle, guiSleepIcon );
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( gCharactersList[ iCounter ].fValid == TRUE ) if( gCharactersList[ iCounter ].fValid == TRUE )
{ {
@@ -12589,7 +12614,7 @@ BOOLEAN MapCharacterHasAccessibleInventory( INT8 bCharNumber )
Assert( bCharNumber >= 0 ); Assert( bCharNumber >= 0 );
Assert( bCharNumber < MAX_CHARACTER_COUNT ); Assert( bCharNumber < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS );
// invalid character slot selected? // invalid character slot selected?
if( gCharactersList[ bCharNumber ].fValid == FALSE ) if( gCharactersList[ bCharNumber ].fValid == FALSE )
@@ -12963,7 +12988,7 @@ INT32 GetContractExpiryTime( SOLDIERTYPE *pSoldier )
void ChangeSelectedInfoChar( INT8 bCharNumber, BOOLEAN fResetSelectedList ) void ChangeSelectedInfoChar( INT8 bCharNumber, BOOLEAN fResetSelectedList )
{ {
Assert( ( bCharNumber >= -1 ) && ( bCharNumber < MAX_CHARACTER_COUNT ) ); Assert( ( bCharNumber >= -1 ) && ( bCharNumber < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ) );
if( ( bCharNumber != -1 ) && ( gCharactersList[ bCharNumber ].fValid == FALSE ) ) if( ( bCharNumber != -1 ) && ( gCharactersList[ bCharNumber ].fValid == FALSE ) )
return; return;
@@ -13039,7 +13064,7 @@ void CopyPathToAllSelectedCharacters( PathStPtr pPath )
// run through list and copy paths for each selected character // run through list and copy paths for each selected character
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )
{ {
@@ -13077,7 +13102,7 @@ void CancelPathsOfAllSelectedCharacters()
// cancel destination for the clicked and ALL other valid & selected characters with a route set // cancel destination for the clicked and ALL other valid & selected characters with a route set
for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) for( bCounter = 0; bCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCounter++ )
{ {
// if we've clicked on a selected valid character // if we've clicked on a selected valid character
if( ( gCharactersList[ bCounter ].fValid == TRUE ) && IsEntryInSelectedListSet( bCounter ) ) if( ( gCharactersList[ bCounter ].fValid == TRUE ) && IsEntryInSelectedListSet( bCounter ) )
@@ -13160,7 +13185,7 @@ INT16 CalcLocationValueForChar( INT32 iCounter )
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
INT16 sLocValue = 0; INT16 sLocValue = 0;
Assert( iCounter < MAX_CHARACTER_COUNT ); Assert( iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS );
if( gCharactersList[ iCounter ].fValid == FALSE ) if( gCharactersList[ iCounter ].fValid == FALSE )
return( sLocValue ); return( sLocValue );
@@ -13380,6 +13405,7 @@ UINT8 PlayerMercsInHelicopterSector( void )
Assert( iHelicopterVehicleId != -1); Assert( iHelicopterVehicleId != -1);
pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup ); pGroup = GetGroup( pVehicleList[ iHelicopterVehicleId ].ubMovementGroup );
AssertNotNIL(pGroup);
if ( pGroup->fBetweenSectors ) if ( pGroup->fBetweenSectors )
{ {
@@ -13457,13 +13483,14 @@ void RandomAwakeSelectedMercConfirmsStrategicMove( void )
{ {
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
INT32 iCounter; INT32 iCounter;
UINT8 ubSelectedMercID[ 20 ]; // WDS - make number of mercenaries, etc. be configurable
UINT8 ubSelectedMercIndex[ 20 ]; UINT8 ubSelectedMercID[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
UINT8 ubSelectedMercIndex[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) )
{ {
@@ -13691,7 +13718,7 @@ void WakeUpAnySleepingSelectedMercsOnFootOrDriving( void )
BOOLEAN fSuccess = FALSE; BOOLEAN fSuccess = FALSE;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) ) if( ( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) )
{ {
@@ -13928,7 +13955,7 @@ void InitPreviousPaths( void )
INT32 iCounter = 0; INT32 iCounter = 0;
// init character previous paths // init character previous paths
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
gpCharacterPreviousMercPath[ iCounter ] = NULL; gpCharacterPreviousMercPath[ iCounter ] = NULL;
} }
@@ -13943,7 +13970,7 @@ void RememberPreviousPathForAllSelectedChars( void )
INT32 iCounter = 0; INT32 iCounter = 0;
SOLDIERTYPE *pSoldier = NULL; SOLDIERTYPE *pSoldier = NULL;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )
{ {
@@ -14010,7 +14037,7 @@ void RestorePreviousPaths( void )
} }
else // character(s) plotting else // character(s) plotting
{ {
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// if selected // if selected
if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )
@@ -14083,7 +14110,7 @@ void ClearPreviousPaths( void )
{ {
INT32 iCounter = 0; INT32 iCounter = 0;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE ) if( fSelectedListOfMercsForMapScreen[ iCounter ] == TRUE )
{ {
@@ -14110,7 +14137,7 @@ void SelectAllCharactersInSquad( INT8 bSquadNumber )
ChangeSelectedInfoChar( -1, TRUE ); ChangeSelectedInfoChar( -1, TRUE );
// now select all the soldiers that are in this squad // now select all the soldiers that are in this squad
for( bCounter = 0; bCounter < MAX_CHARACTER_COUNT; bCounter++ ) for( bCounter = 0; bCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; bCounter++ )
{ {
// is this entry is valid // is this entry is valid
if( gCharactersList[ bCounter ].fValid == TRUE ) if( gCharactersList[ bCounter ].fValid == TRUE )
+34 -24
View File
@@ -4629,12 +4629,18 @@ BOOLEAN SaveStrategicInfoToSavedFile( HWFILE hFile )
} }
// Save the Sector Info // Save the Sector Info
uiSize = sizeof( SECTORINFO ) * 256; for (int sectorID = 0; sectorID <= 255; ++ sectorID) {
FileWrite( hFile, SectorInfo, uiSize, &uiNumBytesWritten ); FileWrite( hFile, &SectorInfo[sectorID], sizeof( SECTORINFO ), &uiNumBytesWritten );
if( uiNumBytesWritten != uiSize) if( uiNumBytesWritten != sizeof( SECTORINFO )) {
{ return(FALSE);
return(FALSE); }
} }
// uiSize = sizeof( SECTORINFO ) * 256;
// FileWrite( hFile, SectorInfo, uiSize, &uiNumBytesWritten );
// if( uiNumBytesWritten != uiSize)
// {
// return(FALSE);
// }
// Save the SAM Controlled Sector Information // Save the SAM Controlled Sector Information
uiSize = MAP_WORLD_X * MAP_WORLD_Y; uiSize = MAP_WORLD_X * MAP_WORLD_Y;
@@ -4675,12 +4681,18 @@ BOOLEAN LoadStrategicInfoFromSavedFile( HWFILE hFile )
} }
// Load the Sector Info // Load the Sector Info
uiSize = sizeof( SECTORINFO ) * 256; for (int sectorID = 0; sectorID <= 255; ++ sectorID) {
FileRead( hFile, SectorInfo, uiSize, &uiNumBytesRead ); FileRead( hFile, &SectorInfo[sectorID], sizeof( SECTORINFO ), &uiNumBytesRead );
if( uiNumBytesRead != uiSize) if( uiNumBytesRead != sizeof( SECTORINFO )) {
{ return(FALSE);
return(FALSE); }
} }
// uiSize = sizeof( SECTORINFO ) * 256;
// FileRead( hFile, SectorInfo, uiSize, &uiNumBytesRead );
// if( uiNumBytesRead != uiSize)
// {
// return(FALSE);
// }
// Load the SAM Controlled Sector Information // Load the SAM Controlled Sector Information
uiSize = MAP_WORLD_X * MAP_WORLD_Y; uiSize = MAP_WORLD_X * MAP_WORLD_Y;
@@ -5527,35 +5539,33 @@ BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode )
return TRUE; return TRUE;
} }
BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle( ) BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle(int pSectorX, int pSectorY, int pSectorZ)
{ {
INT32 i;
//We don't have mercs in the sector. Now, we check to see if there are BOTH enemies and militia. If both //We don't have mercs in the sector. Now, we check to see if there are BOTH enemies and militia. If both
//co-exist in the sector, then make them fight for control of the sector via autoresolve. //co-exist in the sector, then make them fight for control of the sector via autoresolve.
for( i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; i++ ) for( int i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; i++ )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife )
{ {
if( MercPtrs[ i ]->sSectorX == gWorldSectorX && if( MercPtrs[ i ]->sSectorX == pSectorX &&
MercPtrs[ i ]->sSectorY == gWorldSectorY && MercPtrs[ i ]->sSectorY == pSectorY &&
MercPtrs[ i ]->bSectorZ == gbWorldSectorZ ) MercPtrs[ i ]->bSectorZ == pSectorZ )
{ //We have enemies, now look for militia! { //We have enemies, now look for militia!
for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ ) for( i = gTacticalStatus.Team[ MILITIA_TEAM ].bFirstID; i <= gTacticalStatus.Team[ MILITIA_TEAM ].bLastID; i++ )
{ {
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && MercPtrs[ i ]->bSide == OUR_TEAM ) if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && MercPtrs[ i ]->bSide == OUR_TEAM )
{ {
if( MercPtrs[ i ]->sSectorX == gWorldSectorX && if( MercPtrs[ i ]->sSectorX == pSectorX &&
MercPtrs[ i ]->sSectorY == gWorldSectorY && MercPtrs[ i ]->sSectorY == pSectorY &&
MercPtrs[ i ]->bSectorZ == gbWorldSectorZ ) MercPtrs[ i ]->bSectorZ == pSectorZ )
{ //We have militia and enemies and no mercs! Let's finish this battle in autoresolve. { //We have militia and enemies and no mercs! Let's finish this battle in autoresolve.
gfEnteringMapScreen = TRUE; gfEnteringMapScreen = TRUE;
gfEnteringMapScreenToEnterPreBattleInterface = TRUE; gfEnteringMapScreenToEnterPreBattleInterface = TRUE;
gfAutomaticallyStartAutoResolve = TRUE; gfAutomaticallyStartAutoResolve = TRUE;
gfUsePersistantPBI = FALSE; gfUsePersistantPBI = FALSE;
gubPBSectorX = (UINT8)gWorldSectorX; gubPBSectorX = (UINT8)pSectorX;
gubPBSectorY = (UINT8)gWorldSectorY; gubPBSectorY = (UINT8)pSectorY;
gubPBSectorZ = (UINT8)gbWorldSectorZ; gubPBSectorZ = (UINT8)pSectorZ;
gfBlitBattleSectorLocator = TRUE; gfBlitBattleSectorLocator = TRUE;
gfTransferTacticalOppositionToAutoResolve = TRUE; gfTransferTacticalOppositionToAutoResolve = TRUE;
if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE ) if( gubEnemyEncounterCode != CREATURE_ATTACK_CODE )
@@ -5639,7 +5649,7 @@ BOOLEAN CheckAndHandleUnloadingOfCurrentWorld()
// Added logic to prevent a crash when player mercs would retreat from a battle involving militia and enemies. // Added logic to prevent a crash when player mercs would retreat from a battle involving militia and enemies.
// Without the return here, it would proceed to trash the world, and then when autoresolve would come up to // Without the return here, it would proceed to trash the world, and then when autoresolve would come up to
// finish the tactical battle, it would fail to find the existing soldier information (because it was trashed). // finish the tactical battle, it would fail to find the existing soldier information (because it was trashed).
if( HandlePotentialBringUpAutoresolveToFinishBattle( ) ) if( HandlePotentialBringUpAutoresolveToFinishBattle( sBattleSectorX, sBattleSectorY, sBattleSectorZ ) )
{ {
return FALSE; return FALSE;
} }
+1 -1
View File
@@ -168,7 +168,7 @@ INT8 GetSAMIdFromSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
void SetupProfileInsertionDataForSoldier( SOLDIERTYPE *pSoldier ); void SetupProfileInsertionDataForSoldier( SOLDIERTYPE *pSoldier );
BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle( ); BOOLEAN HandlePotentialBringUpAutoresolveToFinishBattle( int pSectorX, int pSectorY, int pSectorZ );
//Used for determining the type of error message that comes up when you can't traverse to //Used for determining the type of error message that comes up when you can't traverse to
//an adjacent sector. THESE VALUES DO NOT NEED TO BE SAVED! //an adjacent sector. THESE VALUES DO NOT NEED TO BE SAVED!
+11
View File
@@ -958,11 +958,17 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
} }
} }
// WDS - Improve Tony's and Devin's inventory like BR's
// Tony has the better stuff sooner (than Bobby R's) // Tony has the better stuff sooner (than Bobby R's)
if (bArmsDealer == ARMS_DEALER_TONY) if (bArmsDealer == ARMS_DEALER_TONY)
{ {
ubMinCoolness += 1; ubMinCoolness += 1;
ubMaxCoolness += 1; ubMaxCoolness += 1;
if (gGameExternalOptions.tonyUsesBRSetting) {
ubMinCoolness += gGameOptions.ubBobbyRay / 3;
ubMaxCoolness += gGameOptions.ubBobbyRay;
}
} }
else if (bArmsDealer == ARMS_DEALER_DEVIN) else if (bArmsDealer == ARMS_DEALER_DEVIN)
{ {
@@ -972,6 +978,11 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
ubMinCoolness = 3; ubMinCoolness = 3;
ubMaxCoolness = 4; ubMaxCoolness = 4;
} }
if (gGameExternalOptions.devinUsesBRSetting) {
ubMinCoolness += gGameOptions.ubBobbyRay / 3;
ubMaxCoolness += gGameOptions.ubBobbyRay;
}
} }
+36 -14
View File
@@ -59,11 +59,14 @@ MOUSE_REGION gAutoBandageRegion;
// the lists of the doctor and patient // the lists of the doctor and patient
INT32 iDoctorList[ MAX_CHARACTER_COUNT ]; std::vector<INT32> iDoctorList (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, -1);
INT32 iPatientList[ MAX_CHARACTER_COUNT ]; std::vector<INT32> iPatientList (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, -1);
//INT32 iDoctorList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
//INT32 iPatientList[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// faces for update panel // faces for update panel
INT32 giAutoBandagesSoldierFaces[ 2 * MAX_CHARACTER_COUNT ]; std::vector<INT32> giAutoBandagesSoldierFaces (2*CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, -1);
//INT32 giAutoBandagesSoldierFaces[ 2 * CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
// has the button for autobandage end been setup yet // has the button for autobandage end been setup yet
BOOLEAN fAutoEndBandageButtonCreated = FALSE; BOOLEAN fAutoEndBandageButtonCreated = FALSE;
@@ -307,7 +310,8 @@ BOOLEAN HandleAutoBandage( )
BOOLEAN CreateAutoBandageString( void ) BOOLEAN CreateAutoBandageString( void )
{ {
INT32 cnt; INT32 cnt;
UINT8 ubDoctor[20], ubDoctors = 0; // WDS - make number of mercenaries, etc. be configurable
UINT8 ubDoctor[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS], ubDoctors = 0;
UINT32 uiDoctorNameStringLength = 1; // for end-of-string character UINT32 uiDoctorNameStringLength = 1; // for end-of-string character
STR16 sTemp; STR16 sTemp;
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
@@ -554,9 +558,16 @@ void SetUpAutoBandageUpdatePanel( void )
INT32 iNumberOnTeam = 0; INT32 iNumberOnTeam = 0;
INT32 iCounterA = 0; INT32 iCounterA = 0;
// WDS - make number of mercenaries, etc. be configurable
// reset the tables of merc ids // reset the tables of merc ids
memset( iDoctorList, -1, sizeof( INT32 ) * MAX_CHARACTER_COUNT ); for (std::vector<INT32>::iterator docIter = iDoctorList.begin(); docIter != iDoctorList.end(); ++docIter) {
memset( iPatientList, -1, sizeof( INT32 ) * MAX_CHARACTER_COUNT ); *docIter = -1;
}
for (std::vector<INT32>::iterator pIter = iPatientList.begin(); pIter != iPatientList.end(); ++pIter) {
*pIter = -1;
}
// memset( iDoctorList, -1, sizeof( iDoctorList ) );
// memset( iPatientList, -1, sizeof( iPatientList ) );
// grab number of potential grunts on players team // grab number of potential grunts on players team
@@ -588,9 +599,16 @@ void SetUpAutoBandageUpdatePanel( void )
// makes sure there is someone to doctor and patient... // makes sure there is someone to doctor and patient...
if( ( iNumberDoctoring == 0 ) || ( iNumberPatienting == 0 ) ) if( ( iNumberDoctoring == 0 ) || ( iNumberPatienting == 0 ) )
{ {
// WDS - make number of mercenaries, etc. be configurable
// reset the tables of merc ids // reset the tables of merc ids
memset( iDoctorList, -1, sizeof( INT32 ) * MAX_CHARACTER_COUNT ); for (std::vector<INT32>::iterator iter = iDoctorList.begin(); iter != iDoctorList.end(); ++iter) {
memset( iPatientList, -1, sizeof( INT32 ) * MAX_CHARACTER_COUNT ); *iter = -1;
}
for (std::vector<INT32>::iterator iter = iPatientList.begin(); iter != iPatientList.end(); ++iter) {
*iter = -1;
}
// memset( iDoctorList, -1, sizeof( iDoctorList ) );
// memset( iPatientList, -1, sizeof( iPatientList ) );
} }
// now add the faces // now add the faces
@@ -1046,12 +1064,16 @@ BOOLEAN AddFacesToAutoBandageBox( void )
VOBJECT_DESC VObjectDesc; VOBJECT_DESC VObjectDesc;
// WDS - make number of mercenaries, etc. be configurable
// reset // reset
memset( &giAutoBandagesSoldierFaces, -1, 2 * MAX_CHARACTER_COUNT ); for (std::vector<INT32>::iterator iter = giAutoBandagesSoldierFaces.begin(); iter != giAutoBandagesSoldierFaces.end(); ++iter) {
*iter = -1;
}
// memset( &giAutoBandagesSoldierFaces, -1, sizeof(giAutoBandagesSoldierFaces));
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// find a free slot // find a free slot
if( iDoctorList[ iCounter ] != -1 ) if( iDoctorList[ iCounter ] != -1 )
@@ -1074,7 +1096,7 @@ BOOLEAN AddFacesToAutoBandageBox( void )
} }
} }
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// find a free slot // find a free slot
if( iPatientList[ iCounter ] != -1 ) if( iPatientList[ iCounter ] != -1 )
@@ -1112,7 +1134,7 @@ BOOLEAN RemoveFacesForAutoBandage( void )
INT32 iCounter = 0, iNumberOfDoctors = 0; INT32 iCounter = 0, iNumberOfDoctors = 0;
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// find a free slot // find a free slot
if( iDoctorList[ iCounter ] != -1 ) if( iDoctorList[ iCounter ] != -1 )
@@ -1124,7 +1146,7 @@ BOOLEAN RemoveFacesForAutoBandage( void )
} }
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// find a free slot // find a free slot
if( iPatientList[ iCounter ] != -1 ) if( iPatientList[ iCounter ] != -1 )
@@ -1160,7 +1182,7 @@ BOOLEAN RenderSoldierSmallFaceForAutoBandagePanel( INT32 iIndex, INT16 sCurrentX
BltVideoObject( FRAME_BUFFER , hHandle , 0, sCurrentXPosition+2, sCurrentYPosition+2, VO_BLT_SRCTRANSPARENCY, NULL ); BltVideoObject( FRAME_BUFFER , hHandle , 0, sCurrentXPosition+2, sCurrentYPosition+2, VO_BLT_SRCTRANSPARENCY, NULL );
for( iCounter = 0; iCounter < MAX_CHARACTER_COUNT; iCounter++ ) for( iCounter = 0; iCounter < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; iCounter++ )
{ {
// find a free slot // find a free slot
if( iDoctorList[ iCounter ] != -1 ) if( iDoctorList[ iCounter ] != -1 )
+13 -4
View File
@@ -1267,7 +1267,7 @@ UINT8 CurrentPlayerProgressPercentage(void)
{ {
UINT32 uiCurrentIncome; UINT32 uiCurrentIncome;
UINT32 uiPossibleIncome; UINT32 uiPossibleIncome;
UINT8 ubCurrentProgress; UINT8 ubCurrentProgress = gGameExternalOptions.ubGameProgressIncrement;
UINT8 ubKillsPerPoint; UINT8 ubKillsPerPoint;
UINT16 usKillsProgress; UINT16 usKillsProgress;
UINT16 usControlProgress; UINT16 usControlProgress;
@@ -1343,12 +1343,21 @@ UINT8 CurrentPlayerProgressPercentage(void)
// WDS: Adding more ways to progress in the game // WDS: Adding more ways to progress in the game
// Get a ratio of sectors visited to the total number of sectors // Get a ratio of sectors visited to the total number of sectors
usVisitProgress = CountSurfaceSectorsVisited() * gGameExternalOptions.ubGameProgressPortionVisited / ((MAP_WORLD_X - 2) * (MAP_WORLD_Y - 2)); usVisitProgress = CountSurfaceSectorsVisited() * gGameExternalOptions.ubGameProgressPortionVisited / ((MAP_WORLD_X - 2) * (MAP_WORLD_Y - 2) - 56 /* note: should be calculated */);
// add control progress // add visit progress
ubCurrentProgress += usVisitProgress; ubCurrentProgress += usVisitProgress;
return(ubCurrentProgress); // Add increment to progress
ubCurrentProgress += gGameExternalOptions.ubGameProgressIncrement;
if (ubCurrentProgress < gGameExternalOptions.ubGameProgressMinimum)
return gGameExternalOptions.ubGameProgressMinimum;
if (ubCurrentProgress < 100)
return ubCurrentProgress;
else
return 100;
} }
+10 -5
View File
@@ -56,6 +56,8 @@
#include "los.h" #include "los.h"
#include "qarray.h" #include "qarray.h"
#endif #endif
#include <vector>
#include "Auto Resolve.h"
#include "connect.h" #include "connect.h"
@@ -478,7 +480,6 @@ void HandleDialogue( )
iQSize = QueueSize( ghDialogueQ ); iQSize = QueueSize( ghDialogueQ );
if ( iQSize == 0 && gpCurrentTalkingFace == NULL ) if ( iQSize == 0 && gpCurrentTalkingFace == NULL )
{ {
HandlePendingInitConv( ); HandlePendingInitConv( );
@@ -2453,7 +2454,8 @@ void RenderSubtitleBoxOverlay( VIDEO_OVERLAY *pBlitter )
void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum ) void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS, 0);
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
@@ -2516,7 +2518,8 @@ void SayQuoteFromAnyBodyInSector( UINT16 usQuoteNum )
void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT16 usQuoteNum ) void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT16 usQuoteNum )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
@@ -2568,7 +2571,8 @@ void SayQuoteFromAnyBodyInThisSector( INT16 sSectorX, INT16 sSectorY, INT8 bSect
void SayQuoteFromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuoteNum ) void SayQuoteFromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuoteNum )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0 );
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
@@ -2612,7 +2616,8 @@ void SayQuoteFromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuo
void SayQuote58FromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuoteNum, INT8 bSex ) void SayQuote58FromNearbyMercInSector( INT16 sGridNo, INT8 bDistance, UINT16 usQuoteNum, INT8 bSex )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
+14 -8
View File
@@ -3,6 +3,7 @@
#include "Enemy Soldier Save.h" #include "Enemy Soldier Save.h"
#else #else
#include "builddefines.h" #include "builddefines.h"
#include "GameSettings.h"
#include <stdio.h> #include <stdio.h>
#include <memory.h> #include <memory.h>
@@ -167,7 +168,8 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
} }
FileRead( hfile, &slots, 4, &uiNumBytesRead ); FileRead( hfile, &slots, 4, &uiNumBytesRead );
if( uiNumBytesRead != 4 ) // WDS - make number of mercenaries, etc. be configurable
if( (uiNumBytesRead != 4) || (slots > TOTAL_SOLDIERS) )
{ {
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "EnemySoldier -- EOF while reading slots. KM" ); sprintf( zReason, "EnemySoldier -- EOF while reading slots. KM" );
@@ -215,7 +217,7 @@ BOOLEAN LoadEnemySoldiersFromTempFile()
FileClose( hfile ); FileClose( hfile );
return TRUE; return TRUE;
} }
if( slots < 0 || slots >= 64 ) if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ //bad IO! { //bad IO!
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "EnemySoldier -- illegal slot value of %d. KM", slots ); sprintf( zReason, "EnemySoldier -- illegal slot value of %d. KM", slots );
@@ -771,7 +773,8 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
FileRead( hfile, &slots, 4, &uiNumBytesRead ); FileRead( hfile, &slots, 4, &uiNumBytesRead );
if( uiNumBytesRead != 4 ) // WDS - make number of mercenaries, etc. be configurable
if( (uiNumBytesRead != 4) || (slots > TOTAL_SOLDIERS) )
{ {
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "EnemySoldier -- EOF while reading slots. KM" ); sprintf( zReason, "EnemySoldier -- EOF while reading slots. KM" );
@@ -820,7 +823,7 @@ BOOLEAN NewWayOfLoadingEnemySoldiersFromTempFile()
} }
if( slots < 0 || slots >= 64 ) if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ //bad IO! { //bad IO!
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "EnemySoldier -- illegal slot value of %d. KM", slots ); sprintf( zReason, "EnemySoldier -- illegal slot value of %d. KM", slots );
@@ -1114,7 +1117,8 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile()
} }
FileRead( hfile, &slots, 4, &uiNumBytesRead ); FileRead( hfile, &slots, 4, &uiNumBytesRead );
if( uiNumBytesRead != 4 ) // WDS - make number of mercenaries, etc. be configurable
if( (uiNumBytesRead != 4) || (slots > TOTAL_SOLDIERS) )
{ {
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "Civilian -- EOF while reading slots. KM" ); sprintf( zReason, "Civilian -- EOF while reading slots. KM" );
@@ -1149,6 +1153,7 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile()
goto FAIL_LOAD; goto FAIL_LOAD;
} }
// WDS - DEBUG - Comment out the following ling to force reinit of a sector
if( !slots ) if( !slots )
{ {
//no need to restore the enemy's to the map. This means we are restoring a saved game. //no need to restore the enemy's to the map. This means we are restoring a saved game.
@@ -1156,7 +1161,7 @@ BOOLEAN NewWayOfLoadingCiviliansFromTempFile()
FileClose( hfile ); FileClose( hfile );
return TRUE; return TRUE;
} }
if( slots < 0 || slots >= 64 ) if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfCivilians )
{ {
//bad IO! //bad IO!
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
@@ -1647,7 +1652,8 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
} }
FileRead( hfile, &slots, 4, &uiNumBytesRead ); FileRead( hfile, &slots, 4, &uiNumBytesRead );
if( uiNumBytesRead != 4 ) // WDS - make number of mercenaries, etc. be configurable
if( (uiNumBytesRead != 4) || (slots > TOTAL_SOLDIERS) )
{ {
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "Check EnemySoldier -- EOF while reading slots. KM" ); sprintf( zReason, "Check EnemySoldier -- EOF while reading slots. KM" );
@@ -1690,7 +1696,7 @@ BOOLEAN CountNumberOfElitesRegularsAdminsAndCreaturesFromEnemySoldiersTempFile(
} }
if( slots < 0 || slots >= 64 ) if( slots < 0 || slots >= (int)gGameExternalOptions.ubGameMaximumNumberOfEnemies )
{ //bad IO! { //bad IO!
#ifdef JA2TESTVERSION #ifdef JA2TESTVERSION
sprintf( zReason, "Check EnemySoldier -- illegal slot value of %d. KM", slots ); sprintf( zReason, "Check EnemySoldier -- illegal slot value of %d. KM", slots );
+11 -3
View File
@@ -4967,10 +4967,18 @@ void MineSpottedDialogueCallBack( void )
GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel ); GetItemPool( gsBoobyTrapGridNo, &pItemPool, gbBoobyTrapLevel );
guiPendingOverrideEvent = LU_BEGINUILOCK; // WDS - Automatically flag mines
if (gGameExternalOptions.automaticallyFlagMines) {
// play a locator at the location of the mine
SetItemPoolLocator( pItemPool );
// play a locator at the location of the mine AddBlueFlag( gsBoobyTrapGridNo, gbBoobyTrapLevel );
SetItemPoolLocatorWithCallback( pItemPool, MineSpottedLocatorCallback ); } else {
guiPendingOverrideEvent = LU_BEGINUILOCK;
// play a locator at the location of the mine
SetItemPoolLocatorWithCallback( pItemPool, MineSpottedLocatorCallback );
}
} }
void MineSpottedLocatorCallback( void ) void MineSpottedLocatorCallback( void )
+3 -2
View File
@@ -1077,9 +1077,10 @@ UINT32 UIHandleNewMerc( UI_EVENT *pUIEvent )
{ {
ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Merc hire failed: Either already hired or dislikes you." ); ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Merc hire failed: Either already hired or dislikes you." );
} }
else if( bReturnCode == MERC_HIRE_OVER_18_MERCS_HIRED ) // WDS - make number of mercenaries, etc. be configurable
else if( bReturnCode == MERC_HIRE_OVER_PLAYER_LIMIT )
{ {
ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Can't hire more than 18 mercs." ); ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"Can't hire that many mercs." );
} }
else else
{ {
+2 -2
View File
@@ -664,7 +664,7 @@ void RenderTopmostTacticalInterface( )
} }
/*
if ( gfUIInDeadlock ) if ( gfUIInDeadlock )
{ {
SetFont( LARGEFONT1 ); SetFont( LARGEFONT1 );
@@ -674,7 +674,7 @@ void RenderTopmostTacticalInterface( )
mprintf( 0, 300, L"OPPONENT %d DEADLOCKED - 'Q' TO DEBUG, <ALT><ENTER> END OPP TURN", gUIDeadlockedSoldier ); mprintf( 0, 300, L"OPPONENT %d DEADLOCKED - 'Q' TO DEBUG, <ALT><ENTER> END OPP TURN", gUIDeadlockedSoldier );
} }
*/
// Syncronize for upcoming soldier counters // Syncronize for upcoming soldier counters
SYNCTIMECOUNTER( ); SYNCTIMECOUNTER( );
+9 -23
View File
@@ -78,6 +78,7 @@
#include "end game.h" #include "end game.h"
#include "Map Screen Helicopter.h" #include "Map Screen Helicopter.h"
#include "Cheats.h" #include "Cheats.h"
#include "Overhead.h"
#endif #endif
//forward declarations of common classes to eliminate includes //forward declarations of common classes to eliminate includes
@@ -2036,13 +2037,16 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
// Delete menu // Delete menu
DeleteTalkingMenu( ); DeleteTalkingMenu( );
if ( PlayerTeamFull( ) ) if ( PlayerTeamFull( ) )
{ {
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_RECRUIT_TEAM_FULL ] ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_RECRUIT_TEAM_FULL ] );
} }
else else
{ {
RecruitRPC( ubTargetNPC ); if (!RecruitRPC( ubTargetNPC )) {
ScreenMsg( FONT_MCOLOR_RED, MSG_ERROR, L"Internal error in recruiting RPC, trying to recover as best it can but this might not be pretty..." );
return;
}
// OK, update UI with message that we have been recruited // OK, update UI with message that we have been recruited
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ HAS_BEEN_RECRUITED_STR ], gMercProfiles[ ubTargetNPC ].zNickname ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ HAS_BEEN_RECRUITED_STR ], gMercProfiles[ ubTargetNPC ].zNickname );
} }
@@ -4366,25 +4370,7 @@ UINT32 CalcMedicalCost( UINT8 ubId )
BOOLEAN PlayerTeamHasTwoSpotsLeft( ) BOOLEAN PlayerTeamHasTwoSpotsLeft( )
{ {
UINT32 cnt, uiCount = 0; return ( CountNonVehiclesOnPlayerTeam() <= gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs - 2 );
SOLDIERTYPE *pSoldier;
for ( cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID, pSoldier = MercPtrs[ cnt ]; cnt <= (UINT32)( gTacticalStatus.Team[ gbPlayerNum ].bLastID - 2 ); cnt++, pSoldier++ )
{
if ( pSoldier->bActive )
{
uiCount++;
}
}
if ( uiCount <= (UINT32) (gTacticalStatus.Team[ gbPlayerNum].bLastID - 2) - 1 )
{
return( TRUE );
}
else
{
return( FALSE );
}
} }
+45 -25
View File
@@ -267,16 +267,17 @@ int MONEY_HEIGHT;
* why we declare array with 12 items? coz we got 2 valuse x and y maby we can work it out * why we declare array with 12 items? coz we got 2 valuse x and y maby we can work it out
* and change INT16 to INV_REGION_DESC for ex. * and change INT16 to INV_REGION_DESC for ex.
*/ */
INT16 sTEAMAPPanelXY[12]; const int TeamInterfaceMax = NUMBER_OF_SOLDIERS_PER_SQUAD * 2; // WDS
INT16 sTEAMFacesXY[12]; INT16 sTEAMAPPanelXY[TeamInterfaceMax];
INT16 sTEAMNamesXY[12]; INT16 sTEAMFacesXY[TeamInterfaceMax];
INT16 sTEAMFaceHighlXY[12]; INT16 sTEAMNamesXY[TeamInterfaceMax];
INT16 sTEAMLifeXY[12]; INT16 sTEAMFaceHighlXY[TeamInterfaceMax];
INT16 sTEAMBreathXY[12]; INT16 sTEAMLifeXY[TeamInterfaceMax];
INT16 sTEAMMoraleXY[12]; INT16 sTEAMBreathXY[TeamInterfaceMax];
INT16 sTEAMApXY[12]; INT16 sTEAMMoraleXY[TeamInterfaceMax];
INT16 sTEAMBarsXY[12]; INT16 sTEAMApXY[TeamInterfaceMax];
INT16 sTEAMHandInvXY[12]; INT16 sTEAMBarsXY[TeamInterfaceMax];
INT16 sTEAMHandInvXY[TeamInterfaceMax];
int TM_FACE_WIDTH; int TM_FACE_WIDTH;
int TM_FACE_HEIGHT; int TM_FACE_HEIGHT;
@@ -454,14 +455,14 @@ MOUSE_REGION gSM_SELMERCBarsRegion;
MOUSE_REGION gSM_SELMERCMoneyRegion; MOUSE_REGION gSM_SELMERCMoneyRegion;
MOUSE_REGION gSM_SELMERCEnemyIndicatorRegion; MOUSE_REGION gSM_SELMERCEnemyIndicatorRegion;
MOUSE_REGION gTEAM_PanelRegion; MOUSE_REGION gTEAM_PanelRegion;
MOUSE_REGION gTEAM_FaceRegions[ 6 ]; MOUSE_REGION gTEAM_FaceRegions[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_BarsRegions[ 6 ]; MOUSE_REGION gTEAM_BarsRegions[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_LeftBarsRegions[ 6 ]; MOUSE_REGION gTEAM_LeftBarsRegions[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_FirstHandInv[ 6 ]; MOUSE_REGION gTEAM_FirstHandInv[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_SecondHandInv[ 6 ]; MOUSE_REGION gTEAM_SecondHandInv[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_EnemyIndicator[ 6 ]; MOUSE_REGION gTEAM_EnemyIndicator[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
BOOLEAN gfTEAM_HandInvDispText[ 6 ][ NUM_INV_SLOTS ]; BOOLEAN gfTEAM_HandInvDispText[ NUMBER_OF_SOLDIERS_PER_SQUAD ][ NUM_INV_SLOTS ];
BOOLEAN gfSM_HandInvDispText[ NUM_INV_SLOTS ]; BOOLEAN gfSM_HandInvDispText[ NUM_INV_SLOTS ];
void HelpTextDoneCallback( void ); void HelpTextDoneCallback( void );
@@ -771,7 +772,7 @@ void UpdateForContOverPortrait( SOLDIERTYPE *pSoldier, BOOLEAN fOn )
} }
else else
{ {
for ( cnt = 0; cnt < 6; cnt++ ) for ( cnt = 0; cnt < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt++ )
{ {
if ( gTeamPanel[ cnt ].ubID == pSoldier->ubID ) if ( gTeamPanel[ cnt ].ubID == pSoldier->ubID )
{ {
@@ -4449,6 +4450,24 @@ BOOLEAN InitializeTEAMPanelCoords( )
INDICATOR_BOX_WIDTH = 12; INDICATOR_BOX_WIDTH = 12;
INDICATOR_BOX_HEIGHT = 10; INDICATOR_BOX_HEIGHT = 10;
for (int idx = 0; idx < TeamInterfaceMax/2; idx+=1) {
const int evenIdx = idx * 2;
Assert(evenIdx < TeamInterfaceMax);
const int oddIdx = idx*2+1;
Assert(oddIdx < TeamInterfaceMax);
sTEAMAPPanelXY[evenIdx] = ( 69+idx*83 + INTERFACE_START_X ); sTEAMAPPanelXY[oddIdx] = ( 6 + INTERFACE_START_Y );
sTEAMFacesXY[evenIdx] = ( 13+idx*83+(idx>0) + INTERFACE_START_X ); sTEAMFacesXY[oddIdx] = ( 6 + INTERFACE_START_Y );
sTEAMNamesXY[evenIdx] = ( 7+idx*83 + INTERFACE_START_X ); sTEAMNamesXY[oddIdx] = ( 55 + INTERFACE_START_Y );
sTEAMFaceHighlXY[evenIdx] = ( 4+idx*83 + INTERFACE_START_X ); sTEAMFaceHighlXY[oddIdx] = ( 2 + INTERFACE_START_Y );
sTEAMLifeXY[evenIdx] = ( 69+idx*83 + INTERFACE_START_X ); sTEAMLifeXY[oddIdx] = ( ( 5 + INTERFACE_START_Y ) + TM_LIFEBAR_HEIGHT );
sTEAMBreathXY[evenIdx] = ( 75+idx*83 + INTERFACE_START_X ); sTEAMBreathXY[oddIdx] = ( ( 5 + INTERFACE_START_Y ) + TM_LIFEBAR_HEIGHT );
sTEAMMoraleXY[evenIdx] = ( 81+idx*83 + INTERFACE_START_X ); sTEAMMoraleXY[oddIdx] = ( ( 5 + INTERFACE_START_Y ) + TM_LIFEBAR_HEIGHT );
sTEAMApXY[evenIdx] = ( 68+idx*83 + INTERFACE_START_X ); sTEAMApXY[oddIdx] = ( 52 + INTERFACE_START_Y );
sTEAMBarsXY[evenIdx] = ( 61+idx*83+(idx>0) + INTERFACE_START_X ); sTEAMBarsXY[oddIdx] = ( 3 + INTERFACE_START_Y );
sTEAMHandInvXY[evenIdx] = ( TM_INV_HAND1STARTX + ( idx * TM_INV_HAND_SEP )); sTEAMHandInvXY[oddIdx] = TM_INV_HAND1STARTY;
}
/*
sTEAMAPPanelXY[0] = ( 69 + INTERFACE_START_X ); sTEAMAPPanelXY[1] = ( 6 + INTERFACE_START_Y ); sTEAMAPPanelXY[0] = ( 69 + INTERFACE_START_X ); sTEAMAPPanelXY[1] = ( 6 + INTERFACE_START_Y );
sTEAMAPPanelXY[2] = ( 151 + INTERFACE_START_X ); sTEAMAPPanelXY[3] = ( 6 + INTERFACE_START_Y ); sTEAMAPPanelXY[2] = ( 151 + INTERFACE_START_X ); sTEAMAPPanelXY[3] = ( 6 + INTERFACE_START_Y );
sTEAMAPPanelXY[4] = ( 234 + INTERFACE_START_X ); sTEAMAPPanelXY[5] = ( 6 + INTERFACE_START_Y ); sTEAMAPPanelXY[4] = ( 234 + INTERFACE_START_X ); sTEAMAPPanelXY[5] = ( 6 + INTERFACE_START_Y );
@@ -4519,7 +4538,7 @@ BOOLEAN InitializeTEAMPanelCoords( )
sTEAMHandInvXY[8] = ( TM_INV_HAND1STARTX + ( 4 * TM_INV_HAND_SEP )); sTEAMHandInvXY[9] = TM_INV_HAND1STARTY; sTEAMHandInvXY[8] = ( TM_INV_HAND1STARTX + ( 4 * TM_INV_HAND_SEP )); sTEAMHandInvXY[9] = TM_INV_HAND1STARTY;
sTEAMHandInvXY[10] = ( TM_INV_HAND1STARTX + ( 5 * TM_INV_HAND_SEP )); sTEAMHandInvXY[11] = TM_INV_HAND1STARTY; sTEAMHandInvXY[10] = ( TM_INV_HAND1STARTX + ( 5 * TM_INV_HAND_SEP )); sTEAMHandInvXY[11] = TM_INV_HAND1STARTY;
// ufff to much copy&paste :D // ufff to much copy&paste :D
*/
// CHRISL: New definitions for the team panel clock and location coordinates // CHRISL: New definitions for the team panel clock and location coordinates
INTERFACE_CLOCK_TM_X = ( SCREEN_WIDTH - 86 ); INTERFACE_CLOCK_TM_X = ( SCREEN_WIDTH - 86 );
INTERFACE_CLOCK_TM_Y = ( 98 + INTERFACE_START_Y ); INTERFACE_CLOCK_TM_Y = ( 98 + INTERFACE_START_Y );
@@ -4680,7 +4699,7 @@ BOOLEAN ShutdownTEAMPanel( )
// Remove viewport // Remove viewport
MSYS_RemoveRegion( &gViewportRegion ); MSYS_RemoveRegion( &gViewportRegion );
for ( cnt = 0; cnt < 6; cnt++ ) for ( cnt = 0; cnt < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt++ )
{ {
MSYS_RemoveRegion( &gTEAM_EnemyIndicator[ cnt ] ); MSYS_RemoveRegion( &gTEAM_EnemyIndicator[ cnt ] );
MSYS_RemoveRegion( &gTEAM_FaceRegions[ cnt ] ); MSYS_RemoveRegion( &gTEAM_FaceRegions[ cnt ] );
@@ -4760,9 +4779,10 @@ void RenderTEAMPanel( BOOLEAN fDirty )
if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER ) ) if ( pSoldier->flags.uiStatusFlags & ( SOLDIER_DRIVER ) )
{ {
// Get soldier pointer for vehicle..... // Get soldier pointer for vehicle.....
SOLDIERTYPE *pVehicle; SOLDIERTYPE *pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId );
pVehicle = GetSoldierStructureForVehicle( pSoldier->iVehicleId ); // WDS 07/02/3008 - Fix bug of getting into vehicle you don't control
Assert (pVehicle != 0);
//OK, for each item, set dirty text if applicable! //OK, for each item, set dirty text if applicable!
swprintf( pStr, TacticalStr[ DRIVER_POPUPTEXT ], pVehicle->stats.bLife, pVehicle->stats.bLifeMax, pVehicle->bBreath, pVehicle->bBreathMax ); swprintf( pStr, TacticalStr[ DRIVER_POPUPTEXT ], pVehicle->stats.bLife, pVehicle->stats.bLifeMax, pVehicle->bBreath, pVehicle->bBreathMax );
@@ -5157,7 +5177,7 @@ void UpdateTEAMPanel( )
DisableButton( iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ); DisableButton( iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] );
// OK, disable item regions....... // OK, disable item regions.......
for ( cnt = 0; cnt < 6; cnt++ ) for ( cnt = 0; cnt < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt++ )
{ {
MSYS_DisableRegion( &gTEAM_EnemyIndicator[ cnt ] ); MSYS_DisableRegion( &gTEAM_EnemyIndicator[ cnt ] );
@@ -5178,7 +5198,7 @@ void UpdateTEAMPanel( )
{ {
EnableButton( iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] ); EnableButton( iTEAMPanelButtons[ CHANGE_SQUAD_BUTTON ] );
for ( cnt = 0; cnt < 6; cnt++ ) for ( cnt = 0; cnt < NUMBER_OF_SOLDIERS_PER_SQUAD; cnt++ )
{ {
MSYS_EnableRegion( &gTEAM_EnemyIndicator[ cnt ] ); MSYS_EnableRegion( &gTEAM_EnemyIndicator[ cnt ] );
@@ -6918,7 +6938,7 @@ void ConfirmationToDepositMoneyToPlayersAccount( UINT8 ubExitValue )
if ( ubExitValue == MSG_BOX_RETURN_YES ) if ( ubExitValue == MSG_BOX_RETURN_YES )
{ {
//add the money to the players account //add the money to the players account
AddTransactionToPlayersBook( MERC_DEPOSITED_MONEY_TO_PLAYER_ACCOUNT, gpSMCurrentMerc->ubProfile, GetWorldTotalMin(), (*gpItemPointer)[0]->data.money.uiMoneyAmount ); AddTransactionToPlayersBook( MERC_DEPOSITED_MONEY_TO_PLAYER_ACCOUNT, gpSMCurrentMerc->ubProfile, GetWorldTotalMin(), (*gpItemPointer)[0]->data.money.uiMoneyAmount);
// dirty shopkeeper // dirty shopkeeper
gubSkiDirtyLevel = SKI_DIRTY_LEVEL2; gubSkiDirtyLevel = SKI_DIRTY_LEVEL2;
+21 -16
View File
@@ -49,21 +49,23 @@ UINT16 itemRPG;
UINT32 guiMortarsRolledByTeam = 0; UINT32 guiMortarsRolledByTeam = 0;
//
// WDS note 08/06/2008: This is no longer used
// ARMY_GUN_CHOICE_TYPE gRegularArmyGunChoices[ARMY_GUN_LEVELS] =
// { // INDEX CLASS #CHOICES
// { /* 0 - lo pistols */ 2, SW38, DESERTEAGLE, -1, -1, -1 },
// { /* 1 - hi pistols */ 2, GLOCK_17, BERETTA_93R, -1, -1, -1 },
// { /* 2 - lo SMG/shotgun */ 2, M870, MP5K, -1, -1, -1 },
// { /* 3 - lo rifles */ 1, MINI14, -1, -1, -1, -1 },
// { /* 4 - hi SMGs */ 2, MAC10, COMMANDO, -1, -1, -1 },
// { /* 5 - med rifles */ 1, G41, -1, -1, -1, -1 },
// { /* 6 - sniper rifles */ 1, M24, -1, -1, -1, -1 },
// { /* 7 - hi rifles */ 2, M14, C7, -1, -1, -1 },
// { /* 8 - best rifle */ 1, FNFAL, -1, -1, -1, -1 },
// { /* 9 - machine guns */ 1, MINIMI, -1, -1, -1, -1 },
// { /* 10- rocket rifle */ 2, ROCKET_RIFLE, MINIMI, -1, -1, -1 },
// };
ARMY_GUN_CHOICE_TYPE gRegularArmyGunChoices[ARMY_GUN_LEVELS] =
{ // INDEX CLASS #CHOICES
{ /* 0 - lo pistols */ 2, SW38, DESERTEAGLE, -1, -1, -1 },
{ /* 1 - hi pistols */ 2, GLOCK_17, BERETTA_93R, -1, -1, -1 },
{ /* 2 - lo SMG/shotgun */ 2, M870, MP5K, -1, -1, -1 },
{ /* 3 - lo rifles */ 1, MINI14, -1, -1, -1, -1 },
{ /* 4 - hi SMGs */ 2, MAC10, COMMANDO, -1, -1, -1 },
{ /* 5 - med rifles */ 1, G41, -1, -1, -1, -1 },
{ /* 6 - sniper rifles */ 1, M24, -1, -1, -1, -1 },
{ /* 7 - hi rifles */ 2, M14, C7, -1, -1, -1 },
{ /* 8 - best rifle */ 1, FNFAL, -1, -1, -1, -1 },
{ /* 9 - machine guns */ 1, MINIMI, -1, -1, -1, -1 },
{ /* 10- rocket rifle */ 2, ROCKET_RIFLE, MINIMI, -1, -1, -1 },
};
ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[ARMY_GUN_LEVELS];// = ARMY_GUN_CHOICE_TYPE gExtendedArmyGunChoices[ARMY_GUN_LEVELS];// =
//{ // INDEX CLASS #CHOICES //{ // INDEX CLASS #CHOICES
@@ -3145,7 +3147,10 @@ UINT16 PickARandomItem(UINT8 typeIndex, UINT8 maxCoolness, BOOLEAN getMatchingCo
} }
// couldn't find anything with the exact matching coolness, so return the best item we did find // couldn't find anything with the exact matching coolness, so return the best item we did find
return defaultItem; if (ItemIsLegal(defaultItem))
return defaultItem;
else
return 0;
} }
UINT16 PickARandomAttachment(UINT8 typeIndex, UINT16 usBaseItem, UINT8 maxCoolness, BOOLEAN getMatchingCoolness) UINT16 PickARandomAttachment(UINT8 typeIndex, UINT16 usBaseItem, UINT8 maxCoolness, BOOLEAN getMatchingCoolness)
{ {
@@ -3187,7 +3192,7 @@ UINT16 PickARandomAttachment(UINT8 typeIndex, UINT16 usBaseItem, UINT8 maxCoolne
// couldn't find anything with the exact matching coolness, so return the best item we did find // couldn't find anything with the exact matching coolness, so return the best item we did find
// DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("PickARandomAttachment: baseItem = %d, defaultItem = %d",usBaseItem, defaultItem)); // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("PickARandomAttachment: baseItem = %d, defaultItem = %d",usBaseItem, defaultItem));
if (ItemIsLegal(usItem)) if (ItemIsLegal(defaultItem))
return defaultItem; return defaultItem;
else else
return 0; return 0;
+25 -10
View File
@@ -8416,39 +8416,54 @@ UINT16 GetFirstExplosiveOfType(UINT16 expType)
return 0; return 0;
} }
OBJECTTYPE* FindSunGogglesInInv( SOLDIERTYPE * pSoldier ) // WDS - Smart goggle switching
OBJECTTYPE* FindSunGogglesInInv( SOLDIERTYPE * pSoldier, BOOLEAN searchAllInventory )
{ {
INT8 bLoop; INT8 bLoop;
INT16 bonusToBeat = 0; INT16 bonusToBeat = 0;
OBJECTTYPE* pGoggles = 0; OBJECTTYPE* pGoggles = 0;
// CHRISL: // CHRISL:
for (bLoop = HANDPOS; bLoop < NUM_INV_SLOTS; bLoop++) for (bLoop = (searchAllInventory ? HELMETPOS : HANDPOS); bLoop < NUM_INV_SLOTS; bLoop++) {
{
if ( pSoldier->inv[bLoop].exists() == true ) { if ( pSoldier->inv[bLoop].exists() == true ) {
if (Item[pSoldier->inv[bLoop].usItem].brightlightvisionrangebonus > bonusToBeat && Item[pSoldier->inv[bLoop].usItem].usItemClass == IC_FACE ) if (Item[pSoldier->inv[bLoop].usItem].brightlightvisionrangebonus > bonusToBeat && Item[pSoldier->inv[bLoop].usItem].usItemClass == IC_FACE ) {
{
pGoggles = &(pSoldier->inv[bLoop]); pGoggles = &(pSoldier->inv[bLoop]);
bonusToBeat = Item[pSoldier->inv[bLoop].usItem].brightlightvisionrangebonus; bonusToBeat = Item[pSoldier->inv[bLoop].usItem].brightlightvisionrangebonus;
} }
if (searchAllInventory) {
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bonusToBeat && Item[ iter->usItem ].usItemClass == IC_FACE ) {
pGoggles = &(*iter);
bonusToBeat = Item[ iter->usItem ].brightlightvisionrangebonus;
}
}
}
} }
} }
return( pGoggles ); return( pGoggles );
} }
OBJECTTYPE* FindNightGogglesInInv( SOLDIERTYPE * pSoldier ) OBJECTTYPE* FindNightGogglesInInv( SOLDIERTYPE * pSoldier, BOOLEAN searchAllInventory )
{ {
INT8 bLoop; INT8 bLoop;
INT16 bonusToBeat = 0; INT16 bonusToBeat = 0;
OBJECTTYPE* pGoggles = 0; OBJECTTYPE* pGoggles = 0;
// CHRISL: // CHRISL:
for (bLoop = HANDPOS; bLoop < NUM_INV_SLOTS; bLoop++) for (bLoop = (searchAllInventory ? HELMETPOS : HANDPOS); bLoop < NUM_INV_SLOTS; bLoop++) {
{
if ( pSoldier->inv[bLoop].exists() == true ) { if ( pSoldier->inv[bLoop].exists() == true ) {
if (Item[pSoldier->inv[bLoop].usItem].nightvisionrangebonus > bonusToBeat && Item[pSoldier->inv[bLoop].usItem].usItemClass == IC_FACE ) if (Item[pSoldier->inv[bLoop].usItem].nightvisionrangebonus > bonusToBeat && Item[pSoldier->inv[bLoop].usItem].usItemClass == IC_FACE ) {
{
pGoggles = &(pSoldier->inv[bLoop]); pGoggles = &(pSoldier->inv[bLoop]);
bonusToBeat = Item[pSoldier->inv[bLoop].usItem].nightvisionrangebonus; bonusToBeat = Item[pSoldier->inv[bLoop].usItem].nightvisionrangebonus;
} }
if (searchAllInventory) {
OBJECTTYPE* pObj = &(pSoldier->inv[bLoop]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
if ( Item[ iter->usItem ].nightvisionrangebonus > bonusToBeat && Item[ iter->usItem ].usItemClass == IC_FACE ) {
pGoggles = &(*iter);
bonusToBeat = Item[ iter->usItem ].nightvisionrangebonus;
}
}
}
} }
} }
return( pGoggles ); return( pGoggles );
+3 -2
View File
@@ -281,6 +281,7 @@ INT8 FindRocketLauncherOrCannon( SOLDIERTYPE * pSoldier );
INT8 FindNonSmokeLaunchable( SOLDIERTYPE * pSoldier, UINT16 usWeapon ); INT8 FindNonSmokeLaunchable( SOLDIERTYPE * pSoldier, UINT16 usWeapon );
OBJECTTYPE* FindNonSmokeLaunchableAttachment( OBJECTTYPE * pObj, UINT16 usWeapon ); OBJECTTYPE* FindNonSmokeLaunchableAttachment( OBJECTTYPE * pObj, UINT16 usWeapon );
UINT16 PickARandomLaunchable(UINT16 itemIndex); UINT16 PickARandomLaunchable(UINT16 itemIndex);
bool BadGoggles(SOLDIERTYPE *pTeamSoldier);
BOOLEAN IsFlashSuppressor( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier ); BOOLEAN IsFlashSuppressor( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier );
// HEADROCK: Declaration of new function to detect flash suppression without SOLDIERTYPE argument // HEADROCK: Declaration of new function to detect flash suppression without SOLDIERTYPE argument
@@ -329,8 +330,8 @@ INT16 GetAPBonus( OBJECTTYPE * pObj );
UINT16 GetFirstExplosiveOfType(UINT16 expType); UINT16 GetFirstExplosiveOfType(UINT16 expType);
OBJECTTYPE* FindSunGogglesInInv( SOLDIERTYPE * pSoldier ); OBJECTTYPE* FindSunGogglesInInv( SOLDIERTYPE * pSoldier, BOOLEAN searchAllInventory = FALSE );
OBJECTTYPE* FindNightGogglesInInv( SOLDIERTYPE * pSoldier ); OBJECTTYPE* FindNightGogglesInInv( SOLDIERTYPE * pSoldier, BOOLEAN searchAllInventory = FALSE );
INT16 GetMinRangeForAimBonus( OBJECTTYPE * pObj ); INT16 GetMinRangeForAimBonus( OBJECTTYPE * pObj );
UINT8 AllowedAimingLevels(SOLDIERTYPE * pSoldier); UINT8 AllowedAimingLevels(SOLDIERTYPE * pSoldier);
+6 -6
View File
@@ -164,7 +164,7 @@ BOOLEAN SoldierHasKey( SOLDIERTYPE *pSoldier, UINT8 ubKeyID )
BOOLEAN KeyExistsInKeyRing( SOLDIERTYPE *pSoldier, UINT8 ubKeyID, UINT8 * pubPos ) BOOLEAN KeyExistsInKeyRing( SOLDIERTYPE *pSoldier, UINT8 ubKeyID, UINT8 * pubPos )
{ {
// returns the index into the key ring where the key can be found // returns the index into the key ring where the key can be found
UINT8 ubLoop; UINT8 ubLoop;
if (!(pSoldier->pKeyRing)) if (!(pSoldier->pKeyRing))
{ {
@@ -193,7 +193,7 @@ BOOLEAN KeyExistsInKeyRing( SOLDIERTYPE *pSoldier, UINT8 ubKeyID, UINT8 * pubPos
BOOLEAN KeyExistsInInventory( SOLDIERTYPE *pSoldier, UINT8 ubKeyID ) BOOLEAN KeyExistsInInventory( SOLDIERTYPE *pSoldier, UINT8 ubKeyID )
{ {
UINT8 ubLoop; UINT8 ubLoop;
for (ubLoop = 0; ubLoop < pSoldier->inv.size(); ubLoop++) for (ubLoop = 0; ubLoop < pSoldier->inv.size(); ubLoop++)
{ {
@@ -250,7 +250,7 @@ BOOLEAN DoUnlockDoor( DOOR * pDoor, UINT8 ubKeyID )
BOOLEAN AttemptToUnlockDoor( SOLDIERTYPE * pSoldier, DOOR * pDoor ) BOOLEAN AttemptToUnlockDoor( SOLDIERTYPE * pSoldier, DOOR * pDoor )
{ {
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubKeyID; UINT8 ubKeyID;
for( ubLoop = 0; ubLoop < MAX_KEYS_PER_LOCK; ubLoop++) for( ubLoop = 0; ubLoop < MAX_KEYS_PER_LOCK; ubLoop++)
@@ -278,7 +278,7 @@ BOOLEAN AttemptToUnlockDoor( SOLDIERTYPE * pSoldier, DOOR * pDoor )
BOOLEAN AttemptToLockDoor( SOLDIERTYPE * pSoldier, DOOR * pDoor ) BOOLEAN AttemptToLockDoor( SOLDIERTYPE * pSoldier, DOOR * pDoor )
{ {
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubKeyID; UINT8 ubKeyID;
for( ubLoop = 0; ubLoop < MAX_KEYS_PER_LOCK; ubLoop++) for( ubLoop = 0; ubLoop < MAX_KEYS_PER_LOCK; ubLoop++)
@@ -1866,7 +1866,7 @@ BOOLEAN LoadDoorStatusArrayFromDoorStatusTempFile()
CHAR8 zMapName[ 128 ]; CHAR8 zMapName[ 128 ];
HWFILE hFile; HWFILE hFile;
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
UINT8 ubLoop; UINT8 ubLoop;
//Convert the current sector location into a file name //Convert the current sector location into a file name
// GetMapFileName( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, zTempName, FALSE ); // GetMapFileName( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, zTempName, FALSE );
@@ -2111,7 +2111,7 @@ void DropKeysInKeyRing( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT8 bLevel, INT8
// no key ring! // no key ring!
return; return;
} }
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubItem; UINT8 ubItem;
for (ubLoop = 0; ubLoop < NUM_KEYS; ubLoop++) for (ubLoop = 0; ubLoop < NUM_KEYS; ubLoop++)
{ {
+1 -1
View File
@@ -3601,7 +3601,7 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA
INT32 iDistance; INT32 iDistance;
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubShots; UINT8 ubShots;
UINT8 ubImpact; UINT8 ubImpact;
INT8 bCTGT; INT8 bCTGT;
+9 -5
View File
@@ -38,6 +38,7 @@
#include "ai.h" #include "ai.h"
#include "Dialogue Control.h" #include "Dialogue Control.h"
#include "Music Control.h" #include "Music Control.h"
#include "Tactical Save.h"
#endif #endif
@@ -45,7 +46,8 @@
class OBJECTTYPE; class OBJECTTYPE;
class SOLDIERTYPE; class SOLDIERTYPE;
#define MAX_MERC_IN_HELI 20 // WDS - make number of mercenaries, etc. be configurable
#define MAX_MERC_IN_HELI CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS
#define MAX_HELI_SCRIPT 30 #define MAX_HELI_SCRIPT 30
#define ME_SCRIPT_DELAY 100 #define ME_SCRIPT_DELAY 100
#define NUM_PER_HELI_RUN 6 #define NUM_PER_HELI_RUN 6
@@ -474,7 +476,7 @@ void HandleHeliDrop( )
{ {
// Add merc to sector // Add merc to sector
MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH; MercPtrs[ gusHeliSeats[ cnt ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
UpdateMercInSector( MercPtrs[ gusHeliSeats[ cnt ] ], 9, 1, 0 ); UpdateMercInSector( MercPtrs[ gusHeliSeats[ cnt ] ], startingX, startingY, startingZ );
// Check for merc arrives quotes... // Check for merc arrives quotes...
HandleMercArrivesQuotes( MercPtrs[ gusHeliSeats[ cnt ] ] ); HandleMercArrivesQuotes( MercPtrs[ gusHeliSeats[ cnt ] ] );
@@ -610,7 +612,7 @@ void HandleHeliDrop( )
// Change insertion code // Change insertion code
MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH; MercPtrs[ gusHeliSeats[ gbCurDrop ] ]->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
UpdateMercInSector( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], 9, 1, 0 ); UpdateMercInSector( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], startingX, startingY, startingZ );
//EVENT_SetSoldierPosition( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], sWorldX, sWorldY ); //EVENT_SetSoldierPosition( MercPtrs[ gusHeliSeats[ gbCurDrop ] ], sWorldX, sWorldY );
// IF the first guy down, set squad! // IF the first guy down, set squad!
@@ -809,6 +811,9 @@ void HandleFirstHeliDropOfGame( )
// Call people to area // Call people to area
CallAvailableEnemiesTo( gsGridNoSweetSpot ); CallAvailableEnemiesTo( gsGridNoSweetSpot );
// Move to header file...
AddExtraItems( startingX, startingY, startingZ, true );
// Say quote..... // Say quote.....
SayQuoteFromAnyBodyInSector( QUOTE_ENEMY_PRESENCE ); SayQuoteFromAnyBodyInSector( QUOTE_ENEMY_PRESENCE );
@@ -820,8 +825,7 @@ void HandleFirstHeliDropOfGame( )
} }
// Send message to turn on ai again.... // Send message to turn on ai again....
CharacterDialogueWithSpecialEvent( 0, 0, 0 , DIALOGUE_TACTICAL_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_ENABLE_AI ,0, 0 ); CharacterDialogueWithSpecialEvent( 0, 0, 0, DIALOGUE_TACTICAL_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_ENABLE_AI ,0, 0 );
} }
+37 -32
View File
@@ -102,8 +102,8 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
if( ( pMerc->bMercStatus != 0 ) && (pMerc->bMercStatus != MERC_ANNOYED_BUT_CAN_STILL_CONTACT ) && ( pMerc->bMercStatus != MERC_HIRED_BUT_NOT_ARRIVED_YET ) ) if( ( pMerc->bMercStatus != 0 ) && (pMerc->bMercStatus != MERC_ANNOYED_BUT_CAN_STILL_CONTACT ) && ( pMerc->bMercStatus != MERC_HIRED_BUT_NOT_ARRIVED_YET ) )
return( MERC_HIRE_FAILED ); return( MERC_HIRE_FAILED );
if( NumberOfMercsOnPlayerTeam() >= 18 || (is_client && NumberOfMercsOnPlayerTeam() >= MAX_MERCS)) //hayden, 7 member team limit setable in ini if( NumberOfMercsOnPlayerTeam() >= gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs )
return( MERC_HIRE_OVER_18_MERCS_HIRED ); return( MERC_HIRE_OVER_PLAYER_LIMIT );
// ATE: if we are to use landing zone, update to latest value // ATE: if we are to use landing zone, update to latest value
// they will be updated again just before arrival... // they will be updated again just before arrival...
@@ -197,21 +197,21 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
if (!is_networked) if (!is_networked)
{ {
if( DidGameJustStart() ) if( DidGameJustStart() )
{ {
pHireMerc->uiTimeTillMercArrives = ( gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay ) / NUM_SEC_IN_MIN; pHireMerc->uiTimeTillMercArrives = ( gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay ) / NUM_SEC_IN_MIN;
// Set insertion for first time in chopper // Set insertion for first time in chopper
pHireMerc->ubInsertionCode = INSERTION_CODE_CHOPPER; pHireMerc->ubInsertionCode = INSERTION_CODE_CHOPPER;
//set when the merc's contract is finished //set when the merc's contract is finished
pSoldier->iEndofContractTime = GetMidnightOfFutureDayInMinutes( pSoldier->iTotalContractLength ) + ( GetHourWhenContractDone( pSoldier ) * 60 ); pSoldier->iEndofContractTime = GetMidnightOfFutureDayInMinutes( pSoldier->iTotalContractLength ) + ( GetHourWhenContractDone( pSoldier ) * 60 );
} }
else else
{ {
//set when the merc's contract is finished ( + 1 cause it takes a day for the merc to arrive ) //set when the merc's contract is finished ( + 1 cause it takes a day for the merc to arrive )
pSoldier->iEndofContractTime = GetMidnightOfFutureDayInMinutes( 1 + pSoldier->iTotalContractLength ) + ( GetHourWhenContractDone( pSoldier ) * 60 ); pSoldier->iEndofContractTime = GetMidnightOfFutureDayInMinutes( 1 + pSoldier->iTotalContractLength ) + ( GetHourWhenContractDone( pSoldier ) * 60 );
} }
} }
// WANNE - MP: We need this, so the merc contract is correct! // WANNE - MP: We need this, so the merc contract is correct!
else else
@@ -225,15 +225,15 @@ INT8 HireMerc( MERC_HIRE_STRUCT *pHireMerc)
if (!is_client) if (!is_client)
{ {
//if we are trying to hire a merc that should arrive later, put the merc in the queue //if we are trying to hire a merc that should arrive later, put the merc in the queue
if( pHireMerc->uiTimeTillMercArrives != 0 ) if( pHireMerc->uiTimeTillMercArrives != 0 )
{ {
AddStrategicEvent( EVENT_DELAYED_HIRING_OF_MERC, pHireMerc->uiTimeTillMercArrives, pSoldier->ubID ); AddStrategicEvent( EVENT_DELAYED_HIRING_OF_MERC, pHireMerc->uiTimeTillMercArrives, pSoldier->ubID );
//specify that the merc is hired but hasnt arrived yet //specify that the merc is hired but hasnt arrived yet
pMerc->bMercStatus = MERC_HIRED_BUT_NOT_ARRIVED_YET; pMerc->bMercStatus = MERC_HIRED_BUT_NOT_ARRIVED_YET;
} }
} }
else else
{ {
@@ -315,17 +315,17 @@ void MercArrivesCallback( UINT8 ubSoldierID )
if (!is_networked) if (!is_networked)
{ {
// hayden - maybe you want to duke it out in omerta ;) // hayden - maybe you want to duke it out in omerta ;)
if( !DidGameJustStart() && gsMercArriveSectorX == 9 && gsMercArriveSectorY == 1 ) if( !DidGameJustStart() && gsMercArriveSectorX == 9 && gsMercArriveSectorY == 1 )
{ {
//Mercs arriving in A9. This sector has been deemed as the always safe sector. //Mercs arriving in A9. This sector has been deemed as the always safe sector.
//Seeing we don't support entry into a hostile sector (except for the beginning), //Seeing we don't support entry into a hostile sector (except for the beginning),
//we will nuke any enemies in this sector first. //we will nuke any enemies in this sector first.
if( gWorldSectorX != 9 || gWorldSectorY != 1 || gbWorldSectorZ ) if( gWorldSectorX != 9 || gWorldSectorY != 1 || gbWorldSectorZ )
{ {
EliminateAllEnemies( (UINT8)gsMercArriveSectorX, (UINT8)gsMercArriveSectorY ); EliminateAllEnemies( (UINT8)gsMercArriveSectorX, (UINT8)gsMercArriveSectorY );
}
} }
} }
}
// This will update ANY soldiers currently schedules to arrive too // This will update ANY soldiers currently schedules to arrive too
CheckForValidArrivalSector( ); CheckForValidArrivalSector( );
@@ -471,17 +471,22 @@ BOOLEAN IsTheSoldierAliveAndConcious( SOLDIERTYPE *pSoldier )
UINT8 NumberOfMercsOnPlayerTeam() UINT8 NumberOfMercsOnPlayerTeam()
{ {
INT8 cnt; INT8 cnt;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
INT16 bLastTeamID; INT16 bLastTeamID;
UINT8 ubCount=0; UINT8 ubCount=0;
// Set locator to first merc // Set locator to first merc
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID; bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
if (! MercPtrs[cnt])
return 0;
for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++) for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++)
{ {
AssertNotNIL(pSoldier);
//if the is active, and is not a vehicle //if the is active, and is not a vehicle
if( pSoldier->bActive && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) ) if( pSoldier->bActive && !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
{ {
+2 -1
View File
@@ -7,7 +7,8 @@
// //
// Used with the HireMerc function // Used with the HireMerc function
// //
#define MERC_HIRE_OVER_18_MERCS_HIRED -1 // WDS - make number of mercenaries, etc. be configurable
#define MERC_HIRE_OVER_PLAYER_LIMIT -1
#define MERC_HIRE_FAILED 0 #define MERC_HIRE_FAILED 0
#define MERC_HIRE_OK 1 #define MERC_HIRE_OK 1
-1
View File
@@ -167,7 +167,6 @@ void ResetMilitia()
// a flag for autoresolve if different initialization or destruction is desired. // a flag for autoresolve if different initialization or destruction is desired.
guiCurrentScreen = GAME_SCREEN; guiCurrentScreen = GAME_SCREEN;
RemoveMilitiaFromTactical(); RemoveMilitiaFromTactical();
ubNumGreen = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, GREEN_MILITIA); ubNumGreen = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, GREEN_MILITIA);
ubNumReg = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, REGULAR_MILITIA); ubNumReg = MilitiaInSectorOfRank(gWorldSectorX, gWorldSectorY, REGULAR_MILITIA);
+3 -3
View File
@@ -151,7 +151,7 @@ void DecayStrategicMorale( SOLDIERTYPE * pSoldier )
void DecayTacticalMoraleModifiers( void ) void DecayTacticalMoraleModifiers( void )
{ {
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
UINT8 ubLoop, ubLoop2; UINT8 ubLoop, ubLoop2;
BOOLEAN fHandleNervous; BOOLEAN fHandleNervous;
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
@@ -251,7 +251,7 @@ void DecayTacticalMoraleModifiers( void )
void DecayStrategicMoraleModifiers( void ) void DecayStrategicMoraleModifiers( void )
{ {
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
UINT8 ubLoop; UINT8 ubLoop;
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
for ( pSoldier = MercPtrs[ ubLoop ]; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop++, pSoldier++ ) for ( pSoldier = MercPtrs[ ubLoop ]; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop++, pSoldier++ )
@@ -444,7 +444,7 @@ void HandleMoraleEventForSoldier( SOLDIERTYPE * pSoldier, INT8 bMoraleEvent )
void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, INT16 sMapY, INT8 bMapZ ) void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{ {
UINT8 ubLoop; UINT8 ubLoop;
SOLDIERTYPE * pTeamSoldier; SOLDIERTYPE * pTeamSoldier;
MERCPROFILESTRUCT * pProfile; MERCPROFILESTRUCT * pProfile;
+41 -2
View File
@@ -25,7 +25,7 @@
#define MAXTEAMS_SP 6 // WANNE: for singleplayer #define MAXTEAMS_SP 6 // WANNE: for singleplayer
#define MAXTEAMS 11 //hayden #define MAXTEAMS 11 //hayden
#define MAXMERCS MAX_NUM_SOLDIERS #define MAXMERCS MAX_NUM_SOLDIERS
//TACTICAL OVERHEAD STUFF //TACTICAL OVERHEAD STUFF
//#define NO_SOLDIER TOTAL_SOLDIERS // SAME AS NOBODY //#define NO_SOLDIER TOTAL_SOLDIERS // SAME AS NOBODY
@@ -264,11 +264,50 @@ enum WorldDirections
}; };
// Starting Sector
const int startingX = 9;
const int startingY = 1;
const int startingZ = 0;
// ENUMERATION OF SOLDIER POSIITONS IN GLOBAL SOLDIER LIST // ENUMERATION OF SOLDIER POSIITONS IN GLOBAL SOLDIER LIST
#define MAX_NUM_SOLDIERS 148 // WDS - make number of mercenaries, etc. be configurable
#define CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS 32
#define CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES 6
#define CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES
#define CODE_MAXIMUM_NUMBER_OF_ENEMIES 64
#define CODE_MAXIMUM_NUMBER_OF_CREATURES 40
#define CODE_MAXIMUM_NUMBER_OF_REBELS 64
#define CODE_MAXIMUM_NUMBER_OF_CIVS 40
// The following should be the largest from the above set of constants.
// Note: Is there any way to compute this via the preprocessor?
#define LARGEST_NUMBER_IN_ANY_GROUP 64
#define MAX_NUM_SOLDIERS (CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES+CODE_MAXIMUM_NUMBER_OF_CREATURES+CODE_MAXIMUM_NUMBER_OF_REBELS+CODE_MAXIMUM_NUMBER_OF_CIVS)
#define NUM_PLANNING_MERCS 8 #define NUM_PLANNING_MERCS 8
#define TOTAL_SOLDIERS ( NUM_PLANNING_MERCS + MAX_NUM_SOLDIERS ) #define TOTAL_SOLDIERS ( NUM_PLANNING_MERCS + MAX_NUM_SOLDIERS )
// If there are more than (one less the size of the field used to store IDs (currently a char)) then fail
#if TOTAL_SOLDIERS > 254
#error Too many!
#endif
#if CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS > LARGEST_NUMBER_IN_ANY_GROUP
#error _LARGEST_NUMBER_IN_ANY_GROUP is too small
#endif
#if CODE_MAXIMUM_NUMBER_OF_ENEMIES > LARGEST_NUMBER_IN_ANY_GROUP
#error _LARGEST_NUMBER_IN_ANY_GROUP is too small
#endif
#if CODE_MAXIMUM_NUMBER_OF_CREATURES > LARGEST_NUMBER_IN_ANY_GROUP
#error _LARGEST_NUMBER_IN_ANY_GROUP is too small
#endif
#if CODE_MAXIMUM_NUMBER_OF_REBELS > LARGEST_NUMBER_IN_ANY_GROUP
#error _LARGEST_NUMBER_IN_ANY_GROUP is too small
#endif
#if CODE_MAXIMUM_NUMBER_OF_CIVS > LARGEST_NUMBER_IN_ANY_GROUP
#error _LARGEST_NUMBER_IN_ANY_GROUP is too small
#endif
// DEFINE TEAMS // DEFINE TEAMS
#define OUR_TEAM 0 #define OUR_TEAM 0
#define ENEMY_TEAM 1 #define ENEMY_TEAM 1
+70 -20
View File
@@ -142,6 +142,7 @@ INT32 giPauseAllAITimer = 0;
BOOLEAN sniperwarning; BOOLEAN sniperwarning;
BOOLEAN biggunwarning; BOOLEAN biggunwarning;
BOOLEAN gogglewarning;
//BOOLEAN airstrikeavailable; //BOOLEAN airstrikeavailable;
TacticalStatusType gTacticalStatus; TacticalStatusType gTacticalStatus;
@@ -326,7 +327,7 @@ CHAR8 gzDirectionStr[][ 30 ] =
"NORTH" "NORTH"
}; };
// TEMP VALUES FOR TEAM DEAFULT POSITIONS // TEMP VALUES FOR TEAM DEFAULT POSITIONS
UINT8 bDefaultTeamRangesMP[ MAXTEAMS ][ 2 ] = UINT8 bDefaultTeamRangesMP[ MAXTEAMS ][ 2 ] =
{ {
@@ -345,12 +346,18 @@ UINT8 bDefaultTeamRangesMP[ MAXTEAMS ][ 2 ] =
UINT8 bDefaultTeamRanges[ MAXTEAMS_SP ][ 2 ] = UINT8 bDefaultTeamRanges[ MAXTEAMS_SP ][ 2 ] =
{ {
0, 19, //20 US 0,
20, 51, //32 ENEMY CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES-1,
52, 83, //32 CREATURE CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES,
84, 115, //32 REBELS ( OUR GUYS ) CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES-1,
116, MAX_NUM_SOLDIERS - 1, //32 CIVILIANS CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES,
MAX_NUM_SOLDIERS, TOTAL_SOLDIERS - 1 // PLANNING SOLDIERS CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES+CODE_MAXIMUM_NUMBER_OF_CREATURES-1,
CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES+CODE_MAXIMUM_NUMBER_OF_CREATURES,
CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES+CODE_MAXIMUM_NUMBER_OF_CREATURES+CODE_MAXIMUM_NUMBER_OF_REBELS-1,
CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS+CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES+CODE_MAXIMUM_NUMBER_OF_ENEMIES+CODE_MAXIMUM_NUMBER_OF_CREATURES+CODE_MAXIMUM_NUMBER_OF_REBELS,
MAX_NUM_SOLDIERS -1,
MAX_NUM_SOLDIERS,
TOTAL_SOLDIERS - 1 // PLANNING SOLDIERS
}; };
COLORVAL bDefaultTeamColors[ MAXTEAMS ] = COLORVAL bDefaultTeamColors[ MAXTEAMS ] =
@@ -669,6 +676,36 @@ BOOLEAN InitOverhead( )
gTacticalStatus.Team[ cnt ].bFirstID = bDefaultTeamRangesMP[ cnt ][0]; gTacticalStatus.Team[ cnt ].bFirstID = bDefaultTeamRangesMP[ cnt ][0];
gTacticalStatus.Team[ cnt ].bLastID = bDefaultTeamRangesMP[ cnt ][1]; gTacticalStatus.Team[ cnt ].bLastID = bDefaultTeamRangesMP[ cnt ][1];
} }
// WDS - make number of mercenaries, etc. be configurable
unsigned max = 0;
switch (cnt) {
case OUR_TEAM:
max = gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs + gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles;
break;
case ENEMY_TEAM:
max = gGameExternalOptions.ubGameMaximumNumberOfEnemies;
break;
case CREATURE_TEAM:
max = gGameExternalOptions.ubGameMaximumNumberOfCreatures;
break;
case MILITIA_TEAM:
max = gGameExternalOptions.ubGameMaximumNumberOfRebels;
break;
case CIV_TEAM:
max = gGameExternalOptions.ubGameMaximumNumberOfCivilians;
break;
// Don't worry about the others
case PLAYER_PLAN:
case LAN_TEAM_ONE:
case LAN_TEAM_TWO:
case LAN_TEAM_THREE:
case LAN_TEAM_FOUR:
max = 9999;
break;
}
if (max < (unsigned)(gTacticalStatus.Team[ cnt ].bLastID - gTacticalStatus.Team[ cnt ].bFirstID + 1)) {
gTacticalStatus.Team[ cnt ].bLastID = gTacticalStatus.Team[ cnt ].bFirstID + max - 1;
}
gTacticalStatus.Team[ cnt ].RadarColor = bDefaultTeamColors[ cnt ]; gTacticalStatus.Team[ cnt ].RadarColor = bDefaultTeamColors[ cnt ];
@@ -727,7 +764,7 @@ BOOLEAN InitOverhead( )
if (is_networked) if (is_networked)
gTacticalStatus.fDidGameJustStart = FALSE; //hayden gTacticalStatus.fDidGameJustStart = FALSE; //hayden
else else
gTacticalStatus.fDidGameJustStart = TRUE; gTacticalStatus.fDidGameJustStart = TRUE;
gTacticalStatus.ubLastRequesterTargetID = NO_PROFILE; gTacticalStatus.ubLastRequesterTargetID = NO_PROFILE;
@@ -986,6 +1023,13 @@ BOOLEAN ExecuteOverhead( )
{ {
pSoldier = MercSlots[ cnt ]; pSoldier = MercSlots[ cnt ];
if ( pSoldier && pSoldier->bActive && (pSoldier->bTeam == OUR_TEAM) ) {
if (!gogglewarning && BadGoggles(pSoldier)) {
gogglewarning = TRUE;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_CHECK_GOGGLES] );
}
}
// Syncronize for upcoming soldier counters // Syncronize for upcoming soldier counters
SYNCTIMECOUNTER( ); SYNCTIMECOUNTER( );
@@ -4015,7 +4059,7 @@ void MilitiaChangesSides( void )
/* /*
void MakePotentiallyHostileCivGroupsHostile( void ) void MakePotentiallyHostileCivGroupsHostile( void )
{ {
UINT8 ubLoop; UINT8 ubLoop;
// loop through all civ groups that might become hostile and set them // loop through all civ groups that might become hostile and set them
// to hostile // to hostile
@@ -5651,11 +5695,11 @@ void EnterCombatMode( UINT8 ubStartingTeam )
if (!is_client || is_server) //hayden if (!is_client || is_server) //hayden
{ {
StartPlayerTeamTurn( FALSE, TRUE ); StartPlayerTeamTurn( FALSE, TRUE );
if(is_client)send_EndTurn( ubStartingTeam ); //hayden if(is_client)send_EndTurn( ubStartingTeam ); //hayden
} }
else else
{ {
//ScreenMsg( FONT_YELLOW, MSG_CHAT, L"client skipped EnterCombatMode"); //ScreenMsg( FONT_YELLOW, MSG_CHAT, L"client skipped EnterCombatMode");
if(is_client)startCombat(ubStartingTeam);//clients other than server meet and send request for combat for server if(is_client)startCombat(ubStartingTeam);//clients other than server meet and send request for combat for server
} }
@@ -5775,6 +5819,7 @@ void SetEnemyPresence( )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = false")); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = false"));
sniperwarning = FALSE; sniperwarning = FALSE;
biggunwarning = FALSE; biggunwarning = FALSE;
gogglewarning = FALSE;
// airstrikeavailable = TRUE; // airstrikeavailable = TRUE;
} }
else else
@@ -5782,6 +5827,7 @@ void SetEnemyPresence( )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = true")); DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("SetEnemyPresence: warnings = true"));
sniperwarning = TRUE; sniperwarning = TRUE;
biggunwarning = TRUE; biggunwarning = TRUE;
//gogglewarning = TRUE;
// airstrikeavailable = FALSE; // airstrikeavailable = FALSE;
} }
@@ -5904,7 +5950,9 @@ BOOLEAN WeSawSomeoneThisTurn( void )
void SayBattleSoundFromAnyBodyInSector( INT32 iBattleSnd ) void SayBattleSoundFromAnyBodyInSector( INT32 iBattleSnd )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
@@ -6615,11 +6663,11 @@ void CycleVisibleEnemies( SOLDIERTYPE *pSrcSoldier )
} }
INT8 CountNonVehiclesOnPlayerTeam( void ) UINT32 CountNonVehiclesOnPlayerTeam( void )
{ {
UINT32 cnt; UINT32 cnt;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
INT8 bNumber = 0; UINT32 bNumber = 0;
for ( cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID, pSoldier = MercPtrs[ cnt ]; cnt <= (UINT32)( gTacticalStatus.Team[ gbPlayerNum ].bLastID ); cnt++, pSoldier++ ) for ( cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID, pSoldier = MercPtrs[ cnt ]; cnt <= (UINT32)( gTacticalStatus.Team[ gbPlayerNum ].bLastID ); cnt++, pSoldier++ )
{ {
@@ -6637,7 +6685,7 @@ INT8 CountNonVehiclesOnPlayerTeam( void )
BOOLEAN PlayerTeamFull( ) BOOLEAN PlayerTeamFull( )
{ {
// last ID for the player team is 19, so long as we have at most 17 non-vehicles... // last ID for the player team is 19, so long as we have at most 17 non-vehicles...
if ( CountNonVehiclesOnPlayerTeam() <= gTacticalStatus.Team[ gbPlayerNum ].bLastID - 2 ) if ( CountNonVehiclesOnPlayerTeam() < gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs /*gTacticalStatus.Team[ gbPlayerNum ].bLastID - 2*/ )
{ {
return( FALSE ); return( FALSE );
} }
@@ -6905,7 +6953,7 @@ BOOLEAN CheckForLosingEndOfBattle( )
{ {
// if here, check if we should autoresolve. // if here, check if we should autoresolve.
// if we have at least one guy unconscious, call below function... // if we have at least one guy unconscious, call below function...
if ( HandlePotentialBringUpAutoresolveToFinishBattle( ) ) if ( HandlePotentialBringUpAutoresolveToFinishBattle( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
{ {
// return false here as we are autoresolving... // return false here as we are autoresolving...
return( FALSE ); return( FALSE );
@@ -7117,7 +7165,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
INT16 sClosestOpponent, sClosestOppLoc; INT16 sClosestOpponent, sClosestOppLoc;
UINT8 ubPointsLost, ubTotalPointsLost, ubNewStance; UINT8 ubPointsLost, ubTotalPointsLost, ubNewStance;
UINT32 uiLoop; UINT32 uiLoop;
UINT8 ubLoop2; UINT8 ubLoop2;
UINT16 uiLoop3; UINT16 uiLoop3;
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
@@ -8419,7 +8467,9 @@ BOOLEAN HostileBloodcatsPresent( void )
void HandleCreatureTenseQuote( ) void HandleCreatureTenseQuote( )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
+7 -4
View File
@@ -45,12 +45,12 @@ typedef struct
UINT8 bFirstID; UINT8 bFirstID;
UINT8 bLastID; UINT8 bLastID;
COLORVAL RadarColor; COLORVAL RadarColor;
INT8 bSide; INT8 bSide;
INT8 bMenInSector; INT8 bMenInSector;
UINT8 ubLastMercToRadio; UINT8 ubLastMercToRadio;
INT8 bTeamActive; INT8 bTeamActive;
INT8 bAwareOfOpposition; INT8 bAwareOfOpposition;
INT8 bHuman; INT8 bHuman;
} TacticalTeamType; } TacticalTeamType;
//for use with TacticalStatusType.ubEnemyIntention //for use with TacticalStatusType.ubEnemyIntention
@@ -223,6 +223,8 @@ BOOLEAN InitOverhead( );
BOOLEAN ShutdownOverhead( ); BOOLEAN ShutdownOverhead( );
BOOLEAN GetSoldier( SOLDIERTYPE **ppSoldier, UINT16 usSoldierIndex ); BOOLEAN GetSoldier( SOLDIERTYPE **ppSoldier, UINT16 usSoldierIndex );
UINT32 CountNonVehiclesOnPlayerTeam( void );
INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeopleToo, INT8 bLevel ); INT16 NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT16 sGridNo, BOOLEAN fPeopleToo, INT8 bLevel );
//Simple check to see if a (one-tiled) soldier can occupy a given location on the ground or roof. //Simple check to see if a (one-tiled) soldier can occupy a given location on the ground or roof.
@@ -361,6 +363,7 @@ void SetSoldierNeutral( SOLDIERTYPE * pSoldier );
extern BOOLEAN sniperwarning; extern BOOLEAN sniperwarning;
extern BOOLEAN biggunwarning; extern BOOLEAN biggunwarning;
extern BOOLEAN gogglewarning;
//extern BOOLEAN airstrikeavailable; //extern BOOLEAN airstrikeavailable;
//void CheckForAndSetupAirRaid (); //void CheckForAndSetupAirRaid ();
+2 -1
View File
@@ -2378,7 +2378,8 @@ INT16 MinAPsToThrow( SOLDIERTYPE *pSoldier, INT16 sGridNo, UINT8 ubAddTurningCos
// make sure the guy's actually got a throwable item in his hand! // make sure the guy's actually got a throwable item in his hand!
usInHand = pSoldier->inv[ HANDPOS ].usItem; usInHand = pSoldier->inv[ HANDPOS ].usItem;
if ( ( !(Item[ usInHand ].usItemClass & IC_GRENADE) ) ) if ( ( !(Item[ usInHand ].usItemClass & IC_GRENADE) &&
!(Item[ usInHand ].usItemClass & IC_LAUNCHER)) )
{ {
//AXP 25.03.2007: See if we are about to throw grenade (grenade was not in hand, but in temp object) //AXP 25.03.2007: See if we are about to throw grenade (grenade was not in hand, but in temp object)
if ( pSoldier->pTempObject != NULL && pSoldier->pThrowParams != NULL && if ( pSoldier->pTempObject != NULL && pSoldier->pThrowParams != NULL &&
+1 -1
View File
@@ -694,7 +694,7 @@ void QueryRTLeftButton( UINT32 *puiNewEvent )
else else
{ {
//if ( FindBestPath( pSoldier, sMapPos, pSoldier->pathing.bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, 0 ) == 0 ) //if ( FindBestPath( pSoldier, sMapPos, pSoldier->pathing.bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, 0 ) == 0 )
if ( gsCurrentActionPoints == 0 && !gfUIAllMoveOn && !gTacticalStatus.fAtLeastOneGuyOnMultiSelect ) if (gsCurrentActionPoints == 0 && !gfUIAllMoveOn && !gTacticalStatus.fAtLeastOneGuyOnMultiSelect )
{ {
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ NO_PATH ] );
gfRTClickLeftHoldIntercepted = TRUE; gfRTClickLeftHoldIntercepted = TRUE;
+2 -2
View File
@@ -354,7 +354,7 @@ INT8 gDecapitatedCorpse[ NUM_CORPSES ] =
ROTTING_CORPSE gRottingCorpse[ MAX_ROTTING_CORPSES ]; std::vector<ROTTING_CORPSE> gRottingCorpse (MAX_ROTTING_CORPSES);
INT32 giNumRottingCorpse = 0; INT32 giNumRottingCorpse = 0;
@@ -465,7 +465,7 @@ INT32 AddRottingCorpse( ROTTING_CORPSE_DEFINITION *pCorpseDef )
STRUCTURE_FILE_REF * pStructureFileRef = NULL; STRUCTURE_FILE_REF * pStructureFileRef = NULL;
CHAR8 zFilename[150]; CHAR8 zFilename[150];
DB_STRUCTURE_REF *pDBStructureRef; DB_STRUCTURE_REF *pDBStructureRef;
UINT8 ubLoop; UINT8 ubLoop;
INT16 sTileGridNo; INT16 sTileGridNo;
DB_STRUCTURE_TILE ** ppTile; DB_STRUCTURE_TILE ** ppTile;
UINT16 usStructIndex; UINT16 usStructIndex;
+4 -2
View File
@@ -168,9 +168,11 @@ void HandleCrowLeave( SOLDIERTYPE *pSoldier );
void HandleCrowFlyAway( SOLDIERTYPE *pSoldier ); void HandleCrowFlyAway( SOLDIERTYPE *pSoldier );
#define MAX_ROTTING_CORPSES 100 // WDS - increase number of corpses
#define MAX_ROTTING_CORPSES 250
extern ROTTING_CORPSE gRottingCorpse[ MAX_ROTTING_CORPSES ]; //extern ROTTING_CORPSE gRottingCorpse[ MAX_ROTTING_CORPSES ];
extern std::vector<ROTTING_CORPSE> gRottingCorpse;
extern INT32 giNumRottingCorpse; extern INT32 giNumRottingCorpse;
extern UINT8 gb4DirectionsFrom8[8]; extern UINT8 gb4DirectionsFrom8[8];
+2 -2
View File
@@ -364,8 +364,8 @@ BOOLEAN gfRemindedPlayerToPickUpHisStuff = FALSE;
BOOLEAN gfDoneBusinessThisSession = FALSE; BOOLEAN gfDoneBusinessThisSession = FALSE;
// this is used within SKI exclusively, to handle small faces // this is used within SKI exclusively, to handle small faces
UINT8 gubArrayOfEmployedMercs[ MAX_CHARACTER_COUNT ]; UINT8 gubArrayOfEmployedMercs[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
UINT32 guiSmallSoldiersFace[ MAX_CHARACTER_COUNT ]; UINT32 guiSmallSoldiersFace[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ];
UINT8 gubNumberMercsInArray; UINT8 gubNumberMercsInArray;
//The subutitled text for what the merc is saying //The subutitled text for what the merc is saying
+1 -1
View File
@@ -295,7 +295,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
case DISARM_TRAP_CHECK: case DISARM_TRAP_CHECK:
fForceDamnSound = TRUE; fForceDamnSound = TRUE;
iSkill = EffectiveExplosive( pSoldier ) * 7; iSkill = EffectiveExplosive( pSoldier ) * 7;
if ( iSkill == 0 ) if ( iSkill == 0 )
+7 -7
View File
@@ -1090,14 +1090,14 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO
if ( pSoldier->bActive ) if ( pSoldier->bActive )
{ {
// ATE: Make sure life of elliot is OK if from a meanwhile // ATE: Make sure life of elliot is OK if from a meanwhile
if ( AreInMeanwhile() && pSoldier->ubProfile == ELLIOT ) if ( AreInMeanwhile() && pSoldier->ubProfile == ELLIOT )
{
if ( pSoldier->stats.bLife < OKLIFE )
{ {
pSoldier->stats.bLife = 25; if ( pSoldier->stats.bLife < OKLIFE )
{
pSoldier->stats.bLife = 25;
}
} }
}
// ADD SOLDIER TO SLOT! // ADD SOLDIER TO SLOT!
if (pSoldier->flags.uiStatusFlags & SOLDIER_OFF_MAP) if (pSoldier->flags.uiStatusFlags & SOLDIER_OFF_MAP)
@@ -1151,7 +1151,7 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
sGridNo = FindGridNoFromSweetSpotWithStructDataUsingGivenDirectionFirst( pSoldier, STANDING, pSoldier->sInsertionGridNo, 12, &ubCalculatedDirection, FALSE, pSoldier->ubInsertionDirection ); sGridNo = FindGridNoFromSweetSpotWithStructDataUsingGivenDirectionFirst( pSoldier, STANDING, pSoldier->sInsertionGridNo, 12, &ubCalculatedDirection, FALSE, pSoldier->ubInsertionDirection );
// ATE: Override insertion direction // ATE: Override insertion direction
if (sGridNo == NOWHERE) if (sGridNo == NOWHERE)
{ {
// Well, we gotta place this soldier/vehicle somewhere. Just use the first position for now // Well, we gotta place this soldier/vehicle somewhere. Just use the first position for now
+8 -3
View File
@@ -2937,8 +2937,11 @@ BOOLEAN ShouldMercSayHappyWithGunQuote( SOLDIERTYPE *pSoldier )
void SayBuddyWitnessedQuoteFromKill( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, INT8 bLevel ) void SayBuddyWitnessedQuoteFromKill( SOLDIERTYPE *pKillerSoldier, INT16 sGridNo, INT8 bLevel )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
INT8 bBuddyIndex[ 20 ] = { -1 }; std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
std::vector<INT8> bBuddyIndex (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, -1);
// INT8 bBuddyIndex[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { -1 };
INT8 bTempBuddyIndex; INT8 bTempBuddyIndex;
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
@@ -3043,7 +3046,9 @@ void HandleKilledQuote( SOLDIERTYPE *pKilledSoldier, SOLDIERTYPE *pKillerSoldier
{ {
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
INT32 cnt; INT32 cnt;
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
BOOLEAN fDoSomeoneElse = FALSE; BOOLEAN fDoSomeoneElse = FALSE;
+1 -1
View File
@@ -7273,7 +7273,7 @@ BOOLEAN SOLDIERTYPE::CreateSoldierPalettes( void )
// --- TAKE FROM CURRENT ANIMATION HVOBJECT! // --- TAKE FROM CURRENT ANIMATION HVOBJECT!
usAnimSurface = GetSoldierAnimationSurface( this, this->usAnimState ); usAnimSurface = GetSoldierAnimationSurface( this, this->usAnimState );
CHECKF( usAnimSurface != INVALID_ANIMATION_SURFACE ); // CHECKF( usAnimSurface != INVALID_ANIMATION_SURFACE );
if ( ( bBodyTypePalette = GetBodyTypePaletteSubstitutionCode( this, this->ubBodyType, zColFilename ) ) == -1 ) if ( ( bBodyTypePalette = GetBodyTypePaletteSubstitutionCode( this, this->ubBodyType, zColFilename ) ) == -1 )
{ {
+3 -2
View File
@@ -438,6 +438,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
tbTeam=pCreateStruct->bTeam; tbTeam=pCreateStruct->bTeam;
tfPP=pCreateStruct->fPlayerPlan; //used as temp indicator of struct sent from the server //hayden. tfPP=pCreateStruct->fPlayerPlan; //used as temp indicator of struct sent from the server //hayden.
if(is_networked) {
if(is_networked && (pCreateStruct->fOnRoof==1)) if(is_networked && (pCreateStruct->fOnRoof==1))
{ {
ScreenMsg( FONT_YELLOW, MSG_CHAT, L"skipping roof merc"); ScreenMsg( FONT_YELLOW, MSG_CHAT, L"skipping roof merc");
@@ -464,7 +465,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
ScreenMsg( FONT_YELLOW, MSG_CHAT, L"skipping tank"); ScreenMsg( FONT_YELLOW, MSG_CHAT, L"skipping tank");
return NULL; return NULL;
} }
}
//hayden //hayden
//Kris: //Kris:
@@ -606,7 +607,7 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
{ {
if( Soldier.bTeam == gbPlayerNum ) if( Soldier.bTeam == gbPlayerNum )
{ {
cnt = gTacticalStatus.Team[ Soldier.bTeam ].bLastID - 1; cnt = gTacticalStatus.Team[ Soldier.bTeam ].bLastID - gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles+1;
} }
} }
+2 -1
View File
@@ -18,6 +18,7 @@ class SOLDIERTYPE;
#define SOLDIER_CREATE_AUTO_TEAM -1 #define SOLDIER_CREATE_AUTO_TEAM -1
// WDS - make number of mercenaries, etc. be configurable
//Kris: //Kris:
//This value is the total maximum number of slots in a map. //This value is the total maximum number of slots in a map.
//Players 20 //Players 20
@@ -26,7 +27,7 @@ class SOLDIERTYPE;
//Rebels 32 //Rebels 32
//Civilians 32 //Civilians 32
//Total 148 //Total 148
#define MAX_INDIVIDUALS 148 #define MAX_INDIVIDUALS TOTAL_SOLDIERS
//Kris: SERIALIZING INFORMATION //Kris: SERIALIZING INFORMATION
//All maps must have: //All maps must have:
+3
View File
@@ -17,6 +17,7 @@
#include "debug.h" #include "debug.h"
#include "Random.h" #include "Random.h"
#include "items.h" #include "items.h"
#include "GameSettings.h"
#include "cursors.h" #include "cursors.h"
@@ -918,6 +919,8 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite; ubMaxNum = ubTotalAdmin + ubTotalTroops + ubTotalElite;
AssertLE (ubMaxNum, gGameExternalOptions.ubGameMaximumNumberOfEnemies);
//Sort the list in the following manner: //Sort the list in the following manner:
//-Priority placements first //-Priority placements first
//-Basic placements next //-Basic placements next
+7 -2
View File
@@ -481,7 +481,7 @@ BOOLEAN LoadMercProfiles(void)
void DecideActiveTerrorists( void ) void DecideActiveTerrorists( void )
{ {
UINT8 ubLoop, ubLoop2; UINT8 ubLoop, ubLoop2;
UINT8 ubTerrorist; UINT8 ubTerrorist;
UINT8 ubNumAdditionalTerrorists, ubNumTerroristsAdded = 0; UINT8 ubNumAdditionalTerrorists, ubNumTerroristsAdded = 0;
UINT32 uiChance, uiLocationChoice; UINT32 uiChance, uiLocationChoice;
@@ -691,7 +691,7 @@ void DecideOnAssassin( void )
{ {
UINT8 ubAssassinPossibility[NUM_ASSASSINS] = { NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE }; UINT8 ubAssassinPossibility[NUM_ASSASSINS] = { NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE };
UINT8 ubAssassinsPossible = 0; UINT8 ubAssassinsPossible = 0;
UINT8 ubLoop, ubLoop2; UINT8 ubLoop, ubLoop2;
UINT8 ubTown; UINT8 ubTown;
#ifdef CRIPPLED_VERSION #ifdef CRIPPLED_VERSION
@@ -1121,6 +1121,11 @@ BOOLEAN RecruitRPC( UINT8 ubCharNum )
// Add this guy to our team! // Add this guy to our team!
pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum ); pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum );
if (!pNewSoldier)
{
return( FALSE );
}
if ( ubCharNum == SLAY ) if ( ubCharNum == SLAY )
{ {
if(gGameExternalOptions.fEnableSlayForever == TRUE) if(gGameExternalOptions.fEnableSlayForever == TRUE)
+16 -20
View File
@@ -18,7 +18,9 @@
#include "jascreens.h" #include "jascreens.h"
#include "screenids.h" #include "screenids.h"
#include "Soldier macros.h" #include "Soldier macros.h"
#include "GameSettings.h"
#endif #endif
#include <vector>
typedef struct typedef struct
@@ -341,9 +343,8 @@ BOOLEAN AddCharacterToAnySquad( SOLDIERTYPE *pCharacter )
RemoveCharacterFromSquads( pCharacter ); RemoveCharacterFromSquads( pCharacter );
// first look for a compatible NON-EMPTY squad (don't start new squad if we don't have to) // first look for a compatible NON-EMPTY squad (don't start new squad if we don't have to)
for( bCounter = 0; bCounter < NUMBER_OF_SQUADS; bCounter++ ) for( bCounter = 0; bCounter < NUMBER_OF_SQUADS; bCounter++ ) {
{ if( !SquadIsEmpty( bCounter ) )
if( SquadIsEmpty( bCounter ) == FALSE )
{ {
if( AddCharacterToSquad( pCharacter, bCounter ) == TRUE ) if( AddCharacterToSquad( pCharacter, bCounter ) == TRUE )
{ {
@@ -400,24 +401,19 @@ INT8 AddCharacterToUniqueSquad( SOLDIERTYPE *pCharacter )
return( -1 ); return( -1 );
} }
// WDS - make number of mercenaries, etc. be configurable
void SortSquadByID( INT8 bSquadValue ) void SortSquadByID( INT8 bSquadValue )
{ {
INT8 teamOrder[18] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; for(unsigned idx1 = 0; idx1 < NUMBER_OF_SOLDIERS_PER_SQUAD-1; ++idx1) {
if (Squad[bSquadValue][idx1]) {
for(int count = 0; count < NUMBER_OF_SOLDIERS_PER_SQUAD; count ++) for(unsigned idx2 = idx1+1; idx2 < NUMBER_OF_SOLDIERS_PER_SQUAD; ++idx2) {
{ if (Squad[bSquadValue][idx2] &&
if(Squad[bSquadValue][0] != NULL) (Squad[bSquadValue][idx2]->ubID < Squad[bSquadValue][idx1]->ubID)) {
{ SOLDIERTYPE *temp = Squad[bSquadValue][idx1];
teamOrder[Squad[bSquadValue][0]->ubID] = count; Squad[bSquadValue][idx1] = Squad[bSquadValue][idx2];
RemoveCharacterFromSquads( Squad[bSquadValue][0] ); Squad[bSquadValue][idx2] = temp;
} }
} }
for(int count = 0; count < 18; count++)
//for(int count = 17; count >= 0; count--)
{
if(teamOrder[count] != -1)
{
AddCharacterToSquad(MercPtrs[count], bSquadValue);
} }
} }
} }
@@ -914,7 +910,7 @@ void RebuildCurrentSquad( void )
void ExamineCurrentSquadLights( void ) void ExamineCurrentSquadLights( void )
{ {
// rebuilds current squad to reset faces in tactical // rebuilds current squad to reset faces in tactical
UINT8 ubLoop; UINT8 ubLoop;
// OK, we should add lights for any guy currently bInSector who is not bad OKLIFE... // OK, we should add lights for any guy currently bInSector who is not bad OKLIFE...
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
+1
View File
@@ -3,6 +3,7 @@
#include "Soldier Control.h" #include "Soldier Control.h"
#include "FileMan.h" #include "FileMan.h"
#include "Overhead Types.h"
// header for squad management system // header for squad management system
#define NUMBER_OF_SOLDIERS_PER_SQUAD 6 #define NUMBER_OF_SOLDIERS_PER_SQUAD 6
+2
View File
@@ -95,6 +95,8 @@ BOOLEAN SetSectorFlag( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet
BOOLEAN ReSetUnderGroundSectorFlag( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToSet ); BOOLEAN ReSetUnderGroundSectorFlag( INT16 sSectorX, INT16 sSectorY, UINT8 ubSectorZ, UINT32 uiFlagToSet );
BOOLEAN ReSetSectorFlag( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet ); BOOLEAN ReSetSectorFlag( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet );
void AddExtraItems (UINT8, UINT8, UINT8, bool = false);
//Saves the NPC temp Quote file to the saved game file //Saves the NPC temp Quote file to the saved game file
BOOLEAN LoadTempNpcQuoteArrayToSaveGameFile( HWFILE hFile ); BOOLEAN LoadTempNpcQuoteArrayToSaveGameFile( HWFILE hFile );
+3 -1
View File
@@ -44,7 +44,9 @@ extern UINT8 NumEnemyInSector();
void HandleRPCDescription( ) void HandleRPCDescription( )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
SOLDIERTYPE *pTeamSoldier; SOLDIERTYPE *pTeamSoldier;
+101 -91
View File
@@ -123,7 +123,7 @@ typedef struct
void ClearIntList( void ) void ClearIntList( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ClearIntList"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"ClearIntList");
memset( &gubOutOfTurnOrder, 0, MAXMERCS ); memset( &gubOutOfTurnOrder, 0, MAXMERCS );
gubOutOfTurnOrder[0] = END_OF_INTERRUPTS; gubOutOfTurnOrder[0] = END_OF_INTERRUPTS;
gubOutOfTurnPersons = 0; gubOutOfTurnPersons = 0;
@@ -134,7 +134,7 @@ BOOLEAN BloodcatsPresent( void )
INT32 iLoop; INT32 iLoop;
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"BloodcatsPresent"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"BloodcatsPresent");
if ( gTacticalStatus.Team[ CREATURE_TEAM ].bTeamActive == FALSE ) if ( gTacticalStatus.Team[ CREATURE_TEAM ].bTeamActive == FALSE )
{ {
return( FALSE ); return( FALSE );
@@ -156,7 +156,7 @@ BOOLEAN BloodcatsPresent( void )
void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode ) void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode )
{ {
INT32 cnt; INT32 cnt;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StartPlayerTeamTurn"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StartPlayerTeamTurn");
// SOLDIERTYPE *pSoldier; // SOLDIERTYPE *pSoldier;
// EV_S_BEGINTURN SBeginTurn; // EV_S_BEGINTURN SBeginTurn;
@@ -204,7 +204,7 @@ void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode )
// Check if this guy is able to be selected.... // Check if this guy is able to be selected....
if ( MercPtrs[ gusSelectedSoldier ]->stats.bLife < OKLIFE ) if ( MercPtrs[ gusSelectedSoldier ]->stats.bLife < OKLIFE )
{ {
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("StartPlayerTeamTurn: SelectNextAvailSoldier")); DebugMsg(TOPIC_JA2INTERRUPT,DBG_LEVEL_3,String("StartPlayerTeamTurn: SelectNextAvailSoldier"));
SelectNextAvailSoldier( MercPtrs[ gusSelectedSoldier ] ); SelectNextAvailSoldier( MercPtrs[ gusSelectedSoldier ] );
} }
else else
@@ -261,7 +261,7 @@ void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode )
void FreezeInterfaceForEnemyTurn( void ) void FreezeInterfaceForEnemyTurn( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"FreezeInterfaceForEnemyTurn"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"FreezeInterfaceForEnemyTurn");
// Reset flags // Reset flags
gfPlotNewMovement = TRUE; gfPlotNewMovement = TRUE;
@@ -288,7 +288,7 @@ void FreezeInterfaceForEnemyTurn( void )
void EndTurn( UINT8 ubNextTeam ) void EndTurn( UINT8 ubNextTeam )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EndTurn"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EndTurn");
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
INT32 cnt; INT32 cnt;
@@ -343,7 +343,7 @@ void EndTurn( UINT8 ubNextTeam )
void EndAITurn( void ) void EndAITurn( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EndAITurn"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EndAITurn");
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
INT32 cnt; INT32 cnt;
@@ -379,7 +379,7 @@ void EndAITurn( void )
void EndAllAITurns( void ) void EndAllAITurns( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EndAllAITurns"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EndAllAITurns");
// warp turn to the player's turn // warp turn to the player's turn
SOLDIERTYPE * pSoldier; SOLDIERTYPE * pSoldier;
INT32 cnt; INT32 cnt;
@@ -413,7 +413,7 @@ void EndAllAITurns( void )
void EndTurnEvents( void ) void EndTurnEvents( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EndTurnEvents"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EndTurnEvents");
// HANDLE END OF TURN EVENTS // HANDLE END OF TURN EVENTS
// handle team services like healing // handle team services like healing
HandleTeamServices( gbPlayerNum ); HandleTeamServices( gbPlayerNum );
@@ -435,7 +435,7 @@ BOOLEAN LightningEndOfTurn( UINT8 ubTeam );
void BeginTeamTurn( UINT8 ubTeam ) void BeginTeamTurn( UINT8 ubTeam )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"BeginTeamTurn"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"BeginTeamTurn");
INT32 cnt; INT32 cnt;
UINT8 ubID; UINT8 ubID;
SOLDIERTYPE *pSoldier; SOLDIERTYPE *pSoldier;
@@ -554,8 +554,8 @@ void BeginTeamTurn( UINT8 ubTeam )
if(!gfAmIHost) if(!gfAmIHost)
break; break;
#endif #endif
if( is_client && !is_server ) //hayden //disable independant client AI if( is_client && !is_server ) //hayden //disable independant client AI
break; break;
// Set First enemy merc to AI control // Set First enemy merc to AI control
@@ -594,7 +594,7 @@ void BeginTeamTurn( UINT8 ubTeam )
void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier ) void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DisplayHiddenInterrupt"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"DisplayHiddenInterrupt");
// If the AI got an interrupt but this has been hidden from the player until this point, // If the AI got an interrupt but this has been hidden from the player until this point,
// this code will display the interrupt // this code will display the interrupt
@@ -621,20 +621,20 @@ void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier )
// Dirty panel interface! // Dirty panel interface!
fInterfacePanelDirty = DIRTYLEVEL2; fInterfacePanelDirty = DIRTYLEVEL2;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to call ErasePath"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"about to call ErasePath");
// Erase path! // Erase path!
ErasePath( TRUE ); ErasePath( TRUE );
// Reset flags // Reset flags
gfPlotNewMovement = TRUE; gfPlotNewMovement = TRUE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to call AdjustNoAPToFinishMove"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"about to call AdjustNoAPToFinishMove");
// Stop our guy.... // Stop our guy....
MercPtrs[ LATEST_INTERRUPT_GUY ]->AdjustNoAPToFinishMove( TRUE ); MercPtrs[ LATEST_INTERRUPT_GUY ]->AdjustNoAPToFinishMove( TRUE );
// Stop him from going to prone position if doing a turn while prone // Stop him from going to prone position if doing a turn while prone
MercPtrs[ LATEST_INTERRUPT_GUY ]->flags.bTurningFromPronePosition = TURNING_FROM_PRONE_OFF; MercPtrs[ LATEST_INTERRUPT_GUY ]->flags.bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to call AddTopMessage"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"about to call AddTopMessage");
// get rid of any old overlay message // get rid of any old overlay message
if ( pSoldier->bTeam == MILITIA_TEAM ) if ( pSoldier->bTeam == MILITIA_TEAM )
{ {
@@ -647,12 +647,12 @@ void DisplayHiddenInterrupt( SOLDIERTYPE * pSoldier )
gfHiddenInterrupt = FALSE; gfHiddenInterrupt = FALSE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DisplayHiddenInterrupt completed"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"DisplayHiddenInterrupt completed");
} }
void DisplayHiddenTurnbased( SOLDIERTYPE * pActingSoldier ) void DisplayHiddenTurnbased( SOLDIERTYPE * pActingSoldier )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DisplayHiddenTurnBased"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"DisplayHiddenTurnBased");
// This code should put the game in turn-based and give control to the AI-controlled soldier // This code should put the game in turn-based and give control to the AI-controlled soldier
// whose pointer has been passed in as an argument (we were in non-combat and the AI is doing // whose pointer has been passed in as an argument (we were in non-combat and the AI is doing
// something visible, i.e. making an attack) // something visible, i.e. making an attack)
@@ -702,7 +702,7 @@ void DisplayHiddenTurnbased( SOLDIERTYPE * pActingSoldier )
BOOLEAN EveryoneInInterruptListOnSameTeam( void ) BOOLEAN EveryoneInInterruptListOnSameTeam( void )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EveryoneInInterruptListOnSameTeam"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EveryoneInInterruptListOnSameTeam");
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubTeam = 255; UINT8 ubTeam = 255;
@@ -732,19 +732,23 @@ void StartInterrupt( void )
UINT8 ubInterrupter; UINT8 ubInterrupter;
INT32 cnt; INT32 cnt;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StartInterrupt"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StartInterrupt");
ubFirstInterrupter = LATEST_INTERRUPT_GUY; ubFirstInterrupter = LATEST_INTERRUPT_GUY;
AssertLE(ubFirstInterrupter, MAX_NUM_SOLDIERS);
pSoldier = MercPtrs[ubFirstInterrupter]; pSoldier = MercPtrs[ubFirstInterrupter];
AssertNotNIL(pSoldier);
bTeam = pSoldier->bTeam; bTeam = pSoldier->bTeam;
ubInterrupter = ubFirstInterrupter; ubInterrupter = ubFirstInterrupter;
#ifdef _DEBUG
// display everyone on int queue! // display everyone on int queue!
for ( cnt = gubOutOfTurnPersons; cnt > 0; cnt-- ) for ( cnt = gubOutOfTurnPersons; cnt > 0; cnt-- )
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("STARTINT: Q position %d: %d", cnt, gubOutOfTurnOrder[ cnt ] ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("STARTINT: Q position %d: %d", cnt, gubOutOfTurnOrder[ cnt ] ) );
} }
#endif
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: %d is now on top of the interrupt queue", ubFirstInterrupter ) ); //DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: %d is now on top of the interrupt queue", ubFirstInterrupter ) );
gTacticalStatus.fInterruptOccurred = TRUE; gTacticalStatus.fInterruptOccurred = TRUE;
@@ -769,7 +773,7 @@ void StartInterrupt( void )
while( 1 ) while( 1 )
{ {
MercPtrs[ubInterrupter]->aiData.bMoved = FALSE; MercPtrs[ubInterrupter]->aiData.bMoved = FALSE;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) );
REMOVE_LATEST_INTERRUPT_GUY(); REMOVE_LATEST_INTERRUPT_GUY();
// now LATEST_INTERRUPT_GUY is the guy before the previous // now LATEST_INTERRUPT_GUY is the guy before the previous
@@ -818,7 +822,7 @@ void StartInterrupt( void )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, sTemp ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, sTemp );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: starting interrupt for %d", ubFirstInterrupter ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: starting interrupt for %d", ubFirstInterrupter ) );
// gusSelectedSoldier should become the topmost guy on the interrupt list // gusSelectedSoldier should become the topmost guy on the interrupt list
//gusSelectedSoldier = ubFirstInterrupter; //gusSelectedSoldier = ubFirstInterrupter;
@@ -889,7 +893,7 @@ void StartInterrupt( void )
MercPtrs[ubInterrupter]->aiData.bMoved = FALSE; MercPtrs[ubInterrupter]->aiData.bMoved = FALSE;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: popping %d off of the interrupt queue", ubInterrupter ) );
REMOVE_LATEST_INTERRUPT_GUY(); REMOVE_LATEST_INTERRUPT_GUY();
// now LATEST_INTERRUPT_GUY is the guy before the previous // now LATEST_INTERRUPT_GUY is the guy before the previous
@@ -949,7 +953,7 @@ void StartInterrupt( void )
MercPtrs[ LATEST_INTERRUPT_GUY ]->AdjustNoAPToFinishMove( TRUE ); MercPtrs[ LATEST_INTERRUPT_GUY ]->AdjustNoAPToFinishMove( TRUE );
MercPtrs[ LATEST_INTERRUPT_GUY ]->flags.bTurningFromPronePosition = TURNING_FROM_PRONE_OFF; MercPtrs[ LATEST_INTERRUPT_GUY ]->flags.bTurningFromPronePosition = TURNING_FROM_PRONE_OFF;
} }
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StartInterrupt done"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StartInterrupt done");
} }
@@ -962,11 +966,11 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
BOOLEAN fFound; BOOLEAN fFound;
INT16 ubMinAPsToAttack; INT16 ubMinAPsToAttack;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"EndInterrupt"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"EndInterrupt");
for ( cnt = gubOutOfTurnPersons; cnt > 0; cnt-- ) for ( cnt = gubOutOfTurnPersons; cnt > 0; cnt-- )
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ENDINT: Q position %d: %d", cnt, gubOutOfTurnOrder[ cnt ] ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("ENDINT: Q position %d: %d", cnt, gubOutOfTurnOrder[ cnt ] ) );
} }
// ATE: OK, now if this all happended on one frame, we may not have to stop // ATE: OK, now if this all happended on one frame, we may not have to stop
@@ -1001,8 +1005,9 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// resume interrupted interrupt // resume interrupted interrupt
//hayden //hayden
if (is_networked) if (!is_networked) {
{ StartInterrupt();
} else {
UINT8 nubFirstInterrupter; UINT8 nubFirstInterrupter;
INT8 nbTeam; INT8 nbTeam;
SOLDIERTYPE * npSoldier; SOLDIERTYPE * npSoldier;
@@ -1021,8 +1026,8 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
else if(is_server && gTacticalStatus.ubCurrentTeam == 1)// against ai else if(is_server && gTacticalStatus.ubCurrentTeam == 1)// against ai
{ {
//hayden //hayden
send_interrupt( npSoldier ); // send_interrupt( npSoldier ); //
if(nbTeam !=0)intAI(npSoldier); if(nbTeam !=0)intAI(npSoldier);
else StartInterrupt();// else StartInterrupt();//
//requestAIint( npSoldier ); //requestAIint( npSoldier );
@@ -1038,17 +1043,13 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
} }
} }
else
{
StartInterrupt();
}
} }
else else
{ {
ubInterruptedSoldier = LATEST_INTERRUPT_GUY; ubInterruptedSoldier = LATEST_INTERRUPT_GUY;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: interrupt over, %d's team regains control", ubInterruptedSoldier ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: interrupt over, %d's team regains control", ubInterruptedSoldier ) );
pSoldier = MercPtrs[ubInterruptedSoldier]; pSoldier = MercPtrs[ubInterruptedSoldier];
@@ -1097,7 +1098,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// Select soldier.... // Select soldier....
if ( MercPtrs[ ubInterruptedSoldier ]->stats.bLife < OKLIFE ) if ( MercPtrs[ ubInterruptedSoldier ]->stats.bLife < OKLIFE )
{ {
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("EndInterrupt: SelectNextAvailSoldier")); DebugMsg(TOPIC_JA2INTERRUPT,DBG_LEVEL_3,String("EndInterrupt: SelectNextAvailSoldier"));
SelectNextAvailSoldier( MercPtrs[ ubInterruptedSoldier ] ); SelectNextAvailSoldier( MercPtrs[ ubInterruptedSoldier ] );
} }
else else
@@ -1171,7 +1172,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
} }
} }
else if(pSoldier->bTeam < 6)//hayden : is Ai or LAN ? else if (!is_networked || (pSoldier->bTeam < 6))//hayden : is Ai or LAN ?
{ {
// this could be set to true for AI-vs-AI interrupts // this could be set to true for AI-vs-AI interrupts
gfHiddenInterrupt = FALSE; gfHiddenInterrupt = FALSE;
@@ -1261,13 +1262,13 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// Signal UI done enemy's turn // Signal UI done enemy's turn
if(is_client) if(is_client)
{ {
guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK; guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK;
} }
else else
{ {
guiPendingOverrideEvent = LU_BEGINUILOCK; guiPendingOverrideEvent = LU_BEGINUILOCK;
} }
// must clear int list before ending turn // must clear int list before ending turn
ClearIntList(); ClearIntList();
@@ -1275,19 +1276,19 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
} }
} }
else //its going to another Lan client..//hayden else if (is_networked) //its going to another Lan client..//hayden
{ {
gTacticalStatus.ubCurrentTeam = pSoldier->bTeam; gTacticalStatus.ubCurrentTeam = pSoldier->bTeam;
AddTopMessage( COMPUTER_TURN_MESSAGE, TeamTurnString[ gTacticalStatus.ubCurrentTeam ] ); AddTopMessage( COMPUTER_TURN_MESSAGE, TeamTurnString[ gTacticalStatus.ubCurrentTeam ] );
if(is_client) if(is_client)
{ {
guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK; guiPendingOverrideEvent = LA_BEGINUIOURTURNLOCK;
} }
else else
{ {
guiPendingOverrideEvent = LU_BEGINUILOCK; guiPendingOverrideEvent = LU_BEGINUILOCK;
} }
// must clear int list before ending turn // must clear int list before ending turn
ClearIntList(); ClearIntList();
@@ -1302,7 +1303,7 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, INT8 bOldOppList) BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, INT8 bOldOppList)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"StandardInterruptConditionsMet"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"StandardInterruptConditionsMet");
// UINT8 ubAniType; // UINT8 ubAniType;
INT16 ubMinPtsNeeded; INT16 ubMinPtsNeeded;
INT8 bDir; INT8 bDir;
@@ -1495,10 +1496,18 @@ BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT8 ubOpponent
} }
else else
{ {
if ( !(is_client || (pOpponent->flags.uiStatusFlags & SOLDIER_UNDERAICONTROL)) && (pSoldier->bSide != pOpponent->bSide)) if (!is_networked) {
{ if ( !(pOpponent->flags.uiStatusFlags & SOLDIER_UNDERAICONTROL) && (pSoldier->bSide != pOpponent->bSide))
return( FALSE ); {
return( FALSE );
}
} else {
if ( !(is_client || (pOpponent->flags.uiStatusFlags & SOLDIER_UNDERAICONTROL)) && (pSoldier->bSide != pOpponent->bSide))
{
return( FALSE );
}
} }
} }
/* old DG code for same: /* old DG code for same:
@@ -1590,7 +1599,7 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
INT32 iPoints; INT32 iPoints;
INT8 bLightLevel; INT8 bLightLevel;
UINT8 ubDistance; UINT8 ubDistance;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcInterruptDuelPts"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"CalcInterruptDuelPts");
// extra check to make sure neutral folks never get interrupts // extra check to make sure neutral folks never get interrupts
if (pSoldier->aiData.bNeutral) if (pSoldier->aiData.bNeutral)
@@ -1766,20 +1775,20 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
} }
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Calculating int pts for %d vs %d, number is %d", pSoldier->ubID, ubOpponentID, iPoints ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Calculating int pts for %d vs %d, number is %d", pSoldier->ubID, ubOpponentID, iPoints ) );
#endif #endif
if(is_networked) if(is_networked)
{ {
SOLDIERTYPE *pOpp = &Menptr[ubOpponentID]; SOLDIERTYPE *pOpp = &Menptr[ubOpponentID];
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_CHAT, L"Interrupt: '%s' vs '%s' = %d points.",pSoldier->name,pOpp->name, iPoints ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_CHAT, L"Interrupt: '%s' vs '%s' = %d points.",pSoldier->name,pOpp->name, iPoints );
} }
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CalcInterruptDuelPts done"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"CalcInterruptDuelPts done");
return( (INT8)iPoints ); return( (INT8)iPoints );
} }
BOOLEAN InterruptDuel( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent) BOOLEAN InterruptDuel( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InterruptDuel"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"InterruptDuel");
BOOLEAN fResult = FALSE; BOOLEAN fResult = FALSE;
// if opponent can't currently see us and we can see them // if opponent can't currently see us and we can see them
@@ -1801,14 +1810,14 @@ BOOLEAN InterruptDuel( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent)
} }
} }
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt duel %d (%d pts) vs %d (%d pts)", pSoldier->ubID, pSoldier->aiData.bInterruptDuelPts, pOpponent->ubID, pOpponent->aiData.bInterruptDuelPts ); // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Interrupt duel %d (%d pts) vs %d (%d pts)", pSoldier->ubID, pSoldier->aiData.bInterruptDuelPts, pOpponent->ubID, pOpponent->aiData.bInterruptDuelPts );
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InterruptDuel done"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"InterruptDuel done");
return( fResult ); return( fResult );
} }
void DeleteFromIntList( UINT8 ubIndex, BOOLEAN fCommunicate) void DeleteFromIntList( UINT8 ubIndex, BOOLEAN fCommunicate)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DeleteFromIntList"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"DeleteFromIntList");
UINT8 ubLoop; UINT8 ubLoop;
UINT8 ubID; UINT8 ubID;
@@ -1821,7 +1830,7 @@ void DeleteFromIntList( UINT8 ubIndex, BOOLEAN fCommunicate)
ubID = gubOutOfTurnOrder[ubIndex]; ubID = gubOutOfTurnOrder[ubIndex];
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: removing ID %d", ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: removing ID %d", ubID ) );
#endif #endif
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%d removed from int list", ubID ); // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%d removed from int list", ubID );
// if we're NOT deleting the LAST entry in the int list // if we're NOT deleting the LAST entry in the int list
@@ -1850,11 +1859,11 @@ void DeleteFromIntList( UINT8 ubIndex, BOOLEAN fCommunicate)
void AddToIntList( UINT8 ubID, BOOLEAN fGainControl, BOOLEAN fCommunicate ) void AddToIntList( UINT8 ubID, BOOLEAN fGainControl, BOOLEAN fCommunicate )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"AddToIntList"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"AddToIntList");
UINT8 ubLoop; UINT8 ubLoop;
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%d added to int list", ubID ); // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%d added to int list", ubID );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: adding ID %d who %s", ubID, fGainControl ? "gains control" : "loses control" ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: adding ID %d who %s", ubID, fGainControl ? "gains control" : "loses control" ) );
// check whether 'who' is already anywhere on the queue after the first index // check whether 'who' is already anywhere on the queue after the first index
// which we want to preserve so we can restore turn order // which we want to preserve so we can restore turn order
@@ -1911,12 +1920,12 @@ void AddToIntList( UINT8 ubID, BOOLEAN fGainControl, BOOLEAN fCommunicate )
void VerifyOutOfTurnOrderArray() void VerifyOutOfTurnOrderArray()
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"VerifyOutOfTurnOrderArray"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"VerifyOutOfTurnOrderArray");
UINT8 ubTeamHighest[ MAXTEAMS ] = { 0 }; UINT8 ubTeamHighest[ MAXTEAMS ] = { 0 };
UINT8 ubTeamsInList; UINT8 ubTeamsInList;
UINT8 ubNextInArrayOnTeam, ubNextIndex; UINT8 ubNextInArrayOnTeam, ubNextIndex;
UINT8 ubTeam; UINT8 ubTeam;
UINT8 ubLoop, ubLoop2; UINT8 ubLoop, ubLoop2;
BOOLEAN fFoundLoop = FALSE; BOOLEAN fFoundLoop = FALSE;
for (ubLoop = 1; ubLoop <= gubOutOfTurnPersons; ubLoop++) for (ubLoop = 1; ubLoop <= gubOutOfTurnPersons; ubLoop++)
@@ -2020,7 +2029,7 @@ void VerifyOutOfTurnOrderArray()
void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInterruptType) void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInterruptType)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DoneAddingToIntList"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"DoneAddingToIntList");
if (fChange) if (fChange)
{ {
VerifyOutOfTurnOrderArray(); VerifyOutOfTurnOrderArray();
@@ -2030,8 +2039,9 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter
} }
else else
{ {
if (is_networked) if (!is_networked) {
{ StartInterrupt();
} else {
UINT8 nubFirstInterrupter; UINT8 nubFirstInterrupter;
INT8 nbTeam; INT8 nbTeam;
SOLDIERTYPE * npSoldier; SOLDIERTYPE * npSoldier;
@@ -2085,17 +2095,13 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter
ClearIntList();//no interrupt to be awarded, clear generated list. ClearIntList();//no interrupt to be awarded, clear generated list.
} }
} }
else
{
StartInterrupt();
}
} }
} }
} }
void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType) void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("ResolveInterruptsVs: Soldier ID = %d, APs = %d",pSoldier->ubID,pSoldier->bActionPoints)); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,String("ResolveInterruptsVs: Soldier ID = %d, APs = %d (interrupt type = %d)",pSoldier->ubID,pSoldier->bActionPoints, ubInterruptType));
UINT8 ubTeam, ubOpp; UINT8 ubTeam, ubOpp;
UINT8 ubIntCnt; UINT8 ubIntCnt;
UINT8 ubIntList[MAXMERCS]; UINT8 ubIntList[MAXMERCS];
@@ -2107,17 +2113,21 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
SOLDIERTYPE * pOpponent; SOLDIERTYPE * pOpponent;
BOOLEAN fControlChanged = FALSE; BOOLEAN fControlChanged = FALSE;
AssertNotNIL(pSoldier);
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) ) if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
{ {
ubIntCnt = 0; ubIntCnt = 0;
for (ubTeam = 0; ubTeam < MAXTEAMS; ubTeam++) for (ubTeam = 0; ubTeam < MAXTEAMS; ubTeam++)
{ {
if (gTacticalStatus.Team[ubTeam].bTeamActive && (gTacticalStatus.Team[ubTeam].bSide != pSoldier->bSide) && ubTeam != CIV_TEAM) // WDS fix broken interrupts (I hope...)
if (/*gTacticalStatus.Team[ubTeam].bTeamActive &&*/ (gTacticalStatus.Team[ubTeam].bSide != pSoldier->bSide) && ubTeam != CIV_TEAM)
{ {
for ( ubOpp = gTacticalStatus.Team[ ubTeam ].bFirstID; ubOpp <= gTacticalStatus.Team[ ubTeam ].bLastID; ubOpp++) for ( ubOpp = gTacticalStatus.Team[ ubTeam ].bFirstID; ubOpp <= gTacticalStatus.Team[ ubTeam ].bLastID; ubOpp++)
{ {
pOpponent = MercPtrs[ubOpp]; pOpponent = MercPtrs[ubOpp];
AssertNotNIL(pOpponent);
if ( pOpponent->bActive && pOpponent->bInSector && (pOpponent->stats.bLife >= OKLIFE) && !(pOpponent->bCollapsed) ) if ( pOpponent->bActive && pOpponent->bInSector && (pOpponent->stats.bLife >= OKLIFE) && !(pOpponent->bCollapsed) )
{ {
if ( ubInterruptType == NOISEINTERRUPT ) if ( ubInterruptType == NOISEINTERRUPT )
@@ -2127,7 +2137,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
{ {
pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT; pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Resetting int pts for %d - NOISE BEYOND SIGHT DISTANCE!?", pOpponent->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Resetting int pts for %d - NOISE BEYOND SIGHT DISTANCE!?", pOpponent->ubID ) );
continue; continue;
} }
@@ -2136,7 +2146,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
{ {
pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT; pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Resetting int pts for %d - DOESN'T SEE ON SIGHT INTERRUPT!?", pOpponent->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Resetting int pts for %d - DOESN'T SEE ON SIGHT INTERRUPT!?", pOpponent->ubID ) );
continue; continue;
@@ -2145,7 +2155,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
switch (pOpponent->aiData.bInterruptDuelPts) switch (pOpponent->aiData.bInterruptDuelPts)
{ {
case NO_INTERRUPT: // no interrupt possible, no duel necessary case NO_INTERRUPT: // no interrupt possible, no duel necessary
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("ResolveInterruptsVs: No interrupt for opponent %d", pOpponent->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("ResolveInterruptsVs: No interrupt for opponent %d", pOpponent->ubID ) );
fIntOccurs = FALSE; fIntOccurs = FALSE;
break; break;
@@ -2153,18 +2163,18 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
pSoldier->aiData.bInterruptDuelPts = 0; // just to have a valid intDiff later pSoldier->aiData.bInterruptDuelPts = 0; // just to have a valid intDiff later
fIntOccurs = TRUE; fIntOccurs = TRUE;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: automatic interrupt on %d by %d", pSoldier->ubID, pOpponent->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: automatic interrupt on %d by %d", pSoldier->ubID, pOpponent->ubID ) );
break; break;
default: // interrupt is possible, run a duel default: // interrupt is possible, run a duel
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Calculating int duel pts for onlooker in ResolveInterruptsVs" ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, "Calculating int duel pts for onlooker in ResolveInterruptsVs" );
pSoldier->aiData.bInterruptDuelPts = CalcInterruptDuelPts(pSoldier,pOpponent->ubID,TRUE); pSoldier->aiData.bInterruptDuelPts = CalcInterruptDuelPts(pSoldier,pOpponent->ubID,TRUE);
fIntOccurs = InterruptDuel(pOpponent,pSoldier); fIntOccurs = InterruptDuel(pOpponent,pSoldier);
#ifdef DEBUG_INTERRUPTS #ifdef DEBUG_INTERRUPTS
if (fIntOccurs) if (fIntOccurs)
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("INTERRUPT: standard interrupt on %d (%d pts) by %d (%d pts)", pSoldier->ubID, pSoldier->aiData.bInterruptDuelPts, pOpponent->ubID, pOpponent->aiData.bInterruptDuelPts) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("INTERRUPT: standard interrupt on %d (%d pts) by %d (%d pts)", pSoldier->ubID, pSoldier->aiData.bInterruptDuelPts, pOpponent->ubID, pOpponent->aiData.bInterruptDuelPts) );
} }
#endif #endif
@@ -2196,7 +2206,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
if (pSoldier->aiData.bInterruptDuelPts != NO_INTERRUPT) if (pSoldier->aiData.bInterruptDuelPts != NO_INTERRUPT)
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Resetting int pts for %d", pSoldier->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Resetting int pts for %d", pSoldier->ubID ) );
} }
@@ -2205,7 +2215,7 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
if (pOpponent->aiData.bInterruptDuelPts != NO_INTERRUPT) if (pOpponent->aiData.bInterruptDuelPts != NO_INTERRUPT)
{ {
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Resetting int pts for %d", pOpponent->ubID ) ); DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Resetting int pts for %d", pOpponent->ubID ) );
} }
pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT; pOpponent->aiData.bInterruptDuelPts = NO_INTERRUPT;
@@ -2285,13 +2295,13 @@ void ResolveInterruptsVs( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType)
// unless it's a MOVEMENT interrupt, in which case that is delayed til later // unless it's a MOVEMENT interrupt, in which case that is delayed til later
DoneAddingToIntList(pSoldier,fControlChanged,ubInterruptType); DoneAddingToIntList(pSoldier,fControlChanged,ubInterruptType);
} }
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ResolveInterruptsVs done"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"ResolveInterruptsVs done");
} }
BOOLEAN SaveTeamTurnsToTheSaveGameFile( HWFILE hFile ) BOOLEAN SaveTeamTurnsToTheSaveGameFile( HWFILE hFile )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SaveTeamTurnsToTheSaveGameFile"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"SaveTeamTurnsToTheSaveGameFile");
UINT32 uiNumBytesWritten; UINT32 uiNumBytesWritten;
TEAM_TURN_SAVE_STRUCT TeamTurnStruct; TEAM_TURN_SAVE_STRUCT TeamTurnStruct;
@@ -2324,7 +2334,7 @@ BOOLEAN SaveTeamTurnsToTheSaveGameFile( HWFILE hFile )
BOOLEAN LoadTeamTurnsFromTheSavedGameFile( HWFILE hFile ) BOOLEAN LoadTeamTurnsFromTheSavedGameFile( HWFILE hFile )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"LoadTeamTurnsFromTheSavedGameFile"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"LoadTeamTurnsFromTheSavedGameFile");
UINT32 uiNumBytesRead; UINT32 uiNumBytesRead;
TEAM_TURN_SAVE_STRUCT TeamTurnStruct; TEAM_TURN_SAVE_STRUCT TeamTurnStruct;
@@ -2357,7 +2367,7 @@ BOOLEAN LoadTeamTurnsFromTheSavedGameFile( HWFILE hFile )
BOOLEAN NPCFirstDraw( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTargetSoldier ) BOOLEAN NPCFirstDraw( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTargetSoldier )
{ {
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPCFirstDraw"); DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"NPCFirstDraw");
// if attacking an NPC check to see who draws first! // if attacking an NPC check to see who draws first!
if ( pTargetSoldier->ubProfile != NO_PROFILE && pTargetSoldier->ubProfile != SLAY && pTargetSoldier->aiData.bNeutral && pTargetSoldier->aiData.bOppList[ pSoldier->ubID ] == SEEN_CURRENTLY && ( FindAIUsableObjClass( pTargetSoldier, IC_WEAPON ) != NO_SLOT ) ) if ( pTargetSoldier->ubProfile != NO_PROFILE && pTargetSoldier->ubProfile != SLAY && pTargetSoldier->aiData.bNeutral && pTargetSoldier->aiData.bOppList[ pSoldier->ubID ] == SEEN_CURRENTLY && ( FindAIUsableObjClass( pTargetSoldier, IC_WEAPON ) != NO_SLOT ) )
+201 -102
View File
@@ -2473,7 +2473,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
//no crates in sector inventory. search merc inventories //no crates in sector inventory. search merc inventories
if(mergeSuccessful == false) if(mergeSuccessful == false)
{ {
for(int loop=0; loop<18; loop++) for(int loop=0; loop<(int)gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs; loop++)
{ {
if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector) if(MercPtrs[loop]->bActive && MercPtrs[loop]->bInSector)
{ {
@@ -2818,6 +2818,12 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
//Display the range to the target //Display the range to the target
DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], sGridNo ); DisplayRangeToTarget( MercPtrs[ gusSelectedSoldier ], sGridNo );
} }
#ifdef JA2TESTVERSION
CHAR16 zOutputString[512];
swprintf( zOutputString, L"gridno: %d", sGridNo);
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
#endif
} }
} }
break; break;
@@ -3302,8 +3308,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
INT8 bLoop; INT8 bLoop;
for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++) for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
{ {
if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) ) {
{
SwapGoggles(pTeamSoldier); SwapGoggles(pTeamSoldier);
} }
} }
@@ -5554,134 +5559,228 @@ void PopupMilitiaControlMenu( SOLDIERTYPE *pSoldier )
gfIgnoreScrolling = TRUE; gfIgnoreScrolling = TRUE;
} }
INT32 PickPocket(MERCPROFILESTRUCT *pProfile, UINT8 ppStart, UINT8 ppStop, UINT16 usItem, UINT8 iNumber, UINT8 * cap);
bool BadGoggles(SOLDIERTYPE *pTeamSoldier) {
// WDS - Smart goggle switching
// NOTE: Investigate using GetItemVisionRangeBonus from Items.cpp???
if (!gGameExternalOptions.smartGoggleSwitch) {
return false;
} else {
// Look through the head slots and find any sort of goggle. Check if it is bad for this time of day.
for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot) {
if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus > 0) && !DayTime() ) {
return true;
} else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus > 0) && DayTime() ) {
return true;
}
}
// Find the best goggles for the current time of day anywhere in inventory
OBJECTTYPE * pGoggles = 0;
if (DayTime()) {
pGoggles = FindSunGogglesInInv( pTeamSoldier, TRUE );
} else {
pGoggles = FindNightGogglesInInv( pTeamSoldier, TRUE );
}
if (pGoggles) {
// Check that the player is actually wearing them
for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot) {
if (!(pTeamSoldier->inv[headSlot] == *pGoggles)) {
// return true;
}
}
}
}
return false;
}
void SwapGoggles(SOLDIERTYPE *pTeamSoldier) void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
{ {
/* CHRISL - Adjusted this option to allow the game to search through Helmet attachments /* CHRISL - Adjusted this option to allow the game to search through Helmet attachments
as well as inventory positions. as well as inventory positions.
*/ */
OBJECTTYPE * pObj;
OBJECTTYPE * pGoggles = NULL; // WDS - Smart goggle switching
INT8 bSlot1; // NOTE: Investigate using GetItemVisionRangeBonus from Items.cpp???
int bestBonus; if (gGameExternalOptions.smartGoggleSwitch) {
bool itemFound = false; // Look through the head slots and find any sort of goggle or an empty spot
//CHRISL: Before doing anything, we should look at both head slots to see if either slot has some sort of goggles int slotToUse = -1;
for(bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++) for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot) {
{ if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus > 0) ) {
if(Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0) slotToUse = headSlot;
itemFound = true;
if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0)
itemFound = true;
}
//2 head slots
for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
{
// if wearing sungoggles
if ( Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0 )
{
itemFound = true;
bestBonus = 0;
pGoggles = FindNightGogglesInInv( pTeamSoldier );
//search for better goggles on the helmet
if (pGoggles)
{
bestBonus = Item[pGoggles->usItem].nightvisionrangebonus;
}
//search helmet and vest
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
{
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
}
}
}
if ( pGoggles )
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
break; break;
} else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus > 0) ) {
slotToUse = headSlot;
break;
} else if (pTeamSoldier->inv[headSlot].exists() == false) {
slotToUse = headSlot;
} }
} }
// else if wearing NVGs if (slotToUse == -1) {
else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0) // No place to swap in a new goggle, give up
{ return;
itemFound = true; }
bestBonus = 0;
pGoggles = FindSunGogglesInInv( pTeamSoldier ); // Find the best goggles for the current time of day anywhere in inventory
//search for better goggles on the helmet OBJECTTYPE * pGoggles = 0;
if (pGoggles) if (DayTime()) {
{ pGoggles = FindSunGogglesInInv( pTeamSoldier, TRUE );
bestBonus = Item[pGoggles->usItem].brightlightvisionrangebonus; } else {
pGoggles = FindNightGogglesInInv( pTeamSoldier, TRUE );
}
if (pGoggles) {
// Now either swap or equip the best one that was found
if (pTeamSoldier->inv[slotToUse].exists()) {
SwapObjs( pTeamSoldier, slotToUse, pGoggles, TRUE );
} else {
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[slotToUse], 1, pTeamSoldier, slotToUse);
} }
//search helmet and vest } else {
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++) // No goggles to equip, should the current ones be unequiped?
{ if (pTeamSoldier->inv[slotToUse].exists()) {
pObj = &(pTeamSoldier->inv[gear]); if ((DayTime() && (Item[pTeamSoldier->inv[slotToUse].usItem].nightvisionrangebonus > 0)) ||
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) (!DayTime() && (Item[pTeamSoldier->inv[slotToUse].usItem].brightlightvisionrangebonus > 0))) {
{ // It's day and we're wearing night goggles (or vice-versa), find a place to stash them
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE ) if (pTeamSoldier->inv[ HELMETPOS ].exists()) {
{ if (pTeamSoldier->inv[ HELMETPOS ].AttachObject( NULL, &pTeamSoldier->inv[slotToUse] )) {
pGoggles = &(*iter); // It worked!
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus; } else {
// Try dumping it anywhere in inventory because it doesn't attach to the helmet
}
} else {
// Try dumping it anywhere in inventory given there's no helemt
} }
} }
} }
if ( pGoggles )
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
break;
}
} }
// else if not wearing anything and no goggles found } else {
else if(itemFound == false && pTeamSoldier->inv[bSlot1].exists() == false) // Normal goggle switching
OBJECTTYPE * pObj;
OBJECTTYPE * pGoggles = NULL;
INT8 bSlot1;
int bestBonus;
bool itemFound = false;
//CHRISL: Before doing anything, we should look at both head slots to see if either slot has some sort of goggles
for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++) {
if ((Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0) ||
(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0))
itemFound = true;
}
//2 head slots
for (bSlot1 = HEAD1POS; bSlot1 <= HEAD2POS; bSlot1++)
{ {
bestBonus = 0; // if wearing sungoggles
// search helmet and vest for goggles of some kind if ( (Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus > 0) )
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
{ {
pObj = &(pTeamSoldier->inv[gear]); bestBonus = 0;
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) pGoggles = FindNightGogglesInInv( pTeamSoldier );
//search for better goggles on the helmet
if (pGoggles)
{ {
if(DayTime() == TRUE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE) bestBonus = Item[pGoggles->usItem].nightvisionrangebonus;
}
//search helmet and vest
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
{
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{ {
pGoggles = &(*iter); if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
bestBonus = Item[iter->usItem].brightlightvisionrangebonus; {
} pGoggles = &(*iter);
else if(NightTime() == TRUE && Item[iter->usItem].nightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE) bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
{ }
pGoggles = &(*iter);
bestBonus = Item[iter->usItem].nightvisionrangebonus;
} }
} }
if(pGoggles) if ( pGoggles )
{
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[bSlot1], 1, pTeamSoldier, bSlot1);
pObj->RemoveAttachment(pGoggles);
break;
}
}
if(pTeamSoldier->inv[bSlot1].exists() == false)
{
if(DayTime() == TRUE)
pGoggles = FindSunGogglesInInv( pTeamSoldier );
else
pGoggles = FindNightGogglesInInv( pTeamSoldier );
if(pGoggles)
{ {
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE ); SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
break; break;
} }
} }
else // else if wearing NVGs
else if(Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus > 0 )
{ {
break; bestBonus = 0;
pGoggles = FindSunGogglesInInv( pTeamSoldier );
//search for better goggles on the helmet
if (pGoggles)
{
bestBonus = Item[pGoggles->usItem].brightlightvisionrangebonus;
}
//search helmet and vest
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
{
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus;
}
}
}
if ( pGoggles )
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
break;
}
}
// else if not wearing anything and no goggles found
else if(itemFound == false && pTeamSoldier->inv[bSlot1].exists() == false)
{
bestBonus = 0;
// search helmet and vest for goggles of some kind
for(UINT8 gear = HELMETPOS; gear <= VESTPOS; gear++)
{
pObj = &(pTeamSoldier->inv[gear]);
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
if(DayTime() == TRUE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
{
pGoggles = &(*iter);
bestBonus = Item[iter->usItem].brightlightvisionrangebonus;
}
else if(NightTime() == TRUE && Item[iter->usItem].nightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
{
pGoggles = &(*iter);
bestBonus = Item[iter->usItem].nightvisionrangebonus;
}
}
if(pGoggles)
{
pGoggles->MoveThisObjectTo(pTeamSoldier->inv[bSlot1], 1, pTeamSoldier, bSlot1);
pObj->RemoveAttachment(pGoggles);
break;
}
}
if(pTeamSoldier->inv[bSlot1].exists() == false)
{
if(DayTime() == TRUE)
pGoggles = FindSunGogglesInInv( pTeamSoldier );
else
pGoggles = FindNightGogglesInInv( pTeamSoldier );
if(pGoggles)
{
SwapObjs( pTeamSoldier, bSlot1, pGoggles, TRUE );
break;
}
}
else
{
break;
}
} }
} }
} }
fCharacterInfoPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE;
fTeamPanelDirty = TRUE; fTeamPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2; fInterfacePanelDirty = DIRTYLEVEL2;
+69 -51
View File
@@ -38,9 +38,11 @@
#include "Soldier macros.h" #include "Soldier macros.h"
#include "opplist.h" #include "opplist.h"
#include "Soldier ani.h" #include "Soldier ani.h"
#include "GameSettings.h"
#endif #endif
INT8 gubVehicleMovementGroups[ MAX_VEHICLES ]; //INT8 gubVehicleMovementGroups[ MAX_VEHICLES ];
std::vector<INT8> gubVehicleMovementGroups (MAX_VEHICLES, 0);
// the list of vehicles // the list of vehicles
VEHICLETYPE *pVehicleList = NULL; VEHICLETYPE *pVehicleList = NULL;
@@ -174,23 +176,20 @@ void SetDriver( INT32 iID, UINT8 ubID );
void TeleportVehicleToItsClosestSector( INT32 iVehicleId, UINT8 ubGroupID ); void TeleportVehicleToItsClosestSector( INT32 iVehicleId, UINT8 ubGroupID );
void InitAVehicle(int index, int x, int y) {
gubVehicleMovementGroups[ index ] = CreateNewVehicleGroupDepartingFromSector( x, y, index );
// Set persistent....
GROUP *pGroup = GetGroup( gubVehicleMovementGroups[ index ] );
AssertNotNIL(pGroup);
pGroup->fPersistant = TRUE;
}
// Loop through and create a few soldier squad ID's for vehicles ( max # 3 ) // Loop through and create a few soldier squad ID's for vehicles
void InitVehicles( ) void InitAllVehicles( ) {
{ for( int cnt = 0; cnt < MAX_VEHICLES; cnt++ )
INT32 cnt; InitAVehicle(cnt, 1, 1);
GROUP *pGroup = NULL;
for( cnt = 0; cnt < MAX_VEHICLES; cnt++ )
{
// create mvt groups
gubVehicleMovementGroups[ cnt ] = CreateNewVehicleGroupDepartingFromSector( 1, 1, cnt );
// Set persistent....
pGroup = GetGroup( gubVehicleMovementGroups[ cnt ] );
pGroup->fPersistant = TRUE;
}
} }
@@ -431,7 +430,7 @@ BOOLEAN IsThisVehicleAccessibleToSoldier( SOLDIERTYPE *pSoldier, INT32 iId )
BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId ) BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
{ {
INT32 iCounter = 0; INT32 iCounter = 0;
INT8 vCount = 0; UINT32 vCount = 0;
SOLDIERTYPE *pVehicleSoldier = NULL; SOLDIERTYPE *pVehicleSoldier = NULL;
@@ -453,7 +452,7 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
pVehicleSoldier = GetSoldierStructureForVehicle( iId ); pVehicleSoldier = GetSoldierStructureForVehicle( iId );
//CHRISL: Get number of vehicles currently in player team //CHRISL: Get number of vehicles currently in player team
for(int x = 0; x < 20; x++) for(int x = 0; x < CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS; x++)
{ {
if(MercPtrs[x]->bTeam == OUR_TEAM && (MercPtrs[x]->flags.uiStatusFlags & SOLDIER_VEHICLE) && MercPtrs[x]->bActive == TRUE) if(MercPtrs[x]->bTeam == OUR_TEAM && (MercPtrs[x]->flags.uiStatusFlags & SOLDIER_VEHICLE) && MercPtrs[x]->bActive == TRUE)
vCount ++; vCount ++;
@@ -464,7 +463,7 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
if ( pVehicleSoldier->bTeam != gbPlayerNum ) if ( pVehicleSoldier->bTeam != gbPlayerNum )
{ {
// Can we add a new vehicle // Can we add a new vehicle
if( vCount >= 2 ) if( vCount >= gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles )
{ {
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[VEHICLE_CAN_NOT_BE_ADDED] ); ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[VEHICLE_CAN_NOT_BE_ADDED] );
return( FALSE ); return( FALSE );
@@ -1793,30 +1792,24 @@ INT16 GetOrigInternalArmorValueForVehicleInLocation( UINT8 ubID, UINT8 ubLocatio
SOLDIERTYPE * GetSoldierStructureForVehicle( INT32 iId ) SOLDIERTYPE * GetSoldierStructureForVehicle( INT32 iId )
{ {
SOLDIERTYPE *pSoldier = NULL, *pFoundSoldier = NULL; for( INT32 iCounter = 0; iCounter < TOTAL_SOLDIERS; iCounter++ )
INT32 iCounter = 0, iNumberOnTeam = 0;
// get number of mercs on team
iNumberOnTeam = TOTAL_SOLDIERS; //gTacticalStatus.Team[ OUR_TEAM ].bLastID;
for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ )
{ {
pSoldier = &Menptr[ iCounter ]; SOLDIERTYPE *pSoldier = &Menptr[ iCounter ];
if ( pSoldier->bActive ) if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{ {
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) if ( pSoldier->bActive )
{ {
if( pSoldier->bVehicleID == iId ) if( pSoldier->bVehicleID == iId )
{ {
pFoundSoldier = pSoldier; return( pSoldier );
iCounter = iNumberOnTeam;
} }
} }
} }
} }
return( pFoundSoldier ); // Didn't find the vehicle
return( 0 );
} }
@@ -2153,10 +2146,16 @@ BOOLEAN SaveVehicleMovementInfoToSavedGameFile( HWFILE hFile )
{ {
UINT32 uiNumBytesWritten = 0; UINT32 uiNumBytesWritten = 0;
//Save all the vehicle movement id's //Save all the vehicle movement id's
FileWrite( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * 5, &uiNumBytesWritten ); // FileWrite( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * 5, &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( INT8 ) * 5 ) // if( uiNumBytesWritten != sizeof( INT8 ) * 5 )
{ // {
return(FALSE); // return(FALSE);
// }
for (int cnt=0; cnt<5; ++cnt) {
FileWrite( hFile, &gubVehicleMovementGroups[cnt], sizeof( INT8 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( INT8 ) ) {
return(FALSE);
}
} }
return( TRUE ); return( TRUE );
@@ -2165,17 +2164,22 @@ BOOLEAN SaveVehicleMovementInfoToSavedGameFile( HWFILE hFile )
BOOLEAN LoadVehicleMovementInfoFromSavedGameFile( HWFILE hFile ) BOOLEAN LoadVehicleMovementInfoFromSavedGameFile( HWFILE hFile )
{ {
INT32 cnt;
GROUP *pGroup = NULL; GROUP *pGroup = NULL;
UINT32 uiNumBytesRead=0; UINT32 uiNumBytesRead=0;
//Load in the Squad movement id's //Load in the Squad movement id's
FileRead( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * 5, &uiNumBytesRead ); // FileRead( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * 5, &uiNumBytesRead );
if( uiNumBytesRead != sizeof( INT8 ) * 5 ) // if( uiNumBytesRead != sizeof( INT8 ) * 5 )
{ // {
return(FALSE); // return(FALSE);
// }
for (int cnt=0; cnt<5; ++cnt) {
FileRead( hFile, &gubVehicleMovementGroups[cnt], sizeof( INT8 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( INT8 ) ) {
return(FALSE);
}
} }
for( cnt = 5; cnt < MAX_VEHICLES; cnt++ ) for( int cnt = 5; cnt < MAX_VEHICLES; cnt++ )
{ {
// create mvt groups // create mvt groups
gubVehicleMovementGroups[ cnt ] = CreateNewVehicleGroupDepartingFromSector( 1, 1, cnt ); gubVehicleMovementGroups[ cnt ] = CreateNewVehicleGroupDepartingFromSector( 1, 1, cnt );
@@ -2193,10 +2197,16 @@ BOOLEAN NewSaveVehicleMovementInfoToSavedGameFile( HWFILE hFile )
{ {
UINT32 uiNumBytesWritten = 0; UINT32 uiNumBytesWritten = 0;
//Save all the vehicle movement id's //Save all the vehicle movement id's
FileWrite( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * MAX_VEHICLES, &uiNumBytesWritten ); // FileWrite( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * MAX_VEHICLES, &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( INT8 ) * MAX_VEHICLES ) // if( uiNumBytesWritten != sizeof( INT8 ) * MAX_VEHICLES )
{ // {
return(FALSE); // return(FALSE);
// }
for (int cnt=0; cnt<MAX_VEHICLES; ++cnt) {
FileWrite( hFile, &gubVehicleMovementGroups[cnt], sizeof( INT8 ), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( INT8 ) ) {
return(FALSE);
}
} }
return( TRUE ); return( TRUE );
@@ -2207,10 +2217,16 @@ BOOLEAN NewLoadVehicleMovementInfoFromSavedGameFile( HWFILE hFile )
{ {
UINT32 uiNumBytesRead=0; UINT32 uiNumBytesRead=0;
//Load in the Squad movement id's //Load in the Squad movement id's
FileRead( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * MAX_VEHICLES, &uiNumBytesRead ); // FileRead( hFile, gubVehicleMovementGroups, sizeof( INT8 ) * MAX_VEHICLES, &uiNumBytesRead );
if( uiNumBytesRead != sizeof( INT8 ) * MAX_VEHICLES ) // if( uiNumBytesRead != sizeof( INT8 ) * MAX_VEHICLES )
{ // {
return(FALSE); // return(FALSE);
// }
for (int cnt=0; cnt<MAX_VEHICLES; ++cnt) {
FileRead( hFile, &gubVehicleMovementGroups[cnt], sizeof( INT8 ), &uiNumBytesRead );
if( uiNumBytesRead != sizeof( INT8 ) ) {
return(FALSE);
}
} }
return( TRUE ); return( TRUE );
@@ -2472,7 +2488,9 @@ BOOLEAN IsSoldierInThisVehicleSquad( SOLDIERTYPE *pSoldier, INT8 bSquadNumber )
SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier ) SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier )
{ {
UINT8 ubMercsInSector[ 20 ] = { 0 }; // WDS - make number of mercenaries, etc. be configurable
std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0);
// UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 };
UINT8 ubNumMercs = 0; UINT8 ubNumMercs = 0;
UINT8 ubChosenMerc; UINT8 ubChosenMerc;
INT32 iCounter, iId; INT32 iCounter, iId;
+5
View File
@@ -7,6 +7,7 @@
#include "Strategic Movement.h" #include "Strategic Movement.h"
#define MAX_VEHICLES 10 #define MAX_VEHICLES 10
extern std::vector<INT8> gubVehicleMovementGroups;
// type of vehicles // type of vehicles
enum{ enum{
@@ -233,5 +234,9 @@ BOOLEAN DoesVehicleGroupHaveAnyPassengers( GROUP *pGroup );
void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId ); void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId );
void InitAVehicle(int index, int x, int y);
void InitAllVehicles( );
#endif #endif

Some files were not shown because too many files have changed in this diff Show More