Strategic States
This script causes the AI to consider their global strategies more often and to choose among a greater number of strategies according to changing situations.
1The Strategies1
2Defensive Strategies2
If our worst enemy is a HUMAN or an advanced AI, and if our city garrisons are a bit weak, we should build up our defense.
2Aerial Strategies2
If our worst enemy is located far away or even sits on a different continent, we should build up an offensive air force, including missiles when available.
2Intelligence Strategies2
If we are way behind in knowledge, we should try to steal some technolgies. If our worst enemy has a different form of government, we should try to support the revolutionaries.
2Nuclear Strategies2
If our worst enemy has a different government and regard is at cold war level, we should build up a really impressive nuclear force - if our worst enemy has the same government a couple of nukes will possibly do.
1The Script1
//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Strategies Framework
////////////////////////////////////////////////////////////////////////////
HandleEvent(NextStrategicState) 'StrategiesSpecial' pre {
int_t stsCountA;
int_t stsPlayer;
int_t stsTurns;
int_t stsPriority;
int_t stsDBIndex;
int_t stsCheckPlayer;
int_t stsWorstEnemyRegard;
int_t stsLowestRegard;
int_t stsWorstEnemy;
int_t stsWorstEnemyCapitalIdx;
city_t stsWorstEnemyCapital;
int_t stsOurCapitalIdx;
city_t stsOurCapital;
int_t stsOurContinent;
int_t stsWorstEnemyContinent;
int_t stsWorstEnemyDistance;
int_t stsOurKnowledgeRank;
int_t stsOurCitiesRank;
int_t stsOurGeographicRank;
int_t stsOurGoldRank;
int_t stsOurMilitaryRank;
int_t stsOurPopulationRank;
int_t stsOurTradeRank;
int_t stsOurUnderseaRank;
int_t stsWorstEnemyKnowledgeRank;
int_t stsWorstEnemyCitiesRank;
int_t stsWorstEnemyGeographicRank;
int_t stsWorstEnemyGoldRank;
int_t stsWorstEnemyMilitaryRank;
int_t stsWorstEnemyPopulationRank;
int_t stsWorstEnemyTradeRank;
int_t stsWorstEnemyUnderseaRank;
int_t stsOurOverallRank;
int_t stsWorstEnemyOverallRank;
int_t stsOurGovernment;
int_t stsWorstEnemyGovernment;
int_t stsBigDistance;
int_t stsCitiesNum;
int_t stsUnitsNum;
int_t stsTotalUnitsNum;
int_t stsDefStrength;
int_t stsRand;
int_t stsGotCityByIndex; // dummy var for unused return values of int_f
int_t stsPersonalityType;
int_t stsStrategyType;
int_t stsLowestSingleRank;
int_t stsLowestOverallRank;
int_t stsWorldCitiesNum;
int_t stsWorldCitiesValue;
int_t stsRoundsToNextDisaster;
int_t stsWorldPollution;
int_t stsOurCitiesValue;
int_t stsOurCitiesAvgValue;
int_t stsWorldCitiesAvgValue;
unit_t stsCheckUnit;
int_t stsMountedNum;
int_t stsInfantryNum;
int_t stsCarrierNum;
int_t stsNuclearSubNum;
int_t stsMissileCruiserNum;
int_t stsAttackHeliNum;
int_t stsPlayersInGame;
int_t stsDefCon;
stsPlayer = player[0].owner;
stsCitiesNum = Cities(stsPlayer);
if(!IsHumanPlayer(stsPlayer) && stsCitiesNum > 0) {
stsLowestSingleRank = g.num_of_players;
stsLowestOverallRank = stsLowestSingleRank * 8;
stsUnitsNum = player[0].militaryunits;
stsTotalUnitsNum = player[0].units;
stsOurGovernment = player[0].government;
stsOurCapitalIdx = GetCapital(stsPlayer);
stsGotCityByIndex = GetCityByIndex(stsPlayer, stsOurCapitalIdx, stsOurCapital);
stsOurContinent = GetContinent(stsOurCapital.location);
stsBigDistance = GetMapWidth() / 3;
stsOurKnowledgeRank = KnowledgeRank(stsPlayer);
stsOurCitiesRank = CitiesRank(stsPlayer);
stsOurGeographicRank = GeographicRank(stsPlayer);
stsOurGoldRank = GoldRank(stsPlayer);
stsOurMilitaryRank = MilitaryRank(stsPlayer);
stsOurPopulationRank = PopulationRank(stsPlayer);
stsOurTradeRank = TradeRank(stsPlayer);
stsOurUnderseaRank = UnderseaRank(stsPlayer);
stsOurOverallRank = CitiesRank(stsPlayer) + GeographicRank(stsPlayer) + GoldRank(stsPlayer) + KnowledgeRank(stsPlayer) + MilitaryRank(stsPlayer) + PopulationRank(stsPlayer) + TradeRank(stsPlayer) + UnderseaRank(stsPlayer);
stsDefStrength = stsUnitsNum / stsCitiesNum;
stsOurCitiesValue = GetTotalValue(stsPlayer);
stsOurCitiesAvgValue = stsOurCitiesValue / stsCitiesNum;
stsTurns = GetCurrentRound();
stsPriority = 0;
stsDBIndex = 999;
stsWorstEnemy = 0; // good old barbs by default
stsLowestRegard = 300; // neutral
stsWorldCitiesNum = 0;
stsWorldCitiesValue = 0;
stsWorldPollution = 0;
stsRoundsToNextDisaster = GetRoundsToNextDisaster();
stsPlayersInGame = 0;
stsDefCon = 0;
// Compute strategic parameters
for(stsCheckPlayer = 0; stsCheckPlayer < g.max_players; stsCheckPlayer = stsCheckPlayer + 1) {
if(IsPlayerAlive(stsCheckPlayer)) {
player[3] = stsCheckPlayer;
stsWorldPollution = stsWorldPollution + player[3].totalpollution;
stsWorstEnemyRegard = GetEffectiveRegard(stsPlayer, stsCheckPlayer);
if(stsWorstEnemyRegard < stsLowestRegard) {
stsWorstEnemy = stsCheckPlayer;
stsLowestRegard = stsWorstEnemyRegard;
}
stsWorldCitiesNum = stsWorldCitiesNum + Cities(stsCheckPlayer);
stsWorldCitiesValue = stsWorldCitiesValue + GetTotalValue(stsCheckPlayer);
stsPlayersInGame = stsPlayersInGame + 1;
}
}
stsWorldCitiesAvgValue = stsWorldCitiesValue / stsWorldCitiesNum;
if(stsWorstEnemy > 0) {
player[3] = stsWorstEnemy;
stsWorstEnemyGovernment = player[3].government;
stsWorstEnemyCapitalIdx = GetCapital(stsWorstEnemy);
stsGotCityByIndex = GetCityByIndex(stsWorstEnemy, stsWorstEnemyCapitalIdx, stsWorstEnemyCapital);
stsWorstEnemyContinent = GetContinent(stsWorstEnemyCapital.location);
stsWorstEnemyDistance = Distance(stsOurCapital.location, stsWorstEnemyCapital.location);
stsWorstEnemyCitiesRank = CitiesRank(stsWorstEnemy);
stsWorstEnemyGeographicRank = GeographicRank(stsWorstEnemy);
stsWorstEnemyGoldRank = GoldRank(stsWorstEnemy);
stsWorstEnemyKnowledgeRank = KnowledgeRank(stsWorstEnemy);
stsWorstEnemyMilitaryRank = MilitaryRank(stsWorstEnemy);
stsWorstEnemyPopulationRank = PopulationRank(stsWorstEnemy);
stsWorstEnemyTradeRank = TradeRank(stsWorstEnemy);
stsWorstEnemyUnderseaRank = UnderseaRank(stsWorstEnemy);
stsWorstEnemyOverallRank = CitiesRank(stsWorstEnemy) + GeographicRank(stsWorstEnemy) + GoldRank(stsWorstEnemy) + KnowledgeRank(stsWorstEnemy) + MilitaryRank(stsWorstEnemy) + PopulationRank(stsWorstEnemy) + TradeRank(stsWorstEnemy) + UnderseaRank(stsWorstEnemy);
}
stsPersonalityType = GetPersonalityType(stsPlayer);
if(stsPersonalityType == 0 || stsPersonalityType == 2 || stsPersonalityType == 3 || stsPersonalityType == 4) {
stsStrategyType = 1; // militarist
}
elseif(stsPersonalityType == 1) {
stsStrategyType = 2; // diplomatic
}
elseif(stsPersonalityType == 5) {
stsStrategyType = 3; // economic
}
elseif(stsPersonalityType == 6 || stsPersonalityType == 7) {
stsStrategyType = 4; // scientist
}
elseif(stsPersonalityType == 8 || stsPersonalityType == 9) {
stsStrategyType = 5; // ecotopian
}
// The following structure elements are only changed by a SetStrategicState function call:
// PopAssignmentElement elements, the order of Government elements and SliderElement elements.
// use SetStrategicState() and STRATEGY_GOVT_ strategies
// SetStrategicState() not implemented in CTP2 AE
// Defensive Strategies
if(MOD_AIMODE[stsPlayer] >= 1) {
if(MOD_AIMODE[stsWorstEnemy] == 1
|| (stsTurns > 49 && IsHumanPlayer(stsWorstEnemy))) {
stsDBIndex = StrategyDB(STRATEGY_DEFENSE_MEDIUM);
stsPriority = 900;
stsDefCon = 2;
}
if(MOD_AIMODE[stsWorstEnemy] >= 2
|| (stsTurns > 99 && IsHumanPlayer(stsWorstEnemy))) {
if(stsDefStrength < 12) {
stsDBIndex = StrategyDB(STRATEGY_DEFENSE_VERY_HIGH);
stsPriority = 900;
stsDefCon = 4;
}
if(stsDefStrength >= 12) {
stsDBIndex = StrategyDB(STRATEGY_DEFENSE_HIGH);
stsPriority = 900;
stsDefCon = 3;
}
}
}
// Execute Defensive Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// Aerial Strategies
if(stsOurContinent != stsWorstEnemyContinent
|| stsWorstEnemyDistance >= stsBigDistance) {
stsRand = Random(100);
if(0 <= stsRand < 50) {
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_NAVAL_AVIATION))) {
stsDBIndex = StrategyDB(STRATEGY_AIR_SPECIAL);
stsPriority = 900;
}
}
if(50 <= stsRand < 100) {
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_GUIDED_WEAPON_SYSTEMS))) {
stsDBIndex = StrategyDB(STRATEGY_MISSILE_SPECIAL);
stsPriority = 900;
}
}
}
// Execute Aerial Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// Armament Strategies
stsMountedNum = 0;
stsInfantryNum = 0;
stsCarrierNum = 0;
stsNuclearSubNum = 0;
stsMissileCruiserNum = 0;
stsAttackHeliNum = 0;
for(stsCountA = 0; stsCountA < stsTotalUnitsNum; stsCountA = stsCountA + 1) {
if(GetUnitByIndex(stsPlayer, stsCountA, stsCheckUnit)) {
if(UnitDB(stsCheckUnit.type).IsMounted) {
stsMountedNum = stsMountedNum + 1;
}
if(IsAircraftCarrier(stsCheckUnit)) {
stsCarrierNum = stsCarrierNum + 1;
}
if(stsCheckUnit.type == UnitDB(UNIT_NUCLEAR_SUBMARINE)) {
stsNuclearSubNum = stsNuclearSubNum + 1;
}
if(stsCheckUnit.type == UnitDB(UNIT_MISSILE_CRUISER)) {
stsMissileCruiserNum = stsMissileCruiserNum + 1;
}
if(stsCheckUnit.type == UnitDB(UNIT_ATTACK_HELICOPTER)) {
stsAttackHeliNum = stsAttackHeliNum + 1;
}
}
}
stsInfantryNum = stsUnitsNum - stsMountedNum;
if(stsInfantryNum >= (stsCitiesNum * 20)) {
stsDBIndex = StrategyDB(STRATEGY_ARMAMENT_MOUNTED);
stsPriority = 900;
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_MODERN_METALLURGY))) {
if(stsCarrierNum < (stsCitiesNum / 8)) {
stsDBIndex = StrategyDB(STRATEGY_ARMAMENT_CARRIERS);
stsPriority = 900;
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
}
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_ELECTRONICS))) {
if(stsNuclearSubNum < (stsCitiesNum / 6)) {
stsDBIndex = StrategyDB(STRATEGY_ARMAMENT_NUCLEAR_SUBS);
stsPriority = 900;
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
}
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_ADVANCED_COMPOSITES))) {
if(stsMissileCruiserNum < (stsCitiesNum / 6)) {
stsDBIndex = StrategyDB(STRATEGY_ARMAMENT_MISSILE_CRUISERS);
stsPriority = 900;
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
}
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_DEEP_BATTLE_TACTICS))) {
if(stsAttackHeliNum < (stsCitiesNum / 5)) {
stsDBIndex = StrategyDB(STRATEGY_ARMAMENT_ATTACK_HELICOPTERS);
stsPriority = 900;
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
}
// Intelligence Strategies
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_COMMUNISM))
|| HasAdvance(stsPlayer, AdvanceDB(ADVANCE_CYBERNETICS))) {
if(stsOurKnowledgeRank > stsWorstEnemyKnowledgeRank) {
stsDBIndex = StrategyDB(STRATEGY_SPECIAL_SPY_TECHNO);
stsPriority = 900;
}
if(stsOurGovernment != stsWorstEnemyGovernment) {
stsDBIndex = StrategyDB(STRATEGY_SPECIAL_SPY_REVO);
stsPriority = 900;
}
}
// Execute Intelligence Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// Nuclear Strategies
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_ELECTRONICS))
&& WonderOwner(WonderDB(WONDER_NANITE_DEFUSER)) < 0) {
if(stsOurGovernment != stsWorstEnemyGovernment) {
if(101 <= stsWorstEnemyRegard < 301) { // cold war
stsDBIndex = StrategyDB(STRATEGY_THE_MAXIMUM_NUKES);
stsPriority = 900;
}
if(301 <= stsWorstEnemyRegard < 701) { // neutral
stsDBIndex = StrategyDB(STRATEGY_THE_AVERAGE_NUKES);
stsPriority = 900;
}
}
if(stsOurGovernment == stsWorstEnemyGovernment) {
if(101 <= stsWorstEnemyRegard < 301) { // cold war
stsDBIndex = StrategyDB(STRATEGY_THE_MINIMAL_NUKES);
stsPriority = 900;
}
if(301 <= stsWorstEnemyRegard < 701) { // neutral
stsDBIndex = StrategyDB(STRATEGY_A_PAIR_OF_NUKES);
stsPriority = 900;
}
}
if(stsWorstEnemyRegard < 101
&& stsOurOverallRank > stsWorstEnemyOverallRank
&& TurnsAtWar(stsPlayer, stsWorstEnemy) > 20) {
stsDBIndex = StrategyDB(STRATEGY_LAUNCH_NUKES);
stsPriority = 900;
}
}
// Execute Nuclear Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// Wonder Strategies
if(stsOurKnowledgeRank > (stsPlayersInGame / 2)) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_SCIENCE);
stsPriority = 900;
}
elseif(stsOurPopulationRank > (stsPlayersInGame / 2)) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_GROWTH);
stsPriority = 900;
}
elseif(stsOurCitiesAvgValue < stsWorldCitiesAvgValue) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_PRODUCTION);
stsPriority = 900;
}
elseif(stsOurGeographicRank < (stsPlayersInGame /2)) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_HAPPINESS);
stsPriority = 900;
}
elseif(stsOurGoldRank > (stsPlayersInGame / 2)) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_GOLD);
stsPriority = 900;
}
elseif(stsDefCon > 2) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_DEFENSE);
stsPriority = 900;
}
elseif(stsDefCon == 0) {
stsDBIndex = StrategyDB(STRATEGY_WONDERS_OFFENSE);
stsPriority = 900;
}
// Execute Wonder Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// Modernization Strategies
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_INDUSTRIAL_REVOLUTION))
|| HasAdvance(stsPlayer, AdvanceDB(ADVANCE_CORPORATION))) {
stsDBIndex = StrategyDB(STRATEGY_TI_MODERNIZATION);
stsPriority = 900;
}
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_PLASTICS))) {
stsDBIndex = StrategyDB(STRATEGY_TI_MODERNIZATION_POST);
stsPriority = 900;
}
// Execute Modernization Strategies
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
// PW Reserve Strategies (save the ressources for building military facilities)
// if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_ENGINEERING))) {
// if(STL_SETCON[stsPlayer] <= 2
// && AtWarCount(stsPlayer) > 0) {
// stsDBIndex = StrategyDB(STRATEGY_LARGE_PW_RESERVE);
// stsPriority = 900;
// }
// if(STL_SETCON[stsPlayer] <= 2
// && EffectiveAtWarCount(stsPlayer) > 1) {
// stsDBIndex = StrategyDB(STRATEGY_VERY_LARGE_PW_RESERVE);
// stsPriority = 900;
// }
// }
// Execute PW Reserve Strategies
// if(stsPriority > 0) {
// ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
// stsPriority = 0;
// }
// No Science Strategy (don't waste money for science if there is nothing left to research)
if(HasAdvance(stsPlayer, AdvanceDB(ADVANCE_ARCOLOGIES))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_SMART_MATERIALS))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_NANO_WARFARE))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_PLASMA_WEAPONRY))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_CHAOS_THEORY))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_FUSION))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_GAIA_THEORY))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_GAIA_CONTROLLER))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_GENETIC_TAILORING))
&& HasAdvance(stsPlayer, AdvanceDB(ADVANCE_LIFE_EXTENSION))
) {
stsDBIndex = StrategyDB(STRATEGY_NO_SCIENCE);
stsPriority = 900;
}
// Execute No Science Stratgy
if(stsPriority > 0) {
ConsiderStrategicState(player[0], stsPriority, stsDBIndex);
stsPriority = 0;
}
}
return CONTINUE;
}