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.

1The Script1

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