Images
Pirate Island

Barbarian Cities

This is an attempt to make good old barbs a bit more interesting and challenging in the later game:

  • Upon certain player events a part of the player’s population possibly "flees" and founds a "barb" city in a distant place. This may happen when a player unconverts or recaptures a city, or when a player is killed.
  • Whenever a city riots a part of the city population possibly flees and joins the outlaws in these "independent" settlements.

Additionally, a modified version of the original Frenzy AI script (1.0, by BlueOrange) is applied to barbarian strategies, since no diplomatic precautions or tactical refinements are needed here: It’s the job of barbs/terrorists to just terrorize the other players. Their hate level towards a certain player will rise whenever

  • the player achieves certain advances, considered "evil" by the revolutionaries
  • the player enters a new age
  • the player captures a city
  • the player nukes a city
  • the player fights a battle against good old barbs

Their hate level will also be reduced when the player achieves certain advances, considered "good/progressive" from a revolutionary point of view.

The rest is history: Good old barbs will throw frenzy stacks against the player they hate most.

The Script

//--------------------------------------------------------------------------
// MoT Mod for CTP2 (Apolyton Edition) by BureauBert
// v1.1
// http://motmod.ctp2.info
//--------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Barbarian City Code
// by BureauBert
// Creates Barb cities upon certain player events
// and lets good old Barbs go frenzy against their worst enemy
////////////////////////////////////////////////////////////////////////////

///////////////////////////////////
// Keep Good Old Barbs up to date
///////////////////////////////////

HandleEvent(BeginTurn) 'KeepBarbsUpdated' pre {
	int_t brbCurrPlayer;
	int_t brbDesiredAdvance;

	brbCurrPlayer = player[0].owner;
	brbDesiredAdvance = GetNextAdvance(0);

 	if(brbCurrPlayer != 0 && KnowledgeRank(brbCurrPlayer) >= (g.num_of_players / 2)) {
		if(HasAdvance(brbCurrPlayer, brbDesiredAdvance)) {
			GrantAdvance(0, brbDesiredAdvance);
		}
	}
	return CONTINUE;
}

///////////////////////////////////
// Barb City Creation
///////////////////////////////////

// Functions

int_f IsGoodBarbLocation(location_t brbTmpLoc) {
	int_t brbTmpPlayer;
	int_t brbCityCount;
	city_t brbThisCity;
	int_t brbMinDist;
	int_t brbCityDist;
	location_t brbCheckLoc;
	int_t brbCountA;
	int_t brbCheckDist;

	brbCheckLoc = brbTmpLoc;
	brbMinDist = GetMapWidth() / 7;
	brbCheckDist = 9999;

	for(brbTmpPlayer = 1; brbTmpPlayer < g.max_players; brbTmpPlayer = brbTmpPlayer + 1) {
		if(IsPlayerAlive(brbTmpPlayer)) {
			brbCityCount = PlayerCityCount(brbTmpPlayer);
			for(brbCountA = 0; brbCountA < brbCityCount; brbCountA = brbCountA + 1) {
				if(GetCityByIndex(brbTmpPlayer, brbCountA, brbThisCity)) {
					brbCityDist = Distance(brbCheckLoc, brbThisCity.location);
					if(brbCityDist < brbCheckDist) {
						brbCheckDist = brbCityDist;
					}
				}
			}
		}
	}
	if(brbCheckDist >= brbMinDist) {
		return 1;
	}
	return 0;
}

int_f CreateBarbCity() {
	int_t brbCountB;
	int_t brbX;
	int_t brbY;
	location_t brbTmpLoc;
	city_t brbTmpCity;
	
	// 30 attempts per event

	if(AE_SAFEMODE_BARBCITIES != 1) {
		for(brbCountB = 0; brbCountB < 30; brbCountB = brbCountB + 1) {
			brbX = Random(GetMapWidth());
			brbY = Random(GetMapHeight());
			MakeLocation(brbTmpLoc, brbX, brbY);
			if(CellOwner(brbTmpLoc) == -1
			&& ColSiteScore(brbTmpLoc, 0, 1) > 0
			&& IsGoodBarbLocation(brbTmpLoc) == 1) {
				CreateCity(0, brbTmpLoc, 0, brbTmpCity);
				if(CityIsValid(brbTmpCity)) {
					Event:MakePop(brbTmpCity);
					Event:MakePop(brbTmpCity);
					if(HasAdvance(0, AdvanceDB(ADVANCE_JURISPRUDENCE))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_COURTHOUSE));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_ASTRONOMY))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_GRANARY));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_RELIGION))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_SHRINE));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_MASONRY))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_AQUEDUCT));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_ENGINEERING))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_ARENA));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_CURRENCY))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_BAZAAR));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_MECHANICAL_POWER))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_MILL));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_MECHANICAL_CLOCK))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_CITY_CLOCK));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_BANKING))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_BANK));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_PHILOSOPHY))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_ACADEMY));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_PRINTING_PRESS))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_PUBLISHING_HOUSE));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_ECONOMICS))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_BROKERAGE));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_INDUSTRIAL_REVOLUTION))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_FACTORY));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_RAILROAD))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_FOOD_SILO));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_SANITATION))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_DRUG_STORE));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_ADV_URBAN_PLANNING))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_PUBLIC_PARK));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_PUBLIC_EDUCATION))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_ORBITAL_LABORATORY));
					}
					if(HasAdvance(0, AdvanceDB(ADVANCE_MEDICINE))) {
						CreateBuilding(brbTmpCity, BuildingDB(IMPROVE_HOSPITAL));
					}
					city[3] = brbTmpCity;	// for use in message
					return 1;
				}
			}
		}
	}
	return 0;
}

// Triggers

HandleEvent(UnconvertCity) 'CityForBarbsUnconvert' post {
	int_t brbMaxCityNum;
	int_t brbCountC;
	city_t brbUnconvertCity;
	
	brbMaxCityNum = GetMapHeight() / 40;
	brbUnconvertCity = city[0];
	brbCountC = PlayerCityCount(0);
	
	if(brbCountC <= brbMaxCityNum) { 
		if(CreateBarbCity() == 1) {
			
			// if we could create a barb city, enable
			// barb frenzy tactics (below):
	
			BRB_INIT = 1;
	
			// and let the world know:

			city[0] = brbUnconvertCity;
			player[0] = city[0].owner;
			Message(player[0], 'BarbsGotCityUnconvertMsgA');
			MessageAllBut(player[0], 'BarbsGotCityUnconvertMsgB');
		}
	}
	if(brbCountC > brbMaxCityNum) {
		DisableTrigger('CityForBarbsUnconvert');
	}
}

HandleEvent(KillPlayer) 'CityForBarbsKillPlayer' pre {
	int_t brbMaxCityNum;
	int_t brbCountC;
	
	brbMaxCityNum = GetMapHeight() / 40;
	brbCountC = PlayerCityCount(0);

	if(brbCountC <= brbMaxCityNum) { 
		if(CreateBarbCity() == 1) {
			
			// if we could create a barb city, enable
			// barb frenzy tactics (below):

			BRB_INIT = 1;
			BRB_HateLevel[player[0].owner] = BRB_HateLevel[player[0].owner] + 50;
	
			// and let the world know:

			Message(player[0], 'BarbsGotCityKillPlayerMsgA');
			MessageAllBut(player[0], 'BarbsGotCityKillPlayerMsgB');
		}
	}
	if(brbCountC > brbMaxCityNum) {
		DisableTrigger('CityForBarbsKillPlayer');
	}
	return CONTINUE;
}

HandleEvent(AccomplishFeat) 'CityForBarbsRecapture' post {
	int_t brbMaxCityNum;
	int_t brbCountC;
	int_t brbFeatureNum;

	brbFeatureNum = value[0].value;
	
	if(brbFeatureNum == FeatDB(FEAT_CITY_RECAPTURED)) {
		brbMaxCityNum = GetMapHeight() / 40;
		brbCountC = PlayerCityCount(0);
		if(brbCountC <= brbMaxCityNum) { 
			if(CreateBarbCity() == 1) {
					
				// if we could create a barb city, enable
				// barb frenzy tactics (below):
		
				BRB_INIT = 1;
		
				// and let the world know:
	
				Message(player[0], 'BarbsGotCityRecaptureMsgA');
				MessageAllBut(player[0], 'BarbsGotCityRecaptureMsgB');
			}
		}
	}
	if(brbCountC > brbMaxCityNum) {
		DisableTrigger('CityForBarbsRecapture');
	}
}

// Messages

messagebox 'BarbsGotCityUnconvertMsgA' {
	Text(ID_BARBS_GOT_CITY_UNCONVERT_A);
	Show();
}

messagebox 'BarbsGotCityUnconvertMsgB' {
	Text(ID_BARBS_GOT_CITY_UNCONVERT_B);
	Show();
}

messagebox 'BarbsGotCityKillPlayerMsgA' {
	Text(ID_BARBS_GOT_CITY_KILLPLAYER_A);
	Show();
}

messagebox 'BarbsGotCityKillPlayerMsgB' {
	Text(ID_BARBS_GOT_CITY_KILLPLAYER_B);
	Show();
}

messagebox 'BarbsGotCityRecaptureMsgA' {
	Text(ID_BARBS_GOT_CITY_RECAPTURE_A);
	Show();
}

messagebox 'BarbsGotCityRecaptureMsgB' {
	Text(ID_BARBS_GOT_CITY_RECAPTURE_B);
	Show();
}

///////////////////////////////////
// Other non-barb civ events
///////////////////////////////////

// eg. unhappy people from our unhappy cities joining the outlaws in the woods

HandleEvent(CityRiot) 'PopJoinsBarbs' pre {
	city_t brbRiotCity;
	int_t brbRiotPlayer;
	int_t brbRiotCitySize;
	location_t brbRiotCityLoc;
	int_t brbEmigChance;
	int_t brbMaxEmig;
	int_t brbEmigNum;
	int_t brbRemPops;
	int_t brbCityIdx;
	city_t brbCity;

	brbRiotCity = city[0];
	brbRiotPlayer = city[0].owner;
	brbRiotCitySize = city[0].population;
	brbRiotCityLoc = city[0].location;
	player[0] = g.player;
	
	if(PlayerCityCount(0) > 0) {
		brbCityIdx = GetNearestCity(brbRiotCityLoc, 0);
		if(GetCityByIndex(0, brbCityIdx, brbCity)) {
			if(brbRiotCitySize > 5) {
				brbEmigChance = Random(100);
				if(brbEmigChance < 25) {
					brbMaxEmig = brbRiotCitySize / 4;
					brbEmigNum = Random(brbMaxEmig);
					if(brbEmigNum > 0) {
						for(brbRemPops = 1; brbRemPops == brbEmigNum; brbRemPops = brbRemPops + 1) {
							Event:KillPop(brbRiotCity);
							// if(IsHumanPlayer(player[3])) {
	
								// our outlawed former citizens tell the people in the woods
								// about the cruelity and corruptness of our government:
	
								BRB_HateLevel[brbRiotPlayer] = BRB_HateLevel[brbRiotPlayer] + 1;
							// }
						}
						AddPops(brbCity, brbEmigNum);
						if(IsHumanPlayer(brbRiotPlayer)) {
							city[3] = brbCity;
							Message(player[0], 'PopJoinedBarbs');
						}
					}
				}
			}
		}
	}
	return CONTINUE;
}

messagebox 'PopJoinedBarbs' {
	Text(ID_POP_JOINED_BARBS);
	Eyepoint(city[0].location);
	Show();
}

///////////////////////////////////
// Barb frenzy tactics (frenzy1)
///////////////////////////////////

// good old frenzy script without diplomatic precautions for good old barbs ...

////////////////////////////////////////////////
// Frenzy AI Mod version 1.04
// Code by: Blueorange 1/18/2001
// Additional optimization and mofification by
// Wouter Snijders (aka Locutus)
// adapted for MoT-Mod barbs by RZ
////////////////////////////////////////////////

// globals declared in MoT_s_main.slc

void_f SetupBarbFrenzy() {
	int_t brbCountB;

	BRB_ATTACK_SIZE = 5;
	BRB_SECOND_ARMY_COEF = 2;
	BRB_HATE1_COEF = 5;
	BRB_HATE2_COEF = 45;
	BRB_HATE3_COEF = 75;
	BRB_HATE4_COEF = 100;
	BRB_FRENZY = 0;

	for(brbCountB = 1; brbCountB < g.max_players; brbCountB = brbCountB + 1) {
		BRB_HateLevel[brbCountB] = 0;
	}
	BRB_INIT = 0;
}

// This section sets BRB_ATTACK_SIZE and BRB_HATE_LEVEL[] according to our social/political development

HandleEvent(GrantAdvance) 'BRB_Grant_Advance' post {
	int_t brbAdvPlayer;
	int_t brbAdvance;

	brbAdvPlayer = player[0].owner;
	brbAdvance = value[0].value;

	// the choice of advances leading to +/- barb hate may be reconsidered,
	// anyway it is not only a question of 'political' accuracy, but also of gameplay

	// if(IsHumanPlayer(brbAdvPlayer)) {
		if(brbAdvance == AdvanceDB(ADVANCE_SLAVE_LABOR)
		|| brbAdvance == AdvanceDB(ADVANCE_ARISTOCRACY)
		|| brbAdvance == AdvanceDB(ADVANCE_CITIZENSHIP)
		|| brbAdvance == AdvanceDB(ADVANCE_NATIONALISM)
		|| brbAdvance == AdvanceDB(ADVANCE_THEOLOGY)
		|| brbAdvance == AdvanceDB(ADVANCE_CONSCRIPTION)
		|| brbAdvance == AdvanceDB(ADVANCE_ECONOMICS)
		|| brbAdvance == AdvanceDB(ADVANCE_GLOBAL_ECONOMICS)
		|| brbAdvance == AdvanceDB(ADVANCE_MASS_MEDIA)
		|| brbAdvance == AdvanceDB(ADVANCE_NUCLEAR_POWER)) {
			BRB_HateLevel[brbAdvPlayer] = BRB_HateLevel[brbAdvPlayer] + 10;
		}
		if(brbAdvance == AdvanceDB(ADVANCE_PHILOSOPHY)
		|| brbAdvance == AdvanceDB(ADVANCE_CLASSICAL_EDUCATION)
		|| brbAdvance == AdvanceDB(ADVANCE_HUMAN_RIGHTS)
		|| brbAdvance == AdvanceDB(ADVANCE_AGE_OF_REASON)
		|| brbAdvance == AdvanceDB(ADVANCE_PUBLIC_EDUCATION)
		|| brbAdvance == AdvanceDB(ADVANCE_PSYCHOLOGY)
		|| brbAdvance == AdvanceDB(ADVANCE_CONSERVATION)
		|| brbAdvance == AdvanceDB(ADVANCE_AI_SURVEILLANCE)) {
			BRB_HateLevel[brbAdvPlayer] = BRB_HateLevel[brbAdvPlayer] - 10;
		}
	// }
}

HandleEvent(EnterAge) 'BRB_New_Age' post {
	int_t brbAgePlayer;
	city_t brbTmpCity;

	brbAgePlayer = player[0].owner;
	
	// if(IsHumanPlayer(brbAgePlayer)) {
		if(BRB_ATTACK_SIZE < 12) {
			BRB_ATTACK_SIZE = BRB_ATTACK_SIZE + 1;
		}
		BRB_HateLevel[brbAgePlayer] = BRB_HateLevel[brbAgePlayer] + 20;
	// }
}

// This section handles BRB_HATELEVEL[] changes according to our prosecution efforts

HandleEvent(CaptureCity) 'BRB_hate_level_city_capture' pre {
	int_t brbTmpInvader;
	city_t brbTmpCity;
	int_t brbTmpCityOwner;

	brbTmpCity = city[0];
	brbTmpCityOwner = city[0].owner;
	brbTmpInvader = player[0].owner;

	if(brbTmpCityOwner == 0) {
		// if(IsHumanPlayer(brbTmpInvader)) {
			BRB_HateLevel[brbTmpInvader] = BRB_HateLevel[brbTmpInvader] + 5;
		// }
	}
	return CONTINUE;
}

HandleEvent(NukeCity) 'BRB_hate_level_city_nuke' pre {
	city_t brbTmpCity;
	int_t brbTmpCityOwner;
	int_t brbNukePlayer;

	brbTmpCity = city[0];
	brbTmpCityOwner = city[0].owner;
	brbNukePlayer = player[0].owner;

	if(brbTmpCityOwner == 0) {
		// if(IsHumanPlayer(brbNukePlayer)) {
			BRB_HateLevel[brbNukePlayer] = BRB_HateLevel[brbNukePlayer] + 20;
		// }
	}
	return CONTINUE;
}

HandleEvent(Battle) 'BRB_hate_level_battle' pre {
	unit_t brbTmpUnit;
	int_t brbTmpUnitOwner;
	location_t brbTmpLoc;
	int_t brbTmpInvader;

	brbTmpLoc = location[0];
	brbTmpInvader = army[0].owner;

	if(GetUnitsAtLocation(brbTmpLoc) > 0 && BRB_INIT == 1) {
		if(GetUnitFromCell(brbTmpLoc, 0, brbTmpUnit)) {
			brbTmpUnitOwner = brbTmpUnit.owner;
			// if(brbTmpUnitOwner == 0 && IsHumanPlayer(brbTmpInvader)) {
			if(brbTmpUnitOwner == 0) {
				BRB_HateLevel[brbTmpInvader] = BRB_HateLevel[brbTmpInvader] + 5;
			}
		}
	}
	return CONTINUE;
}

// this handles the brbResulting tactical stage of old barbs

HandleEvent(BeginTurn) 'BRB_FRENZY_level' pre {
	if(BRB_FRENZY != 4 && BRB_INIT == 1) {
		if(BRB_HateLevel[player[0].owner] >= BRB_HATE4_COEF) {
			BRB_FRENZY = 4;
		}
		elseif(BRB_HateLevel[player[0].owner] >= BRB_HATE3_COEF) {
			BRB_FRENZY = 3;
		}
		elseif(BRB_HateLevel[player[0].owner] >= BRB_HATE2_COEF) {
			BRB_FRENZY = 2;
		}
		elseif(BRB_HateLevel[player[0].owner] >= BRB_HATE1_COEF) {
			BRB_FRENZY = 1;
		}		
	}
	return CONTINUE;
}

// This section operates the "Huge Attack-Human Armies Algorithms" ... H.A.H.A.A.

// The barbs will have one stack of army, BRB_FirstArmy, dedicated to destroying the closest
// human-held city. Any unit that fortifies itself outside the city, is considered idle.
// The first biggest idle stack greater than BRB_ATTACK_SIZE will have the honor as the BRB_FirstArmy.
// If the barbs have BRB_SECOND_ARMY_COEF as many units at the human player, they will form 
// BRB_SecondArmy from any stacks available.	
// The barbs will also mark their hate level toward the human player. Hate level can increase or
// decrease according to player/ai actions.  Likewise, BRB_FRENZY state can change as the brbResult of 
// the hate level.
//
// BRB_FRENZY STATE 0:			Barbs use only normal AI.
// BRB_FRENZY STATE 1 (minimal):	Barbs use BRB_FirstArmy and BRB_SecondArmy only to attack player.  
//					(Hate ranges 5 - 45 to initiate)
// BRB_FRENZY STATE 2 (nominal):	Barbs use any stack that is BRB_ATTACK_SIZE or greater to attack. 
//					(Hate ranges 46 - 75 to initiate)
//					(must have more units than human player)
// BRB_FRENZY STATE 3 (maximal):	Barbs use any stack that is BRB_ATTACK_SIZE/3 or greater to attack. 
//					(Hate ranges 76 - 100)
//					(must have at least half as many units as human player)
// BRB_FRENZY STATE 4 (suicidal):	Barbs use any stack that is greater than 2 to attack! 
//					(Hate ranges 100+)
//					(must have at least 1/NumOfPlayers as many units as human player)

HandleEvent(EndTurn) 'BRB_set_AttackTarget' pre {
	int_t brbCountA;
	location_t brbTmpLoc;
	city_t brbTmpCity;
	int_t brbTmpDistance;
	int_t brbMinDistance;

	// if(IsHumanPlayer(player[0]) && BRB_FRENZY > 0 && BRB_INIT == 1) {
	if(BRB_FRENZY > 0 && BRB_INIT == 1) {
		BRB_HumanNumber = player[0].owner;
		brbMinDistance = 10000;
		if(PlayerCityCount(BRB_HumanNumber) > 0) {
			if(ArmyIsValid(BRB_FirstArmy)) {				
				for(brbCountA = 0; brbCountA < PlayerCityCount(BRB_HumanNumber); brbCountA = brbCountA + 1) {
					if(GetCityByIndex(BRB_HumanNumber, brbCountA, brbTmpCity)) {
						brbTmpDistance = Distance(brbTmpCity.location, BRB_FirstArmy.location);
						if(brbTmpDistance < brbMinDistance && !IsUnderseaCity(brbTmpCity)) {
							if(GetContinent(brbTmpCity.location) == GetContinent(BRB_FirstArmy.location)) {
								GetRandomNeighbor(brbTmpCity.location, brbTmpLoc);
								BRB_AttackTarget = brbTmpLoc;
								brbMinDistance = brbTmpDistance;
							}
						}
					}
				}
			}
			else {
				if(GetCityByIndex(BRB_HumanNumber, 0, brbTmpCity)) {
					GetRandomNeighbor(brbTmpCity.location, brbTmpLoc);
					BRB_AttackTarget = brbTmpLoc;
				}
			}				
		}
	}
	return CONTINUE;
}

HandleEvent(BeginTurnArmy) 'BRB_forced_move_armies' pre {
	army_t brbTmpArmy;
	int_t brbResult;
	int_t brbTmpOwner;
	location_t brbTargetLoc;

	brbTmpArmy = army[0];
	brbTmpOwner = brbTmpArmy.owner;

	if(brbTmpOwner == 0 && BRB_INIT == 1 && BRB_FRENZY > 0) {
		if(brbTmpArmy == BRB_FirstArmy)	{
			brbResult = AttackEvaluateLocation(brbTmpArmy.location);
			if(brbResult == 10) {
				MoveArmyToTarget(brbTmpArmy, BRB_AttackTarget);
			}
			else {
				if(GetNeighbor(brbTmpArmy.location, brbResult, brbTargetLoc)) {
					AttackLocation(brbTmpArmy, brbResult, brbTargetLoc);
				}
			}		
		}
		if(brbTmpArmy == BRB_SecondArmy) {
			brbResult = AttackEvaluateLocation(brbTmpArmy.location);
			if(brbResult == 10) {
				MoveArmyToTarget(brbTmpArmy, BRB_AttackTarget);
			}
			else {
				if(GetNeighbor(brbTmpArmy.location, brbResult, brbTargetLoc)) {
					AttackLocation(brbTmpArmy, brbResult, brbTargetLoc);
				}
			}		
		}
	}
	return CONTINUE;
}

HandleEvent(EntrenchOrder) 'BRB_EntrenchUnits' pre {
	int_t brbResult;
	army_t brbTmpArmy;								
	city_t brbTmpCity;								
	int_t brbTmpOwner;
	int_t brbDoFrenzyMoves;

	if(BRB_FRENZY > 0 && ArmyIsValid(army[0]) && BRB_INIT == 1) {
		brbDoFrenzyMoves = 0;
		brbTmpArmy = army[0];
		brbTmpOwner = army[0].owner;
		if(brbTmpOwner == 0) {
			if(!GetCityByLocation(brbTmpArmy.location, brbTmpCity)) {
				if(brbTmpArmy.size >= BRB_ATTACK_SIZE) {
					if(ArmyIsValid(BRB_FirstArmy)) {
						if(brbTmpArmy.size > BRB_FirstArmy.size) {
							BRB_FirstArmy = army[0];
						}
					}
					else {
						BRB_FirstArmy = army[0];				
					}
				}
			}
			elseif(brbTmpArmy.size >= BRB_ATTACK_SIZE && MilitaryRank(brbTmpArmy.owner) < MilitaryRank(BRB_HumanNumber) * BRB_SECOND_ARMY_COEF) {
				if (ArmyIsValid(BRB_FirstArmy)) {
					if(brbTmpArmy != BRB_FirstArmy) {
						if(!ArmyIsValid(BRB_SecondArmy)) {
							BRB_SecondArmy = brbTmpArmy;
						}
					}
				}
			}
			if(brbTmpArmy.size >= BRB_ATTACK_SIZE) {
				if(BRB_FRENZY == 1) {
					brbDoFrenzyMoves = 1;
				}
				elseif(BRB_FRENZY == 2 && MilitaryRank(brbTmpArmy.owner) < MilitaryRank(BRB_HumanNumber)) {
					brbDoFrenzyMoves = 1;
				}
			}
			elseif(brbTmpArmy.size >= BRB_ATTACK_SIZE/3 && BRB_FRENZY == 3 && MilitaryRank(brbTmpArmy.owner) < MilitaryRank(BRB_HumanNumber)*2) {
				brbDoFrenzyMoves = 1;
			}
			elseif(brbTmpArmy.size >= 2 && BRB_FRENZY == 4 && MilitaryRank(brbTmpArmy.owner) < MilitaryRank(BRB_HumanNumber)*3) {
				brbDoFrenzyMoves = 1;
			}
			if(brbDoFrenzyMoves == 1) {
				MoveArmyToTarget(brbTmpArmy, BRB_AttackTarget);
				return STOP;
			}
		}
	}
	return CONTINUE;
}