New Feature: Added up to 15 game difficulty settings (by Jazz)

- Externalized the difficulty setings to "TableData\DifficultySettings.xml" file
- Some INI Settings (ja2_options.ini, CTHConstants.ini and Creature_Settings.ini) moved from INI file to this xml file
- see #define DIFFICULTY_SETTING

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7447 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2014-08-28 10:30:40 +00:00
parent 6b728e56ac
commit 344797f6af
47 changed files with 1976 additions and 49 deletions
+14 -1
View File
@@ -75,6 +75,10 @@
#include "Vehicles.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -5651,6 +5655,10 @@ void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
return;
UINT8 normalgroupsize = 0;
#ifdef DIFFICULTY_SETTING
normalgroupsize = zDeffSetting[gGameOptions.ubDifficultyLevel].iMinEnemyGroupSize;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -5667,6 +5675,7 @@ void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ )
normalgroupsize = gGameExternalOptions.ubMinEnemyGroupSizeInsane;
break;
}
#endif
normalgroupsize *= 2;
@@ -5997,6 +6006,10 @@ void HandleGatheringInformationBySoldier( SOLDIERTYPE* pSoldier )
}
UINT16 usNormalGroupSize = 0;
#ifdef DIFFICULTY_SETTING
usNormalGroupSize = zDeffSetting[gGameOptions.ubDifficultyLevel].iMinEnemyGroupSize;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -6013,7 +6026,7 @@ void HandleGatheringInformationBySoldier( SOLDIERTYPE* pSoldier )
usNormalGroupSize = gGameExternalOptions.ubMinEnemyGroupSizeInsane;
break;
}
#endif
usNormalGroupSize *= 2;
FLOAT fBaseChance = ( EffectiveLeadership(pSoldier) + EffectiveWisdom(pSoldier) + EffectiveExpLevel(pSoldier) * 10 ) / 3000.0f;
+36 -4
View File
@@ -24,6 +24,10 @@
#include "UndergroundInit.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
extern BOOLEAN InitStrategicMovementCosts();
void InitKnowFacilitiesFlags( );
@@ -428,6 +432,9 @@ void BuildUndergroundSectorInfoList()
//J9
curr = NewUndergroundNode( 9, 10, 1 );
#ifdef DIFFICULTY_SETTING
curr->ubNumTroops = zDeffSetting[gGameOptions.ubDifficultyLevel].iJ9B1NumTroops;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -443,22 +450,47 @@ void BuildUndergroundSectorInfoList()
curr->ubNumTroops = 20;
break;
}
#endif
//J9 feeding zone
curr = NewUndergroundNode( 9, 10, 2 );
#ifdef DIFFICULTY_SETTING
curr->ubNumCreatures = (UINT8)(2 + zDeffSetting[gGameOptions.ubDifficultyLevel].iJ9B2NumCreatures*2 + Random( 2 ));
#else
curr->ubNumCreatures = (UINT8)(2 + gGameOptions.ubDifficultyLevel*2 + Random( 2 ));
#endif
//K4
curr = NewUndergroundNode( 4, 11, 1 );
#ifdef DIFFICULTY_SETTING
curr->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iK4B1NumTroops*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + zDeffSetting[gGameOptions.ubDifficultyLevel].iK4B1NumElites + Random( 2 ));
#else
curr->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + gGameOptions.ubDifficultyLevel + Random( 2 ));
#endif
//O3
curr = NewUndergroundNode( 3, 15, 1 );
#ifdef DIFFICULTY_SETTING
curr->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iO3B1NumTroops*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + zDeffSetting[gGameOptions.ubDifficultyLevel].iO3B1NumElites + Random( 2 ));
#else
curr->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel*2 + Random( 3 ));
curr->ubNumElites = (UINT8)(4 + gGameOptions.ubDifficultyLevel + Random( 2 ));
#endif
//P3
curr = NewUndergroundNode( 3, 16, 1 );
#ifdef DIFFICULTY_SETTING
if (gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
curr->ubNumElites = (UINT8)(zDeffSetting[gGameOptions.ubDifficultyLevel].iP3B1NumElites + Random( 3 ));
else if (gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
curr->ubNumElites = (UINT8)(zDeffSetting[gGameOptions.ubDifficultyLevel].iP3B1NumElites + Random( 5 ));
else if (gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
curr->ubNumElites = (UINT8)(zDeffSetting[gGameOptions.ubDifficultyLevel].iP3B1NumElites + Random( 6 ));
else
curr->ubNumElites = zDeffSetting[gGameOptions.ubDifficultyLevel].iP3B1NumElites;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -474,7 +506,7 @@ void BuildUndergroundSectorInfoList()
curr->ubNumElites = 20;
break;
}
#endif
//Do all of the mandatory underground mine sectors
//Drassen's mine
+33 -1
View File
@@ -36,6 +36,9 @@
#include "Strategic Mines.h"
#include "connect.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#ifdef JA2BETAVERSION
BOOLEAN gfClearCreatureQuest = FALSE;
@@ -345,6 +348,10 @@ void InitCreatureQuest()
}
#endif
giHabitatedDistance = 0;
#ifdef DIFFICULTY_SETTING
giPopulationModifier = zDeffSetting[gGameOptions.ubDifficultyLevel].iCreaturePopulationModifier;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -360,7 +367,8 @@ void InitCreatureQuest()
giPopulationModifier = INSANE_POPULATION_MODIFIER;
break;
}
#endif
//Determine which of the maps are infectible by creatures. Infectible mines
//are those that are player controlled and unlimited. We don't want the creatures to
//infect the mine that runs out.
@@ -508,6 +516,11 @@ void InitCreatureQuest()
curr->uiFlags |= SF_PENDING_ALTERNATE_MAP;
//Now determine how often we will spread the creatures.
#ifdef DIFFICULTY_SETTING
i = zDeffSetting[gGameOptions.ubDifficultyLevel].iQueenInitBonusSpread;
AddPeriodStrategicEvent( EVENT_CREATURE_SPREAD, zDeffSetting[gGameOptions.ubDifficultyLevel].iCreatureSpreadTime, 0 );
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -527,6 +540,7 @@ void InitCreatureQuest()
AddPeriodStrategicEvent( EVENT_CREATURE_SPREAD, INSANE_SPREAD_TIME_IN_MINUTES, 0 );
break;
}
#endif
//Set things up so that the creatures can plan attacks on helpless miners and civilians while
//they are sleeping. They do their planning at 10PM every day, and decide to attack sometime
@@ -637,6 +651,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"CreatureSpreading1");
case DIF_LEVEL_INSANE: //200%
iAbsoluteMaxPopulation *= 2;
break;
#ifdef DIFFICULTY_SETTING
default:
iAbsoluteMaxPopulation /= 2; //Half
break;
#endif
}
//Calculate the desired max population percentage based purely on current distant to creature range.
@@ -682,6 +701,9 @@ void SpreadCreatures()
}
//queen just produced a litter of creature larvae. Let's do some spreading now.
#ifdef DIFFICULTY_SETTING
usNewCreatures = (UINT16)( zDeffSetting[gGameOptions.ubDifficultyLevel].iQueenReproductionBase + Random( 1 + zDeffSetting[gGameOptions.ubDifficultyLevel].iQueenReproductionBonus ));
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -697,6 +719,7 @@ void SpreadCreatures()
usNewCreatures = (UINT16)(INSANE_QUEEN_REPRODUCTION_BASE + Random( 1 + INSANE_QUEEN_REPRODUCTION_BONUS ));
break;
}
#endif
while( usNewCreatures-- )
{
@@ -1737,6 +1760,14 @@ void CreatureNightPlanning()
ubNumCreatures = CreaturesInUndergroundSector( ubSectorID , 1 );
//10% chance for each creature with difficulty modifier to decide it's time to attack.
#ifdef DIFFICULTY_SETTING
i = zDeffSetting[gGameOptions.ubDifficultyLevel].iCreatureTownAggressiveness;
if( ubNumCreatures > 1 && ubNumCreatures * 10 + i > (INT32)PreRandom( 100 ) )
{
AddStrategicEvent( EVENT_CREATURE_ATTACK, GetWorldTotalMin() + 1 + PreRandom( 429 ), ubSectorID );
}
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -1768,6 +1799,7 @@ void CreatureNightPlanning()
}
break;
}
#endif
//if( ubNumCreatures > 1 && ubNumCreatures * 10 > (INT32)PreRandom( 100 ) )
//{ //10% chance for each creature to decide it's time to attack.
// AddStrategicEvent( EVENT_CREATURE_ATTACK, GetWorldTotalMin() + 1 + PreRandom( 429 ), ubSectorID );
+12
View File
@@ -84,6 +84,10 @@
#include "Map Screen Interface Bottom.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#include "PostalService.h"
extern CPostalService gPostalService;
@@ -558,6 +562,10 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
AutoSaveToSlot[3] = FALSE;
AutoSaveToSlot[4] = FALSE;
#ifdef DIFFICULTY_SETTING
gGameExternalOptions.gfAllowReinforcements = zDeffSetting[gGameOptions.ubDifficultyLevel].bAllowReinforcements;
#endif
#ifdef JA2UB
//Ja25 no meanwhiles
@@ -740,6 +748,9 @@ fFirstTimeInMapScreen = TRUE;
}
// ATE: Set starting cash....
#ifdef DIFFICULTY_SETTING
iStartingCash = zDeffSetting[gGameOptions.ubDifficultyLevel].iStartingCash;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -770,6 +781,7 @@ fFirstTimeInMapScreen = TRUE;
Assert(0);
return( FALSE );
}
#endif
// Setup initial money
AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), iStartingCash );
+46
View File
@@ -45,6 +45,10 @@
#include "Music Control.h"
#include "NPC.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#ifdef JA2UB
#include "Ja25 Strategic Ai.h"
#include "Ja25_Tactical.h"
@@ -81,6 +85,8 @@ extern INT8 Test;
static int l_HireMerc (lua_State *L);
static int l_SetStartingCashDifLevel (lua_State *L);
//Briefing room
static int l_SetEndMission(lua_State *L);
static int l_SetStartMission(lua_State *L);
@@ -932,6 +938,8 @@ void IniFunction(lua_State *L, BOOLEAN bQuests )
{
lua_register(L, "HireMerc", l_HireMerc);
lua_register(L, "SetStartingCashDifLevel", l_SetStartingCashDifLevel);
lua_register(L, "SetLaptopBroken", l_SetLaptopBroken);
//------Briefing Room------
@@ -12951,3 +12959,41 @@ BOOLEAN LoadLuaGlobalFromLoadGameFile( HWFILE hFile )
return( TRUE );
}
//--------------------------------------------------------------
static int l_SetStartingCashDifLevel (lua_State *L)
{
if ( lua_gettop(L) >= 1 )
{
INT32 DifficultyLevel = lua_tointeger(L,1);
INT32 iStartingCash = 0;
#ifdef DIFFICULTY_SETTING
AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), zDeffSetting[DifficultyLevel].iStartingCash );
#else
switch( DifficultyLevel )
{
case DIF_LEVEL_EASY:
iStartingCash = gGameExternalOptions.iStartingCashNovice;
break;
case DIF_LEVEL_MEDIUM:
iStartingCash = gGameExternalOptions.iStartingCashExperienced;
break;
case DIF_LEVEL_HARD:
iStartingCash = gGameExternalOptions.iStartingCashExpert;
break;
case DIF_LEVEL_INSANE:
iStartingCash = gGameExternalOptions.iStartingCashInsane;
break;
default:
iStartingCash = 4500;
}
AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), iStartingCash );
#endif
}
return 0;
}
+9
View File
@@ -38,6 +38,10 @@
#include "Random.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#define MAX_MEANWHILE_PROFILES 10
INT8 gzMeanwhileStr[][30] =
@@ -697,7 +701,12 @@ void ProcessImplicationsOfMeanwhile( void )
switch( gCurrentMeanwhileDef.ubMeanwhileID )
{
case END_OF_PLAYERS_FIRST_BATTLE:
#ifdef DIFFICULTY_SETTING
if( zDeffSetting[gGameOptions.ubDifficultyLevel].bStrategicAiActionWakeQueen == TRUE )
#else
if( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
#endif
{ //Wake up the queen earlier to punish the good players!
ExecuteStrategicAIAction( STRATEGIC_AI_ACTION_WAKE_QUEEN, 0, 0 );
}
+9
View File
@@ -32,6 +32,10 @@
#include "postalservice.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
extern BOOLEAN fMapScreenBottomDirty;
extern CPostalService gPostalService;
@@ -326,7 +330,11 @@ BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, B
if ( !SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled )
{
// grant grace period
#ifdef DIFFICULTY_SETTING
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + zDeffSetting[gGameOptions.ubDifficultyLevel].iUpdateLastDayOfPlayerActivity ) );
#else
if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) );
}
@@ -334,6 +342,7 @@ BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, B
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 1 ) );
}
#endif
}
}
+9
View File
@@ -54,6 +54,10 @@
#include "ub_config.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
extern void InitializeTacticalStatusAtBattleStart();
extern BOOLEAN gfDelayAutoResolveStart;
extern BOOLEAN gfTransitionMapscreenToAutoResolve;
@@ -652,6 +656,10 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
iChance -= (2 * ((ubNumMobileEnemies + ubNumStationaryEnemies) - 6)); // -2% adjustment per enemy beyond 6
// adjust the chance for difficulty setting
#ifdef DIFFICULTY_SETTING
iChance = iChance + (zDeffSetting[gGameOptions.ubDifficultyLevel].iChanceOfEnemyAmbushes);
#else
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
iChance -= 15;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
@@ -660,6 +668,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
iChance += 12;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
iChance += 25;
#endif
// adjust the chance for what we know about the sector
if( WhatPlayerKnowsAboutEnemiesInSector( gubPBSectorX, gubPBSectorY ) == KNOWS_NOTHING )
+8
View File
@@ -64,6 +64,10 @@
#include "Arms Dealer Init.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#include <vector>
//The sector information required for the strategic AI. Contains the number of enemy troops,
@@ -569,7 +573,11 @@ BOOLEAN PrepareEnemyForSectorBattle()
// Reinforcement groups? Bring it on!
if( gGameExternalOptions.gfAllowReinforcements &&
#ifdef DIFFICULTY_SETTING
!( (GetTownIdForSector( gWorldSectorX, gWorldSectorY ) == OMERTA ) ) )
#else
!( (GetTownIdForSector( gWorldSectorX, gWorldSectorY ) == OMERTA )&&( gGameOptions.ubDifficultyLevel != DIF_LEVEL_INSANE ) ) )
#endif
{
UINT16 pusMoveDir[4][3];
UINT8 ubDirNumber = 0;
+10 -1
View File
@@ -24,6 +24,10 @@
#include "Inventory Choosing.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#include "connect.h"
#include "Reinforcement.h"
#include "MilitiaSquads.h"
@@ -49,9 +53,14 @@ void GetNumberOfEnemiesInFiveSectors( INT16 sSectorX, INT16 sSectorY, UINT8 *pub
if( !gGameExternalOptions.gfAllowReinforcements )
return;
#ifdef DIFFICULTY_SETTING
if ( ( GetTownIdForSector( sSectorX, sSectorY ) == OMERTA )&&( zDeffSetting[gGameOptions.ubDifficultyLevel].bAllowReinforcementsOmerta == FALSE ) ) //Madd: skip Omerta //Lal: but not on insane ;-)
return;
#else
if ( ( GetTownIdForSector( sSectorX, sSectorY ) == OMERTA )&&( gGameOptions.ubDifficultyLevel != DIF_LEVEL_INSANE ) ) //Madd: skip Omerta //Lal: but not on insane ;-)
return;
#endif
GenerateDirectionInfos( sSectorX, sSectorY, &ubDirNumber, pusMoveDir, FALSE, TRUE );
for( ubIndex = 0; ubIndex < ubDirNumber; ubIndex++ )
+425 -13
View File
@@ -37,6 +37,10 @@
#include "interface dialogue.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#define SAI_VERSION 29
/*
@@ -547,6 +551,10 @@ void Ensure_RepairedGarrisonGroup( GARRISON_GROUP **ppGarrison, INT32 *pGarraySi
//returns the number of reinforcements permitted to be sent. Will increased if the denied counter is non-zero.
INT32 GarrisonReinforcementsRequested( INT32 iGarrisonID, UINT8 *pubExtraReinforcements )
{
#ifdef DIFFICULTY_SETTING
INT32 iExtraReinforcements;
#endif
INT32 iReinforcementsRequested;
INT32 iExistingForces;
SECTORINFO *pSector;
@@ -561,7 +569,25 @@ INT32 GarrisonReinforcementsRequested( INT32 iGarrisonID, UINT8 *pubExtraReinfor
//Record how many of the reinforcements are additionally provided due to being denied in the past. This will grow
//until it is finally excepted or an absolute max is made.
#ifdef DIFFICULTY_SETTING
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
iExtraReinforcements = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
iExtraReinforcements = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
iExtraReinforcements = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
iExtraReinforcements = 4;
else
{
iExtraReinforcements = Random (4);
if (iExtraReinforcements == 0) iExtraReinforcements = 1;
}
*pubExtraReinforcements = (UINT8)(gubGarrisonReinforcementsDenied[ iGarrisonID ] / (6 - iExtraReinforcements));
#else
*pubExtraReinforcements = (UINT8)(gubGarrisonReinforcementsDenied[ iGarrisonID ] / (6 - gGameOptions.ubDifficultyLevel));
#endif
//Make sure the number of extra reinforcements don't bump the force size past the max of MAX_STRATEGIC_TEAM_SIZE.
*pubExtraReinforcements = (UINT16)min( (INT32)*pubExtraReinforcements, min( (INT32)(*pubExtraReinforcements), iMaxEnemyGroupSize - iReinforcementsRequested ) );
@@ -1164,6 +1190,19 @@ void InitStrategicAI()
dEnemyGeneralsSpeedupFactor = max( 0.5f, dEnemyGeneralsSpeedupFactor - gStrategicStatus.usVIPsLeft * gGameExternalOptions.fEnemyGeneralStrategicDecisionSpeedBonus );
}
#ifdef DIFFICULTY_SETTING
giReinforcementPool = zDeffSetting[gGameOptions.ubDifficultyLevel].iQueensInitialPoolOfTroops;
giForcePercentage = zDeffSetting[gGameOptions.ubDifficultyLevel].iInitialGarrisonPercentages;
giArmyAlertness = zDeffSetting[gGameOptions.ubDifficultyLevel].iEnemyStartingAlertLevel;
giArmyAlertnessDecay = zDeffSetting[gGameOptions.ubDifficultyLevel].iEnemyAlertDecay;
gubMinEnemyGroupSize = zDeffSetting[gGameOptions.ubDifficultyLevel].iMinEnemyGroupSize;
gubHoursGracePeriod = zDeffSetting[gGameOptions.ubDifficultyLevel].iGracePeriodInHoursAfterSectorLiberation;
gfUnlimitedTroops = zDeffSetting[gGameOptions.ubDifficultyLevel].bUnlimitedPoolOfTroops;
gfAggressiveQueen = zDeffSetting[gGameOptions.ubDifficultyLevel].bAggressiveQueenAi;
// 475 is 7:55am in minutes since midnight, the time the game starts on day 1
AddStrategicEvent( EVENT_EVALUATE_QUEEN_SITUATION, 475 + dEnemyGeneralsSpeedupFactor * (zDeffSetting[gGameOptions.ubDifficultyLevel].iBaseDelayInMinutesBetweenEvaluations + Random( zDeffSetting[gGameOptions.ubDifficultyLevel].iEvaluationDelayVariance )), 0 );
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -1212,6 +1251,7 @@ void InitStrategicAI()
AddStrategicEvent( EVENT_EVALUATE_QUEEN_SITUATION, 475 + dEnemyGeneralsSpeedupFactor * (gGameExternalOptions.ubInsaneTimeEvaluateInMinutes + Random( gGameExternalOptions.ubInsaneTimeEvaluateVariance )), 0);
break;
}
#endif
//Initialize the sectorinfo structure so all sectors don't point to a garrisonID.
for( i = 0; i <= 255; i++ )
@@ -1224,6 +1264,34 @@ void InitStrategicAI()
memcpy( gArmyComp, gOrigArmyComp, sizeof( gArmyComp ) );
//Eliminate more perimeter defenses on the easier levels.
#ifdef DIFFICULTY_SETTING
if (zDeffSetting[gGameOptions.ubDifficultyLevel].iDesiredPopulationL2 == FALSE)
{
gArmyComp[ LEVEL2_DEFENCE ].bDesiredPopulation = 0;
gArmyComp[ LEVEL2_DEFENCE ].bStartPopulation = 0;
}
if (zDeffSetting[gGameOptions.ubDifficultyLevel].iDesiredPopulationL3 == FALSE)
{
gArmyComp[ LEVEL3_DEFENCE ].bDesiredPopulation = 0;
gArmyComp[ LEVEL3_DEFENCE ].bStartPopulation = 0;
}
if (zDeffSetting[gGameOptions.ubDifficultyLevel].iDesiredPopulationL3 == FALSE && zDeffSetting[gGameOptions.ubDifficultyLevel].iDesiredPopulationL3 == FALSE)
{
for( i = 0; i < NUM_ARMY_COMPOSITIONS; i++ )
{
if ( i != OMERTA_WELCOME_WAGON )
{
iPercentElitesBonus = zDeffSetting[gGameOptions.ubDifficultyLevel].iPercentElitesBonus;
gArmyComp[ i ].bElitePercentage = min(100,gArmyComp[ i ].bElitePercentage + iPercentElitesBonus);
gArmyComp[ i ].bTroopPercentage = max(0,gArmyComp[ i ].bTroopPercentage - iPercentElitesBonus);
gArmyComp[ i ].bAdminPercentage = 0;
}
}
}
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -1286,7 +1354,7 @@ void InitStrategicAI()
}
break;
}
#endif
//initialize the patrol group definitions
giPatrolArraySize = iOrigPatrolArraySize;
if( gPatrolGroup )
@@ -1461,7 +1529,26 @@ void InitStrategicAI()
//Now post an event which allows them to check adjacent sectors periodically.
//Spread them out so that they process at different times.
#ifdef DIFFICULTY_SETTING
UINT32 val;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
val = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
val = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
val = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
val = 4;
else
{
val = Random( 4 );
if (val == 0) val = 1;
}
AddPeriodStrategicEventWithOffset( EVENT_CHECK_ENEMY_CONTROLLED_SECTOR, 140 - 20 * val + Random( 4 ), 475 + i, gGarrisonGroup[ i ].ubSectorID );
#else
AddPeriodStrategicEventWithOffset( EVENT_CHECK_ENEMY_CONTROLLED_SECTOR, 140 - 20 * gGameOptions.ubDifficultyLevel + Random( 4 ), 475 + i, gGarrisonGroup[ i ].ubSectorID );
#endif
}
//Now, initialize each of the patrol groups
@@ -1477,7 +1564,27 @@ void InitStrategicAI()
if( ubNumTroops && gGameExternalOptions.fArmyUsesTanksInPatrols )
{
#ifdef DIFFICULTY_SETTING
UINT32 val2;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
val2 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
val2 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
val2 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
val2 = 4;
else
{
val2 = Random( 4 );
if (val2 == 0) val2 = 1;
}
if( Random( 10 ) < val2 && i != 3 && i != 4)
#else
if( Random( 10 ) < gGameOptions.ubDifficultyLevel && i != 3 && i != 4)
#endif
{
ubNumTroops--;
ubNumTanks++;
@@ -1554,7 +1661,11 @@ void InitStrategicAI()
{
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache1X, gModSettings.ubWeaponCache1Y ) ]; //SEC_E11
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
#ifdef DIFFICULTY_SETTING
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops1 * 2);
#else
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
@@ -1572,7 +1683,11 @@ void InitStrategicAI()
{
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache2X, gModSettings.ubWeaponCache2Y ) ]; //SEC_H5
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
#ifdef DIFFICULTY_SETTING
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops2 * 2);
#else
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
@@ -1590,7 +1705,11 @@ void InitStrategicAI()
{
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache3X, gModSettings.ubWeaponCache3Y ) ]; //SEC_H10
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
#ifdef DIFFICULTY_SETTING
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops3 * 2);
#else
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
@@ -1608,7 +1727,11 @@ void InitStrategicAI()
{
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache4X, gModSettings.ubWeaponCache4Y ) ]; //SEC_J12
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
#ifdef DIFFICULTY_SETTING
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops4 * 2);
#else
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
@@ -1626,7 +1749,11 @@ void InitStrategicAI()
{
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache5X, gModSettings.ubWeaponCache5Y ) ]; //SEC_M9
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
#ifdef DIFFICULTY_SETTING
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops5 * 2);
#else
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
@@ -1648,6 +1775,28 @@ void InitStrategicAI()
}
else
{
#ifdef DIFFICULTY_SETTING
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache1X, gModSettings.ubWeaponCache1Y ) ]; //SEC_E11
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops1 * 2);
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache2X, gModSettings.ubWeaponCache2Y ) ]; //SEC_H5
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops2 * 2);
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache3X, gModSettings.ubWeaponCache3Y ) ]; //SEC_H10
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops3 * 2);
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache4X, gModSettings.ubWeaponCache4Y ) ]; //SEC_J12
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops4 * 2);
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache5X, gModSettings.ubWeaponCache5Y ) ]; //SEC_M9
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + zDeffSetting[gGameOptions.ubDifficultyLevel].iWeaponCacheTroops5 * 2);
#else
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache1X, gModSettings.ubWeaponCache1Y ) ]; //SEC_E11
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
@@ -1667,6 +1816,7 @@ void InitStrategicAI()
pSector = &SectorInfo[ SECTOR( gModSettings.ubWeaponCache5X, gModSettings.ubWeaponCache5Y ) ]; //SEC_M9
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
#endif
}
ValidateWeights( 1 );
@@ -3302,7 +3452,9 @@ void EvaluateQueenSituation()
{
dEnemyGeneralsSpeedupFactor = max( 0.5f, dEnemyGeneralsSpeedupFactor - gStrategicStatus.usVIPsLeft * gGameExternalOptions.fEnemyGeneralStrategicDecisionSpeedBonus );
}
#ifdef DIFFICULTY_SETTING
uiOffset += dEnemyGeneralsSpeedupFactor * (zDeffSetting[gGameOptions.ubDifficultyLevel].iBaseDelayInMinutesBetweenEvaluations + Random( zDeffSetting[gGameOptions.ubDifficultyLevel].iEvaluationDelayVariance ));
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -3318,12 +3470,19 @@ void EvaluateQueenSituation()
uiOffset += dEnemyGeneralsSpeedupFactor * (gGameExternalOptions.ubInsaneTimeEvaluateInMinutes + Random( gGameExternalOptions.ubInsaneTimeEvaluateVariance ));
break;
}
#endif
if( !giReinforcementPool )
{ //Queen has run out of reinforcements. Simulate recruiting and training new troops
uiOffset *= 10;
//Madd: don't need an unlimited troops check here, since they can never run out like this
#ifdef DIFFICULTY_SETTING
giReinforcementPool += ( zDeffSetting[gGameOptions.ubDifficultyLevel].iQueenPoolIncrementPerDifficultyLevel * gGameOptions.ubDifficultyLevel ) * ( 100 + CurrentPlayerProgressPercentage() ) / 100 ;
#else
giReinforcementPool += ( gGameExternalOptions.guiBaseQueenPoolIncrement * gGameOptions.ubDifficultyLevel ) * ( 100 + CurrentPlayerProgressPercentage() ) / 100 ;
#endif
AddStrategicEvent( EVENT_EVALUATE_QUEEN_SITUATION, GetWorldTotalMin() + uiOffset, 0 );
return;
}
@@ -3581,6 +3740,10 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
UINT8 ubSAIVersion;
INT32 iMaxEnemyGroupSize = gGameExternalOptions.iMaxEnemyGroupSize;
#ifdef DIFFICULTY_SETTING
gfUnlimitedTroops = zDeffSetting[gGameOptions.ubDifficultyLevel].bUnlimitedPoolOfTroops;
gfAggressiveQueen = zDeffSetting[gGameOptions.ubDifficultyLevel].bAggressiveQueenAi;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -3600,6 +3763,7 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
gfAggressiveQueen = gGameExternalOptions.gfInsaneAggressiveQueen;
break;
}
#endif
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic6");
FileRead( hFile, gbPadding2, 3, &uiNumBytesRead );
@@ -3934,6 +4098,12 @@ BOOLEAN LoadStrategicAI( HWFILE hFile )
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 12;
SectorInfo[ SEC_N5 ].bBloodCats = 15;
break;
#ifdef DIFFICULTY_SETTING
default:
SectorInfo[ SEC_N5 ].bBloodCatPlacements = 8;
SectorInfo[ SEC_N5 ].bBloodCats = 10;
break;
#endif
}
}
if( ubSAIVersion < 23 )
@@ -4237,8 +4407,27 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Strategic7");
//if gfExtraElites is set, then augment the composition sizes
if( gfExtraElites && iFactor >= 15 && gArmyComp[ i ].bElitePercentage )
{
#ifdef DIFFICULTY_SETTING
INT32 val;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
val = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
val = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
val = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
val = 4;
else
{
val = Random (4);
if (val == 0) val = 1;
}
iChange = val * 5;
#else
iChange = gGameOptions.ubDifficultyLevel * 5;
#endif
//increase elite % (max 100)
iNew = gArmyComp[ i ].bElitePercentage + iChange;
iNew = (INT8)min( 100, iNew );
@@ -4418,8 +4607,26 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
ubSourceSectorID = SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY );
}
#ifdef DIFFICULTY_SETTING
UINT8 val;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
val = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
val = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
val = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
val = 4;
else
{
val = Random (4);
if (val == 0) val = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + val * 3);
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
#endif
// anv: replace one of soldiers with tank
for( UINT8 ubCounter = 0; ubCounter < 4; ubCounter++ )
{
@@ -4427,19 +4634,28 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
grouptanks[ubCounter] = 0;
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
#ifdef DIFFICULTY_SETTING
if( Random(10) < val )
#else
if( Random(10) < gGameOptions.ubDifficultyLevel )
#endif
{
grouptroops[ubCounter]--;
grouptanks[ubCounter]++;
}
}
}
#ifdef DIFFICULTY_SETTING
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[0], grouptroops[0] - grouptroops[0] / val, grouptanks[0] );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[1], grouptroops[1] - grouptroops[1] / val, grouptanks[1] );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[2], grouptroops[2] - grouptroops[2] / val, grouptanks[2] );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[3], grouptroops[3] - grouptroops[3] / val, grouptanks[3] );
#else
pGroup0 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[0], grouptroops[0] - grouptroops[0] / gGameOptions.ubDifficultyLevel, grouptanks[0] );
pGroup1 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[1], grouptroops[1] - grouptroops[1] / gGameOptions.ubDifficultyLevel, grouptanks[1] );
pGroup2 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[2], grouptroops[2] - grouptroops[2] / gGameOptions.ubDifficultyLevel, grouptanks[2] );
pGroup3 = CreateNewEnemyGroupDepartingFromSector( ubSourceSectorID, 0, grouptroops[3], grouptroops[3] - grouptroops[3] / gGameOptions.ubDifficultyLevel, grouptanks[3] );
#endif
if( !gGarrisonGroup[ SectorInfo[ ubTargetSectorID ].ubGarrisonID ].ubPendingGroupID )
{
pGroup0->pEnemyGroup->ubIntention = STAGE;
@@ -4483,8 +4699,27 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
break;
}
#ifdef DIFFICULTY_SETTING
UINT8 value;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value = 4;
else
{
value = Random (4);
if (value == 0) value = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value * 3);
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
#endif
// anv: replace one of soldiers with tank
for( UINT8 ubCounter = 0; ubCounter < 4; ubCounter++ )
{
@@ -4492,15 +4727,24 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
grouptanks[ubCounter] = 0;
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
#ifdef DIFFICULTY_SETTING
if( Random(10) < gGameOptions.ubDifficultyLevel )
#else
if( Random(10) < value )
#endif
{
grouptroops[ubCounter]--;
grouptanks[ubCounter]++;
}
}
groupelites[ubCounter] = 0;
#ifdef DIFFICULTY_SETTING
if ( value > 0 )
groupelites[ubCounter] = grouptroops[ubCounter] - grouptroops[ubCounter] / value;
#else
if ( gGameOptions.ubDifficultyLevel > 0 )
groupelites[ubCounter] = grouptroops[ubCounter] - grouptroops[ubCounter] / gGameOptions.ubDifficultyLevel;
#endif
}
//UINT32 totalusedsoldiers = 4 * min(grouptroops + groupelites + ubNumTanks, (UINT32)gGameExternalOptions.iMaxEnemyGroupSize);
@@ -4678,9 +4922,26 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
BOOLEAN fAttack_Alma = !(SectorInfo[ SEC_I13 ].ubNumTroops > 0);
BOOLEAN fAttack_Balime = !(SectorInfo[ SEC_L11 ].ubNumTroops > 0);
BOOLEAN fAttack_Chitzena = !(SectorInfo[ SEC_L11 ].ubNumTroops > 0);
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
#ifdef DIFFICULTY_SETTING
UINT8 value2;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value2 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value2 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value2 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value2 = 4;
else
{
value2 = Random (4);
if (value2 == 0) value2 = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value2 * 3);
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 3);
#endif
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
@@ -4690,9 +4951,16 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
UINT32 grouptroops = ubNumSoldiers;
UINT32 groupelites = 0;
#ifdef DIFFICULTY_SETTING
if ( value2 > 0 )
#else
if ( gGameOptions.ubDifficultyLevel > 0 )
#endif
#ifdef DIFFICULTY_SETTING
groupelites = ubNumSoldiers - ubNumSoldiers / value2;
#else
groupelites = ubNumSoldiers - ubNumSoldiers / gGameOptions.ubDifficultyLevel;
#endif
UINT32 totalusedsoldiers = 0;
if ( fAttack_Grumm )
@@ -4927,12 +5195,34 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
//those troops will get reassigned.
ubSectorID = (UINT8)STRATEGIC_INDEX_TO_SECTOR_INFO( sWorldSectorLocationOfFirstBattle );
pSector = &SectorInfo[ ubSectorID ];
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 4);
#ifdef DIFFICULTY_SETTING
UINT8 value4;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value4 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value4 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value4 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value4 = 4;
else
{
value4 = Random (4);
if (value4 == 0) value4 = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value4 * 4);
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 4);
#endif
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
#ifdef DIFFICULTY_SETTING
if( Random( 10 ) < value4 )
#else
if( Random( 10 ) < gGameOptions.ubDifficultyLevel )
#endif
{
ubNumSoldiers--;
ubNumTanks++;
@@ -4984,12 +5274,35 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
Assert(direness >= 0 && direness <= 100);
unsigned intention = (unsigned) option2;
Assert(intention < NUM_ENEMY_INTENTIONS);
#ifdef DIFFICULTY_SETTING
UINT8 value5;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value5 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value5 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value5 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value5 = 4;
else
{
value5 = Random (4);
if (value5 == 0) value5 = 1;
}
ubNumSoldiers = ( gubMinEnemyGroupSize +
value5 * 3 +
Random(HighestPlayerProgressPercentage() / 5) +
Random(option1 / 5)
);
#else
ubNumSoldiers = ( gubMinEnemyGroupSize +
gGameOptions.ubDifficultyLevel * 3 +
Random(HighestPlayerProgressPercentage() / 5) +
Random(option1 / 5)
);
#endif
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
@@ -5036,7 +5349,12 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
#ifdef DIFFICULTY_SETTING
if( Random( 10 * 100 ) < value5 * direness )
#else
if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * direness )
#endif
{
elitesThisSquad--;
tanksThisSquad++;
@@ -5127,7 +5445,26 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
break;
case NPC_ACTION_SEND_SOLDIERS_TO_OMERTA:
#ifdef DIFFICULTY_SETTING
UINT8 value6;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value6 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value6 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value6 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value6 = 4;
else
{
value6 = Random (4);
if (value6 == 0) value6 = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value6 * 6); //6, 12, or 18 based on difficulty.
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel * 6); //6, 12, or 18 based on difficulty.
#endif
pGroup = CreateNewEnemyGroupDepartingFromSector( SECTOR( gModSettings.ubSAISpawnSectorX, gModSettings.ubSAISpawnSectorY ), 0, ubNumSoldiers, (UINT8)(ubNumSoldiers/7), 0 ); //add 1 elite to normal, and 2 for hard
ubNumSoldiers = (UINT8)(ubNumSoldiers + ubNumSoldiers / 7);
@@ -5152,8 +5489,25 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
case NPC_ACTION_SEND_TROOPS_TO_SAM:
ubSectorID = (UINT8)SECTOR( sSectorX, sSectorY );
#ifdef DIFFICULTY_SETTING
UINT8 value7;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value7 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value7 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value7 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value7 = 4;
else
{
value7 = Random (4);
if (value7 == 0) value7 = 1;
}
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + value7 + HighestPlayerProgressPercentage() / 15 );
#else
ubNumSoldiers = (UINT8)( gubMinEnemyGroupSize + gGameOptions.ubDifficultyLevel + HighestPlayerProgressPercentage() / 15 );
#endif
//Madd: unlimited reinforcements?
if ( !gfUnlimitedTroops )
giReinforcementPool -= ubNumSoldiers;
@@ -5161,7 +5515,11 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
// anv: replace one of soldiers with tank
if( ubNumSoldiers && gGameExternalOptions.fArmyUsesTanksInAttacks )
{
#ifdef DIFFICULTY_SETTING
if( Random( 10 * 100 ) < value7 * HighestPlayerProgressPercentage() )
#else
if( Random( 10 * 100 ) < gGameOptions.ubDifficultyLevel * HighestPlayerProgressPercentage() )
#endif
{
ubNumSoldiers--;
ubNumTanks++;
@@ -5199,6 +5557,9 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
case NPC_ACTION_GIVE_KNOWLEDGE_OF_ALL_MERCS:
//temporarily make the queen's forces more aware (high alert)
#ifdef DIFFICULTY_SETTING
gubNumAwareBattles = zDeffSetting[gGameOptions.ubDifficultyLevel].iNumAwareBattles;
#else
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
@@ -5214,6 +5575,7 @@ void ExecuteStrategicAIAction( UINT16 usActionCode, INT16 sSectorX, INT16 sSecto
gubNumAwareBattles = gGameExternalOptions.ubInsaneNumAwareBattles;
break;
}
#endif
break;
default:
@@ -5478,7 +5840,26 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
//Keep track of victories and wake up the queen after x number of battles.
gusPlayerBattleVictories++;
#ifdef DIFFICULTY_SETTING
UINT8 value8;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value8 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value8 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value8 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value8 = 4;
else
{
value8 = Random (4);
if (value8 == 0) value8 = 1;
}
if( gusPlayerBattleVictories == 5 - value8 )
#else
if( gusPlayerBattleVictories == 5 - gGameOptions.ubDifficultyLevel )
#endif
{ //4 victories for easy, 3 for normal, 2 for hard
WakeUpQueen();
}
@@ -5600,7 +5981,26 @@ void StrategicHandleQueenLosingControlOfSector( INT16 sSectorX, INT16 sSectorY,
}
//Madd: tweaked to increase attacks for experienced and expert to 8 and 12, and unlimited for insane
#ifdef DIFFICULTY_SETTING
UINT8 value9;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
value9 = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
value9 = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
value9 = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
value9 = 4;
else
{
value9 = Random (4);
if (value9 == 0) value9 = 1;
}
if( pSector->ubInvestigativeState >= ( 4 * value9 ) && zDeffSetting[gGameOptions.ubDifficultyLevel].bQueenLosingControlOfSector == FALSE )
#else
if( pSector->ubInvestigativeState >= ( 4 * gGameOptions.ubDifficultyLevel ) && gGameOptions.ubDifficultyLevel < DIF_LEVEL_INSANE )
#endif
{
//This is the 4th time the player has conquered this sector. We won't pester the player with probing attacks here anymore.
return;
@@ -6158,7 +6558,11 @@ void UpgradeAdminsToTroops()
while ( ubAdminsToCheck > 0)
{
// chance to upgrade at each check is random, and also dependant on the garrison's priority
#ifdef DIFFICULTY_SETTING
if ( Chance ( bPriority ) || zDeffSetting[gGameOptions.ubDifficultyLevel].bUpgradeAdminsToTroops == TRUE )
#else
if ( Chance ( bPriority ) || gGameOptions.ubDifficultyLevel > DIF_LEVEL_HARD ) // Madd: Always happens on Insane
#endif
{
pSector->ubNumAdmins--;
pSector->ubNumTroops++;
@@ -6213,7 +6617,11 @@ void UpgradeAdminsToTroops()
while ( ubAdminsToCheck > 0)
{
// chance to upgrade at each check is random, and also dependant on the group's priority
#ifdef DIFFICULTY_SETTING
if ( Chance ( bPriority ) || zDeffSetting[gGameOptions.ubDifficultyLevel].bUpgradeAdminsToTroops2 == TRUE )
#else
if ( Chance ( bPriority ) || gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )// Madd: Always happens on Expert and Insane
#endif
{
pGroup->pEnemyGroup->ubNumAdmins--;
pGroup->pEnemyGroup->ubNumTroops++;
@@ -6453,6 +6861,9 @@ void TagSAIGroupWithGracePeriod( GROUP *pGroup )
if( iPatrolID != -1 )
{
#ifdef DIFFICULTY_SETTING
gPatrolGroup[ iPatrolID ].bFillPermittedAfterDayMod100 = (UINT8)((GetWorldDay() + zDeffSetting[gGameOptions.ubDifficultyLevel].iGracePeriodInDaysAfterPatrolDestroyed) % 100);
#else
switch( gGameOptions.ubDifficultyLevel ) {
case DIF_LEVEL_EASY:
gPatrolGroup[ iPatrolID ].bFillPermittedAfterDayMod100 = (UINT8)((GetWorldDay() + gGameExternalOptions.ubEasyPatrolGracePeriodInDays) % 100);
@@ -6467,6 +6878,7 @@ void TagSAIGroupWithGracePeriod( GROUP *pGroup )
gPatrolGroup[ iPatrolID ].bFillPermittedAfterDayMod100 = (UINT8)((GetWorldDay() + gGameExternalOptions.ubInsanePatrolGracePeriodInDays) % 100);
break;
}
#endif
}
}
}
+8
View File
@@ -24,6 +24,10 @@
#include "Facilities.h"
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#include "Strategic Mines LUA.h"
#include <vector>
@@ -194,7 +198,11 @@ void InitializeMines( void )
ubMineProductionIncreases = 15;
break;
default:
#ifdef DIFFICULTY_SETTING
ubMineProductionIncreases = 25;
#else
Assert( 0 );
#endif
return;
}
+17
View File
@@ -61,6 +61,10 @@
//extern JA25_SECTOR_AI *gJa25AiSectorStruct;
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#include "connect.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -4877,6 +4881,19 @@ BOOLEAN TestForBloodcatAmbush( GROUP *pGroup )
{ //no ambushes underground (no bloodcats either)
return FALSE;
}
#ifdef DIFFICULTY_SETTING
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
ubDifficulty = 0;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
ubDifficulty = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
ubDifficulty = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
ubDifficulty = 3;
else
ubDifficulty = 0;
#endif
ubSectorID = (UINT8)SECTOR( pGroup->ubSectorX, pGroup->ubSectorY );
pSector = &SectorInfo[ ubSectorID ];
+28 -1
View File
@@ -18,6 +18,9 @@
#include "SaveLoadGame.h" // added by Flugente
#endif
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
STRATEGIC_STATUS gStrategicStatus;
@@ -217,13 +220,37 @@ void UpdateLastDayOfPlayerActivity( UINT16 usDay )
UINT8 LackOfProgressTolerance( void )
{
#ifdef DIFFICULTY_SETTING
UINT8 iTolerance;
#endif
#ifdef DIFFICULTY_SETTING
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD || gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
#else
if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
#endif
{
// give an EXTRA day over normal
return( 7 - DIF_LEVEL_MEDIUM + gStrategicStatus.ubHighestProgress / 42 );
}
#ifdef DIFFICULTY_SETTING
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
iTolerance = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
iTolerance = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
iTolerance = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
iTolerance = 4;
else
iTolerance = 1;
return( 6 - iTolerance + gStrategicStatus.ubHighestProgress / 42 );
#else
return( 6 - gGameOptions.ubDifficultyLevel + gStrategicStatus.ubHighestProgress / 42 );
#endif
}
+27
View File
@@ -44,6 +44,10 @@
#include "LuaInitNPCs.h"
#include "Interface.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
// the max loyalty rating for any given town
#define MAX_LOYALTY_VALUE 100
@@ -1874,7 +1878,12 @@ void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSec
}
// even taking over non-trainable "towns" like Orta/Tixa for the first time should count as "player activity"
#ifdef DIFFICULTY_SETTING
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD || gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE)
#else
if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD )
#endif
{
UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 4 ) );
}
@@ -2053,7 +2062,25 @@ void HandleLoyaltyImplicationsOfMercRetreat( INT8 bRetreatCode, INT16 sSectorX,
{
// if not worse than 2:1 odds, then penalize morale
// SANDRO - Set the odds based on difficulty level
#ifdef DIFFICULTY_SETTING
UINT8 DiffLevel;
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
DiffLevel = 1;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
DiffLevel = 2;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
DiffLevel = 3;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
DiffLevel = 4;
else
DiffLevel = 1;
if ( gTacticalStatus.fEnemyInSector && ( (PlayerStrength() * (2 + DiffLevel)) >= EnemyStrength() ) )
#else
if ( gTacticalStatus.fEnemyInSector && ( (PlayerStrength() * (2 + gGameOptions.ubDifficultyLevel)) >= EnemyStrength() ) )
#endif
{
HandleMoraleEvent( NULL, MORALE_RAN_AWAY, sSectorX, sSectorY, (INT8)sSectorZ );
}
+57
View File
@@ -10,6 +10,9 @@
#include "Debug Control.h"
#include "GameSettings.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
typedef enum
{
@@ -187,6 +190,59 @@ void AddExtraItems(UINT8 x, UINT8 y, UINT8 z, bool sectorIsLoaded)
int baseFNLength = strlen(fileName);
// Append a suffix based on the difficulty
#ifdef DIFFICULTY_SETTING
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:
strcat(fileName, "_Diff_5");
break;
case 6:
strcat(fileName, "_Diff_6");
break;
case 7:
strcat(fileName, "_Diff_7");
break;
case 8:
strcat(fileName, "_Diff_8");
break;
case 9:
strcat(fileName, "_Diff_9");
break;
case 10:
strcat(fileName, "_Diff_10");
break;
case 11:
strcat(fileName, "_Diff_11");
break;
case 12:
strcat(fileName, "_Diff_12");
break;
case 13:
strcat(fileName, "_Diff_13");
break;
case 14:
strcat(fileName, "_Diff_14");
break;
case 15:
strcat(fileName, "_Diff_15");
break;
default:
break;
}
#else
switch (gGameOptions.ubDifficultyLevel) {
case DIF_LEVEL_ZERO:
break;
@@ -207,6 +263,7 @@ void AddExtraItems(UINT8 x, UINT8 y, UINT8 z, bool sectorIsLoaded)
default:
break;
}
#endif
strcat(fileName, ".xml");
if(!FileExists(fileName))//dnl ch75 261013 just to avoid sdd::exception under debug from VFS when file not exist
+9
View File
@@ -161,6 +161,10 @@
#define MINS_TO_FLASH_CONTRACT_TIME (4 * 60)
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#ifdef JA2UB
void MakeBadSectorListFromMapsOnHardDrive( BOOLEAN fDisplayMessages ); // ja25 UB
#endif
@@ -15401,7 +15405,12 @@ void DumpSectorDifficultyInfo( void )
// NOTE: This operates on the selected map sector!
CHAR16 wSectorName[ 128 ];
#ifdef DIFFICULTY_SETTING
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Playing Difficulty: %s", zDeffSetting[gGameOptions.ubDifficultyLevel].szDeffName );
#else
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Playing Difficulty: %s", gzGIOScreenText[ GIO_DIF_LEVEL_TEXT + gGameOptions.ubDifficultyLevel ] );
#endif
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Highest Progress (0-100) = %d%%", HighestPlayerProgressPercentage() );
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Player Kills = %d", gStrategicStatus.usPlayerKills );
+20
View File
@@ -109,6 +109,10 @@
#include "LuaInitNPCs.h"
#include "Luaglobal.h"
#ifdef DIFFICULTY_SETTING
#include "GameInitOptionsScreen.h"
#endif
#ifdef JA2UB
#include "SaveLoadGame.h"
#include "email.h"
@@ -7318,7 +7322,12 @@ void CreateAndAddMoneyObjectToGround( UINT32 sGridNo, INT32 iEasyAmount, INT32 i
break;
default:
#ifdef DIFFICULTY_SETTING
iCash = iNormalAmount;
break;
#else
Assert(0);
#endif
}
CreateMoney( iCash, &Object );
@@ -7515,6 +7524,12 @@ void HandleMovingEnemiesOntoRoofs()
MoveEnemyFromGridNoToRoofGridNo( 15446, 13993 );
MoveEnemyFromGridNoToRoofGridNo( 15436, 14006 );
break;
#ifdef DIFFICULTY_SETTING
default:
MoveEnemyFromGridNoToRoofGridNo( 15446, 13993 );
MoveEnemyFromGridNoToRoofGridNo( 15436, 14006 );
break;
#endif
}
}
@@ -7529,6 +7544,11 @@ void HandleMovingEnemiesOntoRoofs()
case DIF_LEVEL_HARD:
MoveEnemyFromGridNoToRoofGridNo( 8711, 5521 );
break;
#ifdef DIFFICULTY_SETTING
default:
MoveEnemyFromGridNoToRoofGridNo( 8711, 5521 );
break;
#endif
}
}
}