////////////////////////////////////////////////////////////////////////////
//
// 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);
//				}		
//			}
//		}
//	}
//}
//




