Images
Turn 150: Forts
Turn 500: Barbed Wire
Fortification
Barbed Wire
Pillbox
Air Base
Missile Silo

Military Facilities

This script makes the AI build military facilities:

  • fortifications within their own territory
  • military camps outside their territory
  • barbed wires and pillboxes along the borders with their enemies
  • air bases and missile silos within their territory and next to their military camps

Unfortunately I did not get as far as to teach the AI how to use these facilities properly. In particular, the AI has absolutely no idea about pillboxes and missile silos.

The Script

//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Facilities by BureauBert
// Military Facilities Construction Script
// Builds forts, pillboxes, barbed wire,
// military camps, airbases, and missile silos for the AI
////////////////////////////////////////////////////////////////////////////

HandleEvent(FinishBeginTurn) 'BuildMilitaryFacilities' post {
        int_t facPlayer;
        int_t facPlayerPWReserve;
        location_t facLocations[];
        location_t facExtLocations[];
        int_t facCountA;
        int_t facCountC;
        int_t facCountD;
        int_t facCampFound;
        int_t facFenceFound;
        int_t facPillboxFound;
        int_t facFacilityFound;
        int_t facBorderFound;
        int_t facEnemyFenceFound;
        int_t facRoadFound;
        int_t facAirbaseFound;
        int_t facSiloFound;
        int_t facCityFound;
        int_t facCheckDir;
        location_t facCheckLoc;
        city_t facCheckCity;
        city_t facNearestCity;
        int_t facNearestCityIdx;
        int_t facNearestCityDist;
        int_t facTimpToBuild;
        int_t facNeighbor;
        int_t facNeighborIsEnemy;
        int_t facX;
        int_t facY;
        location_t facMapLoc;
        location_t facCampLoc;
        int_t facFortDone;
        int_t facAirbaseDone;
        int_t facSiloDone;
        int_t facPillboxDone;
        int_t facSiloCount;

        facPlayer = player[0].owner;
        facPlayerPWReserve = player[0].publicworkslevel;
        facFortDone = 0;
        facAirbaseDone = 0;
        facSiloDone = 0;
        facPillboxDone = 0;
        facSiloCount = 0;
       
        if(!IsHumanPlayer(facPlayer) && facPlayer > 0 && MOD_IMPROVEAITHISTURN[facPlayer]) {
                facCountC = 0;
                for(facCountA = 0; facCountA < MOD_MAPLOCATIONS.#; facCountA = facCountA + 1) {
                        if(CellOwner(MOD_MAPLOCATIONS[facCountA]) == facPlayer
                        && !IsWater(MOD_MAPLOCATIONS[facCountA])) {
                                facLocations[facCountC] = MOD_MAPLOCATIONS[facCountA];
                                facCountC = facCountC + 1;
                        }
                        if(CellOwner(MOD_MAPLOCATIONS[facCountA]) == facPlayer
                        && TileHasImprovement(MOD_MAPLOCATIONS[facCountA], TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
                                facSiloCount = facSiloCount + 1;
                        }
                }
                for(facCountA = 0; facCountA < facLocations.#; facCountA = facCountA + 1) {
                        facTimpToBuild = -1;
                        if(!TileHasLandRoad(facLocations[facCountA])
                        && !TileHasFacility(facLocations[facCountA])
                        && !TileHasNaturalWonder(facLocations[facCountA])
                        && !TileHasWonder(facLocations[facCountA])
                        && !TileHasCapital(facLocations[facCountA])
                        && !TileHasMonument(facLocations[facCountA])) {
                                facCityFound = 0;
                                facCampFound = 0;
                                facFenceFound = 0;
                                facPillboxFound = 0;
                                facBorderFound = 0;
                                facEnemyFenceFound = 0;
                                facRoadFound = 0;
                                facFacilityFound = 0;
                                facNeighborIsEnemy = 0;
                                facAirbaseFound = 0;
                                facSiloFound = 0;
                                facNearestCityDist = 0;
                                // check surroundings
                                for(facCheckDir = 0; facCheckDir <= 7; facCheckDir = facCheckDir + 1) {
                                        if(GetNeighbor(facLocations[facCountA], facCheckDir, facCheckLoc)) {
                                                facNeighbor = CellOwner(facCheckLoc);
                                                if(facNeighbor > -1 && facNeighbor != facPlayer && facNeighbor != 0) {        // don't build fence around barb cities
                                                        facBorderFound = 1;
                                                        if(RegardLevel(facPlayer, facNeighbor) <= 300
                                                        || GetDesireWarWith(facPlayer, facNeighbor)) {
                                                                facNeighborIsEnemy = 1;
                                                        }
                                                        if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_BARBED_WIRE))) {
                                                                facEnemyFenceFound = 1;
                                                        }
                                                }
                                                if(GetCityByLocation(facCheckLoc, facCheckCity)) {
                                                        facCityFound = 1;
                                                }
                                                if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_MILITARY_CAMPS))) {
                                                        facCampFound = 1;
                                                        facCampLoc = facCheckLoc;
                                                }
                                                // we want to see pillboxes along the border fence
                                                if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_BARBED_WIRE))) {
                                                        facFenceFound = 1;
                                                }
                                                // but not on every tile
                                                if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_PILLBOX))) {
                                                        facPillboxFound = 1;
                                                }
                                                if(TileHasLandRoad(facCheckLoc)) {
                                                        facRoadFound = facRoadFound + 1;
                                                }
                                                if(TileHasFacility(facCheckLoc)) {
                                                        facFacilityFound = 1;
                                                }
                                        }
                                }
                                // check strategic situation
                                facNearestCityIdx = GetNearestCity(facLocations[facCountA], facPlayer);
                                if(GetCityByIndex(facPlayer, facNearestCityIdx, facNearestCity)) {
                                        facNearestCityDist = Distance(facLocations[facCountA], facNearestCity.location);
                                }
                                // Build military camp extensions
                                if(facCampFound == 1) {
                                        // check state of camp facilities
                                        for(facCheckDir = 0; facCheckDir <= 7; facCheckDir = facCheckDir + 1) {
                                                if(GetNeighbor(facCampLoc, facCheckDir, facCheckLoc)) {
                                                        if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_AIR_BASES))) {
                                                                facAirbaseFound = 1;
                                                        }
                                                        if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
                                                                facSiloFound = 1;
                                                        }
                                                }
                                        }
                                        if(facAirbaseDone == 0
                                        && facAirbaseFound == 0
                                        && HasAdvance(facPlayer, AdvanceDB(ADVANCE_AERODYNAMICS))) {
                                                facTimpToBuild = TerrainImprovementDB(TILEIMP_AIR_BASES);
                                                facAirbaseDone = 1;
                                        }
                                        elseif(facSiloDone == 0
                                        && facSiloFound == 0
                                        && HasAdvance(facPlayer, AdvanceDB(ADVANCE_ROCKETRY))) {
                                                facTimpToBuild = TerrainImprovementDB(TILEIMP_MISSILE_SILO);
                                                facSiloDone = 1;
                                        }
                                }
                                // Build barbed wire
                                if(facTimpToBuild == -1
                                && facNeighborIsEnemy == 1
                                && !TileHasLandRoad(facLocations[facCountA])
                                && IsAllLandArmyTerrain(facLocations[facCountA])) {
                                        if(HasAdvance(facPlayer, AdvanceDB(ADVANCE_TANK_WARFARE))) {
                                                if(!TileHasImprovement(facLocations[facCountA], TerrainImprovementDB(TILEIMP_BARBED_WIRE))
                                                && facEnemyFenceFound == 0) {
                                                        facTimpToBuild = TerrainImprovementDB(TILEIMP_BARBED_WIRE);
                                                }
                                        }
                                }
                                // cut barbed wire if no longer needed
                                if(facNeighborIsEnemy == 0 && TileHasImprovement(facLocations[facCountA],TerrainImprovementDB(TILEIMP_BARBED_WIRE))) {
                                        Event:CutImprovements(facLocations[facCountA]);
                                }
                                // Build pillboxes and forts
                                if(facTimpToBuild == -1
                                && facNeighborIsEnemy == 0
                                && facCityFound == 0) {
                                        // build pillboxes along the border
                                        if(HasAdvance(facPlayer, AdvanceDB(ADVANCE_TANK_WARFARE))) {
                                                if(facPillboxDone == 0
                                                && (facFenceFound == 1 || facEnemyFenceFound == 1)
                                                && facPillboxFound == 0
                                                && (facBorderFound == 0 || facEnemyFenceFound == 1)) {
                                                        facTimpToBuild = TerrainImprovementDB(TILEIMP_PILLBOX);
                                                        facPillboxDone = 1;
                                                }
                                        }
                                        // build forts otherwise  ...
                                        if(HasAdvance(facPlayer, AdvanceDB(ADVANCE_ENGINEERING))) {
                                                if(facTimpToBuild == -1
                                                && facFortDone == 0
                                                && facBorderFound == 0
                                                && facRoadFound > 2                // at least 3 road segments ready
                                                && facFacilityFound == 0
                                                && facNearestCityDist > 2) {
                                                        // check for existing forts in the distance of a city radius
                                                        GetSurroundings(facLocations[facCountA]);
                                                        for(facCountD = 0; facCountD < MOD_SurroundingTiles.#; facCountD = facCountD + 1) {
                                                                if(TileHasImprovement(MOD_SurroundingTiles[facCountD], TerrainImprovementDB(TILEIMP_FORTIFICATIONS))) {
                                                                        facFortDone = 1;
                                                                }
                                                        }
                                                        // if no forts in this region, build one
                                                        if(facFortDone == 0) {
                                                                facTimpToBuild = TerrainImprovementDB(TILEIMP_FORTIFICATIONS);
                                                                facFortDone = 1;
                                                        }
                                                }
                                        }
                                }
                                // Build air bases on own territory
                                if(facTimpToBuild == -1
                                && facAirbaseDone == 0
                                && facBorderFound == 0
                                && facRoadFound == 0
                                && facFacilityFound == 0
                                && facNearestCityDist > 2) {
                                        if(HasAdvance(facPlayer, AdvanceDB(ADVANCE_AERODYNAMICS))) {
                                                // check for existing air bases in the distance of a city radius
                                                GetSurroundings(facLocations[facCountA]);
                                                for(facCountD = 0; facCountD < MOD_SurroundingTiles.#; facCountD = facCountD + 1) {
                                                        if(TileHasImprovement(MOD_SurroundingTiles[facCountD], TerrainImprovementDB(TILEIMP_AIR_BASES))) {
                                                                facAirbaseDone = 1;
                                                        }
                                                }
                                                // if no airbase in this region, build one
                                                if(facAirbaseDone == 0) {
                                                        facTimpToBuild = TerrainImprovementDB(TILEIMP_AIR_BASES);
                                                        facAirbaseDone = 1;
                                                }
                                        }
                                }
                        }
                        if(facTimpToBuild > -1) {
                                Event:CutImprovements(facLocations[facCountA]);
                                FinishImprovements(facLocations[facCountA]);
                                Event:CreateImprovement(facPlayer, facLocations[facCountA], facTimpToBuild, 0);
                        }
                       
                }
                // Build nuclear facilities next to homeland
                if(HasAdvance(facPlayer, AdvanceDB(ADVANCE_ROCKETRY)) && facSiloCount <= 5) {
                        facCountC = 0;
                        for(facCountA = 0; facCountA < MOD_MAPLOCATIONS.#; facCountA = facCountA + 1) {
                                if(CellOwner(MOD_MAPLOCATIONS[facCountA]) == -1
                                && !IsWater(MOD_MAPLOCATIONS[facCountA])) {
                                        facExtLocations[facCountC] = MOD_MAPLOCATIONS[facCountA];
                                        facCountC = facCountC + 1;
                                }
                        }
                        for(facCountA = 0; facCountA < facExtLocations.#; facCountA = facCountA + 1) {
                                if(facSiloDone == 0) {
                                        facTimpToBuild = -1;
                                        if(!TileHasAnyImprovement(facExtLocations[facCountA])
                                        && HasGood(facExtLocations[facCountA]) == -1
                                        && !GetCityByLocation(facExtLocations[facCountA], facCheckCity)) {
                                                facNearestCityIdx = GetNearestCity(facExtLocations[facCountA], facPlayer);
                                                if(GetCityByIndex(facPlayer, facNearestCityIdx, facNearestCity)) {
                                                        facNearestCityDist = Distance(facExtLocations[facCountA], facNearestCity.location);
                                                }
                                                if(facNearestCityDist > 3 && facNearestCityDist < 7) {
                                                        // check for existing silos in the distance of a city radius
                                                        GetSurroundings(facExtLocations[facCountA]);
                                                        for(facCountD = 0; facCountD < MOD_SurroundingTiles.#; facCountD = facCountD + 1) {
                                                                if(!TileHasImprovement(MOD_SurroundingTiles[facCountD], TerrainImprovementDB(TILEIMP_MISSILE_SILO))) {
                                                                        facTimpToBuild = TerrainImprovementDB(TILEIMP_MISSILE_SILO);
                                                                }
                                                        }
                                                }
                                        }
                                        if(facTimpToBuild > -1) {
                                                Event:CutImprovements(facLocations[facCountA]);
                                                FinishImprovements(facLocations[facCountA]);
                                                Event:CreateImprovement(facPlayer, facExtLocations[facCountA], facTimpToBuild, 0);
                                                facSiloDone = 1;
                                                facCountA = facExtLocations.#;
                                        }
                                }
                        }
                }

        }
}

HandleEvent(FinishUnload) 'BuildOverseasBase' post {
        army_t fortArmy;
        int_t fortPlayer;
        location_t fortLoc;
        int_t fortLookDir;
        location_t fortCheckLoc;
        city_t fortCheckCity;
        int_t fortProceed;
        int_t fortPlayerCapitalIdx;
        city_t fortPlayerCapital;
        location_t fortPlayerCapitalLoc;
        int_t fortPlayerHomeContinent;
        int_t fortCurrentContinent;
        int_t fortMinDist;
        int_t fortTmpPlayer;
        int_t fortCityCount;
        int_t fortCount;
        int_t fortCityDist;
        int_t fortCheckDist;

        fortArmy = army[1];
        fortPlayer = army[1].owner;
        fortLoc = location[0];
        fortProceed = 1;
        fortMinDist = GetMapWidth() / 8;
        fortCheckDist = 9999;

        if(IsHumanPlayer(fortPlayer)) {
                fortProceed = 0;
        }
        if(CellOwner(fortLoc) == fortPlayer) {
                fortProceed = 0;
        }
        if(IsLandSettlerInStack(fortArmy)) {
                fortProceed = 0;
        }
        if(fortProceed == 1) {
                for(fortLookDir = 0; fortLookDir < 8; fortLookDir = fortLookDir + 1) {
                        if(GetNeighbor(fortLoc, fortLookDir, fortCheckLoc)) {
                                if(GetCityByLocation(fortCheckLoc, fortCheckCity)) {
                                        fortProceed = 0;
                                        fortLookDir = 8;
                                }
                        }
                }
        }
        if(fortProceed == 1) {
                if(IsAllLandArmyTerrain(fortLoc)
                && !TileHasLandRoad(fortLoc)) {
                        if(HasAdvance(fortPlayer, AdvanceDB(ADVANCE_ENGINEERING))) {
                                for(fortLookDir = 0; fortLookDir < 8; fortLookDir = fortLookDir + 1) {
                                        if(GetNeighbor(fortLoc, fortLookDir, fortCheckLoc)) {
                                                if(CellOwner(fortCheckLoc) == fortPlayer) {
                                                        fortProceed = 0;
                                                }
                                        }
                                }
                        }
                }
        }
        if(fortProceed == 1) {
                for(fortTmpPlayer = 1; fortTmpPlayer < g.max_players; fortTmpPlayer = fortTmpPlayer + 1) {
                        if(IsPlayerAlive(fortTmpPlayer)) {
                                fortCityCount = PlayerCityCount(fortTmpPlayer);
                                for(fortCount = 0; fortCount < fortCityCount; fortCount = fortCount + 1) {
                                        if(GetCityByIndex(fortTmpPlayer, fortCount, fortCheckCity)) {
                                                fortCityDist = Distance(fortLoc, fortCheckCity.location);
                                                if(fortCityDist < fortCheckDist) {
                                                        fortCheckDist = fortCityDist;
                                                }
                                        }
                                }
                        }
                }
                if(fortCheckDist < fortMinDist) {
                        fortProceed = 0;
                }
        }
        if(fortProceed == 1) {
                Event:CutImprovements(fortLoc);
                FinishImprovements(fortLoc);
                Event:CreateImprovement(fortPlayer, fortLoc, TerrainImprovementDB(TILEIMP_MILITARY_CAMPS), 0);
        }
}

//////////////////////////////////////////////////////////////////////////
// Based upon the concept of TileImpOrders by Martin Gühmann:
//////////////////////////////////////////////////////////////////////////

HandleEvent(UseSpaceLadderOrder) 'BuildMilitaryCamps' pre {
        int_t fortPlayer;
        location_t fortLoc;
        int_t fortLookDir;
        location_t fortCheckLoc;
        city_t fortCheckCity;
        int_t fortProceed;
        int_t fortFenceFound;
        int_t fortPillboxFound;
        int_t fortBorderFound;
        int_t fortTmpPlayer;
        int_t fortCityCount;
        int_t fortCount;
        int_t fortCityDist;
        int_t fortCheckDist;
        int_t fortMinDist;

        fortPlayer = army[0].owner;
        fortLoc = army[0].location;
        fortProceed = 1;
        fortFenceFound = 0;
        fortPillboxFound = 0;
        fortBorderFound = 0;
        fortMinDist = GetMapWidth() / 8;
        fortCheckDist = 999999;

       
        if(CellOwner(fortLoc) == fortPlayer) {
                fortProceed = 0;
        }
        if(fortProceed == 1) {
                for(fortLookDir = 0; fortLookDir < 8; fortLookDir = fortLookDir + 1) {
                        if(GetNeighbor(fortLoc, fortLookDir, fortCheckLoc)) {
                                if(GetCityByLocation(fortCheckLoc, fortCheckCity)) {
                                        fortProceed = 0;
                                        fortLookDir = 8;
                                }
                        }
                }
        }
        if(fortProceed == 1) {
                if(IsAllLandArmyTerrain(fortLoc)
                && !TileHasLandRoad(fortLoc)) {
                        if(HasAdvance(fortPlayer, AdvanceDB(ADVANCE_ENGINEERING))) {
                                for(fortLookDir = 0; fortLookDir < 8; fortLookDir = fortLookDir + 1) {
                                        if(GetNeighbor(fortLoc, fortLookDir, fortCheckLoc)) {
                                                if(CellOwner(fortCheckLoc) == fortPlayer) {
                                                        fortProceed = 0;
                                                }
                                        }
                                }
                        }
                }
        }
        if(fortProceed == 1) {
                for(fortTmpPlayer = 1; fortTmpPlayer < g.max_players; fortTmpPlayer = fortTmpPlayer + 1) {
                        if(IsPlayerAlive(fortTmpPlayer)) {
                                fortCityCount = PlayerCityCount(fortTmpPlayer);
                                for(fortCount = 0; fortCount < fortCityCount; fortCount = fortCount + 1) {
                                        if(GetCityByIndex(fortTmpPlayer, fortCount, fortCheckCity)) {
                                                fortCityDist = Distance(fortLoc, fortCheckCity.location);
                                                if(fortCityDist < fortCheckDist) {
                                                        fortCheckDist = fortCityDist;
                                                }
                                        }
                                }
                        }
                }
                if(fortCheckDist < fortMinDist) {
                        fortProceed = 0;
                }
        }
        if(fortProceed == 1) {
                Event:CutImprovements(fortLoc);
                FinishImprovements(fortLoc);
                Event:CreateImprovement(fortPlayer, fortLoc, TerrainImprovementDB(TILEIMP_MILITARY_CAMPS), 0);
        }
        return CONTINUE;
}

///////////////////////////////////////////////////////////////////////////////////////////
// Preserve facilities
// Code snippets from City Expansion by BlueO, Pedrunn and IW
///////////////////////////////////////////////////////////////////////////////////////////

// Prevents the building of tile improvements over forts, military camps, barbed wires,
// pillboxes, air bases and villages - except for the replacement of one of these 'military'
// ti's by another one. Border fences that are no longer needed may be replaced by something useful.

HandleEvent(CreateImprovement) 'DontLetPlaceImpsOverForts' pre {
        location_t facLoc;
        int_t facCheckDir;
        location_t facCheckLoc;
        int_t facNeighbor;
        int_t facBorderFound;
        int_t facPlayer;
        int_t facNeighborIsEnemy;
        int_t facFenceFound;

        facLoc = location[0];
        facPlayer = CellOwner(facLoc);
        facBorderFound = 0;
        facNeighborIsEnemy = 0;
        facFenceFound = 0;

        if(TileHasFacility(facLoc)) {
                if(value[0] == TerrainImprovementDB(TILEIMP_FORTIFICATIONS)
                || value[0] == TerrainImprovementDB(TILEIMP_MILITARY_CAMPS)
                || value[0] == TerrainImprovementDB(TILEIMP_BARBED_WIRE)
                || value[0] == TerrainImprovementDB(TILEIMP_PILLBOX)
                || value[0] == TerrainImprovementDB(TILEIMP_AIR_BASES)
                || value[0] == TerrainImprovementDB(TILEIMP_MISSILE_SILO)
                ) {
                        return CONTINUE;                       
                }
                for(facCheckDir = 0; facCheckDir <= 7; facCheckDir = facCheckDir + 1) {
                        if(GetNeighbor(facLoc, facCheckDir, facCheckLoc)) {
                                facNeighbor = CellOwner(facCheckLoc);
                                if(facNeighbor != facPlayer) {
                                        facBorderFound = 1;
                                        if(RegardLevel(facPlayer, facNeighbor) <= 300
                                        || GetDesireWarWith(facPlayer, facNeighbor)) {
                                                facNeighborIsEnemy = 1;
                                        }
                                }
                                if(TileHasImprovement(facCheckLoc, TerrainImprovementDB(TILEIMP_BARBED_WIRE))) {
                                        facFenceFound = 1;
                                }
                        }
                }
                if(TileHasImprovement(facLoc, TerrainImprovementDB(TILEIMP_BARBED_WIRE))) {
                        if(facNeighborIsEnemy == 1) {
                                return STOP;
                        }
                        else {
                                return CONTINUE;
                        }
                }
                if(TileHasImprovement(facLoc, TerrainImprovementDB(TILEIMP_PILLBOX))) {
                        if(facFenceFound == 1) {
                                return STOP;
                        }
                        else {
                                return CONTINUE;
                        }
                }
                return STOP;
        }
}