//////////////////////////////////////////////////////////////////////////// // // 1) Scenario script for Frenzy AI Mod version 2.0 // //////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// // 1) Scenario script for Frenzy AI Mod version 2.0 // // Code by: Blueorange 1/18/2001 // Additional optimization and mofification by: WOUTER SNIJDERS (AKA LOCUTUS) - 2001-01-13 ///////////////////////////////////////////////////////////////////////////////////////////// // The Frenzy AI code is simple. Move a lot of AI stacks to the human city, repeatly! // Then, it is up to the Game AI itself to attack any human cities or units, thus strategy.txt and goal.txt are important. // // -For slic writers, feel free to crack, hack, edit, change, modify, whatever with any codes you find here. // especially if you can improve the ai more. (ie, get the ai to use transports, etc...) /////////////////////////////////////////////////////////////////////////////////////////// int_t FAI_ATTACK_SIZE; // minimum stack size for what I consider BIG int_t FAI_WorstEnemyNum[]; army_t FAI_FirstArmy[]; army_t FAI_SecondArmy[]; army_t FAI_ThirdArmy[]; army_t FAI_FourthArmy[]; army_t FAI_FirstNavy[]; army_t FAI_SecondNavy[]; army_t FAI_ThirdNavy[]; army_t FAI_FourthNavy[]; location_t FAI_AttackTarget[]; location_t FAI_NavyTarget[]; HandleEvent(BeginTurn) 'FAI_Initialization' pre { // To prevent debugg slic errors int_t i; army_t tmpArmy; for (i = 0; i <= 32; i = i + 1) { // initialize all playes, so new players from revolts will be 'supported' as well // much simpler & faster like this FAI_FirstArmy[i] = tmpArmy; FAI_SecondArmy[i] = tmpArmy; FAI_ThirdArmy[i] = tmpArmy; FAI_FourthArmy[i] = tmpArmy; FAI_FirstNavy[i] = tmpArmy; FAI_SecondNavy[i] = tmpArmy; FAI_ThirdNavy[i] = tmpArmy; FAI_FourthNavy[i] = tmpArmy; FAI_WorstEnemyNum[i] = 0; FAI_AttackTarget[i] = tmpArmy.location; FAI_NavyTarget[i] = tmpArmy.location; } DisableTrigger('FAI_Initialization'); } int_f FAI_UnitsCount(int_t tmpPlayer) { player[5] = tmpPlayer; // 5 is unlikely to overwrite an existing value return player[5].units; } int_f FAI_ArmyCount(int_t tmpPlayer) { player[5] = tmpPlayer; // 5 is unlikely to overwrite an existing value return player[5].armies; } ////////////////////////////////////////////////// // From Martns code to figure out the sea units // ////////////////////////////////////////////////// int_f IsNonSeaTransporter(unit_t theUnit) { unit_t MGUnit; MGUnit = theUnit; if(MGUnit.type == UnitDB(UNIT_BATTLESHIP) || MGUnit.type == UnitDB(UNIT_DESTROYER) || MGUnit.type == UnitDB(UNIT_FIRE_TRIREME) || MGUnit.type == UnitDB(UNIT_FRIGATE) || MGUnit.type == UnitDB(UNIT_IRONCLAD) || MGUnit.type == UnitDB(UNIT_PLASMA_DESTROYER) || MGUnit.type == UnitDB(UNIT_SHIP_OF_THE_LINE) || MGUnit.type == UnitDB(UNIT_DREADNAUGHT) || MGUnit.type == UnitDB(UNIT_KRAKEN) || MGUnit.type == UnitDB(UNIT_MOREY_STRIKER) || MGUnit.type == UnitDB(UNIT_SCOUT_SUB) || MGUnit.type == UnitDB(UNIT_SUBMARINE) ) { return 1; } return 0; } int_f IsSeaSettler(unit_t theUnit) { // unit_t MGUnit; // Actual this functions asks MGUnit = theUnit; // if a unit is a sea engineer if(MGUnit.type == UnitDB(UNIT_SEA_ENGINEER)) { // and returns true if it is the return 1; // case otherwise false. } // Note in slic the boolean values return 0; // false and true are represented by } // 0 for false and 1 for true. // int_f IsSeaTransporter(unit_t theUnit) { // unit_t MGUnit; // Due to a bug you have to copy the variable MGUnit = theUnit; // if(MGUnit.type == UnitDB(UNIT_CARRACK) // || MGUnit.type == UnitDB(UNIT_CRAWLER) // || MGUnit.type == UnitDB(UNIT_TROOP_SHIP) // This function follow the pattern || MGUnit.type == UnitDB(UNIT_CATAMARAN) // in the functions above. || MGUnit.type == UnitDB(UNIT_LONGSHIP) // Note this is function of type ) { // int_f meaning it returns an integer. return 1; // } // return 0; // } // int_f IsRocketShip(unit_t theUnit) { unit_t MGUnit; MGUnit = theUnit; if(MGUnit.type == UnitDB(UNIT_AIRCRAFT_CARRIER) || MGUnit.type == UnitDB(UNIT_NUCLEAR_SUBMARINE) ) { return 1; } return 0; } int_f IsSeaUnit(unit_t theUnit) { unit_t MGUnit; MGUnit = theUnit; if(IsNonSeaTransporter(MGUnit) || IsRocketShip(MGUnit) || IsSeaTransporter(MGUnit) || IsSeaSettler(MGUnit) ) { return 1; } return 0; } ////////////////////////////////////////////////// // To find out geographic aspects // ////////////////////////////////////////////////// int_f IsLandTerrain(location_t tmpLoc) { int_t TType; TType = TerrainType(tmpLoc); if (TType == TerrainDB(TERRAIN_GRASSLAND) || TType == TerrainDB(TERRAIN_PLAINS) || TType == TerrainDB(TERRAIN_DESERT) || TType == TerrainDB(TERRAIN_TUNDRA) || TType == TerrainDB(TERRAIN_GLACIER) || TType == TerrainDB(TERRAIN_HILL) || TType == TerrainDB(TERRAIN_BROWN_HILL) || TType == TerrainDB(TERRAIN_WHITE_HILL) || TType == TerrainDB(TERRAIN_FOREST) || TType == TerrainDB(TERRAIN_JUNGLE) || TType == TerrainDB(TERRAIN_MOUNTAIN) || TType == TerrainDB(TERRAIN_BROWN_MOUNTAIN) || TType == TerrainDB(TERRAIN_WHITE_MOUNTAIN) || TType == TerrainDB(TERRAIN_SWAMP) || TType == TerrainDB(TERRAIN_DEAD)){ return 1; } return 0; } int_f IsCoastalCity(city_t theCity) { int_t sucess; int_t i; city_t tmpCity; location_t tmpLoc; location_t cityLoc; tmpCity = theCity; cityLoc = tmpCity.location; sucess = 0; while(i < 8 && sucess == 0) { GetNeighbor(cityLoc, i, tmpLoc); if(TerrainType(tmpLoc) == TerrainDB(TERRAIN_WATER_BEACH)) { sucess = 1; } i = i + 1; } return sucess; } int_f IsSeaTerrain(location_t tmpLoc) { int_t TType; TType = TerrainType(tmpLoc); if (TType == TerrainDB(TERRAIN_WATER_BEACH) || TType == TerrainDB(TERRAIN_WATER_DEEP) || TType == TerrainDB(TERRAIN_WATER_RIFT) || TType == TerrainDB(TERRAIN_WATER_SHALLOW) || TType == TerrainDB(TERRAIN_WATER_KELP) || TType == TerrainDB(TERRAIN_WATER_REEF) || TType == TerrainDB(TERRAIN_WATER_SHELF) || TType == TerrainDB(TERRAIN_WATER_TRENCH) || TType == TerrainDB(TERRAIN_WATER_VOLCANO)){ return 1; } return 0; } ////////////////////////////////////////////////// // From BlueO´s original code // ////////////////////////////////////////////////// int_f FAI_CheckGroupage(army_t checkArmy) { // check to see if army should do group order int_t i; int_t num; city_t tmpCity; unit_t tmpUnit; army_t tmpArmy; tmpArmy = checkArmy; if (GetCityByLocation(tmpArmy.location, tmpCity)) { return 0; } else { num = GetUnitsAtLocation(tmpArmy.location); for (i = 0; i < num; i = i + 1) { GetUnitFromCell(tmpArmy.location, i, tmpUnit); if (tmpUnit == UnitDB(UNIT_SETTLER) || tmpUnit == UnitDB(UNIT_URBAN_PLANNER) || tmpUnit == UnitDB(UNIT_SPY) || tmpUnit == UnitDB(UNIT_DIPLOMAT)) { return 0; } } } return 1; } int_f FAI_AttackEvaluateLocation(location_t evalLoc, int_t evalPlayer) { // find direction of human assets // remember to test for sea stack, and see what happens. int_t i; location_t tmpLoc; city_t tmpCity; unit_t tmpUnit; for (i=0; i<=7 ; i=i+1) { tmpLoc = evalLoc; GetNeighbor(tmpLoc, i, tmpLoc); if (GetCityByLocation(tmpLoc, tmpCity)) { if(CityIsValid(tmpCity) && GetEffectiveRegard(evalPlayer, tmpCity.owner) < 300) { return i; } } elseif (GetUnitsAtLocation(tmpLoc) > 0) { GetUnitFromCell(tmpLoc, 0, tmpUnit); if(tmpUnit.valid == 1 && GetEffectiveRegard(evalPlayer, tmpUnit.owner) < 300) { return i; } } } return 10; // no target found } HandleEvent(EndTurn) 'FAI_SetAttackLandTarget' pre { int_t i; int_t j; int_t a; int_t num; int_t sucess; int_t c; int_t EnemyRegard; int_t minArmySize; int_t tmpDistance; int_t minDistance; int_t WorstEnemy; int_t LowestRegard; int_t checkPlayer; int_t CityCount; int_t armyCount; int_t tmpPlayer; army_t tmpArmy; city_t tmpCity; location_t tmpLoc; location_t armyLoc; minDistance = 500; minArmySize = 1; LowestRegard = 1000; EnemyRegard = 0; if(!IsHumanPlayer(player[0])) { for (checkPlayer = 1; checkPlayer <= 32; checkPlayer = checkPlayer + 1) { if(IsPlayerAlive(checkPlayer)) { EnemyRegard = GetEffectiveRegard(player[0], checkPlayer); if(EnemyRegard < LowestRegard) { FAI_WorstEnemyNum[player[0]]= checkPlayer; LowestRegard = EnemyRegard; } } } if(LowestRegard > 500) { FAI_WorstEnemyNum[player[0]] = 0; } num = FAI_ArmyCount(player[0]); for (i = 0; i < num; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsLandTerrain(tmpArmy.location) && FAI_CheckGroupage(tmpArmy) == 1) { if(minArmySize < tmpArmy.size) { FAI_FirstArmy[player[0]] = tmpArmy; } } } for (i = 0; i < num; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsLandTerrain(tmpArmy.location) && tmpArmy != FAI_FirstArmy[player[0]] && FAI_CheckGroupage(tmpArmy) == 1) { if(minArmySize < tmpArmy.size) { FAI_SecondArmy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } for (i = 0; i < num; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsLandTerrain(tmpArmy.location) && tmpArmy != FAI_FirstArmy[player[0]] && tmpArmy != FAI_SecondArmy[player[0]] && FAI_CheckGroupage(tmpArmy) == 1) { if(minArmySize < tmpArmy.size) { FAI_ThirdArmy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } for (i = 0; i < num; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsLandTerrain(tmpArmy.location) && tmpArmy != FAI_FirstArmy[player[0]] && tmpArmy != FAI_SecondArmy[player[0]] && tmpArmy != FAI_ThirdArmy[player[0]] && FAI_CheckGroupage(tmpArmy) == 1) { if(minArmySize < tmpArmy.size) { FAI_FourthArmy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } if(ArmyIsValid(FAI_FirstArmy[player[0]])) { CityCount = PlayerCityCount(WorstEnemy); for(j = 0; j < CityCount; j = j + 1) { GetCityByIndex(WorstEnemy, j, tmpCity); if(CityIsValid(tmpCity) && !IsUnderseaCity(tmpCity)) { tmpLoc = tmpCity.location; tmpDistance = Distance(tmpLoc, FAI_FirstArmy[i].location); if (tmpDistance < minDistance) { if(IsContinentBiggerThan(tmpCity.location, tmpDistance) && IsContinentBiggerThan(FAI_FirstArmy[i].location, tmpDistance)) { GetRandomNeighbor(tmpCity.location, tmpLoc); FAI_AttackTarget[player[0]] = tmpLoc; minDistance = tmpDistance; } } } } if(minDistance == 500) { for(tmpPlayer = 0; tmpPlayer < 33; tmpPlayer = tmpPlayer + 1) { if(IsPlayerAlive(tmpPlayer)) { armyCount = FAI_ArmyCount(tmpPlayer); for(a = 0; a < armyCount; a = a + 1) { GetArmyByIndex(tmpPlayer, a, tmpArmy); tmpLoc = tmpArmy.location; if(armyIsValid(tmpArmy) && CellOwner(tmpArmy.location) == player[0] && GetEffectiveRegard(player[0], tmpPlayer) < 300 && IsLandTerrain(tmpLoc)) { tmpDistance = Distance(tmpLoc, FAI_FirstArmy[i].location); if (tmpDistance < minDistance) { FAI_AttackTarget[player[0]] = tmpLoc; minDistance = tmpDistance; } } } } } } } if(minDistance == 500 && WorstEnemy > 0) { GetMostAtRiskCity(player[0], WorstEnemy, tmpCity); if(CityIsValid(tmpCity) && !IsUnderseaCity(tmpCity)) { for (j = 0; j < 8; j = j + 1){ GetNeighbor(tmpCity.location, j, tmpLoc); if(IsLandTerrain(tmpLoc)) { minDistance = 100; FAI_AttackTarget[player[0]] = tmpLoc; sucess = 1; } } } } if(minDistance == 500) { c = 0; while(c < player[0].cities && sucess == 0) { GetCityByIndex(player[0], c, tmpCity); if(CityIsValid(tmpCity) && !IsUnderseaCity(tmpCity)) { for (j = 0; j < 8; j = j + 1){ GetNeighbor(tmpCity.location, j, tmpLoc); if(IsLandTerrain(tmpLoc)) { FAI_AttackTarget[player[0]] = tmpLoc; sucess = 1; } } } c = c + 1; } } } } HandleEvent(BeginTurn) 'FAI_ForceArmiesToMove' post { // gives continuous orders to 1st, 2nd Armies army_t tmpArmy; city_t tmpCity; location_t tmpLoc; int_t result; int_t tmpOwner; int_t WorstEnemy; tmpOwner = player[0]; if(!IsHumanPlayer(tmpOwner)) { if(ArmyIsValid(FAI_FirstArmy[tmpOwner])) { tmpArmy = FAI_FirstArmy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_SecondArmy[tmpOwner])) { tmpArmy = FAI_SecondArmy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_ThirdArmy[tmpOwner])) { tmpArmy = FAI_ThirdArmy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_FourthArmy[tmpOwner])) { tmpArmy = FAI_FourthArmy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } } } HandleEvent(MovePathOrder) 'ArmiesGetBiggerAndBigger' post { int_t tmpPlayer; tmpPlayer = g.player; if(army[0] == FAI_FirstArmy[tmpPlayer] || army[0] == FAI_SecondArmy[tmpPlayer] || army[0] == FAI_ThirdArmy[tmpPlayer] || army[0] == FAI_FourthArmy[tmpPlayer]) { if(FAI_CheckGroupage(army[0]) == 1) { Event: GroupOrder(army[0]); } } } // //HandleEvent(MoveUnits) 'FAI_MoveUnits' pre { // This handler gives continuous orders for frenzied units on the move //int_t result; //int_t tmpPlayer; //int_t regard; //army_t tmpArmy; //city_t tmpCity; //location_t tmpLoc; //location_t tmp2Loc; //int_t doFrenzyMoves; //int_t WorstEnemy; // if (ArmyIsValid(army[0]) // && IsLandTerrain(army[0].location)){ // doFrenzyMoves = 0; // tmpArmy = army[0]; // tmpPlayer = tmpArmy.owner; // if(!IsHumanPlayer(tmpPlayer)){ // if(FAI_CheckGroupage(tmpArmy) == 1) { // Event: GroupOrder(tmpArmy); // } // WorstEnemy = FAI_WorstEnemyNum[tmpArmy.owner]; // if(WorstEnemy > 0 // && IsPlayerAlive(WorstEnemy) // && tmpArmy != FAI_FirstArmy[tmpArmy.owner] // && tmpArmy != FAI_SecondArmy[tmpArmy.owner] // && tmpArmy != FAI_ThirdArmy[tmpArmy.owner] // && tmpArmy != FAI_FourthArmy[tmpArmy.owner] // ) { // regard = GetEffectiveRegard(tmpArmy.owner, WorstEnemy); // if(regard < 50) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/3 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/4) { // doFrenzyMoves = 1; // } // } // if(regard >= 50 && regard < 150) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/3) { // doFrenzyMoves = 1; // } // } // if(regard >= 150 && regard < 300) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/2) { // doFrenzyMoves = 1; // } // } // if(regard >= 300 && regard < 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // if(regard >= 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // } // if (doFrenzyMoves == 1 // && FAI_CheckGroupage(tmpArmy) == 1) { // result = FAI_AttackEvaluateLocation(tmpArmy.location, WorstEnemy); // if (result == 10) { // Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); // } else { // Event: MoveToOrder(tmpArmy, result); // } // } // } // } //} // // Causing loops somehow :( // //HandleEvent(EntrenchOrder) 'FAI_EntrenchUnits' pre { // This handler will choose FAI_FirstArmy and FAI_SecondArmy //int_t result; //int_t regard; //army_t tmpArmy; //city_t tmpCity; //location_t tmpLoc; //location_t tmp2Loc; //int_t doFrenzyMoves; //int_t WorstEnemy; // // if (ArmyIsValid(army[0])){ // doFrenzyMoves = 0; // tmpArmy = army[0]; // if(!IsHumanPlayer(tmpArmy.owner)){ // if(FAI_CheckGroupage(tmpArmy) == 1) { // Event: GroupOrder(tmpArmy); // } // if(tmpArmy.size > FAI_FirstArmy[tmpArmy.owner].size // || !ArmyIsValid(FAI_FirstArmy[tmpArmy.owner])) { // FAI_FirstArmy[tmpArmy.owner] = tmpArmy; // } // elseif(tmpArmy.size > FAI_SecondArmy[tmpArmy.owner].size // || !ArmyIsValid(FAI_SecondArmy[tmpArmy.owner])) { // FAI_SecondArmy[tmpArmy.owner] = tmpArmy; // } // elseif(tmpArmy.size > FAI_ThirdArmy[tmpArmy.owner].size // || !ArmyIsValid(FAI_ThirdArmy[tmpArmy.owner])) { // FAI_ThirdArmy[tmpArmy.owner] = tmpArmy; // } // elseif(tmpArmy.size > FAI_FourthArmy[tmpArmy.owner].size // || !ArmyIsValid(FAI_FourthArmy[tmpArmy.owner])) { // FAI_FourthArmy[tmpArmy.owner] = tmpArmy; // } // WorstEnemy = FAI_WorstEnemyNum[tmpArmy.owner]; // if(WorstEnemy > 0 // && IsPlayerAlive(WorstEnemy)) { // regard = GetEffectiveRegard(tmpArmy.owner, WorstEnemy); // if(regard < 50) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/3 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/4) { // doFrenzyMoves = 1; // } // } // if(regard >= 50 && regard < 150) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/3) { // doFrenzyMoves = 1; // } // } // if(regard >= 150 && regard < 300) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/2) { // doFrenzyMoves = 1; // } // } // if(regard >= 300 && regard < 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // if(regard >= 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE // && IsLandTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // } // if (doFrenzyMoves == 1) { // result = FAI_AttackEvaluateLocation(tmpArmy.location, WorstEnemy); // if (result == 10) { // Event: MovePathOrder(tmpArmy, FAI_AttackTarget[tmpArmy.owner]); // } else { // Event: MoveToOrder(tmpArmy, result); // } // } // } // } //} ////////////////////////////////// // // Navy Code // ////////////////////////////////// HandleEvent(CreateUnit) 'InitiateNavyPrepare' post { int_t unitNum; int_t i; int_t j; int_t sucess; unit_t tmpUnit; army_t tmpArmy; army_t tmpArmy2; city_t tmpcity; location_t cityLoc; location_t tmpLoc; if(CityIsValid(city[0]) && IsCoastalCity(city[0]) && IsUnderseaCity(city[0])) { cityLoc = city[0].location; unitNum = GetUnitsAtLocation(cityLoc); if(unitNum > 3) { for(i = 0; i < unitNum; i = i + 1) { GetUnitFromCell(cityLoc, i, tmpUnit); GetArmyFromUnit(tmpUnit, tmpArmy); if(IsSeaUnit(tmpUnit) && ArmyIsValid(tmpArmy)){ Event: UngroupOrder(tmpArmy); j = 0; sucess = 0; while(j < 8 && sucess == 0) { GetArmyFromUnit(tmpUnit, tmpArmy2); GetNeighBor(cityLoc, j, tmpLoc); if(IsSeaTerrain(tmpLoc) && ArmyIsValid(tmpArmy)){ Event: MoveToOrder(tmpArmy, j); sucess = 1; } j = j + 1; } } } } } } HandleEvent(BeginTurn) 'FAI_SetNaviesTarget' pre { int_t i; int_t j; int_t a; int_t c; int_t num; int_t minArmySize; int_t sucess; location_t tmpLoc; city_t tmpCity; int_t tmpDistance; int_t minDistance; int_t WorstEnemy; int_t CityCount; int_t armyCount; int_t tmpPlayer; army_t tmpArmy; location_t armyLoc; minDistance = 500; minArmySize = 1; if(!IsHumanPlayer(player[0])) { WorstEnemy = FAI_WorstEnemyNum[player[0]]; for (i = 0; i < player[0].armies; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsSeaTerrain(tmpArmy.location)) { if(minArmySize < tmpArmy.size) { minArmySize = tmpArmy.size; FAI_FirstNavy[player[0]] = tmpArmy; } } } minArmySize = 1; for (i = 0; i < player[0].armies; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsSeaTerrain(tmpArmy.location) && tmpArmy != FAI_FirstNavy[player[0]]) { if(minArmySize < tmpArmy.size) { FAI_SecondNavy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } minArmySize = 1; for (i = 0; i < player[0].armies; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsSeaTerrain(tmpArmy.location) && tmpArmy != FAI_FirstNavy[player[0]] && tmpArmy != FAI_SecondNavy[player[0]]) { if(minArmySize < tmpArmy.size) { FAI_ThirdNavy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } minArmySize = 1; for (i = 0; i < player[0].armies; i = i + 1){ GetArmyByIndex(player[0], i, tmpArmy); if(ArmyIsValid(tmpArmy) && IsSeaTerrain(tmpArmy.location) && tmpArmy != FAI_FirstNavy[player[0]] && tmpArmy != FAI_SecondNavy[player[0]] && tmpArmy != FAI_ThirdNavy[player[0]]) { if(minArmySize < tmpArmy.size) { FAI_FourthNavy[player[0]] = tmpArmy; minArmySize = tmpArmy.size; } } } if(ArmyIsValid(FAI_FirstNavy[player[0]])) { CityCount = PlayerCityCount(WorstEnemy); for(j = 0; j < CityCount; j = j + 1) { GetCityByIndex(WorstEnemy, j, tmpCity); if(CityIsValid(tmpCity)) { if(IsUnderseaCity(tmpCity) || IsCoastalCity(tmpCity)) { tmpLoc = tmpCity.location; tmpDistance = Distance(tmpLoc, FAI_FirstNavy[i].location); if (tmpDistance < minDistance) { GetRandomNeighbor(tmpCity.location, tmpLoc); FAI_NavyTarget[player[0]] = tmpLoc; minDistance = tmpDistance; } } } } if(minDistance == 500) { for(tmpPlayer = 0; tmpPlayer < 33; tmpPlayer = tmpPlayer + 1) { if(IsPlayerAlive(tmpPlayer)) { armyCount = FAI_ArmyCount(tmpPlayer); for(a = 0; a < armyCount; a = a + 1) { GetArmyByIndex(tmpPlayer, a, tmpArmy); tmpLoc = tmpArmy.location; if(armyIsValid(tmpArmy) && CellOwner(tmpArmy.location) == player[0] && GetEffectiveRegard(player[0], tmpPlayer) < 300 && IsSeaTerrain(tmpLoc)) { tmpDistance = Distance(tmpLoc, FAI_FirstNavy[i].location); if (tmpDistance < minDistance) { FAI_NavyTarget[player[0]] = tmpLoc; minDistance = tmpDistance; } } } } } } } if(minDistance == 500 && WorstEnemy > 0) { GetMostAtRiskCity(player[0], WorstEnemy, tmpCity); if(CityIsValid(tmpCity)) { if(IsCoastalCity(tmpCity) || IsUnderSeaCity(tmpCity)) { for(j = 0; j < 8; j = j + 1) { GetNeighbor(tmpCity.location, j, tmpLoc); if(IsSeaTerrain(tmpLoc)) { minDistance = 100; FAI_NavyTarget[player[0]] = tmpLoc; sucess = 1; } } } c = c + 1; } } if(minDistance == 500) { while(c < player[0].cities && sucess == 0) { GetCityByIndex(player[0], c, tmpCity); if(IsCoastalCity(tmpCity) || IsUnderSeaCity(tmpCity)) { for(j = 0; j < 8; j = j + 1) { GetNeighbor(tmpCity.location, j, tmpLoc); if(IsSeaTerrain(tmpLoc)) { FAI_NavyTarget[player[0]] = tmpLoc; sucess = 1; } } } c = c + 1; } } } } HandleEvent(BeginTurn) 'FAI_ForceNaviesToMove' post { // gives continuous orders to 1st, 2nd Armies army_t tmpArmy; city_t tmpCity; location_t tmpLoc; int_t result; int_t tmpOwner; tmpOwner = player[0]; if(!IsHumanPlayer(tmpOwner)) { if(ArmyIsValid(FAI_FirstNavy[tmpOwner])) { tmpArmy = FAI_FirstNavy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_NavyTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_SecondNavy[tmpOwner])) { tmpArmy = FAI_SecondNavy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_NavyTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_ThirdNavy[tmpOwner])) { tmpArmy = FAI_ThirdNavy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_NavyTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } if (ArmyIsValid(FAI_FourthNavy[tmpOwner])) { tmpArmy = FAI_FourthNavy[tmpOwner]; result = FAI_AttackEvaluateLocation(tmpArmy.location, tmpArmy.owner); if (result == 10) { Event: MovePathOrder(tmpArmy, FAI_NavyTarget[tmpArmy.owner]); } else { Event: MoveToOrder(tmpArmy, result); } } } } HandleEvent(MovePathOrder) 'NaviesGetBiggerAndBigger' post { int_t tmpPlayer; tmpPlayer = g.player; if(army[0] == FAI_FirstNavy[tmpPlayer] || army[0] == FAI_SecondNavy[tmpPlayer] || army[0] == FAI_ThirdNavy[tmpPlayer] || army[0] == FAI_FourthNavy[tmpPlayer]) { if(FAI_CheckGroupage(army[0]) == 1) { Event: GroupOrder(army[0]); } } } // // Four attacking navies is enough so i removed this // Since despite land armies the sea armies are more important as transporters // //HandleEvent(MoveUnits) 'FAI_MoveSeaUnits' pre { // This handler gives continuous orders for frenzied units on the move //int_t result; //int_t tmpPlayer; //int_t regard; //army_t tmpArmy; //city_t tmpCity; //location_t tmpLoc; //location_t tmp2Loc; //int_t doFrenzyMoves; //int_t WorstEnemy; // if (ArmyIsValid(army[0]) // && IsSeaTerrain(army[0].location)){ // doFrenzyMoves = 0; // tmpArmy = army[0]; // tmpPlayer = tmpArmy.owner; // if(!IsHumanPlayer(tmpPlayer)){ // if(FAI_CheckGroupage(tmpArmy) == 1) { // Event: GroupOrder(tmpArmy); // } // WorstEnemy = FAI_WorstEnemyNum[tmpPlayer]; // regard = GetEffectiveRegard(tmpPlayer, WorstEnemy); // if(regard < 50) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/3 // && IsSeaTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/4) { // doFrenzyMoves = 1; // } // } // if(regard >= 50 && regard < 150) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsSeaTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/3) { // doFrenzyMoves = 1; // } // } // if(regard >= 150 && regard < 300) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsSeaTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)/2) { // doFrenzyMoves = 1; // } // } // if(regard >= 300 && regard < 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE/2 // && IsSeaTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // if(regard >= 500) { // if (tmpArmy.size >= FAI_ATTACK_SIZE // && IsSeaTerrain(tmpArmy.location) // && FAI_UnitsCount(tmpArmy.owner) > FAI_Unitscount(WorstEnemy)) { // doFrenzyMoves = 1; // } // } // if (doFrenzyMoves == 1) { // result = FAI_AttackEvaluateLocation(tmpArmy.location, WorstEnemy); // if (result == 10) { // Event: MovePathOrder(tmpArmy, FAI_NavyTarget[tmpArmy.owner]); // } else { // Event: MoveToOrder(tmpArmy, result); // } // } // } // } //} //