Images
Turn 50
Turn 150
Turn 350
Turn 500
Early Settling Competition

Settling

Although settling, specially during the early game, is crucial for success, the AI’s settling behaviour in the default game is extremely poor:

  • The AI doesn’t settle aggessively and consequently enough.
  • The AI has no idea about strategic aspects of settling, they don’t try to expand on the landmass that’s available but “invade” their neighbor’s territory with “hordes” of settlers trying to settle next to their competitor’s capital.
  • The AI places it’s cities too close or too far depending on “leader personality” instead of considering their actual geographic situation.
  • At some point in the later game the AI just stops settling, often having a settler standing at a good location and and just “forgetting” to settle — also the AI don’t seem to like settling while at war with anyone.

I am trying to improve settling by providing a set of settling strategies and using a SLIC script which partly overrides the internal scheduler.

The script basically

  • checks how many cities the AI needs to found in order to keep up with their (human) opponent(s).
  • determines settling strategies according to the need for additional cities (basically this determines only how many settlers should be built).
  • looks for good settling locations considering distance to the nearest own city, distance to competing civs, and niceness of the settling location (gold, food, production, tile improvements, neighboring terrain etc.).
  • picks the “first five” settlers, leads them to good settling locations and forces them to settle there.
  • tries to lead the remaining settlers near good settling locations in the meantime.
  • forces the AI to settle in a “compact” manner as long as possible, and only allows settling far away from home if the AI is no longer able to find a good settling location nearby (at this point I am planning to extend the script with some sort of “colonization” logic — exploring the “new world”, currently the script just leaves the settlers to the internal scheduler).

Better Settling In Action

The AI playing with themselves:

https://www.youtube.com/watch?v=9Y3X-_YcZwk
Modern Times Mod for Call To Power II - Better Settling
by [Robert Zöchling->https://www.youtube.com/channel/UC2BoOBG-7AxDsyfMm3XhgSw]
https://www.youtube.com/watch?v=9Y3X-_YcZwk

The Script

//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Better Settling Code
// by BureauBert
// Makes the AI settle more consequently and more intelligently, considering
// not only "tile values", but also their strategic situation.
////////////////////////////////////////////////////////////////////////////

///////////////////////////
// GLOBALS
///////////////////////////

// declared in main.slc

///////////////////////////
// PARTICULAR FUNCTIONS
///////////////////////////

int_f FindColSite(city_t startCity, int_t considerMountains) {
        location_t findTmpLoc;
        location_t findTmpLoc2;
        location_t findHighScoreLoc;
        location_t findEmptyLoc;
        city_t findTmpCity;
        int_t findCount;
        int_t findCount2;
        int_t findBorderDirection;
        int_t findLocScore;
        int_t findHighLocScore;
        int_t findRandNum;
        int_t findPlayer;
        int_t findConsiderMountainTerrain;

        findTmpCity = startCity;
        findConsiderMountainTerrain = considerMountains;
        findLocScore = 0;
        findHighLocScore = 0;
        findBorderDirection = 0;        // 1 = near north map edge, 2 = near south border edge, 0 = near neither
        findTmpLoc = findTmpCity.location;
        findPlayer = findTmpCity.owner;
        findHighScoreLoc = findTmpLoc;
        STL_ColSiteScore = 0;
        for(findCount = 0; findCount < 6; findCount = findCount + 1) {        // Check if near north border
                if(!(GetNeighbor(findTmpLoc, 0, findTmpLoc))) {
                        findBorderDirection = 1;
                }
        }
        findTmpLoc = findTmpCity.location;
        for(findCount = 0; findCount < 6; findCount = findCount + 1) {        // Check if near south border
                if(!(GetNeighbor(findTmpLoc, 7, findTmpLoc))) {
                        findBorderDirection = 2;
                }
        }
        findTmpLoc = findTmpCity.location;
        if(findBorderDirection != 1 ) {        // findBorderDirection = 0 or 2; north side of city
                for(findCount = 0; findCount < 4; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 2, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 1, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 0, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 6; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 3, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 3; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 5, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 6; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 6, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 7, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
        }
        if(findBorderDirection != 2 ) {        // findBorderDirection = 0 or 1; south side of city
                findTmpLoc = findTmpCity.location;
                for(findCount = 0; findCount < 4; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 2, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 4, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 7, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 6; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 6, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 3; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 5, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                for(findCount = 0; findCount < 6; findCount = findCount + 1) {
                        if(!(GetNeighbor(findTmpLoc, 3, findTmpLoc))) {
                                STL_ColSite = findEmptyLoc;
                                STL_ColSiteScore = 0;
                                return 0;
                        }
                        findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                        if(findLocScore > findHighLocScore) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                        if(findLocScore == findHighLocScore) {
                                findRandNum = Random(1);
                                if(findRandNum < 1) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc;
                                }
                        }
                        for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                                if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                        findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                        if(findLocScore > findHighLocScore) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                        if(findLocScore == findHighLocScore) {
                                                findRandNum = Random(1);
                                                if(findRandNum < 1) {
                                                        findHighLocScore = findLocScore;
                                                        findHighScoreLoc = findTmpLoc2;
                                                }
                                        }
                                }
                        }
                }
                if(!(GetNeighbor(findTmpLoc, 0, findTmpLoc))) {
                        STL_ColSite = findEmptyLoc;
                        STL_ColSiteScore = 0;
                        return 0;
                }
                findLocScore = ColSiteScore(findTmpLoc, findPlayer, findConsiderMountainTerrain);
                if(findLocScore > findHighLocScore) {
                        findHighLocScore = findLocScore;
                        findHighScoreLoc = findTmpLoc;
                }
                if(findLocScore == findHighLocScore) {
                        findRandNum = Random(1);
                        if(findRandNum < 1) {
                                findHighLocScore = findLocScore;
                                findHighScoreLoc = findTmpLoc;
                        }
                }
                for(findCount2 = 0; findCount2 < 8; findCount2 = findCount2 + 1) {
                        if(GetNeighbor(findTmpLoc, findCount2, findTmpLoc2)) {
                                findLocScore = ColSiteScore(findTmpLoc2, findPlayer, findConsiderMountainTerrain);
                                if(findLocScore > findHighLocScore) {
                                        findHighLocScore = findLocScore;
                                        findHighScoreLoc = findTmpLoc2;
                                }
                                if(findLocScore == findHighLocScore) {
                                        findRandNum = Random(1);
                                        if(findRandNum < 1) {
                                                findHighLocScore = findLocScore;
                                                findHighScoreLoc = findTmpLoc2;
                                        }
                                }
                        }
                }
        }
        if(findHighScoreLoc == findTmpLoc || findHighLocScore == 0) {
                STL_ColSite = findEmptyLoc;
                STL_ColSiteScore = 0;
                return 0;
        }
        else {
                STL_ColSite = findHighScoreLoc;
                STL_ColSiteScore = findHighLocScore;
                return 1;
        }
}

///////////////////////////
// SETUP SETTLING
///////////////////////////

void_f SetupSettling() {
        int_t stlInitCount;
        army_t stlInitArmy;

        for(stlInitCount = 0; stlInitCount < g.max_players; stlInitCount = stlInitCount + 1) {
                STL_SETCON[stlInitCount] = 0;
                STL_FRUSTRATION[stlInitCount] = 0;
                STL_MINSETTLEDIST[stlInitCount] = 4;

                STL_FirstSettler[stlInitCount] = stlInitArmy;
                STL_SecondSettler[stlInitCount] = stlInitArmy;
                STL_ThirdSettler[stlInitCount] = stlInitArmy;
                STL_FourthSettler[stlInitCount] = stlInitArmy;
                STL_FifthSettler[stlInitCount] = stlInitArmy;

                STL_FirstSettLoc[stlInitCount] = stlInitArmy.location;
                STL_SecondSettLoc[stlInitCount] = stlInitArmy.location;
                STL_ThirdSettLoc[stlInitCount] = stlInitArmy.location;
                STL_FourthSettLoc[stlInitCount] = stlInitArmy.location;
                STL_FifthSettLoc[stlInitCount] = stlInitArmy.location;

                STL_FirstSettScore[stlInitCount] = -1;
                STL_SecondSettScore[stlInitCount] = -1;
                STL_ThirdSettScore[stlInitCount] = -1;
                STL_FourthSettScore[stlInitCount] = -1;
                STL_FifthSettScore[stlInitCount] = -1;
        }
}

///////////////////////////
// SET SETCON
///////////////////////////

void_f SetAiSetCon() {
        int_t stlSetupPlayer;
        int_t stlSetupHasCities;
        int_t stlSetupMaxCities;
        int_t stlSetupWantCities;
        int_t stlSetupNeedCities;
        int_t stlSetupTurn;

        player[3] = g.player;
        stlSetupPlayer = player[3].owner;
        stlSetupHasCities = player[3].cities;
        stlSetupTurn = GetCurrentRound();
        stlSetupWantCities = MOD_DESIREDCITIES;
        stlSetupMaxCities = MOD_MAXCITIES[stlSetupPlayer];
       
        if(stlSetupPlayer > 0 && !IsHumanPlayer(stlSetupPlayer)) {
                // until turn 200 AI's desire to have their GovSpec MaxCities
                if(stlSetupTurn <= 200) {
                        stlSetupNeedCities = stlSetupMaxCities - stlSetupHasCities;
                }
                // from turn 201 to turn 600 they desire to have as many cities as the "avarage" HUMAN
                // up to MaxCities - 10%
                if(stlSetupTurn > 200 && stlSetupTurn <= 600) {
                        if((stlSetupMaxCities - (stlSetupMaxCities / 10)) >= MOD_DESIREDCITIES) {
                                stlSetupNeedCities = MOD_DESIREDCITIES - stlSetupHasCities;
                        }
                        else {
                                stlSetupNeedCities = (stlSetupMaxcities - (stlSetupMaxCities / 10)) - stlSetupHasCities;
                        }
                }
                // from turn 601 to turn 900 they desire to have as many cities as the "avarage" HUMAN
                // up to MaxCities - 20%
                if(stlSetupTurn > 600 && stlSetupTurn <= 900) {
                        if((stlSetupMaxCities - (stlSetupMaxCities / 5)) >= MOD_DESIREDCITIES) {
                                stlSetupNeedCities = MOD_DESIREDCITIES - stlSetupHasCities;
                        }
                        else {
                                stlSetupNeedCities = (stlSetupMaxcities - (stlSetupMaxCities / 5)) - stlSetupHasCities;
                        }
                }
                // from turn 901 to the end of the game they desire to have as many cities as the "avarage" HUMAN
                // up to MaxCities - 30%
                if(stlSetupTurn > 900) {
                        if((stlSetupMaxCities - (stlSetupMaxCities / 3)) >= MOD_DESIREDCITIES) {
                                stlSetupNeedCities = MOD_DESIREDCITIES - stlSetupHasCities;
                        }
                        else {
                                stlSetupNeedCities = (stlSetupMaxcities - (stlSetupMaxCities / 2)) - stlSetupHasCities;
                        }
                }
                if(stlSetupNeedCities <= 0) {
                        STL_SETCON[stlSetupPlayer] = 0;
                        STL_FRUSTRATION[stlSetupPlayer] = 0;
                }
                if(stlSetupNeedCities > 0 && stlSetupNeedCities <= 5) {
                        STL_SETCON[stlSetupPlayer] = 1;
                }
                if(stlSetupNeedCities > 5 && stlSetupNeedCities <= 10) {
                        STL_SETCON[stlSetupPlayer] = 2;
                }
                if(stlSetupNeedCities > 10) {
                        STL_SETCON[stlSetupPlayer] = 3;
                }
                if(STL_FRUSTRATION[stlSetupPlayer] >= 100) {
                        STL_SETCON[stlSetupPlayer] = 0;
                }
                // determine settling distance
                if(STL_FRUSTRATION[stlSetupPlayer] == 0) {
                        STL_MINSETTLEDIST[stlSetupPlayer] = 7;
                }
                if((STL_FRUSTRATION[stlSetupPlayer] > 0 && STL_FRUSTRATION[stlSetupPlayer] < 30)) {
                        STL_MINSETTLEDIST[stlSetupPlayer] = 5;
                }
                if(STL_FRUSTRATION[stlSetupPlayer] >= 30) {
                        STL_MINSETTLEDIST[stlSetupPlayer] = 4;
                }
        }
}

///////////////////////////
// SETTLING STRATEGIES
///////////////////////////

HandleEvent(NextStrategicState) 'SettlingStrategies' pre {
        int_t stlStratPlayer;
        int_t stlStratCitiesNum;
        int_t stlStratPersonality;

        stlStratPlayer = player[0].owner;
        stlStratCitiesNum = player[0].cities;

        if(!IsHumanPlayer(stlStratPlayer) && stlStratPlayer > 0 && stlStratCitiesNum >= 1) {
                if(STL_SETCON[stlStratPlayer] == 1) {
                        ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_SETCON_1));
                }
                elseif(STL_SETCON[stlStratPlayer] == 2) {
                        ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_SETCON_2));
                }
                elseif(STL_SETCON[stlStratPlayer] == 3) {
                        ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_SETCON_3));
                }
                elseif(STL_SETCON[stlStratPlayer] == 0 && STL_FRUSTRATION[stlStratPlayer] > 0) {
                        stlStratPersonality = GetPersonalityType(stlStratPlayer);
                        if(stlStratPersonality == 0 || stlStratPersonality == 2 || stlStratPersonality == 3 || stlStratPersonality == 4) {        // militarist
                                ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_ISLAND_MILITARIST));
                        }
                        elseif(stlStratPersonality == 1) {                                                                                        // diplomatic
                                ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_ISLAND_DIPLOMATIC));
                        }
                        elseif(stlStratPersonality == 5) {                                                                                        // economic
                                ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_ISLAND_ECONOMIC));
                        }
                        elseif(stlStratPersonality == 6 || stlStratPersonality == 7) {                                                                // scientist
                                ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_ISLAND_SCIENTIST));
                        }
                        elseif(stlStratPersonality == 8 || stlStratPersonality == 9) {                                                                // ecotopian
                                ConsiderStrategicState(player[0], 9999, StrategyDB(STRATEGY_ISLAND_ECOTOPIAN));
                        }
                       
                }
        }
        return CONTINUE;
}

int_f TaskTheSettler(army_t theSettler, int_t whichSettler) {
        army_t        stlTaskSettler;
        location_t stlTaskSettlerLoc;
        int_t stlTaskPlayer;
        int_t stlTaskNearestCityIdx;
        city_t        stlTaskNearestCity;
        int_t stlTaskSuccess;
        int_t stlThisSettler;
        location_t stlTaskEmptyLoc;
        int_t stlTaskConsiderMountains;
        int_t stlTaskAvoid;
        int_t stlTaskCountA;

        stlTaskSettler = theSettler;
        stlThisSettler = whichSettler;
        stlTaskSettlerLoc = stlTaskSettler.location;
        stlTaskPlayer = stlTaskSettler.owner;
        stlTaskNearestCityIdx = GetNearestCity(stlTaskSettlerLoc, stlTaskPlayer);
        stlTaskAvoid = 0;
        stlTaskSuccess = 0;

        if(IsMountainSettlerInStack(stlTaskSettler)) {
                stlTaskConsiderMountains = 1;
        }
        else {
                stlTaskConsiderMountains = 0;
        }
        if(!IsWater(stlTaskSettlerLoc) && GetCityByIndex(stlTaskPlayer, stlTaskNearestCityIdx, stlTaskNearestCity)) {
                if(FindColSite(stlTaskNearestCity, stlTaskConsiderMountains) == 1) {
                        // don't assign sites twice:
                        if(STL_ColSite == STL_FirstSettLoc[stlTaskPlayer]
                        || STL_ColSite == STL_SecondSettLoc[stlTaskPlayer]
                        || STL_ColSite == STL_ThirdSettLoc[stlTaskPlayer]
                        || STL_ColSite == STL_FourthSettLoc[stlTaskPlayer]
                        || STL_ColSite == STL_FifthSettLoc[stlTaskPlayer]) {
                                stlTaskAvoid = 1;
                        }
                        // and don't assign more than one site within one city radius:
                        GetSurroundings(STL_ColSite);
                        for(stlTaskCountA = 0; stlTaskCountA < MOD_SurroundingTiles.#; stlTaskCountA = stlTaskCountA + 1) {
                                if(MOD_SurroundingTiles[stlTaskCountA] == STL_FirstSettLoc[stlTaskPlayer]
                                || MOD_SurroundingTiles[stlTaskCountA] == STL_SecondSettLoc[stlTaskPlayer]
                                || MOD_SurroundingTiles[stlTaskCountA] == STL_ThirdSettLoc[stlTaskPlayer]
                                || MOD_SurroundingTiles[stlTaskCountA] == STL_FourthSettLoc[stlTaskPlayer]
                                || MOD_SurroundingTiles[stlTaskCountA] == STL_FifthSettLoc[stlTaskPlayer]) {
                                        stlTaskAvoid = 1;
                                }
                        }
                        if(stlTaskAvoid == 1) {
                                stlTaskSuccess = 0;
                        }
                        elseif(stlThisSettler == 1) {
                                STL_FirstSettLoc[stlTaskPlayer] = STL_ColSite;
                                STL_FirstSettScore[stlTaskPlayer] = STL_ColSiteScore;
                                stlTaskSuccess = 1;
                        }
                        elseif(stlThisSettler == 2) {
                                STL_SecondSettLoc[stlTaskPlayer] = STL_ColSite;
                                STL_SecondSettScore[stlTaskPlayer] = STL_ColSiteScore;
                                stlTaskSuccess = 1;
                        }
                        elseif(stlThisSettler == 3) {
                                STL_ThirdSettLoc[stlTaskPlayer] = STL_ColSite;
                                STL_ThirdSettScore[stlTaskPlayer] = STL_ColSiteScore;
                                stlTaskSuccess = 1;
                        }
                        elseif(stlThisSettler == 4) {
                                STL_FourthSettLoc[stlTaskPlayer] = STL_ColSite;
                                STL_FourthSettScore[stlTaskPlayer] = STL_ColSiteScore;
                                stlTaskSuccess = 1;
                        }
                        elseif(stlThisSettler == 5) {
                                STL_FifthSettLoc[stlTaskPlayer] = STL_ColSite;
                                STL_FifthSettScore[stlTaskPlayer] = STL_ColSiteScore;
                                stlTaskSuccess = 1;
                        }
                }
        }
        // TEST
        //if(stlTaskSuccess == 1) {
        //        AddCenter(stlTaskSettlerLoc);
        //        AddEffect(stlTaskSettlerLoc,"SPECEFFECT_INVESTIGATE_READINESS","SOUND_ID_ALIEN_GLOW");
        //}
        return stlTaskSuccess;
}

int_f ReTaskTheSettler(army_t theSettler) {
        army_t        stlReTaskSettler;
        location_t stlReTaskSettlerLoc;
        int_t stlReTaskPlayer;
        int_t stlReTaskNearestCityIdx;
        city_t stlReTaskNearestCity;
        int_t stlReTaskConsiderMountains;

        stlReTaskSettler = theSettler;
        stlReTaskSettlerLoc = stlReTaskSettler.location;
        stlReTaskPlayer = stlReTaskSettler.owner;

        if(IsMountainSettlerInStack(stlReTaskSettler)) {
                stlReTaskConsiderMountains = 1;
        }
        else {
                stlReTaskConsiderMountains = 0;
        }
        if(PlayerCityCount(stlReTaskPlayer) > 0) {
                stlReTaskNearestCityIdx = GetNearestCity(stlReTaskSettlerLoc, stlReTaskPlayer);
                if(!IsWater(stlReTaskSettlerLoc) && GetCityByIndex(stlReTaskPlayer, stlReTaskNearestCityIdx, stlReTaskNearestCity)) {
                        if(FindColSite(stlReTaskNearestCity, stlReTaskConsiderMountains) == 1) {
                                if(STL_ColSite != STL_FirstSettLoc[stlReTaskPlayer]
                                && STL_ColSite != STL_SecondSettLoc[stlReTaskPlayer]
                                && STL_ColSite != STL_ThirdSettLoc[stlReTaskPlayer]
                                && STL_ColSite != STL_FourthSettLoc[stlReTaskPlayer]
                                && STL_ColSite != STL_FifthSettLoc[stlReTaskPlayer]) {
                                        return 1;
                                }
                        }
                }
                else {
                        return 0;
                }
        }
        else {
                return 0;
        }
}

void_f SettleNow(army_t theArmy) {
        army_t tmpArmy;
        unit_t tmpUnit;
        location_t tmpArmyLoc;
        city_t tmpCity;
        int_t tmpCount;
        int_t tmpArmySize;

        tmpArmy = theArmy;
        tmpArmyLoc = tmpArmy.location;
        tmpArmySize = tmpArmy.size;

        if(GetUnitFromArmy(tmpArmy, 0, tmpUnit)) {
                Event:Settle(tmpArmy);
        }
}

// Don't override my orders, dammit:

HandleEvent(SettleOrder) 'DontOverrideMyMoveOrdersSettlingGeneral' pre {
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FirstSettler[tmpPlayer]
        || tmpArmy == STL_SecondSettler[tmpPlayer]
        || tmpArmy == STL_ThirdSettler[tmpPlayer]
        || tmpArmy == STL_FourthSettler[tmpPlayer]
        || tmpArmy == STL_FifthSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MoveOrder) 'DontOverrideMyMoveOrdersSettler_1' pre {        // triggers every time the exe gives a pathed move order
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FirstSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MovePathOrder) 'EnableMyOwnMoveOrdersSettler_1' pre {        // triggers when a pathed move order is given via SLIC
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FirstSettler[tmpPlayer]) {
                DisableTrigger('DontOverrideMyMoveOrdersSettler_1');        // in case the exe adds a MoveOrder to MY MovePathOrder
        }
        return CONTINUE;
}

HandleEvent(MoveUnits) 'ResetDontOverrideMyMoveOrdersSettler_1' pre {        // after the desired move has been executed
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FirstSettler[tmpPlayer]) {
                EnableTrigger('DontOverrideMyMoveOrdersSettler_1');
        }
        return CONTINUE;
}

HandleEvent(MoveOrder) 'DontOverrideMyMoveOrdersSettler_2' pre {        // triggers every time the exe gives a pathed move order
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_SecondSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MovePathOrder) 'EnableMyOwnMoveOrdersSettler_2' pre {        // triggers when a pathed move order is given via SLIC
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_SecondSettler[tmpPlayer]) {
                DisableTrigger('DontOverrideMyMoveOrdersSettler_2');        // in case the exe adds a MoveOrder to MY MovePathOrder
        }
        return CONTINUE;
}

HandleEvent(MoveUnits) 'ResetDontOverrideMyMoveOrdersSettler_2' pre {        // after the desired move has been executed
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_SecondSettler[tmpPlayer]) {
                EnableTrigger('DontOverrideMyMoveOrdersSettler_2');
        }
        return CONTINUE;
}

HandleEvent(MoveOrder) 'DontOverrideMyMoveOrdersSettler_3' pre {                // triggers every time the exe gives a pathed move order
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_ThirdSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MovePathOrder) 'EnableMyOwnMoveOrdersSettler_3' pre {        // triggers when a pathed move order is given via SLIC
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_ThirdSettler[tmpPlayer]) {
                DisableTrigger('DontOverrideMyMoveOrdersSettler_3');        // in case the exe adds a MoveOrder to MY MovePathOrder
        }
        return CONTINUE;
}

HandleEvent(MoveUnits) 'ResetDontOverrideMyMoveOrdersSettler_3' pre {        // after the desired move has been executed
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_ThirdSettler[tmpPlayer]) {
                EnableTrigger('DontOverrideMyMoveOrdersSettler_3');
        }
        return CONTINUE;
}

HandleEvent(MoveOrder) 'DontOverrideMyMoveOrdersSettler_4' pre {        // triggers every time the exe gives a pathed move order
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FourthSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MovePathOrder) 'EnableMyOwnMoveOrdersSettler_4' pre {        // triggers when a pathed move order is given via SLIC
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FourthSettler[tmpPlayer]) {
                DisableTrigger('DontOverrideMyMoveOrdersSettler_4');        // in case the exe adds a MoveOrder to MY MovePathOrder
        }
        return CONTINUE;
}

HandleEvent(MoveUnits) 'ResetDontOverrideMyMoveOrdersSettler_4' pre {        // after the desired move has been executed
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FourthSettler[tmpPlayer]) {
                EnableTrigger('DontOverrideMyMoveOrdersSettler_4');
        }
        return CONTINUE;
}

HandleEvent(MoveOrder) 'DontOverrideMyMoveOrdersSettler_5' pre {        // triggers every time the exe gives a pathed move order
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FifthSettler[tmpPlayer]) {
                return STOP;
        }
        return CONTINUE;
}

HandleEvent(MovePathOrder) 'EnableMyOwnMoveOrdersSettler_5' pre {        // triggers when a pathed move order is given via SLIC
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FifthSettler[tmpPlayer]) {
                DisableTrigger('DontOverrideMyMoveOrdersSettler_5');        // in case the exe adds a MoveOrder to MY MovePathOrder
        }
        return CONTINUE;
}

HandleEvent(MoveUnits) 'ResetDontOverrideMyMoveOrdersSettler_5' pre {        // after the desired move has been executed
        army_t tmpArmy;
        int_t tmpPlayer;
       
        tmpArmy = army[0];
        tmpPlayer = tmpArmy.owner;

        if(tmpArmy == STL_FifthSettler[tmpPlayer]) {
                EnableTrigger('DontOverrideMyMoveOrdersSettler_5');
        }
        return CONTINUE;
}

///////////////////////////
// SELECT AND MOVE SETTLERS
///////////////////////////

HandleEvent(StartMovePhase) 'SelectAndMoveSettlers' pre {
        int_t stlArmies;
        int_t stlArmyCount;
        army_t stlArmy;
        int_t stlPlayer;
        location_t stlArmyLoc;
        location_t stlEmptyLoc;
        army_t stlEmptyArmy;
        int_t stlCitiesNum;
        unit_t stlUnit;
        int_t stlCount;
        int_t stlConsiderMountains;

        stlArmies = player[0].armies;
        stlPlayer = player[0].owner;

        for(stlArmyCount = 0; stlArmyCount < stlArmies; stlArmyCount = stlArmyCount + 1) {
                if(GetArmyByIndex(player[0].owner, stlArmyCount, stlArmy)) {
                        if(ArmyIsValid(stlArmy)) {
                                stlArmyLoc = stlArmy.location;
                                stlCitiesNum = PlayerCityCount(stlPlayer);
                                if(!IsHumanPlayer(stlPlayer) && stlPlayer > 0 && stlCitiesNum >= 1 && IsLandSettlerInStack(stlArmy)) {
                                        if(Cities(stlPlayer) < MOD_MAXCITIES[stlPlayer] && !IsPrivilegedArmy(stlArmy, stlPlayer) && !IsWater(stlArmyLoc)) {
                                                if(!ArmyIsValid(STL_FirstSettler[stlPlayer])) {
                                                        if(TaskTheSettler(stlArmy, 1)) {
                                                                STL_FirstSettler[stlPlayer] = stlArmy;
                                                                MoveArmyToTarget(stlArmy, STL_FirstSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(!ArmyIsValid(STL_SecondSettler[stlPlayer])) {
                                                        if(TaskTheSettler(stlArmy, 2)) {
                                                                STL_SecondSettler[stlPlayer] = stlArmy;
                                                                MoveArmyToTarget(stlArmy, STL_SecondSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(!ArmyIsValid(STL_ThirdSettler[stlPlayer])) {
                                                        if(TaskTheSettler(stlArmy, 3)) {
                                                                STL_ThirdSettler[stlPlayer] = stlArmy;
                                                                MoveArmyToTarget(stlArmy, STL_ThirdSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(!ArmyIsValid(STL_FourthSettler[stlPlayer])) {
                                                        if(TaskTheSettler(stlArmy, 4)) {
                                                                STL_FourthSettler[stlPlayer] = stlArmy;
                                                                MoveArmyToTarget(stlArmy, STL_FourthSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(!ArmyIsValid(STL_FifthSettler[stlPlayer])) {
                                                        if(TaskTheSettler(stlArmy, 5)) {
                                                                STL_FifthSettler[stlPlayer] = stlArmy;
                                                                MoveArmyToTarget(stlArmy, STL_FifthSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                        }
                                        if(stlArmy == STL_FirstSettler[stlPlayer]) {
                                                stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                if(ColSiteScore(STL_FirstSettLoc[stlPlayer], stlPlayer, stlConsiderMountains) < STL_FirstSettScore[stlPlayer]) {
                                                        if(STL_SETCON[stlPlayer] > 0 && TaskTheSettler(stlArmy, 1)) {
                                                                MoveArmyToTarget(stlArmy, STL_FirstSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FirstSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(stlArmyLoc != STL_FirstSettLoc[stlPlayer]) {
                                                        MoveArmyToTarget(stlArmy, STL_FirstSettLoc[stlPlayer]);
                                                }
                                        }
                                        if(stlArmy == STL_SecondSettler[stlPlayer]) {
                                                stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                if(ColSiteScore(STL_SecondSettLoc[stlPlayer], stlPlayer, stlConsiderMountains) < STL_SecondSettScore[stlPlayer]) {
                                                        if(STL_SETCON[stlPlayer] > 0 && TaskTheSettler(stlArmy, 2)) {
                                                                MoveArmyToTarget(stlArmy, STL_SecondSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_SecondSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(stlArmyLoc != STL_SecondSettLoc[stlPlayer]) {
                                                        MoveArmyToTarget(stlArmy, STL_SecondSettLoc[stlPlayer]);
                                                }
                                        }
                                        if(stlArmy == STL_ThirdSettler[stlPlayer]) {
                                                stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                if(ColSiteScore(STL_ThirdSettLoc[stlPlayer], stlPlayer, stlConsiderMountains) < STL_ThirdSettScore[stlPlayer]) {
                                                        if(STL_SETCON[stlPlayer] > 0 && TaskTheSettler(stlArmy, 3)) {
                                                                MoveArmyToTarget(stlArmy, STL_ThirdSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_ThirdSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(stlArmyLoc != STL_ThirdSettLoc[stlPlayer]) {
                                                        MoveArmyToTarget(stlArmy, STL_ThirdSettLoc[stlPlayer]);
                                                }
                                        }
                                        if(stlArmy == STL_FourthSettler[stlPlayer]) {
                                                stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                if(ColSiteScore(STL_FourthSettLoc[stlPlayer], stlPlayer, stlConsiderMountains) < STL_FourthSettScore[stlPlayer]) {
                                                        if(STL_SETCON[stlPlayer] > 0 && TaskTheSettler(stlArmy, 4)) {
                                                                MoveArmyToTarget(stlArmy, STL_FourthSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FourthSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(stlArmyLoc != STL_FourthSettLoc[stlPlayer]) {
                                                        MoveArmyToTarget(stlArmy, STL_FourthSettLoc[stlPlayer]);
                                                }
                                        }
                                        if(stlArmy == STL_FifthSettler[stlPlayer]) {
                                                stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                if(ColSiteScore(STL_FifthSettLoc[stlPlayer], stlPlayer, stlConsiderMountains) < STL_FifthSettScore[stlPlayer]) {
                                                        if(STL_SETCON[stlPlayer] > 0 && TaskTheSettler(stlArmy, 5)) {
                                                                MoveArmyToTarget(stlArmy, STL_FifthSettLoc[stlPlayer]);
                                                        }
                                                        else {
                                                                STL_FifthSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                                STL_FRUSTRATION[stlPlayer] = STL_FRUSTRATION[stlPlayer] + 1;
                                                        }
                                                }
                                                elseif(stlArmyLoc != STL_FifthSettLoc[stlPlayer]) {
                                                        MoveArmyToTarget(stlArmy, STL_FifthSettLoc[stlPlayer]);
                                                }
                                        }
                                }
                        }
                }
        }
        return CONTINUE;
}

HandleEvent(BeginTurnAllCities) 'SettleWithMySettlers' pre {
        int_t stlArmies;
        int_t stlArmyCount;
        army_t stlArmy;
        int_t stlPlayer;
        location_t stlArmyLoc;
        int_t stlCitiesNum;
        army_t stlEmptyArmy;
        int_t stlConsiderMountains;

        stlArmies = player[0].armies;

        for(stlArmyCount = 0; stlArmyCount < stlArmies; stlArmyCount = stlArmyCount + 1) {
                if(GetArmyByIndex(player[0].owner, stlArmyCount, stlArmy)) {
                        if(ArmyIsValid(stlArmy)) {
                                stlPlayer = stlArmy.owner;
                                stlArmyLoc = stlArmy.location;
                                stlCitiesNum = PlayerCityCount(stlPlayer);
                                if(!IsHumanPlayer(stlPlayer) && stlPlayer > 0 && stlCitiesNum >= 1 && IsLandSettlerInStack(stlArmy)) {
                                        if(stlArmy == STL_FirstSettler[stlPlayer]) {
                                                if(stlArmyLoc == STL_FirstSettLoc[stlPlayer]) {
                                                        stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                        if(ColSiteScore(stlArmyLoc, stlPlayer, stlConsiderMountains) >= STL_FirstSettScore[stlPlayer]) {
                                                                SettleNow(stlArmy);
                                                        }
                                                        else {
                                                                STL_FirstSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                        }
                                                }
                                        }
                                        if(stlArmy == STL_SecondSettler[stlPlayer]) {
                                                if(stlArmyLoc == STL_SecondSettLoc[stlPlayer]) {
                                                        stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                        if(ColSiteScore(stlArmyLoc, stlPlayer, stlConsiderMountains) >= STL_SecondSettScore[stlPlayer]) {
                                                                SettleNow(stlArmy);
                                                        }
                                                        else {
                                                                STL_SecondSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                        }
                                                }
                                        }
                                        if(stlArmy == STL_ThirdSettler[stlPlayer]) {
                                                if(stlArmyLoc == STL_ThirdSettLoc[stlPlayer]) {
                                                        stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                        if(ColSiteScore(stlArmyLoc, stlPlayer, stlConsiderMountains) >= STL_ThirdSettScore[stlPlayer]) {
                                                                SettleNow(stlArmy);

                                                        }
                                                        else {
                                                                STL_ThirdSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                        }
                                                }
                                        }
                                        if(stlArmy == STL_FourthSettler[stlPlayer]) {
                                                if(stlArmyLoc == STL_FourthSettLoc[stlPlayer]) {
                                                        stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                        if(ColSiteScore(stlArmyLoc, stlPlayer, stlConsiderMountains) >= STL_FourthSettScore[stlPlayer]) {
                                                                SettleNow(stlArmy);

                                                        }
                                                        else {
                                                                STL_FourthSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                        }
                                                }
                                        }
                                        if(stlArmy == STL_FifthSettler[stlPlayer]) {
                                                if(stlArmyLoc == STL_FifthSettLoc[stlPlayer]) {
                                                        stlConsiderMountains = IsMountainSettlerInStack(stlArmy);
                                                        if(ColSiteScore(stlArmyLoc, stlPlayer, stlConsiderMountains) >= STL_FifthSettScore[stlPlayer]) {
                                                                SettleNow(stlArmy);

                                                        }
                                                        else {
                                                                STL_FifthSettler[stlPlayer] = stlEmptyArmy;
                                                                ClearArmyOrders(stlArmy);
                                                        }
                                                }
                                        }
                                }
                        }
                }
        }
        return CONTINUE;
}

///////////////////////////
// DON'T SETTLE HERE
///////////////////////////

HandleEvent(Settle) 'DontSettleHere' pre {
        army_t stlDesperateArmy;
        location_t stlSettleLoc;
        int_t stlDesperadoOwner;
        int_t stlSettleLocOwner;
        int_t stlDontSettleCitiesNum;
        unit_t stlDesperateUnit;
        int_t stlDesperateCapitalIdx;
        city_t stlDesperateCapital;
        location_t stlDesperateCapitalLoc;
        int_t stlDesperateOurContinent;
        int_t stlDesperateStlContinent;
        int_t stlDesperateScore;
        int_t stlDesperateConsiderMountains;

        stlDesperateArmy = army[0];
        stlSettleLoc = stlDesperateArmy.location;
        stlDesperadoOwner = stlDesperateArmy.owner;
        stlSettleLocOwner = CellOwner(stlSettleLoc);
        stlDontSettleCitiesNum = PlayerCityCount(stlDesperadoOwner);
       
        // Move on, please
//        if(stlDesperateArmy == STL_FirstSettler[stlDesperadoOwner]
//        && stlSettleLoc != STL_FirstSettLoc[stlDesperadoOwner]) {
//                return STOP;
//        }
//        if(stlDesperateArmy == STL_SecondSettler[stlDesperadoOwner]
//        && stlSettleLoc != STL_SecondSettLoc[stlDesperadoOwner]) {
//                return STOP;
//        }
//        if(stlDesperateArmy == STL_ThirdSettler[stlDesperadoOwner]
//        && stlSettleLoc != STL_ThirdSettLoc[stlDesperadoOwner]) {
//                return STOP;
//        }
        if(stlSettleLocOwner >= 0 && stlSettleLocOwner != stlDesperadoOwner) {
                if(!IsHumanPlayer(stlDesperadoOwner)) {
                        if(ReTaskTheSettler(stlDesperateArmy)) {
                                MoveArmyToTarget(stlDesperateArmy, STL_ColSite);
                        }
                        else {
                                STL_FRUSTRATION[stlDesperadoOwner] = STL_FRUSTRATION[stlDesperadoOwner] + 1;
                                ClearArmyOrders(stlDesperateArmy);
                        }
                }
                return STOP;
        }
        elseif(!IsHumanPlayer(stlDesperadoOwner) && stlDontSettleCitiesNum > 1) {
                if(stlSettleLoc != STL_FirstSettLoc[stlDesperadoOwner]
                && stlSettleLoc != STL_SecondSettLoc[stlDesperadoOwner]
                && stlSettleLoc != STL_ThirdSettLoc[stlDesperadoOwner]
                && stlSettleLoc != STL_FourthSettLoc[stlDesperadoOwner]
                && stlSettleLoc != STL_FifthSettLoc[stlDesperadoOwner]
                && stlDesperateArmy != STL_FirstSettler[stlDesperadoOwner]
                && stlDesperateArmy != STL_SecondSettler[stlDesperadoOwner]
                && stlDesperateArmy != STL_ThirdSettler[stlDesperadoOwner]
                && stlDesperateArmy != STL_FourthSettler[stlDesperadoOwner]
                && stlDesperateArmy != STL_FifthSettler[stlDesperadoOwner]) {
                        stlDesperateConsiderMountains = IsMountainSettlerInStack(stlDesperateArmy);
                        stlDesperateScore = ColSiteScore(stlSettleLoc, stlDesperadoOwner, stlDesperateConsiderMountains);
                        if(stlDesperateScore == 1) {
                                if(STL_FRUSTRATION[stlDesperadoOwner] < 30) {
                                        stlDesperateCapitalIdx = GetCapital(stlDesperadoOwner);
                                        if(GetCityByIndex(stlDesperadoOwner, stlDesperateCapitalIdx, stlDesperateCapital)) {
                                                stlDesperateCapitalLoc = stlDesperateCapital.location;
                                                stlDesperateOurContinent = GetContinent(stlDesperateCapitalLoc);
                                                stlDesperateStlContinent = GetContinent(stlSettleLoc);
                                                if(stlDesperateOurContinent == stlDesperateStlContinent) {
                                                        if(ReTaskTheSettler(stlDesperateArmy)) {
                                                                MoveArmyToTarget(stlDesperateArmy, STL_ColSite);
                                                        }
                                                        else {
                                                                ClearArmyOrders(stlDesperateArmy);
                                                                STL_FRUSTRATION[stlDesperadoOwner] = STL_FRUSTRATION[stlDesperadoOwner] + 1;
                                                        }
                                                        return STOP;
                                                }
                                        }
                                }
                                else {
                                        return CONTINUE;
                                }
                        }
                        elseif(stlDesperateScore == 0) {
                                if(ReTaskTheSettler(stlDesperateArmy)) {
                                        MoveArmyToTarget(stlDesperateArmy, STL_ColSite);
                                }
                                else {
                                        ClearArmyOrders(stlDesperateArmy);
                                        STL_FRUSTRATION[stlDesperadoOwner] = STL_FRUSTRATION[stlDesperadoOwner] + 1;
                                }
                                return STOP;
                        }
                        else {
                                return CONTINUE;
                        }
                }
                else {
                        return CONTINUE;
                }
        }
        else {
                return CONTINUE;
        }
}

HandleEvent(Settle) 'DecreaseSettlingFrustrationUponSettling' post {
        int_t stlSuccessfulSettler;
        city_t stlSuccessCity;

        // adjusting AI's geographical awareness "could still find land for settling":
        if(STL_FRUSTRATION[stlSuccessfulSettler] > 2) {
                stlSuccessCity = city[0];
                stlSuccessfulSettler = city[0].owner;

                if(CityIsValid(stlSuccessCity)) {
                        if(STL_FRUSTRATION[stlSuccessfulSettler] >= 3) {
                                STL_FRUSTRATION[stlSuccessfulSettler] = (STL_FRUSTRATION[stlSuccessfulSettler] / 3);
                        }
                        else {
                                STL_FRUSTRATION[stlSuccessfulSettler] = 0;
                        }
                }
        }
}

HandleEvent(KillCity) 'DecreaseSettlingFrustrationUponCityLoss' pre {
        int_t stlCityLooser;

        stlCityLooser = city[0].owner;

        if(STL_FRUSTRATION[stlCityLooser] >= 4) {
                STL_FRUSTRATION[stlCityLooser] = (STL_FRUSTRATION[stlCityLooser] / 4);
        }
        else {
                STL_FRUSTRATION[stlCityLooser] = 0;
        }
        return CONTINUE;
}