include "TriggerLibs/NativeLib"
include "TriggerLibs/HeroesLib_h"
include "TriggerLibs/GameLib_h"
include "TriggerLibs/MapMechanicsLib_h"
include "TriggerLibs/UILib_h"
include "TriggerLibs/SoundLib_h"
include "TriggerLibs/SupportLib_h"

include "TriggerLibs/AILib_h"

//--------------------------------------------------------------------------------------------------
// Library: AI
//--------------------------------------------------------------------------------------------------
// External Library Initialization
void libAIAI_InitLibraries () {
    libNtve_InitVariables();
    libCore_InitVariables();
    libGame_InitVariables();
    libMapM_InitVariables();
    libUIUI_InitVariables();
    libSond_InitVariables();
    libSprt_InitVariables();
}

// Variable Initialization
bool libAIAI_InitVariables_completed = false;

void libAIAI_InitVariables () {
    int init_i;
    int init_i1;

    if (libAIAI_InitVariables_completed) {
        return;
    }

    libAIAI_InitVariables_completed = true;

    libAIAI_gv_aIMinionRangedMinionWeaponRange = StringToFixed(CatalogFieldValueGet(c_gameCatalogWeapon, "RangedMinion", "Range", c_playerAny));
    libAIAI_gv_aIMinionAttackHeroDistance = (libAIAI_gv_aIMinionRangedMinionWeaponRange + 0.5);
    libAIAI_gv_aIMinionHeroOutOfRangeDistance = (libAIAI_gv_aIMinionRangedMinionWeaponRange + 2.5);
    libAIAI_gv_aIMinionEnemyMinionAttackRange = (StringToFixed(CatalogFieldValueGet(c_gameCatalogWeapon, "RangedMinion", "Range", c_playerAny)) + 1.0);
    libAIAI_gv_aIMinionOgreKingHeroOutOfRangeDistance = (libAIAI_gv_aIMinionOgreKingHeroAggroRange + 2.0);
    libAIAI_gv_aITowerRange = (StringToFixed(CatalogFieldValueGet(c_gameCatalogWeapon, "KingsCore", "Range", 0)) - 0.25);
    libAIAI_gv_uF_MinionAI_AnyEnemyMinions = UnitFilter((1 << c_targetFilterBiological) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterSummoned - 32)));
    libAIAI_gv_uF_MinionAI_GetNearestEnemyStructure = UnitFilter((1 << c_targetFilterStructure) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterBiological) | (1 << c_targetFilterPsionic) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterCloaked) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterSummoned - 32)));
    libAIAI_gv_uF_MinionAI_GetNearestEnemyHero = UnitFilter((1 << c_targetFilterHeroic) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterBiological) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)));
    libAIAI_gv_uF_MinionAI_HeroInWayOfStandard = UnitFilter((1 << c_targetFilterHeroic) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterBiological) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)));
    libAIAI_gv_uF_MinionAI_DetermineOgreKingLogic = UnitFilter((1 << c_targetFilterStructure) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterBiological) | (1 << c_targetFilterPsionic) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterSummoned - 32)));
    libAIAI_gv_uF_TowerAI_Scan_Group = UnitFilter((1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterMechanical) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)));
    libAIAI_gv_uF_TowerAI_Required_Summoned = UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0);
    libAIAI_gv_uF_TowerAI_Required_Heroic = UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0);
    libAIAI_gv_uF_TowerAI_Required_Biological = UnitFilter((1 << c_targetFilterBiological), 0, 0, 0);
    libAIAI_gv_uF_TowerAI_Required_Invulnerable = UnitFilter(0, (1 << (c_targetFilterInvulnerable - 32)), 0, 0);
    libAIAI_gv_uF_TowerAI_Required_Stasis = UnitFilter((1 << c_targetFilterStasis), 0, 0, 0);
    for (init_i = 0; init_i <= libAIAI_gv_defenderAIMaxNumberOfDefenderAI; init_i += 1) {
        libAIAI_gv_defenderAI[init_i].lv_defendersGroup = UnitGroupEmpty();
        libAIAI_gv_defenderAI[init_i].lv_validTargets = UnitGroupEmpty();
    }
    libAIAI_gv_defenderAILastCreatedDefenderAIIndex = "DefenderAILastCreatedDefenderAI";
    for (init_i = 0; init_i <= libMapM_gv_jungleMaxCamps; init_i += 1) {
        libAIAI_gv_heroAIOrderMercCampList[init_i] = -1;
    }
    for (init_i = 0; init_i <= libMapM_gv_jungleMaxCamps; init_i += 1) {
        libAIAI_gv_heroAIChaosMercCampList[init_i] = -1;
    }
    for (init_i = 0; init_i <= libMapM_gv_jungleMaxCamps; init_i += 1) {
        libAIAI_gv_heroAIMiddleMercCampList[init_i] = -1;
    }
    libAIAI_gv_heroAITreasureChests = UnitGroupEmpty();
    libAIAI_gv_heroAIDragonShireObelisks = UnitGroupEmpty();
    libAIAI_gv_heroAIUnderworldStatus.lv_entrances = UnitGroupEmpty();
    libAIAI_gv_heroAIUnderworldStatus.lv_exits = UnitGroupEmpty();
    for (init_i = 0; init_i <= libCore_gv_talents_MaxTalentEntryCount_C; init_i += 1) {
        libAIAI_gv_heroAIItemData[init_i].lv_item = "";
    }
    for (init_i = 0; init_i <= 2; init_i += 1) {
        for (init_i1 = 0; init_i1 <= libGame_gv_laneMaxCount; init_i1 += 1) {
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_allyHeroes = PlayerGroupEmpty();
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_contentionPointLanePosition = 1.0;
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_frontTowerPosition = 1.0;
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_frontMinionPosition = 1.0;
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_frontHumanAllyPosition = 1.0;
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_coreDefensePosition = 1.0;
            libAIAI_gv_heroAITeamData[init_i].lv_laneData[init_i1].lv_lastTimeHumanAllyEnteredLane = -1.0;
        }
        for (init_i1 = 0; init_i1 <= libCore_gv_bALMaxPlayers; init_i1 += 1) {
            libAIAI_gv_heroAITeamData[init_i].lv_heroTrackingData[init_i1].lv_lastSeenTime = -100.0;
            libAIAI_gv_heroAITeamData[init_i].lv_heroTrackingData[init_i1].lv_lastSeenLocation = Point(0.0, 0.0);
        }
        libAIAI_gv_heroAITeamData[init_i].lv_weakestLane = 1;
    }
    for (init_i = 0; init_i <= 2; init_i += 1) {
        libAIAI_gv_heroAITeamPlayerData[init_i].lv_players = PlayerGroupEmpty();
        libAIAI_gv_heroAITeamPlayerData[init_i].lv_humanPlayers = PlayerGroupEmpty();
        libAIAI_gv_heroAITeamPlayerData[init_i].lv_aIPlayers = PlayerGroupEmpty();
    }
    for (init_i = 0; init_i <= 10; init_i += 1) {
        libAIAI_gv_aIHeroes[init_i].lv_enemies = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_enemyHeroes = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_enemyMinionsSummons = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_enemyTowers = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_allies = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_allyHeroes = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_allyMinionsSummons = UnitGroupEmpty();
        libAIAI_gv_aIHeroes[init_i].lv_allyTowers = UnitGroupEmpty();
    }
}

// Presets
string libAIAI_ge_HeroAIDifficulty_Ident (int lp_val) {
         if (lp_val == 0) { return "Null"; }
    else if (lp_val == 1) { return "HeroAITutorial1Enemy"; }
    else if (lp_val == 2) { return "HeroAITutorial1Ally"; }
    else if (lp_val == 3) { return "HeroAITutorial2Enemy"; }
    else if (lp_val == 4) { return "HeroAITutorial2Ally"; }
    else if (lp_val == 5) { return "HeroAITryMeMode"; }
    else if (lp_val == 6) { return "HeroAIVeryEasy"; }
    else if (lp_val == 7) { return "HeroAIVeryEasyWithHumanAlly"; }
    else if (lp_val == 8) { return "HeroAIEasy"; }
    else if (lp_val == 9) { return "HeroAIEasyWithHumanAlly"; }
    else if (lp_val == 10) { return "HeroAIMedium"; }
    else if (lp_val == 11) { return "HeroAIVeryHard"; }
    else if (lp_val == 12) { return "HeroAIElite"; }
    return null;
}

string libAIAI_ge_HeroAIObjective_Ident (int lp_val) {
         if (lp_val == 0) { return "PushLane"; }
    else if (lp_val == 1) { return "WaitInSpawn"; }
    else if (lp_val == 2) { return "CaptureDragon"; }
    else if (lp_val == 3) { return "DefendCore"; }
    else if (lp_val == 4) { return "TakeCamp"; }
    else if (lp_val == 5) { return "CaptureWatchTower"; }
    else if (lp_val == 6) { return "CaptureTearOfElune"; }
    else if (lp_val == 7) { return "CaptureObelisk"; }
    else if (lp_val == 8) { return "TurnInDoubloons"; }
    else if (lp_val == 9) { return "FollowHero"; }
    else if (lp_val == 10) { return "CollectSkulls"; }
    else if (lp_val == 11) { return "AttackTreasureChest"; }
    else if (lp_val == 12) { return "UseAbathurLogic"; }
    return null;
}

string libAIAI_ge_HeroAIPriority_Ident (int lp_val) {
         if (lp_val == 0) { return "GenericUninterruptable"; }
    else if (lp_val == 1) { return "CollectSkullsInUnderworld"; }
    else if (lp_val == 2) { return "WaitInSpawnAnyState"; }
    else if (lp_val == 3) { return "AbathurLogicAnyState"; }
    else if (lp_val == 4) { return "FollowHeroAnyState"; }
    else if (lp_val == 5) { return "PushLaneAttackCore"; }
    else if (lp_val == 6) { return "DefendCoreAnyState"; }
    else if (lp_val == 7) { return "TakeCampTakingCamp"; }
    else if (lp_val == 8) { return "PushLaneDefendingBase"; }
    else if (lp_val == 9) { return "CaptureTearOfEluneHeadingToTribute"; }
    else if (lp_val == 10) { return "TakeCampMoveToCampWithHuman"; }
    else if (lp_val == 11) { return "CollectSkullsHeadingToUnderworld"; }
    else if (lp_val == 12) { return "CaptureDragonMoveToDragon"; }
    else if (lp_val == 13) { return "CaptureObeliskAnyState"; }
    else if (lp_val == 14) { return "PushLanePushWithTeam"; }
    else if (lp_val == 15) { return "PushLaneTeamFightLikely"; }
    else if (lp_val == 16) { return "PushLaneDefendTown"; }
    else if (lp_val == 17) { return "PushLaneAttackTown"; }
    else if (lp_val == 18) { return "PushLaneRavenKingsCurseActive"; }
    else if (lp_val == 19) { return "PushLaneUnderworldBossActive"; }
    else if (lp_val == 20) { return "PushLanePushWithAllyMercs"; }
    else if (lp_val == 21) { return "PushLaneClearEnemyMercs"; }
    else if (lp_val == 22) { return "PushLaneNearActiveObelisk"; }
    else if (lp_val == 23) { return "TurnInDoubloonsHeadingToBeacon"; }
    else if (lp_val == 24) { return "TakeCampMoveToCampOnlyAI"; }
    else if (lp_val == 25) { return "GenericPreformTeamStrategy"; }
    else if (lp_val == 26) { return "AttackTreasureChestAnyState"; }
    else if (lp_val == 27) { return "PushLaneInMinionBattle"; }
    else if (lp_val == 28) { return "PushLaneChangingLanes"; }
    else if (lp_val == 29) { return "CaptureWatchTowerAnyState"; }
    else if (lp_val == 30) { return "PushLaneNormalLogic"; }
    return null;
}

string libAIAI_ge_HeroAIStates_Ident (int lp_val) {
         if (lp_val == 0) { return "HSUnused"; }
    else if (lp_val == 1) { return "HSDead"; }
    else if (lp_val == 2) { return "HSAfterDeathAttack"; }
    else if (lp_val == 3) { return "HSReturnToSpawn"; }
    else if (lp_val == 4) { return "HSWaitForGameToStart"; }
    else if (lp_val == 5) { return "HSWaitToHeal"; }
    else if (lp_val == 6) { return "HSWaitInSpawn"; }
    else if (lp_val == 7) { return "HSAdvance"; }
    else if (lp_val == 8) { return "HSRetreat"; }
    else if (lp_val == 9) { return "HSAvoidAOE"; }
    else if (lp_val == 10) { return "HSMinionBattleRetreat"; }
    else if (lp_val == 11) { return "HSMinionBattleReposition"; }
    else if (lp_val == 12) { return "HSMinionBattleAttack"; }
    else if (lp_val == 13) { return "HSMinionBattleHarass"; }
    else if (lp_val == 14) { return "HSHarassSiegeEnemy"; }
    else if (lp_val == 15) { return "HSWaitForMinions"; }
    else if (lp_val == 16) { return "HSReturnToLane"; }
    else if (lp_val == 17) { return "HSPickUpHealthGlobeJungle"; }
    else if (lp_val == 18) { return "HSFocusHero"; }
    else if (lp_val == 19) { return "HSFocusCore"; }
    else if (lp_val == 20) { return "HSDefendCoreAttack"; }
    else if (lp_val == 21) { return "HSDefendCoreLeash"; }
    else if (lp_val == 22) { return "HSVehicleReturnToLane"; }
    else if (lp_val == 23) { return "HSVehicleAdvanceInLane"; }
    else if (lp_val == 24) { return "HSCaptureWatchTower"; }
    else if (lp_val == 25) { return "HSPortHomeLane"; }
    else if (lp_val == 26) { return "HSDrinkMoonwell"; }
    else if (lp_val == 27) { return "HSTearOfEluneMoveToTear"; }
    else if (lp_val == 28) { return "HSTearOfEluneCapture"; }
    else if (lp_val == 29) { return "HSTearOfEluneGuard"; }
    else if (lp_val == 30) { return "HSTearOfEluneDefend"; }
    else if (lp_val == 31) { return "HSPickUpDoubloon"; }
    else if (lp_val == 32) { return "HSTurnInDoubloons"; }
    else if (lp_val == 33) { return "HSTurnInDoubloonsDefend"; }
    else if (lp_val == 34) { return "HSTreasureChestMoveToChest"; }
    else if (lp_val == 35) { return "HSTreasureChestAttackChest"; }
    else if (lp_val == 36) { return "HSTreasureChestDefend"; }
    else if (lp_val == 37) { return "HSMCampInit"; }
    else if (lp_val == 38) { return "HSMoveToCamp"; }
    else if (lp_val == 39) { return "HSWaitAtCamp"; }
    else if (lp_val == 40) { return "HSAttackSoloCamp"; }
    else if (lp_val == 41) { return "HSCaptureCampBeacon"; }
    else if (lp_val == 42) { return "HSDefendCampAttack"; }
    else if (lp_val == 43) { return "HSDefendCampLeash"; }
    else if (lp_val == 44) { return "HSFleeInJungle"; }
    else if (lp_val == 45) { return "HSPortHomeJungle"; }
    else if (lp_val == 46) { return "HSHarassInJungle"; }
    else if (lp_val == 47) { return "HSPaceAround"; }
    else if (lp_val == 48) { return "HSObeliskMoveToObelisk"; }
    else if (lp_val == 49) { return "HSObeliskCapture"; }
    else if (lp_val == 50) { return "HSObeliskDefend"; }
    else if (lp_val == 51) { return "HSDragonMoveToDragon"; }
    else if (lp_val == 52) { return "HSDragonEnter"; }
    else if (lp_val == 53) { return "HSDragonDefend"; }
    else if (lp_val == 54) { return "HSDragonGuard"; }
    else if (lp_val == 55) { return "HSFollowerGuardLeader"; }
    else if (lp_val == 56) { return "HSFollowerGuardLeaderLeash"; }
    else if (lp_val == 57) { return "HSUnderworldEnter"; }
    else if (lp_val == 58) { return "HSUnderworldKillMinions"; }
    else if (lp_val == 59) { return "HSUnderworldFocusHero"; }
    else if (lp_val == 60) { return "HSUnderworldPickupSkull"; }
    else if (lp_val == 61) { return "HSUnderworldMoveToExit"; }
    else if (lp_val == 62) { return "HSUnderworldTeleportHome"; }
    else if (lp_val == 63) { return "HSUnderworldExit"; }
    else if (lp_val == 64) { return "HSAbathurAdvanceInLane"; }
    else if (lp_val == 65) { return "HSAbathurRetreatInLane"; }
    else if (lp_val == 66) { return "HSAbathurHideInTown"; }
    else if (lp_val == 67) { return "HSAbathurChangeLanes"; }
    return null;
}

// Functions
int libAIAI_gf_MinionAINewMinionIndex () {
    int autoA2EF3213_ae;
    int autoA2EF3213_ai;

    // Variable Declarations
    int lv_minionIndex;

    // Variable Initialization

    // Implementation
    autoA2EF3213_ae = libAIAI_gv_minionAIMaxActiveMinions;
    autoA2EF3213_ai = 1;
    lv_minionIndex = 1;
    for ( ; ( (autoA2EF3213_ai >= 0 && lv_minionIndex <= autoA2EF3213_ae) || (autoA2EF3213_ai <= 0 && lv_minionIndex >= autoA2EF3213_ae) ) ; lv_minionIndex += autoA2EF3213_ai ) {
        if ((libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_isAlive == false)) {
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_isAlive = true;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state = 0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_aggressiveLeashing = false;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_nextWaypoint = 0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_unitPosition = null;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_targetUnit = null;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_forceStateTransition = false;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_battleStandardDistancePercentage = 0.0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_battleStandardPoint = null;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_battleStandardLastUpdate = 0.0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_ownerPlayer = 0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_teamToAttack = 0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_lane = 0;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit = null;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnitType = null;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_useSpecialOgreKingLogic = false;
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_onlyAttackStructures = false;
            libAIAI_gv_minionAIActiveMinionsUpperBound = MaxI(lv_minionIndex, libAIAI_gv_minionAIActiveMinionsUpperBound);
            return lv_minionIndex;
        }
        else {
        }
    }
    return (libAIAI_gv_minionAIMaxActiveMinions + 1);
}

point libAIAI_gf_MinionAIGetNextWaypointForMinion (int lp_minionIndex) {
    // Implementation
    return libGame_gv_laneData[libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane].lv_waypoints[libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint];
}

point libAIAI_gf_MinionAIGetPreviousWaypointForMinion (int lp_minionIndex) {
    // Variable Declarations
    int lv_lane;

    // Variable Initialization

    // Implementation
    lv_lane = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane;
    if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_teamToAttack == libGame_gv_teamChaosIndex_C)) {
        return libGame_gv_laneData[lv_lane].lv_waypoints[(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint - 1)];
    }
    else {
        return libGame_gv_laneData[lv_lane].lv_waypoints[(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint + 1)];
    }
}

bool libAIAI_gf_MinionAIAnyEnemyMinionsInRangeOfMinion (int lp_minionIndex, fixed lp_range) {
    unitgroup autoE8C402AE_g;
    int autoE8C402AE_u;
    unitgroup auto78F7A09B_g;
    int auto78F7A09B_u;

    // Variable Declarations
    int lv_position;
    unitgroup lv_enemyMinions;
    unit lv_enemyMinion;
    fixed lv_lanePosition;
    int lv_laneIndex;

    // Variable Initialization
    lv_enemyMinions = UnitGroupEmpty();

    // Implementation
    lv_enemyMinions = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition, lp_range, libAIAI_gv_uF_MinionAI_AnyEnemyMinions, 1);
    lv_laneIndex = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane;
    if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_teamToAttack == libGame_gv_teamChaosIndex_C)) {
        auto78F7A09B_g = lv_enemyMinions;
        auto78F7A09B_u = 1;
        for ( ; auto78F7A09B_u <= UnitGroupCount(auto78F7A09B_g, c_unitCountAll) ; auto78F7A09B_u += BoolToInt(lv_enemyMinion == UnitGroupUnit(auto78F7A09B_g, auto78F7A09B_u)) ) {
            lv_enemyMinion = UnitGroupUnit(auto78F7A09B_g, auto78F7A09B_u);
            if ((libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, UnitGetPosition(lv_enemyMinion)) < libAIAI_gv_minionAILaneInfo[lv_laneIndex].lv_frontChaosGateLanePosition)) {
                return true;
            }
            else {
            }
        }
    }
    else {
        autoE8C402AE_g = lv_enemyMinions;
        autoE8C402AE_u = 1;
        for ( ; autoE8C402AE_u <= UnitGroupCount(autoE8C402AE_g, c_unitCountAll) ; autoE8C402AE_u += BoolToInt(lv_enemyMinion == UnitGroupUnit(autoE8C402AE_g, autoE8C402AE_u)) ) {
            lv_enemyMinion = UnitGroupUnit(autoE8C402AE_g, autoE8C402AE_u);
            if ((libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, UnitGetPosition(lv_enemyMinion)) > libAIAI_gv_minionAILaneInfo[lv_laneIndex].lv_frontOrderGameLanePosition)) {
                return true;
            }
            else {
            }
        }
    }
    return false;
}

bool libAIAI_gf_MinionAIIsValidTarget (int lp_minionIndex, unit lp_targetUnit) {
    // Variable Declarations
    order lv_order;

    // Variable Initialization

    // Implementation
    lv_order = OrderTargetingUnit(AbilityCommand("AttackAlly", 0), lp_targetUnit);
    if ((UnitOrderIsValid(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, lv_order) == true)) {
        return true;
    }
    else {
        return false;
    }
}

unit libAIAI_gf_MinionAIGetNearestEnemyStructureInRangeOfMinion (int lp_minionIndex, fixed lp_range) {
    unitgroup auto8B70D728_g;
    int auto8B70D728_u;

    // Variable Declarations
    point lv_minionPosition;
    unit lv_u;
    unitgroup lv_scanGroup;
    int lv_townIndex;

    // Variable Initialization
    lv_scanGroup = UnitGroupEmpty();

    // Implementation
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    lv_scanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, lp_range, libAIAI_gv_uF_MinionAI_GetNearestEnemyStructure, 0);
    auto8B70D728_g = lv_scanGroup;
    auto8B70D728_u = 1;
    for ( ; auto8B70D728_u <= UnitGroupCount(auto8B70D728_g, c_unitCountAll) ; auto8B70D728_u += BoolToInt(lv_u == UnitGroupUnit(auto8B70D728_g, auto8B70D728_u)) ) {
        lv_u = UnitGroupUnit(auto8B70D728_g, auto8B70D728_u);
        lv_townIndex = libGame_gf_TownGetTownForUnit(lv_u);
        if (((libAIAI_gf_MinionAIIsValidTarget(lp_minionIndex, lv_u) == false) || ((lv_townIndex > 0) && (libGame_gv_townTownData[lv_townIndex].lv_lane != libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane)))) {
            UnitGroupRemove(lv_scanGroup, lv_u);
        }
        else {
        }
    }
    return UnitGroupClosestToPoint(lv_scanGroup, lv_minionPosition);
}

unit libAIAI_gf_MinionAIGetNearestEnemyHeroInRangeOfMinion (int lp_minionIndex, fixed lp_range) {
    unitgroup autoD6362878_g;
    int autoD6362878_u;

    // Variable Declarations
    point lv_minionPosition;
    unit lv_u;
    unitgroup lv_scanGroup;

    // Variable Initialization
    lv_scanGroup = UnitGroupEmpty();

    // Implementation
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    lv_scanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, lp_range, libAIAI_gv_uF_MinionAI_GetNearestEnemyHero, 0);
    autoD6362878_g = lv_scanGroup;
    autoD6362878_u = 1;
    for ( ; autoD6362878_u <= UnitGroupCount(autoD6362878_g, c_unitCountAll) ; autoD6362878_u += BoolToInt(lv_u == UnitGroupUnit(autoD6362878_g, autoD6362878_u)) ) {
        lv_u = UnitGroupUnit(autoD6362878_g, autoD6362878_u);
        if ((libAIAI_gf_MinionAIIsValidTarget(lp_minionIndex, lv_u) == false)) {
            UnitGroupRemove(lv_scanGroup, lv_u);
        }
        else {
        }
    }
    return UnitGroupClosestToPoint(lv_scanGroup, lv_minionPosition);
}

unit libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion (int lp_minionIndex, int lp_townStructureType, unitgroup lp_scanGroup) {
    unitgroup auto2AD423A1_g;
    int auto2AD423A1_u;

    // Variable Declarations
    unit lv_u;
    unitgroup lv_finalScanGroup;

    // Variable Initialization
    lv_finalScanGroup = UnitGroupEmpty();

    // Implementation
    auto2AD423A1_g = lp_scanGroup;
    auto2AD423A1_u = 1;
    for ( ; auto2AD423A1_u <= UnitGroupCount(auto2AD423A1_g, c_unitCountAll) ; auto2AD423A1_u += BoolToInt(lv_u == UnitGroupUnit(auto2AD423A1_g, auto2AD423A1_u)) ) {
        lv_u = UnitGroupUnit(auto2AD423A1_g, auto2AD423A1_u);
        if ((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_u)) == lp_townStructureType)) {
            UnitGroupAdd(lv_finalScanGroup, lv_u);
        }
        else {
        }
    }
    return UnitGroupClosestToPoint(lv_finalScanGroup, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition);
}

unit libAIAI_gf_MinionAIGetNearestEnemyHeroInTheWayOfBattleStandard (int lp_minionIndex, point lp_battleStandardPoint, fixed lp_range) {
    unitgroup auto9CBCCB53_g;
    int auto9CBCCB53_u;

    // Variable Declarations
    unit lv_u;
    point lv_minionPosition;
    fixed lv_distanceFromWaveToBattleStandard;
    unitgroup lv_scanGroup;

    // Variable Initialization
    lv_scanGroup = UnitGroupEmpty();

    // Implementation
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    lv_distanceFromWaveToBattleStandard = DistanceBetweenPoints(lv_minionPosition, lp_battleStandardPoint);
    lv_scanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, lp_range, libAIAI_gv_uF_MinionAI_HeroInWayOfStandard, 0);
    auto9CBCCB53_g = lv_scanGroup;
    auto9CBCCB53_u = 1;
    for ( ; auto9CBCCB53_u <= UnitGroupCount(auto9CBCCB53_g, c_unitCountAll) ; auto9CBCCB53_u += BoolToInt(lv_u == UnitGroupUnit(auto9CBCCB53_g, auto9CBCCB53_u)) ) {
        lv_u = UnitGroupUnit(auto9CBCCB53_g, auto9CBCCB53_u);
        if ((DistanceBetweenPoints(UnitGetPosition(lv_u), lp_battleStandardPoint) > lv_distanceFromWaveToBattleStandard)) {
            UnitGroupRemove(lv_scanGroup, lv_u);
        }
        else {
        }
    }
    return UnitGroupClosestToPoint(lv_scanGroup, lv_minionPosition);
}

int libAIAI_gf_MinionAIDetermineState (int lp_minionIndex, int lp_oldState) {
    int auto11561EA4_val;

    // Variable Declarations
    fixed lv_distanceToBattleStandard;
    unit lv_heroToFollow;
    int lv_attackState;

    // Variable Initialization

    // Implementation
    auto11561EA4_val = lp_oldState;
    if (auto11561EA4_val == 0) {
        lv_attackState = libAIAI_gf_MinionAIDetermineAttackStateAndTarget(lp_minionIndex);
        return lv_attackState;
    }
    else if (auto11561EA4_val == 1) {
        lv_attackState = libAIAI_gf_MinionAIDetermineAttackStateAndTarget(lp_minionIndex);
        return lv_attackState;
    }
    else if (auto11561EA4_val == 2) {
        lv_attackState = libAIAI_gf_MinionAIDetermineAttackStateAndTarget(lp_minionIndex);
        return lv_attackState;
    }
    else if (auto11561EA4_val == 3) {
        lv_attackState = libAIAI_gf_MinionAIDetermineAttackStateAndTarget(lp_minionIndex);
        return lv_attackState;
    }
    else if (auto11561EA4_val == 4) {
        libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lp_minionIndex);
        lv_distanceToBattleStandard = DistanceBetweenPoints(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint);
        if ((lv_distanceToBattleStandard <= libAIAI_gv_aIMinionBattleStandardAdvanceDistance)) {
            return 0;
        }
        else {
        }
    }
    else if (auto11561EA4_val == 5) {
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)) == true)) {
            return 0;
        }
        else {
        }
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), UnitGetPosition(libAIAI_gf_MinionAIGetHeroToFollow(lp_minionIndex))) == false)) {
            return 6;
        }
        else {
        }
    }
    else if (auto11561EA4_val == 6) {
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)) == true)) {
            return 0;
        }
        else {
        }
        lv_heroToFollow = libAIAI_gf_MinionAIGetHeroToFollow(lp_minionIndex);
        if ((UnitIsValid(lv_heroToFollow) == true) && (PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), UnitGetPosition(lv_heroToFollow)) == true)) {
            return 5;
        }
        else {
        }
    }
    else {
    }
    return lp_oldState;
}

int libAIAI_gf_MinionAIDetermineAttackStateAndTarget (int lp_minionIndex) {
    // Variable Declarations
    order lv_minionOrder;
    unit lv_currentTarget;

    // Variable Initialization

    // Implementation
    lv_minionOrder = UnitOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, 0);
    if ((lv_minionOrder != null) && ((OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("attack", 0)) || (OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("AttackAlly", 0))) && (OrderGetTargetType(lv_minionOrder) == c_orderTargetUnit)) {
        lv_currentTarget = OrderGetTargetUnit(lv_minionOrder);
    }
    else {
    }
    if ((UnitGetType(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit) == "UnderworldSummonedBoss")) {
        if ((libAIAI_gf_MinionAIShouldAttackStructure(lp_minionIndex, lv_currentTarget) == true)) {
            return 2;
        }
        else {
            return 0;
        }
    }
    else {
        if ((libAIAI_gf_MinionAIShouldAttackMinions(lp_minionIndex, lv_currentTarget) == true)) {
            return 1;
        }
        else {
            if ((libAIAI_gf_MinionAIShouldAttackStructure(lp_minionIndex, lv_currentTarget) == true)) {
                return 2;
            }
            else {
                return libAIAI_gf_MinionAIAttackHeroState(lp_minionIndex, lv_currentTarget);
            }
        }
    }
}

bool libAIAI_gf_MinionAIShouldAttackMinions (int lp_minionIndex, unit lp_currentTarget) {
    // Implementation
    if ((UnitIsValid(lp_currentTarget) == true) && ((UnitTypeTestAttribute(UnitGetType(lp_currentTarget), c_unitAttributeBiological) == true) || (UnitTypeTestAttribute(UnitGetType(lp_currentTarget), c_unitAttributeSummoned) == true))) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_MinionAIAnyEnemyMinionsInRangeOfMinion(lp_minionIndex, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_attackRange) == true)) {
        libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_MinionAIShouldAttackStructure (int lp_minionIndex, unit lp_currentTarget) {
    // Variable Declarations
    unit lv_targetStructure;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(lp_currentTarget) == true) && (UnitFilterMatch(lp_currentTarget, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, libAIAI_gv_uF_MinionAI_GetNearestEnemyStructure) == true)) {
        libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lp_currentTarget;
        return true;
    }
    else {
    }
    lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemyStructureInRangeOfMinion(lp_minionIndex, (libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_attackRange + libAIAI_gv_aIMinionAttackStructureBonusScanRange));
    if ((UnitIsAlive(lv_targetStructure) == true)) {
        libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
        libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
        return true;
    }
    else {
    }
    return false;
}

int libAIAI_gf_MinionAIAttackHeroState (int lp_minionIndex, unit lp_currentTarget) {
    // Variable Declarations
    point lv_minionPosition;
    fixed lv_pathingCostToBattleStandard;
    unit lv_targetHero;

    // Variable Initialization

    // Implementation
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    if ((UnitIsValid(lp_currentTarget) == true) && (UnitFilterMatch(lp_currentTarget, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, libAIAI_gv_uF_MinionAI_GetNearestEnemyHero) == true) && (DistanceBetweenPoints(lv_minionPosition, UnitGetPosition(lp_currentTarget)) < libAIAI_gv_aIMinionHeroOutOfRangeDistance)) {
        lv_targetHero = lp_currentTarget;
    }
    else {
        lv_targetHero = libAIAI_gf_MinionAIGetNearestEnemyHeroInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionAttackHeroDistance);
    }
    if ((UnitIsValid(lv_targetHero) == false)) {
        return 0;
    }
    else {
    }
    if ((UnitFilterMatch(lv_targetHero, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, UnitFilter(0, 0, 0, (1 << (c_targetFilterPassive - 32)))) == false) && (UnitHasBehavior2(lv_targetHero, "Mounted") == false) && (UnitHasBehavior2(lv_targetHero, "MountedCustom") == false) && (UnitHasBehavior2(lv_targetHero, "MountedFlyer") == false)) {
        return 0;
    }
    else {
    }
    libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lp_minionIndex);
    lv_pathingCostToBattleStandard = IntToFixed(PointPathingCost(lv_minionPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint));
    if ((lv_pathingCostToBattleStandard >= libAIAI_gv_aIMaxPathDistance)) {
        lv_pathingCostToBattleStandard = DistanceBetweenPoints(lv_minionPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint);
    }
    else {
    }
    if ((lv_pathingCostToBattleStandard >= libAIAI_gv_aIMinionLeashDistance)) {
        if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_aggressiveLeashing == true)) {
            return 0;
        }
        else {
            return 4;
        }
    }
    else {
    }
    if ((lv_targetHero != lp_currentTarget)) {
        libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
    }
    else {
    }
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetHero;
    return 3;
}

int libAIAI_gf_MinionAIDetermineStateUsingOgreKingLogic (int lp_minionIndex, int lp_oldState) {
    int autoD64613EE_val;

    // Variable Declarations
    point lv_minionPosition;
    unitgroup lv_structureScanGroup;
    unit lv_targetStructure;
    unit lv_targetHero;
    fixed lv_distanceToBattleStandard;
    fixed lv_pathingCostToBattleStandard;
    unit lv_heroToFollow;

    // Variable Initialization
    lv_structureScanGroup = UnitGroupEmpty();

    // Implementation
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    autoD64613EE_val = lp_oldState;
    if (autoD64613EE_val == 0) {
        lv_structureScanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, libAIAI_gv_aIMinionOgreKingStructureAggroRange, libAIAI_gv_uF_MinionAI_DetermineOgreKingLogic, 0);
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 8, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 5, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 3, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 1, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 6, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetHero = libAIAI_gf_MinionAIGetNearestEnemyHeroInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionOgreKingHeroAggroRange);
        if ((UnitIsAlive(lv_targetHero) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetHero;
            return 3;
        }
        else {
        }
        if ((libAIAI_gf_MinionAIAnyEnemyMinionsInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionOgreKingMinionAggroRange) == true)) {
            return 1;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 1) {
        lv_structureScanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, libAIAI_gv_aIMinionOgreKingStructureAggroRange, libAIAI_gv_uF_MinionAI_DetermineOgreKingLogic, 0);
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 8, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 5, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 3, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 1, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 6, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetHero = libAIAI_gf_MinionAIGetNearestEnemyHeroInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionOgreKingHeroAggroRange);
        if ((UnitIsAlive(lv_targetHero) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetHero;
            return 3;
        }
        else {
        }
        if ((libAIAI_gf_MinionAIAnyEnemyMinionsInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionEnemyMinionAttackRange) == false)) {
            return 0;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 2) {
        if (((UnitIsAlive(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit) == false) || (UnitFilterMatch(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, UnitFilter((1 << c_targetFilterStasis), 0, 0, 0)) == true) || (UnitFilterMatch(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, UnitFilter(0, (1 << (c_targetFilterInvulnerable - 32)), 0, 0)) == true))) {
            lv_structureScanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, libAIAI_gv_aIMinionOgreKingStructureAggroRange, libAIAI_gv_uF_MinionAI_DetermineOgreKingLogic, 0);
            lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 8, lv_structureScanGroup);
            if ((UnitIsAlive(lv_targetStructure) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
                return 2;
            }
            else {
            }
            lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 5, lv_structureScanGroup);
            if ((UnitIsAlive(lv_targetStructure) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
                return 2;
            }
            else {
            }
            lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 3, lv_structureScanGroup);
            if ((UnitIsAlive(lv_targetStructure) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
                return 2;
            }
            else {
            }
            lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 1, lv_structureScanGroup);
            if ((UnitIsAlive(lv_targetStructure) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
                return 2;
            }
            else {
            }
            lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 6, lv_structureScanGroup);
            if ((UnitIsAlive(lv_targetStructure) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
                return 2;
            }
            else {
            }
            lv_targetHero = libAIAI_gf_MinionAIGetNearestEnemyHeroInRangeOfMinion(lp_minionIndex, libAIAI_gv_aIMinionOgreKingHeroAggroRange);
            if ((UnitIsAlive(lv_targetHero) == true)) {
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetHero;
                return 3;
            }
            else {
            }
            return 0;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 3) {
        lv_structureScanGroup = UnitGroupSearch(null, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, lv_minionPosition, libAIAI_gv_aIMinionOgreKingStructureAggroRange, libAIAI_gv_uF_MinionAI_DetermineOgreKingLogic, 0);
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 8, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 5, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 3, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 1, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_forceStateTransition = true;
            return 2;
        }
        else {
        }
        lv_targetStructure = libAIAI_gf_MinionAIGetNearestEnemySpecificTownStructureInRangeOfMinion(lp_minionIndex, 6, lv_structureScanGroup);
        if ((UnitIsAlive(lv_targetStructure) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetStructure;
            return 2;
        }
        else {
        }
        if ((UnitIsAlive(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit) == false)) {
            return 4;
        }
        else {
        }
        if ((libNtve_gf_UnitIsVisibleToPlayer(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer) == false)) {
            return 4;
        }
        else {
        }
        if ((UnitFilterMatch(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, UnitFilter(0, 0, (1 << c_targetFilterCloaked) | (1 << c_targetFilterStasis), (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)))) == false)) {
            return 4;
        }
        else {
        }
        if ((UnitFilterMatch(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_ownerPlayer, UnitFilter(0, 0, 0, (1 << (c_targetFilterPassive - 32)))) == false) && (UnitHasBehavior2(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, "Mounted") == false) && (UnitHasBehavior2(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit, "MountedFlyer") == false)) {
            return 4;
        }
        else {
        }
        if ((DistanceBetweenPoints(lv_minionPosition, UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit)) > libAIAI_gv_aIMinionOgreKingHeroOutOfRangeDistance)) {
            return 4;
        }
        else {
        }
        libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lp_minionIndex);
        lv_pathingCostToBattleStandard = IntToFixed(PointPathingCost(lv_minionPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint));
        if ((lv_pathingCostToBattleStandard >= libAIAI_gv_aIMaxPathDistance)) {
            lv_pathingCostToBattleStandard = DistanceBetweenPoints(lv_minionPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint);
        }
        else {
        }
        if ((lv_pathingCostToBattleStandard >= libAIAI_gv_aIMinionOgreKingLeashDistance)) {
            return 4;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 4) {
        libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lp_minionIndex);
        lv_distanceToBattleStandard = DistanceBetweenPoints(lv_minionPosition, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint);
        if ((lv_distanceToBattleStandard <= libAIAI_gv_aIMinionBattleStandardAdvanceDistance)) {
            return 0;
        }
        else {
        }
        lv_targetHero = libAIAI_gf_MinionAIGetNearestEnemyHeroInTheWayOfBattleStandard(lp_minionIndex, libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint, libAIAI_gv_aIMinionOgreKingHeroAggroRange);
        if ((UnitIsAlive(lv_targetHero) == true)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit = lv_targetHero;
            return 3;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 5) {
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)) == true)) {
            return 0;
        }
        else {
        }
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), UnitGetPosition(libAIAI_gf_MinionAIGetHeroToFollow(lp_minionIndex))) == false)) {
            return 6;
        }
        else {
        }
    }
    else if (autoD64613EE_val == 6) {
        if ((PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)) == true)) {
            return 0;
        }
        else {
        }
        lv_heroToFollow = libAIAI_gf_MinionAIGetHeroToFollow(lp_minionIndex);
        if ((UnitIsValid(lv_heroToFollow) == true) && (PointPathingIsConnected(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), UnitGetPosition(lv_heroToFollow)) == true)) {
            return 5;
        }
        else {
        }
    }
    else {
    }
    return lp_oldState;
}

unit libAIAI_gf_MinionAIGetHeroToFollow (int lp_minionIndex) {
    // Variable Declarations
    int lv_owningPlayer;

    // Variable Initialization

    // Implementation
    if ((UnitGetOwner(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit) <= libCore_gv_bALMaxPlayers)) {
        lv_owningPlayer = UnitGetOwner(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit);
        if ((UnitIsValid(libGame_gv_players[lv_owningPlayer].lv_heroUnit) == true)) {
            return libGame_gv_players[lv_owningPlayer].lv_heroUnit;
        }
        else {
        }
    }
    else {
    }
    return null;
}

bool libAIAI_gf_MinionAIAttackingWrongTarget (int lp_minionIndex) {
    // Variable Declarations
    order lv_minionOrder;

    // Variable Initialization

    // Implementation
    if (((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_state == 3) || (libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_state == 2))) {
        lv_minionOrder = UnitOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, 0);
        if ((lv_minionOrder != null) && ((OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("attack", 0)) || (OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("AttackAlly", 0))) && (OrderGetTargetType(lv_minionOrder) == c_orderTargetUnit) && (OrderGetTargetUnit(lv_minionOrder) != libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit)) {
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

void libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion (int lp_minionIndex) {
    // Variable Declarations
    fixed lv_missionTime;
    point lv_previousWaypoint;
    point lv_nextWaypoint;
    fixed lv_distanceBetweenWaypoints;
    point lv_minionPosition;
    fixed lv_angleBetweenPreviousPointandMinionPosition;
    fixed lv_distanceBetweenPreviousPointandMinionPosition;
    fixed lv_battleStandardDistance;
    fixed lv_battleStandardDistancePercentage;
    point lv_battleStandardPoint;

    // Variable Initialization

    // Implementation
    lv_missionTime = GameGetMissionTime();
    if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardLastUpdate >= lv_missionTime)) {
        return ;
    }
    else {
    }
    lv_previousWaypoint = libAIAI_gf_MinionAIGetPreviousWaypointForMinion(lp_minionIndex);
    lv_nextWaypoint = libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex);
    lv_distanceBetweenWaypoints = DistanceBetweenPoints(lv_previousWaypoint, lv_nextWaypoint);
    lv_minionPosition = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_unitPosition;
    if ((lv_distanceBetweenWaypoints == 0.0)) {
        return ;
    }
    else {
    }
    lv_distanceBetweenPreviousPointandMinionPosition = DistanceBetweenPoints(lv_previousWaypoint, lv_minionPosition);
    lv_angleBetweenPreviousPointandMinionPosition = (AngleBetweenPoints(lv_previousWaypoint, lv_minionPosition) - AngleBetweenPoints(lv_previousWaypoint, lv_nextWaypoint));
    lv_battleStandardDistance = (Cos(lv_angleBetweenPreviousPointandMinionPosition) * lv_distanceBetweenPreviousPointandMinionPosition);
    lv_battleStandardDistancePercentage = (lv_battleStandardDistance / lv_distanceBetweenWaypoints);
    lv_battleStandardPoint = libNtve_gf_PointOffsetTowardsPoint(lv_previousWaypoint, (lv_distanceBetweenWaypoints * lv_battleStandardDistancePercentage), lv_nextWaypoint);
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardDistancePercentage = lv_battleStandardDistancePercentage;
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint = lv_battleStandardPoint;
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardLastUpdate = lv_missionTime;
}

void libAIAI_gf_MinionAIAdvanceMinionToNextWaypoint (int lp_minionIndex) {
    // Variable Declarations
    int lv_camp;
    int lv_nextWaypoint;
    int lv_waypointCount;

    // Variable Initialization

    // Implementation
    lv_nextWaypoint = libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint;
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardDistancePercentage = 0.0;
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint = libGame_gv_laneData[libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane].lv_waypoints[lv_nextWaypoint];
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardLastUpdate = GameGetMissionTime();
    lv_waypointCount = libGame_gv_laneData[libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_lane].lv_waypointCount;
    if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_teamToAttack == libGame_gv_teamChaosIndex_C)) {
        if ((lv_nextWaypoint < (lv_waypointCount - 1))) {
            lv_nextWaypoint += 1;
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint = lv_nextWaypoint;
        }
        else {
        }
    }
    else {
        if ((lv_nextWaypoint == 0)) {
            libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint = lv_waypointCount;
        }
        else {
            if ((lv_nextWaypoint > 2)) {
                lv_nextWaypoint -= 1;
                libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_nextWaypoint = lv_nextWaypoint;
            }
            else {
            }
        }
    }
    lv_camp = FixedToInt(UnitGetCustomValue(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, libCore_gf_CustomValueIndex(3)));
    if ((lv_camp != 0)) {
        libMapM_gf_JungleCreateMercPath(libMapM_gv_jungleMiniMapLeader[lv_camp], false);
    }
    else {
    }
}

void libAIAI_gf_MinionAITransitionMinionIntoState (int lp_minionIndex, int lp_state) {
    int auto4E1F7705_val;

    // Variable Declarations
    int lv_newState;
    point lv_previousWaypoint;
    point lv_nextWaypoint;
    point lv_heroPosition;
    point lv_offsetHeroPosition;

    // Variable Initialization

    // Implementation
    auto4E1F7705_val = lp_state;
    if (auto4E1F7705_val == 0) {
        UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingPoint(AbilityCommand("AttackAlly", 0), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)), c_orderQueueReplace);
    }
    else if (auto4E1F7705_val == 1) {
        if ((libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_useSpecialOgreKingLogic == false)) {
            UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)), c_orderQueueReplace);
        }
        else {
        }
        UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingPoint(AbilityCommand("AttackAlly", 0), libAIAI_gf_MinionAIGetNextWaypointForMinion(lp_minionIndex)), c_orderQueueReplace);
    }
    else if (auto4E1F7705_val == 2) {
        UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingUnit(AbilityCommand("AttackAlly", 0), libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit), c_orderQueueReplace);
    }
    else if (auto4E1F7705_val == 3) {
        UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingUnit(AbilityCommand("AttackAlly", 0), libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_targetUnit), c_orderQueueReplace);
    }
    else if (auto4E1F7705_val == 4) {
        UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_battleStandardPoint), c_orderQueueReplace);
    }
    else if (auto4E1F7705_val == 5) {
        lv_heroPosition = UnitGetPosition(libAIAI_gf_MinionAIGetHeroToFollow(lp_minionIndex));
        if ((DistanceBetweenPoints(UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit), lv_heroPosition) > 2.5)) {
            lv_offsetHeroPosition = libNtve_gf_PointOffsetTowardsPoint(lv_heroPosition, 2.0, UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit));
            UnitIssueOrder(libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_minionUnit, OrderTargetingPoint(AbilityCommand("attack", 0), lv_offsetHeroPosition), c_orderQueueReplace);
        }
        else {
        }
    }
    else if (auto4E1F7705_val == 6) {
    }
    else {
    }
}

void libAIAI_gf_MinionAIUpdateLaneInfo () {
    int auto1C79ECF1_ae;
    int auto1C79ECF1_ai;
    int autoE217CA49_ae;
    int autoBC7B573C_ae;

    // Variable Declarations
    int lv_laneIndex;
    int lv_townIndex;
    int lv_structureIndex;
    fixed lv_lanePosition;
    int lv_untitledVariable001;

    // Variable Initialization

    // Implementation
    auto1C79ECF1_ae = libGame_gv_laneCount;
    auto1C79ECF1_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto1C79ECF1_ai >= 0 && lv_laneIndex <= auto1C79ECF1_ae) || (auto1C79ECF1_ai <= 0 && lv_laneIndex >= auto1C79ECF1_ae) ) ; lv_laneIndex += auto1C79ECF1_ai ) {
        libAIAI_gv_minionAILaneInfo[lv_laneIndex].lv_frontOrderGameLanePosition = 1.0;
        libAIAI_gv_minionAILaneInfo[lv_laneIndex].lv_frontChaosGateLanePosition = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
    }
    autoE217CA49_ae = libGame_gv_townTownCount;
    lv_townIndex = 1;
    for ( ; lv_townIndex <= autoE217CA49_ae ; lv_townIndex += 1 ) {
        autoBC7B573C_ae = libGame_gv_townTownData[lv_townIndex].lv_structureCount;
        lv_structureIndex = 1;
        for ( ; lv_structureIndex <= autoBC7B573C_ae ; lv_structureIndex += 1 ) {
            if ((libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 3) && (UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]) == true)) {
                lv_lanePosition = libAIAI_gf_AIGetClosestLanePosition(libGame_gv_townTownData[lv_townIndex].lv_lane, UnitGetPosition(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]));
                if ((libGame_gv_townTownData[lv_townIndex].lv_owner == libCore_gv_cOMPUTER_TeamOrder)) {
                    libAIAI_gv_minionAILaneInfo[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_frontOrderGameLanePosition = MaxF(libAIAI_gv_minionAILaneInfo[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_frontOrderGameLanePosition, lv_lanePosition);
                }
                else {
                    libAIAI_gv_minionAILaneInfo[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_frontChaosGateLanePosition = MinF(libAIAI_gv_minionAILaneInfo[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_frontChaosGateLanePosition, lv_lanePosition);
                }
            }
            else {
            }
        }
    }
}

int libAIAI_gf_MinionAIGetIndexForMinion (unit lp_minion) {
    // Implementation
    return FixedToInt(UnitGetCustomValue(lp_minion, libCore_gf_CustomValueIndex(0)));
}

void libAIAI_gf_MinionAIFreeMinionIndex (int lp_minionIndex) {
    int autoA196110F_ae;
    int autoA196110F_ai;

    // Variable Declarations
    int lv_i;

    // Variable Initialization

    // Implementation
    if ((lp_minionIndex <= 0)) {
        return ;
    }
    else {
    }
    libAIAI_gv_minionAIActiveMinions[lp_minionIndex].lv_isAlive = false;
    if ((lp_minionIndex == libAIAI_gv_minionAIActiveMinionsUpperBound)) {
        autoA196110F_ae = 1;
        autoA196110F_ai = -1;
        lv_i = (libAIAI_gv_minionAIActiveMinionsUpperBound - 1);
        for ( ; ( (autoA196110F_ai >= 0 && lv_i <= autoA196110F_ae) || (autoA196110F_ai <= 0 && lv_i >= autoA196110F_ae) ) ; lv_i += autoA196110F_ai ) {
            if ((libAIAI_gv_minionAIActiveMinions[lv_i].lv_isAlive == true)) {
                libAIAI_gv_minionAIActiveMinionsUpperBound = lv_i;
                break;
            }
            else {
            }
        }
    }
    else {
    }
}

void libAIAI_gf_MinionAIUnhookUnitFromMinionAI (unit lp_unit) {
    // Variable Declarations
    int lv_minionIndex;

    // Variable Initialization

    // Implementation
    lv_minionIndex = libAIAI_gf_MinionAIGetIndexForMinion(lp_unit);
    if ((lv_minionIndex <= 0)) {
        return ;
    }
    else {
    }
    libAIAI_gf_MinionAIFreeMinionIndex(lv_minionIndex);
    UnitSetCustomValue(lp_unit, libCore_gf_CustomValueIndex(0), 0.0);
    UnitIssueOrder(lp_unit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
}

void libAIAI_gf_MinionAIStartMinionAI (unit lp_unit, int lp_lane, int lp_nextWaypoint, bool lp_useSpecialOgreKingLogic, bool lp_aggresiveLeashing, int lp_teamToAttack) {
    // Variable Declarations
    int lv_minionIndex;
    unit lv_heroToFollow;
    fixed lv_weaponRange;

    // Variable Initialization

    // Implementation
    if ((lp_lane == 0)) {
        return ;
    }
    else {
    }
    libAIAI_gf_MinionAIUnhookUnitFromMinionAI(lp_unit);
    lv_minionIndex = libAIAI_gf_MinionAINewMinionIndex();
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit = lp_unit;
    UnitSetCustomValue(lp_unit, libCore_gf_CustomValueIndex(0), IntToFixed(lv_minionIndex));
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnitType = UnitGetType(lp_unit);
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_ownerPlayer = UnitGetOwner(lp_unit);
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_lane = lp_lane;
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_nextWaypoint = lp_nextWaypoint;
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_unitPosition = UnitGetPosition(lp_unit);
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_useSpecialOgreKingLogic = lp_useSpecialOgreKingLogic;
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_aggressiveLeashing = lp_aggresiveLeashing;
    lv_weaponRange = libAIAI_gf_AIGetAnyWeaponRangeIncludesNonActive(lp_unit);
    if ((lv_weaponRange < libAIAI_gv_aIMinionEnemyMinionAttackRange)) {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_attackRange = libAIAI_gv_aIMinionEnemyMinionAttackRange;
    }
    else {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_attackRange = lv_weaponRange;
    }
    if (((lp_teamToAttack <= 0) || (lp_teamToAttack > libCore_gv_bALMaxTeams))) {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_teamToAttack = libGame_gf_EnemyTeamNumberOfPlayer(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_ownerPlayer);
        if ((libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_teamToAttack == 0)) {
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_teamToAttack = 1;
        }
        else {
        }
    }
    else {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_teamToAttack = lp_teamToAttack;
    }
    libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lv_minionIndex);
    if ((PointPathingIsConnected(UnitGetPosition(lp_unit), libAIAI_gf_MinionAIGetNextWaypointForMinion(lv_minionIndex)) == true)) {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state = 0;
        libAIAI_gf_MinionAITransitionMinionIntoState(lv_minionIndex, libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state);
        return ;
    }
    else {
    }
    lv_heroToFollow = libAIAI_gf_MinionAIGetHeroToFollow(lv_minionIndex);
    if ((UnitIsValid(lv_heroToFollow) == true) && (PointPathingIsConnected(UnitGetPosition(lp_unit), UnitGetPosition(lv_heroToFollow)) == true)) {
        libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state = 5;
        libAIAI_gf_MinionAITransitionMinionIntoState(lv_minionIndex, libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state);
        return ;
    }
    else {
    }
    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state = 6;
    libAIAI_gf_MinionAITransitionMinionIntoState(lv_minionIndex, libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state);
}

void libAIAI_gf_MinionAIStartMinionAISimple (unit lp_unit) {
    // Variable Declarations
    int lv_minionIndex;

    // Variable Initialization

    // Implementation
    libGame_gf_CalculateSpawnedMinionGoalPoints(UnitGetOwner(lp_unit), UnitGetPosition(lp_unit));
    libAIAI_gf_MinionAIStartMinionAI(lp_unit, libGame_gv_spawnedMinionLane, libGame_gv_spawnedMinionFirstWaypointIndex, false, false, 0);
}

void libAIAI_gf_MinionAITurnMinionAISystemOnOff (bool lp_onOff) {
    int auto59C8C76E_ae;
    int auto59C8C76E_ai;

    // Variable Declarations
    int lv_i;

    // Variable Initialization

    // Implementation
    if ((lp_onOff == true)) {
        libAIAI_gf_MinionAIUpdateLaneInfo();
        TriggerEnable(libAIAI_gt_MinionAIAIRoutine, true);
        TriggerEnable(libAIAI_gt_MinionAIGateDies, true);
        TriggerEnable(libAIAI_gt_MinionAITownDataInitialized, true);
        TriggerEnable(libGame_gt_MinionDies, true);
    }
    else {
        TriggerEnable(libAIAI_gt_MinionAIAIRoutine, false);
        TriggerEnable(libAIAI_gt_MinionAIGateDies, false);
        TriggerEnable(libAIAI_gt_MinionAITownDataInitialized, false);
        TriggerEnable(libGame_gt_MinionDies, false);
        auto59C8C76E_ae = libAIAI_gv_minionAIMaxActiveMinions;
        auto59C8C76E_ai = 1;
        lv_i = 1;
        for ( ; ( (auto59C8C76E_ai >= 0 && lv_i <= auto59C8C76E_ae) || (auto59C8C76E_ai <= 0 && lv_i >= auto59C8C76E_ae) ) ; lv_i += auto59C8C76E_ai ) {
            if ((libAIAI_gv_minionAIActiveMinions[lv_i].lv_isAlive == true)) {
                UnitRemove(libAIAI_gv_minionAIActiveMinions[lv_i].lv_minionUnit);
                libAIAI_gv_minionAIActiveMinions[lv_i].lv_isAlive = false;
            }
            else {
            }
        }
        libAIAI_gv_minionAIActiveMinionsUpperBound = 0;
    }
}

void libAIAI_gf_MinionAIPauseUnpauseMinionAISystem (bool lp_pauseUnpause) {
    int autoC07AA3FF_ae;
    int autoC07AA3FF_ai;
    int autoD1EAA4C0_ae;
    int autoD1EAA4C0_ai;

    // Variable Declarations
    int lv_i;

    // Variable Initialization

    // Implementation
    if ((lp_pauseUnpause == true)) {
        TriggerEnable(libAIAI_gt_MinionAIAIRoutine, false);
        autoD1EAA4C0_ae = libAIAI_gv_minionAIMaxActiveMinions;
        autoD1EAA4C0_ai = 1;
        lv_i = 1;
        for ( ; ( (autoD1EAA4C0_ai >= 0 && lv_i <= autoD1EAA4C0_ae) || (autoD1EAA4C0_ai <= 0 && lv_i >= autoD1EAA4C0_ae) ) ; lv_i += autoD1EAA4C0_ai ) {
            if ((libAIAI_gv_minionAIActiveMinions[lv_i].lv_isAlive == true)) {
                libNtve_gf_PauseUnit(libAIAI_gv_minionAIActiveMinions[lv_i].lv_minionUnit, true);
            }
            else {
            }
        }
    }
    else {
        autoC07AA3FF_ae = libAIAI_gv_minionAIMaxActiveMinions;
        autoC07AA3FF_ai = 1;
        lv_i = 1;
        for ( ; ( (autoC07AA3FF_ai >= 0 && lv_i <= autoC07AA3FF_ae) || (autoC07AA3FF_ai <= 0 && lv_i >= autoC07AA3FF_ae) ) ; lv_i += autoC07AA3FF_ai ) {
            if ((libAIAI_gv_minionAIActiveMinions[lv_i].lv_isAlive == true)) {
                libNtve_gf_PauseUnit(libAIAI_gv_minionAIActiveMinions[lv_i].lv_minionUnit, false);
            }
            else {
            }
        }
        TriggerEnable(libAIAI_gt_MinionAIAIRoutine, true);
    }
}

void libAIAI_gf_TowerTurnTowerSystemOnOff (bool lp_onOff) {
    int auto505CB3D7_ae;
    int auto505CB3D7_ai;
    int auto829B6BA0_ae;
    int auto829B6BA0_ai;

    // Variable Declarations
    int lv_i;

    // Variable Initialization

    // Implementation
    if ((lp_onOff == true)) {
        libAIAI_gv_towerSystemOn = true;
        TriggerExecute(libAIAI_gt_InitializeTowerAISystem, true, true);
        TriggerEnable(libGame_gt_TowerCoreIsAttacked, true);
        TriggerEnable(libAIAI_gt_TowerAIRoutine, true);
    }
    else {
        libAIAI_gv_towerSystemOn = false;
        TriggerEnable(libAIAI_gt_TowerAIRoutine, false);
        TriggerEnable(libGame_gt_TowerCoreIsAttacked, false);
        TriggerStop(libAIAI_gt_TowerAIRoutine);
        auto505CB3D7_ae = libAIAI_gv_towerTowerCount;
        auto505CB3D7_ai = 1;
        lv_i = 1;
        for ( ; ( (auto505CB3D7_ai >= 0 && lv_i <= auto505CB3D7_ae) || (auto505CB3D7_ai <= 0 && lv_i >= auto505CB3D7_ae) ) ; lv_i += auto505CB3D7_ai ) {
            if ((libAIAI_gv_towerTowers[lv_i].lv_towerUnit != null)) {
                ActorSendTo(libNtve_gf_MainActorofUnit(libAIAI_gv_towerTowers[lv_i].lv_towerUnit), "TowerAttackRange", "Destroy");
                libNtve_gf_MakeUnitInvulnerable(libAIAI_gv_towerTowers[lv_i].lv_towerUnit, false);
                if ((libAIAI_gv_towerTowers[lv_i].lv_targetUnit != null)) {
                    UnitCreateEffectUnit(libAIAI_gv_towerTowers[lv_i].lv_towerUnit, "TowerTargetingLaserDestroyPersistent", libAIAI_gv_towerTowers[lv_i].lv_targetUnit);
                }
                else {
                }
            }
            else {
            }
        }
        auto829B6BA0_ae = libAIAI_gv_towerTowerCount;
        auto829B6BA0_ai = 1;
        lv_i = 1;
        for ( ; ( (auto829B6BA0_ai >= 0 && lv_i <= auto829B6BA0_ae) || (auto829B6BA0_ai <= 0 && lv_i >= auto829B6BA0_ae) ) ; lv_i += auto829B6BA0_ai ) {
            libAIAI_gv_towerTowers[lv_i].lv_towerUnit = null;
            libAIAI_gv_towerTowers[lv_i].lv_targetUnit = null;
        }
    }
}

int libAIAI_gf_DefenderAIDetermineState (int lp_defenderAIIndex, int lp_oldState) {
    int autoE8A1792A_val;
    int autoAE389E8B_ae;
    int autoAE389E8B_ai;
    int autoE80965AF_ae;
    int autoE80965AF_ai;

    // Variable Declarations
    int lv_unitIndex;
    unit lv_defenderUnit;
    int lv_camp;
    bool lv_defendersFinishedLeashing;
    int lv_playerIndex;

    // Variable Initialization
    lv_defendersFinishedLeashing = true;

    // Implementation
    autoE8A1792A_val = lp_oldState;
    if (autoE8A1792A_val == 0) {
        if ((UnitGroupCount(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_validTargets, c_unitCountAlive) > 0)) {
            return 1;
        }
        else {
        }
        lv_camp = libMapM_gf_JungleGetCampIndexFromDefenderIndex(lp_defenderAIIndex);
        if (((lv_camp <= 0) || ((libMapM_gv_jungleCreepCamps[lv_camp].lv_aIState != 4) && (libMapM_gv_jungleCreepCamps[lv_camp].lv_aIState != 5)))) {
            autoAE389E8B_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
            autoAE389E8B_ai = 1;
            lv_unitIndex = 1;
            for ( ; ( (autoAE389E8B_ai >= 0 && lv_unitIndex <= autoAE389E8B_ae) || (autoAE389E8B_ai <= 0 && lv_unitIndex >= autoAE389E8B_ae) ) ; lv_unitIndex += autoAE389E8B_ai ) {
                lv_defenderUnit = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_unitIndex];
                if ((UnitIsAlive(lv_defenderUnit) == true) && (DistanceBetweenPoints(UnitGetPosition(lv_defenderUnit), libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex]) > libAIAI_gv_aIDefenderFarFromLeashPosition)) {
                    return 2;
                }
                else {
                }
            }
        }
        else {
        }
    }
    else if (autoE8A1792A_val == 1) {
        if ((UnitGroupCount(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_validTargets, c_unitCountAlive) == 0)) {
            return 2;
        }
        else {
        }
    }
    else if (autoE8A1792A_val == 2) {
        lv_defendersFinishedLeashing = true;
        autoE80965AF_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
        autoE80965AF_ai = 1;
        lv_unitIndex = 1;
        for ( ; ( (autoE80965AF_ai >= 0 && lv_unitIndex <= autoE80965AF_ae) || (autoE80965AF_ai <= 0 && lv_unitIndex >= autoE80965AF_ae) ) ; lv_unitIndex += autoE80965AF_ai ) {
            lv_defenderUnit = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_unitIndex];
            if ((UnitIsAlive(lv_defenderUnit) == true) && ((UnitTestState(lv_defenderUnit, c_unitStateIdle) == false) || (DistanceBetweenPoints(UnitGetPosition(lv_defenderUnit), libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex]) > libAIAI_gv_aIDefenderCloseEnoughDistance) || ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_healOnLeash == true) && (UnitGetPropertyFixed(lv_defenderUnit, c_unitPropLifePercent, c_unitPropCurrent) <= 95.0)))) {
                lv_defendersFinishedLeashing = false;
                break;
            }
            else {
            }
        }
        if ((lv_defendersFinishedLeashing == true)) {
            return 0;
        }
        else {
        }
    }
    else {
    }
    return lp_oldState;
}

void libAIAI_gf_DefenderAIStateLogic (int lp_defenderAIIndex) {
    int auto05ED653C_val;
    int auto81C95978_ae;
    int auto81C95978_ai;
    int autoA93EBE50_ae;
    int autoA93EBE50_ai;

    // Variable Declarations
    int lv_unitIndex;
    unit lv_defenderUnit;

    // Variable Initialization

    // Implementation
    auto05ED653C_val = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state;
    if (auto05ED653C_val == 0) {
    }
    else if (auto05ED653C_val == 1) {
        auto81C95978_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
        auto81C95978_ai = 1;
        lv_unitIndex = 1;
        for ( ; ( (auto81C95978_ai >= 0 && lv_unitIndex <= auto81C95978_ae) || (auto81C95978_ai <= 0 && lv_unitIndex >= auto81C95978_ae) ) ; lv_unitIndex += auto81C95978_ai ) {
            if ((UnitIsAlive(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_unitIndex]) == true)) {
                libAIAI_gf_DefenderAIIssueOrdersToCreep(lp_defenderAIIndex, lv_unitIndex);
            }
            else {
            }
        }
    }
    else if (auto05ED653C_val == 2) {
        autoA93EBE50_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
        autoA93EBE50_ai = 1;
        lv_unitIndex = 1;
        for ( ; ( (autoA93EBE50_ai >= 0 && lv_unitIndex <= autoA93EBE50_ae) || (autoA93EBE50_ai <= 0 && lv_unitIndex >= autoA93EBE50_ae) ) ; lv_unitIndex += autoA93EBE50_ai ) {
            lv_defenderUnit = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_unitIndex];
            if ((UnitIsAlive(lv_defenderUnit) == true) && (UnitTestState(lv_defenderUnit, c_unitStateIdle) == true) && (DistanceBetweenPoints(UnitGetPosition(lv_defenderUnit), libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex]) > libAIAI_gv_aIDefenderCloseEnoughDistance)) {
                UnitIssueOrder(lv_defenderUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex]), c_orderQueueReplace);
                UnitIssueOrder(lv_defenderUnit, OrderTargetingPoint(AbilityCommand("move", 4), PointWithOffsetPolar(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex], 1.0, PointGetFacing(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_unitIndex]))), c_orderQueueAddToEnd);
            }
            else {
            }
        }
    }
    else {
    }
}

void libAIAI_gf_DefenderAIUpdateValidTargetList (int lp_defenderAIIndex) {
    unitgroup auto58C3FB91_g;
    int auto58C3FB91_u;

    // Variable Declarations
    unit lv_u;
    int lv_defenderOwner;
    int lv_unitOwner;
    region lv_attackRegion;

    // Variable Initialization

    // Implementation
    libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_validTargets = UnitGroupEmpty();
    if ((UnitGroupCount(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup, c_unitCountAlive) == 0)) {
        return ;
    }
    else {
    }
    lv_defenderOwner = UnitGetOwner(UnitGroupRandomUnit(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup, c_unitCountAlive));
    auto58C3FB91_g = UnitGroup(null, c_playerAny, libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashRegion, UnitFilter(0, 0, (1 << c_targetFilterPsionic) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterBuried) | (1 << c_targetFilterCloaked), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterBenign - 32))), 0);
    auto58C3FB91_u = 1;
    for ( ; auto58C3FB91_u <= UnitGroupCount(auto58C3FB91_g, c_unitCountAll) ; auto58C3FB91_u += BoolToInt(lv_u == UnitGroupUnit(auto58C3FB91_g, auto58C3FB91_u)) ) {
        lv_u = UnitGroupUnit(auto58C3FB91_g, auto58C3FB91_u);
        lv_unitOwner = UnitGetOwner(lv_u);
        if (((lv_unitOwner > libCore_gv_bALMaxPlayers) || (libNtve_gf_PlayerIsEnemy(lv_defenderOwner, lv_unitOwner, 4) == false) || (UnitTypeTestFlag(UnitGetType(lv_u), c_unitFlagUntargetable) == true))) {
            continue;
        }
        else {
        }
        if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_playerIsThreat[lv_unitOwner] == false) && (libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_aggoRegion != null) && (libNtve_gf_UnitInRegion(lv_u, libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_aggoRegion) == true)) {
            libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_playerIsThreat[lv_unitOwner] = true;
        }
        else {
        }
        if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_playerIsThreat[lv_unitOwner] == true)) {
            UnitGroupAdd(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_validTargets, lv_u);
        }
        else {
        }
    }
}

void libAIAI_gf_DefenderAITransitionDefenderAIIntoState (int lp_defenderAIIndex, int lp_state) {
    int autoBA9F3ACA_val;
    unitgroup auto6D316A15_g;
    int auto6D316A15_u;
    unitgroup autoEC56D37D_g;
    int autoEC56D37D_u;
    int auto43FE2DF2_ae;
    int auto43FE2DF2_ai;
    int autoD540A8BC_ae;
    int autoD540A8BC_ai;
    int autoFFA8C480_ae;
    int autoFFA8C480_ai;

    // Variable Declarations
    int lv_i;
    unit lv_u;
    string lv_creepUnitType;
    string lv_icon;
    int lv_oldState;

    // Variable Initialization

    // Implementation
    lv_oldState = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state;
    libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state = lp_state;
    autoBA9F3ACA_val = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state;
    if (autoBA9F3ACA_val == 0) {
        auto6D316A15_g = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup;
        auto6D316A15_u = 1;
        for ( ; auto6D316A15_u <= UnitGroupCount(auto6D316A15_g, c_unitCountAll) ; auto6D316A15_u += BoolToInt(lv_u == UnitGroupUnit(auto6D316A15_g, auto6D316A15_u)) ) {
            lv_u = UnitGroupUnit(auto6D316A15_g, auto6D316A15_u);
            UnitBehaviorRemove(lv_u, "JungleCreepHardLeashing", 1);
            UnitBehaviorRemove(lv_u, "JungleCreepSoftLeashing", 1);
            UnitIssueOrder(lv_u, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        }
        libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashCount = 0;
    }
    else if (autoBA9F3ACA_val == 1) {
        autoEC56D37D_g = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup;
        autoEC56D37D_u = 1;
        for ( ; autoEC56D37D_u <= UnitGroupCount(autoEC56D37D_g, c_unitCountAll) ; autoEC56D37D_u += BoolToInt(lv_u == UnitGroupUnit(autoEC56D37D_g, autoEC56D37D_u)) ) {
            lv_u = UnitGroupUnit(autoEC56D37D_g, autoEC56D37D_u);
            if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_aggoRegion == null)) {
                UnitBehaviorRemove(lv_u, "JungleCreepBenign", 1);
            }
            else {
            }
            UnitBehaviorRemove(lv_u, "JungleCreepPassive", 1);
            UnitBehaviorRemove(lv_u, "JungleCreepSoftLeashing", 1);
            if ((UnitGetType(lv_u) == "MercDefenderSiegeGiant") && (libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashCount == 0)) {
                UnitBehaviorAddPlayer(lv_u, "JungleCreepPrepAggro", libCore_gv_cOMPUTER_Hostile, 1);
            }
            else {
            }
        }
    }
    else if (autoBA9F3ACA_val == 2) {
        if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashCount < libAIAI_gv_aIDefenderMaxLeashCount)) {
            libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashCount += 1;
        }
        else {
        }
        auto43FE2DF2_ae = libCore_gv_bALMaxPlayers;
        auto43FE2DF2_ai = 1;
        lv_i = 1;
        for ( ; ( (auto43FE2DF2_ai >= 0 && lv_i <= auto43FE2DF2_ae) || (auto43FE2DF2_ai <= 0 && lv_i >= auto43FE2DF2_ae) ) ; lv_i += auto43FE2DF2_ai ) {
            libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_playerIsThreat[lv_i] = false;
        }
        autoD540A8BC_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
        autoD540A8BC_ai = 1;
        lv_i = 1;
        for ( ; ( (autoD540A8BC_ai >= 0 && lv_i <= autoD540A8BC_ae) || (autoD540A8BC_ai <= 0 && lv_i >= autoD540A8BC_ae) ) ; lv_i += autoD540A8BC_ai ) {
            lv_u = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_i];
            if ((UnitIsAlive(lv_u) == true)) {
                if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashCount < libAIAI_gv_aIDefenderMaxLeashCount) && (libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_healOnLeash == true)) {
                    UnitBehaviorAddPlayer(lv_u, "JungleCreepSoftLeashing", libCore_gv_cOMPUTER_Hostile, 1);
                }
                else {
                    UnitBehaviorAddPlayer(lv_u, "JungleCreepHardLeashing", libCore_gv_cOMPUTER_Hostile, 1);
                    if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_healOnLeash == true)) {
                        UnitSetPropertyFixed(lv_u, c_unitPropLifePercent, 100.0);
                    }
                    else {
                    }
                }
                if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_aggoRegion == null)) {
                    UnitBehaviorAddPlayer(lv_u, "JungleCreepBenign", libCore_gv_cOMPUTER_Hostile, 1);
                }
                else {
                }
                UnitBehaviorAddPlayer(lv_u, "JungleCreepPassive", libCore_gv_cOMPUTER_Hostile, 1);
                UnitIssueOrder(lv_u, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_i]), c_orderQueueReplace);
                UnitIssueOrder(lv_u, OrderTargetingPoint(AbilityCommand("move", 4), PointWithOffsetPolar(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_i], 1.0, PointGetFacing(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_i]))), c_orderQueueAddToEnd);
            }
            else {
            }
        }
        Wait(30.0, c_timeGame);
        if ((UnitGetType(lv_u) != "JungleGraveGolemLaner") && (UnitGetType(lv_u) != "JungleGraveGolemDefender") && (UnitGetType(lv_u) != "UnderworldBoss") && (UnitGetType(lv_u) != "UnderworldSummonedBossBody") && (UnitGetType(lv_u) != "UnderworldSummonedBoss") && (UnitGetType(lv_u) != "UnderworldRangedMinion") && (UnitGetType(lv_u) != "UnderworldMinion") && (UnitHasBehavior2(lv_u, "JungleCreepSoftLeashing") == true)) {
            autoFFA8C480_ae = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderCount;
            autoFFA8C480_ai = 1;
            lv_i = 1;
            for ( ; ( (autoFFA8C480_ai >= 0 && lv_i <= autoFFA8C480_ae) || (autoFFA8C480_ai <= 0 && lv_i >= autoFFA8C480_ae) ) ; lv_i += autoFFA8C480_ai ) {
                lv_u = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lv_i];
                UnitSetPosition(lv_u, libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_leashPositions[lv_i], false);
                UnitCreateEffectUnit(lv_u, "JungleJungleCreepDummyTeleport", lv_u);
            }
        }
        else {
        }
    }
    else {
    }
    if ((lv_oldState == 0) && (lp_state == 1)) {
        libGame_gf_SendEventJungleDefenderAIDefendersBeginFighting(lp_defenderAIIndex);
    }
    else {
    }
    if ((lv_oldState == 2) && (lp_state == 0)) {
        libGame_gf_SendEventJungleDefenderAIDefendersEndFighting(lp_defenderAIIndex);
    }
    else {
    }
}

void libAIAI_gf_DefenderAIIssueOrdersToCreep (int lp_defenderAIIndex, int lp_creep) {
    unitgroup auto615463A1_g;
    int auto615463A1_u;

    // Variable Declarations
    unit lv_u;
    unit lv_creepUnit;
    bool lv_creepNeedsNewOrders;
    unit lv_currentOrderTarget;
    unit lv_newOrderTarget;
    fixed lv_newOrderTargetHealth;
    unitgroup lv_untitledVariable001;
    int lv_graveGolemBindingRootsValidTargets;
    int lv_index;

    // Variable Initialization
    lv_newOrderTargetHealth = 3000.0;
    lv_untitledVariable001 = UnitGroupEmpty();

    // Implementation
    lv_creepUnit = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lp_creep];
    lv_currentOrderTarget = OrderGetTargetUnit(UnitOrder(lv_creepUnit, 0));
    lv_creepNeedsNewOrders = true;
    if ((UnitWeaponPeriodRemaining(lv_creepUnit, 1) > 2.0)) {
        lv_creepNeedsNewOrders = false;
    }
    else {
    }
    if ((UnitGetType(lv_creepUnit) == "MercDefenderRangedOgre")) {
        if ((UnitGetCooldown(lv_creepUnit, "Abil/MercDefenderOgreBuffAbility") <= 0.0) && (UnitGroupCount(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup, c_unitCountAlive) > 1)) {
            auto615463A1_g = libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup;
            auto615463A1_u = 1;
            for ( ; auto615463A1_u <= UnitGroupCount(auto615463A1_g, c_unitCountAll) ; auto615463A1_u += BoolToInt(lv_u == UnitGroupUnit(auto615463A1_g, auto615463A1_u)) ) {
                lv_u = UnitGroupUnit(auto615463A1_g, auto615463A1_u);
                if ((UnitGetType(lv_u) == "MercDefenderMeleeOgre")) {
                    if ((lv_newOrderTargetHealth > UnitGetPropertyFixed(lv_u, c_unitPropLife, c_unitPropCurrent))) {
                        lv_newOrderTargetHealth = UnitGetPropertyFixed(lv_u, c_unitPropLife, c_unitPropCurrent);
                        lv_newOrderTarget = lv_u;
                    }
                    else {
                    }
                }
                else {
                }
            }
            UnitIssueOrder(lv_creepUnit, OrderTargetingUnit(AbilityCommand("MercDefenderOgreBuffAbility", 0), lv_newOrderTarget), c_orderQueueReplace);
            lv_creepNeedsNewOrders = false;
            lv_newOrderTargetHealth = 3000.0;
        }
        else {
        }
    }
    else {
        if (((UnitGetType(lv_creepUnit) == "JungleGraveGolemDefender") || (UnitGetType(lv_creepUnit) == "UnderworldBoss"))) {
            if ((UnitGetCooldown(lv_creepUnit, "Abil/UnderworldBossStun") <= 0.0) && (UnitGroupCount(UnitGroup(null, c_playerAny, RegionCircle(UnitGetPosition(lv_creepUnit), 5.0), UnitFilter((1 << c_targetFilterHeroic) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterStructure) | (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0), c_unitCountAlive) >= 1)) {
                UnitIssueOrder(lv_creepUnit, Order(AbilityCommand("UnderworldBossStun", 0)), c_orderQueueReplace);
                lv_creepNeedsNewOrders = false;
            }
            else {
            }
            if ((UnitGetCooldown(lv_creepUnit, "Abil/UnderworldBossRoots") <= 0.0) && (UnitGroupCount(UnitGroup(null, c_playerAny, RegionCircle(UnitGetPosition(lv_creepUnit), 9.0), UnitFilter((1 << c_targetFilterHeroic) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterStructure) | (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0), c_unitCountAlive) > 1)) {
                UnitGroupLoopBegin(UnitGroup(null, c_playerAny, RegionCircle(UnitGetPosition(lv_creepUnit), 9.0), UnitFilter((1 << c_targetFilterHeroic) | (1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterStructure) | (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0));
                for ( ; !UnitGroupLoopDone() ; UnitGroupLoopStep() ) {
                    if ((DistanceBetweenPoints(UnitGetPosition(UnitGroupLoopCurrent()), UnitGetPosition(lv_creepUnit)) >= 2.0)) {
                        lv_graveGolemBindingRootsValidTargets += 1;
                    }
                    else {
                    }
                }
                UnitGroupLoopEnd();
                if ((lv_graveGolemBindingRootsValidTargets >= 1)) {
                    UnitIssueOrder(lv_creepUnit, OrderTargetingPoint(AbilityCommand("UnderworldBossRoots", 0), UnitGetPosition(libMapM_gf_JungleGetRandomEnemyHeroInRangeOfMinionWithMinimumRangeRequirements(lv_creepUnit, UnitGetPosition(lv_creepUnit), 0.0, 9.0, lv_currentOrderTarget))), c_orderQueueReplace);
                    UnitAddCooldown(lv_creepUnit, "Abil/UnderwoldBindingRoots", 1.5);
                    lv_creepNeedsNewOrders = false;
                }
                else {
                    UnitAddCooldown(lv_creepUnit, "Abil/UnderwoldBindingRoots", 0.5);
                }
            }
            else {
            }
        }
        else {
        }
    }
    libCore_gv_segTriggerUnit = lv_creepUnit;
    libCore_gf_CallRegisteredSegregationTriggers(0);
    if ((lv_creepNeedsNewOrders == true) && ((UnitOrder(lv_creepUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(lv_creepUnit, 0)) == AbilityCommand("attack", 0)) || (OrderGetAbilityCommand(UnitOrder(lv_creepUnit, 0)) == AbilityCommand("AttackAlly", 0)))) {
        lv_newOrderTarget = UnitGroupClosestToPoint(libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_validTargets, UnitGetPosition(lv_creepUnit));
        if ((lv_newOrderTarget != lv_currentOrderTarget)) {
            UnitIssueOrder(lv_creepUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_newOrderTarget), c_orderQueueReplace);
        }
        else {
        }
    }
    else {
    }
}

void libAIAI_gf_DefenderAICreepDies (int lp_defenderAIIndex, unit lp_unit, unit lp_killingUnit) {
    // Implementation
    libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_numberOfDefendersAlive -= 1;
    libGame_gf_SendEventJungleDefenderAIDefenderKilled(lp_defenderAIIndex, lp_unit, lp_killingUnit);
    if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_numberOfDefendersAlive == 0)) {
        libGame_gf_SendEventJungleDefenderAIAllDefendersKilled(lp_defenderAIIndex, lp_killingUnit);
    }
    else {
    }
}

int libAIAI_gf_DefenderAINewIndex () {
    int autoD5805ED0_ae;
    int autoD5805ED0_ai;
    int autoA8796576_ae;
    int autoA8796576_ai;

    // Variable Declarations
    int lv_defenderAIIndex;
    int lv_bestIndex;
    fixed lv_bestIndexTime;

    // Variable Initialization
    lv_bestIndexTime = 524287.0;

    // Implementation
    autoD5805ED0_ae = libAIAI_gv_defenderAIMaxNumberOfDefenderAI;
    autoD5805ED0_ai = 1;
    lv_defenderAIIndex = 1;
    for ( ; ( (autoD5805ED0_ai >= 0 && lv_defenderAIIndex <= autoD5805ED0_ae) || (autoD5805ED0_ai <= 0 && lv_defenderAIIndex >= autoD5805ED0_ae) ) ; lv_defenderAIIndex += autoD5805ED0_ai ) {
        if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_used == false)) {
            libAIAI_gv_defenderAIDefenderAIUpperBound = lv_defenderAIIndex;
            return lv_defenderAIIndex;
        }
        else {
        }
    }
    autoA8796576_ae = libAIAI_gv_defenderAIMaxNumberOfDefenderAI;
    autoA8796576_ai = 1;
    lv_defenderAIIndex = 1;
    for ( ; ( (autoA8796576_ai >= 0 && lv_defenderAIIndex <= autoA8796576_ae) || (autoA8796576_ai <= 0 && lv_defenderAIIndex >= autoA8796576_ae) ) ; lv_defenderAIIndex += autoA8796576_ai ) {
        if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_numberOfDefendersAlive == 0) && (libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_timeStarted < lv_bestIndexTime)) {
            lv_bestIndex = lv_defenderAIIndex;
            lv_bestIndexTime = libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_timeStarted;
        }
        else {
        }
    }
    return lv_bestIndex;
}

void libAIAI_gf_StartDefenderAI (unitgroup lp_defenders, region lp_leashRegion, region lp_aggroRegion, bool lp_healOnLeash) {
    unitgroup auto5BE89C99_g;
    int auto5BE89C99_u;

    // Variable Declarations
    int lv_defenderAIIndex;
    int lv_testIndex;
    unit lv_unit;
    int lv_unitIndex;

    // Variable Initialization

    // Implementation
    lv_defenderAIIndex = libAIAI_gf_DefenderAINewIndex();
    if ((lv_defenderAIIndex <= 0)) {
        TriggerDebugOutput(1, StringExternal("Param/Value/lib_AIAI_F84235F3"), true);
        return ;
    }
    else {
    }
    if ((UnitGroupCount(lp_defenders, c_unitCountAlive) > libAIAI_gv_defenderAIMaxNumberOfDefendersPerGroup)) {
        TriggerDebugOutput(1, StringExternal("Param/Value/lib_AIAI_4ACB7326"), true);
        return ;
    }
    else {
    }
    if ((TriggerIsEnabled(libAIAI_gt_DefenderAIDefenderAILogic) == false)) {
        TriggerEnable(libAIAI_gt_DefenderAIDefenderAILogic, true);
        TriggerEnable(libAIAI_gt_DefenderAICreepsAttacked, true);
    }
    else {
    }
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_used = true;
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_timeStarted = TimerGetElapsed(libGame_gv_gameTimer);
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_leashRegion = lp_leashRegion;
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_aggoRegion = lp_aggroRegion;
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_healOnLeash = lp_healOnLeash;
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defendersGroup = UnitGroupEmpty();
    libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defenderCount = 0;
    auto5BE89C99_g = lp_defenders;
    auto5BE89C99_u = 1;
    for ( ; auto5BE89C99_u <= UnitGroupCount(auto5BE89C99_g, c_unitCountAll) ; auto5BE89C99_u += BoolToInt(lv_unit == UnitGroupUnit(auto5BE89C99_g, auto5BE89C99_u)) ) {
        lv_unit = UnitGroupUnit(auto5BE89C99_g, auto5BE89C99_u);
        UnitGroupAdd(libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defendersGroup, lv_unit);
        if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_aggoRegion == null)) {
            UnitBehaviorAdd(lv_unit, "JungleCreepBenign", lv_unit, 1);
        }
        else {
        }
        UnitBehaviorAdd(lv_unit, "JungleCreepPassive", lv_unit, 1);
        UnitStatusBarOverride(lv_unit, c_unitStatusGroupAll);
        UnitSetCustomValue(lv_unit, libCore_gf_CustomValueIndex(2), IntToFixed(lv_defenderAIIndex));
        libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defenderCount += 1;
        libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_numberOfDefendersAlive += 1;
        lv_unitIndex = libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defenderCount;
        libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_defenderUnits[lv_unitIndex] = lv_unit;
        libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_leashPositions[lv_unitIndex] = UnitGetPosition(lv_unit);
    }
    libAIAI_gf_DefenderAITransitionDefenderAIIntoState(lv_defenderAIIndex, 0);
    DataTableSetInt(false, libAIAI_gv_defenderAILastCreatedDefenderAIIndex, lv_defenderAIIndex);
}

int libAIAI_gf_LastCreatedDefenderAI () {
    // Implementation
    return DataTableGetInt(false, libAIAI_gv_defenderAILastCreatedDefenderAIIndex);
}

int libAIAI_gf_DefenderAIIndexOfUnit (unit lp_unit) {
    // Variable Declarations
    int lv_i;

    // Variable Initialization

    // Implementation
    return FixedToInt(UnitGetCustomValue(lp_unit, libCore_gf_CustomValueIndex(2)));
}

unitgroup libAIAI_gf_DefenderGroup (int lp_defenderAIIndex) {
    // Implementation
    if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_used == false)) {
        return UnitGroupEmpty();
    }
    else {
        return libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defendersGroup;
    }
}

unit libAIAI_gf_DefenderUnit (int lp_defenderAIIndex, int lp_index) {
    // Implementation
    if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_used == false)) {
        return null;
    }
    else {
        return libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_defenderUnits[lp_index];
    }
}

bool libAIAI_gf_DefendersAreFighting (int lp_defenderAIIndex) {
    // Implementation
    if ((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_used == false)) {
        return false;
    }
    else {
    }
    if (((libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state == 1) || (libAIAI_gv_defenderAI[lp_defenderAIIndex].lv_state == 2))) {
        return true;
    }
    else {
        return false;
    }
}

text libAIAI_gf_HeroAIDifficultyDisplayText (int lp_player) {
    int autoAFC95489_val;

    // Implementation
    autoAFC95489_val = libAIAI_gv_aIHeroes[lp_player].lv_difficulty;
    if (autoAFC95489_val == 1) {
        return StringExternal("Param/Value/lib_AIAI_2E625D66");
    }
    else if (autoAFC95489_val == 2) {
        return StringExternal("Param/Value/lib_AIAI_846F1ECA");
    }
    else if (autoAFC95489_val == 3) {
        return StringExternal("Param/Value/lib_AIAI_F3DEE6F6");
    }
    else if (autoAFC95489_val == 4) {
        return StringExternal("Param/Value/lib_AIAI_F94BE010");
    }
    else if (autoAFC95489_val == 5) {
        return StringExternal("Param/Value/lib_AIAI_40C01A05");
    }
    else if (autoAFC95489_val == 6) {
        return StringExternal("Param/Value/lib_AIAI_25BF051E");
    }
    else if (autoAFC95489_val == 7) {
        return StringExternal("Param/Value/lib_AIAI_001484B6");
    }
    else if (autoAFC95489_val == 8) {
        return StringExternal("Param/Value/lib_AIAI_95BDCE78");
    }
    else if (autoAFC95489_val == 9) {
        return StringExternal("Param/Value/lib_AIAI_7D80355C");
    }
    else if (autoAFC95489_val == 10) {
        return StringExternal("Param/Value/lib_AIAI_0B6F66E6");
    }
    else if (autoAFC95489_val == 11) {
        return StringExternal("Param/Value/lib_AIAI_D85DF7F9");
    }
    else if (autoAFC95489_val == 12) {
        return StringExternal("Param/Value/lib_AIAI_1F45ECCF");
    }
    else {
        return StringExternal("Param/Value/lib_AIAI_D45E7A83");
    }
}

void libAIAI_gf_HeroAIAddHeroToTierData (int lp_tier, string lp_heroType) {
    int autoB2D0B98E_ae;

    // Variable Declarations
    int lv_index;

    // Variable Initialization

    // Implementation
    autoB2D0B98E_ae = libCore_gv_dataHeroesMaxHeroCount;
    lv_index = 1;
    for ( ; lv_index <= autoB2D0B98E_ae ; lv_index += 1 ) {
        if ((libAIAI_gv_heroAIHeroTierData[(lp_tier)][lv_index] == null)) {
            libAIAI_gv_heroAIHeroTierData[(lp_tier)][lv_index] = lp_heroType;
            return ;
        }
        else {
        }
    }
    TextExpressionSetToken("Param/Expression/lib_AIAI_F06DDB0A", "A", UnitTypeGetName(lp_heroType));
    TextExpressionSetToken("Param/Expression/lib_AIAI_F06DDB0A", "B", IntToText((lp_tier)));
    TriggerDebugOutput(1, TextExpressionAssemble("Param/Expression/lib_AIAI_F06DDB0A"), true);
}

void libAIAI_gf_HeroAIGeneralPreInit () {
    int init_i;

    int auto65D01E62_ae;
    int auto622CE5EF_ae;
    int auto622CE5EF_ai;
    int auto24B01FD4_val;
    int auto7A79B344_ae;
    int auto7A79B344_ai;
    int auto17F71483_ae;
    int auto17F71483_ai;
    int auto60404955_ae;
    int auto60404955_ai;
    int auto0C98E68B_ae;
    int auto0C98E68B_ai;
    int autoBBF9ABE8_ae;
    int autoBBF9ABE8_ai;
    int auto6712195B_ae;
    int auto6712195B_ai;
    int auto523DE555_ae;
    int auto523DE555_ai;

    // Variable Declarations
    int lv_loopIndex;
    int lv_currentPlayer;
    int lv_mainCampIndex;
    int lv_altCampIndex;
    int lv_insertCampIndex;
    int[libMapM_gv_jungleMaxCamps + 1] lv_sortedCampIndex;

    // Variable Initialization
    for (init_i = 0; init_i <= libMapM_gv_jungleMaxCamps; init_i += 1) {
        lv_sortedCampIndex[init_i] = -1;
    }

    // Implementation
    TriggerEnable(libAIAI_gt_HeroAITakeOverHero, true);
    TriggerEnable(libAIAI_gt_HeroAIReleaseHeroControl, true);
    auto65D01E62_ae = libCore_gv_bALMaxPlayers;
    lv_currentPlayer = 1;
    for ( ; lv_currentPlayer <= auto65D01E62_ae ; lv_currentPlayer += 1 ) {
        PlayerSetAllowAIControl(lv_currentPlayer, true);
    }
    auto622CE5EF_ae = libCore_gv_bALMaxPlayers;
    auto622CE5EF_ai = 1;
    lv_currentPlayer = 1;
    for ( ; ( (auto622CE5EF_ai >= 0 && lv_currentPlayer <= auto622CE5EF_ae) || (auto622CE5EF_ai <= 0 && lv_currentPlayer >= auto622CE5EF_ae) ) ; lv_currentPlayer += auto622CE5EF_ai ) {
        if ((PlayerStatus(lv_currentPlayer) != c_playerStatusUnused)) {
            if ((PlayerType(lv_currentPlayer) != c_playerTypeComputer) && (PlayerStatus(lv_currentPlayer) != c_playerStatusLeft)) {
            }
            else {
                if ((libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty == 0)) {
                    auto24B01FD4_val = PlayerDifficulty(lv_currentPlayer);
                    if (auto24B01FD4_val == 1) {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 6;
                    }
                    else if (auto24B01FD4_val == 2) {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 8;
                    }
                    else if (auto24B01FD4_val == 3) {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 10;
                    }
                    else if (auto24B01FD4_val == 6) {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 11;
                    }
                    else if (auto24B01FD4_val == 7) {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 12;
                    }
                    else {
                        libAIAI_gv_aIHeroes[lv_currentPlayer].lv_difficulty = 12;
                    }
                }
                else {
                }
            }
        }
        else {
        }
    }
    libAIAI_gf_HeroAIUpdateTeamDifficulty(0);
    libAIAI_gf_HeroAIUpdateTeamDifficulty(1);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(0);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(1);
    auto7A79B344_ae = libMapM_gv_jungleNumberOfCreepCamps;
    auto7A79B344_ai = 1;
    lv_mainCampIndex = 1;
    for ( ; ( (auto7A79B344_ai >= 0 && lv_mainCampIndex <= auto7A79B344_ae) || (auto7A79B344_ai <= 0 && lv_mainCampIndex >= auto7A79B344_ae) ) ; lv_mainCampIndex += auto7A79B344_ai ) {
        auto17F71483_ae = libMapM_gv_jungleNumberOfCreepCamps;
        auto17F71483_ai = 1;
        lv_altCampIndex = 1;
        for ( ; ( (auto17F71483_ai >= 0 && lv_altCampIndex <= auto17F71483_ae) || (auto17F71483_ai <= 0 && lv_altCampIndex >= auto17F71483_ae) ) ; lv_altCampIndex += auto17F71483_ai ) {
            if ((lv_sortedCampIndex[lv_altCampIndex] <= 0)) {
                lv_sortedCampIndex[lv_altCampIndex] = lv_mainCampIndex;
                break;
            }
            else {
                if ((libMapM_gv_jungleCreepCamps[lv_sortedCampIndex[lv_altCampIndex]].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lv_sortedCampIndex[lv_altCampIndex]].lv_stateCurrentDefenderScalingTicks] > libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_stateCurrentDefenderScalingTicks])) {
                    auto60404955_ae = lv_altCampIndex;
                    auto60404955_ai = -1;
                    lv_insertCampIndex = (libMapM_gv_jungleMaxCamps - 1);
                    for ( ; ( (auto60404955_ai >= 0 && lv_insertCampIndex <= auto60404955_ae) || (auto60404955_ai <= 0 && lv_insertCampIndex >= auto60404955_ae) ) ; lv_insertCampIndex += auto60404955_ai ) {
                        lv_sortedCampIndex[(lv_insertCampIndex + 1)] = lv_sortedCampIndex[lv_insertCampIndex];
                    }
                    lv_sortedCampIndex[lv_altCampIndex] = lv_mainCampIndex;
                    break;
                }
                else {
                }
            }
        }
    }
    auto0C98E68B_ae = libMapM_gv_jungleNumberOfCreepCamps;
    auto0C98E68B_ai = 1;
    lv_altCampIndex = 1;
    for ( ; ( (auto0C98E68B_ai >= 0 && lv_altCampIndex <= auto0C98E68B_ae) || (auto0C98E68B_ai <= 0 && lv_altCampIndex >= auto0C98E68B_ae) ) ; lv_altCampIndex += auto0C98E68B_ai ) {
        lv_mainCampIndex = lv_sortedCampIndex[lv_altCampIndex];
        if ((libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_mapDataCampCaptainSpawnPoint != null) && ((libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_mapDataCampType == 0) || (libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_mapDataCampType == 2))) {
            if ((libCore_gf_TestLocationClosertoFactionSide(libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_mapDataCampCaptainSpawnPoint, 0, 0.8) == true)) {
                autoBBF9ABE8_ae = libMapM_gv_jungleNumberOfCreepCamps;
                autoBBF9ABE8_ai = 1;
                lv_insertCampIndex = 1;
                for ( ; ( (autoBBF9ABE8_ai >= 0 && lv_insertCampIndex <= autoBBF9ABE8_ae) || (autoBBF9ABE8_ai <= 0 && lv_insertCampIndex >= autoBBF9ABE8_ae) ) ; lv_insertCampIndex += autoBBF9ABE8_ai ) {
                    if ((libAIAI_gv_heroAIOrderMercCampList[lv_insertCampIndex] <= 0)) {
                        libAIAI_gv_heroAIOrderMercCampList[lv_insertCampIndex] = lv_mainCampIndex;
                        break;
                    }
                    else {
                    }
                }
            }
            else {
                if ((libCore_gf_TestLocationClosertoFactionSide(libMapM_gv_jungleCreepCamps[lv_mainCampIndex].lv_mapDataCampCaptainSpawnPoint, 1, 0.8) == true)) {
                    auto523DE555_ae = libMapM_gv_jungleNumberOfCreepCamps;
                    auto523DE555_ai = 1;
                    lv_insertCampIndex = 1;
                    for ( ; ( (auto523DE555_ai >= 0 && lv_insertCampIndex <= auto523DE555_ae) || (auto523DE555_ai <= 0 && lv_insertCampIndex >= auto523DE555_ae) ) ; lv_insertCampIndex += auto523DE555_ai ) {
                        if ((libAIAI_gv_heroAIChaosMercCampList[lv_insertCampIndex] <= 0)) {
                            libAIAI_gv_heroAIChaosMercCampList[lv_insertCampIndex] = lv_mainCampIndex;
                            break;
                        }
                        else {
                        }
                    }
                }
                else {
                    auto6712195B_ae = libMapM_gv_jungleNumberOfCreepCamps;
                    auto6712195B_ai = 1;
                    lv_insertCampIndex = 1;
                    for ( ; ( (auto6712195B_ai >= 0 && lv_insertCampIndex <= auto6712195B_ae) || (auto6712195B_ai <= 0 && lv_insertCampIndex >= auto6712195B_ae) ) ; lv_insertCampIndex += auto6712195B_ai ) {
                        if ((libAIAI_gv_heroAIMiddleMercCampList[lv_insertCampIndex] <= 0)) {
                            libAIAI_gv_heroAIMiddleMercCampList[lv_insertCampIndex] = lv_mainCampIndex;
                            break;
                        }
                        else {
                        }
                    }
                }
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIInitAbilities (int lp_player) {
    string auto8FA3803F_val;

    // Implementation
    auto8FA3803F_val = UnitGetType(libGame_gv_players[lp_player].lv_heroUnit);
    if (auto8FA3803F_val == "HeroMuradin") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("MuradinStormBolt", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("MuradinThunderclap", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("MuradinDwarfToss", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("MuradinAvatar", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("MuradinHaymaker", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 1;
    }
    else if (auto8FA3803F_val == "HeroStitches") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("StitchesHook", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("StitchesSlam", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("StitchesDevour", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("StitchesPutridBile", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("StitchesGorge", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 1;
    }
    else if (auto8FA3803F_val == "HeroNova") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("NovaSnipeStorm", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("NovaPinningShot", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("NovaHoloDecoy", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("NovaTripleTap", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("NovaPrecisionStrike", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroKerrigan") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("KerriganRavage", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("KerriganCrushingGrip", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("KerriganPrimalGrasp", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("KerriganSummonUltralisk", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("KerriganMaelstrom", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 3;
    }
    else if (auto8FA3803F_val == "HeroZeratul") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("ZeratulCleave", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("ZeratulSustainedAnomaly", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("ZeratulBlinkStorm", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 7;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("ZeratulShadowAssault", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("ZeratulVoidPrison", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroSgtHammer") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("SgtHammerSiegeMode", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 0;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("SgtHammerConcussiveBlast", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("SgtHammerMineField", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("SgtHammerNapalmStrike", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("SgtHammerBluntForceGun", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroUther") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("UtherHolyLight", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("UtherHolyRadiance", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("UtherHammerOfJustice", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("UtherDivineIntervention", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("UtherDivineStorm", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 10;
    }
    else if (auto8FA3803F_val == "HeroTassadar") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("TassadarPlasmaShield", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("TassadarVoidShift", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("TassadarTimeWarp", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("TassadarTwilightMessiah", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("TassadarForceWall", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroArthas") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("ArthasFrostStrike", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("ArthasHowlingBlast", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("ArthasDeathAndDecay", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("ArthasArmyOfTheDead", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("ArthasSummonSindragosa", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroTinker") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("TinkerRockItTurret", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 7;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("TinkerDethLazorCharged", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 0;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("TinkerXplodiumBomb", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("TinkerRoboGoblin", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("TinkerGravOBomb3000", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroWitchDoctor") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("WitchDoctorCorpseSpiders", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("WitchDoctorZombiePrison", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("WitchDoctorPlagueToadsCone", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("WitchDoctorGargantuan", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("WitchDoctorRavenousSouls", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroL90ETC") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("L90ETCPowerslide", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("L90ETCFaceMelt", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("L90ETCGuitarSolo", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("L90ETCStageDive", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("L90ETCMoshPit", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 3;
    }
    else if (auto8FA3803F_val == "HeroIllidan") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("IllidanDive", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("IllidanSweepingStrike", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("IllidanEvasion", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("IllidanTheHunt", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("IllidanMetamorphosisTargeted", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroMalfurion") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("MalfurionRegrowth", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("MalfurionMoonfire", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("MalfurionEntanglingRoots", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("MalfurionTranquility", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 8;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("MalfurionTwilightDream", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 3;
    }
    else if (auto8FA3803F_val == "HeroFalstad") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("FalstadHammerang", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("FalstadThunderstorm", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("FalstadBarrelRoll", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("FalstadAerialBlitzkrieg", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("FalstadShockAndAwe", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroDiablo") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("DiabloShadowCharge", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("DiabloFireStomp", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("DiabloPound", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("DiabloLightningBreathTargeted", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("DiabloApocalypse", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 10;
    }
    else if (auto8FA3803F_val == "HeroTychus") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("TychusGrenade", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("TychusRunAndGun", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("TychusOverkillTargeted", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("TychusOdin", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("TychusDrakkenLaserDrill", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroDemonHunter") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("DemonHunterHungeringArrow", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("DemonHunterMultishot", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("DemonHunterVault", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("DemonHunterStrafe", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("DemonHunterRainOfVengeance", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroTyrande") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("TyrandeLightofElune", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("TyrandeSentinelShot", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 0;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("TyrandeLunarFlare", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("TyrandeShadowstalk", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("TyrandeStarfall", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroTyrael") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("TyraelElDruinsMight", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("TyraelRighteousness", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("TyraelBlessingofSacrifice", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("TyraelJudgement", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("TyraelSanctificationUpdated", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 10;
    }
    else if (auto8FA3803F_val == "HeroBarbarian") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("BarbarianSeismicSlam", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("BarbarianWhirlwind", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("BarbarianBattleCry", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("BarbarianLeap", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("BarbarianWrathoftheBerserker", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 10;
    }
    else if (auto8FA3803F_val == "HeroRaynor") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("RaynorPenetratingRound", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("RaynorInspire", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("RaynorAdrenalineRush", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("RaynorHyperion", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("RaynorRaynorsRaiders", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 2;
    }
    else if (auto8FA3803F_val == "HeroFaerieDragon") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("FaerieDragonArcaneFlare", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 2;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("FaerieDragonPolymorph", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 1;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("FaerieDragonPixieDust", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("FaerieDragonBlinkHeal", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("FaerieDragonEmeraldWind", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 3;
    }
    else if (auto8FA3803F_val == "HeroLiLi") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("LiLiHealingBrew", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("LiLiCloudSerpent", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 6;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("LiLiBlindingWind", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 3;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("LiLiJugof1000Cups", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 10;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[4] = AbilityCommand("LiLiWaterDragon", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[4] = 1;
    }
    else if (auto8FA3803F_val == "HeroAbathur") {
        libAIAI_gv_aIHeroes[lp_player].lv_hasTactical = true;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[0] = AbilityCommand("AbathurNeuralParasite", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[0] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[1] = AbilityCommand("AbathurSymbiote", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[1] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[2] = AbilityCommand("AbathurToxicNest", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[2] = 11;
        libAIAI_gv_aIHeroes[lp_player].lv_castAbility[3] = AbilityCommand("AbathurUltimateEvolution", 0);
        libAIAI_gv_aIHeroes[lp_player].lv_abilityType[3] = 11;
    }
    else {
        libAIAI_gv_heroAIInitAbilitesHeroFound = false;
        libCore_gv_segTriggerPlayer = lp_player;
        libCore_gv_segTriggerUnit = libGame_gv_players[lp_player].lv_heroUnit;
        libCore_gf_CallRegisteredSegregationTriggers(2);
        if ((libAIAI_gv_heroAIInitAbilitesHeroFound == false)) {
            TextExpressionSetToken("Param/Expression/lib_AIAI_D20C6DD4", "A", UnitTypeGetName(UnitGetType(libGame_gv_players[lp_player].lv_heroUnit)));
            TriggerDebugOutput(1, TextExpressionAssemble("Param/Expression/lib_AIAI_D20C6DD4"), true);
        }
        else {
            libAIAI_gv_heroAIInitAbilitesHeroFound = false;
        }
    }
}

void libAIAI_gf_HeroAIEnableAIForPlayer (int lp_trigPlayer) {
    int auto9BF99977_val;

    // Variable Declarations
    region lv_baseRegion;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_baseRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_baseRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState != 0)) {
        return ;
    }
    else {
    }
    if ((libAIAI_gv_heroAIActive == false)) {
        libAIAI_gf_HeroAIStartAI();
    }
    else {
    }
    if ((libAIAI_gf_HeroAITeamHasHumanPlayers(libGame_gv_players[lp_trigPlayer].lv_faction) == true)) {
        auto9BF99977_val = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty;
        if (auto9BF99977_val == 6) {
            libAIAI_gf_HeroAISetAIDifficultyLevel(lp_trigPlayer, 7);
        }
        else if (auto9BF99977_val == 8) {
            libAIAI_gf_HeroAISetAIDifficultyLevel(lp_trigPlayer, 9);
        }
        else {
        }
    }
    else {
    }
    libAIAI_gf_HeroAIInitAbilities(lp_trigPlayer);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
    if ((libGame_gv_players[lp_trigPlayer].lv_isDead == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 1);
    }
    else if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
    else if ((libAIAI_gv_heroAIUnderworldStatus.lv_opened == true) && (libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls = true;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 58);
    }
    else if ((libAIAI_gf_HeroAIHasGameStarted() == false)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 4);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextWaitForGameToStartRepositionTime = TimerGetElapsed(libGame_gv_totalTime);
    }
    else if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartWaitToHeal(lp_trigPlayer);
    }
    else if (true) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
    libAIAI_gf_HeroAIUpdateAIStatus(lp_trigPlayer);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(libGame_gv_players[lp_trigPlayer].lv_faction);
}

void libAIAI_gf_HeroAIDisableAIForPlayer (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 0)) {
        return ;
    }
    else {
    }
    libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 0);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
    libAIAI_gf_HeroAIUpdateAIStatus(lp_trigPlayer);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(libGame_gv_players[lp_trigPlayer].lv_faction);
}

void libAIAI_gf_HeroAISetAIDifficultyLevel (int lp_player, int lp_difficulty) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_player].lv_difficulty = lp_difficulty;
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        libAIAI_gf_HeroAIUpdateTeamDifficulty(0);
    }
    else {
        libAIAI_gf_HeroAIUpdateTeamDifficulty(1);
    }
}

void libAIAI_gf_HeroAISetupUnitDangerTracking (unit lp_unit) {
    // Implementation
    if ((libAIAI_gv_heroAIActive == true)) {
        AITrackUnitDanger(lp_unit);
    }
    else {
    }
}

void libAIAI_gf_HeroAISetStartingLane (int lp_trigPlayer, int lp_laneIndex) {
    // Implementation
    if ((lp_laneIndex > 0) && (lp_laneIndex <= libGame_gv_laneCount)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_startingLane = lp_laneIndex;
    }
    else {
    }
}

void libAIAI_gf_HeroAIAssistPlayerInLane (int lp_trigPlayer, int lp_playerToAssist) {
    // Implementation
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_trigPlayer, 0) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_followPlayer = lp_playerToAssist;
    }
    else {
    }
}

trigger auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_Trigger = null;
playergroup auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_players;
int auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_humanPlayer;
int auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_campIndex;

void libAIAI_gf_HeroAIAssistHumanPlayerWithCamp (playergroup lp_players, int lp_humanPlayer, int lp_campIndex) {
    auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_players = lp_players;
    auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_humanPlayer = lp_humanPlayer;
    auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_campIndex = lp_campIndex;

    if (auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_Trigger == null) {
        auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_Trigger = TriggerCreate("auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_TriggerFunc");
    }

    TriggerExecute(auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_Trigger, false, false);
}

bool auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_TriggerFunc (bool testConds, bool runActions) {
    playergroup lp_players = auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_players;
    int lp_humanPlayer = auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_humanPlayer;
    int lp_campIndex = auto_libAIAI_gf_HeroAIAssistHumanPlayerWithCamp_lp_campIndex;

    playergroup autoC6D6DBE2_g;
    int autoC6D6DBE2_p;
    playergroup auto10971D9D_g;
    int auto10971D9D_p;
    playergroup autoAC095C4A_g;
    int autoAC095C4A_p;

    // Variable Declarations
    bool lv_campCaptured;
    int lv_playerIndex;
    playergroup lv_aIPlayers;
    bool lv_aIBusy;
    fixed lv_timeout;
    const fixed lv_considerFrequency = 3.0;
    const fixed lv_considerTimeout = 120.0;

    // Variable Initialization
    lv_aIPlayers = PlayerGroupEmpty();

    // Implementation
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_humanPlayer, 1) == false)) {
        return true;
    }
    else {
    }
    autoC6D6DBE2_g = lp_players; 
    autoC6D6DBE2_p = 1;
    for ( ; autoC6D6DBE2_p <= PlayerGroupCount(autoC6D6DBE2_g) ; autoC6D6DBE2_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoC6D6DBE2_g, autoC6D6DBE2_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoC6D6DBE2_g, autoC6D6DBE2_p);
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true)) {
            PlayerGroupAdd(lv_aIPlayers, lv_playerIndex);
        }
        else {
        }
    }
    if ((PlayerGroupCount(lv_aIPlayers) == 0)) {
        return true;
    }
    else {
    }
    lv_timeout = (TimerGetElapsed(libGame_gv_gameTimer) + lv_considerTimeout);
    while (true) {
        if ((TimerGetElapsed(libGame_gv_gameTimer) >= lv_timeout)) {
            return true;
        }
        else {
        }
        lv_aIBusy = false;
        auto10971D9D_g = lv_aIPlayers; 
        auto10971D9D_p = 1;
        for ( ; auto10971D9D_p <= PlayerGroupCount(auto10971D9D_g) ; auto10971D9D_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto10971D9D_g, auto10971D9D_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(auto10971D9D_g, auto10971D9D_p);
            if ((libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 10) == false)) {
                lv_aIBusy = true;
                break;
            }
            else {
            }
        }
        if ((lv_aIBusy == false)) {
            break;
        }
        else {
        }
        Wait(lv_considerFrequency, c_timeGame);
    }
    autoAC095C4A_g = lv_aIPlayers; 
    autoAC095C4A_p = 1;
    for ( ; autoAC095C4A_p <= PlayerGroupCount(autoAC095C4A_g) ; autoAC095C4A_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoAC095C4A_g, autoAC095C4A_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoAC095C4A_g, autoAC095C4A_p);
        libAIAI_gf_HeroAIStartTakeCamp(lv_playerIndex, lp_campIndex, lp_humanPlayer);
    }
    return true;
}

void libAIAI_gf_HeroAIStartWaitInSpawn (int lp_trigPlayer) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_shouldWaitInSpawn = true;
}

void libAIAI_gf_HeroAIStopWaitInSpawn (int lp_trigPlayer) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_shouldWaitInSpawn = false;
}

void libAIAI_gf_HeroAIStartAI () {
    int autoB174DA04_ae;
    int autoB174DA04_ai;

    // Variable Declarations
    int lv_playerIndex;
    int lv_townIndex;
    int lv_structureIndex;

    // Variable Initialization

    // Implementation
    AIForceActive();
    libAIAI_gv_heroAIActive = true;
    libAIAI_gv_heroAITeamCampData[0].lv_startCampCheckTimer = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroCampConsiderFrequency - 3.0), (libAIAI_gv_aIHeroCampConsiderFrequency + 3.0)));
    libAIAI_gv_heroAITeamCampData[1].lv_startCampCheckTimer = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroCampConsiderFrequency - 3.0), (libAIAI_gv_aIHeroCampConsiderFrequency + 3.0)));
    AIAddTeamRepresentative(libCore_gv_cOMPUTER_TeamOrder);
    AIAddTeamRepresentative(libCore_gv_cOMPUTER_TeamChaos);
    autoB174DA04_ae = libCore_gv_bALMaxPlayers;
    autoB174DA04_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoB174DA04_ai >= 0 && lv_playerIndex <= autoB174DA04_ae) || (autoB174DA04_ai <= 0 && lv_playerIndex >= autoB174DA04_ae) ) ; lv_playerIndex += autoB174DA04_ai ) {
        if ((UnitIsValid(libGame_gv_players[lv_playerIndex].lv_heroUnit) == true)) {
            libAIAI_gf_HeroAISetupUnitDangerTracking(libGame_gv_players[lv_playerIndex].lv_heroUnit);
        }
        else {
        }
    }
    libAIAI_gf_HeroAISetupUnitDangerTracking(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    libAIAI_gf_HeroAISetupUnitDangerTracking(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(0);
    libAIAI_gf_HeroAIUpdateTeamPlayerData(1);
    libAIAI_gf_HeroAICalcCoreDefensePosition(0);
    libAIAI_gf_HeroAICalcCoreDefensePosition(1);
    libAIAI_gf_HeroAISetupTownData();
    libAIAI_gf_HeroAIEvalLanes(0);
    libAIAI_gf_HeroAIEvalLanes(1);
    libAIAI_gf_HeroAIRegisterDataModAOEEffects();
    TriggerEnable(libAIAI_gt_HeroAIWatchForAOEAbilityCasted, true);
    TriggerEnable(libAIAI_gt_HeroAITownDataInitialized, true);
    TriggerEnable(libAIAI_gt_HeroAITowerDies, true);
    TriggerEnable(libAIAI_gt_HeroAIFollowerCommand, true);
    TriggerEnable(libAIAI_gt_HeroAIHeroTakesDamage, true);
    TriggerEnable(libAIAI_gt_HeroAIHeroEntersAfterDeathState, true);
    TriggerEnable(libAIAI_gt_HeroAIHeroDies, true);
    TriggerEnable(libAIAI_gt_HeroAIHumanAllyInitiatesFight, true);
    TriggerExecute(libAIAI_gt_HeroAIRunMainGroupLoop, true, false);
}

void libAIAI_gf_HeroAISetupTownData () {
    int auto6775C45A_ae;
    int auto6775C45A_ai;
    int auto12EF4BF9_ae;
    int auto12EF4BF9_ai;

    // Variable Declarations
    int lv_townIndex;
    int lv_structureIndex;

    // Variable Initialization

    // Implementation
    auto6775C45A_ae = libGame_gv_townTownCount;
    auto6775C45A_ai = 1;
    lv_townIndex = 1;
    for ( ; ( (auto6775C45A_ai >= 0 && lv_townIndex <= auto6775C45A_ae) || (auto6775C45A_ai <= 0 && lv_townIndex >= auto6775C45A_ae) ) ; lv_townIndex += auto6775C45A_ai ) {
        auto12EF4BF9_ae = libGame_gv_townTownData[lv_townIndex].lv_structureCount;
        auto12EF4BF9_ai = 1;
        lv_structureIndex = 1;
        for ( ; ( (auto12EF4BF9_ai >= 0 && lv_structureIndex <= auto12EF4BF9_ae) || (auto12EF4BF9_ai <= 0 && lv_structureIndex >= auto12EF4BF9_ae) ) ; lv_structureIndex += auto12EF4BF9_ai ) {
            if ((UnitIsValid(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]) == true) && ((libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 5) || (libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 1))) {
                libAIAI_gf_HeroAISetupUnitDangerTracking(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]);
            }
            else {
            }
        }
    }
    libAIAI_gf_HeroAIUpdateFrontTower(0);
    libAIAI_gf_HeroAIUpdateFrontTower(1);
}

void libAIAI_gf_HeroAITakeOverHeroForPlayer (int lp_player) {
    // Variable Declarations
    int lv_enemyFaction;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        lv_enemyFaction = 1;
    }
    else {
        lv_enemyFaction = 0;
    }
    if ((libAIAI_gf_HeroAITeamHasHumanPlayers(lv_enemyFaction) == true)) {
        libAIAI_gf_HeroAISetAIDifficultyLevel(lp_player, 12);
    }
    else {
        libAIAI_gf_HeroAISetAIDifficultyLevel(lp_player, 12);
    }
    if ((libGame_gv_players[lp_player].lv_heroUnit == null)) {
        return ;
    }
    else {
        libUIUI_gf_UIUnitStatusFramesShowHideBotLabel(lp_player, true);
        libAIAI_gf_HeroAIEnableAIForPlayer(lp_player);
    }
}

void libAIAI_gf_HeroAIReleaseHeroControl (int lp_player) {
    // Variable Declarations
    int lv_enemyFaction;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_player].lv_heroUnit != null)) {
        libUIUI_gf_UIUnitStatusFramesShowHideBotLabel(lp_player, false);
        libAIAI_gf_HeroAIDisableAIForPlayer(lp_player);
    }
    else {
    }
}

void libAIAI_gf_HeroAINotifyHeroDamaged (int lp_trigPlayer, unit lp_damagingUnit) {
    int auto9FE443AF_val;

    // Variable Declarations
    fixed lv_distance;
    fixed lv_weaponRange;
    fixed lv_delayTime;

    // Variable Initialization

    // Implementation
    lv_delayTime = libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty];
    auto9FE443AF_val = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState;
    if (auto9FE443AF_val == 12) {
        if ((libAIAI_gf_HeroAIShouldRetreatFromAttacker(lp_trigPlayer) == false)) {
            return ;
        }
        else {
        }
        lv_weaponRange = libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
        lv_distance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_damagingUnit));
        if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) && (libNtve_gf_RandomPercent() < libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[(libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_difficulty)]) && (UnitTypeTestAttribute(UnitGetType(lp_damagingUnit), c_unitAttributeHeroic) == true) && (lv_distance <= (lv_weaponRange + 2.0))) {
            libAIAI_gf_HeroAIStartMinionBattleHarass(lp_trigPlayer, lp_damagingUnit);
        }
        else {
            if ((UnitTypeTestAttribute(UnitGetType(lp_damagingUnit), c_unitAttributeHeroic) == true)) {
                Wait(lv_delayTime, c_timeGame);
            }
            else {
            }
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 12) && (libAIAI_gf_HeroAITimeInCurrentState(lp_trigPlayer) > lv_delayTime)) {
                libAIAI_gf_HeroAIStartMinionBattleRetreat(lp_trigPlayer);
            }
            else {
            }
        }
    }
    else if (auto9FE443AF_val == 7) {
        if ((libAIAI_gf_HeroAIShouldRetreatFromAttacker(lp_trigPlayer) == false)) {
            return ;
        }
        else {
        }
        if ((UnitTypeTestAttribute(UnitGetType(lp_damagingUnit), c_unitAttributeHeroic) == true)) {
            Wait(lv_delayTime, c_timeGame);
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 7) && (libAIAI_gf_HeroAITimeInCurrentState(lp_trigPlayer) > lv_delayTime)) {
            libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        }
        else {
        }
    }
    else {
    }
}

int libAIAI_gf_HeroAIGetCurrentPriority (int lp_trigPlayer) {
    int autoBDA26B67_val;

    // Variable Declarations
    int lv_currentObjective;
    point lv_contentionPoint;
    region lv_nearbyRegion;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allyHeroes;
    point lv_campPosition;
    order lv_heroOrder;

    // Variable Initialization
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    lv_currentObjective = libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 0)) {
        return 0;
    }
    else {
    }
    if (((libGame_gv_players[lp_trigPlayer].lv_isDead == true) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 2))) {
        return 0;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_trigPlayer) == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < 95.0)) {
        return 0;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 9)) {
        return 0;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 13) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 46))) {
        return 0;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 31)) {
        return 0;
    }
    else {
    }
    autoBDA26B67_val = lv_currentObjective;
    if (autoBDA26B67_val == 0) {
        if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) {
            return 0;
        }
        else {
        }
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero) == true)) {
            return 0;
        }
        else {
        }
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell) == true)) {
            return 0;
        }
        else {
        }
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe) == true)) {
            return 0;
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0) && (libAIAI_gf_HeroAIIsPlayerInsideEnemyBase(lp_trigPlayer) == true) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyTowns == 0)) {
            return 5;
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane > 0)) {
            lv_contentionPoint = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane].lv_contentionPoint;
            if ((libCore_gf_TestLocationClosertoFactionSide(lv_contentionPoint, libGame_gv_players[lp_trigPlayer].lv_faction, 0.65) == true)) {
                return 8;
            }
            else {
            }
        }
        else {
        }
        lv_nearbyRegion = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 14.0);
        lv_allyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        lv_enemyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        if ((libCore_gf_TestLocationClosertoFactionSide(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libGame_gv_players[lp_trigPlayer].lv_faction, 1.0) == false) && (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) >= 4)) {
            return 14;
        }
        else {
        }
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) >= 2) && (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) >= 2)) {
            return 15;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIIsPlayerDefendingTown(lp_trigPlayer) == true)) {
            return 16;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIIsPlayerAttackingTown(lp_trigPlayer) == true)) {
            return 17;
        }
        else {
        }
        if ((libAIAI_gv_heroAIRavenLordCurseStatus.lv_curseActive == true)) {
            return 18;
        }
        else {
        }
        if (((libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state == 1) || (libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state == 2) || (libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state == 1) || (libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state == 2))) {
            return 19;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIInLaneWithAllyMercs(lp_trigPlayer) == true)) {
            return 20;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIInLaneWithEnemyMercs(lp_trigPlayer) == true)) {
            return 21;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIIsNearActiveObelisk(lp_trigPlayer) == true)) {
            return 22;
        }
        else {
        }
        if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 10) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 11) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 13) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 12))) {
            return 27;
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane)) {
            return 28;
        }
        else {
        }
        return 30;
    }
    else if (autoBDA26B67_val == 1) {
        return 2;
    }
    else if (autoBDA26B67_val == 2) {
        if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
            return 0;
        }
        else {
        }
        return 12;
    }
    else if (autoBDA26B67_val == 3) {
        return 6;
    }
    else if (autoBDA26B67_val == 4) {
        lv_campPosition = libMapM_gv_jungleCreepCamps[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp].lv_mapDataCampCaptainSpawnPoint;
        libAIAI_gf_HeroAIEval(lp_trigPlayer);
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campPosition) <= libAIAI_gv_aIHeroLeashDistance) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval == 0.0) && (libMapM_gv_jungleCreepCamps[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp].lv_captureCaptureEnabled == true)) {
            return 0;
        }
        else {
        }
        if ((((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campPosition) <= libAIAI_gv_aIHeroLeashDistance) && (libAIAI_gf_HeroAICampEval(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp) < libAIAI_gv_aIHeroHighCampEval)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 42) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 43))) {
            return 7;
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting > 0)) {
            return 10;
        }
        else {
        }
        return 24;
    }
    else if (autoBDA26B67_val == 5) {
        return 29;
    }
    else if (autoBDA26B67_val == 6) {
        lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) <= 6.0) && (lv_heroOrder != null) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("CaptureMacGuffin", 0))) {
            return 0;
        }
        else {
        }
        return 9;
    }
    else if (autoBDA26B67_val == 8) {
        lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit)) <= 6.0) && (lv_heroOrder != null) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("CaptureMacGuffin", 0))) {
            return 0;
        }
        else {
        }
        return 23;
    }
    else if (autoBDA26B67_val == 9) {
        return 4;
    }
    else if (autoBDA26B67_val == 7) {
        return 13;
    }
    else if (autoBDA26B67_val == 10) {
        if ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == true)) {
            return 1;
        }
        else {
            return 11;
        }
    }
    else if (autoBDA26B67_val == 11) {
        return 26;
    }
    else if (autoBDA26B67_val == 12) {
        return 3;
    }
    else {
        return 30;
    }
}

int libAIAI_gf_HeroAIGetCurrentObjective (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToWaitInSpawn == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp > 0)) {
        return 4;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToUseAbathurLogic == true)) {
        return 12;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune == true)) {
        return 6;
    }
    else {
    }
    if (((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == true) || (UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true))) {
        return 2;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToDefendCore == true)) {
        return 3;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetWatchTower > 0)) {
        return 5;
    }
    else {
    }
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk) == true)) {
        return 7;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls == true)) {
        return 10;
    }
    else {
    }
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest) == true)) {
        return 11;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer > 0)) {
        return 9;
    }
    else {
    }
    return 0;
}

bool libAIAI_gf_HeroAIIsHigherPriority (int lp_trigPlayer, int lp_priority) {
    // Variable Declarations
    int lv_currentPriority;

    // Variable Initialization

    // Implementation
    lv_currentPriority = libAIAI_gf_HeroAIGetCurrentPriority(lp_trigPlayer);
    return ((lp_priority) < (lv_currentPriority));
}

void libAIAI_gf_HeroAILeaveCurrentObjective (int lp_trigPlayer) {
    int auto516C8740_val;

    // Variable Declarations
    int lv_currentObjective;

    // Variable Initialization

    // Implementation
    lv_currentObjective = libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer);
    auto516C8740_val = lv_currentObjective;
    if (auto516C8740_val == 0) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe = null;
    }
    else if (auto516C8740_val == 1) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToWaitInSpawn = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    }
    else if (auto516C8740_val == 2) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
    }
    else if (auto516C8740_val == 3) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToDefendCore = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    }
    else if (auto516C8740_val == 4) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    }
    else if (auto516C8740_val == 5) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetWatchTower = 0;
    }
    else if (auto516C8740_val == 6) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    }
    else if (auto516C8740_val == 8) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    }
    else if (auto516C8740_val == 9) {
    }
    else if (auto516C8740_val == 7) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk = null;
    }
    else if (auto516C8740_val == 10) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldEntrance = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit = null;
    }
    else if (auto516C8740_val == 11) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest = null;
    }
    else if (auto516C8740_val == 12) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToUseAbathurLogic = false;
    }
    else {
    }
    if ((libGame_gv_players[lp_trigPlayer].lv_isDead == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 1);
    }
    else {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
}

void libAIAI_gf_HeroAIReturnToCurrentObjective (int lp_trigPlayer) {
    int auto3C6E12D4_val;

    // Variable Declarations
    int lv_currentObjective;
    point lv_corePosition;
    point lv_campLocation;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    lv_currentObjective = libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer);
    auto3C6E12D4_val = lv_currentObjective;
    if (auto3C6E12D4_val == 0) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0)) {
            libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        }
        else {
            libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        }
    }
    else if (auto3C6E12D4_val == 1) {
        if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_trigPlayer) == true)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 6);
        }
        else {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0)) {
                libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
            }
            else {
                libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
            }
        }
    }
    else if (auto3C6E12D4_val == 2) {
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue)) < libAIAI_gv_aIHeroFarFromDragonStatueDistance)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 54);
        }
        else {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 51);
        }
    }
    else if (auto3C6E12D4_val == 3) {
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_corePosition) < libAIAI_gv_aIHeroFarFromCoreDistance)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 20);
        }
        else {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
            libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        }
    }
    else if (auto3C6E12D4_val == 4) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 38);
    }
    else if (auto3C6E12D4_val == 5) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 24);
    }
    else if (auto3C6E12D4_val == 6) {
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) < libAIAI_gv_aIHeroFarFromTearOfEluneDistance)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 29);
        }
        else {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 27);
        }
    }
    else if (auto3C6E12D4_val == 7) {
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk)) < libAIAI_gv_aIHeroFarFromObeliskDistance)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 49);
        }
        else {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 48);
        }
    }
    else if (auto3C6E12D4_val == 8) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 32);
    }
    else if (auto3C6E12D4_val == 9) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 55);
    }
    else if (auto3C6E12D4_val == 10) {
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldEntrance) == true)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 57);
        }
        else {
            if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit) == true)) {
                libAIAI_gf_HeroAIUpdateUnderworldExitTargetPosition(lp_trigPlayer);
                libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 61);
            }
            else {
                libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 58);
            }
        }
    }
    else if (auto3C6E12D4_val == 11) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 34);
    }
    else if (auto3C6E12D4_val == 12) {
        if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_trigPlayer) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane;
            libAIAI_gf_HeroAIStartAbathurAdvanceLane(lp_trigPlayer);
        }
        else {
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0)) {
                libAIAI_gf_HeroAIStartAbathurRetreatLane(lp_trigPlayer);
            }
            else {
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
                libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
            }
        }
    }
    else {
    }
}

int libAIAI_gf_HeroAIDead (int lp_trigPlayer) {
    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_isDead == false)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaveSpawnTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroExtraWaitAfterRespawn[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]);
        libAIAI_gf_HeroAIStartWaitToHeal(lp_trigPlayer);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIAfterDeathAttack (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_bestTarget;

    // Variable Initialization

    // Implementation
    lv_bestTarget = libAIAI_gf_HeroAIAfterDeathAttackChooseTarget(lp_trigPlayer);
    if ((UnitIsValid(lv_bestTarget) == false)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, lv_bestTarget) == true)) {
        return 8;
    }
    else {
    }
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_bestTarget), c_orderQueueReplace);
    return 8;
}

int libAIAI_gf_HeroAIReturnToSpawn (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libGame_gv_players[lp_trigPlayer].lv_spawnPoint) < libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIStartWaitToHeal(lp_trigPlayer);
        return 1;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libGame_gv_players[lp_trigPlayer].lv_spawnPoint) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libGame_gv_players[lp_trigPlayer].lv_spawnPoint), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIWaitForGameToStart (int lp_trigPlayer) {
    // Variable Declarations
    int lv_startingLane;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIHasGameStarted() == true)) {
        lv_startingLane = libAIAI_gf_HeroAIChooseLaneLogic(lp_trigPlayer);
        libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_startingLane);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane;
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextWaitForGameToStartRepositionTime < TimerGetElapsed(libGame_gv_totalTime))) {
        libAIAI_gf_HeroAIChooseWaitForGameToStartPosition(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextWaitForGameToStartRepositionTime = (TimerGetElapsed(libGame_gv_totalTime) + libAIAI_gv_aIHeroWaitForGameToStartRepositionFrequency + RandomFixed(-1.0, 1.0));
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_waitForGameToStartPosition) > 0.5) && ((lv_heroOrder == null) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("move", 0)) && (lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_waitForGameToStartPosition) > 0.5)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_waitForGameToStartPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIWaitToHeal (int lp_trigPlayer) {
    // Variable Declarations
    int lv_desiredLane;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < 95.0)) {
        if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_trigPlayer) == false)) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libGame_gv_players[lp_trigPlayer].lv_spawnPoint), c_orderQueueReplace);
        }
        else {
        }
        return 1;
    }
    else {
    }
    if ((TimerGetElapsed(libGame_gv_gameTimer) < libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaveSpawnTime)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane <= 0)) {
        lv_desiredLane = libAIAI_gf_HeroAIChooseLaneLogic(lp_trigPlayer);
        libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_desiredLane);
    }
    else {
    }
    libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
    return 1;
}

int libAIAI_gf_HeroAIAdvanceInLane (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldRetreatLane(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangingLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((DistanceBetweenPoints(libGame_gv_players[lp_trigPlayer].lv_spawnPoint, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) > 30.0) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroClosestLanePoint) > libAIAI_gv_aIHeroLaneLeashDistance)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldEnterMinionBattle(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartMinionBattleAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldWaitForMinions(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartWaitForMinions(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextLaneOffsetChangeTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIChangeLaneOffset(lp_trigPlayer, libAIAI_gf_HeroAIChooseNewLaneOffset(lp_trigPlayer, libAIAI_gf_HeroAIAllyHeroesinArea(lp_trigPlayer, libAIAI_gv_aIHeroAvoidAllyHeroesSearchRadius)));
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextLaneOffsetChangeTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroAdvanceChangeLaneOffsetFrequency);
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassSiegeEnemyLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangeTarget(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAttackingWeakHumanHero(lp_trigPlayer, 50.0) == true)) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIAggroEnemyCore(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHealthGlobeLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIAttackingBadTarget(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
    }
    else {
    }
    if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIRetreatInLane (int lp_trigPlayer) {
    // Variable Declarations
    region lv_homeRegion;
    fixed lv_heroToHomeDistance;
    fixed lv_retreatPositionToHomeDistance;
    point lv_retreatPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;
    unitgroup lv_heroesToAvoid;

    // Variable Initialization
    lv_heroesToAvoid = UnitGroupEmpty();

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsSafeLane(lp_trigPlayer) == true)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInLaneRetreating == false)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInLaneRetreating = true;
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInLaneStartTime = TimerGetElapsed(libGame_gv_gameTimer);
        }
        else {
        }
        if ((libAIAI_gf_HeroAISafeWhileRetreatingInLaneLogic(lp_trigPlayer) == true)) {
            return 8;
        }
        else {
        }
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInLaneRetreating = false;
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextLaneOffsetChangeTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        lv_heroesToAvoid = libAIAI_gf_HeroAIGetEnemyHeroesInRetreatPath(lp_trigPlayer);
        if ((UnitGroupCount(lv_heroesToAvoid, c_unitCountAlive) == 0)) {
            lv_heroesToAvoid = libAIAI_gf_HeroAIAllyHeroesinArea(lp_trigPlayer, libAIAI_gv_aIHeroAvoidAllyHeroesSearchRadius);
        }
        else {
        }
        libAIAI_gf_HeroAIChangeLaneOffset(lp_trigPlayer, libAIAI_gf_HeroAIChooseNewLaneOffset(lp_trigPlayer, lv_heroesToAvoid));
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextLaneOffsetChangeTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroRetreatChangeLaneOffsetFrequency);
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((DistanceBetweenPoints(libGame_gv_players[lp_trigPlayer].lv_spawnPoint, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) > 30.0) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroClosestLanePoint) > libAIAI_gv_aIHeroLaneLeashDistance)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || (UnitOrderIsValid(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_heroOrder) == false) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAvoidAOE (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if (((TimerGetElapsed(libGame_gv_gameTimer) > libAIAI_gv_aIHeroes[lp_trigPlayer].lv_avoidAOETimeout) || ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])))) {
        libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIHarassSiegeEnemy (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    unit lv_lastAttacker;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    lv_lastAttacker = libAIAI_gv_heroAIDamageTracking[lp_trigPlayer].lv_lastAttacker;
    if (((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0)) || (UnitIsAlive(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget) == false) || (libAIAI_gf_AIGetActiveWeaponRange(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget) < libAIAI_gv_aIHeroSiegeEnemyMinWeaponRange) || (libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget), libAIAI_gv_aIHeroCloseToSiegeEnemyDistance, true, true, true) > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval + 100.0)) || ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true) && (UnitTypeTestAttribute(UnitGetType(lv_lastAttacker), c_unitAttributeHeroic) == true) && (lv_lastAttacker != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget)))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget = null;
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIWaitForMinions (int lp_trigPlayer) {
    // Variable Declarations
    point lv_contentionPoint;
    fixed lv_frontTowerPosition;
    fixed lv_frontMinionPosition;
    fixed lv_contentionPointLanePosition;
    bool lv_allyMinionsHaveArrived;
    fixed lv_laneOffset;
    fixed lv_distanceBehindContentionPoint;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if (((libAIAI_gf_HeroAIShouldRetreatLane(lp_trigPlayer) == true) || (libAIAI_gf_HeroAIShouldRetreatFromAttacker(lp_trigPlayer) == true))) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_contentionPoint = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPoint;
    lv_frontMinionPosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontMinionPosition;
    lv_contentionPointLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPointLanePosition;
    if (((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_contentionPoint) > 10.0) || (lv_contentionPointLanePosition == lv_frontMinionPosition) || (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyHeroesNearContentionPoint > 0) || (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyMinionsNearContentionPoint > 0))) {
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassSiegeEnemyLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextWaitingRepositionTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIChooseNewWaitingPosition(lp_trigPlayer);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIReturnToLane (int lp_trigPlayer) {
    // Variable Declarations
    int lv_targetLane;
    int lv_closestLane;
    point lv_closestPointToLane;
    point lv_campLoc;
    int lv_closestIndex;
    int lv_secondaryIndex;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_targetLane = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_returnToLaneLane;
    libGame_gf_CalculateClosestLaneDataForLane(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_targetLane);
    lv_closestPointToLane = libGame_gv_closestLaneData.lv_laneData[lv_targetLane].lv_closestPoint;
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_closestPointToLane) <= libAIAI_gv_aIHeroCloseToLaneDistance)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = lv_targetLane;
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatJungle(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPickUpHealthGlobeJungleLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateJungleTargetPosition(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_returnToLanePosition);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || (UnitOrderIsValid(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_heroOrder) == false) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) > 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIPickUpHealthGlobeJungle (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe)) > 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe)), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIFocusHero (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_hero;
    fixed lv_targetEval;
    fixed lv_bestTargetEval;
    unit lv_bestTarget;
    int lv_closestIndex;
    int lv_secondaryIndex;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization
    lv_bestTargetEval = 524287.0;

    // Implementation
    if ((UnitIsAlive(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero) == false)) {
        lv_bestTarget = libAIAI_gf_HeroAIFindBestFocusHeroTarget(lp_trigPlayer);
        if ((lv_bestTarget != null)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = lv_bestTarget;
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition = null;
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero), c_orderQueueReplace);
            return 8;
        }
        else {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = null;
            if ((libAIAI_gf_HeroAIIsSafeLane(lp_trigPlayer) == true)) {
                libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
            }
            else {
                libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
            }
            return 8;
        }
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldGiveUpOnFocusHero(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = null;
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libNtve_gf_UnitIsVisibleToPlayer(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, lp_trigPlayer) == false)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition == null)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero);
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
        }
        else {
        }
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition = null;
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((lv_heroOrder == null) && (libNtve_gf_UnitIsVisibleToPlayer(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, lp_trigPlayer) == false) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition) < 1.0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = null;
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextFocusHeroCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroDelayAfterGivingUp);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero = null;
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIInWeaponRangeOfTarget(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, 1.0) == true) && (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero), 1.0) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition != null)) {
        lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
        if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition) >= 1.0)))) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHeroCheckPosition), c_orderQueueReplace);
        }
        else {
        }
    }
    else {
        if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("move", 0)) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero)))) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero), c_orderQueueReplace);
        }
        else {
        }
    }
    return 8;
}

int libAIAI_gf_HeroAIFocusCore (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_enemyCore;
    unit lv_hero;
    fixed lv_targetEval;
    fixed lv_bestTargetEval;
    unit lv_bestTarget;
    int lv_closestIndex;
    int lv_secondaryIndex;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization
    lv_bestTargetEval = 524287.0;

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_enemyCore = libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core;
    }
    else {
        lv_enemyCore = libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core;
    }
    if ((libAIAI_gf_HeroAIShouldGiveUpOnFocusCore(lp_trigPlayer, lv_enemyCore) == true)) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, lv_enemyCore) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, UnitGetPosition(lv_enemyCore)) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_enemyCore), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITeleportHomeLane (int lp_trigPlayer) {
    unitgroup auto09A62E51_g;
    int auto09A62E51_u;

    // Variable Declarations
    region lv_homeRegion;
    unit lv_allyHero;
    unitgroup lv_nearbyAllyHeroes;
    playergroup lv_nearbyAllyPlayers;

    // Variable Initialization
    lv_nearbyAllyHeroes = UnitGroupEmpty();
    lv_nearbyAllyPlayers = PlayerGroupEmpty();

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((libNtve_gf_UnitInRegion(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_homeRegion) == false) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_announcedRetreat == false)) {
        lv_nearbyAllyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 15.0), UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        auto09A62E51_g = lv_nearbyAllyHeroes;
        auto09A62E51_u = 1;
        for ( ; auto09A62E51_u <= UnitGroupCount(auto09A62E51_g, c_unitCountAll) ; auto09A62E51_u += BoolToInt(lv_allyHero == UnitGroupUnit(auto09A62E51_g, auto09A62E51_u)) ) {
            lv_allyHero = UnitGroupUnit(auto09A62E51_g, auto09A62E51_u);
            PlayerGroupAdd(lv_nearbyAllyPlayers, UnitGetOwner(lv_allyHero));
        }
        libSond_gf_HeroVOPlayHeroLine(9, lp_trigPlayer, lv_nearbyAllyPlayers);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_announcedRetreat = true;
    }
    else {
    }
    if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 3);
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsSafeLane(lp_trigPlayer) == false)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 8);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("PortBackToBase", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("PortBackToBase", 0)), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIDrinkMoonwell (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_currentHealthPercent;
    order lv_order;

    // Variable Initialization

    // Implementation
    lv_currentHealthPercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if (((lv_currentHealthPercent >= 99.0) || (UnitHasBehavior2(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "HealingFountainCooldown") == true) || (UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell) == false) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("FountainDrink", 0)))) {
        lv_order = OrderTargetingUnit(AbilityCommand("FountainDrink", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_order, c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIFleeInJungle (int lp_trigPlayer) {
    // Variable Declarations
    region lv_homeRegion;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 3);
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsSafeJungle(lp_trigPlayer) == true)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInJungleRetreating == false)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInJungleRetreating = true;
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInJungleStartTime = TimerGetElapsed(libGame_gv_gameTimer);
        }
        else {
        }
        if ((libAIAI_gf_HeroAISafeWhileRetreatingInJungleLogic(lp_trigPlayer) == true)) {
            return 8;
        }
        else {
        }
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInJungleRetreating = false;
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateJungleTargetPosition(lp_trigPlayer, libGame_gv_players[lp_trigPlayer].lv_spawnPoint);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || (UnitOrderIsValid(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_heroOrder) == false) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) > libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITeleportHomeJungle (int lp_trigPlayer) {
    // Variable Declarations
    region lv_homeRegion;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 3);
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsSafeJungle(lp_trigPlayer) == false)) {
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("PortBackToBase", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("PortBackToBase", 0)), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIHarassInJungle (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if (((UnitIsAlive(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget) == false) || ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] + 10.0))) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTimeout < TimerGetElapsed(libGame_gv_gameTimer)))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget = null;
        libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIPaceAround (int lp_trigPlayer) {
    // Variable Declarations
    point lv_pacePosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_paceAroundTimeout < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextPaceAroundRepositionTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextPaceAroundRepositionTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroPaceAroundRepositionFrequency);
        lv_pacePosition = RegionRandomPoint(RegionCircle(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_paceAroundStartPosition, libAIAI_gv_aIHeroPaceAroundRadius));
        UnitBehaviorAdd(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "TemporarilyHoldFire", libGame_gv_players[lp_trigPlayer].lv_heroUnit, 1);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_pacePosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIWaitInSpawn (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_shouldWaitInSpawn == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToWaitInSpawn = false;
        libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
        return 1;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libGame_gv_players[lp_trigPlayer].lv_spawnPoint) > 0.5) && ((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libGame_gv_players[lp_trigPlayer].lv_spawnPoint) > 0.5)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libGame_gv_players[lp_trigPlayer].lv_spawnPoint), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAICaptureWatchTower (int lp_trigPlayer) {
    // Variable Declarations
    int lv_team;
    order lv_heroOrder;
    unit lv_watchTower;
    point lv_watchTowerLocation;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_team = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_team = libCore_gv_cOMPUTER_TeamChaos;
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    lv_watchTower = libGame_gv_watchTowers[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetWatchTower].lv_watchTowerUnit;
    if (((lv_team == UnitGetOwner(lv_watchTower)) || (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes, c_unitCountAlive) > 0) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 3.0) == true))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetWatchTower = 0;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_watchTowerLocation = UnitGetPosition(lv_watchTower);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_watchTowerLocation) > libCore_gv_data_WatchTower_CaptureRadius_C)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_watchTowerLocation), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIVehicleReturnToLane (int lp_trigPlayer) {
    // Variable Declarations
    int lv_targetLane;
    int lv_closestLane;
    point lv_closestPointToLane;
    point lv_campLoc;
    int lv_closestIndex;
    int lv_secondaryIndex;
    order lv_vehicleOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_targetLane = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_returnToLaneLane;
    libGame_gf_CalculateClosestLaneDataForLane(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle), lv_targetLane);
    lv_closestPointToLane = libGame_gv_closestLaneData.lv_laneData[lv_targetLane].lv_closestPoint;
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle), lv_closestPointToLane) <= libAIAI_gv_aIHeroCloseToLaneDistance)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = lv_targetLane;
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateJungleTargetPosition(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_returnToLanePosition);
    }
    else {
    }
    lv_vehicleOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_vehicleOrder);
    if (((lv_vehicleOrder == null) || (UnitOrderIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, lv_vehicleOrder) == false) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition) > 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIVehicleAdvanceInLane (int lp_trigPlayer) {
    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == false)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangeTarget(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIAggroEnemyCore(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIAdvanceWaypoint(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneOffset);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, 0) == null)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointPoint), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDefendCoreAttack (int lp_trigPlayer) {
    // Variable Declarations
    point lv_corePosition;
    order lv_currentOrder;
    unit lv_currentTarget;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_corePosition) > libAIAI_gv_aIHeroFarFromCoreDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 21);
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_currentTarget = libAIAI_gf_HeroAIDefendCoreChooseTarget(lp_trigPlayer, libAIAI_gv_aIHeroCloseToCoreDistance);
    if ((UnitIsValid(lv_currentTarget) == false)) {
        lv_currentTarget = libAIAI_gf_HeroAIDefendCoreChooseTarget(lp_trigPlayer, libAIAI_gv_aIHeroFarFromCoreDistance);
        if ((UnitIsValid(lv_currentTarget) == false)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToDefendCore = false;
            libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
            return 8;
        }
        else {
        }
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer))) {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
        if ((libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, lv_currentTarget) == true)) {
            return 8;
        }
        else {
        }
    }
    else {
    }
    lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((lv_currentOrder == null)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_currentTarget), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDefendCoreLeash (int lp_trigPlayer) {
    // Variable Declarations
    point lv_corePosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroCloseToCoreDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 20);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_corePosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_corePosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIMinionBattleRetreat (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_laneOffset;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIMinionBattleFinished(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangingLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsSafeLane(lp_trigPlayer) == true) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRetreatTimeout < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIStartMinionBattleReposition(lp_trigPlayer);
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIMinionBattleReposition (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_laneOffset;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIMinionBattleFinished(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangingLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if (((libAIAI_gf_HeroAIShouldRetreatLane(lp_trigPlayer) == true) || (libAIAI_gf_HeroAIShouldRetreatFromAttacker(lp_trigPlayer) == true))) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextMinionBattleAttackTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIStartMinionBattleAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextMinionBattleRepositionRecalculateTime <= TimerGetElapsed(libGame_gv_gameTimer)) || (lv_heroOrder == null))) {
        libAIAI_gf_HeroAIUpdateMinionBattleRepositionPosition(lp_trigPlayer);
    }
    else {
    }
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIMinionBattleAttack (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_lastAttacker;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMinionBattleFinished(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatLane(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleAttackTimeout < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIStartMinionBattleRetreat(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassSiegeEnemyLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAILaneChangeTarget(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
    }
    else {
    }
    if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIMinionBattleHarass (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldRetreatLane(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleHarassTimeout < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleHarassTarget)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleHarassTarget), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIMinionCampInit (int lp_trigPlayer) {
    // Variable Declarations
    point lv_campLoc;
    region lv_homeRegion;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    lv_campLoc = libMapM_gv_jungleCreepCamps[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp].lv_mapDataCampCaptainSpawnPoint;
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) < (libAIAI_gv_aIHeroHeadStraightToCampDist + 5.0)) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > 60.0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = 0;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 38);
        return 8;
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0)) {
            libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
            return 8;
        }
        else {
            libAIAI_gf_HeroAIStartRetreatLane(lp_trigPlayer);
            return 8;
        }
    }
}

int libAIAI_gf_HeroAIMoveToCamp (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    bool lv_allDefendersKilled;
    bool lv_campCaptured;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_allDefendersKilled = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_captureCaptureEnabled;
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatJungle(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIMountLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) <= libAIAI_gv_aIHeroNearCampDistance)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_arrivedAtCampTime <= 0.0)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_arrivedAtCampTime = TimerGetElapsed(libGame_gv_gameTimer);
        }
        else {
        }
        if ((lv_allDefendersKilled == true)) {
            libAIAI_gf_HeroAIStartCaptureCampBeacon(lp_trigPlayer);
            return 8;
        }
        else {
            if ((libAIAI_gf_HeroAIShouldInitiateCamp(lp_trigPlayer) == true)) {
                libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 40);
                return 8;
            }
            else {
                libAIAI_gf_HeroAIStartWaitAtCamp(lp_trigPlayer);
                return 8;
            }
        }
    }
    else {
    }
    if ((lv_allDefendersKilled == false) && (TimerGetElapsed(libGame_gv_gameTimer) > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_moveToCampStartTime + libAIAI_gv_aIHeroMoveToCampTimeout))) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_campLoc) >= libAIAI_gv_aIHeroCampCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_campLoc), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIWaitAtCamp (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    bool lv_campCaptured;
    point lv_humanPlayerAssistingLocation;
    int lv_humanPlayerAssistingDistance;
    point lv_standPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldDefendCamp(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 42);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldInitiateCamp(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 40);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting > 0) && (libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == true)) {
    }
    else {
        if ((TimerGetElapsed(libGame_gv_gameTimer) >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_arrivedAtCampTime + libAIAI_gv_aIHeroCampWaitTimeout[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) {
            libAIAI_gf_HeroAICancelCampAttack(lv_campIndex, libGame_gv_players[lp_trigPlayer].lv_faction);
            return 8;
        }
        else {
        }
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting > 0) && (libAIAI_gf_HeroAIAllRecruitedAIHaveArrivedAtCamp(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp) == true)) {
            lv_humanPlayerAssistingLocation = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting].lv_heroUnit);
            lv_humanPlayerAssistingDistance = PointPathingCost(lv_humanPlayerAssistingLocation, lv_campLoc);
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssistingDistance == -1)) {
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssistingDistance = lv_humanPlayerAssistingDistance;
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextHumanPlayerAssistingDistanceCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroHumanPlayerAssistingCheckFrequency);
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_cancelCampAttackCounter = 0;
                return 8;
            }
            else {
            }
            if ((lv_humanPlayerAssistingDistance != -1) && (TimerGetElapsed(libGame_gv_gameTimer) >= libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextHumanPlayerAssistingDistanceCheckTime)) {
                if ((lv_humanPlayerAssistingDistance < libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssistingDistance)) {
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_cancelCampAttackCounter = 0;
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssistingDistance = lv_humanPlayerAssistingDistance;
                }
                else {
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_cancelCampAttackCounter += 1;
                }
                if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_cancelCampAttackCounter > 2)) {
                    libAIAI_gf_HeroAICancelCampAttack(lv_campIndex, libGame_gv_players[lp_trigPlayer].lv_faction);
                    return 8;
                }
                else {
                }
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextHumanPlayerAssistingDistanceCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroHumanPlayerAssistingCheckFrequency);
            }
            else {
            }
        }
        else {
        }
    }
    lv_standPosition = libAIAI_gf_HeroAIChooseCampGuardPosition(lp_trigPlayer);
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_standPosition) >= libAIAI_gv_aIHeroCampCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_standPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAttackSoloCamp (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    bool lv_allDefendersKilled;
    bool lv_campCaptured;
    unit lv_bestTarget;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_allDefendersKilled = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_captureCaptureEnabled;
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldDefendCamp(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 42);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatJungle(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) > libAIAI_gv_aIHeroLeashDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 38);
        return 8;
    }
    else {
    }
    if ((lv_allDefendersKilled == true) && (lv_campCaptured == false)) {
        libAIAI_gf_HeroAIStartCaptureCampBeacon(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_bestTarget = libAIAI_gf_HeroAIAttackCampChooseTarget(lp_trigPlayer);
    if ((lv_bestTarget == null)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, lv_bestTarget) == true)) {
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetTargetUnit(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != lv_bestTarget))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_bestTarget), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAICaptureCampBeacon (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    bool lv_campCaptured;
    point lv_standPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldDefendCamp(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 42);
        return 8;
    }
    else {
    }
    lv_standPosition = libAIAI_gf_HeroAIChooseCampCaptureStandPosition(lp_trigPlayer);
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_standPosition) >= libAIAI_gv_aIHeroCampCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_standPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDefendCampAttack (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    bool lv_campCaptured;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_campCaptured = ((UnitGroupCount(libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex), c_unitCountAlive) <= 0) && !(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_captureCaptureEnabled));
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroStopCampAttackPercent)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) > libAIAI_gv_aIHeroFarFromCampDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 43);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, lv_campLoc, libAIAI_gv_aIHeroFarFromCampDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 38);
    return 8;
}

int libAIAI_gf_HeroAIDefendCampLeash (int lp_trigPlayer) {
    // Variable Declarations
    point lv_campLoc;
    int lv_campIndex;
    bool lv_campCaptured;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_campCaptured = ((UnitGroupCount(libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex), c_unitCountAlive) <= 0) && !(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_captureCaptureEnabled));
    if ((lv_campCaptured == true)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldCancelCampAttack(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAICancelCampAttack(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libGame_gv_players[lp_trigPlayer].lv_faction);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroStopCampAttackPercent)) {
        libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) <= libAIAI_gv_aIHeroCampCloseEnoughDist)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 42);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_campLoc) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_campLoc), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIFollowerGuardLeader (int lp_trigPlayer) {
    // Variable Declarations
    point lv_leaderPosition;
    order lv_heroOrder;
    order lv_leaderOrder;

    // Variable Initialization

    // Implementation
    lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer].lv_heroUnit);
    if ((libAIAI_gf_HeroAIShouldStopFollowingLeader(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 45);
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_leaderPosition) > libAIAI_gv_aIHeroFollowerLeashDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 56);
        return 8;
    }
    else {
    }
    libGame_gf_CalculateClosestLaneData(lv_leaderPosition);
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((libGame_gv_closestLaneData.lv_laneData[libGame_gv_closestLaneData.lv_closestLane].lv_closestDist < libAIAI_gv_aIHeroLaneLeashDistance) && ((UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyMinionsSummons, c_unitCountAlive) > 0) || (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes, c_unitCountAlive) > 0))) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_leaderOrder = UnitOrder(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer].lv_heroUnit, 0);
    if ((lv_leaderOrder != null) && (OrderGetTargetUnit(lv_leaderOrder) != null) && (libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(OrderGetTargetUnit(lv_leaderOrder)), 4) == true)) {
        if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
            return 1;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, OrderGetTargetUnit(lv_leaderOrder)) == true)) {
            return 8;
        }
        else {
        }
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), OrderGetTargetUnit(lv_leaderOrder)), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("move", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_leaderPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIFollowerGuardLeaderLeash (int lp_trigPlayer) {
    // Variable Declarations
    point lv_leaderPosition;

    // Variable Initialization

    // Implementation
    lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer].lv_heroUnit);
    if ((libAIAI_gf_HeroAIShouldStopFollowingLeader(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_leaderPosition) < libAIAI_gv_aIHeroFollowerCloseEnoughDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 55);
        return 8;
    }
    else {
    }
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_leaderPosition), c_orderQueueReplace);
    return 8;
}

int libAIAI_gf_HeroAITearOfEluneMoveToTear (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) < libAIAI_gv_aIHeroCloseToTearOfEluneDistance)) {
        if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 2) && (libAIAI_gf_HeroAIIsAllyCapturingTear(lp_trigPlayer) == false)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 28);
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit), c_orderQueueReplace);
            return 8;
        }
        else {
            libAIAI_gf_HeroAIChooseTearOfEluneGuardPostion(lp_trigPlayer);
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 29);
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_tearGuardPosition), c_orderQueueReplace);
            return 8;
        }
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITearOfEluneGuard (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldDefendTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 30);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 2) && (libAIAI_gf_HeroAIIsAllyCapturingTear(lp_trigPlayer) == false)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 28);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextTearGuardPositionUpdateTime < TimerGetElapsed(libGame_gv_gameTimer))) {
        libAIAI_gf_HeroAIChooseTearOfEluneGuardPostion(lp_trigPlayer);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_tearGuardPosition) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_tearGuardPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITearOfEluneCapture (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldDefendTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 30);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("CaptureMacGuffin", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITearOfEluneDefend (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTearOfElune(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCaptureTearOfElune = false;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        libAIAI_gf_HeroAIStartFleeInJungle(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) > libAIAI_gv_aIHeroFarFromTearOfEluneDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 27);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroFarFromTearOfEluneDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 27);
    return 8;
}

int libAIAI_gf_HeroAITurnInDoubloons (int lp_trigPlayer) {
    unitgroup auto516D43FE_g;
    int auto516D43FE_u;

    // Variable Declarations
    int lv_pirateShipCost;
    int lv_doubloonsTurnedIn;
    point lv_ghostShipBeaconPosition;
    region lv_areaAroundBeacon;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemySummons;
    unit lv_enemy;
    order lv_heroOrder;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTurningInDoubloons(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextTurnInDoubloonsConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTurnInDoubloonsInterruptedTimeout);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_pirateShipCost = libMapM_gf_MMCannonballsPirateShipCost(libGame_gv_teamOrderIndex_C);
        lv_doubloonsTurnedIn = libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamOrderIndex_C];
    }
    else {
        lv_pirateShipCost = libMapM_gf_MMCannonballsPirateShipCost(libGame_gv_teamChaosIndex_C);
        lv_doubloonsTurnedIn = libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamChaosIndex_C];
    }
    if (((lv_doubloonsTurnedIn >= lv_pirateShipCost) || (UnitBehaviorCount(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "CannonballStack") == 0))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_ghostShipBeaconPosition = UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_ghostShipBeaconPosition) > libAIAI_gv_aIHeroCloseToGhostShipBeaconDistance)) {
        if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
            return 8;
        }
        else {
        }
    }
    else {
        lv_areaAroundBeacon = RegionCircle(lv_ghostShipBeaconPosition, libAIAI_gv_aIHeroCloseToGhostShipBeaconDistance);
        lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_areaAroundBeacon, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
        auto516D43FE_g = lv_enemyHeroes;
        auto516D43FE_u = 1;
        for ( ; auto516D43FE_u <= UnitGroupCount(auto516D43FE_g, c_unitCountAll) ; auto516D43FE_u += BoolToInt(lv_enemy == UnitGroupUnit(auto516D43FE_g, auto516D43FE_u)) ) {
            lv_enemy = UnitGroupUnit(auto516D43FE_g, auto516D43FE_u);
            if ((libNtve_gf_UnitIsVisibleToPlayer(lv_enemy, lp_trigPlayer) == false)) {
                UnitGroupRemove(lv_enemyHeroes, lv_enemy);
            }
            else {
            }
        }
        if (((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0) || (UnitGroupCount(lv_enemySummons, c_unitCountAlive) > 0))) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 33);
            return 8;
        }
        else {
        }
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("CaptureMacGuffin", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITurnInDoubloonsDefend (int lp_trigPlayer) {
    // Variable Declarations
    point lv_ghostShipBeaconPosition;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTurningInDoubloons(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextTurnInDoubloonsConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTurnInDoubloonsInterruptedTimeout);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus == 0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_ghostShipBeaconPosition = UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_ghostShipBeaconPosition) > libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 32);
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, lv_ghostShipBeaconPosition, libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 32);
    return 8;
}

int libAIAI_gf_HeroAIPickUpDoubloon (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon = libAIAI_gf_HeroAISearchForNearbyDoubloon(lp_trigPlayer);
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon) == true)) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon)), c_orderQueueReplace);
            return 8;
        }
        else {
            libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
            return 8;
        }
    }
    else {
        if ((libAIAI_gf_HeroAINumberofEnemyHeroesNearLocation(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon), libAIAI_gv_aIHeroNearDoubloonDistance) == 0) && (libAIAI_gf_HeroAIIsHumanAllyPickingUpDoubloon(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon) == true)) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
            libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
            return 8;
        }
        else {
        }
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon = null;
        libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon)) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDoubloon)), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITreasureChestMoveToChest (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_distanceToChest;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTreasureChest(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_distanceToChest = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest));
    if ((lv_distanceToChest > libAIAI_gv_aIHeroFarFromTreasureChestDistance)) {
        if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
            return 8;
        }
        else {
        }
    }
    else {
        if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), libAIAI_gv_aIHeroCloseToTreasureChestDistance) == true)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 36);
            return 8;
        }
        else {
        }
    }
    if ((lv_distanceToChest < libAIAI_gv_aIHeroStandNearTreasureChestDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 35);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest)) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest)), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITreasureChestAttackChest (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTreasureChest(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIDismount(lp_trigPlayer) == true)) {
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), libAIAI_gv_aIHeroCloseToTreasureChestDistance) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 36);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("attack", 0)) || (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAITreasureChestDefend (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnTreasureChest(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), libAIAI_gv_aIHeroFarFromTreasureChestDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 34);
    return 8;
}

int libAIAI_gf_HeroAIObeliskMoveToObelisk (int lp_trigPlayer) {
    // Variable Declarations
    point lv_obeliskPosition;
    int lv_obeliskOwner;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_obeliskPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    lv_obeliskOwner = UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    if ((libAIAI_gf_HeroAIShouldGiveUpOnObelisk(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 1;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_obeliskPosition) <= libAIAI_gv_aIHeroCloseToObeliskDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 49);
        return 1;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_obeliskPosition) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_obeliskPosition), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIObeliskCapture (int lp_trigPlayer) {
    unitgroup autoF78F455A_g;
    int autoF78F455A_u;

    // Variable Declarations
    point lv_obeliskPosition;
    int lv_obeliskOwner;
    region lv_areaAroundObelisk;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemySummons;
    unit lv_enemy;
    order lv_heroOrder;
    point lv_orderTargetPosition;
    point lv_dragonShrineGuardPosition;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();

    // Implementation
    lv_obeliskPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    lv_obeliskOwner = UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    if ((libAIAI_gf_HeroAIShouldGiveUpOnObelisk(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 1;
    }
    else {
    }
    lv_areaAroundObelisk = RegionCircle(lv_obeliskPosition, libAIAI_gv_aIHeroCloseToObeliskDistance);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_areaAroundObelisk, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    autoF78F455A_g = lv_enemyHeroes;
    autoF78F455A_u = 1;
    for ( ; autoF78F455A_u <= UnitGroupCount(autoF78F455A_g, c_unitCountAll) ; autoF78F455A_u += BoolToInt(lv_enemy == UnitGroupUnit(autoF78F455A_g, autoF78F455A_u)) ) {
        lv_enemy = UnitGroupUnit(autoF78F455A_g, autoF78F455A_u);
        if ((libNtve_gf_UnitIsVisibleToPlayer(lv_enemy, lp_trigPlayer) == false)) {
            UnitGroupRemove(lv_enemyHeroes, lv_enemy);
        }
        else {
        }
    }
    if (((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0) || (UnitGroupCount(lv_enemySummons, c_unitCountAlive) > 0))) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 50);
        return 8;
    }
    else {
    }
    if ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, lv_obeliskOwner, 0) == true) && (libMapM_gf_MMGardensDragonObeliskFullyCaptured(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 1;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_obeliskPosition) >= (libAIAI_gv_aIHeroObeliskGuardDistance + 1.0))))) {
        lv_dragonShrineGuardPosition = libAIAI_gf_HeroAIChooseDragonShrineGuardPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_dragonShrineGuardPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIObeliskDefend (int lp_trigPlayer) {
    // Variable Declarations
    point lv_obeliskPosition;
    int lv_obeliskOwner;

    // Variable Initialization

    // Implementation
    lv_obeliskPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    lv_obeliskOwner = UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    if ((libAIAI_gf_HeroAIShouldGiveUpOnObelisk(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_obeliskPosition) > libAIAI_gv_aIHeroFarFromObeliskDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 48);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroFarFromObeliskDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 48);
    return 8;
}

int libAIAI_gf_HeroAIDragonMoveToDragon (int lp_trigPlayer) {
    // Variable Declarations
    point lv_dragonStatuePosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnDragon(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    lv_dragonStatuePosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_dragonStatuePosition) <= libAIAI_gv_aIHeroCloseToDragonStatueDistance)) {
        if ((libAIAI_gf_HeroAIIsAllyEnteringDragon(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == true)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 54);
        }
        else {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 52);
        }
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_dragonStatuePosition) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_dragonStatuePosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDragonEnter (int lp_trigPlayer) {
    // Variable Declarations
    order lv_order;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldGiveUpOnDragon(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue), libAIAI_gv_aIHeroCloseToDragonStatueDistance) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 53);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsHumanAllyEnteringDragon(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 54);
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("UseVehicle", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("UseVehicle", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDragonGuard (int lp_trigPlayer) {
    // Variable Declarations
    point lv_dragonStatuePosition;
    point lv_guardPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnDragon(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue), libAIAI_gv_aIHeroCloseToDragonStatueDistance) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 53);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsAllyEnteringDragon(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == false)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 52);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("UseVehicle", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue), c_orderQueueReplace);
        return 8;
    }
    else {
    }
    lv_dragonStatuePosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue);
    lv_guardPosition = PointWithOffset(lv_dragonStatuePosition, 0.0, -10.0);
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_guardPosition) >= 3.0) && ((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, lv_guardPosition) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_guardPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIDragonDefend (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gf_HeroAIShouldGiveUpOnDragon(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue = null;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIPaceAroundLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIJungleChooseTarget(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue), libAIAI_gv_aIHeroFarFromDragonStatueDistance) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 51);
    return 8;
}

int libAIAI_gf_HeroAIUnderworldEnter (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldEntrance = null;
        libAIAI_gf_HeroAIStartUnderworldKillMinions(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if (((libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining == 0) || (libAIAI_gf_HeroAIShouldRetreatUnderworld(lp_trigPlayer) == true))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldEntrance = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, true) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("CaptureMacGuffin", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldEntrance), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIUnderworldKillMinions (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_enemyHero;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIShouldRetreatUnderworld(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartExitUnderworld(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIUnderworldFocusNearbyHero(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining == 0)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 62);
        return 8;
    }
    else {
    }
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion = libAIAI_gf_HeroAIUnderworldChooseTarget(lp_trigPlayer);
        if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion) == false)) {
            if ((libAIAI_gf_HeroAISearchForNearbySkull(lp_trigPlayer, libAIAI_gv_heroAIUnderworldStatus.lv_underworldRegion, true) == true)) {
                return 8;
            }
            else {
            }
            libAIAI_gf_HeroAIStartExitUnderworld(lp_trigPlayer);
            return 8;
        }
        else {
        }
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((UnitGetType(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion) == "UnderworldBoss")) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
            return 8;
        }
        else {
        }
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((libNtve_gf_UnitIsVisibleToPlayer(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion, lp_trigPlayer) == true)) {
        if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("move", 0)) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion)))) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion), c_orderQueueReplace);
        }
        else {
        }
    }
    else {
        if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("move", 0)) || (DistanceBetweenPoints(OrderGetTargetPoint(lv_heroOrder), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion)) > 1.0))) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion)), c_orderQueueReplace);
        }
        else {
        }
    }
    return 8;
}

int libAIAI_gf_HeroAIUnderworldFocusHero (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if (((UnitIsAlive(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero) == false) || (libAIAI_gf_HeroAIIsUnitInUnderworld(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero) == false) || (libNtve_gf_UnitIsInvulnerable(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero) == true))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero = null;
        if ((libAIAI_gf_HeroAIUnderworldFocusNearbyHero(lp_trigPlayer) == true)) {
            return 8;
        }
        else {
        }
        libAIAI_gf_HeroAIStartUnderworldKillMinions(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatUnderworld(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero = null;
        libAIAI_gf_HeroAIStartExitUnderworld(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("move", 0)) || ((OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetUnit(lv_heroOrder) != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIUnderworldPickupSkull (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull = null;
        if ((libAIAI_gf_HeroAISearchForNearbySkull(lp_trigPlayer, RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroSkullSearchRadius), false) == true)) {
            return 8;
        }
        else {
            libAIAI_gf_HeroAIReturnToCurrentObjective(lp_trigPlayer);
            return 8;
        }
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull)) >= 1.0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull)), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIUnderworldMoveToExit (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsSafeUnderworld(lp_trigPlayer) == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit = null;
        if ((libAIAI_gf_HeroAIUnderworldFocusNearbyHero(lp_trigPlayer) == true)) {
            return 8;
        }
        else {
        }
        if ((libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining > 0)) {
            libAIAI_gf_HeroAIStartUnderworldKillMinions(lp_trigPlayer);
            return 8;
        }
        else {
        }
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 62);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit)) < libAIAI_gv_aIHeroUnderworldCloseToExitDistance)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 63);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHarassInJungleLogic(lp_trigPlayer, false) == true)) {
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateUnderworldExitTargetPosition(lp_trigPlayer);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIUnderworldTeleportHome (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldRetreatUnderworld(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartExitUnderworld(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIUnderworldFocusNearbyHero(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if (((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null) || (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("PortBackToBase", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("PortBackToBase", 0)), c_orderQueueReplace);
    }
    else {
    }
    return 1;
}

int libAIAI_gf_HeroAIUnderworldExit (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == false)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit = null;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToCollectSkulls = false;
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining > 0) && (libAIAI_gf_HeroAIIsSafeUnderworld(lp_trigPlayer) == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit = null;
        libAIAI_gf_HeroAIStartUnderworldKillMinions(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null) || (OrderGetAbilityCommand(lv_heroOrder) != AbilityCommand("CaptureMacGuffin", 0)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("CaptureMacGuffin", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAbathurAdvanceInLane (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_curLifePercent;
    fixed lv_frontTowerLanePosition;
    fixed lv_farBehindFrontTowerLanePosition;
    point lv_frontTowerPosition;
    point lv_hideInTownPosition;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    lv_curLifePercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if ((lv_curLifePercent <= libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        return 8;
    }
    else {
    }
    lv_frontTowerLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontTowerPosition;
    lv_farBehindFrontTowerLanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_frontTowerLanePosition, libAIAI_gv_aIHeroAbathurFarBehindFrontTowerDistance);
    if (((libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroAbathurCloseToEnemiesDistance, true, true, true) > 0.0) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > 0.0) || ((libGame_gv_players[lp_trigPlayer].lv_faction == 0) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroLanePosition > lv_farBehindFrontTowerLanePosition)) || ((libGame_gv_players[lp_trigPlayer].lv_faction == 1) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroLanePosition < lv_farBehindFrontTowerLanePosition)))) {
        libAIAI_gf_HeroAIStartAbathurRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    lv_hideInTownPosition = libAIAI_gf_HeroAIGetHideInTownPosition(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_hideInTownPosition) < libAIAI_gv_aIHeroAbathurCloseToHideInTownPosition)) {
        libAIAI_gf_HeroAIStartAbathurHideInTown(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
    }
    else {
    }
    if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) == null)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAbathurRetreatInLane (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_curLifePercent;
    fixed lv_farBehindFrontTowerLanePosition;
    fixed lv_frontTowerLanePosition;
    point lv_frontTowerPosition;
    point lv_hideInTownPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;

    // Variable Initialization

    // Implementation
    lv_curLifePercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if ((lv_curLifePercent <= libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    lv_frontTowerLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontTowerPosition;
    lv_farBehindFrontTowerLanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_frontTowerLanePosition, libAIAI_gv_aIHeroAbathurFarBehindFrontTowerDistance);
    if ((libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeorAbathurFarFromEnemiesDistance, true, true, true) == 0.0) && (((libGame_gv_players[lp_trigPlayer].lv_faction == 0) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroLanePosition < lv_farBehindFrontTowerLanePosition)) || ((libGame_gv_players[lp_trigPlayer].lv_faction == 1) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroLanePosition > lv_farBehindFrontTowerLanePosition))) && (libAIAI_gf_HeroAITimeInCurrentState(lp_trigPlayer) > libAIAI_gv_aIHeroMinRetreatDuration)) {
        libAIAI_gf_HeroAIStartAbathurAdvanceLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) <= libAIAI_gv_aIHeroCloseEnoughDist)) {
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if (((lv_heroOrder == null) || ((lv_orderTargetPosition != null) && (DistanceBetweenPoints(lv_orderTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition) >= libAIAI_gv_aIHeroCloseEnoughDist)))) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAbathurHideInTown (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_curLifePercent;
    int lv_desiredLane;
    point lv_hideInTownPosition;
    point lv_weakestLaneHideInTownPosition;
    int lv_closestIndex;
    int lv_secondaryIndex;
    point lv_tunnelPosition;
    fixed lv_delay;
    int lv_closestWaypoint;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    lv_curLifePercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if ((lv_curLifePercent <= libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
        return 8;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroAbathurCloseToEnemiesDistance, true, true, true) > 0.0)) {
        libAIAI_gf_HeroAIStartAbathurRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libAIAI_gf_HeroAIAvoidAreaLogic(lp_trigPlayer) == true)) {
        return 8;
    }
    else {
    }
    if ((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState != 2)) {
        lv_desiredLane = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_weakestLane;
    }
    else {
        lv_desiredLane = libAIAI_gf_HeroAIGetLaneWithMostAllies(lp_trigPlayer);
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane != lv_desiredLane) && (libCore_gf_IsAbilityOnCooldown(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "AbathurDeepTunnel") == false) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextChangeLanesConsiderTime <= TimerGetElapsed(libGame_gv_gameTimer)) && (TimerGetElapsed(libGame_gv_gameTimer) > libAIAI_gv_aIHeroInitialLaneChoosingTime)) {
        lv_weakestLaneHideInTownPosition = libAIAI_gf_HeroAIGetHideInTownPosition(lp_trigPlayer, lv_desiredLane);
        lv_tunnelPosition = libAIAI_gf_HeroAIFindNearbyPathablePoint(lp_trigPlayer, lv_weakestLaneHideInTownPosition, 5.0, true);
        if ((lv_tunnelPosition != null)) {
            libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_desiredLane);
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("AbathurDeepTunnel", 0), lv_tunnelPosition), c_orderQueueReplace);
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 67);
            lv_delay = RandomFixed((libAIAI_gv_aIHeroAbathurChangeLanesDelay - 5.0), (libAIAI_gv_aIHeroAbathurChangeLanesDelay + 5.0));
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextChangeLanesConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + lv_delay);
            return 8;
        }
        else {
        }
    }
    else {
    }
    lv_hideInTownPosition = libAIAI_gf_HeroAIGetHideInTownPosition(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_hideInTownPosition) > libAIAI_gv_aIHeroAbathurFarFromHideInTownPosition)) {
        libAIAI_gf_HeroAIStartAbathurRetreatLane(lp_trigPlayer);
        return 8;
    }
    else {
    }
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if (((lv_heroOrder == null)) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_hideInTownPosition) > 1.0)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_hideInTownPosition), c_orderQueueReplace);
    }
    else {
    }
    return 8;
}

int libAIAI_gf_HeroAIAbathurChangeLanes (int lp_trigPlayer) {
    // Variable Declarations
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((lv_heroOrder != null) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("AbathurDeepTunnel", 0))) {
        return 8;
    }
    else {
    }
    libGame_gf_CalculateClosestLaneData(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = libGame_gv_closestLaneData.lv_closestLane;
    libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane);
    libAIAI_gf_HeroAIStartAbathurHideInTown(lp_trigPlayer);
    return 8;
}

bool libAIAI_gf_HeroAIHasGameStarted () {
    // Implementation
    return (libGame_gf_MinionSystemStarted() == true);
}

void libAIAI_gf_HeroAIChangeState (int lp_player, int lp_state) {
    // Implementation
    libAIAI_gf_HeroAIClearEval(lp_player);
    libAIAI_gv_aIHeroes[lp_player].lv_heroState = lp_state;
    libAIAI_gv_aIHeroes[lp_player].lv_timeEnteredState = TimerGetElapsed(libGame_gv_gameTimer);
}

void libAIAI_gf_HeroAIChangeDesiredLane (int lp_trigPlayer, int lp_laneIndex) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane == lp_laneIndex)) {
        return ;
    }
    else {
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane = lp_laneIndex;
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        libAIAI_gf_HeroAIUpdateLaneHeroCounts(0);
    }
    else {
        libAIAI_gf_HeroAIUpdateLaneHeroCounts(1);
    }
}

bool libAIAI_gf_HeroAIIsInFollowerState (int lp_trigPlayer) {
    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 55) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 56))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsInAdvancingState (int lp_trigPlayer) {
    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 7) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 23) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 12) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 64))) {
        return true;
    }
    else {
        return false;
    }
}

fixed libAIAI_gf_HeroAITimeInCurrentState (int lp_trigPlayer) {
    // Implementation
    return (TimerGetElapsed(libGame_gv_gameTimer) - libAIAI_gv_aIHeroes[lp_trigPlayer].lv_timeEnteredState);
}

void libAIAI_gf_HeroAIChooseWaitForGameToStartPosition (int lp_trigPlayer) {
    int auto63968557_ae;
    int auto63968557_ai;

    // Variable Declarations
    point lv_laneEndpoint;
    point lv_corePosition;
    point lv_direction;
    point lv_normal;
    point lv_behindCore;
    fixed lv_offset;
    point lv_waitingPosition;
    fixed lv_distance;
    int lv_playerIndex;
    const fixed lv_spreadDistance = 15.0;
    int lv_numberOfAIPlayersOnTeam;
    int lv_aIPlayerOnTeamIndex;
    fixed lv_bucketWidth;

    // Variable Initialization

    // Implementation
    auto63968557_ae = libCore_gv_bALMaxPlayers;
    auto63968557_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto63968557_ai >= 0 && lv_playerIndex <= auto63968557_ae) || (auto63968557_ai <= 0 && lv_playerIndex >= auto63968557_ae) ) ; lv_playerIndex += auto63968557_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libNtve_gf_PlayerIsEnemy(lp_trigPlayer, lv_playerIndex, 0) == true)) {
            lv_numberOfAIPlayersOnTeam += 1;
            if ((lv_playerIndex <= lp_trigPlayer)) {
                lv_aIPlayerOnTeamIndex += 1;
            }
            else {
            }
        }
        else {
        }
    }
    if ((lv_numberOfAIPlayersOnTeam == 0) && (libGame_gv_laneCount == 0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_waitForGameToStartPosition = libGame_gv_players[lp_trigPlayer].lv_spawnPoint;
        return ;
    }
    else {
    }
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
        lv_laneEndpoint = libGame_gv_laneData[libGame_gv_teamOrderIndex_C].lv_waypoints[1];
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
        lv_laneEndpoint = libGame_gv_laneData[libGame_gv_teamChaosIndex_C].lv_waypoints[libGame_gv_laneData[libGame_gv_teamChaosIndex_C].lv_waypointCount];
    }
    lv_direction = AIGetDirection(lv_corePosition, lv_laneEndpoint);
    lv_behindCore = libCore_gf_AdvancePointinDirection(lv_corePosition, lv_direction, 8.0);
    lv_normal = Point(PointGetY(lv_direction), (-1.0 * PointGetX(lv_direction)));
    lv_bucketWidth = (lv_spreadDistance / IntToFixed(lv_numberOfAIPlayersOnTeam));
    lv_offset = (((0.5 + FixedToInt((lv_aIPlayerOnTeamIndex - 1))) * lv_bucketWidth) - (lv_spreadDistance / 2.0));
    lv_waitingPosition = libCore_gf_AdvancePointinDirection(lv_behindCore, lv_normal, lv_offset);
    lv_waitingPosition = RegionRandomPoint(RegionCircle(lv_waitingPosition, 1.0));
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_waitForGameToStartPosition = lv_waitingPosition;
}

void libAIAI_gf_HeroAIStartWaitToHeal (int lp_trigPlayer) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = 0;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointIndex = 0;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointPoint = libGame_gv_players[lp_trigPlayer].lv_spawnPoint;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = libGame_gv_players[lp_trigPlayer].lv_spawnPoint;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_announcedRetreat = false;
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 5);
}

unit libAIAI_gf_HeroAIAfterDeathAttackChooseTarget (int lp_trigPlayer) {
    unitgroup autoE00C0690_g;
    int autoE00C0690_u;

    // Variable Declarations
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyMinions;
    unitgroup lv_enemySummons;
    unit lv_testUnit;
    unit lv_bestTarget;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();

    // Implementation
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 12.0), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    autoE00C0690_g = lv_enemyHeroes;
    autoE00C0690_u = 1;
    for ( ; autoE00C0690_u <= UnitGroupCount(autoE00C0690_g, c_unitCountAll) ; autoE00C0690_u += BoolToInt(lv_testUnit == UnitGroupUnit(autoE00C0690_g, autoE00C0690_u)) ) {
        lv_testUnit = UnitGroupUnit(autoE00C0690_g, autoE00C0690_u);
        if ((libNtve_gf_UnitIsVisibleToPlayer(lv_testUnit, lp_trigPlayer) == false)) {
            UnitGroupRemove(lv_enemyHeroes, lv_testUnit);
        }
        else {
        }
    }
    if ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true)) {
        lv_bestTarget = UnitGroupClosestToPoint(lv_enemyMinions, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
        if ((UnitIsValid(lv_bestTarget) == false)) {
            lv_bestTarget = UnitGroupClosestToPoint(lv_enemySummons, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
            if ((UnitIsValid(lv_bestTarget) == false)) {
                lv_bestTarget = UnitGroupClosestToPoint(lv_enemyHeroes, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
            }
            else {
            }
        }
        else {
        }
    }
    else {
        lv_bestTarget = UnitGroupClosestToPoint(lv_enemyHeroes, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
        if ((UnitIsValid(lv_bestTarget) == false)) {
            lv_bestTarget = UnitGroupClosestToPoint(lv_enemyMinions, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
            if ((UnitIsValid(lv_bestTarget) == false)) {
                lv_bestTarget = UnitGroupClosestToPoint(lv_enemySummons, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
            }
            else {
            }
        }
        else {
        }
    }
    return lv_bestTarget;
}

bool libAIAI_gf_HeroAISafeWhileRetreatingInLaneLogic (int lp_trigPlayer) {
    // Variable Declarations
    region lv_homeRegion;
    fixed lv_heroToHomeDistance;
    fixed lv_retreatPositionToHomeDistance;
    point lv_currentLaneRetreatPosition;
    fixed lv_safeDistanceBehindFrontTower;
    bool lv_wantsToTeleportHome;
    bool lv_wantsToWalkBetweenLanes;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    if ((libAIAI_gf_HeroAIDrinkMoonwellLogic(lp_trigPlayer) == true)) {
        return true;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])))) {
        lv_wantsToTeleportHome = true;
    }
    else {
    }
    if ((lv_wantsToTeleportHome == false) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane)) {
        if (((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) || ((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_numberOfMissingEnemies > 3) && (libAIAI_gf_HeroAIIsPlayerInsideBase(lp_trigPlayer) == false)) || (libAIAI_gf_HeroAIBetterToWalkDirectlyToLane(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane) == false))) {
            lv_wantsToTeleportHome = true;
        }
        else {
            lv_wantsToWalkBetweenLanes = true;
        }
    }
    else {
    }
    if ((lv_wantsToTeleportHome == true)) {
        lv_safeDistanceBehindFrontTower = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontTowerPosition;
        lv_safeDistanceBehindFrontTower = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_safeDistanceBehindFrontTower, 8.0);
        if (((libAIAI_gf_HeroAIIsPlayerBehindLanePosition(lp_trigPlayer, lv_safeDistanceBehindFrontTower) == true) || ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInLaneStartTime + libAIAI_gv_aIHeroExtraRetreatLaneTimeBeforeTeleporting) < TimerGetElapsed(libGame_gv_gameTimer)))) {
            if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true)) {
                libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 3);
            }
            else {
                libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 25);
            }
            return true;
        }
        else {
            return false;
        }
    }
    else {
    }
    if ((lv_wantsToWalkBetweenLanes == true)) {
        lv_currentLaneRetreatPosition = libAIAI_gf_HeroAIGetPositionBehindContentionPoint(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, libAIAI_gv_aIHeroRetreatDistanceToChangeLanes, 0.0);
        lv_heroToHomeDistance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libGame_gv_players[lp_trigPlayer].lv_spawnPoint);
        lv_retreatPositionToHomeDistance = DistanceBetweenPoints(lv_currentLaneRetreatPosition, libGame_gv_players[lp_trigPlayer].lv_spawnPoint);
        if (((libNtve_gf_UnitInRegion(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_homeRegion) == true) || (lv_heroToHomeDistance <= lv_retreatPositionToHomeDistance))) {
            libAIAI_gf_HeroAIStartReturnToLane(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane);
            return true;
        }
        else {
            return false;
        }
    }
    else {
    }
    if ((libAIAI_gf_HeroAIShouldWaitForMinions(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIStartWaitForMinions(lp_trigPlayer);
        return true;
    }
    else {
    }
    libAIAI_gf_HeroAIStartAdvanceLane(lp_trigPlayer);
    return true;
}

bool libAIAI_gf_HeroAISafeWhileRetreatingInJungleLogic (int lp_trigPlayer) {
    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true) || ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp <= 0) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) || ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp > 0) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroStopCampAttackPercent)) || ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp > 0) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_arrivedAtCampTime <= 0.0)))) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp > 0)) {
            libAIAI_gf_HeroAIHeroStoppingCampAttack(lp_trigPlayer);
            return true;
        }
        else {
        }
        if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_safeInJungleStartTime + libAIAI_gv_aIHeroExtraRetreatJungleTimeBeforeTeleporting) < TimerGetElapsed(libGame_gv_gameTimer))) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 45);
            return true;
        }
        else {
        }
    }
    else {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp > 0)) {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 40);
            return true;
        }
        else {
            libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
            return true;
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIHeroHasMount (int lp_trigPlayer) {
    // Implementation
    if ((libCore_gv_dataHeroesHeroData[libGame_gv_players[lp_trigPlayer].lv_heroIndex].lv_isFlyer == false) && (libGame_gv_players[lp_trigPlayer].lv_heroIndex != libCore_gf_GetHeroIndexForUnitType("HeroAbathur")) && (libGame_gv_players[lp_trigPlayer].lv_heroIndex != libCore_gf_GetHeroIndexForUnitType("HeroSgtHammer"))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIBetterToWalkDirectlyToLane (int lp_trigPlayer, int lp_laneIndex) {
    // Variable Declarations
    fixed lv_walkingSpeed;
    fixed lv_speedBonus;
    point lv_heroPosition;
    point lv_returnToLanePosition;
    fixed lv_movementSpeed;
    fixed lv_teleportChannelTime;
    fixed lv_timeToWalkToLane;
    fixed lv_timeToTeleportHomeFirst;

    // Variable Initialization

    // Implementation
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_teleportChannelTime = StringToFixed(CatalogFieldValueGet(c_gameCatalogAbil, "PortBackToBase", "CastIntroTime[" + IntToString(0) + "]", c_playerAny));
    lv_walkingSpeed = StringToFixed(CatalogFieldValueGet(c_gameCatalogUnit, UnitGetType(libGame_gv_players[lp_trigPlayer].lv_heroUnit), "Speed", lp_trigPlayer));
    if ((libAIAI_gf_HeroAIHeroHasMount(lp_trigPlayer) == true)) {
        lv_speedBonus = StringToFixed(CatalogFieldValueGet(c_gameCatalogBehavior, "Mounted", "Modification.UnifiedMoveSpeedFactor", lp_trigPlayer));
        lv_movementSpeed = (lv_walkingSpeed * (1.0 + lv_speedBonus));
    }
    else {
        lv_movementSpeed = lv_walkingSpeed;
    }
    lv_returnToLanePosition = libAIAI_gf_HeroAIGetReturnToLanePosition(lp_trigPlayer, lp_laneIndex);
    if ((DistanceBetweenPoints(lv_heroPosition, lv_returnToLanePosition) > libAIAI_gv_aIHeroWalkDirectlyToLaneDistance)) {
        return false;
    }
    else {
    }
    lv_timeToWalkToLane = (DistanceBetweenPoints(lv_heroPosition, lv_returnToLanePosition) / lv_movementSpeed);
    lv_timeToTeleportHomeFirst = (lv_teleportChannelTime + (DistanceBetweenPoints(libGame_gv_players[lp_trigPlayer].lv_spawnPoint, lv_returnToLanePosition) / lv_movementSpeed));
    if ((lv_timeToWalkToLane < lv_timeToTeleportHomeFirst)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAILaneChangeTarget (int lp_trigPlayer) {
    unitgroup auto6BEFFB21_g;
    int auto6BEFFB21_u;
    unitgroup autoCFDBF903_g;
    int autoCFDBF903_u;
    unitgroup autoF7C7C396_g;
    int autoF7C7C396_u;
    unitgroup autoAD2E6DC7_g;
    int autoAD2E6DC7_u;
    unitgroup auto5A65BE74_g;
    int auto5A65BE74_u;

    // Variable Declarations
    order lv_currentOrder;
    point lv_currentPosition;
    unit lv_currentTarget;
    bool lv_attackingWall;
    bool lv_attackingFountain;
    bool lv_attackingHero;
    bool lv_attackingBadTarget;
    fixed lv_minionAggroRange;
    fixed lv_towerAggroRange;
    fixed lv_heroAggroRange;
    fixed lv_extendedTowerAggroRange;
    fixed lv_attackRange;
    fixed lv_heroHarassRange;
    fixed lv_lowHealthHeroHarassRange;
    unitgroup lv_allNearbyEnemies;
    unitgroup lv_nearbyEnemyTowers;
    unitgroup lv_nearbyEnemyHeroes;
    unitgroup lv_nearbyEnemyMinions;
    unitgroup lv_nearbyEnemySummons;
    unitgroup lv_allNearbyAllies;
    unitgroup lv_nearbyAllyHeroes;
    int lv_strucureType;
    unit lv_allyHero;
    unit lv_lastAttacker;
    unit lv_enemy;
    fixed lv_enemyHP;
    fixed lv_leastHP;
    fixed lv_enemyEval;
    fixed lv_leastEval;
    unit lv_bestTarget;
    int lv_townIndex;

    // Variable Initialization
    lv_allNearbyEnemies = UnitGroupEmpty();
    lv_nearbyEnemyTowers = UnitGroupEmpty();
    lv_nearbyEnemyHeroes = UnitGroupEmpty();
    lv_nearbyEnemyMinions = UnitGroupEmpty();
    lv_nearbyEnemySummons = UnitGroupEmpty();
    lv_allNearbyAllies = UnitGroupEmpty();
    lv_nearbyAllyHeroes = UnitGroupEmpty();
    lv_leastHP = 524287.0;
    lv_leastEval = 524287.0;

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, 0);
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle);
    }
    else {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    }
    if ((lv_currentOrder != null) && (OrderGetAbilityCommand(lv_currentOrder) == AbilityCommand("attack", 0))) {
        lv_currentTarget = OrderGetTargetUnit(lv_currentOrder);
    }
    else {
    }
    if ((lv_currentTarget == null)) {
        return false;
    }
    else {
    }
    if ((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_currentTarget)) == 2)) {
        lv_attackingWall = true;
    }
    else {
    }
    if ((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_currentTarget)) == 6)) {
        lv_attackingFountain = true;
    }
    else {
    }
    if ((UnitTypeTestAttribute(UnitGetType(lv_currentTarget), c_unitAttributeHeroic) == true)) {
        lv_attackingHero = true;
    }
    else {
    }
    if (((lv_attackingWall == true) || ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (lv_attackingHero == true)) || ((libAIAI_gv_aIHeroAvoidTargettingFountains[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (lv_attackingFountain == true)))) {
        lv_attackingBadTarget = true;
    }
    else {
    }
    lv_minionAggroRange = libAIAI_gv_aIHeroSightRange;
    lv_towerAggroRange = libAIAI_gv_aIHeroSightRange;
    lv_heroAggroRange = libAIAI_gv_aIHeroSightRange;
    lv_extendedTowerAggroRange = (libAIAI_gv_aIHeroSightRange * 2.0);
    lv_attackRange = libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_heroHarassRange = (lv_attackRange + 2.0);
    lv_lowHealthHeroHarassRange = (lv_attackRange + 4.0);
    lv_allNearbyEnemies = UnitGroupSearch(null, lp_trigPlayer, lv_currentPosition, lv_extendedTowerAggroRange, UnitFilter((1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterAlly) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterLight) | (1 << c_targetFilterMissile) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_nearbyEnemyTowers = UnitGroupFilter(null, c_playerAny, lv_allNearbyEnemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    lv_nearbyEnemyHeroes = UnitGroupFilter(null, c_playerAny, lv_allNearbyEnemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_nearbyEnemyMinions = UnitGroupFilter(null, c_playerAny, lv_allNearbyEnemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_nearbyEnemySummons = UnitGroupFilter(null, c_playerAny, lv_allNearbyEnemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    lv_allNearbyAllies = UnitGroupSearch(null, lp_trigPlayer, lv_currentPosition, lv_extendedTowerAggroRange, UnitFilter((1 << c_targetFilterVisible), 0, (1 << c_targetFilterPlayer) | (1 << c_targetFilterNeutral) | (1 << c_targetFilterEnemy) | (1 << c_targetFilterLight) | (1 << c_targetFilterMissile) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_nearbyAllyHeroes = UnitGroupFilter(null, c_playerAny, lv_allNearbyAllies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((libAIAI_gv_aIHeroSmartLaneTargetting[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true)) {
        auto6BEFFB21_g = lv_nearbyAllyHeroes;
        auto6BEFFB21_u = 1;
        for ( ; auto6BEFFB21_u <= UnitGroupCount(auto6BEFFB21_g, c_unitCountAll) ; auto6BEFFB21_u += BoolToInt(lv_allyHero == UnitGroupUnit(auto6BEFFB21_g, auto6BEFFB21_u)) ) {
            lv_allyHero = UnitGroupUnit(auto6BEFFB21_g, auto6BEFFB21_u);
            if ((UnitGetOwner(lv_allyHero) > libCore_gv_bALMaxPlayers)) {
                continue;
            }
            else {
            }
            lv_lastAttacker = libAIAI_gv_heroAIDamageTracking[UnitGetOwner(lv_allyHero)].lv_lastAttacker;
            if (((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(UnitGetOwner(lv_allyHero), 2.0) == true) && (UnitIsValid(lv_lastAttacker) == true) && (UnitTypeTestAttribute(UnitGetType(lv_lastAttacker), c_unitAttributeHeroic) == true) && (DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_lastAttacker)) <= lv_heroAggroRange) && (libAIAI_gf_HeroAIIsUnitBehindGate(lv_lastAttacker) == false))) {
                lv_enemyEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_lastAttacker, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
                if ((lv_enemyEval < lv_leastEval)) {
                    lv_leastEval = lv_enemyEval;
                    lv_bestTarget = lv_lastAttacker;
                }
                else {
                }
            }
            else {
            }
        }
        if ((lv_bestTarget == null)) {
            autoCFDBF903_g = lv_nearbyEnemyHeroes;
            autoCFDBF903_u = 1;
            for ( ; autoCFDBF903_u <= UnitGroupCount(autoCFDBF903_g, c_unitCountAll) ; autoCFDBF903_u += BoolToInt(lv_enemy == UnitGroupUnit(autoCFDBF903_g, autoCFDBF903_u)) ) {
                lv_enemy = UnitGroupUnit(autoCFDBF903_g, autoCFDBF903_u);
                if ((libNtve_gf_UnitIsVisibleToPlayer(lv_enemy, lp_trigPlayer) == true) && ((DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_heroHarassRange) || ((UnitGetPropertyFixed(lv_enemy, c_unitPropLifePercent, c_unitPropCurrent) < 50.0) && (DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_lowHealthHeroHarassRange)))) {
                    lv_enemyHP = UnitGetPropertyFixed(lv_enemy, c_unitPropLife, c_unitPropCurrent);
                    if ((lv_enemyHP < lv_leastHP)) {
                        lv_leastHP = lv_enemyHP;
                        lv_bestTarget = lv_enemy;
                    }
                    else {
                    }
                }
                else {
                }
            }
        }
        else {
        }
    }
    else {
    }
    if (((libAIAI_gv_aIHeroSmartLaneTargetting[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) || (lv_attackingBadTarget == true))) {
        if ((lv_bestTarget == null)) {
            autoF7C7C396_g = lv_nearbyEnemyTowers;
            autoF7C7C396_u = 1;
            for ( ; autoF7C7C396_u <= UnitGroupCount(autoF7C7C396_g, c_unitCountAll) ; autoF7C7C396_u += BoolToInt(lv_enemy == UnitGroupUnit(autoF7C7C396_g, autoF7C7C396_u)) ) {
                lv_enemy = UnitGroupUnit(autoF7C7C396_g, autoF7C7C396_u);
                if (((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState == 2) || (libAIAI_gf_HeroAIIsTowerAThreat(lv_enemy) == false) || (libAIAI_gf_HeroAIAlliesNearEnemyBuilding(lp_trigPlayer, lv_enemy) == true)) && ((DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_towerAggroRange) || ((lv_attackingBadTarget == true) && (DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_extendedTowerAggroRange)))) {
                    lv_townIndex = libGame_gf_TownGetTownForUnit(lv_enemy);
                    if ((lv_townIndex > 0) && (libGame_gv_townTownData[lv_townIndex].lv_lane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane)) {
                        continue;
                    }
                    else {
                    }
                    lv_enemyEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetTowerDistanceWeight);
                    if ((lv_enemyEval < lv_leastEval)) {
                        lv_leastEval = lv_enemyEval;
                        lv_bestTarget = lv_enemy;
                    }
                    else {
                    }
                }
                else {
                }
            }
            autoAD2E6DC7_g = lv_nearbyEnemyMinions;
            autoAD2E6DC7_u = 1;
            for ( ; autoAD2E6DC7_u <= UnitGroupCount(autoAD2E6DC7_g, c_unitCountAll) ; autoAD2E6DC7_u += BoolToInt(lv_enemy == UnitGroupUnit(autoAD2E6DC7_g, autoAD2E6DC7_u)) ) {
                lv_enemy = UnitGroupUnit(autoAD2E6DC7_g, autoAD2E6DC7_u);
                if ((libNtve_gf_UnitIsVisibleToPlayer(lv_enemy, lp_trigPlayer) == true) && (DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_minionAggroRange)) {
                    lv_enemyEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
                    if ((lv_enemyEval < lv_leastEval)) {
                        lv_leastEval = lv_enemyEval;
                        lv_bestTarget = lv_enemy;
                    }
                    else {
                    }
                }
                else {
                }
            }
            auto5A65BE74_g = lv_nearbyEnemySummons;
            auto5A65BE74_u = 1;
            for ( ; auto5A65BE74_u <= UnitGroupCount(auto5A65BE74_g, c_unitCountAll) ; auto5A65BE74_u += BoolToInt(lv_enemy == UnitGroupUnit(auto5A65BE74_g, auto5A65BE74_u)) ) {
                lv_enemy = UnitGroupUnit(auto5A65BE74_g, auto5A65BE74_u);
                if ((libNtve_gf_UnitIsVisibleToPlayer(lv_enemy, lp_trigPlayer) == true) && (DistanceBetweenPoints(lv_currentPosition, UnitGetPosition(lv_enemy)) <= lv_minionAggroRange)) {
                    lv_enemyEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
                    if ((lv_enemyEval < lv_leastEval)) {
                        lv_leastEval = lv_enemyEval;
                        lv_bestTarget = lv_enemy;
                    }
                    else {
                    }
                }
                else {
                }
            }
        }
        else {
        }
    }
    else {
    }
    if ((lv_bestTarget == null)) {
        return false;
    }
    else {
        if ((lv_currentTarget != lv_bestTarget)) {
            if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingUnit(AbilityCommand("attack", 0), lv_bestTarget), c_orderQueueReplace);
            }
            else {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_bestTarget), c_orderQueueReplace);
            }
            return true;
        }
        else {
            return false;
        }
    }
}

bool libAIAI_gf_HeroAIJungleChooseTarget (int lp_trigPlayer, point lp_location, fixed lp_radius) {
    unitgroup auto70369214_g;
    int auto70369214_u;
    unitgroup auto0798A2D8_g;
    int auto0798A2D8_u;
    unitgroup autoA9D64B29_g;
    int autoA9D64B29_u;

    // Variable Declarations
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemySummons;
    unit lv_hero;
    unit lv_target;
    fixed lv_targetEval;
    unit lv_bestTarget;
    fixed lv_bestTargetEval;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();
    lv_bestTargetEval = 524287.0;

    // Implementation
    lv_nearbyRegion = RegionCircle(lp_location, lp_radius);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), (1 << c_targetFilterBiological), 0), 0);
    auto70369214_g = lv_enemyHeroes;
    auto70369214_u = 1;
    for ( ; auto70369214_u <= UnitGroupCount(auto70369214_g, c_unitCountAll) ; auto70369214_u += BoolToInt(lv_hero == UnitGroupUnit(auto70369214_g, auto70369214_u)) ) {
        lv_hero = UnitGroupUnit(auto70369214_g, auto70369214_u);
        if ((libNtve_gf_UnitIsVisibleToPlayer(lv_hero, lp_trigPlayer) == false)) {
            UnitGroupRemove(lv_enemyHeroes, lv_hero);
        }
        else {
        }
    }
    auto0798A2D8_g = lv_enemyHeroes;
    auto0798A2D8_u = 1;
    for ( ; auto0798A2D8_u <= UnitGroupCount(auto0798A2D8_g, c_unitCountAll) ; auto0798A2D8_u += BoolToInt(lv_target == UnitGroupUnit(auto0798A2D8_g, auto0798A2D8_u)) ) {
        lv_target = UnitGroupUnit(auto0798A2D8_g, auto0798A2D8_u);
        lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_target, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
        if ((lv_targetEval < lv_bestTargetEval)) {
            lv_bestTarget = lv_target;
            lv_bestTargetEval = lv_targetEval;
        }
        else {
        }
    }
    if ((UnitIsValid(lv_bestTarget) == false)) {
        autoA9D64B29_g = lv_enemySummons;
        autoA9D64B29_u = 1;
        for ( ; autoA9D64B29_u <= UnitGroupCount(autoA9D64B29_g, c_unitCountAll) ; autoA9D64B29_u += BoolToInt(lv_target == UnitGroupUnit(autoA9D64B29_g, autoA9D64B29_u)) ) {
            lv_target = UnitGroupUnit(autoA9D64B29_g, autoA9D64B29_u);
            lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_target, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
            if ((lv_targetEval < lv_bestTargetEval)) {
                lv_bestTarget = lv_target;
                lv_bestTargetEval = lv_targetEval;
            }
            else {
            }
        }
    }
    else {
    }
    if ((UnitIsValid(lv_bestTarget) == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lv_bestTarget), c_orderQueueReplace);
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIAggroEnemyCore (int lp_trigPlayer) {
    // Variable Declarations
    order lv_currentOrder;
    point lv_currentPosition;
    unitgroup lv_enemyCoreGroup;

    // Variable Initialization
    lv_enemyCoreGroup = UnitGroupEmpty();

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, 0);
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle);
    }
    else {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    }
    if ((lv_currentOrder != null) && (OrderGetAbilityCommand(lv_currentOrder) == AbilityCommand("attack", 0)) && (OrderGetTargetType(lv_currentOrder) == c_orderTargetPoint)) {
        lv_enemyCoreGroup = libNtve_gf_UnitsInRegionWithAllianceToPlayerMatchingCondition("KingsCore", "", "", lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(lv_currentPosition, 17.0), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        if ((UnitGroupCount(lv_enemyCoreGroup, c_unitCountAlive) > 0)) {
            if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingUnit(AbilityCommand("attack", 0), UnitGroupUnit(lv_enemyCoreGroup, 1)), c_orderQueueReplace);
            }
            else {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), UnitGroupUnit(lv_enemyCoreGroup, 1)), c_orderQueueReplace);
            }
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIHarassSiegeEnemyLogic (int lp_trigPlayer) {
    unitgroup autoF889F1B0_g;
    int autoF889F1B0_u;
    unitgroup autoF99274E8_g;
    int autoF99274E8_u;

    // Variable Declarations
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyMinions;
    unit lv_enemy;
    region lv_nearEnemyRegion;
    unitgroup lv_enemyHeroesNearEnemy;
    order lv_order;
    fixed lv_targetEval;
    unit lv_bestTarget;
    fixed lv_bestTargetEval;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_enemyHeroesNearEnemy = UnitGroupEmpty();
    lv_bestTargetEval = 524287.0;

    // Implementation
    if ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 2.0) == true)) {
        return false;
    }
    else {
    }
    lv_nearbyRegion = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroSiegeEnemySearchRadius);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    if ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == false)) {
        autoF889F1B0_g = lv_enemyHeroes;
        autoF889F1B0_u = 1;
        for ( ; autoF889F1B0_u <= UnitGroupCount(autoF889F1B0_g, c_unitCountAll) ; autoF889F1B0_u += BoolToInt(lv_enemy == UnitGroupUnit(autoF889F1B0_g, autoF889F1B0_u)) ) {
            lv_enemy = UnitGroupUnit(autoF889F1B0_g, autoF889F1B0_u);
            if (((UnitGetType(lv_enemy) != "HeroSgtHammer") || (libAIAI_gf_AIGetActiveWeaponRange(lv_enemy) < libAIAI_gv_aIHeroSiegeEnemyMinWeaponRange))) {
                continue;
            }
            else {
            }
            libAIAI_gf_HeroAIEval(lp_trigPlayer);
            if (((libAIAI_gf_HeroAIUnitProtectedByTower(lv_enemy, libAIAI_gv_aIHeroFarFromTowerDistance) == true) || (libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(lv_enemy), libAIAI_gv_aIHeroCloseToSiegeEnemyDistance, true, true, true) > libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval))) {
                continue;
            }
            else {
            }
            lv_bestTarget = lv_enemy;
            break;
        }
    }
    else {
    }
    if ((UnitIsValid(lv_bestTarget) == false) && (libAIAI_gf_HeroAIUnitProtectedByTower(libGame_gv_players[lp_trigPlayer].lv_heroUnit, libAIAI_gv_aIHeroFarFromTowerDistance) == true)) {
        autoF99274E8_g = lv_enemyMinions;
        autoF99274E8_u = 1;
        for ( ; autoF99274E8_u <= UnitGroupCount(autoF99274E8_g, c_unitCountAll) ; autoF99274E8_u += BoolToInt(lv_enemy == UnitGroupUnit(autoF99274E8_g, autoF99274E8_u)) ) {
            lv_enemy = UnitGroupUnit(autoF99274E8_g, autoF99274E8_u);
            if ((libAIAI_gf_AIGetActiveWeaponRange(lv_enemy) < libAIAI_gv_aIHeroSiegeEnemyMinWeaponRange)) {
                continue;
            }
            else {
            }
            lv_order = UnitOrder(lv_enemy, 0);
            if (((lv_order == null) || (OrderGetTargetType(lv_order) != c_orderTargetUnit) || (UnitTypeTestAttribute(UnitGetType(OrderGetTargetUnit(lv_order)), c_unitAttributeStructure) == false))) {
                continue;
            }
            else {
            }
            libAIAI_gf_HeroAIEval(lp_trigPlayer);
            if (((libAIAI_gf_HeroAIUnitProtectedByTower(lv_enemy, libAIAI_gv_aIHeroFarFromTowerDistance) == true) || (libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(lv_enemy), libAIAI_gv_aIHeroCloseToSiegeEnemyDistance, true, true, true) > libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval))) {
                continue;
            }
            else {
            }
            lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
            if ((lv_targetEval < lv_bestTargetEval)) {
                lv_bestTarget = lv_enemy;
                lv_bestTargetEval = lv_targetEval;
            }
            else {
            }
        }
    }
    else {
    }
    if ((UnitIsValid(lv_bestTarget) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget = lv_bestTarget;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 14);
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_siegeHarassTarget), c_orderQueueReplace);
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIHealthGlobeLogic (int lp_trigPlayer) {
    unitgroup auto5E59227F_g;
    int auto5E59227F_u;

    // Variable Declarations
    region lv_areaAroundGlobe;
    unitgroup lv_neabyGlobes;
    unit lv_globe;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;

    // Variable Initialization
    lv_neabyGlobes = UnitGroupEmpty();
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    if (((libAIAI_gv_aIHeroPickUpHealthGlobes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == false) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 3.0) == true))) {
        return false;
    }
    else {
    }
    lv_neabyGlobes = UnitGroupSearch("RegenGlobe", c_playerAny, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroHealthGlobeSearchRadius, UnitFilter(0, 0, 0, 0), 0);
    auto5E59227F_g = lv_neabyGlobes;
    auto5E59227F_u = 1;
    for ( ; auto5E59227F_u <= UnitGroupCount(auto5E59227F_g, c_unitCountAll) ; auto5E59227F_u += BoolToInt(lv_globe == UnitGroupUnit(auto5E59227F_g, auto5E59227F_u)) ) {
        lv_globe = UnitGroupUnit(auto5E59227F_g, auto5E59227F_u);
        lv_areaAroundGlobe = RegionCircle(UnitGetPosition(lv_globe), 5.0);
        lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_areaAroundGlobe, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        if ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(lv_globe), 0) == true) && (UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) == 0)) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(lv_globe)), c_orderQueueAddToFront);
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIPickUpHealthGlobeJungleLogic (int lp_trigPlayer) {
    unitgroup auto0DD62637_g;
    int auto0DD62637_u;

    // Variable Declarations
    region lv_areaAroundGlobe;
    unitgroup lv_neabyGlobes;
    unit lv_globe;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;

    // Variable Initialization
    lv_neabyGlobes = UnitGroupEmpty();
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    lv_neabyGlobes = UnitGroupSearch("RegenGlobe", c_playerAny, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroHealthGlobeSearchRadius, UnitFilter(0, 0, 0, 0), 0);
    auto0DD62637_g = lv_neabyGlobes;
    auto0DD62637_u = 1;
    for ( ; auto0DD62637_u <= UnitGroupCount(auto0DD62637_g, c_unitCountAll) ; auto0DD62637_u += BoolToInt(lv_globe == UnitGroupUnit(auto0DD62637_g, auto0DD62637_u)) ) {
        lv_globe = UnitGroupUnit(auto0DD62637_g, auto0DD62637_u);
        if ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(lv_globe), 0) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe = lv_globe;
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 17);
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetHealthGlobe)), c_orderQueueReplace);
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIDrinkMoonwellLogic (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_currentHealthPercent;
    int lv_desiredHealth;
    int lv_healingNeeded;
    region lv_nearbyRegion;
    unitgroup lv_nearbyMoonwells;

    // Variable Initialization
    lv_nearbyMoonwells = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_aIHeroUseMoonwells[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == false)) {
        return false;
    }
    else {
    }
    lv_currentHealthPercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if (((lv_currentHealthPercent >= (80.0 - libAIAI_gv_aIMoonwellHealPercent)) || ((lv_currentHealthPercent + libAIAI_gv_aIMoonwellHealPercent) < libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) {
        return false;
    }
    else {
    }
    if ((UnitHasBehavior2(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "HealingFountainCooldown") == true)) {
        return false;
    }
    else {
    }
    lv_nearbyRegion = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroMoonwellSearchRadius);
    lv_nearbyMoonwells = libNtve_gf_UnitsInRegionWithAllianceToPlayerMatchingCondition("TownMoonwell", "TownMoonwellL2", "TownMoonwellL3", lp_trigPlayer, c_unitAllianceAlly, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((UnitGroupCount(lv_nearbyMoonwells, c_unitCountAlive) > 0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetMoonwell = UnitGroupClosestToPoint(lv_nearbyMoonwells, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 26);
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldWaitForMinions (int lp_trigPlayer) {
    // Variable Declarations
    point lv_contentionPoint;
    fixed lv_frontMinionPosition;

    // Variable Initialization

    // Implementation
    if (((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState == 2) || (libAIAI_gf_HeroAIEnemyTeamCursed(lp_trigPlayer) == true))) {
        return false;
    }
    else {
    }
    lv_contentionPoint = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPoint;
    lv_frontMinionPosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontMinionPosition;
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_contentionPoint) < 8.0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyHeroesNearContentionPoint == 0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyMinionsNearContentionPoint == 0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numNonSiegeAllyMinionsNearContentionPoint == 0)) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIStartWaitForMinions (int lp_trigPlayer) {
    // Implementation
    libAIAI_gf_HeroAIChooseNewWaitingPosition(lp_trigPlayer);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 15);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
}

void libAIAI_gf_HeroAIChooseNewWaitingPosition (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_laneOffset;
    fixed lv_distanceBehindContentionPoint;

    // Variable Initialization

    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextWaitingRepositionTime = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed(1.0, 4.0));
    lv_laneOffset = RandomFixed((-1.0 * libAIAI_gv_aIHeroMaximumLaneOffset), libAIAI_gv_aIHeroMaximumLaneOffset);
    lv_distanceBehindContentionPoint = RandomFixed(1.0, 4.0);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = libAIAI_gf_HeroAIGetPositionBehindContentionPoint(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_distanceBehindContentionPoint, lv_laneOffset);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
}

bool libAIAI_gf_HeroAIHarassInJungleLogic (int lp_trigPlayer, bool lp_aggresivelyHarass) {
    // Variable Declarations
    fixed lv_weaponRange;
    region lv_closeToHero;
    unitgroup lv_enemies;
    unit lv_harassTarget;
    unitgroup lv_enemyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextHarassInJungleCheckTime >= TimerGetElapsed(libGame_gv_gameTimer))) {
        return false;
    }
    else {
    }
    lv_weaponRange = libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_closeToHero = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), (lv_weaponRange + 2.0));
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_closeToHero, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) == 0)) {
        return false;
    }
    else {
    }
    if ((lp_aggresivelyHarass == true)) {
        lv_harassTarget = UnitGroupClosestToPoint(lv_enemyHeroes, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    }
    else {
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 1)) {
            return false;
        }
        else {
        }
        lv_harassTarget = UnitGroupUnit(lv_enemyHeroes, 1);
        if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= UnitGetPropertyFixed(UnitGroupUnit(lv_enemyHeroes, 1), c_unitPropLifePercent, c_unitPropCurrent))) {
            return false;
        }
        else {
        }
    }
    libAIAI_gf_HeroAIStartHarassInJungle(lp_trigPlayer, lv_harassTarget);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextHarassInJungleCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroHarassInJungleTimeout - 1.0), (libAIAI_gv_aIHeroHarassInJungleTimeout + 1.0)));
    return true;
}

void libAIAI_gf_HeroAIStartHarassInJungle (int lp_trigPlayer, unit lp_target) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroHarassInJungleDuration);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget = lp_target;
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 46);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_harassInJungleTarget), c_orderQueueReplace);
}

bool libAIAI_gf_HeroAIPaceAroundLogic (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == true) && (libAIAI_gf_HeroAITimeInCurrentState(lp_trigPlayer) > libAIAI_gv_aIHeroPaceAroundDelay) && (libAIAI_gf_HeroAIAttackingWeakHumanHero(lp_trigPlayer, 75.0) == true)) {
        libAIAI_gf_HeroAIStartPaceAround(lp_trigPlayer);
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIStartPaceAround (int lp_trigPlayer) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_paceAroundStartPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_paceAroundTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroPaceAroundDuration + RandomFixed(-0.5, 0.5));
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextPaceAroundRepositionTime = TimerGetElapsed(libGame_gv_gameTimer);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 47);
}

void libAIAI_gf_HeroAITeamLogic (int lp_faction) {
    // Implementation
    libAIAI_gf_HeroAIUpdateGameState(lp_faction);
    libAIAI_gf_HeroAIUpdateHomeEval(lp_faction);
    if ((lp_faction == 0)) {
        libAIAI_gf_HeroAIEvalLanes(0);
    }
    else {
        libAIAI_gf_HeroAIEvalLanes(1);
    }
    libAIAI_gf_HeroAILeashFollowers(lp_faction);
    libAIAI_gf_HeroAIFollowLeaderTimeout(lp_faction);
    libAIAI_gf_HeroAIChooseABChoices(lp_faction);
    libAIAI_gf_HeroAISwapLanesLogic(lp_faction);
    libAIAI_gf_HeroAIAbathurLogic(lp_faction);
    libAIAI_gf_HeroAIDefendCoreLogic(lp_faction);
    libAIAI_gf_HeroAIReturnToDefendCoreLogic(lp_faction);
    libAIAI_gf_HeroAIFocusPingedHeroLogic(lp_faction);
    libAIAI_gf_HeroAIFocusWeakHeroLogic(lp_faction);
    libAIAI_gf_HeroAIInitiateTeamFightLogic(lp_faction);
    libAIAI_gf_HeroAIFocusPingedCore(lp_faction);
    libAIAI_gf_HeroAIFocusWeakCore(lp_faction);
    libAIAI_gf_HeroAIWaitInSpawnLogic(lp_faction);
    libAIAI_gf_HeroAITeamStrategyLogic(lp_faction);
    libAIAI_gf_HeroAIMinionCampLogic(lp_faction);
    libAIAI_gf_HeroAIJoinCampLogic(lp_faction);
    libAIAI_gf_HeroAICaptureWatchTowerLogic(lp_faction);
    if ((libMapM_gf_MapMechanicExistsOnMap(1) == true)) {
        libAIAI_gf_HeroAICaptureTearOfEluneLogic(lp_faction);
    }
    else {
    }
    if ((libMapM_gf_MapMechanicExistsOnMap(2) == true)) {
        libAIAI_gf_HeroAIPickUpDoubloonsLogic(lp_faction);
        libAIAI_gf_HeroAITurnInDoubloonsLogic(lp_faction);
        libAIAI_gf_HeroAIAttackTreasureChestLogic(lp_faction);
    }
    else {
    }
    if ((libMapM_gf_MapMechanicExistsOnMap(3) == true)) {
        libAIAI_gf_HeroAICaptureObeliskLogic(lp_faction);
        libAIAI_gf_HeroAICaptureDragonLogic(lp_faction);
    }
    else {
    }
    if ((libMapM_gf_MapMechanicExistsOnMap(4) == true)) {
        libAIAI_gf_HeroAIEnterUnderworldLogic(lp_faction);
        libAIAI_gf_HeroAIPickupSkullsLogic(lp_faction);
    }
    else {
    }
    libAIAI_gf_HeroAICleanUp(lp_faction);
}

void libAIAI_gf_HeroAITeamStrategyLogic (int lp_faction) {
    // Variable Declarations
    playergroup lv_team;
    int lv_teamIndex;
    int lv_playerOnTeam;
    int lv_playerIndex;
    int lv_currentTeamLane;
    bool lv_campFound;

    // Variable Initialization
    lv_team = PlayerGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_team = libCore_gv_teamOrder;
        lv_teamIndex = (0);
    }
    else {
        lv_team = libCore_gv_teamChaos;
        lv_teamIndex = (1);
    }
    if (((PlayerGroupCount(lv_team) == 0) || (libAIAI_gv_aIHeroPerformTeamStrategies[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)] == false) || (libAIAI_gf_HeroAITeamHasHumanPlayers(lp_faction) == true) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextTeamStrategyTime >= TimerGetElapsed(libGame_gv_gameTimer)) || (libAIAI_gf_HeroAIIsTeamBusy(lp_faction) == true))) {
        return ;
    }
    else {
    }
    lv_playerOnTeam = PlayerGroupPlayer(lv_team, 1);
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState == 2)) {
        if ((libAIAI_gf_HeroAIIsSideOfMapSafe(libGame_gv_players[lv_playerOnTeam].lv_faction, 0.5) == true)) {
            lv_campFound = libAIAI_gf_HeroAITeamAttackCampLogic(lp_faction, 500.0);
            if ((lv_campFound == true)) {
                libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextTeamStrategyTime = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroTeamStrategyDelay - 5.0), (libAIAI_gv_aIHeroTeamStrategyDelay + 5.0)));
                return ;
            }
            else {
            }
        }
        else {
        }
    }
    else {
    }
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextTeamStrategyTime = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroTeamStrategyConsiderFrequency - 3.0), (libAIAI_gv_aIHeroTeamStrategyConsiderFrequency + 3.0)));
}

void libAIAI_gf_HeroAICleanUp (int lp_faction) {
    int auto9768679F_ae;
    int auto9768679F_ai;
    int autoA6AC63CC_ae;
    int autoA6AC63CC_ai;
    int auto65F78E71_ae;
    int auto65F78E71_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_pingIndex;
    int lv_avoidAreaIndex;
    int lv_secondaryAvoidAreaIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto9768679F_ae = libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_numberofCampPings;
    auto9768679F_ai = 1;
    lv_pingIndex = 1;
    for ( ; ( (auto9768679F_ai >= 0 && lv_pingIndex <= auto9768679F_ae) || (auto9768679F_ai <= 0 && lv_pingIndex >= auto9768679F_ae) ) ; lv_pingIndex += auto9768679F_ai ) {
        if (((libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_campPings[lv_pingIndex].lv_pingTime + libAIAI_gv_aIHeroCampPingDuration) < TimerGetElapsed(libGame_gv_gameTimer))) {
            libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_numberofCampPings = (lv_pingIndex - 1);
            break;
        }
        else {
        }
    }
    autoA6AC63CC_ae = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_numberofAvoidAreas;
    autoA6AC63CC_ai = 1;
    lv_avoidAreaIndex = 1;
    for ( ; ( (autoA6AC63CC_ai >= 0 && lv_avoidAreaIndex <= autoA6AC63CC_ae) || (autoA6AC63CC_ai <= 0 && lv_avoidAreaIndex >= autoA6AC63CC_ae) ) ; lv_avoidAreaIndex += autoA6AC63CC_ai ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_expireTime < TimerGetElapsed(libGame_gv_gameTimer))) {
            auto65F78E71_ae = (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_numberofAvoidAreas - 1);
            auto65F78E71_ai = 1;
            lv_secondaryAvoidAreaIndex = lv_avoidAreaIndex;
            for ( ; ( (auto65F78E71_ai >= 0 && lv_secondaryAvoidAreaIndex <= auto65F78E71_ae) || (auto65F78E71_ai <= 0 && lv_secondaryAvoidAreaIndex >= auto65F78E71_ae) ) ; lv_secondaryAvoidAreaIndex += auto65F78E71_ai ) {
                libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_secondaryAvoidAreaIndex].lv_unit = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[(lv_secondaryAvoidAreaIndex + 1)].lv_unit;
                libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_secondaryAvoidAreaIndex].lv_position = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[(lv_secondaryAvoidAreaIndex + 1)].lv_position;
                libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_secondaryAvoidAreaIndex].lv_radius = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[(lv_secondaryAvoidAreaIndex + 1)].lv_radius;
                libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_secondaryAvoidAreaIndex].lv_expireTime = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[(lv_secondaryAvoidAreaIndex + 1)].lv_expireTime;
            }
            libAIAI_gv_heroAITeamData[lv_teamIndex].lv_numberofAvoidAreas -= 1;
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAICalcCurrentLaneInfo (int lp_player) {
    // Variable Declarations
    point lv_closestPoint;
    int lv_closestIndex;
    int lv_secondaryIndex;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_currentLane <= 0)) {
        return ;
    }
    else {
    }
    libGame_gf_CalculateClosestLaneData(UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit));
    lv_closestIndex = libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_closestIndex;
    lv_secondaryIndex = libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_secondaryIndex;
    lv_closestPoint = libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_closestPoint;
    libAIAI_gv_aIHeroes[lp_player].lv_heroClosestLanePoint = lv_closestPoint;
    libAIAI_gv_aIHeroes[lp_player].lv_heroLaneDirection = AIGetDirection(lv_closestPoint, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint);
    libAIAI_gv_aIHeroes[lp_player].lv_heroLanePosition = AILaneWaypointConvertPointToWaydist(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, lv_closestIndex, lv_secondaryIndex, lv_closestPoint);
}

void libAIAI_gf_HeroAIEval (int lp_player) {
    // Variable Declarations
    region lv_enemyRegion;
    region lv_friendlyRegion;
    point lv_curDir;
    point lv_curPos;
    fixed lv_extendEnemyRegion;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_nextEvalUpdateTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
    }
    libAIAI_gv_heroAIDidEval = true;
    libAIAI_gf_HeroAIClearEval(lp_player);
    libAIAI_gv_aIHeroes[lp_player].lv_nextEvalUpdateTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroNearbyEvalFrequency);
    lv_friendlyRegion = RegionEmpty();
    lv_enemyRegion = RegionEmpty();
    if ((libAIAI_gv_aIHeroes[lp_player].lv_currentLane <= 0)) {
        if ((UnitGetPropertyFixed(libGame_gv_players[lp_player].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_player].lv_difficulty)]))) {
            lv_extendEnemyRegion = 4.0;
        }
        else {
        }
        RegionAddCircle(lv_enemyRegion, true, UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit), (8.0 + lv_extendEnemyRegion));
        RegionAddCircle(lv_friendlyRegion, true, UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit), 8.0);
    }
    else {
        libAIAI_gf_HeroAICalcCurrentLaneInfo(lp_player);
        if ((UnitGetPropertyFixed(libGame_gv_players[lp_player].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (10.0 + libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_player].lv_difficulty)]))) {
            lv_extendEnemyRegion = 3.0;
        }
        else {
        }
        lv_curDir = libAIAI_gv_aIHeroes[lp_player].lv_heroLaneDirection;
        lv_curDir = Point((PointGetX(lv_curDir) * (8.0 + lv_extendEnemyRegion)), (PointGetY(lv_curDir) * (8.0 + lv_extendEnemyRegion)));
        lv_curPos = libAIAI_gv_aIHeroes[lp_player].lv_heroClosestLanePoint;
        RegionAddCircle(lv_enemyRegion, true, lv_curPos, (10.0 + lv_extendEnemyRegion));
        lv_curPos = Point((PointGetX(lv_curPos) + PointGetX(lv_curDir)), (PointGetY(lv_curPos) + PointGetY(lv_curDir)));
        RegionAddCircle(lv_enemyRegion, true, lv_curPos, (10.0 + lv_extendEnemyRegion));
        lv_curPos = libAIAI_gv_aIHeroes[lp_player].lv_heroClosestLanePoint;
        lv_curPos = Point((PointGetX(lv_curPos) - PointGetX(lv_curDir)), (PointGetY(lv_curPos) - PointGetY(lv_curDir)));
        RegionAddCircle(lv_enemyRegion, true, lv_curPos, (10.0 + lv_extendEnemyRegion));
        if ((libAIAI_gf_HeroAIIsInAdvancingState(lp_player) == true)) {
            lv_curDir = libAIAI_gv_aIHeroes[lp_player].lv_heroLaneDirection;
            lv_curDir = Point((PointGetX(lv_curDir) * 6.0), (PointGetY(lv_curDir) * 6.0));
            lv_curPos = libAIAI_gv_aIHeroes[lp_player].lv_heroClosestLanePoint;
            lv_curPos = Point((PointGetX(lv_curPos) + PointGetX(lv_curDir)), (PointGetY(lv_curPos) + PointGetY(lv_curDir)));
            RegionAddCircle(lv_friendlyRegion, true, lv_curPos, 10.0);
        }
        else {
            lv_curDir = libAIAI_gv_aIHeroes[lp_player].lv_heroLaneDirection;
            lv_curDir = Point((PointGetX(lv_curDir) * -3.5), (PointGetY(lv_curDir) * -3.5));
            lv_curPos = libAIAI_gv_aIHeroes[lp_player].lv_heroClosestLanePoint;
            lv_curPos = Point((PointGetX(lv_curPos) + PointGetX(lv_curDir)), (PointGetY(lv_curPos) + PointGetY(lv_curDir)));
            RegionAddCircle(lv_friendlyRegion, true, lv_curPos, 6.5);
        }
    }
    libAIAI_gf_HeroAINearbyEval(lp_player, lv_enemyRegion, lv_friendlyRegion);
}

void libAIAI_gf_HeroAINearbyEval (int lp_trigPlayer, region lp_enemyRegion, region lp_friendlyRegion) {
    playergroup autoB9C84F4C_g;
    int autoB9C84F4C_p;
    unitgroup autoBDEBA7C0_g;
    int autoBDEBA7C0_u;
    unitgroup autoAE60BA4F_g;
    int autoAE60BA4F_u;
    unitgroup auto3EB2FA8D_g;
    int auto3EB2FA8D_u;
    unitgroup auto7C39C96F_g;
    int auto7C39C96F_u;
    unitgroup auto4632FFF9_g;
    int auto4632FFF9_u;

    // Variable Declarations
    unit lv_curUnit;
    fixed lv_curEval;
    unitgroup lv_enemies;
    unitgroup lv_friendlies;
    unitgroup lv_heroes;
    unitgroup lv_minions;
    unitgroup lv_summons;
    unitgroup lv_minionsAndSummons;
    unitgroup lv_towers;
    int lv_playerIndex;
    bool lv_seenRecently;
    bool lv_isNearby;
    int lv_teamIndex;
    unit lv_underworldBoss;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_friendlies = UnitGroupEmpty();
    lv_heroes = UnitGroupEmpty();
    lv_minions = UnitGroupEmpty();
    lv_summons = UnitGroupEmpty();
    lv_minionsAndSummons = UnitGroupEmpty();
    lv_towers = UnitGroupEmpty();

    // Implementation
    lv_curEval = libAIAI_gf_HeroAIHeroEval(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval = lv_curEval;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval = lv_curEval;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval = lv_curEval;
    UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allies, libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroes, libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    autoB9C84F4C_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetEnemyTeamIndex(lp_trigPlayer)].lv_players; 
    autoB9C84F4C_p = 1;
    for ( ; autoB9C84F4C_p <= PlayerGroupCount(autoB9C84F4C_g) ; autoB9C84F4C_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoB9C84F4C_g, autoB9C84F4C_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoB9C84F4C_g, autoB9C84F4C_p);
        if ((TimerGetRemaining(libGame_gv_players[lv_playerIndex].lv_respawnTimer) <= 0.0)) {
            lv_seenRecently = ((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenTime + libAIAI_gv_aIHeroMissingDelay) >= TimerGetElapsed(libGame_gv_gameTimer));
            lv_isNearby = RegionContainsPoint(lp_enemyRegion, libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLocation);
            if ((lv_seenRecently == true) && (lv_isNearby == true)) {
                if ((libNtve_gf_UnitIsVisibleToPlayer(libGame_gv_players[lv_playerIndex].lv_heroUnit, lp_trigPlayer) == true)) {
                    lv_curEval = libAIAI_gf_HeroAIHeroEval(libGame_gv_players[lv_playerIndex].lv_heroUnit);
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += lv_curEval;
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval += lv_curEval;
                    UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemies, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                    UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                }
                else {
                    lv_curEval = (libAIAI_gv_aIHeroLevelEvalValue * UnitLevel(libGame_gv_players[lv_playerIndex].lv_heroUnit));
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += lv_curEval;
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval += lv_curEval;
                }
            }
            else {
                if ((libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (lv_seenRecently == false) && (libCore_gf_TestLocationClosertoFactionSide(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libGame_gv_players[lp_trigPlayer].lv_faction, 1.2) == false)) {
                    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += (libAIAI_gv_aIMissingHeroLevelEvalValue * UnitLevel(libGame_gv_players[lv_playerIndex].lv_heroUnit));
                }
                else {
                }
            }
        }
        else {
        }
    }
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lp_enemyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_minions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_summons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    lv_minionsAndSummons = UnitGroupEmpty();
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
    autoBDEBA7C0_g = lv_minionsAndSummons;
    autoBDEBA7C0_u = 1;
    for ( ; autoBDEBA7C0_u <= UnitGroupCount(autoBDEBA7C0_g, c_unitCountAll) ; autoBDEBA7C0_u += BoolToInt(lv_curUnit == UnitGroupUnit(autoBDEBA7C0_g, autoBDEBA7C0_u)) ) {
        lv_curUnit = UnitGroupUnit(autoBDEBA7C0_g, autoBDEBA7C0_u);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += (libAIAI_gv_aIHeroEnemyMinionSummonEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemies, lv_curUnit);
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyMinionsSummons, lv_curUnit);
    }
    lv_towers = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    autoAE60BA4F_g = lv_towers;
    autoAE60BA4F_u = 1;
    for ( ; autoAE60BA4F_u <= UnitGroupCount(autoAE60BA4F_g, c_unitCountAll) ; autoAE60BA4F_u += BoolToInt(lv_curUnit == UnitGroupUnit(autoAE60BA4F_g, autoAE60BA4F_u)) ) {
        lv_curUnit = UnitGroupUnit(autoAE60BA4F_g, autoAE60BA4F_u);
        if ((libAIAI_gf_HeroAIIsTowerAThreat(lv_curUnit) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += (libAIAI_gv_aIHeroEnemyTowerEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowerEval += (libAIAI_gv_aIHeroEnemyTowerEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
        else {
        }
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemies, lv_curUnit);
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowers, lv_curUnit);
    }
    lv_friendlies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAllyExcludeSelf, lp_friendlyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_heroes = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    auto3EB2FA8D_g = lv_heroes;
    auto3EB2FA8D_u = 1;
    for ( ; auto3EB2FA8D_u <= UnitGroupCount(auto3EB2FA8D_g, c_unitCountAll) ; auto3EB2FA8D_u += BoolToInt(lv_curUnit == UnitGroupUnit(auto3EB2FA8D_g, auto3EB2FA8D_u)) ) {
        lv_curUnit = UnitGroupUnit(auto3EB2FA8D_g, auto3EB2FA8D_u);
        lv_curEval = libAIAI_gf_HeroAIHeroEval(lv_curUnit);
        if ((libAIAI_gf_HeroAIIsPlayerActive(UnitGetOwner(lv_curUnit), 1) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanAllyHeroNearby = true;
            lv_curEval *= 10.0;
        }
        else {
        }
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval += lv_curEval;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval += lv_curEval;
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allies, lv_curUnit);
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroes, lv_curUnit);
    }
    lv_minions = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_summons = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    lv_minionsAndSummons = UnitGroupEmpty();
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
    auto7C39C96F_g = lv_minionsAndSummons;
    auto7C39C96F_u = 1;
    for ( ; auto7C39C96F_u <= UnitGroupCount(auto7C39C96F_g, c_unitCountAll) ; auto7C39C96F_u += BoolToInt(lv_curUnit == UnitGroupUnit(auto7C39C96F_g, auto7C39C96F_u)) ) {
        lv_curUnit = UnitGroupUnit(auto7C39C96F_g, auto7C39C96F_u);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval += (libAIAI_gv_aIHeroAllyMinionSummonEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allies, lv_curUnit);
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, lv_curUnit);
    }
    lv_towers = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    auto4632FFF9_g = lv_towers;
    auto4632FFF9_u = 1;
    for ( ; auto4632FFF9_u <= UnitGroupCount(auto4632FFF9_g, c_unitCountAll) ; auto4632FFF9_u += BoolToInt(lv_curUnit == UnitGroupUnit(auto4632FFF9_g, auto4632FFF9_u)) ) {
        lv_curUnit = UnitGroupUnit(auto4632FFF9_g, auto4632FFF9_u);
        if ((libAIAI_gf_HeroAIIsTowerAThreat(lv_curUnit) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval += (libAIAI_gv_aIHeroAllyTowerEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowerEval += (libAIAI_gv_aIHeroAllyTowerEvalValue * (UnitGetPropertyFixed(lv_curUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
        else {
        }
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allies, lv_curUnit);
        UnitGroupAdd(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowers, lv_curUnit);
    }
    if ((UnitIsValid(libAIAI_gv_heroAIDragonShireDragon) == true)) {
        if ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(libAIAI_gv_heroAIDragonShireDragon), 0) == true)) {
            if ((libNtve_gf_UnitInRegion(libAIAI_gv_heroAIDragonShireDragon, lp_friendlyRegion) == true)) {
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval += libAIAI_gf_HeroAIHeroEval(libAIAI_gv_heroAIDragonShireDragon);
            }
            else {
            }
        }
        else {
            if ((libNtve_gf_UnitInRegion(libAIAI_gv_heroAIDragonShireDragon, lp_enemyRegion) == true)) {
                libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval += libAIAI_gf_HeroAIHeroEval(libAIAI_gv_heroAIDragonShireDragon);
            }
            else {
            }
        }
    }
    else {
    }
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    if ((libAIAI_gv_heroAIUnderworldBossStatus[lv_teamIndex].lv_state == 2)) {
        lv_underworldBoss = libAIAI_gv_heroAIUnderworldBossStatus[lv_teamIndex].lv_underworldBossUnit;
        if ((libNtve_gf_UnitInRegion(lv_underworldBoss, lp_friendlyRegion) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval += (libAIAI_gv_aIHeroAllyUnderworldBossEvalValue * (UnitGetPropertyFixed(lv_underworldBoss, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
        else {
        }
    }
    else {
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowerEval *= ((100.0 - libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) / 100.0);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval *= ((100.0 - libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) / 100.0);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval *= ((100.0 - libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) / 100.0);
}

void libAIAI_gf_HeroAIClearEval (int lp_player) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_player].lv_nextEvalUpdateTime = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_totalEnemyEval = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_enemyHeroEval = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_enemyTowerEval = 0.0;
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_enemies);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_enemyHeroes);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_enemyMinionsSummons);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_enemyTowers);
    libAIAI_gv_aIHeroes[lp_player].lv_totalAllyEval = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_allyHeroEval = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_allyTowerEval = 0.0;
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_allies);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_allyHeroes);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_allyMinionsSummons);
    UnitGroupClear(libAIAI_gv_aIHeroes[lp_player].lv_allyTowers);
    libAIAI_gv_aIHeroes[lp_player].lv_selfEval = 0.0;
    libAIAI_gv_aIHeroes[lp_player].lv_humanAllyHeroNearby = false;
}

fixed libAIAI_gf_HeroAIEnemyEvalInArea (int lp_trigPlayer, point lp_position, fixed lp_radius, bool lp_includeHeroes, bool lp_includeMinionsSummons, bool lp_includeTowers) {
    unitgroup auto6FB14B48_g;
    int auto6FB14B48_u;
    unitgroup autoB747A3B2_g;
    int autoB747A3B2_u;
    unitgroup auto74A9D374_g;
    int auto74A9D374_u;

    // Variable Declarations
    region lv_region;
    fixed lv_totalEval;
    unit lv_enemy;
    unitgroup lv_enemies;
    int lv_playerIndex;
    unitgroup lv_heroes;
    unitgroup lv_minions;
    unitgroup lv_summons;
    unitgroup lv_minionsAndSummons;
    unitgroup lv_towers;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_heroes = UnitGroupEmpty();
    lv_minions = UnitGroupEmpty();
    lv_summons = UnitGroupEmpty();
    lv_minionsAndSummons = UnitGroupEmpty();
    lv_towers = UnitGroupEmpty();

    // Implementation
    lv_region = RegionCircle(lp_position, lp_radius);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_region, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((lp_includeHeroes == true)) {
        lv_heroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        auto6FB14B48_g = lv_heroes;
        auto6FB14B48_u = 1;
        for ( ; auto6FB14B48_u <= UnitGroupCount(auto6FB14B48_g, c_unitCountAll) ; auto6FB14B48_u += BoolToInt(lv_enemy == UnitGroupUnit(auto6FB14B48_g, auto6FB14B48_u)) ) {
            lv_enemy = UnitGroupUnit(auto6FB14B48_g, auto6FB14B48_u);
            lv_totalEval += libAIAI_gf_HeroAIHeroEval(lv_enemy);
        }
    }
    else {
    }
    if ((lp_includeMinionsSummons == true)) {
        lv_minions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
        lv_summons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
        lv_minionsAndSummons = UnitGroupEmpty();
        UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
        UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
        autoB747A3B2_g = lv_minionsAndSummons;
        autoB747A3B2_u = 1;
        for ( ; autoB747A3B2_u <= UnitGroupCount(autoB747A3B2_g, c_unitCountAll) ; autoB747A3B2_u += BoolToInt(lv_enemy == UnitGroupUnit(autoB747A3B2_g, autoB747A3B2_u)) ) {
            lv_enemy = UnitGroupUnit(autoB747A3B2_g, autoB747A3B2_u);
            lv_totalEval += (libAIAI_gv_aIHeroEnemyMinionSummonEvalValue * (UnitGetPropertyFixed(lv_enemy, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
    }
    else {
    }
    if ((lp_includeTowers == true)) {
        lv_towers = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
        auto74A9D374_g = lv_towers;
        auto74A9D374_u = 1;
        for ( ; auto74A9D374_u <= UnitGroupCount(auto74A9D374_g, c_unitCountAll) ; auto74A9D374_u += BoolToInt(lv_enemy == UnitGroupUnit(auto74A9D374_g, auto74A9D374_u)) ) {
            lv_enemy = UnitGroupUnit(auto74A9D374_g, auto74A9D374_u);
            lv_totalEval += (libAIAI_gv_aIHeroEnemyTowerEvalValue * (UnitGetPropertyFixed(lv_enemy, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
    }
    else {
    }
    lv_totalEval *= ((100.0 - libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) / 100.0);
    return lv_totalEval;
}

fixed libAIAI_gf_HeroAIAllyEvalInArea (int lp_trigPlayer, point lp_position, fixed lp_radius, bool lp_includeHeroes, bool lp_includeMinionsSummons, bool lp_includeTowers) {
    unitgroup autoE9D1085F_g;
    int autoE9D1085F_u;
    unitgroup auto1C4FF477_g;
    int auto1C4FF477_u;
    unitgroup auto1B0BA079_g;
    int auto1B0BA079_u;

    // Variable Declarations
    region lv_region;
    fixed lv_totalEval;
    unit lv_unit;
    unitgroup lv_allies;
    unitgroup lv_heroes;
    unitgroup lv_minions;
    unitgroup lv_summons;
    unitgroup lv_minionsAndSummons;
    unitgroup lv_towers;

    // Variable Initialization
    lv_allies = UnitGroupEmpty();
    lv_heroes = UnitGroupEmpty();
    lv_minions = UnitGroupEmpty();
    lv_summons = UnitGroupEmpty();
    lv_minionsAndSummons = UnitGroupEmpty();
    lv_towers = UnitGroupEmpty();

    // Implementation
    lv_region = RegionCircle(lp_position, lp_radius);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, lv_region, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((lp_includeHeroes == true)) {
        lv_heroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        autoE9D1085F_g = lv_heroes;
        autoE9D1085F_u = 1;
        for ( ; autoE9D1085F_u <= UnitGroupCount(autoE9D1085F_g, c_unitCountAll) ; autoE9D1085F_u += BoolToInt(lv_unit == UnitGroupUnit(autoE9D1085F_g, autoE9D1085F_u)) ) {
            lv_unit = UnitGroupUnit(autoE9D1085F_g, autoE9D1085F_u);
            lv_totalEval += libAIAI_gf_HeroAIHeroEval(lv_unit);
        }
    }
    else {
    }
    if ((lp_includeMinionsSummons == true)) {
        lv_minions = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
        lv_summons = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
        lv_minionsAndSummons = UnitGroupEmpty();
        UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
        UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
        auto1C4FF477_g = lv_minionsAndSummons;
        auto1C4FF477_u = 1;
        for ( ; auto1C4FF477_u <= UnitGroupCount(auto1C4FF477_g, c_unitCountAll) ; auto1C4FF477_u += BoolToInt(lv_unit == UnitGroupUnit(auto1C4FF477_g, auto1C4FF477_u)) ) {
            lv_unit = UnitGroupUnit(auto1C4FF477_g, auto1C4FF477_u);
            lv_totalEval += (libAIAI_gv_aIHeroAllyMinionSummonEvalValue * (UnitGetPropertyFixed(lv_unit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
    }
    else {
    }
    if ((lp_includeTowers == true)) {
        lv_towers = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
        auto1B0BA079_g = lv_towers;
        auto1B0BA079_u = 1;
        for ( ; auto1B0BA079_u <= UnitGroupCount(auto1B0BA079_g, c_unitCountAll) ; auto1B0BA079_u += BoolToInt(lv_unit == UnitGroupUnit(auto1B0BA079_g, auto1B0BA079_u)) ) {
            lv_unit = UnitGroupUnit(auto1B0BA079_g, auto1B0BA079_u);
            lv_totalEval += (libAIAI_gv_aIHeroAllyTowerEvalValue * (UnitGetPropertyFixed(lv_unit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0));
        }
    }
    else {
    }
    return lv_totalEval;
}

bool libAIAI_gf_HeroAIHumanAllyInArea (int lp_trigPlayer, point lp_position, fixed lp_radius) {
    int autoBE486E5A_ae;
    int autoBE486E5A_ai;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    autoBE486E5A_ae = libCore_gv_bALMaxPlayers;
    autoBE486E5A_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoBE486E5A_ai >= 0 && lv_playerIndex <= autoBE486E5A_ae) || (autoBE486E5A_ai <= 0 && lv_playerIndex >= autoBE486E5A_ae) ) ; lv_playerIndex += autoBE486E5A_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lp_position) < lp_radius)) {
            return true;
        }
        else {
        }
    }
    return false;
}

unitgroup libAIAI_gf_HeroAIAllyHeroesinArea (int lp_trigPlayer, fixed lp_radius) {
    int autoCBBE96F7_ae;

    // Variable Declarations
    int lv_playerIndex;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    autoCBBE96F7_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoCBBE96F7_ae ; lv_playerIndex += 1 ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) <= lp_radius)) {
            UnitGroupAdd(lv_allyHeroes, libGame_gv_players[lv_playerIndex].lv_heroUnit);
        }
        else {
        }
    }
    return lv_allyHeroes;
}

fixed libAIAI_gf_HeroAIHeroEval (unit lp_heroUnit) {
    // Variable Declarations
    fixed lv_healthPercent;

    // Variable Initialization

    // Implementation
    lv_healthPercent = (UnitGetPropertyFixed(lp_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) / 100.0);
    lv_healthPercent = libNtve_gf_ArithmeticRealClamp(lv_healthPercent, 0.0, 1.0);
    lv_healthPercent = (1.0 - lv_healthPercent);
    lv_healthPercent = (1.5 * (lv_healthPercent * lv_healthPercent));
    lv_healthPercent = (1.0 - lv_healthPercent);
    lv_healthPercent = libNtve_gf_ArithmeticRealClamp(lv_healthPercent, 0.0, 1.0);
    return (lv_healthPercent * (libAIAI_gv_aIHeroLevelEvalValue * UnitLevel(lp_heroUnit)));
}

void libAIAI_gf_HeroAIUpdateHomeEval (int lp_team) {
    // Variable Declarations
    int lv_teamIndex;
    region lv_baseRegion;
    int lv_allyComputerPlayer;
    unit lv_coreUnit;
    unitgroup lv_enemies;
    unitgroup lv_friendlies;
    unitgroup lv_heroes;
    unitgroup lv_minions;
    unitgroup lv_summons;
    unitgroup lv_minionsAndSummons;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_friendlies = UnitGroupEmpty();
    lv_heroes = UnitGroupEmpty();
    lv_minions = UnitGroupEmpty();
    lv_summons = UnitGroupEmpty();
    lv_minionsAndSummons = UnitGroupEmpty();

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
        lv_baseRegion = libCore_gv_mAPOrderBaseRegion;
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_teamIndex = (1);
        lv_baseRegion = libCore_gv_mAPChaosBaseRegion;
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    lv_friendlies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, lv_baseRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_heroes = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numAllyHeroes = UnitGroupCount(lv_heroes, c_unitCountAlive);
    lv_minions = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_summons = UnitGroupFilter(null, c_playerAny, lv_friendlies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    lv_minionsAndSummons = UnitGroupEmpty();
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numAllyMinionsAndSummons = UnitGroupCount(lv_minionsAndSummons, c_unitCountAlive);
    lv_enemies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceEnemy, lv_baseRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_heroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numEnemyHeroes = UnitGroupCount(lv_heroes, c_unitCountAlive);
    lv_minions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_summons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    lv_minionsAndSummons = UnitGroupEmpty();
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_minions);
    UnitGroupAddUnitGroup(lv_minionsAndSummons, lv_summons);
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numEnemyMinionsAndSummons = UnitGroupCount(lv_minionsAndSummons, c_unitCountAlive);
}

void libAIAI_gf_HeroAIUpdateTeamPlayerData (int lp_team) {
    int auto90ED577E_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    PlayerGroupClear(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_players);
    PlayerGroupClear(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_humanPlayers);
    PlayerGroupClear(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_aIPlayers);
    auto90ED577E_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto90ED577E_ae ; lv_playerIndex += 1 ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_team)) {
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true)) {
                PlayerGroupAdd(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_players, lv_playerIndex);
                PlayerGroupAdd(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_humanPlayers, lv_playerIndex);
            }
            else {
                if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true)) {
                    PlayerGroupAdd(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_players, lv_playerIndex);
                    PlayerGroupAdd(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_aIPlayers, lv_playerIndex);
                }
                else {
                }
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIUpdateHeroTracking (int lp_team) {
    int autoB0D8C308_ae;
    playergroup auto6A92A96F_g;
    int auto6A92A96F_p;

    // Variable Declarations
    playergroup lv_allyPlayerGroup;
    int lv_allyFaction;
    int lv_enemyFaction;
    int lv_playerIndex;
    int lv_laneIndex;
    fixed lv_distanceToLane;

    // Variable Initialization
    lv_allyPlayerGroup = PlayerGroupEmpty();

    // Implementation
    if ((lp_team == 0)) {
        lv_allyPlayerGroup = libCore_gv_teamOrder;
        lv_allyFaction = 0;
        lv_enemyFaction = 1;
    }
    else {
        lv_allyPlayerGroup = libCore_gv_teamChaos;
        lv_allyFaction = 1;
        lv_enemyFaction = 0;
    }
    autoB0D8C308_ae = 10;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoB0D8C308_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (TimerGetRemaining(libGame_gv_players[lv_playerIndex].lv_respawnTimer) <= 0.0) && (libNtve_gf_UnitIsVisibleToPlayer(libGame_gv_players[lv_playerIndex].lv_heroUnit, PlayerGroupPlayer(lv_allyPlayerGroup, 1)) == true) && (UnitIsValid(libGame_gv_players[lv_playerIndex].lv_activeVehicle) == false)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenTime = TimerGetElapsed(libGame_gv_gameTimer);
            libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLocation = UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit);
            if ((libAIAI_gf_HeroAIIsPlayerInsideBase(lv_playerIndex) == false) && (libAIAI_gf_HeroAIIsPlayerInsideEnemyBase(lv_playerIndex) == false)) {
                libGame_gf_CalculateClosestLaneData(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit));
                lv_laneIndex = libGame_gv_closestLaneData.lv_closestLane;
                lv_distanceToLane = libGame_gv_closestLaneData.lv_laneData[lv_laneIndex].lv_closestDist;
                if ((lv_distanceToLane <= libAIAI_gv_aIHeroLaneLeashDistance)) {
                    if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lv_allyFaction) && (lv_laneIndex != libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLane)) {
                        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_lastTimeHumanAllyEnteredLane = TimerGetElapsed(libGame_gv_gameTimer);
                    }
                    else {
                    }
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLane = lv_laneIndex;
                }
                else {
                }
            }
            else {
            }
        }
        else {
        }
    }
    libAIAI_gv_heroAITeamData[(lp_team)].lv_numberOfMissingEnemies = 0;
    auto6A92A96F_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lv_enemyFaction)].lv_players; 
    auto6A92A96F_p = 1;
    for ( ; auto6A92A96F_p <= PlayerGroupCount(auto6A92A96F_g) ; auto6A92A96F_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto6A92A96F_g, auto6A92A96F_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto6A92A96F_g, auto6A92A96F_p);
        if ((TimerGetRemaining(libGame_gv_players[lv_playerIndex].lv_respawnTimer) <= 0.0) && ((libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_playerIndex].lv_lastSeenTime + libAIAI_gv_aIHeroMissingDelay) < TimerGetElapsed(libGame_gv_gameTimer))) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_numberOfMissingEnemies += 1;
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIUpdateLaneEvals (int lp_team) {
    int autoFCC43C9A_ae;
    int autoFCC43C9A_ai;

    // Variable Declarations
    int lv_laneToAvoid;
    int lv_curLane;
    fixed lv_curEval;
    fixed lv_worstEval;
    int lv_weakestLane;
    int lv_numAllyTowns;
    int lv_numAllyHeroes;
    int lv_numEnemyHeroes;
    int lv_numEnemySiegeGiants;
    int lv_numEnemyOgres;
    int lv_numEnemyOgreKings;
    int lv_numEnemyDragonKnights;
    int lv_numEnemyUnderworldBossSkulls;
    fixed lv_underestimateEnemyPercent;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_heroAITeamData[(lp_team)].lv_avoidPlayer != 0)) {
        lv_laneToAvoid = libAIAI_gv_heroAITeamData[(lp_team)].lv_avoidLane;
    }
    else {
    }
    lv_underestimateEnemyPercent = libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[(libAIAI_gv_heroAITeamData[(lp_team)].lv_difficulty)];
    lv_worstEval = 524287;
    autoFCC43C9A_ae = libGame_gv_laneCount;
    autoFCC43C9A_ai = 1;
    lv_curLane = 1;
    for ( ; ( (autoFCC43C9A_ai >= 0 && lv_curLane <= autoFCC43C9A_ae) || (autoFCC43C9A_ai <= 0 && lv_curLane >= autoFCC43C9A_ae) ) ; lv_curLane += autoFCC43C9A_ai ) {
        lv_numAllyTowns = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numAllyTowns;
        lv_numAllyHeroes = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numAllyHeroes;
        lv_numEnemyHeroes = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemyHeroes;
        lv_numEnemySiegeGiants = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemySiegeGiants;
        lv_numEnemyOgres = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemyOgres;
        lv_numEnemyOgreKings = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemyOgreKings;
        lv_numEnemyDragonKnights = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemyDragonKnights;
        lv_numEnemyUnderworldBossSkulls = libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_numEnemyUnderworldBossSkulls;
        lv_curEval = libAIAI_gf_HeroAICalcLaneEval(lv_numAllyTowns, lv_numAllyHeroes, lv_numEnemyHeroes, lv_numEnemySiegeGiants, lv_numEnemyOgres, lv_numEnemyOgreKings, lv_numEnemyDragonKnights, lv_numEnemyUnderworldBossSkulls, lv_underestimateEnemyPercent);
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_curLane].lv_eval = lv_curEval;
        if ((libGame_gv_laneData[lv_curLane].lv_minionSpawningEnabled == true) && (lv_curLane != lv_laneToAvoid)) {
            if ((lv_curEval < lv_worstEval)) {
                lv_weakestLane = lv_curLane;
                lv_worstEval = lv_curEval;
            }
            else {
            }
        }
        else {
        }
    }
    libAIAI_gv_heroAITeamData[(lp_team)].lv_weakestLane = lv_weakestLane;
}

void libAIAI_gf_HeroAIUpdateLaneHeroCounts (int lp_team) {
    int auto9C204E7B_ae;
    int auto9C204E7B_ai;
    int autoF36B4E08_ae;
    int autoF36B4E08_ai;

    // Variable Declarations
    int lv_laneIndex;
    int lv_heroIndex;
    int lv_heroTeam;
    region lv_heroBaseRegion;

    // Variable Initialization

    // Implementation
    auto9C204E7B_ae = libGame_gv_laneCount;
    auto9C204E7B_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto9C204E7B_ai >= 0 && lv_laneIndex <= auto9C204E7B_ae) || (auto9C204E7B_ai <= 0 && lv_laneIndex >= auto9C204E7B_ae) ) ; lv_laneIndex += auto9C204E7B_ai ) {
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHeroes = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHumanHeroes = 0;
        PlayerGroupClear(libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_allyHeroes);
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyHeroes = 0;
    }
    autoF36B4E08_ae = 10;
    autoF36B4E08_ai = 1;
    lv_heroIndex = 1;
    for ( ; ( (autoF36B4E08_ai >= 0 && lv_heroIndex <= autoF36B4E08_ae) || (autoF36B4E08_ai <= 0 && lv_heroIndex >= autoF36B4E08_ae) ) ; lv_heroIndex += autoF36B4E08_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_heroIndex, 0) == true)) {
            if ((libAIAI_gf_HeroAIExcludeHeroFromLaneEvals(lv_heroIndex) == true)) {
                continue;
            }
            else {
            }
            if ((libGame_gv_players[lv_heroIndex].lv_faction == 0)) {
                lv_heroTeam = 0;
                lv_heroBaseRegion = libCore_gv_mAPOrderBaseRegion;
            }
            else {
                lv_heroTeam = 1;
                lv_heroBaseRegion = libCore_gv_mAPChaosBaseRegion;
            }
            if ((lv_heroTeam == lp_team) && (libAIAI_gv_aIHeroes[lv_heroIndex].lv_desiredLane != 0)) {
                lv_laneIndex = libAIAI_gv_aIHeroes[lv_heroIndex].lv_desiredLane;
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHeroes += 1;
                PlayerGroupAdd(libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_allyHeroes, lv_heroIndex);
            }
            else if ((lv_heroTeam == lp_team) && (libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_heroIndex].lv_lastSeenLane != 0)) {
                lv_laneIndex = libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_heroIndex].lv_lastSeenLane;
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHeroes += 1;
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHumanHeroes += 1;
                PlayerGroupAdd(libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_allyHeroes, lv_heroIndex);
            }
            else if ((lv_heroTeam != lp_team) && (libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_heroIndex].lv_lastSeenLane != 0)) {
                lv_laneIndex = libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[lv_heroIndex].lv_lastSeenLane;
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyHeroes += 1;
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIUpdateFrontMinion (int lp_team) {
    int autoC20B7F77_ae;
    int autoC20B7F77_ai;
    int autoC307B275_ae;
    int autoC307B275_ai;
    int auto786EA2FC_ae;
    int auto786EA2FC_ai;
    int auto8598D571_ae;
    int auto8598D571_ai;
    unitgroup auto89E5EF89_g;
    int auto89E5EF89_u;

    // Variable Declarations
    int lv_allyComputerPlayer;
    int lv_laneIndex;
    int lv_waypointIndex;
    region lv_waypointRegion;
    unitgroup lv_allyUnits;
    unit lv_allyUnit;
    point lv_position;
    fixed lv_lanePosition;

    // Variable Initialization
    lv_waypointRegion = RegionEmpty();
    lv_allyUnits = UnitGroupEmpty();

    // Implementation
    if ((lp_team == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    autoC20B7F77_ae = libGame_gv_laneCount;
    autoC20B7F77_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoC20B7F77_ai >= 0 && lv_laneIndex <= autoC20B7F77_ae) || (autoC20B7F77_ai <= 0 && lv_laneIndex >= autoC20B7F77_ae) ) ; lv_laneIndex += autoC20B7F77_ai ) {
        if ((lp_team == 0)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition = 1.0;
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
        }
    }
    autoC307B275_ae = libGame_gv_laneCount;
    autoC307B275_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoC307B275_ai >= 0 && lv_laneIndex <= autoC307B275_ae) || (autoC307B275_ai <= 0 && lv_laneIndex >= autoC307B275_ae) ) ; lv_laneIndex += autoC307B275_ai ) {
        if ((lp_team == 0)) {
            auto786EA2FC_ae = 1;
            auto786EA2FC_ai = -1;
            lv_waypointIndex = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
            for ( ; ( (auto786EA2FC_ai >= 0 && lv_waypointIndex <= auto786EA2FC_ae) || (auto786EA2FC_ai <= 0 && lv_waypointIndex >= auto786EA2FC_ae) ) ; lv_waypointIndex += auto786EA2FC_ai ) {
                lv_waypointRegion = RegionCircle(libGame_gv_laneData[lv_laneIndex].lv_waypoints[lv_waypointIndex], 15.0);
                lv_allyUnits = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, lv_waypointRegion, UnitFilter((1 << c_targetFilterBiological), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
                if ((UnitGroupCount(lv_allyUnits, c_unitCountAlive) > 0)) {
                    break;
                }
                else {
                }
            }
        }
        else {
            auto8598D571_ae = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
            auto8598D571_ai = 1;
            lv_waypointIndex = 1;
            for ( ; ( (auto8598D571_ai >= 0 && lv_waypointIndex <= auto8598D571_ae) || (auto8598D571_ai <= 0 && lv_waypointIndex >= auto8598D571_ae) ) ; lv_waypointIndex += auto8598D571_ai ) {
                lv_waypointRegion = RegionCircle(libGame_gv_laneData[lv_laneIndex].lv_waypoints[lv_waypointIndex], 15.0);
                lv_allyUnits = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, lv_waypointRegion, UnitFilter((1 << c_targetFilterBiological), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
                if ((UnitGroupCount(lv_allyUnits, c_unitCountAlive) > 0)) {
                    break;
                }
                else {
                }
            }
        }
        auto89E5EF89_g = lv_allyUnits;
        auto89E5EF89_u = 1;
        for ( ; auto89E5EF89_u <= UnitGroupCount(auto89E5EF89_g, c_unitCountAll) ; auto89E5EF89_u += BoolToInt(lv_allyUnit == UnitGroupUnit(auto89E5EF89_g, auto89E5EF89_u)) ) {
            lv_allyUnit = UnitGroupUnit(auto89E5EF89_g, auto89E5EF89_u);
            lv_position = UnitGetPosition(lv_allyUnit);
            lv_lanePosition = libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, lv_position);
            if ((lp_team == 0)) {
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition = MaxF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
            }
            else {
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition = MinF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
            }
        }
    }
}

void libAIAI_gf_HeroAIUpdateFrontTower (int lp_team) {
    int auto8B410C8D_ae;
    int auto8B410C8D_ai;
    int autoC86AFC27_ae;
    int autoC86AFC27_ai;
    int autoA4217D95_ae;
    int autoA4217D95_ai;

    // Variable Declarations
    int lv_allyComputerPlayer;
    int lv_townIndex;
    int lv_structureIndex;
    int lv_laneIndex;
    point lv_position;
    fixed lv_lanePosition;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    auto8B410C8D_ae = libGame_gv_laneCount;
    auto8B410C8D_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto8B410C8D_ai >= 0 && lv_laneIndex <= auto8B410C8D_ae) || (auto8B410C8D_ai <= 0 && lv_laneIndex >= auto8B410C8D_ae) ) ; lv_laneIndex += auto8B410C8D_ai ) {
        if ((lp_team == 0)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition = 1.0;
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
        }
    }
    autoC86AFC27_ae = libGame_gv_townTownCount;
    autoC86AFC27_ai = 1;
    lv_townIndex = 1;
    for ( ; ( (autoC86AFC27_ai >= 0 && lv_townIndex <= autoC86AFC27_ae) || (autoC86AFC27_ai <= 0 && lv_townIndex >= autoC86AFC27_ae) ) ; lv_townIndex += autoC86AFC27_ai ) {
        autoA4217D95_ae = libGame_gv_townTownData[lv_townIndex].lv_structureCount;
        autoA4217D95_ai = 1;
        lv_structureIndex = 1;
        for ( ; ( (autoA4217D95_ai >= 0 && lv_structureIndex <= autoA4217D95_ae) || (autoA4217D95_ai <= 0 && lv_structureIndex >= autoA4217D95_ae) ) ; lv_structureIndex += autoA4217D95_ai ) {
            if ((libGame_gv_townTownData[lv_townIndex].lv_owner == lv_allyComputerPlayer) && (UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]) == true) && ((libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 5) || (libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 1))) {
                lv_position = UnitGetPosition(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]);
                lv_laneIndex = libGame_gv_townTownData[lv_townIndex].lv_lane;
                lv_lanePosition = libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, lv_position);
                if ((lp_team == 0)) {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition = MaxF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                }
                else {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition = MinF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                }
            }
            else {
            }
        }
    }
}

void libAIAI_gf_HeroAIUpdateFrontHumanAlly (int lp_team) {
    int auto7E37147A_ae;
    int auto7E37147A_ai;
    int auto0A2A314C_ae;
    int auto0A2A314C_ai;

    // Variable Declarations
    int lv_faction;
    int lv_playerIndex;
    point lv_position;
    int lv_laneIndex;
    fixed lv_distanceToLane;
    int lv_closestIndex;
    int lv_secondaryIndex;
    point lv_closestPoint;
    fixed lv_lanePosition;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_faction = 0;
    }
    else {
        lv_faction = 1;
    }
    auto7E37147A_ae = libGame_gv_laneCount;
    auto7E37147A_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto7E37147A_ai >= 0 && lv_laneIndex <= auto7E37147A_ae) || (auto7E37147A_ai <= 0 && lv_laneIndex >= auto7E37147A_ae) ) ; lv_laneIndex += auto7E37147A_ai ) {
        if ((lp_team == 0)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition = 1.0;
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
        }
    }
    auto0A2A314C_ae = libCore_gv_bALMaxPlayers;
    auto0A2A314C_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto0A2A314C_ai >= 0 && lv_playerIndex <= auto0A2A314C_ae) || (auto0A2A314C_ai <= 0 && lv_playerIndex >= auto0A2A314C_ae) ) ; lv_playerIndex += auto0A2A314C_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lv_faction)) {
            lv_position = UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit);
            libGame_gf_CalculateClosestLaneData(lv_position);
            lv_laneIndex = libGame_gv_closestLaneData.lv_closestLane;
            lv_distanceToLane = libGame_gv_closestLaneData.lv_laneData[lv_laneIndex].lv_closestDist;
            if ((lv_distanceToLane > libAIAI_gv_aIHeroLaneLeashDistance)) {
                continue;
            }
            else {
            }
            lv_closestIndex = libGame_gv_closestLaneData.lv_laneData[lv_laneIndex].lv_closestIndex;
            lv_secondaryIndex = libGame_gv_closestLaneData.lv_laneData[lv_laneIndex].lv_secondaryIndex;
            lv_closestPoint = libGame_gv_closestLaneData.lv_laneData[lv_laneIndex].lv_closestPoint;
            lv_lanePosition = AILaneWaypointConvertPointToWaydist(lv_laneIndex, lv_closestIndex, lv_secondaryIndex, lv_closestPoint);
            if ((lp_team == 0)) {
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition = MaxF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition);
            }
            else {
                libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition = MinF(lv_lanePosition, libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition);
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAICalcCoreDefensePosition (int lp_team) {
    int autoCA059FA6_ae;
    int autoCA059FA6_ai;

    // Variable Declarations
    point lv_corePosition;
    int lv_faction;
    int lv_laneIndex;
    fixed lv_coreLanePosition;
    fixed lv_coreDefenseLanePosition;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_faction = 0;
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_faction = 1;
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    autoCA059FA6_ae = libGame_gv_laneCount;
    autoCA059FA6_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoCA059FA6_ai >= 0 && lv_laneIndex <= autoCA059FA6_ae) || (autoCA059FA6_ai <= 0 && lv_laneIndex >= autoCA059FA6_ae) ) ; lv_laneIndex += autoCA059FA6_ai ) {
        lv_coreLanePosition = libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, lv_corePosition);
        lv_coreDefenseLanePosition = libAIAI_gf_AIAdvanceLanePosition(lv_faction, lv_laneIndex, lv_coreLanePosition, 12.0);
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_coreDefensePosition = lv_coreDefenseLanePosition;
    }
}

void libAIAI_gf_HeroAIUpdateContentionPoints (int lp_team) {
    int autoB231D41E_ae;
    int autoB231D41E_ai;

    // Variable Declarations
    int lv_allyTeamIndex;
    int lv_enemyTeamIndex;
    int lv_allyComputerPlayer;
    int lv_laneIndex;
    fixed lv_bestLanePosition;
    point lv_bestPosition;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyMinions;
    unitgroup lv_allies;
    unitgroup lv_allyMinions;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyMinions = UnitGroupEmpty();

    // Implementation
    if ((lp_team == 0)) {
        lv_allyTeamIndex = (0);
        lv_enemyTeamIndex = (1);
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyTeamIndex = (1);
        lv_enemyTeamIndex = (0);
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    autoB231D41E_ae = libGame_gv_laneCount;
    autoB231D41E_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoB231D41E_ai >= 0 && lv_laneIndex <= autoB231D41E_ae) || (autoB231D41E_ai <= 0 && lv_laneIndex >= autoB231D41E_ae) ) ; lv_laneIndex += autoB231D41E_ai ) {
        if ((libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_gameState != 2) && (libGame_gv_laneData[lv_laneIndex].lv_minionSpawningEnabled == true)) {
            if ((lp_team == 0)) {
                lv_bestLanePosition = libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_coreDefensePosition;
                lv_bestLanePosition = MaxF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                lv_bestLanePosition = MaxF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
                lv_bestLanePosition = MaxF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition);
            }
            else {
                lv_bestLanePosition = libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_coreDefensePosition;
                lv_bestLanePosition = MinF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                lv_bestLanePosition = MinF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
                lv_bestLanePosition = MinF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_frontHumanAllyPosition);
            }
        }
        else {
            if ((lp_team == 0)) {
                lv_bestLanePosition = libGame_gv_laneData[lv_laneIndex].lv_waypointCount;
                lv_bestLanePosition = MinF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_enemyTeamIndex].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                lv_bestLanePosition = MinF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_enemyTeamIndex].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
            }
            else {
                lv_bestLanePosition = 1.0;
                lv_bestLanePosition = MaxF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_enemyTeamIndex].lv_laneData[lv_laneIndex].lv_frontTowerPosition);
                lv_bestLanePosition = MaxF(lv_bestLanePosition, libAIAI_gv_heroAITeamData[lv_enemyTeamIndex].lv_laneData[lv_laneIndex].lv_frontMinionPosition);
            }
        }
        lv_bestPosition = AILaneWaypointConvertWaydistOffsetToPoint(lv_laneIndex, lv_bestLanePosition, 0.0);
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_contentionPointLanePosition = lv_bestLanePosition;
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_contentionPoint = lv_bestPosition;
        lv_enemies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceEnemy, RegionCircle(lv_bestPosition, 12.0), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_allies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, RegionCircle(lv_bestPosition, 12.0), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
        lv_allyMinions = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_numEnemyHeroesNearContentionPoint = UnitGroupCount(lv_enemyHeroes, c_unitCountAlive);
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_numEnemyMinionsNearContentionPoint = UnitGroupCount(lv_enemyMinions, c_unitCountAlive);
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_numAllyMinionsNearContentionPoint = UnitGroupCount(lv_allyMinions, c_unitCountAlive);
        lv_allyMinions = UnitGroupFilter("MercLanerSiegeGiant", c_playerAny, lv_allies, UnitFilter(0, 0, 0, 0), 0);
        libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_numNonSiegeAllyMinionsNearContentionPoint = (libAIAI_gv_heroAITeamData[lv_allyTeamIndex].lv_laneData[lv_laneIndex].lv_numAllyMinionsNearContentionPoint - UnitGroupCount(lv_allyMinions, c_unitCountAlive));
    }
}

bool libAIAI_gf_HeroAIOneTownPerLaneRemaining (int lp_faction) {
    int autoA99764FE_ae;
    int autoEA2CC850_ae;

    // Variable Declarations
    int lv_allyComputerPlayer;
    int lv_townIndex;
    int lv_laneIndex;
    int[libMapM_gv_mMRavenTributeThreshold_C + 1] lv_numberOfTownsAlive;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    autoA99764FE_ae = libGame_gv_townTownCount;
    lv_townIndex = 1;
    for ( ; lv_townIndex <= autoA99764FE_ae ; lv_townIndex += 1 ) {
        if ((libGame_gv_townTownData[lv_townIndex].lv_owner == lv_allyComputerPlayer) && (libGame_gv_townTownData[lv_townIndex].lv_townHallIndex > 0) && (UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[libGame_gv_townTownData[lv_townIndex].lv_townHallIndex]) == true)) {
            lv_numberOfTownsAlive[libGame_gv_townTownData[lv_townIndex].lv_lane] += 1;
        }
        else {
        }
    }
    autoEA2CC850_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= autoEA2CC850_ae ; lv_laneIndex += 1 ) {
        if ((lv_numberOfTownsAlive[lv_laneIndex] > 1)) {
            return false;
        }
        else {
        }
    }
    return true;
}

void libAIAI_gf_HeroAIUpdateGameState (int lp_faction) {
    int autoDD6C3D15_ae;
    int autoDD6C3D15_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_player;
    fixed lv_totalLevel;
    int lv_numberofPlayers;
    fixed lv_averageLevel;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_aIHeroNeverEnterLateGame[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)] == true)) {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState = 0;
        return ;
    }
    else {
    }
    autoDD6C3D15_ae = libCore_gv_bALMaxPlayers;
    autoDD6C3D15_ai = 1;
    lv_player = 1;
    for ( ; ( (autoDD6C3D15_ai >= 0 && lv_player <= autoDD6C3D15_ae) || (autoDD6C3D15_ai <= 0 && lv_player >= autoDD6C3D15_ae) ) ; lv_player += autoDD6C3D15_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_player, 0) == true) && (libGame_gv_players[lv_player].lv_faction == lp_faction)) {
            lv_totalLevel += UnitLevel(libGame_gv_players[lv_player].lv_heroUnit);
            lv_numberofPlayers += 1;
        }
        else {
        }
    }
    if ((lv_numberofPlayers == 0)) {
        return ;
    }
    else {
    }
    lv_averageLevel = (lv_totalLevel / lv_numberofPlayers);
    if ((lv_averageLevel < libAIAI_gv_aIHeroAct2StartLevel[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)])) {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState = 0;
    }
    else {
        if ((lv_averageLevel < libAIAI_gv_aIHeroAct3StartLevel[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)]) && (libAIAI_gf_HeroAIOneTownPerLaneRemaining(0) == false) && (libAIAI_gf_HeroAIOneTownPerLaneRemaining(1) == false)) {
            libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState = 1;
        }
        else {
            libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState = 2;
        }
    }
}

void libAIAI_gf_HeroAIEvalLanes (int lp_team) {
    int auto2212DC98_ae;
    int auto2212DC98_ai;
    int auto52DDA55A_ae;
    int auto52DDA55A_ai;
    int auto46794512_ae;
    int auto46794512_ai;
    int auto0E5447FD_ae;
    int auto0E5447FD_ai;

    // Variable Declarations
    playergroup lv_allyTeam;
    int lv_laneIndex;
    int lv_townIndex;
    int lv_structureIndex;
    int lv_townTeam;
    unit lv_hero;
    int lv_heroIndex;
    int lv_heroTeam;
    region lv_heroBaseRegion;
    int lv_campIndex;
    int lv_numberofUnits;
    unitgroup lv_underworldBossGroup;
    unit lv_underworldBoss;

    // Variable Initialization
    lv_allyTeam = PlayerGroupEmpty();
    lv_underworldBossGroup = UnitGroupEmpty();

    // Implementation
    if ((lp_team == 0)) {
        lv_allyTeam = libCore_gv_teamOrder;
    }
    else {
        lv_allyTeam = libCore_gv_teamChaos;
    }
    if ((PlayerGroupCount(lv_allyTeam) == 0)) {
        return ;
    }
    else {
    }
    if ((libAIAI_gv_heroAITeamData[(lp_team)].lv_nextLaneEvalUpdateTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamData[(lp_team)].lv_nextLaneEvalUpdateTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroLaneEvalFrequency);
    }
    auto2212DC98_ae = libGame_gv_laneCount;
    auto2212DC98_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto2212DC98_ai >= 0 && lv_laneIndex <= auto2212DC98_ae) || (auto2212DC98_ai <= 0 && lv_laneIndex >= auto2212DC98_ae) ) ; lv_laneIndex += auto2212DC98_ai ) {
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyTowns = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHeroes = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyHumanHeroes = 0;
        PlayerGroupClear(libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_allyHeroes);
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyTowns = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyHeroes = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemySiegeGiants = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyOgres = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyOgreKings = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyDragonKnights = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyUnderworldBossSkulls = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllySiegeGiants = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyOgres = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyOgreKings = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyDragonKnights = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyUnderworldBossSkulls = 0;
        libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_eval = 0;
    }
    auto52DDA55A_ae = libGame_gv_townTownCount;
    auto52DDA55A_ai = 1;
    lv_townIndex = 1;
    for ( ; ( (auto52DDA55A_ai >= 0 && lv_townIndex <= auto52DDA55A_ae) || (auto52DDA55A_ai <= 0 && lv_townIndex >= auto52DDA55A_ae) ) ; lv_townIndex += auto52DDA55A_ai ) {
        auto46794512_ae = libGame_gv_townTownData[lv_townIndex].lv_structureCount;
        auto46794512_ai = 1;
        lv_structureIndex = 1;
        for ( ; ( (auto46794512_ai >= 0 && lv_structureIndex <= auto46794512_ae) || (auto46794512_ai <= 0 && lv_structureIndex >= auto46794512_ae) ) ; lv_structureIndex += auto46794512_ai ) {
            if ((UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]) == true) && (libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 1)) {
                if ((libGame_gv_townTownData[lv_townIndex].lv_owner == libCore_gv_cOMPUTER_TeamOrder)) {
                    lv_townTeam = 0;
                }
                else {
                    lv_townTeam = 1;
                }
                if ((lv_townTeam == lp_team)) {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_numAllyTowns += 1;
                }
                else {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[libGame_gv_townTownData[lv_townIndex].lv_lane].lv_numEnemyTowns += 1;
                }
            }
            else {
            }
        }
    }
    libAIAI_gf_HeroAIUpdateHeroTracking(lp_team);
    libAIAI_gf_HeroAIUpdateLaneHeroCounts(lp_team);
    if ((libAIAI_gv_heroAITeamData[(lp_team)].lv_avoidPlayer != 0)) {
        libAIAI_gv_heroAITeamData[(lp_team)].lv_avoidLane = libAIAI_gv_heroAITeamData[(lp_team)].lv_heroTrackingData[libAIAI_gv_heroAITeamData[(lp_team)].lv_avoidPlayer].lv_lastSeenLane;
    }
    else {
    }
    auto0E5447FD_ae = libMapM_gv_jungleMaxCamps;
    auto0E5447FD_ai = 1;
    lv_campIndex = 1;
    for ( ; ( (auto0E5447FD_ai >= 0 && lv_campIndex <= auto0E5447FD_ae) || (auto0E5447FD_ai <= 0 && lv_campIndex >= auto0E5447FD_ae) ) ; lv_campIndex += auto0E5447FD_ai ) {
        if ((UnitIsAlive(libMapM_gv_jungleMiniMapLeader[lv_campIndex]) == true) && (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampType == 0)) {
            lv_laneIndex = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mercSpawnLane[libGame_gf_TeamNumberOfPlayer(PlayerGroupPlayer(lv_allyTeam, 1))];
            lv_numberofUnits = UnitGroupCount(libMapM_gv_jungleMiniMapIconGroup[lv_campIndex], c_unitCountAlive);
            if ((libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataMercSpawnType == 1)) {
                if ((PlayerGroupHasPlayer(lv_allyTeam, UnitGetOwner(libMapM_gv_jungleMiniMapLeader[lv_campIndex])) == true)) {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllySiegeGiants += lv_numberofUnits;
                }
                else {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemySiegeGiants += lv_numberofUnits;
                }
            }
            else if ((libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataMercSpawnType == 2)) {
                if ((PlayerGroupHasPlayer(lv_allyTeam, UnitGetOwner(libMapM_gv_jungleMiniMapLeader[lv_campIndex])) == true)) {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyOgres += lv_numberofUnits;
                }
                else {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyOgres += lv_numberofUnits;
                }
            }
            else if ((libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataMercSpawnType == 3)) {
                if ((PlayerGroupHasPlayer(lv_allyTeam, UnitGetOwner(libMapM_gv_jungleMiniMapLeader[lv_campIndex])) == true)) {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyOgreKings += lv_numberofUnits;
                }
                else {
                    libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyOgreKings += lv_numberofUnits;
                }
            }
        }
        else {
        }
    }
    if ((UnitIsValid(libAIAI_gv_heroAIDragonShireDragon) == true)) {
        lv_laneIndex = AILaneWaypointGetClosestLane(UnitGetPosition(libAIAI_gv_heroAIDragonShireDragon));
        if ((PlayerGroupHasPlayer(lv_allyTeam, UnitGetOwner(libAIAI_gv_heroAIDragonShireDragon)) == true)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyDragonKnights += 1;
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyDragonKnights += 1;
        }
    }
    else {
    }
    if (((libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state == 1) || (libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state == 2))) {
        lv_laneIndex = libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_lane;
        if ((lp_team == 0)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyUnderworldBossSkulls = libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(0)];
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyUnderworldBossSkulls = libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(0)];
        }
    }
    else {
    }
    if (((libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state == 1) || (libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state == 2))) {
        lv_laneIndex = libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_lane;
        if ((lp_team == 0)) {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numEnemyUnderworldBossSkulls = libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(1)];
        }
        else {
            libAIAI_gv_heroAITeamData[(lp_team)].lv_laneData[lv_laneIndex].lv_numAllyUnderworldBossSkulls = libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(1)];
        }
    }
    else {
    }
    libAIAI_gf_HeroAIUpdateLaneEvals(lp_team);
    libAIAI_gf_HeroAIUpdateFrontHumanAlly(lp_team);
    libAIAI_gf_HeroAIUpdateFrontMinion(lp_team);
    libAIAI_gf_HeroAIUpdateContentionPoints(lp_team);
}

fixed libAIAI_gf_HeroAICalcLaneEval (int lp_numAllyTowns, int lp_numAllyHeroes, int lp_numEnemyHeroes, int lp_numEnemySiegeGiants, int lp_numEnemyOgres, int lp_numEnemyOgreKings, int lp_numEnemyDragonKnights, int lp_numEnemyUnderworldBossSkulls, fixed lp_underestimateEnemyPercent) {
    // Variable Declarations
    fixed lv_eval;
    fixed lv_positiveEval;
    fixed lv_negativeEval;

    // Variable Initialization

    // Implementation
    lv_positiveEval += (lp_numAllyTowns * 5.0);
    lv_positiveEval += (6 * PowI(lp_numAllyHeroes, 2.0));
    lv_negativeEval += (4 * PowI(lp_numEnemyHeroes, 2.0));
    lv_negativeEval += (3 * lp_numEnemySiegeGiants);
    lv_negativeEval += (3 * lp_numEnemyOgres);
    lv_negativeEval += (12 * lp_numEnemyOgreKings);
    lv_negativeEval += (20 * lp_numEnemyDragonKnights);
    lv_negativeEval += (1 * lp_numEnemyUnderworldBossSkulls);
    return (lv_positiveEval - (lv_negativeEval * ((100.0 - lp_underestimateEnemyPercent) / 100.0)));
}

void libAIAI_gf_HeroAIUpdateTeamDifficulty (int lp_faction) {
    int autoA0E34A32_ae;
    int autoA0E34A32_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;
    int lv_lowestDifficulty;

    // Variable Initialization
    lv_lowestDifficulty = 12;

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoA0E34A32_ae = libCore_gv_bALMaxPlayers;
    autoA0E34A32_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoA0E34A32_ai >= 0 && lv_playerIndex <= autoA0E34A32_ae) || (autoA0E34A32_ai <= 0 && lv_playerIndex >= autoA0E34A32_ae) ) ; lv_playerIndex += autoA0E34A32_ai ) {
        if ((PlayerStatus(lv_playerIndex) != c_playerStatusUnused) && (libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && ((PlayerType(lv_playerIndex) == c_playerTypeComputer) || (PlayerStatus(lv_playerIndex) == c_playerStatusLeft)) && ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty) < (lv_lowestDifficulty))) {
            lv_lowestDifficulty = libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty;
        }
        else {
        }
    }
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty = lv_lowestDifficulty;
}

bool libAIAI_gf_HeroAIExcludeHeroFromLaneEvals (int lp_trigPlayer) {
    // Implementation
    if ((UnitGetType(libGame_gv_players[lp_trigPlayer].lv_heroUnit) == "HeroAbathur")) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIHaveEnemiesBeenSeenInLane (int lp_faction) {
    int autoD3DE3D3B_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoD3DE3D3B_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoD3DE3D3B_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction != lp_faction) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLane > 0)) {
            return true;
        }
        else {
        }
    }
    return false;
}

void libAIAI_gf_HeroAIPlayerPingsHero (int lp_pingingPlayer, unit lp_pingedHero) {
    int autoAE56CB48_ae;
    int autoAE56CB48_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_testPingIndex;
    int lv_newPingIndex;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_pingingPlayer, 1) == false)) {
        return ;
    }
    else {
    }
    if ((libNtve_gf_PlayerIsEnemy(lp_pingingPlayer, UnitGetOwner(lp_pingedHero), 0) == true)) {
        return ;
    }
    else {
    }
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer);
    autoAE56CB48_ae = libAIAI_gv_heroAIMaxHeroPingCount;
    autoAE56CB48_ai = 1;
    lv_testPingIndex = 1;
    for ( ; ( (autoAE56CB48_ai >= 0 && lv_testPingIndex <= autoAE56CB48_ae) || (autoAE56CB48_ai <= 0 && lv_testPingIndex >= autoAE56CB48_ae) ) ; lv_testPingIndex += autoAE56CB48_ai ) {
        if ((libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_testPingIndex].lv_pingExpireTime <= TimerGetElapsed(libGame_gv_gameTimer))) {
            lv_newPingIndex = lv_testPingIndex;
            break;
        }
        else {
        }
    }
    if ((lv_newPingIndex == 0)) {
        return ;
    }
    else {
    }
    libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_newPingIndex].lv_pingExpireTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroPingDuration);
    libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_newPingIndex].lv_playerWhoPinged = lp_pingingPlayer;
    libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_newPingIndex].lv_pingedHero = lp_pingedHero;
}

void libAIAI_gf_HeroAIFocusPingedHeroLogic (int lp_faction) {
    int auto72F2B05B_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_pingIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto72F2B05B_ae = libAIAI_gv_heroAIMaxHeroPingCount;
    lv_pingIndex = 1;
    for ( ; lv_pingIndex <= auto72F2B05B_ae ; lv_pingIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_pingIndex].lv_pingExpireTime > TimerGetElapsed(libGame_gv_gameTimer)) && (libAIAI_gf_HeroAIHeroCanBeFocused(libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_pingIndex].lv_pingedHero) == true)) {
            libAIAI_gf_HeroAIStartFocusHero(libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_pingIndex].lv_playerWhoPinged, libAIAI_gv_heroAITeamHeroPingData[lv_teamIndex].lv_heroPings[lv_pingIndex].lv_pingedHero);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIFocusWeakHeroLogic (int lp_faction) {
    int autoBD4E1CA2_ae;
    int autoBD4E1CA2_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_aIHeroFocusWeakHeroes[libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty] == false)) {
        return ;
    }
    else {
    }
    autoBD4E1CA2_ae = libCore_gv_bALMaxPlayers;
    autoBD4E1CA2_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoBD4E1CA2_ai >= 0 && lv_playerIndex <= autoBD4E1CA2_ae) || (autoBD4E1CA2_ai <= 0 && lv_playerIndex >= autoBD4E1CA2_ae) ) ; lv_playerIndex += autoBD4E1CA2_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction != lp_faction) && (UnitGetPropertyFixed(libGame_gv_players[lv_playerIndex].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroFocusHeroHealth) && (libAIAI_gf_HeroAIHeroCanBeFocused(libGame_gv_players[lv_playerIndex].lv_heroUnit) == true)) {
            libAIAI_gf_HeroAIStartFocusHero(-1, libGame_gv_players[lv_playerIndex].lv_heroUnit);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIInitiateTeamFightLogic (int lp_faction) {
    playergroup autoE1BA9E32_g;
    int autoE1BA9E32_p;
    unitgroup autoE07F1330_g;
    int autoE07F1330_u;
    unitgroup autoB8870054_g;
    int autoB8870054_u;

    // Variable Declarations
    int lv_playerIndex;
    region lv_nearbyRegion;
    unitgroup lv_allyHeroes;
    unitgroup lv_enemyHeroes;
    unit lv_allyHero;
    unit lv_enemyHero;
    fixed lv_distancetoHero;
    unit lv_bestTarget;
    fixed lv_bestTargetDistance;

    // Variable Initialization
    lv_allyHeroes = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_bestTargetDistance = 524287.0;

    // Implementation
    autoE1BA9E32_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    autoE1BA9E32_p = 1;
    for ( ; autoE1BA9E32_p <= PlayerGroupCount(autoE1BA9E32_g) ; autoE1BA9E32_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoE1BA9E32_g, autoE1BA9E32_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoE1BA9E32_g, autoE1BA9E32_p);
        if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane > 0)) {
            lv_nearbyRegion = RegionCircle(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), (libAIAI_gv_aIHeroFocusHeroRecruitDistance - 3.0));
            lv_enemyHeroes = UnitGroupAlliance(lv_playerIndex, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
            lv_allyHeroes = UnitGroupAlliance(lv_playerIndex, c_unitAllianceAlly, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
            autoE07F1330_g = lv_allyHeroes;
            autoE07F1330_u = 1;
            for ( ; autoE07F1330_u <= UnitGroupCount(autoE07F1330_g, c_unitCountAll) ; autoE07F1330_u += BoolToInt(lv_allyHero == UnitGroupUnit(autoE07F1330_g, autoE07F1330_u)) ) {
                lv_allyHero = UnitGroupUnit(autoE07F1330_g, autoE07F1330_u);
                if (((UnitGetOwner(lv_allyHero) > libCore_gv_bALMaxPlayers) || (libAIAI_gf_HeroAIIsPlayerActive(UnitGetOwner(lv_allyHero), 2) == false) || (libAIAI_gv_aIHeroes[UnitGetOwner(lv_allyHero)].lv_currentLane <= 0) || (UnitLevel(libGame_gv_players[UnitGetOwner(lv_allyHero)].lv_heroUnit) < libAIAI_gv_aIHeroMinAggresiveFocusHeroLevel) || ((libAIAI_gv_aIHeroAvoidTargettingHeroes[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)] == true) && (UnitLevel(libGame_gv_players[UnitGetOwner(lv_allyHero)].lv_heroUnit) < libAIAI_gv_aIHeroAct2StartLevel[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)])) || (libAIAI_gv_aIHeroEnterTeamFights[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)] == false))) {
                    UnitGroupRemove(lv_allyHeroes, lv_allyHero);
                }
                else {
                }
            }
            if (((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) == 0) || (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) < 3) || (UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > UnitGroupCount(lv_allyHeroes, c_unitCountAlive)))) {
                continue;
            }
            else {
            }
            autoB8870054_g = lv_enemyHeroes;
            autoB8870054_u = 1;
            for ( ; autoB8870054_u <= UnitGroupCount(autoB8870054_g, c_unitCountAll) ; autoB8870054_u += BoolToInt(lv_enemyHero == UnitGroupUnit(autoB8870054_g, autoB8870054_u)) ) {
                lv_enemyHero = UnitGroupUnit(autoB8870054_g, autoB8870054_u);
                lv_distancetoHero = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lv_enemyHero));
                if ((libAIAI_gf_HeroAIHeroCanBeFocused(lv_enemyHero) == true) && (lv_distancetoHero < lv_bestTargetDistance)) {
                    lv_bestTarget = lv_enemyHero;
                    lv_bestTargetDistance = lv_distancetoHero;
                }
                else {
                }
            }
            if ((UnitIsValid(lv_bestTarget) == true)) {
                libAIAI_gf_HeroAIStartFocusHero(-1, lv_bestTarget);
                break;
            }
            else {
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIStartFocusHero (int lp_pingingPlayer, unit lp_targetHero) {
    int autoDE2995F1_ae;
    int autoDE2995F1_ai;
    unitgroup auto387CC239_g;
    int auto387CC239_u;

    // Variable Declarations
    int lv_playerIndex;
    int lv_speakingPlayer;
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyTowers;
    unitgroup lv_nearbyAllyHeroes;
    unit lv_allyHero;
    playergroup lv_nearbyAllyPlayers;
    unit lv_currentTarget;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyTowers = UnitGroupEmpty();
    lv_nearbyAllyHeroes = UnitGroupEmpty();
    lv_nearbyAllyPlayers = PlayerGroupEmpty();

    // Implementation
    autoDE2995F1_ae = libCore_gv_bALMaxPlayers;
    autoDE2995F1_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoDE2995F1_ai >= 0 && lv_playerIndex <= autoDE2995F1_ae) || (autoDE2995F1_ai <= 0 && lv_playerIndex >= autoDE2995F1_ae) ) ; lv_playerIndex += autoDE2995F1_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_targetHero != lp_targetHero) && (libNtve_gf_PlayerIsEnemy(lv_playerIndex, UnitGetOwner(lp_targetHero), 4) == true) && (libAIAI_gf_HeroAIHeroWantsToFocusHero(lv_playerIndex, lp_targetHero) == true) && (libAIAI_gf_HeroAIHeroAvailableToStartFocus(lv_playerIndex) == true)) {
            lv_speakingPlayer = lv_playerIndex;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 18);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_targetHero = lp_targetHero;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_targetHeroCheckPosition = null;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_focusHeroTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroFocusHeroMaxChaseTime);
            UnitIssueOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lv_playerIndex].lv_targetHero), c_orderQueueReplace);
        }
        else {
        }
    }
    if ((lp_pingingPlayer <= 0) && (lv_speakingPlayer > 1) && (TimerGetElapsed(libGame_gv_gameTimer) > (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lv_speakingPlayer)].lv_lastTimePlayedAttackVO + libAIAI_gv_aIHeroAttackVODelay))) {
        lv_nearbyRegion = RegionCircle(UnitGetPosition(lp_targetHero), 12.0);
        lv_enemies = UnitGroupAlliance(lv_speakingPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        lv_enemyTowers = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) == 1) && (UnitGroupCount(lv_enemyTowers, c_unitCountAlive) == 0)) {
            lv_nearbyAllyHeroes = UnitGroupAlliance(lv_speakingPlayer, c_unitAllianceAlly, RegionCircle(UnitGetPosition(libGame_gv_players[lv_speakingPlayer].lv_heroUnit), 14.0), UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
            auto387CC239_g = lv_nearbyAllyHeroes;
            auto387CC239_u = 1;
            for ( ; auto387CC239_u <= UnitGroupCount(auto387CC239_g, c_unitCountAll) ; auto387CC239_u += BoolToInt(lv_allyHero == UnitGroupUnit(auto387CC239_g, auto387CC239_u)) ) {
                lv_allyHero = UnitGroupUnit(auto387CC239_g, auto387CC239_u);
                PlayerGroupAdd(lv_nearbyAllyPlayers, UnitGetOwner(lv_allyHero));
            }
            libSond_gf_HeroVOPlayHeroLine(14, lv_speakingPlayer, lv_nearbyAllyPlayers);
            libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lv_speakingPlayer)].lv_lastTimePlayedAttackVO = TimerGetElapsed(libGame_gv_gameTimer);
        }
        else {
        }
    }
    else {
    }
}

bool libAIAI_gf_HeroAIShouldGiveUpOnFocusHero (int lp_trigPlayer) {
    // Implementation
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if (((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero)) > libAIAI_gv_aIHeroFocusHeroGiveUpDistance) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) || ((DistanceBetweenPoints(libGame_gv_players[lp_trigPlayer].lv_spawnPoint, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) > 30.0) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroClosestLanePoint) > libAIAI_gv_aIHeroLaneLeashDistance)) || (libAIAI_gf_HeroAIIsUnitBehindGate(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero) == true) || (((libAIAI_gf_HeroAIUnitProtectedByTower(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, libAIAI_gv_aIHeroCloseToTowerDistance) == true) || (libAIAI_gf_HeroAICloseToAnyTowerWithoutMinions(lp_trigPlayer) == true)) && ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero)) > libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) || (UnitGetPropertyFixed(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, c_unitPropLifePercent, c_unitPropCurrent) > 10.0))) || (UnitBehaviorCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero, "HomeShieldProtection") > 0) || (libNtve_gf_UnitIsInvulnerable(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_targetHero) == true) || (libAIAI_gf_HeroAIBeingTargettedByDangerousAbility(lp_trigPlayer) == true))) {
        return true;
    }
    else {
    }
    if ((UnitLevel(libGame_gv_players[lp_trigPlayer].lv_heroUnit) < libAIAI_gv_aIHeroMinAggresiveFocusHeroLevel)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 200.0))) {
            return true;
        }
        else {
        }
    }
    else {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 1300.0))) {
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIHeroCanBeFocused (unit lp_targetHero) {
    // Variable Declarations
    int lv_enemyComputerPlayer;
    fixed lv_weaponRange;
    fixed lv_distanceToCurrentTarget;
    fixed lv_distanceToNewTarget;
    fixed lv_currentTargetHealth;
    fixed lv_newTargetHealth;
    fixed lv_currentTargetEval;
    fixed lv_newTargetEval;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(lp_targetHero) == false)) {
        return false;
    }
    else {
    }
    if ((libGame_gv_players[UnitGetOwner(lp_targetHero)].lv_faction == 0)) {
        lv_enemyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    else {
        lv_enemyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    if ((libNtve_gf_UnitIsVisibleToPlayer(lp_targetHero, lv_enemyComputerPlayer) == false)) {
        return false;
    }
    else {
    }
    if (((UnitGetOwner(lp_targetHero) > libCore_gv_bALMaxPlayers) || (libNtve_gf_UnitIsInvulnerable(lp_targetHero) == true) || (libAIAI_gf_HeroAIUnitProtectedByTower(lp_targetHero, libAIAI_gv_aIHeroFarFromTowerDistance) == true) || (libAIAI_gf_HeroAIIsUnitBehindGate(lp_targetHero) == true))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIHeroAvailableToStartFocus (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_weaponRange;
    fixed lv_distanceToCurrentTarget;
    fixed lv_distanceToNewTarget;
    fixed lv_currentTargetHealth;
    fixed lv_newTargetHealth;
    fixed lv_currentTargetEval;
    fixed lv_newTargetEval;

    // Variable Initialization

    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextFocusHeroCheckTime > TimerGetElapsed(libGame_gv_gameTimer)) || (libGame_gv_players[lp_trigPlayer].lv_isDead == true) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0) || (UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true) || (libAIAI_gf_HeroAIIsPlayerInsideEnemyTown(lp_trigPlayer) == true) || (libAIAI_gf_HeroAICloseToAnyTowerWithoutMinions(lp_trigPlayer) == true) || (libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer) != 0) || (libAIAI_gf_HeroAIBeingTargettedByDangerousAbility(lp_trigPlayer) == true))) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((UnitLevel(libGame_gv_players[lp_trigPlayer].lv_heroUnit) < libAIAI_gv_aIHeroMinAggresiveFocusHeroLevel)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval)) {
            return false;
        }
        else {
        }
    }
    else {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 1000.0))) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAIHeroWantsToFocusHero (int lp_trigPlayer, unit lp_targetHero) {
    // Implementation
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_targetHero)) > libAIAI_gv_aIHeroFocusHeroRecruitDistance)) {
        return false;
    }
    else {
    }
    libGame_gf_CalculateClosestLaneDataForLane(UnitGetPosition(lp_targetHero), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane);
    if ((libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_closestDist > libAIAI_gv_aIHeroCloseToLaneDistance)) {
        return false;
    }
    else {
    }
    return true;
}

unit libAIAI_gf_HeroAIFindBestFocusHeroTarget (int lp_trigPlayer) {
    unitgroup auto151A5EFB_g;
    int auto151A5EFB_u;

    // Variable Declarations
    unit lv_enemyHero;
    fixed lv_targetEval;
    fixed lv_bestTargetEval;
    unit lv_bestTarget;

    // Variable Initialization
    lv_bestTargetEval = 524287.0;

    // Implementation
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    auto151A5EFB_g = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes;
    auto151A5EFB_u = 1;
    for ( ; auto151A5EFB_u <= UnitGroupCount(auto151A5EFB_g, c_unitCountAll) ; auto151A5EFB_u += BoolToInt(lv_enemyHero == UnitGroupUnit(auto151A5EFB_g, auto151A5EFB_u)) ) {
        lv_enemyHero = UnitGroupUnit(auto151A5EFB_g, auto151A5EFB_u);
        lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemyHero, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
        if ((lv_targetEval < lv_bestTargetEval) && (libAIAI_gf_HeroAIHeroCanBeFocused(lv_enemyHero) == true) && (libAIAI_gf_HeroAIHeroWantsToFocusHero(lp_trigPlayer, lv_enemyHero) == true)) {
            lv_bestTargetEval = lv_targetEval;
            lv_bestTarget = lv_enemyHero;
        }
        else {
        }
    }
    return lv_bestTarget;
}

void libAIAI_gf_HeroAIPlayerPingsCore (int lp_pingingPlayer, unit lp_pingedCore) {
    // Variable Declarations
    int lv_teamIndex;
    int lv_testPingIndex;
    int lv_newPingIndex;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_pingingPlayer, 1) == false)) {
        return ;
    }
    else {
    }
    if ((libNtve_gf_PlayerIsEnemy(lp_pingingPlayer, UnitGetOwner(lp_pingedCore), 0) == true)) {
        return ;
    }
    else {
    }
    libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_pingExpireTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroCorePingDuration);
    libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_playerWhoPinged = lp_pingingPlayer;
    libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_pingedCore = lp_pingedCore;
}

void libAIAI_gf_HeroAIFocusPingedCore (int lp_faction) {
    int auto39CCEAA1_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_pingIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto39CCEAA1_ae = libAIAI_gv_heroAIMaxHeroPingCount;
    lv_pingIndex = 1;
    for ( ; lv_pingIndex <= auto39CCEAA1_ae ; lv_pingIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_pingExpireTime > TimerGetElapsed(libGame_gv_gameTimer))) {
            libAIAI_gf_HeroAIStartFocusCore(libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_playerWhoPinged, libAIAI_gv_heroAITeamCorePingData[lv_teamIndex].lv_pingedCore);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIFocusWeakCore (int lp_faction) {
    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;
    unit lv_enemyCore;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
        lv_enemyCore = libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core;
    }
    else {
        lv_teamIndex = (1);
        lv_enemyCore = libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core;
    }
    if ((libAIAI_gv_aIHeroFocusWeakCore[libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty] == false)) {
        return ;
    }
    else {
    }
    if ((UnitGetPropertyFixed(lv_enemyCore, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroFocusCoreAlwaysHealth)) {
        libAIAI_gf_HeroAIStartFocusCore(-1, lv_enemyCore);
    }
    else {
        if ((UnitGetPropertyFixed(lv_enemyCore, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroFocusCoreDistractedHeatlh) && (libAIAI_gf_HeroAIEnemiesNearBuilding(lv_enemyCore) == true)) {
            libAIAI_gf_HeroAIStartFocusCore(-1, lv_enemyCore);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIStartFocusCore (int lp_pingingPlayer, unit lp_targetCore) {
    int autoA64FB518_ae;
    int autoA64FB518_ai;
    unitgroup autoADC5EC5C_g;
    int autoADC5EC5C_u;

    // Variable Declarations
    int lv_playerIndex;
    int lv_speakingPlayer;
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_nearbyAllyHeroes;
    unit lv_allyHero;
    playergroup lv_nearbyAllyPlayers;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_nearbyAllyHeroes = UnitGroupEmpty();
    lv_nearbyAllyPlayers = PlayerGroupEmpty();

    // Implementation
    autoA64FB518_ae = libCore_gv_bALMaxPlayers;
    autoA64FB518_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoA64FB518_ai >= 0 && lv_playerIndex <= autoA64FB518_ae) || (autoA64FB518_ai <= 0 && lv_playerIndex >= autoA64FB518_ae) ) ; lv_playerIndex += autoA64FB518_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libNtve_gf_PlayerIsEnemy(lv_playerIndex, UnitGetOwner(lp_targetCore), 4) == true) && (libAIAI_gf_HeroAIShouldFocusCore(lv_playerIndex, lp_targetCore) == true)) {
            lv_speakingPlayer = lv_playerIndex;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 19);
            UnitIssueOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, OrderTargetingUnit(AbilityCommand("attack", 0), lp_targetCore), c_orderQueueReplace);
        }
        else {
        }
    }
    if ((lp_pingingPlayer <= 0) && (lv_speakingPlayer > 1) && (TimerGetElapsed(libGame_gv_gameTimer) > (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lv_speakingPlayer)].lv_lastTimePlayedAttackVO + libAIAI_gv_aIHeroAttackVODelay))) {
        lv_nearbyRegion = RegionCircle(UnitGetPosition(lp_targetCore), 12.0);
        lv_enemies = UnitGroupAlliance(lv_speakingPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) <= 1)) {
            lv_nearbyAllyHeroes = UnitGroupAlliance(lv_speakingPlayer, c_unitAllianceAlly, RegionCircle(UnitGetPosition(libGame_gv_players[lv_speakingPlayer].lv_heroUnit), 14.0), UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
            autoADC5EC5C_g = lv_nearbyAllyHeroes;
            autoADC5EC5C_u = 1;
            for ( ; autoADC5EC5C_u <= UnitGroupCount(autoADC5EC5C_g, c_unitCountAll) ; autoADC5EC5C_u += BoolToInt(lv_allyHero == UnitGroupUnit(autoADC5EC5C_g, autoADC5EC5C_u)) ) {
                lv_allyHero = UnitGroupUnit(autoADC5EC5C_g, autoADC5EC5C_u);
                PlayerGroupAdd(lv_nearbyAllyPlayers, UnitGetOwner(lv_allyHero));
            }
            libSond_gf_HeroVOPlayHeroLine(14, lv_speakingPlayer, lv_nearbyAllyPlayers);
            libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lv_speakingPlayer)].lv_lastTimePlayedAttackVO = TimerGetElapsed(libGame_gv_gameTimer);
        }
        else {
        }
    }
    else {
    }
}

bool libAIAI_gf_HeroAIShouldFocusCore (int lp_trigPlayer, unit lp_targetCore) {
    // Implementation
    if ((libAIAI_gf_HeroAIHeroWillingToFocusCore(lp_trigPlayer, lp_targetCore) != true)) {
        return false;
    }
    else {
    }
    if ((UnitGetPropertyFixed(lp_targetCore, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroFocusCoreAlwaysHealth)) {
        libAIAI_gf_HeroAIEval(lp_trigPlayer);
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval)) {
            return false;
        }
        else {
        }
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldGiveUpOnFocusCore (int lp_trigPlayer, unit lp_targetCore) {
    // Implementation
    if ((libAIAI_gf_HeroAIHeroWillingToFocusCore(lp_trigPlayer, lp_targetCore) != true)) {
        return true;
    }
    else {
    }
    if ((UnitGetPropertyFixed(lp_targetCore, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroFocusCoreAlwaysHealth)) {
        libAIAI_gf_HeroAIEval(lp_trigPlayer);
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 200.0))) {
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIHeroWillingToFocusCore (int lp_trigPlayer, unit lp_targetCore) {
    // Implementation
    if (((libGame_gv_players[lp_trigPlayer].lv_isDead == true) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0) || (UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true) || (libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer) != 0) || (libAIAI_gf_HeroAIBeingTargettedByDangerousAbility(lp_trigPlayer) == true))) {
        return false;
    }
    else {
    }
    if (((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_targetCore)) > libAIAI_gv_aIHeroFocusCoreRecruitDistance) || (UnitGetPropertyFixed(lp_targetCore, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroFocusCorePingHealth))) {
        return false;
    }
    else {
    }
    if ((UnitGetPropertyFixed(lp_targetCore, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroFocusCoreAlwaysHealth) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget (int lp_trigPlayer, unit lp_targetUnit) {
    int auto0908BD15_ae;
    int auto0908BD15_ai;

    // Variable Declarations
    int lv_abilityIndex;
    fixed lv_distanceToTarget;
    order lv_order;

    // Variable Initialization

    // Implementation
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropEnergyPercent, c_unitPropCurrent) < libAIAI_gv_aIHeroLowEnergyPercent)) {
        return false;
    }
    else {
    }
    lv_distanceToTarget = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_targetUnit));
    auto0908BD15_ae = 2;
    auto0908BD15_ai = 1;
    lv_abilityIndex = 0;
    for ( ; ( (auto0908BD15_ai >= 0 && lv_abilityIndex <= auto0908BD15_ae) || (auto0908BD15_ai <= 0 && lv_abilityIndex >= auto0908BD15_ae) ) ; lv_abilityIndex += auto0908BD15_ai ) {
        if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_abilityType[lv_abilityIndex] == 2) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_abilityType[lv_abilityIndex] == 3) || ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_abilityType[lv_abilityIndex] == 1) && (UnitTestState(lp_targetUnit, c_unitStateCloaked) == false))) && (libAIAI_gf_HeroAIIsAbilityOnCooldown(lp_trigPlayer, lv_abilityIndex) == false)) {
            if ((lv_distanceToTarget > libAIAI_gf_HeroAIGetAbilityRange(lp_trigPlayer, lv_abilityIndex))) {
                continue;
            }
            else {
            }
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_abilityType[lv_abilityIndex] == 3)) {
                lv_order = Order(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_castAbility[lv_abilityIndex]);
            }
            else {
                if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_abilityType[lv_abilityIndex] == 1)) {
                    lv_order = OrderTargetingUnit(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_castAbility[lv_abilityIndex], lp_targetUnit);
                }
                else {
                    lv_order = OrderTargetingPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_castAbility[lv_abilityIndex], UnitGetPosition(lp_targetUnit));
                }
            }
            if ((UnitOrderIsValid(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_order) == true)) {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_order, c_orderQueueReplace);
                libAIAI_gf_HeroAIUpdateNextSpellCheckTime(lp_trigPlayer);
                return true;
            }
            else {
            }
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIRandomlyCastAbilityOnCloakedEnemy (int lp_trigPlayer) {
    unitgroup auto356A732D_g;
    int auto356A732D_u;

    // Variable Declarations
    region lv_nearbyHero;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unit lv_unit;
    unit lv_targetUnit;
    int lv_abilityIndex;
    fixed lv_distanceToTarget;
    order lv_order;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    if (((libAIAI_gv_aIHeroFocusWeakHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == false) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropEnergyPercent, c_unitPropCurrent) < libAIAI_gv_aIHeroLowEnergyPercent))) {
        return false;
    }
    else {
    }
    lv_nearbyHero = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 8.0);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyHero, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    auto356A732D_g = lv_enemyHeroes;
    auto356A732D_u = 1;
    for ( ; auto356A732D_u <= UnitGroupCount(auto356A732D_g, c_unitCountAll) ; auto356A732D_u += BoolToInt(lv_unit == UnitGroupUnit(auto356A732D_g, auto356A732D_u)) ) {
        lv_unit = UnitGroupUnit(auto356A732D_g, auto356A732D_u);
        if ((UnitTestState(lv_unit, c_unitStateCloaked) == true) && (VisIsVisibleForPlayer(lp_trigPlayer, UnitGetPosition(lv_unit)) == true)) {
            lv_targetUnit = lv_unit;
            break;
        }
        else {
        }
    }
    if ((UnitIsValid(lv_targetUnit) == true)) {
        return libAIAI_gf_HeroAIRandomlyCastAbilityOnTarget(lp_trigPlayer, lv_targetUnit);
    }
    else {
    }
    return false;
}

order libAIAI_gf_HeroAIRandomlyChooseTarget (int lp_trigPlayer, abilcmd lp_ability, int lp_abilityType, fixed lp_range) {
    int auto41B625C6_val;

    // Variable Declarations
    unit lv_targetUnit;
    point lv_point;

    // Variable Initialization

    // Implementation
    auto41B625C6_val = lp_abilityType;
    if (auto41B625C6_val == 3) {
        if ((libAIAI_gf_HeroAINumEnemiesInRange(lp_trigPlayer, lp_range) >= 2)) {
            return Order(lp_ability);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 8) {
        return Order(lp_ability);
    }
    else if (auto41B625C6_val == 2) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemies, lp_range);
        if ((lv_targetUnit != null)) {
            lv_point = libAIAI_gf_HeroAIFudgeTargetPosition(lp_trigPlayer, UnitGetPosition(lv_targetUnit));
            return OrderTargetingPoint(lp_ability, lv_point);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 7) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroes, lp_range);
        if ((lv_targetUnit != null)) {
            lv_point = libAIAI_gf_HeroAIFudgeTargetPosition(lp_trigPlayer, UnitGetPosition(lv_targetUnit));
            return OrderTargetingPoint(lp_ability, lv_point);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 1) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemies, lp_range);
        if ((lv_targetUnit != null)) {
            return OrderTargetingUnit(lp_ability, lv_targetUnit);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 4) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowers, lp_range);
        if ((lv_targetUnit != null)) {
            return OrderTargetingUnit(lp_ability, lv_targetUnit);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 5) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowers, lp_range);
        if ((lv_targetUnit != null)) {
            return OrderTargetingUnit(lp_ability, lv_targetUnit);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 6) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroes, lp_range);
        if ((lv_targetUnit != null)) {
            return OrderTargetingUnit(lp_ability, lv_targetUnit);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 9) {
        lv_targetUnit = libAIAI_gf_HeroAIRandomlyChooseUnitInRange(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, lp_range);
        if ((lv_targetUnit != null)) {
            lv_point = libAIAI_gf_HeroAIFudgeTargetPosition(lp_trigPlayer, UnitGetPosition(lv_targetUnit));
            return OrderTargetingPoint(lp_ability, lv_point);
        }
        else {
            return null;
        }
    }
    else if (auto41B625C6_val == 10) {
        return Order(lp_ability);
    }
    else {
        return null;
    }
}

int libAIAI_gf_HeroAIGetItemIndex (unit lp_item) {
    int autoCF208E3D_ae;
    int autoCF208E3D_ai;

    // Variable Declarations
    int lv_itemIndex;

    // Variable Initialization

    // Implementation
    autoCF208E3D_ae = libCore_gv_talents_MaxTalentEntryCount_C;
    autoCF208E3D_ai = 1;
    lv_itemIndex = 1;
    for ( ; ( (autoCF208E3D_ai >= 0 && lv_itemIndex <= autoCF208E3D_ae) || (autoCF208E3D_ai <= 0 && lv_itemIndex >= autoCF208E3D_ae) ) ; lv_itemIndex += autoCF208E3D_ai ) {
        if ((libAIAI_gv_heroAIItemData[lv_itemIndex].lv_item == "")) {
            return 0;
        }
        else {
        }
        if ((libAIAI_gv_heroAIItemData[lv_itemIndex].lv_item == UnitGetType(lp_item))) {
            return lv_itemIndex;
        }
        else {
        }
    }
    return 0;
}

fixed libAIAI_gf_HeroAIGetAbilityRange (int lp_player, int lp_spellIndex) {
    // Variable Declarations
    const fixed lv_minRange = 3.0;
    const fixed lv_maxRange = 9.0;
    fixed lv_spellRange;
    abilcmd lv_spellAbil;

    // Variable Initialization

    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 2) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 7) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 9) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 1) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 4) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 6) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 5))) {
        lv_spellAbil = libAIAI_gv_aIHeroes[lp_player].lv_castAbility[lp_spellIndex];
        lv_spellRange = StringToFixed(CatalogFieldValueGet(c_gameCatalogAbil, AbilityCommandGetAbility(lv_spellAbil), "Range[0]", lp_player));
        if ((lv_spellRange < lv_minRange)) {
            lv_spellRange = lv_minRange;
        }
        else {
        }
        if ((lv_spellRange > lv_maxRange)) {
            lv_spellRange = lv_maxRange;
        }
        else {
        }
    }
    else if (((libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 3) || (libAIAI_gv_aIHeroes[lp_player].lv_abilityType[lp_spellIndex] == 8))) {
        lv_spellRange = lv_minRange;
    }
    return lv_spellRange;
}

fixed libAIAI_gf_HeroAIGetItemRange (int lp_player, int lp_itemIndex) {
    // Variable Declarations
    const fixed lv_minRange = 4.0;
    const fixed lv_maxRange = 9.0;
    string lv_item;
    string lv_itemAbility;
    fixed lv_itemRange;

    // Variable Initialization
    lv_itemAbility = "";

    // Implementation
    if (((libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 2) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 9) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 1) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 4) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 7) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 5))) {
        lv_item = libAIAI_gv_heroAIItemData[lp_itemIndex].lv_item;
        lv_itemAbility = CatalogFieldValueGet(c_gameCatalogItem, lv_item, "Abil", lp_player);
        lv_itemRange = StringToFixed(CatalogFieldValueGet(c_gameCatalogAbil, lv_itemAbility, "Range[" + IntToString(0) + "]", lp_player));
        if ((lv_itemRange < lv_minRange)) {
            lv_itemRange = lv_minRange;
        }
        else {
        }
        if ((lv_itemRange > lv_maxRange)) {
            lv_itemRange = lv_maxRange;
        }
        else {
        }
    }
    else if (((libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 3) || (libAIAI_gv_heroAIItemData[lp_itemIndex].lv_itemType == 8))) {
        lv_itemRange = lv_minRange;
    }
    return lv_itemRange;
}

bool libAIAI_gf_HeroAIInWeaponRangeOfTarget (int lp_trigPlayer, unit lp_targetUnit, fixed lp_rangeSlop) {
    // Variable Declarations
    fixed lv_weaponRange;
    fixed lv_heroRadius;
    fixed lv_targetRadius;
    fixed lv_distanceToTarget;

    // Variable Initialization

    // Implementation
    lv_weaponRange = libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_heroRadius = StringToFixed(CatalogFieldValueGet(c_gameCatalogUnit, UnitGetType(libGame_gv_players[lp_trigPlayer].lv_heroUnit), "Radius", c_playerAny));
    lv_targetRadius = StringToFixed(CatalogFieldValueGet(c_gameCatalogUnit, UnitGetType(lp_targetUnit), "Radius", c_playerAny));
    lv_distanceToTarget = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_targetUnit));
    return ((lv_heroRadius + lv_weaponRange + lv_targetRadius + lp_rangeSlop) >= lv_distanceToTarget);
}

int libAIAI_gf_HeroAINumEnemiesInRange (int lp_player, fixed lp_range) {
    unitgroup auto2E3B32BD_g;
    int auto2E3B32BD_u;

    // Variable Declarations
    int lv_numInRange;
    unit lv_enemy;

    // Variable Initialization

    // Implementation
    auto2E3B32BD_g = libAIAI_gv_aIHeroes[lp_player].lv_enemies;
    auto2E3B32BD_u = 1;
    for ( ; auto2E3B32BD_u <= UnitGroupCount(auto2E3B32BD_g, c_unitCountAll) ; auto2E3B32BD_u += BoolToInt(lv_enemy == UnitGroupUnit(auto2E3B32BD_g, auto2E3B32BD_u)) ) {
        lv_enemy = UnitGroupUnit(auto2E3B32BD_g, auto2E3B32BD_u);
        if ((DistanceBetweenPoints(UnitGetPosition(lv_enemy), UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit)) < lp_range)) {
            lv_numInRange = (lv_numInRange + 1);
        }
        else {
        }
    }
    return lv_numInRange;
}

unit libAIAI_gf_HeroAIRandomlyChooseUnitInRange (int lp_player, unitgroup lp_unitGroup, fixed lp_range) {
    unitgroup auto997E955A_g;
    int auto997E955A_u;

    // Variable Declarations
    unit lv_unit;
    unitgroup lv_inRange;

    // Variable Initialization
    lv_inRange = UnitGroupEmpty();

    // Implementation
    auto997E955A_g = lp_unitGroup;
    auto997E955A_u = 1;
    for ( ; auto997E955A_u <= UnitGroupCount(auto997E955A_g, c_unitCountAll) ; auto997E955A_u += BoolToInt(lv_unit == UnitGroupUnit(auto997E955A_g, auto997E955A_u)) ) {
        lv_unit = UnitGroupUnit(auto997E955A_g, auto997E955A_u);
        if ((UnitIsAlive(lv_unit) == true) && (DistanceBetweenPoints(UnitGetPosition(lv_unit), UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit)) < lp_range)) {
            UnitGroupAdd(lv_inRange, lv_unit);
        }
        else {
        }
    }
    if ((UnitGroupCount(lv_inRange, c_unitCountAll) > 0)) {
        return UnitGroupUnit(lv_inRange, RandomInt(1, UnitGroupCount(lv_inRange, c_unitCountAll)));
    }
    else {
    }
    return null;
}

point libAIAI_gf_HeroAIFudgeTargetPosition (int lp_player, point lp_pos) {
    // Variable Declarations
    point lv_target;
    region lv_region;
    fixed lv_distance;
    fixed lv_maxDist;
    int lv_missDirection;
    point lv_endPoint1;
    point lv_endPoint2;
    fixed lv_baseMissDistance;
    fixed lv_diceRoll;
    fixed lv_missChance;

    // Variable Initialization
    lv_target = lp_pos;
    lv_missDirection = 1;
    lv_baseMissDistance = 0.75;

    // Implementation
    lv_diceRoll = libNtve_gf_RandomPercent();
    lv_missChance = libAIAI_gv_aIHeroSkillshotMissRate[libAIAI_gv_aIHeroes[lp_player].lv_difficulty];
    if ((lv_diceRoll >= libAIAI_gv_aIHeroSkillshotMissRate[libAIAI_gv_aIHeroes[lp_player].lv_difficulty])) {
        lv_distance = 0.0;
        lv_baseMissDistance = 0.25;
    }
    else {
        lv_distance = libAIAI_gv_aIHeroFudgeTarget[(libAIAI_gv_aIHeroes[lp_player].lv_difficulty)];
        lv_baseMissDistance = 0.75;
    }
    if ((RandomInt(1, 2) == 1)) {
        lv_missDirection = -1;
    }
    else {
        lv_missDirection = 1;
    }
    lv_endPoint1 = PointWithOffsetPolar(lv_target, lv_baseMissDistance, (AngleBetweenPoints(lv_target, UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit)) + (90 * lv_missDirection)));
    lv_endPoint2 = libNtve_gf_PointOffsetTowardsPoint(lv_target, lv_distance, lv_endPoint1);
    lv_target = libNtve_gf_RandomPointBetweenPoints(lv_endPoint1, lv_endPoint2);
    return lv_target;
}

bool libAIAI_gf_HeroAIIsAbilityOnCooldown (int lp_trigPlayer, int lp_abilityIndex) {
    // Variable Declarations
    string lv_abilityLink;
    string lv_cooldownLink;

    // Variable Initialization

    // Implementation
    lv_abilityLink = AbilityCommandGetAbility(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_castAbility[lp_abilityIndex]);
    lv_cooldownLink = CatalogFieldValueGet(c_gameCatalogAbil, lv_abilityLink, "Cost[" + IntToString(0) + "].Cooldown.Link", c_playerAny);
    return (UnitGetCooldown(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_cooldownLink) > 0.0);
}

bool libAIAI_gf_HeroAIShouldSkipTactical (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 9) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 47)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldTacticalAITargetCreeps (int lp_player) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_heroState == 58)) {
        return true;
    }
    else {
        return false;
    }
}

void libAIAI_gf_HeroAIUpdateNextSpellCheckTime (int lp_trigPlayer) {
    int auto50B97911_ae;

    // Variable Declarations
    int lv_playerIndex;
    fixed lv_nextAllyCheckTime;

    // Variable Initialization

    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextOffensiveSpellCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinSpellFrequency[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]);
    lv_nextAllyCheckTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinTeamSpellFrequency[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]);
    auto50B97911_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto50B97911_ae ; lv_playerIndex += 1 ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) < 12.0)) {
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_nextOffensiveSpellCheckTime = MaxF(libAIAI_gv_aIHeroes[lv_playerIndex].lv_nextOffensiveSpellCheckTime, lv_nextAllyCheckTime);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIChooseABChoices (int lp_faction) {
    playergroup auto0E269936_g;
    int auto0E269936_p;

    // Variable Declarations
    int lv_playerIndex;
    int lv_buttonIndex;

    // Variable Initialization

    // Implementation
    auto0E269936_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto0E269936_p = 1;
    for ( ; auto0E269936_p <= PlayerGroupCount(auto0E269936_g) ; auto0E269936_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto0E269936_g, auto0E269936_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto0E269936_g, auto0E269936_p);
        if ((libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex] != 0) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_allowedToChooseTalentsTime < TimerGetElapsed(libGame_gv_gameTimer)) && (((libCore_gv_dEBUGUseNewTalentBucketSystem == true) && (libGame_gv_players[lv_playerIndex].lv_talentsBucketABChoices[libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex]].lv_selection == 0)) || ((libCore_gv_dEBUGUseNewTalentBucketSystem == false) && (libGame_gv_players[lv_playerIndex].lv_talentsABChoices[libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex]] == 0)))) {
            if ((libCore_gv_dEBUGUseNewTalentBucketSystem == true)) {
                lv_buttonIndex = RandomInt(1, libGame_gv_players[lv_playerIndex].lv_talentsBucketABChoices[libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex]].lv_numberOfButtons);
            }
            else {
                lv_buttonIndex = RandomInt(1, libCore_gv_aBChoices[libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex]].lv_numberOfButtons);
            }
            libUIUI_gf_TalentsBucketChooseABChoiceForPlayerOLD(libUIUI_gv_talents_ActiveABChoiceForPlayer[lv_playerIndex], lv_buttonIndex, lv_playerIndex);
            return ;
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIAdvanceWaypoint (int lp_player) {
    // Variable Declarations
    int lv_nextWaypoint;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_currentLane == 0)) {
        return ;
    }
    else {
    }
    lv_nextWaypoint = libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex;
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        if ((lv_nextWaypoint < libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_waypointCount)) {
            lv_nextWaypoint += 1;
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = lv_nextWaypoint;
        }
        else {
        }
    }
    else {
        if ((lv_nextWaypoint == 0)) {
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_waypointCount;
        }
        else {
            if ((lv_nextWaypoint > 1)) {
                lv_nextWaypoint -= 1;
                libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = lv_nextWaypoint;
            }
            else {
            }
        }
    }
    libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
}

void libAIAI_gf_HeroAIRetreatWaypoint (int lp_player) {
    // Variable Declarations
    int lv_nextWaypoint;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_currentLane == 0)) {
        return ;
    }
    else {
    }
    lv_nextWaypoint = libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex;
    if ((libGame_gv_players[lp_player].lv_faction == 1)) {
        if ((lv_nextWaypoint == libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_waypointCount)) {
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = 0;
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = libGame_gv_players[lp_player].lv_spawnPoint;
        }
        else {
            if ((lv_nextWaypoint != 0)) {
                lv_nextWaypoint += 1;
                libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = lv_nextWaypoint;
                libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
            }
            else {
            }
        }
    }
    else {
        if ((lv_nextWaypoint > 1)) {
            lv_nextWaypoint -= 1;
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = lv_nextWaypoint;
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
        }
        else {
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = 0;
            libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = libGame_gv_players[lp_player].lv_spawnPoint;
        }
    }
}

void libAIAI_gf_HeroAIResetWaypoint (int lp_player, bool lp_advancing) {
    // Variable Declarations
    point lv_position;
    int lv_closestIndex;
    int lv_secondaryIndex;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_player].lv_activeVehicle) == true)) {
        lv_position = UnitGetPosition(libGame_gv_players[lp_player].lv_activeVehicle);
    }
    else {
        lv_position = UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit);
    }
    libGame_gf_CalculateClosestLaneData(lv_position);
    lv_closestIndex = libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_closestIndex;
    lv_secondaryIndex = libGame_gv_closestLaneData.lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_currentLane].lv_secondaryIndex;
    if ((((libGame_gv_players[lp_player].lv_faction == 0) && (lp_advancing == true)) || ((libGame_gv_players[lp_player].lv_faction == 1) && (lp_advancing == false)))) {
        libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = MaxI(lv_closestIndex, lv_secondaryIndex);
    }
    else {
        libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex = MinI(lv_closestIndex, lv_secondaryIndex);
    }
    libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
}

void libAIAI_gf_HeroAIStartAdvanceLane (int lp_player) {
    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_player].lv_activeVehicle) == true)) {
        libAIAI_gv_aIHeroes[lp_player].lv_laneOffset = 0.0;
        libAIAI_gf_HeroAIResetWaypoint(lp_player, true);
        libAIAI_gf_HeroAIChangeState(lp_player, 23);
        libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition = libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint;
    }
    else {
        libAIAI_gf_HeroAIResetWaypoint(lp_player, true);
        libAIAI_gf_HeroAIChangeState(lp_player, 7);
        libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_player, true);
    }
}

void libAIAI_gf_HeroAIStartRetreatLane (int lp_player) {
    // Variable Declarations
    unitgroup lv_heroesToAvoid;

    // Variable Initialization
    lv_heroesToAvoid = UnitGroupEmpty();

    // Implementation
    lv_heroesToAvoid = libAIAI_gf_HeroAIGetEnemyHeroesInRetreatPath(lp_player);
    if ((UnitGroupCount(lv_heroesToAvoid, c_unitCountAlive) > 0)) {
        libAIAI_gf_HeroAIChangeLaneOffset(lp_player, libAIAI_gf_HeroAIChooseNewLaneOffset(lp_player, lv_heroesToAvoid));
    }
    else {
    }
    libAIAI_gf_HeroAIChangeState(lp_player, 8);
    libAIAI_gf_HeroAIResetWaypoint(lp_player, false);
    libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_player, false);
    libAIAI_gv_aIHeroes[lp_player].lv_lastRetreatStartTime = TimerGetElapsed(libGame_gv_gameTimer);
    libAIAI_gv_aIHeroes[lp_player].lv_safeInLaneRetreating = false;
}

void libAIAI_gf_HeroAIStartFleeInJungle (int lp_player) {
    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_player, 44);
    libAIAI_gv_aIHeroes[lp_player].lv_safeInJungleRetreating = false;
    libAIAI_gf_HeroAIUpdateJungleTargetPosition(lp_player, libGame_gv_players[lp_player].lv_spawnPoint);
}

void libAIAI_gf_HeroAIStartReturnToLane (int lp_player, int lp_laneIndex) {
    // Implementation
    libGame_gf_CalculateClosestLaneDataForLane(UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit), lp_laneIndex);
    if ((libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestDist <= libAIAI_gv_aIHeroCloseToLaneDistance)) {
        libAIAI_gv_aIHeroes[lp_player].lv_currentLane = lp_laneIndex;
        libAIAI_gf_HeroAIChangeDesiredLane(lp_player, lp_laneIndex);
        libAIAI_gf_HeroAIStartAdvanceLane(lp_player);
        return ;
    }
    else {
    }
    if ((UnitIsValid(libGame_gv_players[lp_player].lv_activeVehicle) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_player, 22);
    }
    else {
        libAIAI_gf_HeroAIChangeState(lp_player, 16);
    }
    libAIAI_gv_aIHeroes[lp_player].lv_currentLane = 0;
    libAIAI_gf_HeroAIChangeDesiredLane(lp_player, lp_laneIndex);
    libAIAI_gv_aIHeroes[lp_player].lv_returnToLaneLane = lp_laneIndex;
    libAIAI_gv_aIHeroes[lp_player].lv_returnToLanePosition = libAIAI_gf_HeroAIGetReturnToLanePosition(lp_player, lp_laneIndex);
    libAIAI_gf_HeroAIUpdateJungleTargetPosition(lp_player, libAIAI_gv_aIHeroes[lp_player].lv_returnToLanePosition);
}

int libAIAI_gf_HeroAIGetClosestMinionLane (point lp_testPoint) {
    // Implementation
    libGame_gf_CalculateClosestLaneData(lp_testPoint);
    return libGame_gv_closestLaneData.lv_closestMinionLane;
}

void libAIAI_gf_HeroAIReturnToClosestLane (int lp_player) {
    // Variable Declarations
    point lv_currentPosition;
    int lv_closestLane;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_player].lv_activeVehicle) == true)) {
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_player].lv_activeVehicle);
    }
    else {
        lv_currentPosition = UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit);
    }
    if ((libAIAI_gf_HeroAIIsPlayerAtSpawn(lp_player) == true) && (libAIAI_gv_aIHeroes[lp_player].lv_desiredLane > 0)) {
        libAIAI_gf_HeroAIStartReturnToLane(lp_player, libAIAI_gv_aIHeroes[lp_player].lv_desiredLane);
    }
    else {
        lv_closestLane = libAIAI_gf_HeroAIGetClosestMinionLane(lv_currentPosition);
        libAIAI_gf_HeroAIStartReturnToLane(lp_player, lv_closestLane);
    }
}

point libAIAI_gf_HeroAIGetReturnToLanePosition (int lp_player, int lp_laneIndex) {
    // Implementation
    return libAIAI_gf_HeroAIGetPositionBehindContentionPoint(lp_player, lp_laneIndex, libAIAI_gv_aIHeroRetreatDistanceToChangeLanes, 0.0);
}

void libAIAI_gf_HeroAIChangeLaneOffset (int lp_player, fixed lp_laneOffset) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_player].lv_laneOffset = lp_laneOffset;
    if ((libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex == 0)) {
        return ;
    }
    else {
    }
    libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint = AILaneWaypointGetWaypointPosWithOffset(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointIndex, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
}

void libAIAI_gf_HeroAIUpdateLaneTargetPosition (int lp_player, bool lp_advancing) {
    // Variable Declarations
    fixed lv_stepDistance;
    fixed lv_closestLanePosition;
    fixed lv_distanceToNextWaypoint;
    point lv_direction;

    // Variable Initialization

    // Implementation
    if ((lp_advancing == true)) {
        lv_stepDistance = libAIAI_gv_aIHeroAdvanceLaneStepDistance;
    }
    else {
        lv_stepDistance = libAIAI_gv_aIHeroRetreatLaneStepDistance;
    }
    lv_closestLanePosition = libAIAI_gf_AIGetClosestLanePosition(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, UnitGetPosition(libGame_gv_players[lp_player].lv_heroUnit));
    libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition = AILaneWaypointConvertWaydistOffsetToPoint(libAIAI_gv_aIHeroes[lp_player].lv_currentLane, lv_closestLanePosition, libAIAI_gv_aIHeroes[lp_player].lv_laneOffset);
    libAIAI_gf_HeroAIMoveLaneTargetPosition(lp_player, lv_stepDistance, lp_advancing);
    while ((PointPathingPassable(libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition) == false) && (!(((libAIAI_gf_HeroAIIsAtLastWaypoint(lp_player, lp_advancing) == true) && (DistanceBetweenPoints(libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition, libAIAI_gv_aIHeroes[lp_player].lv_curWaypointPoint) <= libAIAI_gv_aIHeroCloseEnoughDist))))) {
        libAIAI_gf_HeroAIMoveLaneTargetPosition(lp_player, lv_stepDistance, lp_advancing);
    }
    if ((lp_advancing == true)) {
        UnitIssueOrder(libGame_gv_players[lp_player].lv_heroUnit, OrderTargetingPoint(AbilityCommand("attack", 0), libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition), c_orderQueueReplace);
    }
    else {
        UnitIssueOrder(libGame_gv_players[lp_player].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_player].lv_laneTargetPosition), c_orderQueueReplace);
    }
}

void libAIAI_gf_HeroAIMoveLaneTargetPosition (int lp_trigPlayer, fixed lp_distance, bool lp_advancing) {
    // Variable Declarations
    point lv_newTargetPosition;
    fixed lv_distanceLeftToMove;
    fixed lv_distanceToNextWaypoint;
    point lv_direction;

    // Variable Initialization

    // Implementation
    lv_newTargetPosition = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition;
    lv_distanceLeftToMove = lp_distance;
    while ((lv_distanceLeftToMove > 0.0)) {
        lv_distanceToNextWaypoint = DistanceBetweenPoints(lv_newTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointPoint);
        if ((lv_distanceToNextWaypoint > lv_distanceLeftToMove)) {
            lv_direction = AIGetDirection(lv_newTargetPosition, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointPoint);
            lv_newTargetPosition = libCore_gf_AdvancePointinDirection(lv_newTargetPosition, lv_direction, lv_distanceLeftToMove);
            lv_distanceLeftToMove = 0.0;
        }
        else {
            lv_newTargetPosition = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointPoint;
            lv_distanceLeftToMove -= lv_distanceToNextWaypoint;
            if ((libAIAI_gf_HeroAIIsAtLastWaypoint(lp_trigPlayer, lp_advancing) == true)) {
                break;
            }
            else {
            }
            if ((lp_advancing == true)) {
                libAIAI_gf_HeroAIAdvanceWaypoint(lp_trigPlayer);
            }
            else {
                libAIAI_gf_HeroAIRetreatWaypoint(lp_trigPlayer);
            }
        }
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = lv_newTargetPosition;
}

void libAIAI_gf_HeroAIUpdateJungleTargetPosition (int lp_trigPlayer, point lp_destination) {
    // Variable Declarations
    point lv_start;
    bool lv_useDangerMap;
    point lv_result;
    point lv_dangerResult;
    point lv_nonDangerResult;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        lv_useDangerMap = false;
        lv_start = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_activeVehicle);
    }
    else {
        lv_useDangerMap = libAIAI_gv_aIHeroPathAroundDanger[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty];
        lv_start = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition = AIPositionAlongPath(lp_trigPlayer, lv_start, lp_destination, libAIAI_gv_aIHeroJungleStepDistance, lv_useDangerMap);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition == null)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition = lp_destination;
    }
    else {
    }
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition), c_orderQueueReplace);
    }
    else {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_jungleTargetPosition), c_orderQueueReplace);
    }
}

bool libAIAI_gf_HeroAIIsAtLastWaypoint (int lp_trigPlayer, bool lp_advancing) {
    // Implementation
    if ((lp_advancing == true)) {
        if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
            return (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointIndex == libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_waypointCount);
        }
        else {
            return (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointIndex == 1);
        }
    }
    else {
        return (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curWaypointIndex == 0);
    }
}

fixed libAIAI_gf_HeroAIChooseNewLaneOffset (int lp_trigPlayer, unitgroup lp_heroesToAvoid) {
    unitgroup autoA58C64B7_g;
    int autoA58C64B7_u;
    int autoF14B4851_ae;

    // Variable Declarations
    int lv_playerIndex;
    int lv_laneIndex;
    region lv_nearbyRegion;
    int lv_numberOfBuckets;
    fixed lv_bucketWidth;
    unit lv_hero;
    int lv_owner;
    fixed lv_laneOffset;
    bool[libCore_gv_bALMaxPlayers + 1] lv_bucketContainsHero;
    int lv_heroBucket;
    int lv_bucketIndex;
    fixed lv_bucketCenter;
    fixed lv_bestBucketCenter;
    fixed lv_bestBucketDistance;
    int lv_bestBucketIndex;
    fixed lv_currentLaneOffset;
    fixed lv_distance;
    fixed lv_min;
    fixed lv_max;

    // Variable Initialization
    lv_bestBucketDistance = 524287.0;

    // Implementation
    lv_numberOfBuckets = (UnitGroupCount(lp_heroesToAvoid, c_unitCountAlive) + 1);
    lv_bucketWidth = ((libAIAI_gv_aIHeroMaximumLaneOffset * 2.0) / lv_numberOfBuckets);
    autoA58C64B7_g = lp_heroesToAvoid;
    autoA58C64B7_u = 1;
    for ( ; autoA58C64B7_u <= UnitGroupCount(autoA58C64B7_g, c_unitCountAll) ; autoA58C64B7_u += BoolToInt(lv_hero == UnitGroupUnit(autoA58C64B7_g, autoA58C64B7_u)) ) {
        lv_hero = UnitGroupUnit(autoA58C64B7_g, autoA58C64B7_u);
        lv_owner = UnitGetOwner(lv_hero);
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_owner, 2) == true) && (libAIAI_gv_aIHeroes[lv_owner].lv_currentLane == libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane)) {
            lv_laneOffset = libAIAI_gv_aIHeroes[lv_owner].lv_laneOffset;
        }
        else {
            lv_laneOffset = libAIAI_gf_AIGetLaneOffsetOfPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, UnitGetPosition(lv_hero));
        }
        lv_heroBucket = (1 + FixedToInt(((lv_laneOffset + libAIAI_gv_aIHeroMaximumLaneOffset) / lv_bucketWidth)));
        if ((lv_heroBucket < 1)) {
            lv_heroBucket = 1;
        }
        else {
        }
        if ((lv_heroBucket > lv_numberOfBuckets)) {
            lv_heroBucket = lv_numberOfBuckets;
        }
        else {
        }
        lv_bucketContainsHero[lv_heroBucket] = true;
    }
    lv_currentLaneOffset = libAIAI_gf_AIGetLaneOffsetOfPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    autoF14B4851_ae = lv_numberOfBuckets;
    lv_bucketIndex = 1;
    for ( ; lv_bucketIndex <= autoF14B4851_ae ; lv_bucketIndex += 1 ) {
        if ((lv_bucketContainsHero[lv_bucketIndex] == true)) {
            continue;
        }
        else {
        }
        lv_bucketCenter = (((0.5 + (lv_bucketIndex - 1)) * lv_bucketWidth) - libAIAI_gv_aIHeroMaximumLaneOffset);
        lv_distance = AbsF((lv_bucketCenter - lv_currentLaneOffset));
        if ((lv_distance < lv_bestBucketDistance)) {
            lv_bestBucketDistance = lv_distance;
            lv_bestBucketCenter = lv_bucketCenter;
            lv_bestBucketIndex = lv_bucketIndex;
        }
        else {
        }
    }
    lv_min = (lv_bestBucketCenter - (lv_bucketWidth * 0.3));
    lv_max = (lv_bestBucketCenter + (lv_bucketWidth * 0.3));
    return RandomFixed(lv_min, lv_max);
}

bool libAIAI_gf_HeroAIIsSafe (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0)) {
        return libAIAI_gf_HeroAIIsSafeJungle(lp_trigPlayer);
    }
    else {
        return libAIAI_gf_HeroAIIsSafeLane(lp_trigPlayer);
    }
}

bool libAIAI_gf_HeroAIIsSafeLane (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_contentionPointLanePosition;

    // Variable Initialization

    // Implementation
    if ((((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_lastRetreatStartTime + libAIAI_gv_aIHeroMinRetreatDuration) > TimerGetElapsed(libGame_gv_gameTimer)) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true))) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((DistanceBetweenPoints(libGame_gv_players[lp_trigPlayer].lv_spawnPoint, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) > 30.0) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroClosestLanePoint) > 8.0)) {
        return false;
    }
    else {
    }
    if (((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] + 10.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane)) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > 0.0)) {
        return false;
    }
    else {
    }
    lv_contentionPointLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPointLanePosition;
    if ((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState != 2) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, c_unitCountAlive) == 0) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowers, c_unitCountAlive) == 0) && (libAIAI_gf_HeroAIIsPlayerBehindLanePosition(lp_trigPlayer, lv_contentionPointLanePosition) == false)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval < (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval + 95.0)) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 100.0))) {
        return false;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 100.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowerEval + 400.0))))) {
        return false;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 800.0))) {
        return false;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIBeingTargettedByDangerousAbility(lp_trigPlayer) == true)) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIIsSafeJungle (int lp_trigPlayer) {
    unitgroup auto57A8744A_g;
    int auto57A8744A_u;
    unitgroup autoD7056FA9_g;
    int autoD7056FA9_u;

    // Variable Declarations
    unitgroup lv_nearbyCampDefenders;
    unit lv_campDefender;
    int lv_campIndex;
    order lv_order;

    // Variable Initialization
    lv_nearbyCampDefenders = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true)) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if (((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] + 10.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true)) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > 0.0)) {
        return false;
    }
    else {
    }
    if ((UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowers, c_unitCountAlive) > 0)) {
        return false;
    }
    else {
    }
    if ((UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes, c_unitCountAlive) > 0)) {
        return false;
    }
    else {
    }
    if ((UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, c_unitCountAlive) == 0) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowers, c_unitCountAlive) == 0) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyMinionsSummons, c_unitCountAlive) > 1)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval >= 200.0) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval < (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval + 100.0))) {
        return false;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 100.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowerEval + 300.0))))) {
        return false;
    }
    else {
    }
    lv_nearbyCampDefenders = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 6.0), UnitFilter((1 << c_targetFilterLight), 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    auto57A8744A_g = lv_nearbyCampDefenders;
    auto57A8744A_u = 1;
    for ( ; auto57A8744A_u <= UnitGroupCount(auto57A8744A_g, c_unitCountAll) ; auto57A8744A_u += BoolToInt(lv_campDefender == UnitGroupUnit(auto57A8744A_g, auto57A8744A_u)) ) {
        lv_campDefender = UnitGroupUnit(auto57A8744A_g, auto57A8744A_u);
        lv_campIndex = libMapM_gf_JungleGetJungleCampForUnit(lv_campDefender);
        if ((lv_campIndex > 0) && (libAIAI_gf_DefendersAreFighting(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex) == true)) {
            return false;
        }
        else {
        }
    }
    lv_nearbyCampDefenders = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 12.0), UnitFilter((1 << c_targetFilterLight), 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    autoD7056FA9_g = lv_nearbyCampDefenders;
    autoD7056FA9_u = 1;
    for ( ; autoD7056FA9_u <= UnitGroupCount(autoD7056FA9_g, c_unitCountAll) ; autoD7056FA9_u += BoolToInt(lv_campDefender == UnitGroupUnit(autoD7056FA9_g, autoD7056FA9_u)) ) {
        lv_campDefender = UnitGroupUnit(autoD7056FA9_g, autoD7056FA9_u);
        lv_order = UnitOrder(lv_campDefender, 0);
        if ((lv_order != null) && (OrderGetTargetType(lv_order) == c_orderTargetUnit) && (OrderGetTargetUnit(lv_order) == libGame_gv_players[lp_trigPlayer].lv_heroUnit)) {
            return false;
        }
        else {
        }
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 700.0))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIIsSideOfMapSafe (int lp_faction, fixed lp_modifier) {
    int autoB391A7CD_ae;
    int autoB391A7CD_ai;
    int autoC7265D48_ae;
    int autoC7265D48_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;
    point lv_contentionPoint;
    int lv_laneIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_numberOfMissingEnemies >= 3)) {
        return false;
    }
    else {
    }
    autoB391A7CD_ae = libCore_gv_bALMaxPlayers;
    autoB391A7CD_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoB391A7CD_ai >= 0 && lv_playerIndex <= autoB391A7CD_ae) || (autoB391A7CD_ai <= 0 && lv_playerIndex >= autoB391A7CD_ae) ) ; lv_playerIndex += autoB391A7CD_ai ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction != lp_faction) && (UnitIsAlive(libGame_gv_players[lv_playerIndex].lv_heroUnit) == true) && ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[lv_playerIndex].lv_lastSeenTime + libAIAI_gv_aIHeroMissingDelay) > TimerGetElapsed(libGame_gv_gameTimer)) && (libCore_gf_TestLocationClosertoFactionSide(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[lv_playerIndex].lv_lastSeenLocation, lp_faction, lp_modifier) == true)) {
            return false;
        }
        else {
        }
    }
    autoC7265D48_ae = libGame_gv_laneCount;
    autoC7265D48_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoC7265D48_ai >= 0 && lv_laneIndex <= autoC7265D48_ae) || (autoC7265D48_ai <= 0 && lv_laneIndex >= autoC7265D48_ae) ) ; lv_laneIndex += autoC7265D48_ai ) {
        lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_contentionPoint;
        if ((libGame_gv_laneData[lv_laneIndex].lv_minionSpawningEnabled == true) && (libCore_gf_TestLocationClosertoFactionSide(lv_contentionPoint, lp_faction, lp_modifier) == true)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAIIsNearbyLaneSafe (int lp_faction, point lp_testPoint, int lp_laneIndex) {
    // Variable Declarations
    point lv_closestPoint;
    int lv_closestIndex;
    int lv_secondaryIndex;
    fixed lv_closestLanePosition;
    fixed lv_enemyTownLanePosition;

    // Variable Initialization

    // Implementation
    libGame_gf_CalculateClosestLaneDataForLane(lp_testPoint, lp_laneIndex);
    lv_closestIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestIndex;
    lv_secondaryIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_secondaryIndex;
    lv_closestPoint = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestPoint;
    lv_closestLanePosition = AILaneWaypointConvertPointToWaydist(lp_laneIndex, lv_closestIndex, lv_secondaryIndex, lv_closestPoint);
    if ((lp_faction == 0)) {
        lv_enemyTownLanePosition = libAIAI_gv_heroAITeamData[(1)].lv_laneData[lp_laneIndex].lv_frontTowerPosition;
        return (lv_closestLanePosition <= lv_enemyTownLanePosition);
    }
    else {
        lv_enemyTownLanePosition = libAIAI_gv_heroAITeamData[(0)].lv_laneData[lp_laneIndex].lv_frontTowerPosition;
        return (lv_closestLanePosition >= lv_enemyTownLanePosition);
    }
}

bool libAIAI_gf_HeroAIShouldRetreatLane (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_lastAttacker;
    order lv_attackerOrder;
    bool lv_attackerTargettingMe;
    fixed lv_curLifePercent;
    fixed lv_contentionPointLanePosition;

    // Variable Initialization

    // Implementation
    lv_curLifePercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if ((lv_curLifePercent <= libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == true) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState != 2) && (libAIAI_gf_HeroAIInRangeOfAnEnemyTower(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, c_unitCountAlive) <= 1)) {
        return true;
    }
    else {
    }
    lv_contentionPointLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPointLanePosition;
    if ((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_gameState != 2) && (libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_minionSpawningEnabled == true) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyMinionsSummons, c_unitCountAlive) == 0) && (UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowers, c_unitCountAlive) == 0) && (libAIAI_gf_HeroAIIsPlayerBehindLanePosition(lp_trigPlayer, lv_contentionPointLanePosition) == false) && (!(((libAIAI_gv_aIHeroStayBehindMinionsNearTowers[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == false) && (libAIAI_gf_HeroAIInRangeOfAnEnemyTower(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true))))) {
        return true;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval < (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_selfEval + 90.0)) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 75.0))) {
        return true;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 200.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowerEval + 800.0))))) {
        return true;
    }
    else {
    }
    if ((((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval - libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowerEval) > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 1000.0)))) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIBeingTargettedByDangerousAbility(lp_trigPlayer) == true)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldRetreatFromAttacker (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_lastAttacker;
    order lv_attackerOrder;
    bool lv_attackerTargettingMe;
    fixed lv_curLifePercent;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    lv_curLifePercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
    if ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true)) {
        if ((lv_curLifePercent <= libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
            return true;
        }
        else {
        }
        lv_lastAttacker = libAIAI_gv_heroAIDamageTracking[lp_trigPlayer].lv_lastAttacker;
        lv_attackerOrder = UnitOrder(lv_lastAttacker, 0);
        if ((lv_attackerOrder != null) && (OrderGetTargetUnit(lv_attackerOrder) == libGame_gv_players[lp_trigPlayer].lv_heroUnit)) {
            lv_attackerTargettingMe = true;
        }
        else {
        }
        if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) != null) && (UnitTypeTestAttribute(UnitGetType(OrderGetTargetUnit(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0))), c_unitAttributeHeroic) == true) && (UnitGetPropertyFixed(OrderGetTargetUnit(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)), c_unitPropLifePercent, c_unitPropCurrent) < 30.0)) {
            if ((lv_attackerTargettingMe == true) && (UnitGetPropertyFixed(OrderGetTargetUnit(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)), c_unitPropLifePercent, c_unitPropCurrent) > 10.0)) {
                if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 500.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 3000.0)))) {
                    return true;
                }
                else {
                }
            }
            else {
            }
        }
        else {
            if ((UnitTypeTestAttribute(UnitGetType(lv_lastAttacker), c_unitAttributeHeroic) == true)) {
                if ((lv_curLifePercent < libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) && ((lv_attackerTargettingMe == true) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 200.0)))) {
                    return true;
                }
                else {
                }
            }
            else {
                if ((lv_curLifePercent < libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) && ((lv_attackerTargettingMe == true) || (UnitTypeTestAttribute(UnitGetType(lv_lastAttacker), c_unitAttributeStructure) == true))) {
                    return true;
                }
                else {
                }
            }
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldRetreatJungle (int lp_trigPlayer) {
    unitgroup autoA1725949_g;
    int autoA1725949_u;

    // Variable Declarations
    unit lv_lastAttacker;
    unitgroup lv_unitsNearCore;
    region lv_homeRegion;
    unit lv_allyHero;
    fixed lv_heroHealthPercent;
    fixed lv_allyHealthPercent;

    // Variable Initialization
    lv_unitsNearCore = UnitGroupEmpty();

    // Implementation
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome == true)) {
        return true;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 2.0) == true)) {
        lv_lastAttacker = libAIAI_gv_heroAIDamageTracking[lp_trigPlayer].lv_lastAttacker;
        if ((UnitTypeTestAttribute(UnitGetType(lv_lastAttacker), c_unitAttributeHeroic) == true)) {
            if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 150.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + 100.0)) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) {
                return true;
            }
            else {
            }
        }
        else {
            lv_heroHealthPercent = UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
            if ((lv_heroHealthPercent <= libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
                autoA1725949_g = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroes;
                autoA1725949_u = 1;
                for ( ; autoA1725949_u <= UnitGroupCount(autoA1725949_g, c_unitCountAll) ; autoA1725949_u += BoolToInt(lv_allyHero == UnitGroupUnit(autoA1725949_g, autoA1725949_u)) ) {
                    lv_allyHero = UnitGroupUnit(autoA1725949_g, autoA1725949_u);
                    lv_allyHealthPercent = UnitGetPropertyFixed(lv_allyHero, c_unitPropLifePercent, c_unitPropCurrent);
                    if ((UnitGetOwner(lv_allyHero) != lp_trigPlayer) && (lv_allyHealthPercent >= (lv_heroHealthPercent + 20.0))) {
                        return true;
                    }
                    else {
                    }
                }
            }
            else {
            }
        }
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 200.0)) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroEval >= (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyHeroEval + (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_allyTowerEval + 400.0))))) {
        return true;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalEnemyEval > (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_totalAllyEval + 800.0)))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIMountLogic (int lp_trigPlayer) {
    // Variable Declarations
    bool lv_isChannelingMount;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIHeroHasMount(lp_trigPlayer) == false)) {
        return false;
    }
    else {
    }
    if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) != null) && (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) == AbilityCommand("Mount", 0))) {
        lv_isChannelingMount = true;
    }
    else {
    }
    if (((lv_isChannelingMount == true) || (UnitHasBehavior(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "Mounted") == true))) {
        if ((libAIAI_gf_HeroAIShouldDismount(lp_trigPlayer) == true)) {
            if ((lv_isChannelingMount == true)) {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
            }
            else {
                UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("Dismount", 0)), c_orderQueueAddToFront);
            }
            return true;
        }
        else {
        }
    }
    else {
        if ((libAIAI_gf_HeroAIShouldMount(lp_trigPlayer) == true)) {
            UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("Mount", 0)), c_orderQueueReplace);
            return true;
        }
        else {
        }
    }
    return lv_isChannelingMount;
}

bool libAIAI_gf_HeroAIShouldMount (int lp_trigPlayer) {
    // Variable Declarations
    region lv_homeRegion;
    int lv_campIndex;
    point lv_campLoc;
    int lv_enemyTeamIndex;
    int lv_laneIndex;
    fixed lv_frontEnemyMinionLanePosition;
    point lv_frontEnemyMinionPoint;
    string lv_cooldownLink;
    order lv_order;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_homeRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_homeRegion = libCore_gv_mAPChaosBaseRegion;
    }
    lv_cooldownLink = CatalogFieldValueGet(c_gameCatalogAbil, "Mount", "Cost[" + IntToString(0) + "].Cooldown.Link", c_playerAny);
    if ((UnitGetCooldown(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_cooldownLink) > 0.0)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gf_HeroAITimeInCurrentState(lp_trigPlayer) < libAIAI_gv_aIHeroUseMountDelay[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return false;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0)) {
        if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) != null) && (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("move", 0))) {
            return false;
        }
        else {
        }
        lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
        if ((lv_campIndex > 0)) {
            lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
            if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) <= (libAIAI_gv_aIHeroLeashDistance * 1.5))) {
                return false;
            }
            else {
            }
        }
        else {
            if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 16) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_returnToLanePosition) <= (libAIAI_gv_aIHeroLaneLeashDistance * 2.0))) {
                return false;
            }
            else {
            }
        }
        if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true) && (libAIAI_gf_HeroAIEnemiesInHomeRegion(libGame_gv_players[lp_trigPlayer].lv_faction) == true)) {
            return false;
        }
        else {
        }
    }
    else {
        if ((UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0) != null) && (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("move", 0)) && (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0)) != AbilityCommand("attack", 0))) {
            return false;
        }
        else {
        }
        if ((RegionContainsPoint(lv_homeRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == false)) {
            return false;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIEnemiesInHomeRegion(libGame_gv_players[lp_trigPlayer].lv_faction) == true)) {
            return false;
        }
        else {
        }
        lv_enemyTeamIndex = libAIAI_gf_HeroAIGetEnemyTeamIndex(lp_trigPlayer);
        lv_laneIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane;
        lv_frontEnemyMinionLanePosition = libAIAI_gv_heroAITeamData[lv_enemyTeamIndex].lv_laneData[lv_laneIndex].lv_frontMinionPosition;
        lv_frontEnemyMinionPoint = AILaneWaypointConvertWaydistOffsetToPoint(lv_laneIndex, lv_frontEnemyMinionLanePosition, 0.0);
        if ((libCore_gf_TestLocationClosertoFactionSide(lv_frontEnemyMinionPoint, libGame_gv_players[lp_trigPlayer].lv_faction, 0.8) == true)) {
            return false;
        }
        else {
        }
    }
    if ((libAIAI_gf_HeroAIHasGameStarted() == true) && ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 3.0) == true) || (libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroMountingFarFromEnemies, true, true, true) > 0.0))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldDismount (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_distance;
    int lv_campIndex;
    point lv_campLoc;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroMountingCloseToEnemies, true, true, true) > 0.0)) {
        return true;
    }
    else {
    }
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    if ((lv_campIndex > 0)) {
        lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
        lv_distance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc);
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campLoc) <= libAIAI_gv_aIHeroLeashDistance)) {
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIDismount (int lp_trigPlayer) {
    // Implementation
    if ((UnitHasBehavior2(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "Mounted") == true)) {
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, Order(AbilityCommand("Dismount", 0)), c_orderQueueAddToFront);
        return true;
    }
    else {
        return false;
    }
}

void libAIAI_gf_HeroAISwapLanesLogic (int lp_faction) {
    int autoC0670020_ae;
    int autoC0670020_ai;
    playergroup auto37EB79D9_g;
    int auto37EB79D9_p;
    playergroup auto72C99F33_g;
    int auto72C99F33_p;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_playerIndex;
    int lv_swapOutPlayer;
    int lv_swapInPlayer;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoC0670020_ae = libGame_gv_laneCount;
    autoC0670020_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoC0670020_ai >= 0 && lv_laneIndex <= autoC0670020_ae) || (autoC0670020_ai <= 0 && lv_laneIndex >= autoC0670020_ae) ) ; lv_laneIndex += autoC0670020_ai ) {
        if (((libAIAI_gf_HeroAILaneHasAllMeleeHeroes(lp_faction, lv_laneIndex) == false) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes < 2) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numEnemyHeroes < 2))) {
            continue;
        }
        else {
        }
        lv_swapOutPlayer = 0;
        auto37EB79D9_g = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes; 
        auto37EB79D9_p = 1;
        for ( ; auto37EB79D9_p <= PlayerGroupCount(auto37EB79D9_g) ; auto37EB79D9_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto37EB79D9_g, auto37EB79D9_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(auto37EB79D9_g, auto37EB79D9_p);
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 28) == true) && (!(((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState == 0) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_startingLane > 0))))) {
                lv_swapOutPlayer = lv_playerIndex;
                break;
            }
            else {
            }
        }
        if ((lv_swapOutPlayer == 0)) {
            continue;
        }
        else {
        }
        lv_swapInPlayer = 0;
        auto72C99F33_g = libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_aIPlayers; 
        auto72C99F33_p = 1;
        for ( ; auto72C99F33_p <= PlayerGroupCount(auto72C99F33_g) ; auto72C99F33_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto72C99F33_g, auto72C99F33_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(auto72C99F33_g, auto72C99F33_p);
            if ((libAIAI_gf_HeroAIIsHeroMelee(lv_playerIndex) == false) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_desiredLane > 0) && (libAIAI_gf_HeroAIInLaneWithAllMeleeHeroes(lv_playerIndex) == false) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 28) == true) && (!(((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState == 0) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_startingLane > 0))))) {
                lv_swapInPlayer = lv_playerIndex;
                break;
            }
            else {
            }
        }
        if ((lv_swapInPlayer == 0)) {
            continue;
        }
        else {
        }
        libAIAI_gf_HeroAIChangeDesiredLane(lv_swapOutPlayer, libAIAI_gv_aIHeroes[lv_swapInPlayer].lv_desiredLane);
        libAIAI_gf_HeroAIChangeDesiredLane(lv_swapInPlayer, lv_laneIndex);
    }
}

bool libAIAI_gf_HeroAILaneChangingLogic (int lp_trigPlayer) {
    // Variable Declarations
    int lv_newLane;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAINeedstoSwitchLanes(lp_trigPlayer) == true)) {
        lv_newLane = libAIAI_gf_HeroAIChooseLaneLogic(lp_trigPlayer);
        if ((lv_newLane != libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane) && (lv_newLane != 0)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextChangeLanesConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroChangeLanesDelay);
            libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_newLane);
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

int libAIAI_gf_HeroAIChooseLaneLogic (int lp_player) {
    int autoA9D4C75F_val;
    int autoC13A1569_ae;
    int autoC13A1569_ai;

    // Variable Declarations
    int lv_teamIndex;
    point lv_leaderPosition;
    int lv_leaderLane;
    point lv_contentionPoint;
    int lv_laneIndex;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player);
    if ((libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer != 0) && (libGame_gv_players[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_isDead == false) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_lastSeenLane > 0)) {
        lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_heroUnit);
        lv_leaderLane = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_lastSeenLane;
        lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_leaderLane].lv_contentionPoint;
        if ((DistanceBetweenPoints(lv_leaderPosition, lv_contentionPoint) <= 15.0)) {
            return lv_leaderLane;
        }
        else {
        }
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_player].lv_followPlayer != 0) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_followPlayer].lv_lastSeenLane > 0)) {
        return libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_followPlayer].lv_lastSeenLane;
    }
    else {
    }
    if ((libAIAI_gf_HeroAINeedstoDefendBase(lp_player) == true)) {
        return libAIAI_gv_heroAITeamData[lv_teamIndex].lv_weakestLane;
    }
    else {
    }
    autoA9D4C75F_val = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState;
    if (autoA9D4C75F_val == 0) {
        if ((libAIAI_gv_aIHeroes[lp_player].lv_startingLane > 0)) {
            lv_laneIndex = libAIAI_gv_aIHeroes[lp_player].lv_startingLane;
        }
        else {
            if ((libAIAI_gf_HeroAIHaveEnemiesBeenSeenInLane(libGame_gv_players[lp_player].lv_faction) == false)) {
                lv_laneIndex = libAIAI_gf_HeroAIChooseStartingLaneLogic(lp_player);
            }
            else {
                lv_laneIndex = libAIAI_gf_HeroAIGetLaneThatPlayerShouldHelp(lp_player);
            }
        }
        if ((lv_laneIndex > 0)) {
            return lv_laneIndex;
        }
        else {
            return libAIAI_gv_heroAITeamData[lv_teamIndex].lv_weakestLane;
        }
    }
    else if (autoA9D4C75F_val == 1) {
        lv_laneIndex = libAIAI_gf_HeroAIGetLaneThatPlayerShouldHelp(lp_player);
        if ((lv_laneIndex > 0)) {
            return lv_laneIndex;
        }
        else {
            return libAIAI_gv_heroAITeamData[lv_teamIndex].lv_weakestLane;
        }
    }
    else {
        if ((libAIAI_gf_HeroAITeamHasHumanPlayers(libGame_gv_players[lp_player].lv_faction) == false)) {
            autoC13A1569_ae = libGame_gv_laneCount;
            autoC13A1569_ai = 1;
            lv_laneIndex = 1;
            for ( ; ( (autoC13A1569_ai >= 0 && lv_laneIndex <= autoC13A1569_ae) || (autoC13A1569_ai <= 0 && lv_laneIndex >= autoC13A1569_ae) ) ; lv_laneIndex += autoC13A1569_ai ) {
                if ((libAIAI_gf_HeroAIMercsAttackingLane(libGame_gv_players[lp_player].lv_faction, lv_laneIndex) == true)) {
                    return lv_laneIndex;
                }
                else {
                }
            }
        }
        else {
        }
        return libAIAI_gf_HeroAIGetLaneWithMostAllies(lp_player);
    }
}

bool libAIAI_gf_HeroAINeedstoDefendBase (int lp_player) {
    // Variable Declarations
    int lv_teamIndex;
    region lv_allyBaseRegion;
    region lv_enemyBaseRegion;
    int lv_laneIdx;
    int lv_weakestLane;
    point lv_weakestLaneContentionPoint;
    point lv_currentLaneContentionPoint;
    unitgroup lv_unitsNearCore;

    // Variable Initialization
    lv_unitsNearCore = UnitGroupEmpty();

    // Implementation
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        lv_teamIndex = (0);
        lv_allyBaseRegion = libCore_gv_mAPOrderBaseRegion;
        lv_enemyBaseRegion = libCore_gv_mAPChaosBaseRegion;
    }
    else {
        lv_teamIndex = (1);
        lv_allyBaseRegion = libCore_gv_mAPChaosBaseRegion;
        lv_enemyBaseRegion = libCore_gv_mAPOrderBaseRegion;
    }
    lv_weakestLane = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_weakestLane;
    lv_weakestLaneContentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_contentionPoint;
    lv_currentLaneContentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_contentionPoint;
    if ((lv_weakestLane != libAIAI_gv_aIHeroes[lp_player].lv_desiredLane) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numAllyTowns <= 1) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numEnemyHeroes >= 2) && (libCore_gf_TestLocationClosertoFactionSide(lv_weakestLaneContentionPoint, libGame_gv_players[lp_player].lv_faction, 0.65) == true) && (!(((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numAllyTowns >= libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numEnemyTowns) && (libCore_gf_TestLocationClosertoFactionSide(lv_currentLaneContentionPoint, libGame_gv_players[lp_player].lv_faction, 1.0) == false)))) && ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numAllyHeroes < libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numEnemyHeroes) || ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numAllyTowns > 0) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numAllyTowns == 0) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numAllyHeroes == libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_weakestLane].lv_numEnemyHeroes)))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAINeedstoSwitchLanes (int lp_player) {
    int auto266DF06C_val;
    int auto86B2095F_ae;
    int auto86B2095F_ai;

    // Variable Declarations
    int lv_teamIndex;
    point lv_leaderPosition;
    int lv_leaderLane;
    point lv_contentionPoint2;
    point lv_contentionPoint;
    int lv_laneIndex;
    fixed lv_lastTimeHumanEnteredLane;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player);
    if ((libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer != 0) && (libGame_gv_players[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_isDead == false) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_lastSeenLane > 0)) {
        lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_heroUnit);
        lv_leaderLane = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_leaderPlayer].lv_lastSeenLane;
        lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_leaderLane].lv_contentionPoint;
        if ((DistanceBetweenPoints(lv_leaderPosition, lv_contentionPoint) <= 15.0)) {
            return true;
        }
        else {
        }
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_player].lv_followPlayer != 0) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_followPlayer].lv_lastSeenLane > 0) && (libAIAI_gv_aIHeroes[lp_player].lv_desiredLane != libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_aIHeroes[lp_player].lv_followPlayer].lv_lastSeenLane)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidLane != 0) && (libAIAI_gv_aIHeroes[lp_player].lv_desiredLane == libAIAI_gv_heroAITeamData[lv_teamIndex].lv_heroTrackingData[libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidPlayer].lv_lastSeenLane)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numAllyHumanHeroes == 0) && (libAIAI_gf_HeroAINeedstoDefendBase(lp_player) == true)) {
        return true;
    }
    else {
    }
    if ((libGame_gv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_minionSpawningEnabled == false) && (libAIAI_gf_HeroAIMercsAttackingLane(libGame_gv_players[lp_player].lv_faction, libAIAI_gv_aIHeroes[lp_player].lv_desiredLane) == false)) {
        return true;
    }
    else {
    }
    lv_lastTimeHumanEnteredLane = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_lastTimeHumanAllyEnteredLane;
    if ((((lv_lastTimeHumanEnteredLane > 0.0) && ((lv_lastTimeHumanEnteredLane + libAIAI_gv_aIHeroStayInLaneAfterHumanArrivesDuration) > TimerGetElapsed(libGame_gv_gameTimer))) || ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numAllyHeroes == 2) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numAllyHumanHeroes == 1)))) {
        return false;
    }
    else {
    }
    if (((libAIAI_gv_aIHeroes[lp_player].lv_nextChangeLanesConsiderTime > TimerGetElapsed(libGame_gv_gameTimer)) || (libAIAI_gf_HeroAIIsHigherPriority(lp_player, 28) == false))) {
        return false;
    }
    else {
    }
    auto266DF06C_val = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_gameState;
    if (auto266DF06C_val == 0) {
        if ((libAIAI_gv_aIHeroes[lp_player].lv_startingLane > 0) && (libAIAI_gv_aIHeroes[lp_player].lv_desiredLane != libAIAI_gv_aIHeroes[lp_player].lv_startingLane)) {
            return true;
        }
        else {
        }
        if ((TimerGetElapsed(libGame_gv_gameTimer) < libAIAI_gv_aIHeroInitialLaneChoosingTime)) {
            return false;
        }
        else {
        }
        return (libAIAI_gf_HeroAIGetLaneThatPlayerShouldHelp(lp_player) != 0);
    }
    else if (auto266DF06C_val == 1) {
        return (libAIAI_gf_HeroAIGetLaneThatPlayerShouldHelp(lp_player) != 0);
    }
    else {
        lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_contentionPoint;
        if ((libCore_gf_TestLocationClosertoFactionSide(lv_contentionPoint, libGame_gv_players[lp_player].lv_faction, 0.8) == true)) {
            return false;
        }
        else {
        }
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_player].lv_desiredLane].lv_numAllyHumanHeroes > 0)) {
            return false;
        }
        else {
        }
        if ((libAIAI_gf_HeroAITeamHasHumanPlayers(libGame_gv_players[lp_player].lv_faction) == false)) {
            auto86B2095F_ae = libGame_gv_laneCount;
            auto86B2095F_ai = 1;
            lv_laneIndex = 1;
            for ( ; ( (auto86B2095F_ai >= 0 && lv_laneIndex <= auto86B2095F_ae) || (auto86B2095F_ai <= 0 && lv_laneIndex >= auto86B2095F_ae) ) ; lv_laneIndex += auto86B2095F_ai ) {
                if ((libAIAI_gv_aIHeroes[lp_player].lv_desiredLane != lv_laneIndex) && (libAIAI_gf_HeroAIMercsAttackingLane(libGame_gv_players[lp_player].lv_faction, lv_laneIndex) == true)) {
                    return true;
                }
                else {
                }
            }
        }
        else {
        }
        return (libAIAI_gv_aIHeroes[lp_player].lv_desiredLane != libAIAI_gf_HeroAIGetLaneWithMostAllies(lp_player));
    }
}

bool libAIAI_gf_HeroAIDoesLaneWantHelpFromPlayer (int lp_trigPlayer, int lp_laneIndex) {
    // Variable Declarations
    int lv_teamIndex;
    fixed lv_ourLaneEval;
    fixed lv_theirLaneEval;
    fixed lv_evalDifference;
    int lv_playerIndex;
    int lv_ourHeroIndex;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    lv_ourLaneEval = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane].lv_eval;
    lv_theirLaneEval = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_eval;
    lv_evalDifference = (lv_theirLaneEval - lv_ourLaneEval);
    if ((lv_evalDifference >= libAIAI_gv_aIHeroLargeEvalDifference)) {
        return false;
    }
    else {
    }
    if ((libGame_gv_laneData[lp_laneIndex].lv_minionSpawningEnabled == false)) {
        if ((libAIAI_gf_HeroAIMercsAttackingLane(libGame_gv_players[lp_trigPlayer].lv_faction, lp_laneIndex) == true) && (lv_theirLaneEval <= 0.0)) {
            return true;
        }
        else {
        }
    }
    else {
        if ((lv_evalDifference <= (-1.0 * libAIAI_gv_aIHeroLargeEvalDifference)) && (lv_theirLaneEval <= 0.0)) {
            return true;
        }
        else {
        }
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numAllyHeroes == 1)) {
            lv_playerIndex = PlayerGroupPlayer(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_allyHeroes, 1);
            lv_heroIndex = libGame_gv_players[lv_playerIndex].lv_heroIndex;
            if ((((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class == c_heroRoleSupport)) || ((libCore_gv_dataHeroesHeroData[lv_ourHeroIndex].lv_isMelee == false) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyHeroes > 1) && (libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == true)))) {
                return true;
            }
            else {

            }
        }
        else {
        }
        lv_ourHeroIndex = libGame_gv_players[lp_trigPlayer].lv_heroIndex;
        if ((libCore_gv_dataHeroesHeroData[lv_ourHeroIndex].lv_class != c_heroRoleSupport) && (libCore_gv_dataHeroesHeroData[lv_ourHeroIndex].lv_isMelee == false) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numAllyHeroes == 0) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyHeroes > 0)) {
            return true;
        }
        else {
        }
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numAllyHeroes == 4) && (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyHeroes >= 4)) {
            return true;
        }
        else {
        }
    }
    return false;
}

int libAIAI_gf_HeroAIGetLaneThatPlayerShouldHelp (int lp_trigPlayer) {
    int autoA43D71EB_ae;
    int autoA43D71EB_ai;

    // Variable Declarations
    int lv_startingLane;
    int lv_laneIndex;
    bool lv_wouldCauseCycle;

    // Variable Initialization

    // Implementation
    lv_startingLane = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane;
    autoA43D71EB_ae = libGame_gv_laneCount;
    autoA43D71EB_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoA43D71EB_ai >= 0 && lv_laneIndex <= autoA43D71EB_ae) || (autoA43D71EB_ai <= 0 && lv_laneIndex >= autoA43D71EB_ae) ) ; lv_laneIndex += autoA43D71EB_ai ) {
        if ((lv_laneIndex != lv_startingLane) && (libAIAI_gf_HeroAIDoesLaneWantHelpFromPlayer(lp_trigPlayer, lv_laneIndex) == true)) {
            libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_laneIndex);
            lv_wouldCauseCycle = libAIAI_gf_HeroAIDoesLaneWantHelpFromPlayer(lp_trigPlayer, lv_startingLane);
            libAIAI_gf_HeroAIChangeDesiredLane(lp_trigPlayer, lv_startingLane);
            if ((lv_wouldCauseCycle == false)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
        }
    }
    return 0;
}

int libAIAI_gf_HeroAIChooseStartingLaneLogic (int lp_trigPlayer) {
    // Variable Declarations
    int lv_heroIndex;
    int lv_laneIndex;

    // Variable Initialization

    // Implementation
    lv_heroIndex = libGame_gv_players[lp_trigPlayer].lv_heroIndex;
    if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == true)) {
        if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class == c_heroRoleSupport)) {
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloRanged(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithNoAllyHeroes(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloMelee(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloRangedSupport(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithNoAllyHeroes(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloRanged(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
        }
    }
    else {
        if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class == c_heroRoleSupport)) {
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloMelee(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithNoAllyHeroes(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloRanged(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloMeleeSupport(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithNoAllyHeroes(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
            lv_laneIndex = libAIAI_gf_HeroAIGetLaneWithSoloMelee(libGame_gv_players[lp_trigPlayer].lv_faction);
            if ((lv_laneIndex > 0)) {
                return lv_laneIndex;
            }
            else {
            }
        }
    }
    return libAIAI_gf_HeroAIGetLaneWithLeastAllyHeroes(libGame_gv_players[lp_trigPlayer].lv_faction);
}

int libAIAI_gf_HeroAIGetLaneWithNoAllyHeroes (int lp_team) {
    int autoE25F0472_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoE25F0472_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= autoE25F0472_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes == 0)) {
            return lv_laneIndex;
        }
        else {
        }
    }
    return 0;
}

int libAIAI_gf_HeroAIGetLaneWithLeastAllyHeroes (int lp_team) {
    int auto8FC7E94D_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_bestLaneIndex;
    int lv_leastHeroCount;

    // Variable Initialization
    lv_leastHeroCount = 99999999;

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto8FC7E94D_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= auto8FC7E94D_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes < lv_leastHeroCount)) {
            lv_bestLaneIndex = lv_laneIndex;
            lv_leastHeroCount = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes;
        }
        else {
        }
    }
    return lv_bestLaneIndex;
}

int libAIAI_gf_HeroAIGetLaneWithSoloMelee (int lp_team) {
    int autoD7200A44_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_playerIndex;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoD7200A44_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= autoD7200A44_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes == 1)) {
            lv_playerIndex = PlayerGroupPlayer(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes, 1);
            lv_heroIndex = libGame_gv_players[lv_playerIndex].lv_heroIndex;
            if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class != c_heroRoleSupport) && (libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == true)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
        }
    }
    return 0;
}

int libAIAI_gf_HeroAIGetLaneWithSoloRanged (int lp_team) {
    int auto2F055CAD_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_playerIndex;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto2F055CAD_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= auto2F055CAD_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes == 1)) {
            lv_playerIndex = PlayerGroupPlayer(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes, 1);
            lv_heroIndex = libGame_gv_players[lv_playerIndex].lv_heroIndex;
            if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class != c_heroRoleSupport) && (libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == false)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
        }
    }
    return 0;
}

int libAIAI_gf_HeroAIGetLaneWithSoloMeleeSupport (int lp_team) {
    int autoE6E12CA4_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_playerIndex;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoE6E12CA4_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= autoE6E12CA4_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes == 1)) {
            lv_playerIndex = PlayerGroupPlayer(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes, 1);
            lv_heroIndex = libGame_gv_players[lv_playerIndex].lv_heroIndex;
            if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == true) && (libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class == c_heroRoleSupport)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
        }
    }
    return 0;
}

int libAIAI_gf_HeroAIGetLaneWithSoloRangedSupport (int lp_team) {
    int auto4FD16FDF_ae;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_playerIndex;
    int lv_heroIndex;

    // Variable Initialization

    // Implementation
    if ((lp_team == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto4FD16FDF_ae = libGame_gv_laneCount;
    lv_laneIndex = 1;
    for ( ; lv_laneIndex <= auto4FD16FDF_ae ; lv_laneIndex += 1 ) {
        if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_numAllyHeroes == 1)) {
            lv_playerIndex = PlayerGroupPlayer(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes, 1);
            lv_heroIndex = libGame_gv_players[lv_playerIndex].lv_heroIndex;
            if ((libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_isMelee == false) && (libCore_gv_dataHeroesHeroData[lv_heroIndex].lv_class == c_heroRoleSupport)) {
                return lv_laneIndex;
            }
            else {
            }
        }
        else {
        }
    }
    return 0;
}

bool libAIAI_gf_HeroAIShouldEnterMinionBattle (int lp_trigPlayer) {
    // Variable Declarations
    point lv_contentionPoint;

    // Variable Initialization

    // Implementation
    lv_contentionPoint = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_contentionPoint;
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_contentionPoint) < 15.0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyHeroesNearContentionPoint > 0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyMinionsNearContentionPoint > 0) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllyMinionsNearContentionPoint > 0)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIMinionBattleFinished (int lp_trigPlayer) {
    // Implementation
    if (((libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyMinionsNearContentionPoint == 0) || (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllyMinionsNearContentionPoint == 0))) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIStartMinionBattleAttack (int lp_trigPlayer) {
    // Implementation
    if ((libAIAI_gf_HeroAIIsHeroMelee(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleAttackTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]);
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleAttackTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]);
    }
    libAIAI_gf_HeroAIResetWaypoint(lp_trigPlayer, true);
    libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 12);
}

void libAIAI_gf_HeroAIStartMinionBattleHarass (int lp_trigPlayer, unit lp_targetUnit) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleHarassTarget = lp_targetUnit;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleHarassTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinionBattleHarassDuration);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 13);
}

void libAIAI_gf_HeroAIStartMinionBattleRetreat (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_retreatLanePosition;
    point lv_retreatPosition;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 10);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRetreatTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinionBattleMinRetreatDuration);
    libAIAI_gf_HeroAIResetWaypoint(lp_trigPlayer, false);
    libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
}

void libAIAI_gf_HeroAIStartMinionBattleReposition (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_lastAttacker;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsHeroMelee(lp_trigPlayer) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextMinionBattleAttackTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMeleeMinionBattleRepositionDuration);
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextMinionBattleAttackTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroRangedMinionBattleRepositionDuration);
    }
    libAIAI_gf_HeroAIChangeLaneOffset(lp_trigPlayer, libAIAI_gf_HeroAIChooseNewLaneOffset(lp_trigPlayer, libAIAI_gf_HeroAIAllyHeroesinArea(lp_trigPlayer, libAIAI_gv_aIHeroAvoidAllyHeroesSearchRadius)));
    libAIAI_gf_HeroAIUpdateMinionBattleRepositionPosition(lp_trigPlayer);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 11);
}

void libAIAI_gf_HeroAIUpdateMinionBattleRepositionPosition (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_laneOffset;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextMinionBattleRepositionRecalculateTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroMinionBattleRepositionRecalculateDelay);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRepositionPositionOffset < 0.0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRepositionPositionOffset = 2.0;
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRepositionPositionOffset = -2.0;
    }
    lv_laneOffset = (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneOffset + libAIAI_gv_aIHeroes[lp_trigPlayer].lv_minionBattleRepositionPositionOffset);
    libAIAI_gf_HeroAICalcCurrentLaneInfo(lp_trigPlayer);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = AILaneWaypointConvertWaydistOffsetToPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroLanePosition, lv_laneOffset);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
}

void libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger (string lp_effectType, fixed lp_radius, fixed lp_duration, fixed lp_startOffset, bool lp_followsUnit) {
    // Implementation
    if ((libAIAI_gv_heroAINumRegisteredAOEAvoidEffects < libAIAI_gv_heroAIMaxAOEAvoidEffects)) {
        libAIAI_gv_heroAIAOEAvoidEffectList[libAIAI_gv_heroAINumRegisteredAOEAvoidEffects].lv_effect = lp_effectType;
        libAIAI_gv_heroAIAOEAvoidEffectList[libAIAI_gv_heroAINumRegisteredAOEAvoidEffects].lv_followsUnit = lp_followsUnit;
        libAIAI_gv_heroAIAOEAvoidEffectList[libAIAI_gv_heroAINumRegisteredAOEAvoidEffects].lv_radius = lp_radius;
        libAIAI_gv_heroAIAOEAvoidEffectList[libAIAI_gv_heroAINumRegisteredAOEAvoidEffects].lv_duration = lp_duration;
        libAIAI_gv_heroAIAOEAvoidEffectList[libAIAI_gv_heroAINumRegisteredAOEAvoidEffects].lv_startOffset = lp_startOffset;
        TriggerAddEventPlayerEffectUsed(libAIAI_gt_HeroAIWatchForAOEAbilityCasted, c_playerAny, lp_effectType);
        libAIAI_gv_heroAINumRegisteredAOEAvoidEffects += 1;
    }
    else {
    }
}

void libAIAI_gf_HeroAIRegisterDataModAOEEffects () {
    // Variable Declarations
    fixed lv_radius;
    fixed lv_duration;
    fixed lv_startOffset;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("ZombiePrisonPersistent", 3.5, 2.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("RavenousSoulsCreateUnit", 3.5, 8.5, 0.0, true);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("EntanglingRootsCreateUnit", 4.0, 3.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("CrushingGripInitialCreatePersistent", 2.0, 1.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("MaelstromCreatePersistent", 4.5, 12.0, 0.0, true);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("PrecisionStrikeWarningCreatePersistent", 5.0, 2.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("RainOfVengeanceStripPersistent", 5.0, 5.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("XplodiumBombCreatePersistent", 3.5, 4.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("GravOBomb3000Persistent", 7.5, 2.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("ApocalypseCreatePersistent", 4.0, 2.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("LightningBreathInitialSet", 5.0, 6.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("ElDruinsMightCreateSwordUnit", 3.5, 6.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("BarbarianWhirlwindCreatePersistent", 3.0, 3.0, 0.0, true);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("ArcaneFlareCreatePersistent", 3.0, 3.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("EmeraldWindInitialPersistent", 8.0, 5.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("NewMetamorphosisInitialSet", 6.0, 2.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("StageDivePersistent", 5.0, 4.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("HyperionSpawnEffectsSet", 9.0, 12.0, 0.0, true);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("NapalmStrikeWarningPersistent", 2.5, 5.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("TimeWarpCreatePersistent", 2.5, 5.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("VoidShiftCreatePersistent", 4.0, 5.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("StarfallCreatePersistent", 6.5, 8.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("BattleshipBombardPersistent", 6.0, 3.0, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("BindingRootsCreatePersistent", 2.5, 1.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("UnderworldBossStunCreatePersistent", 5.5, 1.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("UnderworldBossRootsCreatePersistent", 2.5, 1.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("UnderworldSummonedBossStunCreatePersistent", 5.5, 1.5, 0.0, false);
    libAIAI_gf_HeroAIRegisterAOEwithWatchTrigger("UnderworldSummonedBossRootsCreatePersistent", 2.5, 1.5, 0.0, false);
}

void libAIAI_gf_HeroAINotifyAOEStarting (int lp_faction, point lp_position, fixed lp_radius, fixed lp_expireTime) {
    int auto4AC63A6B_ae;

    // Variable Declarations
    int lv_playerIndex;
    bool lv_aOEStarting;
    bool lv_avoidingAOE;

    // Variable Initialization

    // Implementation
    auto4AC63A6B_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto4AC63A6B_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gv_aIHeroDodgeAOEAbilities[libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty] == true) && ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 7) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 8) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 10) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 11) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 12) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 14) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 20) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 38) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 40) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 44) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 27) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 29) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 28) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 30) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 32) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 33) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 34) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 35) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 36) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 48) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 49) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 50) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 51) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 54) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 53) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 57) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 58) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 61) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 63) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 64) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 65) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 66))) {
            lv_avoidingAOE = libAIAI_gf_HeroAIAvoidCircleArea(lv_playerIndex, lp_position, lp_radius, lp_expireTime);
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIAvoidAreaLogic (int lp_trigPlayer) {
    int autoAF4C8C6A_ae;
    int autoAF4C8C6A_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_avoidAreaIndex;
    point lv_position;
    fixed lv_radius;
    fixed lv_expireTime;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    autoAF4C8C6A_ae = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_numberofAvoidAreas;
    autoAF4C8C6A_ai = 1;
    lv_avoidAreaIndex = 1;
    for ( ; ( (autoAF4C8C6A_ai >= 0 && lv_avoidAreaIndex <= autoAF4C8C6A_ae) || (autoAF4C8C6A_ai <= 0 && lv_avoidAreaIndex >= autoAF4C8C6A_ae) ) ; lv_avoidAreaIndex += autoAF4C8C6A_ai ) {
        if ((TimerGetElapsed(libGame_gv_gameTimer) >= libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_startTime)) {
            if ((UnitIsValid(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_unit) == true)) {
                lv_position = UnitGetPosition(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_unit);
            }
            else {
                lv_position = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_position;
            }
            lv_radius = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_radius;
            lv_expireTime = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidAreas[lv_avoidAreaIndex].lv_expireTime;
            if ((libAIAI_gf_HeroAIAvoidCircleArea(lp_trigPlayer, lv_position, lv_radius, lv_expireTime) == true)) {
                return true;
            }
            else {
            }
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIAvoidCircleArea (int lp_trigPlayer, point lp_position, fixed lp_radius, fixed lp_expireTime) {
    // Variable Declarations
    int lv_teamIndex;
    point lv_playerPosition;
    order lv_heroOrder;
    point lv_orderTargetPosition;
    point lv_playerDirection;
    point lv_aheadOfPlayer;

    // Variable Initialization

    // Implementation
    lv_playerPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_heroOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_orderTargetPosition = OrderGetTargetPosition(lv_heroOrder);
    if ((lv_orderTargetPosition != null)) {
        lv_aheadOfPlayer = PointWithOffsetPolar(lv_playerPosition, 2.0, UnitGetFacing(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    }
    else {
    }
    if (((DistanceBetweenPoints(lv_playerPosition, lp_position) < lp_radius) || ((lv_aheadOfPlayer != null) && (DistanceBetweenPoints(lv_aheadOfPlayer, lp_position) < lp_radius)))) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition = libAIAI_gf_HeroAIGetAvoidCircleAreaRetreatPosition(lp_trigPlayer, lp_position, lp_radius);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_avoidAOETimeout = lp_expireTime;
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneTargetPosition), c_orderQueueReplace);
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 9);
        return true;
    }
    else {
    }
    return false;
}

point libAIAI_gf_HeroAIGetAvoidCircleAreaRetreatPosition (int lp_trigPlayer, point lp_position, fixed lp_radius) {
    int autoB30A10E4_ae;
    int autoB30A10E4_ai;

    // Variable Declarations
    point lv_heroPosition;
    fixed lv_avoidRadius;
    point lv_retreatPosition;
    point lv_retreatDirection;
    int lv_testIndex;
    fixed lv_angle;
    point lv_offset;
    point lv_testPoint;
    fixed lv_distance;
    fixed lv_bestDistance;

    // Variable Initialization
    lv_bestDistance = 524287.0;

    // Implementation
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_avoidRadius = (lp_radius + 1.0);
    lv_retreatDirection = AIGetDirection(lp_position, lv_heroPosition);
    lv_retreatPosition = libCore_gf_AdvancePointinDirection(lp_position, lv_retreatDirection, lv_avoidRadius);
    if ((PointPathingPassable(lv_retreatPosition) == true)) {
        return lv_retreatPosition;
    }
    else {
    }
    lv_retreatPosition = null;
    autoB30A10E4_ae = libAIAI_gv_aIHeroNumberOfAOERetreatTestPoints;
    autoB30A10E4_ai = 1;
    lv_testIndex = 1;
    for ( ; ( (autoB30A10E4_ai >= 0 && lv_testIndex <= autoB30A10E4_ae) || (autoB30A10E4_ai <= 0 && lv_testIndex >= autoB30A10E4_ae) ) ; lv_testIndex += autoB30A10E4_ai ) {
        lv_angle = (360.0 * (lv_testIndex / IntToFixed(libAIAI_gv_aIHeroNumberOfAOERetreatTestPoints)));
        lv_offset = Point((lv_avoidRadius * Cos(lv_angle)), (lv_avoidRadius * Sin(lv_angle)));
        lv_testPoint = Point((PointGetX(lp_position) + PointGetX(lv_offset)), (PointGetY(lp_position) + PointGetY(lv_offset)));
        lv_distance = DistanceBetweenPoints(lv_heroPosition, lv_testPoint);
        if ((PointPathingPassable(lv_testPoint) == true) && (lv_distance < lv_bestDistance)) {
            lv_bestDistance = lv_distance;
            lv_retreatPosition = lv_testPoint;
        }
        else {
        }
    }
    if ((lv_retreatPosition != null)) {
        return lv_retreatPosition;
    }
    else {
    }
    lv_retreatPosition = libGame_gv_players[lp_trigPlayer].lv_spawnPoint;
    return lv_retreatPosition;
}

void libAIAI_gf_HeroAIWatchTowerPinged (int lp_pingingPlayer, unit lp_watchTowerUnit) {
    playergroup auto9B7A488F_g;
    int auto9B7A488F_p;

    // Variable Declarations
    int lv_watchTowerIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    lv_watchTowerIndex = libGame_gf_WatchTowersGetWatchTowerIndexForUnit(lp_watchTowerUnit);
    if ((lv_watchTowerIndex <= 0)) {
        return ;
    }
    else {
    }
    auto9B7A488F_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_aIPlayers; 
    auto9B7A488F_p = 1;
    for ( ; auto9B7A488F_p <= PlayerGroupCount(auto9B7A488F_g) ; auto9B7A488F_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto9B7A488F_g, auto9B7A488F_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto9B7A488F_g, auto9B7A488F_p);
        if ((libAIAI_gf_HeroAIShouldCaptureWatchTower(lv_playerIndex, lv_watchTowerIndex) == true)) {
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetWatchTower = lv_watchTowerIndex;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 24);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAICaptureWatchTowerLogic (int lp_faction) {
    int auto810B45DB_ae;
    int auto810B45DB_ai;
    playergroup auto22756C13_g;
    int auto22756C13_p;

    // Variable Declarations
    int lv_teamPlayer;
    int lv_teamIndex;
    point lv_towerPosition;
    int lv_watchTowerIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
        lv_teamPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_teamIndex = (1);
        lv_teamPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextWatchTowerConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
    }
    libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextWatchTowerConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroWatchTowerConsiderFrequency - 3.0), (libAIAI_gv_aIHeroWatchTowerConsiderFrequency + 3.0)));
    if ((libNtve_gf_RandomPercent() >= libAIAI_gv_aIHeroChanceCaptureWatchTower[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)])) {
        return ;
    }
    else {
    }
    auto810B45DB_ae = libGame_gv_watchTowersCurrentCount;
    auto810B45DB_ai = 1;
    lv_watchTowerIndex = 1;
    for ( ; ( (auto810B45DB_ai >= 0 && lv_watchTowerIndex <= auto810B45DB_ae) || (auto810B45DB_ai <= 0 && lv_watchTowerIndex >= auto810B45DB_ae) ) ; lv_watchTowerIndex += auto810B45DB_ai ) {
        if ((UnitIsValid(libGame_gv_watchTowers[lv_watchTowerIndex].lv_watchTowerUnit) == true) && (lv_teamPlayer != UnitGetOwner(libGame_gv_watchTowers[lv_watchTowerIndex].lv_watchTowerUnit))) {
            lv_towerPosition = UnitGetPosition(libGame_gv_watchTowers[lv_watchTowerIndex].lv_watchTowerUnit);
            if ((libAIAI_gf_HeroAIIsNearbyLaneSafe(lp_faction, lv_towerPosition, libAIAI_gf_HeroAIGetClosestMinionLane(lv_towerPosition)) == false)) {
                continue;
            }
            else {
            }
            auto22756C13_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
            auto22756C13_p = 1;
            for ( ; auto22756C13_p <= PlayerGroupCount(auto22756C13_g) ; auto22756C13_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto22756C13_g, auto22756C13_p)) ) {
                lv_playerIndex = PlayerGroupPlayer(auto22756C13_g, auto22756C13_p);
                if ((libAIAI_gf_HeroAIShouldCaptureWatchTower(lv_playerIndex, lv_watchTowerIndex) == true)) {
                    libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                    libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetWatchTower = lv_watchTowerIndex;
                    libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                    libAIAI_gf_HeroAIChangeState(lv_playerIndex, 24);
                }
                else {
                }
            }
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIShouldCaptureWatchTower (int lp_trigPlayer, int lp_watchTowerIndex) {
    // Variable Declarations
    point lv_towerPosition;

    // Variable Initialization

    // Implementation
    lv_towerPosition = UnitGetPosition(libGame_gv_watchTowers[lp_watchTowerIndex].lv_watchTowerUnit);
    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_towerPosition) > libAIAI_gv_aIHeroWatchTowerCloseRadius)) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    if (((UnitGroupCount(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes, c_unitCountAlive) > 0) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 3.0) == true))) {
        return false;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 29) == false)) {
        return false;
    }
    else {
    }
    return true;
}

void libAIAI_gf_HeroAIMinionCampPinged (int lp_pingingPlayer, unit lp_targetUnit) {
    int auto787B61BD_ae;
    int auto787B61BD_ai;
    int auto9EABDDD1_ae;
    int auto9EABDDD1_ai;

    // Variable Declarations
    int lv_side;
    int lv_lastEntry;
    int lv_loopIndex;
    int lv_campIndex;

    // Variable Initialization
    lv_loopIndex = -1;
    lv_campIndex = -1;

    // Implementation
    if ((libGame_gv_players[lp_pingingPlayer].lv_faction == 0)) {
        lv_side = 0;
    }
    else {
        lv_side = 1;
    }
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_pingingPlayer, 1) == false)) {
        return ;
    }
    else {
    }
    lv_campIndex = libMapM_gf_JungleGetJungleCampForUnit(lp_targetUnit);
    if ((lv_campIndex < 1)) {
        return ;
    }
    else {
    }
    lv_lastEntry = libAIAI_gv_heroAITeamCampData[lv_side].lv_numberofCampPings;
    auto787B61BD_ae = lv_lastEntry;
    auto787B61BD_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto787B61BD_ai >= 0 && lv_loopIndex <= auto787B61BD_ae) || (auto787B61BD_ai <= 0 && lv_loopIndex >= auto787B61BD_ae) ) ; lv_loopIndex += auto787B61BD_ai ) {
        if ((libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[lv_loopIndex].lv_campPinged == lv_campIndex)) {
            lv_lastEntry = (lv_loopIndex - 1);
            break;
        }
        else {
        }
    }
    if ((lv_lastEntry >= libAIAI_gv_heroAIMaxCampPingCount)) {
        lv_lastEntry = (libAIAI_gv_heroAIMaxCampPingCount - 1);
    }
    else {
    }
    auto9EABDDD1_ae = 1;
    auto9EABDDD1_ai = -1;
    lv_loopIndex = lv_lastEntry;
    for ( ; ( (auto9EABDDD1_ai >= 0 && lv_loopIndex <= auto9EABDDD1_ae) || (auto9EABDDD1_ai <= 0 && lv_loopIndex >= auto9EABDDD1_ae) ) ; lv_loopIndex += auto9EABDDD1_ai ) {
        libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[(lv_loopIndex + 1)].lv_pingTime = libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[lv_loopIndex].lv_pingTime;
        libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[(lv_loopIndex + 1)].lv_campPinged = libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[lv_loopIndex].lv_campPinged;
        libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[(lv_loopIndex + 1)].lv_playerWhoPinged = libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[lv_loopIndex].lv_playerWhoPinged;
    }
    libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[1].lv_pingTime = TimerGetElapsed(libGame_gv_gameTimer);
    libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[1].lv_campPinged = lv_campIndex;
    libAIAI_gv_heroAITeamCampData[lv_side].lv_campPings[1].lv_playerWhoPinged = lp_pingingPlayer;
    if ((libAIAI_gv_heroAITeamCampData[lv_side].lv_numberofCampPings == lv_lastEntry)) {
        libAIAI_gv_heroAITeamCampData[lv_side].lv_numberofCampPings += 1;
    }
    else {
    }
    libAIAI_gv_heroAITeamCampData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_startCampCheckTimer = TimerGetElapsed(libGame_gv_gameTimer);
}

void libAIAI_gf_HeroAIMinionCampLogic (int lp_faction) {
    int autoBAE556CB_ae;
    int autoBAE556CB_ai;

    // Variable Declarations
    int lv_campInfo;
    int lv_loopIndex;
    int lv_campIndex;

    // Variable Initialization
    lv_loopIndex = -1;
    lv_campIndex = -1;

    // Implementation
    if ((lp_faction == 0)) {
        lv_campInfo = 0;
    }
    else {
        lv_campInfo = 1;
    }
    if ((libAIAI_gv_heroAITeamCampData[lv_campInfo].lv_startCampCheckTimer > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIEnemiesInHomeRegion(lp_faction) == true)) {
        return ;
    }
    else {
    }
    libAIAI_gv_heroAITeamCampData[lv_campInfo].lv_startCampCheckTimer = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroCampConsiderFrequency - 3.0), (libAIAI_gv_aIHeroCampConsiderFrequency + 3.0)));
    autoBAE556CB_ae = libAIAI_gv_heroAITeamCampData[lv_campInfo].lv_numberofCampPings;
    autoBAE556CB_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (autoBAE556CB_ai >= 0 && lv_loopIndex <= autoBAE556CB_ae) || (autoBAE556CB_ai <= 0 && lv_loopIndex >= autoBAE556CB_ae) ) ; lv_loopIndex += autoBAE556CB_ai ) {
        lv_campIndex = libAIAI_gv_heroAITeamCampData[lv_campInfo].lv_campPings[lv_loopIndex].lv_campPinged;
        if ((lv_campIndex > 0) && (libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, lv_loopIndex, libAIAI_gv_aIHeroHeadStraightToCampDist, false) == true)) {
            return ;
        }
        else {
        }
    }
    if ((libAIAI_gf_HeroAIAttackCampLogic(lp_faction, libAIAI_gv_aIHeroHeadStraightToCampDist) == true)) {
        libAIAI_gv_heroAITeamCampData[lv_campInfo].lv_startCampCheckTimer = (TimerGetElapsed(libGame_gv_gameTimer) + RandomFixed((libAIAI_gv_aIHeroCampAttackDelay - 3.0), (libAIAI_gv_aIHeroCampAttackDelay + 3.0)));
    }
    else {
    }
}

void libAIAI_gf_HeroAIJoinCampLogic (int lp_faction) {
    playergroup autoDE720941_g;
    int autoDE720941_p;

    // Variable Declarations
    int lv_teamIndex;
    int lv_campIndex;
    int lv_playerIndex;
    unit lv_targetUnit;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_joinCampCheckTimer > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_joinCampCheckTimer = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroJoinCampConsiderFrequency);
    }
    autoDE720941_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_humanPlayers; 
    autoDE720941_p = 1;
    for ( ; autoDE720941_p <= PlayerGroupCount(autoDE720941_g) ; autoDE720941_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoDE720941_g, autoDE720941_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoDE720941_g, autoDE720941_p);
        if ((UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0) != null) && (OrderGetAbilityCommand(UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0)) == AbilityCommand("attack", 0))) {
            lv_targetUnit = OrderGetTargetUnit(UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0));
            lv_campIndex = libMapM_gf_JungleGetJungleCampForUnit(OrderGetTargetUnit(UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0)));
            if ((lv_campIndex > 0) && (UnitTypeTestAttribute(UnitGetType(lv_targetUnit), c_unitAttributeLight) == true) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint) <= libAIAI_gv_aIHeroLeashDistance)) {
                libAIAI_gf_HeroAIMinionCampPinged(lv_playerIndex, lv_targetUnit);
            }
            else {
            }
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIAttackCampLogic (int lp_faction, fixed lp_searchRadius) {
    int auto9E7BDEAE_ae;
    int auto9E7BDEAE_ai;
    int autoC487D968_ae;
    int autoC487D968_ai;
    int auto7E33CC8C_ae;
    int auto7E33CC8C_ai;

    // Variable Declarations
    int lv_campInfo;
    int lv_loopIndex;
    int lv_campIndex;

    // Variable Initialization
    lv_loopIndex = -1;
    lv_campIndex = -1;

    // Implementation
    if ((lp_faction == 0)) {
        lv_campInfo = 0;
    }
    else {
        lv_campInfo = 1;
    }
    if (((libNtve_gf_RandomPercent() >= libAIAI_gv_aIHeroChanceNearbyMinionCamp[(libAIAI_gv_heroAITeamData[lv_campInfo].lv_difficulty)]) || (libAIAI_gf_HeroAIEnemiesInHomeRegion(lp_faction) == true))) {
        return false;
    }
    else {
    }
    auto9E7BDEAE_ae = libMapM_gv_jungleMaxCamps;
    auto9E7BDEAE_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto9E7BDEAE_ai >= 0 && lv_loopIndex <= auto9E7BDEAE_ae) || (auto9E7BDEAE_ai <= 0 && lv_loopIndex >= auto9E7BDEAE_ae) ) ; lv_loopIndex += auto9E7BDEAE_ai ) {
        if ((lp_faction == 0)) {
            lv_campIndex = libAIAI_gv_heroAIOrderMercCampList[lv_loopIndex];
        }
        else {
            lv_campIndex = libAIAI_gv_heroAIChaosMercCampList[lv_loopIndex];
        }
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, false) == true)) {
                return true;
            }
            else {
            }
        }
    }
    if (((libNtve_gf_RandomPercent() >= libAIAI_gv_aIHeroChanceMiddleMinionCamp[(libAIAI_gv_heroAITeamData[lv_campInfo].lv_difficulty)]) || (libAIAI_gf_HeroAIIsSideOfMapSafe(lp_faction, 0.6) == false))) {
        return false;
    }
    else {
    }
    autoC487D968_ae = libMapM_gv_jungleMaxCamps;
    autoC487D968_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (autoC487D968_ai >= 0 && lv_loopIndex <= autoC487D968_ae) || (autoC487D968_ai <= 0 && lv_loopIndex >= autoC487D968_ae) ) ; lv_loopIndex += autoC487D968_ai ) {
        lv_campIndex = libAIAI_gv_heroAIMiddleMercCampList[lv_loopIndex];
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, false) == true)) {
                return true;
            }
            else {
            }
        }
    }
    if (((libNtve_gf_RandomPercent() >= libAIAI_gv_aIHeroChanceFarMinionCamp[(libAIAI_gv_heroAITeamData[lv_campInfo].lv_difficulty)]) || (libAIAI_gf_HeroAIIsSideOfMapSafe(lp_faction, 1.1) == false))) {
        return false;
    }
    else {
    }
    auto7E33CC8C_ae = libMapM_gv_jungleMaxCamps;
    auto7E33CC8C_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto7E33CC8C_ai >= 0 && lv_loopIndex <= auto7E33CC8C_ae) || (auto7E33CC8C_ai <= 0 && lv_loopIndex >= auto7E33CC8C_ae) ) ; lv_loopIndex += auto7E33CC8C_ai ) {
        if ((lp_faction == 0)) {
            lv_campIndex = libAIAI_gv_heroAIChaosMercCampList[lv_loopIndex];
        }
        else {
            lv_campIndex = libAIAI_gv_heroAIOrderMercCampList[lv_loopIndex];
        }
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, false) == true)) {
                return true;
            }
            else {
            }
        }
    }
    return false;
}

bool libAIAI_gf_HeroAITeamAttackCampLogic (int lp_faction, fixed lp_searchRadius) {
    int auto6FF3FD52_ae;
    int auto6FF3FD52_ai;
    int auto7CB31608_ae;
    int auto7CB31608_ai;
    int auto576473E2_ae;
    int auto576473E2_ai;

    // Variable Declarations
    int lv_campInfo;
    int lv_loopIndex;
    int lv_campIndex;

    // Variable Initialization
    lv_loopIndex = -1;
    lv_campIndex = -1;

    // Implementation
    if ((lp_faction == 0)) {
        lv_campInfo = 0;
    }
    else {
        lv_campInfo = 1;
    }
    if ((libAIAI_gf_HeroAIEnemiesInHomeRegion(lp_faction) == true)) {
        return false;
    }
    else {
    }
    auto6FF3FD52_ae = libMapM_gv_jungleMaxCamps;
    auto6FF3FD52_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto6FF3FD52_ai >= 0 && lv_loopIndex <= auto6FF3FD52_ae) || (auto6FF3FD52_ai <= 0 && lv_loopIndex >= auto6FF3FD52_ae) ) ; lv_loopIndex += auto6FF3FD52_ai ) {
        if ((lp_faction == 0)) {
            lv_campIndex = libAIAI_gv_heroAIOrderMercCampList[lv_loopIndex];
        }
        else {
            lv_campIndex = libAIAI_gv_heroAIChaosMercCampList[lv_loopIndex];
        }
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAIIsPushWithTeamCamp(lv_campIndex) == true) && (libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, true) == true)) {
                return true;
            }
            else {
            }
        }
    }
    if ((libAIAI_gf_HeroAIIsSideOfMapSafe(lp_faction, 0.6) == false)) {
        return false;
    }
    else {
    }
    auto7CB31608_ae = libMapM_gv_jungleMaxCamps;
    auto7CB31608_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto7CB31608_ai >= 0 && lv_loopIndex <= auto7CB31608_ae) || (auto7CB31608_ai <= 0 && lv_loopIndex >= auto7CB31608_ae) ) ; lv_loopIndex += auto7CB31608_ai ) {
        lv_campIndex = libAIAI_gv_heroAIMiddleMercCampList[lv_loopIndex];
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAIIsPushWithTeamCamp(lv_campIndex) == true) && (libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, true) == true)) {
                return true;
            }
            else {
            }
        }
    }
    if ((libAIAI_gf_HeroAIIsSideOfMapSafe(lp_faction, 1.1) == false)) {
        return false;
    }
    else {
    }
    auto576473E2_ae = libMapM_gv_jungleMaxCamps;
    auto576473E2_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto576473E2_ai >= 0 && lv_loopIndex <= auto576473E2_ae) || (auto576473E2_ai <= 0 && lv_loopIndex >= auto576473E2_ae) ) ; lv_loopIndex += auto576473E2_ai ) {
        if ((lp_faction == 0)) {
            lv_campIndex = libAIAI_gv_heroAIChaosMercCampList[lv_loopIndex];
        }
        else {
            lv_campIndex = libAIAI_gv_heroAIOrderMercCampList[lv_loopIndex];
        }
        if ((lv_campIndex <= 0)) {
            break;
        }
        else {
            if ((libAIAI_gf_HeroAIIsPushWithTeamCamp(lv_campIndex) == true) && (libAIAI_gf_HeroAICanAttackCamp(lp_faction, lv_campIndex, -1, lp_searchRadius, true) == true)) {
                return true;
            }
            else {
            }
        }
    }
    return false;
}

void libAIAI_gf_HeroAIStartTakeCamp (int lp_trigPlayer, int lp_campIndex, int lp_humanPlayerAssisting) {
    // Implementation
    libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp = lp_campIndex;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_moveToCampStartTime = TimerGetElapsed(libGame_gv_gameTimer);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_arrivedAtCampTime = 0.0;
    if ((lp_humanPlayerAssisting > 0)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting = lp_humanPlayerAssisting;
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssistingDistance = -1;
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting = -1;
    }
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 37);
    if ((libAIAI_gf_HeroAINoOtherAllyAITakingCamp(lp_trigPlayer, lp_campIndex) == true)) {
        libGame_gf_SendEventHeroAIStartingCampAttack(libGame_gf_TeamNumberOfPlayer(lp_trigPlayer), lp_campIndex);
    }
    else {
    }
}

bool libAIAI_gf_HeroAICanAttackCamp (int lp_faction, int lp_campIndex, int lp_pingIndex, fixed lp_searchRadius, bool lp_recruitAll) {
    playergroup auto4054DC7E_g;
    int auto4054DC7E_p;
    int auto6B544463_ae;
    int auto6B544463_ai;
    int auto51324E02_ae;
    int auto51324E02_ai;

    // Variable Declarations
    int lv_playerWhoPinged;
    region lv_nearCamp;
    unitgroup lv_allyHeroesNearCamp;
    bool lv_campCaptured;
    playergroup lv_allyTeam;
    int lv_loopIndex;
    int lv_heroIndex;
    int lv_factionOwner;
    int lv_teamIndex;
    int lv_totalLevelNeeded;
    int lv_totalHeroLevel;
    int lv_totalHeroLevelAlreadyRecruited;
    int lv_numHeroes;
    int lv_levelNeeded;
    int lv_recruitPriority;
    int[11] lv_heroesToUse;
    point lv_campLoc;

    // Variable Initialization
    lv_allyHeroesNearCamp = UnitGroupEmpty();
    lv_allyTeam = PlayerGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = 0;
        lv_factionOwner = libCore_gv_cOMPUTER_TeamOrder;
        lv_allyTeam = libCore_gv_teamOrder;
    }
    else {
        lv_teamIndex = 1;
        lv_factionOwner = libCore_gv_cOMPUTER_TeamChaos;
        lv_allyTeam = libCore_gv_teamChaos;
    }
    if ((lp_pingIndex > 0)) {
        if ((lp_faction == 0)) {
            lv_playerWhoPinged = libAIAI_gv_heroAITeamCampData[(0)].lv_campPings[lp_pingIndex].lv_playerWhoPinged;
        }
        else {
            lv_playerWhoPinged = libAIAI_gv_heroAITeamCampData[(1)].lv_campPings[lp_pingIndex].lv_playerWhoPinged;
        }
    }
    else {
        lv_playerWhoPinged = -1;
    }
    if ((PlayerGroupCount(lv_allyTeam) == 0)) {
        return false;
    }
    else {
    }
    lv_campCaptured = (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIState == 2);
    if ((lv_campCaptured == true)) {
        return false;
    }
    else {
    }
    if ((lp_pingIndex <= 0) && (libAIAI_gf_HeroAIIsEasyCamp(lp_campIndex) == false) && (libAIAI_gv_aIHeroOnlyInitiateEasyCamps[lv_teamIndex] == true)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIEnemyHeroesNearCamp(lp_faction, lp_campIndex, libAIAI_gv_aIHeroEnemiesNearCampDistance, (lp_pingIndex <= 0)) > 0)) {
        return false;
    }
    else {
    }
    if ((libAIAI_gf_HeroAICampDefendersAreHibrinating(lp_campIndex) == true)) {
        return false;
    }
    else {
    }
    lv_nearCamp = RegionCircle(libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint, libAIAI_gv_aIHeroLeashDistance);
    lv_allyHeroesNearCamp = UnitGroupAlliance(PlayerGroupPlayer(lv_allyTeam, 1), c_unitAllianceAlly, lv_nearCamp, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((UnitGroupCount(lv_allyHeroesNearCamp, c_unitCountAlive) > 0) && (libAIAI_gf_HeroAICampEval(lp_campIndex) < 20.0)) {
        return false;
    }
    else {
    }
    lv_campLoc = libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint;
    if ((lp_pingIndex <= 0)) {
        lv_levelNeeded = ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lp_campIndex].lv_stateCurrentDefenderScalingTicks] * 2) / 3);
    }
    else {
        lv_levelNeeded = (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lp_campIndex].lv_stateCurrentDefenderScalingTicks] / 2);
    }
    if ((lv_levelNeeded < libAIAI_gv_aIHeroMinTakeCampLevel)) {
        lv_levelNeeded = libAIAI_gv_aIHeroMinTakeCampLevel;
    }
    else {
    }
    if ((lp_pingIndex <= 0)) {
        lv_recruitPriority = 24;
    }
    else {
        lv_recruitPriority = 10;
    }
    auto4054DC7E_g = libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_aIPlayers; 
    auto4054DC7E_p = 1;
    for ( ; auto4054DC7E_p <= PlayerGroupCount(auto4054DC7E_g) ; auto4054DC7E_p += BoolToInt(lv_loopIndex == PlayerGroupPlayer(auto4054DC7E_g, auto4054DC7E_p)) ) {
        lv_loopIndex = PlayerGroupPlayer(auto4054DC7E_g, auto4054DC7E_p);
        if ((libGame_gv_players[lv_loopIndex].lv_isDead != true) && (libAIAI_gf_HeroAIIsHigherPriority(lv_loopIndex, lv_recruitPriority) == true) && (UnitLevel(libGame_gv_players[lv_loopIndex].lv_heroUnit) >= lv_levelNeeded) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_loopIndex].lv_heroUnit), lv_campLoc) <= lp_searchRadius)) {
            lv_totalHeroLevel += UnitLevel(libGame_gv_players[lv_loopIndex].lv_heroUnit);
            lv_numHeroes += 1;
            lv_heroesToUse[lv_numHeroes] = lv_loopIndex;
        }
        else {
        }
    }
    if ((lv_numHeroes == 0)) {
        return false;
    }
    else {
    }
    lv_totalLevelNeeded = (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lp_campIndex].lv_stateCurrentDefenderScalingTicks] * 2);
    auto6B544463_ae = libCore_gv_bALMaxPlayers;
    auto6B544463_ai = 1;
    lv_loopIndex = 1;
    for ( ; ( (auto6B544463_ai >= 0 && lv_loopIndex <= auto6B544463_ae) || (auto6B544463_ai <= 0 && lv_loopIndex >= auto6B544463_ae) ) ; lv_loopIndex += auto6B544463_ai ) {
        if ((libGame_gv_players[lv_loopIndex].lv_faction == lp_faction) && (libGame_gv_players[lv_loopIndex].lv_heroUnit != null) && (libAIAI_gv_aIHeroes[lv_loopIndex].lv_heroState != 0) && (libGame_gv_players[lv_loopIndex].lv_isDead != true) && (libAIAI_gv_aIHeroes[lv_loopIndex].lv_curMinionCamp == lp_campIndex)) {
            lv_totalHeroLevelAlreadyRecruited += UnitLevel(libGame_gv_players[lv_loopIndex].lv_heroUnit);
        }
        else {
        }
    }
    lv_totalLevelNeeded -= lv_totalHeroLevelAlreadyRecruited;
    if ((lv_totalLevelNeeded <= 0)) {
        return false;
    }
    else {
    }
    if ((lp_pingIndex <= 0) && (lv_totalHeroLevel < lv_totalLevelNeeded)) {
        return false;
    }
    else {
    }
    while (((lv_totalLevelNeeded > 0) || (lp_recruitAll == true))) {
        lv_heroIndex = -1;
        auto51324E02_ae = lv_numHeroes;
        auto51324E02_ai = 1;
        lv_loopIndex = 1;
        for ( ; ( (auto51324E02_ai >= 0 && lv_loopIndex <= auto51324E02_ae) || (auto51324E02_ai <= 0 && lv_loopIndex >= auto51324E02_ae) ) ; lv_loopIndex += auto51324E02_ai ) {
            if ((lv_heroesToUse[lv_loopIndex] > 0) && ((lv_heroIndex <= 0) || (UnitLevel(libGame_gv_players[lv_heroesToUse[lv_heroIndex]].lv_heroUnit) < UnitLevel(libGame_gv_players[lv_heroesToUse[lv_loopIndex]].lv_heroUnit)))) {
                lv_heroIndex = lv_loopIndex;
            }
            else {
            }
        }
        if ((lv_heroIndex <= 0)) {
            break;
        }
        else {
        }
        lv_loopIndex = lv_heroIndex;
        lv_heroIndex = lv_heroesToUse[lv_loopIndex];
        libAIAI_gf_HeroAIStartTakeCamp(lv_heroIndex, lp_campIndex, lv_playerWhoPinged);
        lv_totalLevelNeeded -= UnitLevel(libGame_gv_players[lv_heroIndex].lv_heroUnit);
        lv_heroesToUse[lv_loopIndex] = -1;
    }
    libAIAI_gf_HeroAINotifyTeamHeadingToCamp(lv_playerWhoPinged, lp_faction, lp_campIndex);
    return true;
}

trigger auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_Trigger = null;
int auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_playerWhoPinged;
int auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_faction;
int auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_campIndex;

void libAIAI_gf_HeroAINotifyTeamHeadingToCamp (int lp_playerWhoPinged, int lp_faction, int lp_campIndex) {
    auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_playerWhoPinged = lp_playerWhoPinged;
    auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_faction = lp_faction;
    auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_campIndex = lp_campIndex;

    if (auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_Trigger == null) {
        auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_Trigger = TriggerCreate("auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_TriggerFunc");
    }

    TriggerExecute(auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_Trigger, false, false);
}

bool auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_TriggerFunc (bool testConds, bool runActions) {
    int lp_playerWhoPinged = auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_playerWhoPinged;
    int lp_faction = auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_faction;
    int lp_campIndex = auto_libAIAI_gf_HeroAINotifyTeamHeadingToCamp_lp_campIndex;

    int autoFFCAFE20_ae;
    int autoFFCAFE20_ai;
    int autoEFE6B5B2_ae;
    int autoEFE6B5B2_ai;
    playergroup autoDE281168_g;
    int autoDE281168_p;
    playergroup autoB11C1101_g;
    int autoB11C1101_p;
    unitgroup autoC28630AB_g;
    int autoC28630AB_u;

    // Variable Declarations
    point lv_campLocation;
    playergroup lv_allyTeam;
    int lv_attemptNumber;
    playergroup lv_heroesHeadingToCamp;
    int lv_playerIndex;
    bool lv_heroNearEnemies;
    fixed lv_distance;
    fixed lv_bestDistance;
    int lv_closestHero;
    int lv_defenderIndex;
    unit lv_defenderUnit;

    // Variable Initialization
    lv_allyTeam = PlayerGroupEmpty();
    lv_heroesHeadingToCamp = PlayerGroupEmpty();
    lv_bestDistance = 524287.0;

    // Implementation
    lv_campLocation = libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint;
    if ((lp_faction == 0)) {
        lv_allyTeam = libCore_gv_teamOrder;
    }
    else {
        lv_allyTeam = libCore_gv_teamChaos;
    }
    Wait(2.5, c_timeGame);
    autoFFCAFE20_ae = 4;
    autoFFCAFE20_ai = 1;
    lv_attemptNumber = 1;
    for ( ; ( (autoFFCAFE20_ai >= 0 && lv_attemptNumber <= autoFFCAFE20_ae) || (autoFFCAFE20_ai <= 0 && lv_attemptNumber >= autoFFCAFE20_ae) ) ; lv_attemptNumber += autoFFCAFE20_ai ) {
        lv_heroesHeadingToCamp = PlayerGroupEmpty();
        autoEFE6B5B2_ae = libCore_gv_bALMaxPlayers;
        autoEFE6B5B2_ai = 1;
        lv_playerIndex = 1;
        for ( ; ( (autoEFE6B5B2_ai >= 0 && lv_playerIndex <= autoEFE6B5B2_ae) || (autoEFE6B5B2_ai <= 0 && lv_playerIndex >= autoEFE6B5B2_ae) ) ; lv_playerIndex += autoEFE6B5B2_ai ) {
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curMinionCamp == lp_campIndex)) {
                PlayerGroupAdd(lv_heroesHeadingToCamp, lv_playerIndex);
            }
            else {
            }
        }
        if ((PlayerGroupCount(lv_heroesHeadingToCamp) == 0)) {
            return true;
        }
        else {
        }
        lv_heroNearEnemies = false;
        autoDE281168_g = lv_heroesHeadingToCamp; 
        autoDE281168_p = 1;
        for ( ; autoDE281168_p <= PlayerGroupCount(autoDE281168_g) ; autoDE281168_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoDE281168_g, autoDE281168_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(autoDE281168_g, autoDE281168_p);
            libAIAI_gf_HeroAIEval(lv_playerIndex);
            if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_totalEnemyEval > 0.0)) {
                lv_heroNearEnemies = true;
                break;
            }
            else {
            }
        }
        if ((lv_heroNearEnemies == true)) {
            Wait(1.0, c_timeGame);
            continue;
        }
        else {
        }
        autoB11C1101_g = lv_heroesHeadingToCamp; 
        autoB11C1101_p = 1;
        for ( ; autoB11C1101_p <= PlayerGroupCount(autoB11C1101_g) ; autoB11C1101_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoB11C1101_g, autoB11C1101_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(autoB11C1101_g, autoB11C1101_p);
            lv_distance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lv_campLocation);
            if ((lv_distance < lv_bestDistance)) {
                lv_bestDistance = lv_distance;
                lv_closestHero = lv_playerIndex;
            }
            else {
            }
        }
        if ((lv_bestDistance < libAIAI_gv_aIHeroLeashDistance)) {
            return true;
        }
        else {
        }
        if ((lp_playerWhoPinged > 0)) {
            libSond_gf_HeroVOPlayHeroLine(11, lv_closestHero, lv_allyTeam);
        }
        else {
            autoC28630AB_g = libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIDefenderAIIndex);
            autoC28630AB_u = 1;
            for ( ; autoC28630AB_u <= UnitGroupCount(autoC28630AB_g, c_unitCountAll) ; autoC28630AB_u += BoolToInt(lv_defenderUnit == UnitGroupUnit(autoC28630AB_g, autoC28630AB_u)) ) {
                lv_defenderUnit = UnitGroupUnit(autoC28630AB_g, autoC28630AB_u);
                if ((UnitIsValid(lv_defenderUnit) == true)) {
                    libUIUI_gf_UIPingPlayerPingsUnit(lv_closestHero, lv_defenderUnit, lv_allyTeam);
                    break;
                }
                else {
                }
            }
        }
        return true;
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldInitiateCamp (int lp_trigPlayer) {
    unitgroup autoE59D94D1_g;
    int autoE59D94D1_u;

    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    int lv_distance;
    region lv_nearbyRegion;
    unitgroup lv_nearbyFriendlyHeroes;
    unit lv_allyHero;
    int lv_totalNearbyHeroLevel;

    // Variable Initialization
    lv_nearbyFriendlyHeroes = UnitGroupEmpty();

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    if ((libAIAI_gf_DefendersAreFighting(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex) == true)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting > 0) && (libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == true)) {
        lv_distance = PointPathingCost(UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting].lv_heroUnit), lv_campLoc);
        if ((lv_distance > 12)) {
            return false;
        }
        else {
        }
    }
    else {
    }
    lv_nearbyRegion = RegionCircle(lv_campLoc, libAIAI_gv_aIHeroLeashDistance);
    lv_nearbyFriendlyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    autoE59D94D1_g = lv_nearbyFriendlyHeroes;
    autoE59D94D1_u = 1;
    for ( ; autoE59D94D1_u <= UnitGroupCount(autoE59D94D1_g, c_unitCountAll) ; autoE59D94D1_u += BoolToInt(lv_allyHero == UnitGroupUnit(autoE59D94D1_g, autoE59D94D1_u)) ) {
        lv_allyHero = UnitGroupUnit(autoE59D94D1_g, autoE59D94D1_u);
        lv_totalNearbyHeroLevel += UnitLevel(lv_allyHero);
    }
    if ((lv_totalNearbyHeroLevel < ((libMapM_gv_jungleCreepCamps[lv_campIndex].lv_defenderCampLevel[libMapM_gv_jungleCreepCamps[lv_campIndex].lv_stateCurrentDefenderScalingTicks] * 3) / 2))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldDefendCamp (int lp_trigPlayer) {
    // Variable Declarations
    int lv_enemyHeroesNearCamp;

    // Variable Initialization

    // Implementation
    lv_enemyHeroesNearCamp = libAIAI_gf_HeroAIEnemyHeroesNearCamp(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp, libAIAI_gv_aIHeroLeashDistance, false);
    if ((lv_enemyHeroesNearCamp > 0)) {
        return true;
    }
    else {
        return false;
    }
}

void libAIAI_gf_HeroAIStartCaptureCampBeacon (int lp_trigPlayer) {
    // Variable Declarations
    point lv_standPosition;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 41);
    lv_standPosition = libAIAI_gf_HeroAIChooseCampCaptureStandPosition(lp_trigPlayer);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_standPosition), c_orderQueueReplace);
}

void libAIAI_gf_HeroAIStartWaitAtCamp (int lp_trigPlayer) {
    // Variable Declarations
    point lv_standPosition;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 39);
    lv_standPosition = libAIAI_gf_HeroAIChooseCampGuardPosition(lp_trigPlayer);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_standPosition), c_orderQueueReplace);
}

point libAIAI_gf_HeroAIChooseCampGuardPosition (int lp_trigPlayer) {
    int auto4B209750_ae;
    int auto4B209750_ai;

    // Variable Declarations
    region lv_nearbyRegion;
    unitgroup lv_nearbyAllyHeroes;
    int lv_campIndex;
    point lv_campPosition;
    point lv_heroPosition;
    int lv_testIndex;
    fixed lv_angle;
    point lv_guardPosition;
    fixed lv_distance;
    point lv_bestGuardPosition;
    fixed lv_bestDistance;
    unit lv_closestAlly;
    fixed lv_closestAllyDistance;

    // Variable Initialization
    lv_nearbyAllyHeroes = UnitGroupEmpty();
    lv_bestDistance = 524287.0;

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campPosition = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_nearbyRegion = RegionCircle(lv_campPosition, libAIAI_gv_aIHeroLeashDistance);
    lv_nearbyAllyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, lv_nearbyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    UnitGroupRemove(lv_nearbyAllyHeroes, libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_bestGuardPosition = null;
    auto4B209750_ae = libAIAI_gv_aIHeroNumberOfCaptureBeaconGuardTestPoints;
    auto4B209750_ai = 1;
    lv_testIndex = 1;
    for ( ; ( (auto4B209750_ai >= 0 && lv_testIndex <= auto4B209750_ae) || (auto4B209750_ai <= 0 && lv_testIndex >= auto4B209750_ae) ) ; lv_testIndex += auto4B209750_ai ) {
        lv_angle = (360.0 * (lv_testIndex / IntToFixed(libAIAI_gv_aIHeroNumberOfCaptureBeaconGuardTestPoints)));
        lv_guardPosition = PointWithOffsetPolar(lv_campPosition, (libMapM_gv_bALJungleCampCaptureRadius + 2.0), lv_angle);
        if ((PointPathingPassable(lv_guardPosition) == false)) {
            continue;
        }
        else {
        }
        lv_distance = DistanceBetweenPoints(lv_heroPosition, lv_guardPosition);
        if ((lv_distance > lv_bestDistance)) {
            continue;
        }
        else {
        }
        if ((UnitGroupCount(lv_nearbyAllyHeroes, c_unitCountAlive) > 0)) {
            lv_closestAlly = UnitGroupClosestToPoint(lv_nearbyAllyHeroes, lv_guardPosition);
            lv_closestAllyDistance = DistanceBetweenPoints(UnitGetPosition(lv_closestAlly), lv_guardPosition);
            if ((lv_closestAllyDistance < 2.0) && (lv_closestAllyDistance < lv_distance)) {
                continue;
            }
            else {
            }
        }
        else {
        }
        lv_bestDistance = lv_distance;
        lv_bestGuardPosition = lv_guardPosition;
    }
    if ((lv_bestGuardPosition != null)) {
        return lv_bestGuardPosition;
    }
    else {
        return lv_campPosition;
    }
}

point libAIAI_gf_HeroAIChooseCampCaptureStandPosition (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    point lv_campPosition;
    point lv_heroPosition;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campPosition = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    if ((libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] == true)) {
        return libAIAI_gf_HeroAIChooseCampGuardPosition(lp_trigPlayer);
    }
    else {
        return lv_campPosition;
    }
}

unit libAIAI_gf_HeroAIAttackCampChooseTarget (int lp_trigPlayer) {
    unitgroup autoF20E035D_g;
    int autoF20E035D_u;
    unitgroup auto25193B89_g;
    int auto25193B89_u;

    // Variable Declarations
    int lv_campIndex;
    point lv_campLoc;
    unitgroup lv_enemies;
    unitgroup lv_enemySummons;
    unit lv_enemy;
    fixed lv_enemyHP;
    unit lv_bestTarget;
    fixed lv_bestTargetHP;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();
    lv_bestTargetHP = 524287.0;

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLoc = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(lv_campLoc, libAIAI_gv_aIHeroLeashDistance), UnitFilter(0, 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    autoF20E035D_g = lv_enemySummons;
    autoF20E035D_u = 1;
    for ( ; autoF20E035D_u <= UnitGroupCount(autoF20E035D_g, c_unitCountAll) ; autoF20E035D_u += BoolToInt(lv_enemy == UnitGroupUnit(autoF20E035D_g, autoF20E035D_u)) ) {
        lv_enemy = UnitGroupUnit(autoF20E035D_g, autoF20E035D_u);
        lv_enemyHP = UnitGetPropertyFixed(lv_enemy, c_unitPropLife, c_unitPropCurrent);
        if ((lv_enemyHP < lv_bestTargetHP)) {
            lv_bestTargetHP = lv_enemyHP;
            lv_bestTarget = lv_enemy;
        }
        else {
        }
    }
    if ((lv_bestTarget == null)) {
        auto25193B89_g = libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex);
        auto25193B89_u = 1;
        for ( ; auto25193B89_u <= UnitGroupCount(auto25193B89_g, c_unitCountAll) ; auto25193B89_u += BoolToInt(lv_enemy == UnitGroupUnit(auto25193B89_g, auto25193B89_u)) ) {
            lv_enemy = UnitGroupUnit(auto25193B89_g, auto25193B89_u);
            if ((UnitIsValid(lv_enemy) == true)) {
                lv_enemyHP = UnitGetPropertyFixed(lv_enemy, c_unitPropLife, c_unitPropCurrent);
                if ((lv_enemyHP < lv_bestTargetHP)) {
                    lv_bestTargetHP = lv_enemyHP;
                    lv_bestTarget = lv_enemy;
                }
                else {
                }
            }
            else {
            }
        }
    }
    else {
    }
    return lv_bestTarget;
}

void libAIAI_gf_HeroAIHeroStoppingCampAttack (int lp_trigPlayer) {
    // Variable Declarations
    int lv_playerIndex;
    int lv_campIndex;
    point lv_campLocation;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campLocation = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    libAIAI_gf_HeroAILeaveCamp(lp_trigPlayer);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting <= 0) && (libAIAI_gf_HeroAICampEval(lv_campIndex) >= libAIAI_gv_aIHeroHighCampEval) && (libAIAI_gf_HeroAIHumanAllyInArea(lp_trigPlayer, lv_campLocation, libAIAI_gv_aIHeroLeashDistance) == false)) {
        libAIAI_gf_HeroAICancelCampAttack(lv_campIndex, libGame_gv_players[lp_trigPlayer].lv_faction);
    }
    else {
    }
}

bool libAIAI_gf_HeroAIShouldCancelCampAttack (int lp_trigPlayer) {
    // Variable Declarations
    int lv_campIndex;
    int lv_enemyHeroesNearCamp;
    int lv_allyHeroesNearCamp;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_enemyHeroesNearCamp = libAIAI_gf_HeroAIEnemyHeroesNearCamp(libGame_gv_players[lp_trigPlayer].lv_faction, lv_campIndex, libAIAI_gv_aIHeroFarFromCampDistance, false);
    lv_allyHeroesNearCamp = libAIAI_gf_HeroAIAllyHeroesNearCamp(libGame_gv_players[lp_trigPlayer].lv_faction, lv_campIndex, libAIAI_gv_aIHeroFarFromCampDistance);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanPlayerAssisting <= 0) && (libAIAI_gf_HeroAICampEval(lv_campIndex) >= libAIAI_gv_aIHeroHighCampEval)) {
        if ((lv_allyHeroesNearCamp < lv_enemyHeroesNearCamp)) {
            return true;
        }
        else {
        }
    }
    else {
        if ((lv_allyHeroesNearCamp < (lv_enemyHeroesNearCamp - 1))) {
            return true;
        }
        else {
        }
    }
    if ((libAIAI_gf_HeroAICampDefendersAreHibrinating(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp) == true)) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAICancelCampAttack (int lp_campIndex, int lp_faction) {
    int auto3912B205_ae;
    int auto3912B205_ai;
    int autoDC69C3DC_ae;
    int autoDC69C3DC_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;
    int lv_pingIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto3912B205_ae = libCore_gv_bALMaxPlayers;
    auto3912B205_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto3912B205_ai >= 0 && lv_playerIndex <= auto3912B205_ae) || (auto3912B205_ai <= 0 && lv_playerIndex >= auto3912B205_ae) ) ; lv_playerIndex += auto3912B205_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curMinionCamp == lp_campIndex)) {
            libAIAI_gf_HeroAILeaveCamp(lv_playerIndex);
        }
        else {
        }
    }
    autoDC69C3DC_ae = libAIAI_gv_heroAIMaxCampPingCount;
    autoDC69C3DC_ai = 1;
    lv_pingIndex = 1;
    for ( ; ( (autoDC69C3DC_ai >= 0 && lv_pingIndex <= autoDC69C3DC_ae) || (autoDC69C3DC_ai <= 0 && lv_pingIndex >= autoDC69C3DC_ae) ) ; lv_pingIndex += autoDC69C3DC_ai ) {
        if ((libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_campPings[lv_pingIndex].lv_campPinged == lp_campIndex)) {
            libAIAI_gv_heroAITeamCampData[lv_teamIndex].lv_campPings[lv_pingIndex].lv_campPinged = -1;
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAILeaveCamp (int lp_trigPlayer) {
    // Variable Declarations
    int lv_teamIndex;
    int lv_campIndex;
    point lv_campPosition;
    bool lv_campCaptured;
    int lv_mercRallyLane;
    int lv_closestLane;

    // Variable Initialization

    // Implementation
    lv_campIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp;
    lv_campPosition = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mapDataCampCaptainSpawnPoint;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curMinionCamp = 0;
    if ((UnitGroupCount(libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lv_campIndex].lv_aIDefenderAIIndex), c_unitCountAlive) <= 0) && (libMapM_gv_jungleCreepCamps[lv_campIndex].lv_captureCaptureEnabled == false)) {
        lv_campCaptured = true;
    }
    else {
        lv_campCaptured = false;
    }
    if ((libAIAI_gf_HeroAINoOtherAllyAITakingCamp(lp_trigPlayer, lv_campIndex) == true)) {
        libGame_gf_SendEventHeroAIEndingCampAttack(libGame_gf_TeamNumberOfPlayer(lp_trigPlayer), lv_campIndex, lv_campCaptured);
    }
    else {
    }
    if ((lv_campCaptured == true) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_campPosition) <= libAIAI_gv_aIHeroLeashDistance)) {
        lv_teamIndex = libGame_gf_TeamNumberOfPlayer(lp_trigPlayer);
        lv_mercRallyLane = libMapM_gv_jungleCreepCamps[lv_campIndex].lv_mercSpawnLane[lv_teamIndex];
        if ((lv_mercRallyLane > 0) && (libAIAI_gf_HeroAIIsNearbyLaneSafe(libGame_gv_players[lp_trigPlayer].lv_faction, lv_campPosition, lv_mercRallyLane) == true)) {
            libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
            libAIAI_gf_HeroAIStartReturnToLane(lp_trigPlayer, lv_mercRallyLane);
            return ;
        }
        else {
        }
    }
    else {
    }
    lv_closestLane = libAIAI_gf_HeroAIGetClosestMinionLane(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    if ((libAIAI_gf_HeroAIIsNearbyLaneSafe(libGame_gv_players[lp_trigPlayer].lv_faction, lv_campPosition, lv_closestLane) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = false;
        libAIAI_gf_HeroAIStartReturnToLane(lp_trigPlayer, lv_closestLane);
        return ;
    }
    else {
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 45);
}

fixed libAIAI_gf_HeroAICampEval (int lp_campIndex) {
    unitgroup auto15FCA8F3_g;
    int auto15FCA8F3_u;

    // Variable Declarations
    fixed lv_campEval;
    unit lv_defenderUnit;

    // Variable Initialization

    // Implementation
    auto15FCA8F3_g = libAIAI_gf_DefenderGroup(libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIDefenderAIIndex);
    auto15FCA8F3_u = 1;
    for ( ; auto15FCA8F3_u <= UnitGroupCount(auto15FCA8F3_g, c_unitCountAll) ; auto15FCA8F3_u += BoolToInt(lv_defenderUnit == UnitGroupUnit(auto15FCA8F3_g, auto15FCA8F3_u)) ) {
        lv_defenderUnit = UnitGroupUnit(auto15FCA8F3_g, auto15FCA8F3_u);
        lv_campEval += (UnitGetPropertyFixed(lv_defenderUnit, c_unitPropLifePercent, c_unitPropCurrent) / IntToFixed(libMapM_gv_jungleCreepCamps[lp_campIndex].lv_defenderCount));
    }
    return lv_campEval;
}

bool libAIAI_gf_HeroAIIsEasyCamp (int lp_campIndex) {
    // Implementation
    if (((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampType == 2) || (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampType == 1) || ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampType == 0) && ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataMercSpawnType == 1))))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsPushWithTeamCamp (int lp_campIndex) {
    // Implementation
    if ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampType == 0) && ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataMercSpawnType == 2) || (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataMercSpawnType == 3))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAICampDefendersAreHibrinating (int lp_campIndex) {
    // Implementation
    return ((libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIState == 4) || (libMapM_gv_jungleCreepCamps[lp_campIndex].lv_aIState == 5));
}

bool libAIAI_gf_HeroAIEnemiesNearCamp (int lp_campIndex, int lp_faction, fixed lp_searchRadius, bool lp_visionCheat) {
    unitgroup auto0222D975_g;
    int auto0222D975_u;

    // Variable Declarations
    playergroup lv_allyTeam;
    int lv_allyComputerPlayer;
    point lv_campLocation;
    region lv_nearCamp;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unit lv_unit;

    // Variable Initialization
    lv_allyTeam = PlayerGroupEmpty();
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyTeam = libCore_gv_teamOrder;
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyTeam = libCore_gv_teamChaos;
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    lv_campLocation = libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_nearCamp = RegionCircle(lv_campLocation, lp_searchRadius);
    lv_enemies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceEnemy, lv_nearCamp, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((lp_visionCheat == false)) {
        auto0222D975_g = lv_enemyHeroes;
        auto0222D975_u = 1;
        for ( ; auto0222D975_u <= UnitGroupCount(auto0222D975_g, c_unitCountAll) ; auto0222D975_u += BoolToInt(lv_unit == UnitGroupUnit(auto0222D975_g, auto0222D975_u)) ) {
            lv_unit = UnitGroupUnit(auto0222D975_g, auto0222D975_u);
            if ((libNtve_gf_UnitIsVisibleToPlayer(lv_unit, PlayerGroupPlayer(lv_allyTeam, 1)) == false)) {
                UnitGroupRemove(lv_enemyHeroes, lv_unit);
            }
            else {
            }
        }
    }
    else {
    }
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
    }
    return false;
}

int libAIAI_gf_HeroAIEnemyHeroesNearCamp (int lp_faction, int lp_campIndex, fixed lp_searchRadius, bool lp_visionCheat) {
    unitgroup auto3BE2D896_g;
    int auto3BE2D896_u;

    // Variable Declarations
    int lv_allyComputerPlayer;
    point lv_campLocation;
    region lv_nearCamp;
    unitgroup lv_heroes;
    unit lv_unit;

    // Variable Initialization
    lv_heroes = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    lv_campLocation = libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_nearCamp = RegionCircle(lv_campLocation, lp_searchRadius);
    lv_heroes = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceEnemy, lv_nearCamp, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    if ((lp_visionCheat == false)) {
        auto3BE2D896_g = lv_heroes;
        auto3BE2D896_u = 1;
        for ( ; auto3BE2D896_u <= UnitGroupCount(auto3BE2D896_g, c_unitCountAll) ; auto3BE2D896_u += BoolToInt(lv_unit == UnitGroupUnit(auto3BE2D896_g, auto3BE2D896_u)) ) {
            lv_unit = UnitGroupUnit(auto3BE2D896_g, auto3BE2D896_u);
            if ((libNtve_gf_UnitIsVisibleToPlayer(lv_unit, lv_allyComputerPlayer) == false)) {
                UnitGroupRemove(lv_heroes, lv_unit);
            }
            else {
            }
        }
    }
    else {
    }
    return UnitGroupCount(lv_heroes, c_unitCountAlive);
}

int libAIAI_gf_HeroAIAllyHeroesNearCamp (int lp_faction, int lp_campIndex, fixed lp_searchRadius) {
    // Variable Declarations
    int lv_allyComputerPlayer;
    point lv_campLocation;
    region lv_nearCamp;
    unitgroup lv_heroes;
    unit lv_unit;

    // Variable Initialization
    lv_heroes = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    lv_campLocation = libMapM_gv_jungleCreepCamps[lp_campIndex].lv_mapDataCampCaptainSpawnPoint;
    lv_nearCamp = RegionCircle(lv_campLocation, lp_searchRadius);
    lv_heroes = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, lv_nearCamp, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    return UnitGroupCount(lv_heroes, c_unitCountAlive);
}

bool libAIAI_gf_HeroAIAllRecruitedAIHaveArrivedAtCamp (int lp_faction, int lp_campIndex) {
    int auto5851C891_ae;
    int auto5851C891_ai;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    auto5851C891_ae = libCore_gv_bALMaxPlayers;
    auto5851C891_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto5851C891_ai >= 0 && lv_playerIndex <= auto5851C891_ae) || (auto5851C891_ai <= 0 && lv_playerIndex >= auto5851C891_ae) ) ; lv_playerIndex += auto5851C891_ai ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libAIAI_gf_HeroAIGetCurrentObjective(lp_campIndex) == 4) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curMinionCamp == lp_campIndex) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_arrivedAtCampTime <= 0.0)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAINoOtherAllyAITakingCamp (int lp_trigPlayer, int lp_campIndex) {
    int autoEA81E634_ae;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    autoEA81E634_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoEA81E634_ae ; lv_playerIndex += 1 ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lp_trigPlayer, 2) == true) && (libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 4) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curMinionCamp == lp_campIndex)) {
            return false;
        }
        else {
        }
    }
    return true;
}

void libAIAI_gf_HeroAIDefendCoreLogic (int lp_faction) {
    int auto371D23FC_ae;
    int auto371D23FC_ai;
    unitgroup auto8DC1FC95_g;
    int auto8DC1FC95_u;
    unitgroup autoBC3FB77B_g;
    int autoBC3FB77B_u;
    unitgroup autoB8F8A992_g;
    int autoB8F8A992_u;

    // Variable Declarations
    point lv_corePosition;
    int lv_teamIndex;
    int lv_playerIndex;
    unitgroup lv_enemiesAttackingCore;
    unitgroup lv_alliesDefendingCore;
    unitgroup lv_availableAlliesNearCore;
    unitgroup lv_availableAlliesFarFromCore;
    int lv_heroesWantedToDefend;
    int lv_additionalHeroesWantedToDefend;
    unitgroup lv_heroesToRecruit;
    unit lv_hero;
    int lv_ownerPlayer;

    // Variable Initialization
    lv_enemiesAttackingCore = UnitGroupEmpty();
    lv_alliesDefendingCore = UnitGroupEmpty();
    lv_availableAlliesNearCore = UnitGroupEmpty();
    lv_availableAlliesFarFromCore = UnitGroupEmpty();
    lv_heroesToRecruit = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
        lv_teamIndex = (0);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
        lv_teamIndex = (1);
    }
    if ((libAIAI_gf_HeroAIEnemiesNearCore(lp_faction) == false)) {
        return ;
    }
    else {
    }
    auto371D23FC_ae = libCore_gv_bALMaxPlayers;
    auto371D23FC_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto371D23FC_ai >= 0 && lv_playerIndex <= auto371D23FC_ae) || (auto371D23FC_ai <= 0 && lv_playerIndex >= auto371D23FC_ae) ) ; lv_playerIndex += auto371D23FC_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true)) {
            if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction)) {
                if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true)) {
                    if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroFarFromCoreDistance)) {
                        UnitGroupAdd(lv_alliesDefendingCore, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                    }
                    else {
                    }
                }
                else {
                    if ((libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 3)) {
                        UnitGroupAdd(lv_alliesDefendingCore, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                    }
                    else {
                        if ((libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 6) == true)) {
                            if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroFarFromCoreDistance)) {
                                UnitGroupAdd(lv_availableAlliesNearCore, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                            }
                            else {
                                UnitGroupAdd(lv_availableAlliesFarFromCore, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                            }
                        }
                        else {
                        }
                    }
                }
            }
            else {
                if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroFarFromCoreDistance)) {
                    UnitGroupAdd(lv_enemiesAttackingCore, libGame_gv_players[lv_playerIndex].lv_heroUnit);
                }
                else {
                }
            }
        }
        else {
        }
    }
    lv_heroesWantedToDefend = MaxI(2, (UnitGroupCount(lv_enemiesAttackingCore, c_unitCountAlive) + 1));
    lv_additionalHeroesWantedToDefend = MaxI(0, (lv_heroesWantedToDefend - UnitGroupCount(lv_alliesDefendingCore, c_unitCountAlive)));
    auto8DC1FC95_g = lv_availableAlliesNearCore;
    auto8DC1FC95_u = 1;
    for ( ; auto8DC1FC95_u <= UnitGroupCount(auto8DC1FC95_g, c_unitCountAll) ; auto8DC1FC95_u += BoolToInt(lv_hero == UnitGroupUnit(auto8DC1FC95_g, auto8DC1FC95_u)) ) {
        lv_hero = UnitGroupUnit(auto8DC1FC95_g, auto8DC1FC95_u);
        UnitGroupAdd(lv_heroesToRecruit, lv_hero);
        lv_additionalHeroesWantedToDefend = MaxI(0, (lv_additionalHeroesWantedToDefend - 1));
    }
    if ((lv_additionalHeroesWantedToDefend > 0)) {
        autoBC3FB77B_g = lv_availableAlliesFarFromCore;
        autoBC3FB77B_u = 1;
        for ( ; autoBC3FB77B_u <= UnitGroupCount(autoBC3FB77B_g, c_unitCountAll) ; autoBC3FB77B_u += BoolToInt(lv_hero == UnitGroupUnit(autoBC3FB77B_g, autoBC3FB77B_u)) ) {
            lv_hero = UnitGroupUnit(autoBC3FB77B_g, autoBC3FB77B_u);
            UnitGroupAdd(lv_heroesToRecruit, lv_hero);
            lv_additionalHeroesWantedToDefend -= 1;
            if ((lv_additionalHeroesWantedToDefend == 0)) {
                break;
            }
            else {
            }
        }
    }
    else {
    }
    autoB8F8A992_g = lv_heroesToRecruit;
    autoB8F8A992_u = 1;
    for ( ; autoB8F8A992_u <= UnitGroupCount(autoB8F8A992_g, c_unitCountAll) ; autoB8F8A992_u += BoolToInt(lv_hero == UnitGroupUnit(autoB8F8A992_g, autoB8F8A992_u)) ) {
        lv_hero = UnitGroupUnit(autoB8F8A992_g, autoB8F8A992_u);
        if ((UnitGroupCount(lv_alliesDefendingCore, c_unitCountAlive) >= libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_difficulty)])) {
            break;
        }
        else {
        }
        UnitGroupRemove(lv_heroesToRecruit, lv_hero);
        UnitGroupAdd(lv_alliesDefendingCore, lv_hero);
        lv_ownerPlayer = UnitGetOwner(lv_hero);
        libAIAI_gf_HeroAILeaveCurrentObjective(lv_ownerPlayer);
        libAIAI_gv_aIHeroes[lv_ownerPlayer].lv_wantsToDefendCore = true;
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_ownerPlayer].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroFarFromCoreDistance) && (UnitGetPropertyFixed(libGame_gv_players[lv_ownerPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lv_ownerPlayer].lv_difficulty)])) {
            libAIAI_gf_HeroAIChangeState(lv_ownerPlayer, 20);
            libAIAI_gv_aIHeroes[lv_ownerPlayer].lv_currentLane = 0;
        }
        else {
            libAIAI_gv_aIHeroes[lv_ownerPlayer].lv_wantsToGoHome = true;
        }
    }
}

void libAIAI_gf_HeroAIReturnToDefendCoreLogic (int lp_faction) {
    playergroup autoD9C4D370_g;
    int autoD9C4D370_p;

    // Variable Declarations
    int lv_playerIndex;
    point lv_corePosition;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lv_playerIndex].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    autoD9C4D370_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    autoD9C4D370_p = 1;
    for ( ; autoD9C4D370_p <= PlayerGroupCount(autoD9C4D370_g) ; autoD9C4D370_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoD9C4D370_g, autoD9C4D370_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoD9C4D370_g, autoD9C4D370_p);
        if ((libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 3) && (libAIAI_gf_HeroAIGetCurrentPriority(lv_playerIndex) == 6) && (libAIAI_gf_HeroAIInDefendCoreState(lv_playerIndex) == false) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), lv_corePosition) <= libAIAI_gv_aIHeroFarFromCoreDistance) && (UnitGetPropertyFixed(libGame_gv_players[lv_playerIndex].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)] + 10.0))) {
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToGoHome = false;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 20);
        }
        else {
        }
    }
}

unit libAIAI_gf_HeroAIDefendCoreChooseTarget (int lp_trigPlayer, fixed lp_distance) {
    unitgroup auto6B847566_g;
    int auto6B847566_u;
    unitgroup auto4528409C_g;
    int auto4528409C_u;
    unitgroup autoDDF6427F_g;
    int autoDDF6427F_u;
    unitgroup auto1ED28190_g;
    int auto1ED28190_u;

    // Variable Declarations
    point lv_heroPosition;
    point lv_corePosition;
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyMinions;
    unitgroup lv_enemySummons;
    unit lv_hero;
    fixed lv_targetEval;
    unit lv_target;
    fixed lv_distance;
    unit lv_bestTarget;
    fixed lv_bestTargetDistance;
    order lv_currentOrder;
    unit lv_currentTarget;
    fixed lv_currentTargetDistance;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();
    lv_bestTargetDistance = 524287.0;

    // Implementation
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
    }
    lv_nearbyRegion = RegionCircle(lv_corePosition, lp_distance);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    auto6B847566_g = lv_enemyHeroes;
    auto6B847566_u = 1;
    for ( ; auto6B847566_u <= UnitGroupCount(auto6B847566_g, c_unitCountAll) ; auto6B847566_u += BoolToInt(lv_hero == UnitGroupUnit(auto6B847566_g, auto6B847566_u)) ) {
        lv_hero = UnitGroupUnit(auto6B847566_g, auto6B847566_u);
        if ((libNtve_gf_UnitIsVisibleToPlayer(lv_hero, lp_trigPlayer) == false)) {
            UnitGroupRemove(lv_enemyHeroes, lv_hero);
        }
        else {
        }
    }
    auto4528409C_g = lv_enemyMinions;
    auto4528409C_u = 1;
    for ( ; auto4528409C_u <= UnitGroupCount(auto4528409C_g, c_unitCountAll) ; auto4528409C_u += BoolToInt(lv_target == UnitGroupUnit(auto4528409C_g, auto4528409C_u)) ) {
        lv_target = UnitGroupUnit(auto4528409C_g, auto4528409C_u);
        lv_distance = DistanceBetweenPoints(UnitGetPosition(lv_target), lv_heroPosition);
        if ((lv_distance < lv_bestTargetDistance)) {
            lv_bestTarget = lv_target;
            lv_bestTargetDistance = lv_distance;
        }
        else {
        }
    }
    autoDDF6427F_g = lv_enemySummons;
    autoDDF6427F_u = 1;
    for ( ; autoDDF6427F_u <= UnitGroupCount(autoDDF6427F_g, c_unitCountAll) ; autoDDF6427F_u += BoolToInt(lv_target == UnitGroupUnit(autoDDF6427F_g, autoDDF6427F_u)) ) {
        lv_target = UnitGroupUnit(autoDDF6427F_g, autoDDF6427F_u);
        lv_distance = DistanceBetweenPoints(UnitGetPosition(lv_target), lv_heroPosition);
        if ((lv_distance < lv_bestTargetDistance)) {
            lv_bestTarget = lv_target;
            lv_bestTargetDistance = lv_distance;
        }
        else {
        }
    }
    auto1ED28190_g = lv_enemyHeroes;
    auto1ED28190_u = 1;
    for ( ; auto1ED28190_u <= UnitGroupCount(auto1ED28190_g, c_unitCountAll) ; auto1ED28190_u += BoolToInt(lv_target == UnitGroupUnit(auto1ED28190_g, auto1ED28190_u)) ) {
        lv_target = UnitGroupUnit(auto1ED28190_g, auto1ED28190_u);
        lv_distance = DistanceBetweenPoints(UnitGetPosition(lv_target), lv_heroPosition);
        if ((libAIAI_gv_aIHeroAvoidTargettingHeroes[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true)) {
            if (((lv_distance + 7.0) < lv_bestTargetDistance)) {
                lv_bestTarget = lv_target;
                lv_bestTargetDistance = lv_distance;
            }
            else {
            }
        }
        else {
            if ((lv_distance < lv_bestTargetDistance)) {
                lv_bestTarget = lv_target;
                lv_bestTargetDistance = lv_distance;
            }
            else {
            }
        }
    }
    lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    lv_currentTarget = OrderGetTargetUnit(lv_currentOrder);
    if ((lv_currentOrder != null) && (OrderGetAbilityCommand(lv_currentOrder) == AbilityCommand("attack", 0)) && (UnitIsValid(lv_currentTarget) == true)) {
        lv_currentTargetDistance = DistanceBetweenPoints(UnitGetPosition(lv_currentTarget), lv_corePosition);
        if ((lv_currentTargetDistance < (lv_bestTargetDistance + 3.0))) {
            lv_bestTarget = lv_currentTarget;
        }
        else {
        }
    }
    else {
    }
    return lv_bestTarget;
}

bool libAIAI_gf_HeroAIInDefendCoreState (int lp_trigPlayer) {
    // Implementation
    if (((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 20) || (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 21))) {
        return true;
    }
    else {
        return false;
    }
}

void libAIAI_gf_HeroAILeashFollowers (int lp_faction) {
    playergroup auto8285F7D0_g;
    int auto8285F7D0_p;

    // Variable Declarations
    int lv_playerIndex;
    point lv_heroPosition;
    point lv_leaderPosition;

    // Variable Initialization

    // Implementation
    auto8285F7D0_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto8285F7D0_p = 1;
    for ( ; auto8285F7D0_p <= PlayerGroupCount(auto8285F7D0_g) ; auto8285F7D0_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto8285F7D0_g, auto8285F7D0_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto8285F7D0_g, auto8285F7D0_p);
        if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_leaderPlayer > 0) && (libGame_gv_players[libAIAI_gv_aIHeroes[lv_playerIndex].lv_leaderPlayer].lv_isDead == false) && (UnitGetPropertyFixed(libGame_gv_players[lv_playerIndex].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)]) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 4) == true)) {
            lv_heroPosition = UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit);
            lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lv_playerIndex].lv_leaderPlayer].lv_heroUnit);
            if ((DistanceBetweenPoints(lv_heroPosition, lv_leaderPosition) > libAIAI_gv_aIHeroFollowerLeashDistance) && (DistanceBetweenPoints(lv_heroPosition, lv_leaderPosition) < libAIAI_gv_aIHeroFollowerStopLeashingDistance)) {
                libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                libAIAI_gf_HeroAIChangeState(lv_playerIndex, 56);
            }
            else {
            }
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIFollowLeaderTimeout (int lp_faction) {
    playergroup autoAC8ABCE1_g;
    int autoAC8ABCE1_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    autoAC8ABCE1_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    autoAC8ABCE1_p = 1;
    for ( ; autoAC8ABCE1_p <= PlayerGroupCount(autoAC8ABCE1_g) ; autoAC8ABCE1_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoAC8ABCE1_g, autoAC8ABCE1_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoAC8ABCE1_g, autoAC8ABCE1_p);
        if ((libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 9) && (TimerGetElapsed(libGame_gv_gameTimer) > libAIAI_gv_aIHeroes[lv_playerIndex].lv_followLeaderTimeout)) {
            libAIAI_gf_HeroAIStopFollowingLeader(lv_playerIndex);
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIShouldStopFollowingLeader (int lp_trigPlayer) {
    // Variable Declarations
    point lv_leaderPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer <= 0)) {
        return false;
    }
    else {
    }
    lv_leaderPosition = UnitGetPosition(libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer].lv_heroUnit);
    if (((libGame_gv_players[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer].lv_isDead == true) || (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_leaderPosition) > libAIAI_gv_aIHeroFollowerStopLeashingDistance))) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIStartFollowingLeader (int lp_trigPlayer, int lp_leaderPlayer) {
    // Variable Declarations
    text lv_followerName;
    text lv_leaderName;
    text lv_message;

    // Variable Initialization

    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer = lp_leaderPlayer;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_followLeaderTimeout = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIFollowLeaderDuration);
    lv_followerName = UnitTypeGetName(UnitGetType(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    lv_leaderName = UnitTypeGetName(UnitGetType(libGame_gv_players[lp_leaderPlayer].lv_heroUnit));
    TextExpressionSetToken("Param/Expression/lib_AIAI_8F588C94", "A", lv_followerName);
    TextExpressionSetToken("Param/Expression/lib_AIAI_8F588C94", "B", lv_leaderName);
    lv_message = TextExpressionAssemble("Param/Expression/lib_AIAI_8F588C94");
    UIDisplayMessage(libGame_gf_AlliedPlayerGroupOfPlayer(lp_leaderPlayer), c_messageAreaChat, lv_message);
}

void libAIAI_gf_HeroAIStopFollowingLeader (int lp_trigPlayer) {
    // Variable Declarations
    int lv_leaderPlayer;
    text lv_followerName;
    text lv_leaderName;
    text lv_message;

    // Variable Initialization

    // Implementation
    lv_leaderPlayer = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer;
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_leaderPlayer = 0;
    if ((libAIAI_gf_HeroAIIsInFollowerState(lp_trigPlayer) == true)) {
        libAIAI_gf_HeroAIReturnToClosestLane(lp_trigPlayer);
    }
    else {
    }
    lv_followerName = UnitTypeGetName(UnitGetType(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    lv_leaderName = UnitTypeGetName(UnitGetType(libGame_gv_players[lv_leaderPlayer].lv_heroUnit));
    TextExpressionSetToken("Param/Expression/lib_AIAI_3B9B1518", "A", lv_followerName);
    TextExpressionSetToken("Param/Expression/lib_AIAI_3B9B1518", "B", lv_leaderName);
    lv_message = TextExpressionAssemble("Param/Expression/lib_AIAI_3B9B1518");
    UIDisplayMessage(libGame_gf_AlliedPlayerGroupOfPlayer(lv_leaderPlayer), c_messageAreaChat, lv_message);
}

void libAIAI_gf_HeroAITearOfElunePinged (int lp_pingingPlayer) {
    playergroup autoC09D208E_g;
    int autoC09D208E_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState != 1) && (libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState != 2)) {
        return ;
    }
    else {
    }
    autoC09D208E_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_aIPlayers; 
    autoC09D208E_p = 1;
    for ( ; autoC09D208E_p <= PlayerGroupCount(autoC09D208E_g) ; autoC09D208E_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoC09D208E_g, autoC09D208E_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoC09D208E_g, autoC09D208E_p);
        if ((libAIAI_gf_HeroAIShouldCaptureTearOfElune(lv_playerIndex, true) == true)) {
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToCaptureTearOfElune = true;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 27);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAICaptureTearOfEluneLogic (int lp_faction) {
    playergroup autoBDB35C42_g;
    int autoBDB35C42_p;

    // Variable Declarations
    int lv_teamIndex;
    unit lv_tear;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextTearOfEluneConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextTearOfEluneConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTearOfEluneConsiderFrequency);
    }
    if (((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 1) || (libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 2))) {
        autoBDB35C42_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
        autoBDB35C42_p = 1;
        for ( ; autoBDB35C42_p <= PlayerGroupCount(autoBDB35C42_g) ; autoBDB35C42_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoBDB35C42_g, autoBDB35C42_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(autoBDB35C42_g, autoBDB35C42_p);
            if ((libAIAI_gf_HeroAIShouldCaptureTearOfElune(lv_playerIndex, false) == true)) {
                libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToCaptureTearOfElune = true;
                libAIAI_gf_HeroAIChangeState(lv_playerIndex, 27);
            }
            else {
            }
        }
    }
    else {
    }
}

bool libAIAI_gf_HeroAIShouldCaptureTearOfElune (int lp_trigPlayer, bool lp_playerPigned) {
    // Variable Declarations
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 0)) {
        return false;
    }
    else {
    }
    if (((libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 9) == false) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) || (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition) > libAIAI_gv_aIHeroTearOfEluneRecruitDistance) || ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 2.0) == true) && (UnitTypeTestAttribute(UnitGetType(libAIAI_gv_heroAIDamageTracking[lp_trigPlayer].lv_lastAttacker), c_unitAttributeHeroic) == true)))) {
        return false;
    }
    else {
    }
    if ((lp_playerPigned == false) && (libAIAI_gf_HeroAINumberOfAIAlliesCapturingTear(lp_trigPlayer) >= libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return false;
    }
    else {
    }
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroFarFromTearOfEluneDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroFarFromTearOfEluneDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) >= (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) + 2))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldGiveUpOnTearOfElune (int lp_trigPlayer) {
    // Variable Declarations
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 0)) {
        return true;
    }
    else {
    }
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroFarFromTearOfEluneDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, (libAIAI_gv_aIHeroFarFromTearOfEluneDistance * 2.0)), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) >= (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) + 2))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldDefendTearOfElune (int lp_trigPlayer) {
    unitgroup auto02C2D730_g;
    int auto02C2D730_u;

    // Variable Declarations
    region lv_areaAroundTear;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemySummons;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;
    unit lv_hero;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState == 0)) {
        return false;
    }
    else {
    }
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroFarFromTearOfEluneDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_areaAroundTear = RegionCircle(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, libAIAI_gv_aIHeroCloseToTearOfEluneDistance);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_areaAroundTear, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    auto02C2D730_g = lv_enemyHeroes;
    auto02C2D730_u = 1;
    for ( ; auto02C2D730_u <= UnitGroupCount(auto02C2D730_g, c_unitCountAll) ; auto02C2D730_u += BoolToInt(lv_hero == UnitGroupUnit(auto02C2D730_g, auto02C2D730_u)) ) {
        lv_hero = UnitGroupUnit(auto02C2D730_g, auto02C2D730_u);
        if ((libNtve_gf_UnitIsVisibleToPlayer(lv_hero, lp_trigPlayer) == false)) {
            UnitGroupRemove(lv_enemyHeroes, lv_hero);
        }
        else {
        }
    }
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 28) && (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == false) && (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) > UnitGroupCount(lv_enemyHeroes, c_unitCountAlive))) {
        return false;
    }
    else {
    }
    if (((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0) || (UnitGroupCount(lv_enemySummons, c_unitCountAlive) > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsAllyCapturingTear (int lp_trigPlayer) {
    int auto6A00281C_ae;
    int auto6A00281C_ai;

    // Variable Declarations
    int lv_playerIndex;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    auto6A00281C_ae = libCore_gv_bALMaxPlayers;
    auto6A00281C_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto6A00281C_ai >= 0 && lv_playerIndex <= auto6A00281C_ae) || (auto6A00281C_ai <= 0 && lv_playerIndex >= auto6A00281C_ae) ) ; lv_playerIndex += auto6A00281C_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction)) {
            if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit)) > libAIAI_gv_aIHeroCloseToTearOfEluneDistance)) {
                continue;
            }
            else {
            }
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true)) {
                if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 28)) {
                    return true;
                }
                else {
                }
            }
            else {
                lv_heroOrder = UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0);
                if ((lv_heroOrder != null) && (OrderGetTargetType(lv_heroOrder) == c_orderTargetUnit) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("CaptureMacGuffin", 0)) && (OrderGetTargetUnit(lv_heroOrder) == libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit)) {
                    return true;
                }
                else {
                }
            }
        }
        else {
        }
    }
    return false;
}

int libAIAI_gf_HeroAINumberOfAIAlliesCapturingTear (int lp_trigPlayer) {
    int auto23C7A0BD_ae;
    int auto23C7A0BD_ai;

    // Variable Declarations
    int lv_playerIndex;
    int lv_count;

    // Variable Initialization

    // Implementation
    auto23C7A0BD_ae = libCore_gv_bALMaxPlayers;
    auto23C7A0BD_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto23C7A0BD_ai >= 0 && lv_playerIndex <= auto23C7A0BD_ae) || (auto23C7A0BD_ai <= 0 && lv_playerIndex >= auto23C7A0BD_ae) ) ; lv_playerIndex += auto23C7A0BD_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 6)) {
            lv_count += 1;
        }
        else {
        }
    }
    return lv_count;
}

void libAIAI_gf_HeroAIChooseTearOfEluneGuardPostion (int lp_trigPlayer) {
    int auto73FCA898_ae;
    int auto73FCA898_ai;
    int auto42C2BD08_ae;

    // Variable Declarations
    point lv_orderBaseEndpoint;
    point lv_chaosBaseEndpoint;
    point[5] lv_candidateGuardPositions;
    int lv_index;
    int lv_playerIndex;
    bool lv_positionTaken;
    point lv_otherHeroGuardPosition;
    fixed lv_distance;
    point lv_bestGuardPosition;
    fixed lv_bestGuardPositionDistance;

    // Variable Initialization
    lv_bestGuardPositionDistance = 524287.0;

    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_nextTearGuardPositionUpdateTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroGuardPositionUpdateFrequency);
    if ((libGame_gv_laneCount != 0)) {
        lv_orderBaseEndpoint = libGame_gv_laneData[1].lv_waypoints[1];
        lv_chaosBaseEndpoint = libGame_gv_laneData[1].lv_waypoints[libGame_gv_laneData[1].lv_waypointCount];
        lv_candidateGuardPositions[1] = AIPositionAlongPath(lp_trigPlayer, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, lv_orderBaseEndpoint, 3.0, false);
        lv_candidateGuardPositions[2] = AIPositionAlongPath(lp_trigPlayer, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, lv_chaosBaseEndpoint, 3.0, false);
        lv_candidateGuardPositions[3] = AIPositionAlongPath(lp_trigPlayer, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, lv_orderBaseEndpoint, 6.0, false);
        lv_candidateGuardPositions[4] = AIPositionAlongPath(lp_trigPlayer, libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, lv_chaosBaseEndpoint, 6.0, false);
        auto73FCA898_ae = 4;
        auto73FCA898_ai = 1;
        lv_index = 1;
        for ( ; ( (auto73FCA898_ai >= 0 && lv_index <= auto73FCA898_ae) || (auto73FCA898_ai <= 0 && lv_index >= auto73FCA898_ae) ) ; lv_index += auto73FCA898_ai ) {
            lv_positionTaken = false;
            auto42C2BD08_ae = libCore_gv_bALMaxPlayers;
            lv_playerIndex = 1;
            for ( ; lv_playerIndex <= auto42C2BD08_ae ; lv_playerIndex += 1 ) {
                if (((lv_playerIndex == lp_trigPlayer) || (libGame_gv_players[lv_playerIndex].lv_faction != libGame_gv_players[lp_trigPlayer].lv_faction) || (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == false))) {
                    continue;
                }
                else {
                }
                if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 29)) {
                    lv_otherHeroGuardPosition = libAIAI_gv_aIHeroes[lv_playerIndex].lv_tearGuardPosition;
                }
                else {
                    lv_otherHeroGuardPosition = UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit);
                }
                if ((DistanceBetweenPoints(lv_otherHeroGuardPosition, lv_candidateGuardPositions[lv_index]) < 1.5)) {
                    lv_positionTaken = true;
                    break;
                }
                else {
                }
            }
            lv_distance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_candidateGuardPositions[lv_index]);
            if ((lv_positionTaken == false) && (lv_distance < lv_bestGuardPositionDistance)) {
                lv_bestGuardPosition = lv_candidateGuardPositions[lv_index];
                lv_bestGuardPositionDistance = lv_distance;
            }
            else {
            }
        }
    }
    else {
    }
    if ((lv_bestGuardPosition == null)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_tearGuardPosition = PointWithOffsetPolar(libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition, 2.5, libNtve_gf_RandomAngle());
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_tearGuardPosition = RegionRandomPoint(RegionCircle(lv_bestGuardPosition, 1.0));
    }
}

bool libAIAI_gf_HeroAIEnemyTeamCursed (int lp_trigPlayer) {
    // Implementation
    return libMapM_gv_mMRavenTeamStats[(3 - libGame_gf_TeamNumberOfPlayer(lp_trigPlayer))].lv_cursed;
}

bool libAIAI_gf_HeroAIOurTeamCursed (int lp_trigPlayer) {
    // Implementation
    return libMapM_gv_mMRavenTeamStats[libGame_gf_TeamNumberOfPlayer(lp_trigPlayer)].lv_cursed;
}

void libAIAI_gf_HeroAIGhostShipBeaconPinged (int lp_pingingPlayer) {
    playergroup auto6589D110_g;
    int auto6589D110_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus == 0)) {
        return ;
    }
    else {
    }
    auto6589D110_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_aIPlayers; 
    auto6589D110_p = 1;
    for ( ; auto6589D110_p <= PlayerGroupCount(auto6589D110_g) ; auto6589D110_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto6589D110_g, auto6589D110_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto6589D110_g, auto6589D110_p);
        if ((libAIAI_gf_HeroAIShouldTurnInDoubloons(lv_playerIndex, true) == true)) {
            libAIAI_gf_HeroAIStartTurnInDoubloons(lv_playerIndex);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAITurnInDoubloonsLogic (int lp_faction) {
    playergroup auto122FBA2E_g;
    int auto122FBA2E_p;

    // Variable Declarations
    int lv_playerIndex;
    point lv_ghostShipBeaconPosition;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus == 0)) {
        return ;
    }
    else {
    }
    auto122FBA2E_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto122FBA2E_p = 1;
    for ( ; auto122FBA2E_p <= PlayerGroupCount(auto122FBA2E_g) ; auto122FBA2E_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto122FBA2E_g, auto122FBA2E_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto122FBA2E_g, auto122FBA2E_p);
        if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_nextTurnInDoubloonsConsiderTime <= TimerGetElapsed(libGame_gv_gameTimer))) {
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_nextTurnInDoubloonsConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTurnInDoubloonsConsiderFrequency);
            if ((libAIAI_gf_HeroAIShouldTurnInDoubloons(lv_playerIndex, false) == true)) {
                libAIAI_gf_HeroAIStartTurnInDoubloons(lv_playerIndex);
            }
            else {
            }
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIShouldTurnInDoubloons (int lp_trigPlayer, bool lp_playerPinged) {
    // Variable Declarations
    int lv_pirateShipCost;
    int lv_doubloonsHolding;
    int lv_doubloonsTurnedIn;
    int lv_doubloonsNeededToFillBeacon;
    point lv_ghostShipBeaconPosition;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;
    int lv_immediateTurnInAmount;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    if (((libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus == 0) || (libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 23) == false))) {
        return false;
    }
    else {
    }
    lv_doubloonsHolding = libAIAI_gf_HeroAINumberOfDoubloonsHeroIsHolding(lp_trigPlayer);
    if ((lp_playerPinged == true)) {
        if ((lv_doubloonsHolding == 0)) {
            return false;
        }
        else {
        }
    }
    else {
        if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
            lv_pirateShipCost = libMapM_gf_MMCannonballsPirateShipCost(libGame_gv_teamOrderIndex_C);
            lv_doubloonsTurnedIn = libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamOrderIndex_C];
        }
        else {
            lv_pirateShipCost = libMapM_gf_MMCannonballsPirateShipCost(libGame_gv_teamChaosIndex_C);
            lv_doubloonsTurnedIn = libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamChaosIndex_C];
        }
        lv_doubloonsNeededToFillBeacon = (lv_pirateShipCost - lv_doubloonsTurnedIn);
        if ((libAIAI_gf_HeroAITeamHasHumanPlayers(libGame_gv_players[lp_trigPlayer].lv_faction) == true)) {
            lv_immediateTurnInAmount = libAIAI_gv_aIHeroWantToTurnInDoubloonsAmountHumanTeam;
        }
        else {
            lv_immediateTurnInAmount = libAIAI_gv_aIHeroWantToTurnInDoubloonsAmountAllAITeam;
        }
        if ((lv_doubloonsHolding < lv_doubloonsNeededToFillBeacon) && (lv_doubloonsHolding < lv_immediateTurnInAmount) && (!(((lv_doubloonsHolding > 0) && (libAIAI_gf_HeroAINumberOfDoubloonsTeamIsHolding(libGame_gv_players[lp_trigPlayer].lv_faction) >= lv_doubloonsNeededToFillBeacon))))) {
            return false;
        }
        else {
        }
    }
    lv_ghostShipBeaconPosition = UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(lv_ghostShipBeaconPosition, libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(lv_ghostShipBeaconPosition, libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) >= (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) + 2))) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldGiveUpOnTurningInDoubloons (int lp_trigPlayer) {
    // Variable Declarations
    point lv_beaconPosition;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus == 0)) {
        return true;
    }
    else {
    }
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        return true;
    }
    else {
    }
    lv_beaconPosition = UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(lv_beaconPosition, libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAlly, RegionCircle(lv_beaconPosition, (libAIAI_gv_aIHeroFarFromGhostShipBeaconDistance * 2.0)), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) >= (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) + 2))) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIStartTurnInDoubloons (int lp_trigPlayer) {
    // Variable Declarations
    point lv_ghostShipBeaconPosition;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAILeaveCurrentObjective(lp_trigPlayer);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToTurnInDoubloons = true;
    lv_ghostShipBeaconPosition = UnitGetPosition(libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit);
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) >= libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_ghostShipBeaconPosition) <= libAIAI_gv_aIHeroWalkDirectlyToGhostShipBeaconDistance)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane = 0;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 32);
    }
    else {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_wantsToGoHome = true;
    }
}

int libAIAI_gf_HeroAINumberOfDoubloonsHeroIsHolding (int lp_trigPlayer) {
    // Implementation
    return UnitBehaviorCount(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "CannonballStack");
}

int libAIAI_gf_HeroAINumberOfDoubloonsTeamIsHolding (int lp_faction) {
    int auto6E500AF9_ae;
    int auto6E500AF9_ai;

    // Variable Declarations
    int lv_playerIndex;
    int lv_doubloonsHolding;
    int lv_totalTeamDoubloons;

    // Variable Initialization

    // Implementation
    auto6E500AF9_ae = libCore_gv_bALMaxPlayers;
    auto6E500AF9_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto6E500AF9_ai >= 0 && lv_playerIndex <= auto6E500AF9_ae) || (auto6E500AF9_ai <= 0 && lv_playerIndex >= auto6E500AF9_ae) ) ; lv_playerIndex += auto6E500AF9_ai ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true)) {
            lv_totalTeamDoubloons += libAIAI_gf_HeroAINumberOfDoubloonsHeroIsHolding(lv_playerIndex);
        }
        else {
        }
    }
    return lv_totalTeamDoubloons;
}

void libAIAI_gf_HeroAIPickUpDoubloonsLogic (int lp_faction) {
    playergroup autoC6F37C1A_g;
    int autoC6F37C1A_p;

    // Variable Declarations
    int lv_playerIndex;
    unit lv_doubloon;

    // Variable Initialization

    // Implementation
    autoC6F37C1A_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    autoC6F37C1A_p = 1;
    for ( ; autoC6F37C1A_p <= PlayerGroupCount(autoC6F37C1A_g) ; autoC6F37C1A_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoC6F37C1A_g, autoC6F37C1A_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoC6F37C1A_g, autoC6F37C1A_p);
        if ((UnitGetPropertyFixed(libGame_gv_players[lv_playerIndex].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (libAIAI_gv_aIHeroTeleportPercent[(libAIAI_gv_aIHeroes[lv_playerIndex].lv_difficulty)] + 10.0))) {
            lv_doubloon = libAIAI_gf_HeroAISearchForNearbyDoubloon(lv_playerIndex);
            if ((UnitIsValid(lv_doubloon) == true) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 0) == true)) {
                libAIAI_gf_HeroAIChangeState(lv_playerIndex, 31);
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDoubloon = lv_doubloon;
                UnitIssueOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDoubloon)), c_orderQueueReplace);
            }
            else {
            }
        }
        else {
        }
    }
}

unit libAIAI_gf_HeroAISearchForNearbyDoubloon (int lp_trigPlayer) {
    unitgroup autoC9BA04CC_g;
    int autoC9BA04CC_u;

    // Variable Declarations
    point lv_heroPosition;
    region lv_nearbyRegion;
    unitgroup lv_nearbyDoubloons;
    unit lv_doubloon;
    region lv_enemyRegion;
    unitgroup lv_enemyHeroes;
    fixed lv_distance;
    fixed lv_pathDist;
    unit lv_bestDoubloon;
    fixed lv_bestDoubloonDistance;

    // Variable Initialization
    lv_nearbyDoubloons = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_bestDoubloonDistance = 524287.0;

    // Implementation
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_nearbyRegion = RegionCircle(lv_heroPosition, libAIAI_gv_aIHeroDoubloonSearchRadius);
    lv_nearbyDoubloons = UnitGroup("ItemCannonball", c_playerAny, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    autoC9BA04CC_g = lv_nearbyDoubloons;
    autoC9BA04CC_u = 1;
    for ( ; autoC9BA04CC_u <= UnitGroupCount(autoC9BA04CC_g, c_unitCountAll) ; autoC9BA04CC_u += BoolToInt(lv_doubloon == UnitGroupUnit(autoC9BA04CC_g, autoC9BA04CC_u)) ) {
        lv_doubloon = UnitGroupUnit(autoC9BA04CC_g, autoC9BA04CC_u);
        if ((libAIAI_gf_HeroAIIsAllyPickingUpDoubloon(lp_trigPlayer, lv_doubloon) == true)) {
            continue;
        }
        else {
        }
        lv_enemyRegion = RegionEmpty();
        RegionAddRegion(lv_enemyRegion, RegionCircle(UnitGetPosition(lv_doubloon), libAIAI_gv_aIHeroDoubloonCloseToEnemyDistance));
        RegionAddRegion(lv_enemyRegion, RegionCircle(lv_heroPosition, libAIAI_gv_aIHeroDoubloonCloseToEnemyDistance));
        lv_enemyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_enemyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0)) {
            continue;
        }
        else {
        }
        lv_distance = DistanceBetweenPoints(lv_heroPosition, UnitGetPosition(lv_doubloon));
        if ((lv_distance < lv_bestDoubloonDistance)) {
            lv_pathDist = AIPathingCostUnit(libGame_gv_players[lp_trigPlayer].lv_heroUnit, UnitGetPosition(lv_doubloon), c_includeAllBuildings);
            if ((lv_pathDist >= 0.0) && (lv_pathDist < (lv_distance * 3.0))) {
                lv_bestDoubloon = lv_doubloon;
                lv_bestDoubloonDistance = lv_distance;
            }
            else {
            }
        }
        else {
        }
    }
    return lv_bestDoubloon;
}

bool libAIAI_gf_HeroAIIsAllyPickingUpDoubloon (int lp_trigPlayer, unit lp_doubloon) {
    int autoD13C3385_ae;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    autoD13C3385_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoD13C3385_ae ; lv_playerIndex += 1 ) {
        if ((lp_trigPlayer != lv_playerIndex) && (libGame_gv_players[lp_trigPlayer].lv_faction == libGame_gv_players[lv_playerIndex].lv_faction)) {
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true)) {
                if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 31) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDoubloon == lp_doubloon)) {
                    return true;
                }
                else {
                }
            }
            else {
                if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lp_doubloon)) < libAIAI_gv_aIHeroNearDoubloonDistance)) {
                    return true;
                }
                else {
                }
            }
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIIsHumanAllyPickingUpDoubloon (int lp_trigPlayer, unit lp_doubloon) {
    int auto65B16319_ae;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    auto65B16319_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto65B16319_ae ; lv_playerIndex += 1 ) {
        if ((lp_trigPlayer != lv_playerIndex) && (libGame_gv_players[lp_trigPlayer].lv_faction == libGame_gv_players[lv_playerIndex].lv_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true)) {
            if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lp_doubloon)) < libAIAI_gv_aIHeroNearDoubloonDistance)) {
                return true;
            }
            else {
            }
        }
        else {
        }
    }
    return false;
}

void libAIAI_gf_HeroAIAttackTreasureChestLogic (int lp_faction) {
    unitgroup auto52CCF201_g;
    int auto52CCF201_u;
    playergroup auto6BC19790_g;
    int auto6BC19790_p;

    // Variable Declarations
    int lv_playerIndex;
    int lv_teamIndex;
    unit lv_treasureChest;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextDoubloonChestConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
    }
    auto52CCF201_g = libAIAI_gv_heroAITreasureChests;
    auto52CCF201_u = 1;
    for ( ; auto52CCF201_u <= UnitGroupCount(auto52CCF201_g, c_unitCountAll) ; auto52CCF201_u += BoolToInt(lv_treasureChest == UnitGroupUnit(auto52CCF201_g, auto52CCF201_u)) ) {
        lv_treasureChest = UnitGroupUnit(auto52CCF201_g, auto52CCF201_u);
        if ((UnitIsValid(lv_treasureChest) == true)) {
            auto6BC19790_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
            auto6BC19790_p = 1;
            for ( ; auto6BC19790_p <= PlayerGroupCount(auto6BC19790_g) ; auto6BC19790_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto6BC19790_g, auto6BC19790_p)) ) {
                lv_playerIndex = PlayerGroupPlayer(auto6BC19790_g, auto6BC19790_p);
                if ((libAIAI_gf_HeroAIShouldAttackTreasureChest(lv_playerIndex, lv_treasureChest) == true)) {
                    libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                    libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                    libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetTreasureChest = lv_treasureChest;
                    libAIAI_gf_HeroAIChangeState(lv_playerIndex, 34);
                }
                else {
                }
            }
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIShouldAttackTreasureChest (int lp_trigPlayer, unit lp_treasureChest) {
    // Variable Declarations
    fixed lv_allyEval;
    fixed lv_enemyEval;
    int lv_priority;

    // Variable Initialization

    // Implementation
    if (((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_treasureChest)) > libAIAI_gv_aIHeroTreasureChestRecruitDistance) || (libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 26) == false))) {
        return false;
    }
    else {
    }
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, UnitGetPosition(lp_treasureChest), libAIAI_gv_aIHeroTreasureChestRecruitDistance, true, false, false);
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(lp_treasureChest), libAIAI_gv_aIHeroTreasureChestRecruitDistance, true, false, false);
    if ((lv_enemyEval > lv_allyEval)) {
        return false;
    }
    else {
    }
    return true;
}

bool libAIAI_gf_HeroAIShouldGiveUpOnTreasureChest (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_allyEval;
    fixed lv_enemyEval;

    // Variable Initialization

    // Implementation
    if (((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest) == false) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0)))) {
        return true;
    }
    else {
    }
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), libAIAI_gv_aIHeroTreasureChestRecruitDistance, true, false, false);
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetTreasureChest), libAIAI_gv_aIHeroFarFromTreasureChestDistance, true, false, false);
    if ((lv_enemyEval > (lv_allyEval + 100.0))) {
        return true;
    }
    else {
    }
    return false;
}

void libAIAI_gf_HeroAIObeliskPinged (int lp_pingingPlayer, unit lp_obeliskUnit) {
    playergroup auto39AED46C_g;
    int auto39AED46C_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if (((UnitGroupHasUnit(libAIAI_gv_heroAIDragonShireObelisks, lp_obeliskUnit) == false) || (libNtve_gf_PlayerIsEnemy(lp_pingingPlayer, UnitGetOwner(lp_obeliskUnit), 0) == true))) {
        return ;
    }
    else {
    }
    auto39AED46C_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_aIPlayers; 
    auto39AED46C_p = 1;
    for ( ; auto39AED46C_p <= PlayerGroupCount(auto39AED46C_g) ; auto39AED46C_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto39AED46C_g, auto39AED46C_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto39AED46C_g, auto39AED46C_p);
        if ((libAIAI_gf_HeroAIShouldCaptureObelisk(lv_playerIndex, lp_obeliskUnit, true) == true)) {
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetObelisk = lp_obeliskUnit;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 48);
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAICaptureObeliskLogic (int lp_faction) {
    unitgroup auto20C291F9_g;
    int auto20C291F9_u;
    playergroup auto7E472386_g;
    int auto7E472386_p;

    // Variable Declarations
    int lv_allyComputerPlayer;
    int lv_enemyComputerPlayer;
    int lv_teamIndex;
    int lv_playerIndex;
    unit lv_obelisk;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
        lv_enemyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
        lv_teamIndex = (0);
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
        lv_enemyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextObeliskConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextObeliskConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroObeliskConsiderFrequency);
    }
    auto20C291F9_g = libAIAI_gv_heroAIDragonShireObelisks;
    auto20C291F9_u = 1;
    for ( ; auto20C291F9_u <= UnitGroupCount(auto20C291F9_g, c_unitCountAll) ; auto20C291F9_u += BoolToInt(lv_obelisk == UnitGroupUnit(auto20C291F9_g, auto20C291F9_u)) ) {
        lv_obelisk = UnitGroupUnit(auto20C291F9_g, auto20C291F9_u);
        auto7E472386_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
        auto7E472386_p = 1;
        for ( ; auto7E472386_p <= PlayerGroupCount(auto7E472386_g) ; auto7E472386_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto7E472386_g, auto7E472386_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(auto7E472386_g, auto7E472386_p);
            if ((libAIAI_gf_HeroAIShouldCaptureObelisk(lv_playerIndex, lv_obelisk, false) == true)) {
                libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetObelisk = lv_obelisk;
                libAIAI_gf_HeroAIChangeState(lv_playerIndex, 48);
            }
            else {
            }
        }
    }
}

bool libAIAI_gf_HeroAIShouldCaptureObelisk (int lp_trigPlayer, unit lp_obelisk, bool lp_playerPinged) {
    // Variable Declarations
    int lv_allyFaction;
    int lv_enemyFaction;
    point lv_obeliskPosition;
    fixed lv_enemyEval;
    fixed lv_allyEval;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    lv_obeliskPosition = UnitGetPosition(lp_obelisk);
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_allyFaction = 0;
        lv_enemyFaction = 1;
    }
    else {
        lv_allyFaction = 1;
        lv_enemyFaction = 0;
    }
    if (((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_obeliskPosition) > libAIAI_gv_aIHeroObeliskRecruitDistance) || (libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 13) == false) || (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]))) {
        return false;
    }
    else {
    }
    if ((lp_playerPinged == false) && (libAIAI_gf_HeroAINumberOfAIAlliesCapturingObelisk(lp_trigPlayer, lp_obelisk) >= libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)])) {
        return false;
    }
    else {
    }
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroObeliskRecruitDistance, true, false, false);
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroObeliskRecruitDistance, true, false, false);
    if ((lv_enemyEval > (lv_allyEval + 250.0))) {
        return false;
    }
    else {
    }
    if ((lp_playerPinged == true)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAITeamOwnsAllObelisks(lv_enemyFaction) == true)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAITeamIsCapturingAllObelisks(lv_enemyFaction) == true)) {
        return true;
    }
    else {
    }
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, RegionCircle(lv_obeliskPosition, libAIAI_gv_aIHeroCloseToObeliskDistance), UnitFilter(0, 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    if ((libAIAI_gf_HeroAITeamOwnsAllObelisks(lv_allyFaction) == true) && (UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHumanAllyInArea(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroCloseToObeliskDistance) == true) && ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(lp_obelisk), 0) == false) || (UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0))) {
        return true;
    }
    else {
    }
    if ((libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(lp_obelisk), 0) == false) && (libMapM_gf_MMGardensDragonObeliskFullyCaptured(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk) == false) && (lv_enemyEval == 0.0)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIShouldGiveUpOnObelisk (int lp_trigPlayer) {
    // Variable Declarations
    point lv_obeliskPosition;
    int lv_obeliskOwner;
    fixed lv_enemyEval;
    fixed lv_allyEval;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();

    // Implementation
    lv_obeliskPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    lv_obeliskOwner = UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk);
    if ((UnitGroupHasUnit(libAIAI_gv_heroAIDragonShireObelisks, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetObelisk) == false)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lp_trigPlayer, 1.0) == true) && (UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) <= (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0))) {
        return true;
    }
    else {
    }
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroObeliskRecruitDistance, true, false, false);
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, lv_obeliskPosition, libAIAI_gv_aIHeroObeliskRecruitDistance, true, false, false);
    if ((lv_enemyEval > (lv_allyEval + 750.0))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAITeamOwnsAllObelisks (int lp_faction) {
    unitgroup auto60FFB834_g;
    int auto60FFB834_u;

    // Variable Declarations
    int lv_allyComputerPlayer;
    unit lv_obelisk;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    auto60FFB834_g = libAIAI_gv_heroAIDragonShireObelisks;
    auto60FFB834_u = 1;
    for ( ; auto60FFB834_u <= UnitGroupCount(auto60FFB834_g, c_unitCountAll) ; auto60FFB834_u += BoolToInt(lv_obelisk == UnitGroupUnit(auto60FFB834_g, auto60FFB834_u)) ) {
        lv_obelisk = UnitGroupUnit(auto60FFB834_g, auto60FFB834_u);
        if ((libNtve_gf_PlayerIsEnemy(lv_allyComputerPlayer, UnitGetOwner(lv_obelisk), 0) == false)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAITeamIsCapturingAllObelisks (int lp_faction) {
    unitgroup autoDB123EB4_g;
    int autoDB123EB4_u;

    // Variable Declarations
    int lv_allyComputerPlayer;
    unit lv_obelisk;
    unitgroup lv_units;
    unitgroup lv_heroes;

    // Variable Initialization
    lv_units = UnitGroupEmpty();
    lv_heroes = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    autoDB123EB4_g = libAIAI_gv_heroAIDragonShireObelisks;
    autoDB123EB4_u = 1;
    for ( ; autoDB123EB4_u <= UnitGroupCount(autoDB123EB4_g, c_unitCountAll) ; autoDB123EB4_u += BoolToInt(lv_obelisk == UnitGroupUnit(autoDB123EB4_g, autoDB123EB4_u)) ) {
        lv_obelisk = UnitGroupUnit(autoDB123EB4_g, autoDB123EB4_u);
        lv_units = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceAlly, RegionCircle(UnitGetPosition(lv_obelisk), libAIAI_gv_aIHeroCloseToObeliskDistance), UnitFilter(0, 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        lv_heroes = UnitGroupFilter(null, c_playerAny, lv_units, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        if ((UnitGroupCount(lv_heroes, c_unitCountAlive) == 0) && (libNtve_gf_PlayerIsEnemy(lv_allyComputerPlayer, UnitGetOwner(lv_obelisk), 0) == false)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAIIsNearActiveObelisk (int lp_trigPlayer) {
    unitgroup auto44AF5D65_g;
    int auto44AF5D65_u;

    // Variable Declarations
    unit lv_obelisk;

    // Variable Initialization

    // Implementation
    auto44AF5D65_g = libAIAI_gv_heroAIDragonShireObelisks;
    auto44AF5D65_u = 1;
    for ( ; auto44AF5D65_u <= UnitGroupCount(auto44AF5D65_g, c_unitCountAll) ; auto44AF5D65_u += BoolToInt(lv_obelisk == UnitGroupUnit(auto44AF5D65_g, auto44AF5D65_u)) ) {
        lv_obelisk = UnitGroupUnit(auto44AF5D65_g, auto44AF5D65_u);
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lv_obelisk)) < libAIAI_gv_aIHeroObeliskRecruitDistance)) {
            return true;
        }
        else {
        }
    }
    return false;
}

point libAIAI_gf_HeroAIChooseDragonShrineGuardPosition (unit lp_obelisk) {
    // Implementation
    return PointWithOffsetPolar(UnitGetPosition(lp_obelisk), libAIAI_gv_aIHeroObeliskGuardDistance, libNtve_gf_RandomAngle());
}

int libAIAI_gf_HeroAINumberOfAIAlliesCapturingObelisk (int lp_trigPlayer, unit lp_obelisk) {
    int auto8538BDDE_ae;
    int auto8538BDDE_ai;

    // Variable Declarations
    int lv_playerIndex;
    int lv_count;

    // Variable Initialization

    // Implementation
    auto8538BDDE_ae = libCore_gv_bALMaxPlayers;
    auto8538BDDE_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto8538BDDE_ai >= 0 && lv_playerIndex <= auto8538BDDE_ae) || (auto8538BDDE_ai <= 0 && lv_playerIndex >= auto8538BDDE_ae) ) ; lv_playerIndex += auto8538BDDE_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 7) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetObelisk == lp_obelisk)) {
            lv_count += 1;
        }
        else {
        }
    }
    return lv_count;
}

void libAIAI_gf_HeroAICaptureDragonLogic (int lp_faction) {
    unitgroup autoE7A454C1_g;
    int autoE7A454C1_u;
    unitgroup autoFEDC454E_g;
    int autoFEDC454E_u;
    playergroup autoA04BFAA1_g;
    int autoA04BFAA1_p;
    playergroup auto1C6A939A_g;
    int auto1C6A939A_p;

    // Variable Declarations
    int lv_teamComputerPlayer;
    int lv_teamIndex;
    unit lv_obelisk;
    point lv_obeliskPosition;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_allies;
    unitgroup lv_allyHeroes;
    unitgroup lv_dragonStatueGroup;
    unit lv_dragonStatue;
    int lv_playerIndex;
    int lv_closestHero;
    fixed lv_closestHeroDistance;
    fixed lv_distance;
    playergroup lv_heroesToRecruit;
    int lv_numberOfAlliesCapturingDragon;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_allies = UnitGroupEmpty();
    lv_allyHeroes = UnitGroupEmpty();
    lv_dragonStatueGroup = UnitGroupEmpty();
    lv_closestHeroDistance = 524287.0;
    lv_heroesToRecruit = PlayerGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
        lv_teamIndex = (0);
    }
    else {
        lv_teamComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextUseDragonVehicleConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextUseDragonVehicleConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroEnterDragonVehicleConsiderFrequency);
    }
    autoE7A454C1_g = libAIAI_gv_heroAIDragonShireObelisks;
    autoE7A454C1_u = 1;
    for ( ; autoE7A454C1_u <= UnitGroupCount(autoE7A454C1_g, c_unitCountAll) ; autoE7A454C1_u += BoolToInt(lv_obelisk == UnitGroupUnit(autoE7A454C1_g, autoE7A454C1_u)) ) {
        lv_obelisk = UnitGroupUnit(autoE7A454C1_g, autoE7A454C1_u);
        lv_obeliskPosition = UnitGetPosition(lv_obelisk);
        lv_enemies = UnitGroupAlliance(lv_teamComputerPlayer, c_unitAllianceEnemy, RegionCircle(lv_obeliskPosition, libAIAI_gv_aIHeroFarFromObeliskDistance), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        lv_allies = UnitGroupAlliance(lv_teamComputerPlayer, c_unitAllianceAlly, RegionCircle(lv_obeliskPosition, (libAIAI_gv_aIHeroFarFromObeliskDistance * 2.0)), UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_allyHeroes = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
        if ((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0) && (UnitGroupCount(lv_allyHeroes, c_unitCountAlive) == 0)) {
            return ;
        }
        else {
        }
    }
    lv_dragonStatueGroup = UnitGroup("VehicleDragon", lv_teamComputerPlayer, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    autoFEDC454E_g = lv_dragonStatueGroup;
    autoFEDC454E_u = 1;
    for ( ; autoFEDC454E_u <= UnitGroupCount(autoFEDC454E_g, c_unitCountAll) ; autoFEDC454E_u += BoolToInt(lv_dragonStatue == UnitGroupUnit(autoFEDC454E_g, autoFEDC454E_u)) ) {
        lv_dragonStatue = UnitGroupUnit(autoFEDC454E_g, autoFEDC454E_u);
        autoA04BFAA1_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
        autoA04BFAA1_p = 1;
        for ( ; autoA04BFAA1_p <= PlayerGroupCount(autoA04BFAA1_g) ; autoA04BFAA1_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoA04BFAA1_g, autoA04BFAA1_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(autoA04BFAA1_g, autoA04BFAA1_p);
            if ((libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 12) == true)) {
                lv_distance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lv_dragonStatue));
                if ((lv_distance < lv_closestHeroDistance)) {
                    lv_closestHeroDistance = lv_distance;
                    lv_closestHero = lv_playerIndex;
                }
                else {
                }
                if ((lv_distance < libAIAI_gv_aIHeroEnterDragonRecruitDistance)) {
                    PlayerGroupAdd(lv_heroesToRecruit, lv_playerIndex);
                }
                else {
                }
            }
            else {
            }
        }
        if ((libAIAI_gf_HeroAINumberOfAlliesCapturingDragon(lp_faction, lv_dragonStatue) == 0)) {
            PlayerGroupAdd(lv_heroesToRecruit, lv_closestHero);
        }
        else {
        }
        auto1C6A939A_g = lv_heroesToRecruit; 
        auto1C6A939A_p = 1;
        for ( ; auto1C6A939A_p <= PlayerGroupCount(auto1C6A939A_g) ; auto1C6A939A_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto1C6A939A_g, auto1C6A939A_p)) ) {
            lv_playerIndex = PlayerGroupPlayer(auto1C6A939A_g, auto1C6A939A_p);
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDragonStatue = lv_dragonStatue;
            libAIAI_gf_HeroAIChangeState(lv_playerIndex, 51);
        }
        break;
    }
}

bool libAIAI_gf_HeroAIShouldGiveUpOnDragon (int lp_trigPlayer) {
    // Variable Declarations
    int lv_allyTeamComputerPlayer;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_allyTeamComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_allyTeamComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    if (((UnitIsValid(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == false) || (UnitIsAlive(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) == false) || (UnitGetOwner(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetDragonStatue) != lv_allyTeamComputerPlayer))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIIsAllyEnteringDragon (int lp_faction, unit lp_dragonStatue) {
    int autoED1D8443_ae;

    // Variable Declarations
    int lv_playerIndex;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    autoED1D8443_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoED1D8443_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == lp_faction)) {
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true)) {
                lv_heroOrder = UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0);
                if ((lv_heroOrder != null) && (OrderGetTargetType(lv_heroOrder) == c_orderTargetUnit) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("UseVehicle", 0)) && (OrderGetTargetUnit(lv_heroOrder) == lp_dragonStatue) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lp_dragonStatue)) < libAIAI_gv_aIHeroFarFromDragonStatueDistance)) {
                    return true;
                }
                else {
                }
            }
            else {
                if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 52) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDragonStatue == lp_dragonStatue)) {
                    return true;
                }
                else {
                }
            }
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIIsHumanAllyEnteringDragon (int lp_faction, unit lp_dragonStatue) {
    int auto58800901_ae;

    // Variable Declarations
    int lv_playerIndex;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    auto58800901_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto58800901_ae ; lv_playerIndex += 1 ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 1) == true)) {
            lv_heroOrder = UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0);
            if ((lv_heroOrder != null) && (OrderGetTargetType(lv_heroOrder) == c_orderTargetUnit) && (OrderGetAbilityCommand(lv_heroOrder) == AbilityCommand("UseVehicle", 0)) && (OrderGetTargetUnit(lv_heroOrder) == lp_dragonStatue) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lp_dragonStatue)) < libAIAI_gv_aIHeroFarFromDragonStatueDistance)) {
                return true;
            }
            else {
            }
        }
        else {
        }
    }
    return false;
}

int libAIAI_gf_HeroAINumberOfAlliesCapturingDragon (int lp_faction, unit lp_dragonStatue) {
    int auto4E998EFE_ae;

    // Variable Declarations
    int lv_playerIndex;
    int lv_playerCount;

    // Variable Initialization

    // Implementation
    auto4E998EFE_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto4E998EFE_ae ; lv_playerIndex += 1 ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction)) {
            if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true)) {
                if ((libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 2) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetDragonStatue == lp_dragonStatue)) {
                    lv_playerCount += 1;
                }
                else {
                }
            }
            else {
                if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lp_dragonStatue)) < libAIAI_gv_aIHeroFarFromDragonStatueDistance)) {
                    lv_playerCount += 1;
                }
                else {
                }
            }
        }
        else {
        }
    }
    return lv_playerCount;
}

void libAIAI_gf_HeroAIEnterUnderworldLogic (int lp_faction) {
    int autoC1129549_ae;
    playergroup auto3A423D45_g;
    int auto3A423D45_p;
    unitgroup auto2490C338_g;
    int auto2490C338_u;

    // Variable Declarations
    int lv_allyHeroesInUnderworld;
    int lv_teamIndex;
    int lv_enemyHeroesInUnderworld;
    int lv_playerIndex;
    int lv_desiredNumberOfHeroesInUnderworld;
    int lv_additionalHeroesNeeded;
    unit lv_entrance;
    fixed lv_entranceDistance;
    unit lv_bestEntrance;
    fixed lv_bestEntranceDistance;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextUnderworldConsiderTime > TimerGetElapsed(libGame_gv_gameTimer))) {
        return ;
    }
    else {
        libAIAI_gv_heroAITeamData[lv_teamIndex].lv_nextUnderworldConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroUnderworldConsiderFrequency);
    }
    if (((libAIAI_gv_heroAIUnderworldStatus.lv_opened == false) || (libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining == 0))) {
        return ;
    }
    else {
    }
    autoC1129549_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= autoC1129549_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lv_playerIndex].lv_heroUnit) == true) || ((libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 57)))) {
            if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction)) {
                lv_allyHeroesInUnderworld += 1;
            }
            else {
                lv_enemyHeroesInUnderworld += 1;
            }
        }
        else {
        }
    }
    if ((libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining > (libAIAI_gv_heroAIUnderworldStatus.lv_totalSkulls / 2))) {
        lv_desiredNumberOfHeroesInUnderworld = 5;
    }
    else {
        lv_desiredNumberOfHeroesInUnderworld = 3;
    }
    lv_desiredNumberOfHeroesInUnderworld = MaxI(lv_desiredNumberOfHeroesInUnderworld, lv_enemyHeroesInUnderworld);
    lv_additionalHeroesNeeded = (lv_desiredNumberOfHeroesInUnderworld - lv_allyHeroesInUnderworld);
    if ((lv_additionalHeroesNeeded <= 0)) {
        return ;
    }
    else {
    }
    auto3A423D45_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto3A423D45_p = 1;
    for ( ; auto3A423D45_p <= PlayerGroupCount(auto3A423D45_g) ; auto3A423D45_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto3A423D45_g, auto3A423D45_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto3A423D45_g, auto3A423D45_p);
        if ((lv_additionalHeroesNeeded == 0)) {
            break;
        }
        else {
        }
        if ((libAIAI_gf_HeroAIShouldEnterUnderworld(lv_playerIndex) == true)) {
            lv_bestEntrance = null;
            lv_bestEntranceDistance = 524287.0;
            auto2490C338_g = libAIAI_gv_heroAIUnderworldStatus.lv_entrances;
            auto2490C338_u = 1;
            for ( ; auto2490C338_u <= UnitGroupCount(auto2490C338_g, c_unitCountAll) ; auto2490C338_u += BoolToInt(lv_entrance == UnitGroupUnit(auto2490C338_g, auto2490C338_u)) ) {
                lv_entrance = UnitGroupUnit(auto2490C338_g, auto2490C338_u);
                lv_entranceDistance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), UnitGetPosition(lv_entrance));
                if ((lv_entranceDistance < lv_bestEntranceDistance)) {
                    lv_bestEntrance = lv_entrance;
                    lv_bestEntranceDistance = lv_entranceDistance;
                }
                else {
                }
            }
            if ((UnitIsValid(lv_bestEntrance) == true)) {
                libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_currentLane = 0;
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetUnderworldEntrance = lv_bestEntrance;
                libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToCollectSkulls = true;
                libAIAI_gf_HeroAIChangeState(lv_playerIndex, 57);
                lv_additionalHeroesNeeded -= 1;
            }
            else {
            }
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIShouldEnterUnderworld (int lp_trigPlayer) {
    // Implementation
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)]) && (libAIAI_gf_HeroAIIsHigherPriority(lp_trigPlayer, 11) == true)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIShouldRetreatUnderworld (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_allyEval;
    fixed lv_enemyEval;

    // Variable Initialization

    // Implementation
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroSightRange, true, false, false);
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), libAIAI_gv_aIHeroSightRange, true, false, false);
    if (((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) < (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0)) || (lv_enemyEval > (lv_allyEval + 250.0)))) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIIsSafeUnderworld (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_allyEval;
    fixed lv_enemyEval;

    // Variable Initialization

    // Implementation
    lv_allyEval = libAIAI_gf_HeroAIAllyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), (libAIAI_gv_aIHeroSightRange + 6.0), true, false, false);
    lv_enemyEval = libAIAI_gf_HeroAIEnemyEvalInArea(lp_trigPlayer, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), (libAIAI_gv_aIHeroSightRange + 5.0), true, false, false);
    if ((UnitGetPropertyFixed(libGame_gv_players[lp_trigPlayer].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent) > (libAIAI_gv_aIHeroMinOffensiveHealth[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)] - 10.0)) && (lv_enemyEval < lv_allyEval)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIIsUnitInUnderworld (unit lp_unit) {
    // Implementation
    if ((libAIAI_gv_heroAIUnderworldStatus.lv_opened == false)) {
        return false;
    }
    else {
    }
    return libNtve_gf_UnitInRegion(lp_unit, libAIAI_gv_heroAIUnderworldStatus.lv_underworldRegion);
}

int libAIAI_gf_HeroAINumberOfAIAlliesCollectingSkulls (int lp_trigPlayer) {
    int autoA37D2B4C_ae;
    int autoA37D2B4C_ai;

    // Variable Declarations
    int lv_playerIndex;
    int lv_count;

    // Variable Initialization

    // Implementation
    autoA37D2B4C_ae = libCore_gv_bALMaxPlayers;
    autoA37D2B4C_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoA37D2B4C_ai >= 0 && lv_playerIndex <= autoA37D2B4C_ae) || (autoA37D2B4C_ai <= 0 && lv_playerIndex >= autoA37D2B4C_ae) ) ; lv_playerIndex += autoA37D2B4C_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 2) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (libAIAI_gf_HeroAIGetCurrentObjective(lv_playerIndex) == 10)) {
            lv_count += 1;
        }
        else {
        }
    }
    return lv_count;
}

void libAIAI_gf_HeroAIStartUnderworldKillMinions (int lp_trigPlayer) {
    // Implementation
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetMinion = libAIAI_gf_HeroAIUnderworldChooseTarget(lp_trigPlayer);
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 58);
}

void libAIAI_gf_HeroAIStartExitUnderworld (int lp_trigPlayer) {
    unitgroup autoF2D8F0C7_g;
    int autoF2D8F0C7_u;

    // Variable Declarations
    unit lv_exit;
    fixed lv_exitDistance;
    unit lv_bestExit;
    fixed lv_bestExitDistance;

    // Variable Initialization
    lv_bestExitDistance = 524287.0;

    // Implementation
    autoF2D8F0C7_g = libAIAI_gv_heroAIUnderworldStatus.lv_exits;
    autoF2D8F0C7_u = 1;
    for ( ; autoF2D8F0C7_u <= UnitGroupCount(autoF2D8F0C7_g, c_unitCountAll) ; autoF2D8F0C7_u += BoolToInt(lv_exit == UnitGroupUnit(autoF2D8F0C7_g, autoF2D8F0C7_u)) ) {
        lv_exit = UnitGroupUnit(autoF2D8F0C7_g, autoF2D8F0C7_u);
        lv_exitDistance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lv_exit));
        if ((lv_exitDistance < lv_bestExitDistance)) {
            lv_bestExit = lv_exit;
            lv_bestExitDistance = lv_exitDistance;
        }
        else {
        }
    }
    if ((UnitIsValid(lv_bestExit) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit = lv_bestExit;
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lv_bestExit)) > libAIAI_gv_aIHeroUnderworldCloseToExitDistance)) {
            libAIAI_gf_HeroAIUpdateUnderworldExitTargetPosition(lp_trigPlayer);
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 61);
        }
        else {
            libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 63);
        }
    }
    else {
    }
}

void libAIAI_gf_HeroAIUpdateUnderworldExitTargetPosition (int lp_trigPlayer) {
    // Variable Declarations
    bool lv_useDangerMap;
    point lv_start;
    point lv_pathablePoint;
    point lv_destination;
    point lv_targetPosition;

    // Variable Initialization

    // Implementation
    lv_start = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_destination = libAIAI_gf_HeroAIFindNearbyPathablePoint(lp_trigPlayer, UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit), 2.0, false);
    if ((lv_destination == null)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit);
        return ;
    }
    else {
    }
    lv_useDangerMap = libAIAI_gv_aIHeroPathAroundDanger[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty];
    lv_targetPosition = AIPositionAlongPath(lp_trigPlayer, lv_start, lv_destination, libAIAI_gv_aIHeroJungleStepDistance, lv_useDangerMap);
    if ((lv_targetPosition == null)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition = UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetUnderworldExit);
        return ;
    }
    else {
    }
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldExitTargetPosition = lv_targetPosition;
}

void libAIAI_gf_HeroAIUnderworldBossPinged (int lp_pingingPlayer, unit lp_targetUnit) {
    playergroup auto1849237D_g;
    int auto1849237D_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if (((UnitIsValid(lp_targetUnit) == false) || (libAIAI_gf_HeroAIIsUnitInUnderworld(lp_targetUnit) == false))) {
        return ;
    }
    else {
    }
    auto1849237D_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_pingingPlayer)].lv_aIPlayers; 
    auto1849237D_p = 1;
    for ( ; auto1849237D_p <= PlayerGroupCount(auto1849237D_g) ; auto1849237D_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto1849237D_g, auto1849237D_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto1849237D_g, auto1849237D_p);
        if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 58)) {
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_underworldTargetMinion = lp_targetUnit;
        }
        else {
        }
    }
}

unit libAIAI_gf_HeroAIUnderworldChooseTarget (int lp_trigPlayer) {
    unitgroup auto024DF90E_g;
    int auto024DF90E_u;
    unitgroup autoE11B8BBA_g;
    int autoE11B8BBA_u;
    unitgroup auto0542AC5C_g;
    int auto0542AC5C_u;

    // Variable Declarations
    unitgroup lv_enemies;
    unitgroup lv_enemyMinions;
    unitgroup lv_enemyBosses;
    unit lv_enemy;
    fixed lv_targetEval;
    unit lv_bestTarget;
    fixed lv_bestTargetEval;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_enemyBosses = UnitGroupEmpty();
    lv_bestTargetEval = 524287.0;

    // Implementation
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, libAIAI_gv_heroAIUnderworldStatus.lv_underworldRegion, UnitFilter(0, 0, (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterLight), 0, 0, 0), 0);
    auto024DF90E_g = lv_enemyMinions;
    auto024DF90E_u = 1;
    for ( ; auto024DF90E_u <= UnitGroupCount(auto024DF90E_g, c_unitCountAll) ; auto024DF90E_u += BoolToInt(lv_enemy == UnitGroupUnit(auto024DF90E_g, auto024DF90E_u)) ) {
        lv_enemy = UnitGroupUnit(auto024DF90E_g, auto024DF90E_u);
        if ((UnitGetType(lv_enemy) == "UnderworldBoss")) {
            UnitGroupRemove(lv_enemyMinions, lv_enemy);
            UnitGroupAdd(lv_enemyBosses, lv_enemy);
        }
        else {
        }
    }
    autoE11B8BBA_g = lv_enemyMinions;
    autoE11B8BBA_u = 1;
    for ( ; autoE11B8BBA_u <= UnitGroupCount(autoE11B8BBA_g, c_unitCountAll) ; autoE11B8BBA_u += BoolToInt(lv_enemy == UnitGroupUnit(autoE11B8BBA_g, autoE11B8BBA_u)) ) {
        lv_enemy = UnitGroupUnit(autoE11B8BBA_g, autoE11B8BBA_u);
        lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
        if ((lv_targetEval < lv_bestTargetEval)) {
            lv_bestTarget = lv_enemy;
            lv_bestTargetEval = lv_targetEval;
        }
        else {
        }
    }
    if ((UnitIsValid(lv_bestTarget) == false)) {
        auto0542AC5C_g = lv_enemyBosses;
        auto0542AC5C_u = 1;
        for ( ; auto0542AC5C_u <= UnitGroupCount(auto0542AC5C_g, c_unitCountAll) ; auto0542AC5C_u += BoolToInt(lv_enemy == UnitGroupUnit(auto0542AC5C_g, auto0542AC5C_u)) ) {
            lv_enemy = UnitGroupUnit(auto0542AC5C_g, auto0542AC5C_u);
            lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_enemy, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
            if ((lv_targetEval < lv_bestTargetEval)) {
                lv_bestTarget = lv_enemy;
                lv_bestTargetEval = lv_targetEval;
            }
            else {
            }
        }
    }
    else {
    }
    return lv_bestTarget;
}

bool libAIAI_gf_HeroAIUnderworldFocusNearbyHero (int lp_trigPlayer) {
    // Variable Declarations
    unit lv_enemyHero;

    // Variable Initialization

    // Implementation
    lv_enemyHero = libAIAI_gf_HeroAIUnderworldFocusHeroChooseTarget(lp_trigPlayer);
    if ((UnitIsValid(lv_enemyHero) == true)) {
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_underworldTargetHero = lv_enemyHero;
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 59);
        return true;
    }
    else {
    }
    return false;
}

unit libAIAI_gf_HeroAIUnderworldFocusHeroChooseTarget (int lp_trigPlayer) {
    unitgroup autoE5E5B1D9_g;
    int autoE5E5B1D9_u;

    // Variable Declarations
    unit lv_hero;
    fixed lv_targetEval;
    fixed lv_bestTargetEval;
    unit lv_bestTarget;

    // Variable Initialization
    lv_bestTargetEval = 524287.0;

    // Implementation
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    autoE5E5B1D9_g = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes;
    autoE5E5B1D9_u = 1;
    for ( ; autoE5E5B1D9_u <= UnitGroupCount(autoE5E5B1D9_g, c_unitCountAll) ; autoE5E5B1D9_u += BoolToInt(lv_hero == UnitGroupUnit(autoE5E5B1D9_g, autoE5E5B1D9_u)) ) {
        lv_hero = UnitGroupUnit(autoE5E5B1D9_g, autoE5E5B1D9_u);
        lv_targetEval = libAIAI_gf_HeroAIEvaluateTarget(lp_trigPlayer, lv_hero, libAIAI_gv_aIHeroChangeTargetDistanceWeight);
        if ((lv_targetEval < lv_bestTargetEval) && (libNtve_gf_UnitIsInvulnerable(lv_hero) == false)) {
            lv_bestTargetEval = lv_targetEval;
            lv_bestTarget = lv_hero;
        }
        else {
        }
    }
    return lv_bestTarget;
}

void libAIAI_gf_HeroAIPickupSkullsLogic (int lp_faction) {
    playergroup auto2AD73773_g;
    int auto2AD73773_p;

    // Variable Declarations
    int lv_playerIndex;
    bool lv_skullFound;

    // Variable Initialization

    // Implementation
    auto2AD73773_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto2AD73773_p = 1;
    for ( ; auto2AD73773_p <= PlayerGroupCount(auto2AD73773_g) ; auto2AD73773_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto2AD73773_g, auto2AD73773_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto2AD73773_g, auto2AD73773_p);
        if ((libAIAI_gf_HeroAIIsUnitInUnderworld(libGame_gv_players[lv_playerIndex].lv_heroUnit) == true) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 0) == true)) {
            lv_skullFound = libAIAI_gf_HeroAISearchForNearbySkull(lv_playerIndex, RegionCircle(UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit), libAIAI_gv_aIHeroSkullSearchRadius), false);
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAISearchForNearbySkull (int lp_trigPlayer, region lp_searchRegion, bool lp_ignoreAllies) {
    unitgroup auto30629D51_g;
    int auto30629D51_u;

    // Variable Declarations
    unitgroup lv_nearbySkulls;
    unit lv_skull;
    fixed lv_skullDistance;
    unit lv_bestSkull;
    fixed lv_bestSkullDistance;

    // Variable Initialization
    lv_nearbySkulls = UnitGroupEmpty();
    lv_bestSkullDistance = 524287.0;

    // Implementation
    lv_nearbySkulls = UnitGroup("ItemUnderworldPowerup", c_playerAny, lp_searchRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto30629D51_g = lv_nearbySkulls;
    auto30629D51_u = 1;
    for ( ; auto30629D51_u <= UnitGroupCount(auto30629D51_g, c_unitCountAll) ; auto30629D51_u += BoolToInt(lv_skull == UnitGroupUnit(auto30629D51_g, auto30629D51_u)) ) {
        lv_skull = UnitGroupUnit(auto30629D51_g, auto30629D51_u);
        if ((lp_ignoreAllies == false) && (libAIAI_gf_HeroAIIsAllyPickingUpSkull(lp_trigPlayer, lv_skull) == true)) {
            continue;
        }
        else {
        }
        lv_skullDistance = DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lv_skull));
        if ((lv_skullDistance < lv_bestSkullDistance)) {
            lv_bestSkull = lv_skull;
            lv_bestSkullDistance = lv_skullDistance;
        }
        else {
        }
    }
    if ((UnitIsValid(lv_bestSkull) == true)) {
        libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 60);
        libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull = lv_bestSkull;
        UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), UnitGetPosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_curTargetSkull)), c_orderQueueReplace);
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsAllyPickingUpSkull (int lp_trigPlayer, unit lp_skull) {
    int auto372D9743_ae;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    auto372D9743_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto372D9743_ae ; lv_playerIndex += 1 ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lp_trigPlayer, 2) == true) && (lp_trigPlayer != lv_playerIndex) && (libGame_gv_players[lp_trigPlayer].lv_faction == libGame_gv_players[lv_playerIndex].lv_faction) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_heroState == 60) && (libAIAI_gv_aIHeroes[lv_playerIndex].lv_curTargetSkull == lp_skull)) {
            return true;
        }
        else {
        }
    }
    return false;
}

void libAIAI_gf_HeroAIAbathurLogic (int lp_faction) {
    playergroup autoDCCB236A_g;
    int autoDCCB236A_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    autoDCCB236A_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    autoDCCB236A_p = 1;
    for ( ; autoDCCB236A_p <= PlayerGroupCount(autoDCCB236A_g) ; autoDCCB236A_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoDCCB236A_g, autoDCCB236A_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoDCCB236A_g, autoDCCB236A_p);
        if ((UnitGetType(libGame_gv_players[lv_playerIndex].lv_heroUnit) == "HeroAbathur") && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 3) == true)) {
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToUseAbathurLogic = true;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToGoHome = true;
        }
        else {
        }
    }
}

void libAIAI_gf_HeroAIStartAbathurAdvanceLane (int lp_trigPlayer) {
    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 64);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneOffset = 0.0;
    libAIAI_gf_HeroAIResetWaypoint(lp_trigPlayer, true);
    libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, true);
}

void libAIAI_gf_HeroAIStartAbathurRetreatLane (int lp_trigPlayer) {
    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 65);
    libAIAI_gv_aIHeroes[lp_trigPlayer].lv_laneOffset = 0.0;
    libAIAI_gf_HeroAIResetWaypoint(lp_trigPlayer, false);
    libAIAI_gf_HeroAIUpdateLaneTargetPosition(lp_trigPlayer, false);
}

void libAIAI_gf_HeroAIStartAbathurHideInTown (int lp_trigPlayer) {
    // Variable Declarations
    point lv_hideInTownPosition;

    // Variable Initialization

    // Implementation
    libAIAI_gf_HeroAIChangeState(lp_trigPlayer, 66);
    lv_hideInTownPosition = libAIAI_gf_HeroAIGetHideInTownPosition(lp_trigPlayer, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane);
    UnitIssueOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, OrderTargetingPoint(AbilityCommand("move", 0), lv_hideInTownPosition), c_orderQueueReplace);
}

point libAIAI_gf_HeroAIGetHideInTownPosition (int lp_trigPlayer, int lp_laneIndex) {
    // Variable Declarations
    fixed lv_frontTowerLanePosition;
    fixed lv_hideInTownLanePosition;

    // Variable Initialization

    // Implementation
    lv_frontTowerLanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[lp_laneIndex].lv_frontTowerPosition;
    lv_hideInTownLanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, lp_laneIndex, lv_frontTowerLanePosition, libAIAI_gv_aIHeroAbathurFarBehindFrontTowerDistance);
    return AILaneWaypointConvertWaydistOffsetToPoint(lp_laneIndex, lv_hideInTownLanePosition, 0.0);
}

void libAIAI_gf_HeroAIWaitInSpawnLogic (int lp_faction) {
    playergroup auto8186535D_g;
    int auto8186535D_p;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    auto8186535D_g = libAIAI_gv_heroAITeamPlayerData[libAIAI_gf_HeroAITeamIndexOfFaction(lp_faction)].lv_aIPlayers; 
    auto8186535D_p = 1;
    for ( ; auto8186535D_p <= PlayerGroupCount(auto8186535D_g) ; auto8186535D_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto8186535D_g, auto8186535D_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto8186535D_g, auto8186535D_p);
        if ((libAIAI_gv_aIHeroes[lv_playerIndex].lv_shouldWaitInSpawn == true) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 2) == true)) {
            libAIAI_gf_HeroAILeaveCurrentObjective(lv_playerIndex);
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToWaitInSpawn = true;
            libAIAI_gv_aIHeroes[lv_playerIndex].lv_wantsToGoHome = true;
        }
        else {
        }
    }
}

bool libAIAI_gf_HeroAIIsPlayerActive (int lp_trigPlayer, int lp_type) {
    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_heroUnit == null)) {
        return false;
    }
    else {
    }
    if ((lp_type == 0)) {
        return true;
    }
    else {
    }
    if ((lp_type == 1)) {
        if ((PlayerStatus(lp_trigPlayer) == c_playerStatusActive) && (PlayerType(lp_trigPlayer) == c_playerTypeUser) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 0)) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
        if ((PlayerStatus(lp_trigPlayer) == c_playerStatusActive) && (PlayerType(lp_trigPlayer) == c_playerTypeUser) && (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 0)) {
            return false;
        }
        else {
            return true;
        }
    }
}

bool libAIAI_gf_HeroAIIsTeamBusy (int lp_faction) {
    int auto8D831914_ae;
    int auto8D831914_ai;

    // Variable Declarations
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    auto8D831914_ae = libCore_gv_bALMaxPlayers;
    auto8D831914_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto8D831914_ai >= 0 && lv_playerIndex <= auto8D831914_ae) || (auto8D831914_ai <= 0 && lv_playerIndex >= auto8D831914_ae) ) ; lv_playerIndex += auto8D831914_ai ) {
        if ((libGame_gv_players[lv_playerIndex].lv_faction == lp_faction) && (libAIAI_gf_HeroAIIsHigherPriority(lv_playerIndex, 25) == false)) {
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIIsPlayerBehindLanePosition (int lp_player, fixed lp_lanePosition) {
    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_player].lv_currentLane == 0)) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_player);
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        return (libAIAI_gv_aIHeroes[lp_player].lv_heroLanePosition <= lp_lanePosition);
    }
    else {
        return (libAIAI_gv_aIHeroes[lp_player].lv_heroLanePosition >= lp_lanePosition);
    }
}

bool libAIAI_gf_HeroAIIsPlayerDefendingTown (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_lanePosition;
    point lv_lanePoint;
    point lv_frontTowerPosition;
    int lv_frontTown;
    region lv_townDefendRegion;
    unitgroup lv_enemies;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0)) {
        return false;
    }
    else {
    }
    lv_townDefendRegion = RegionEmpty();
    lv_lanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_frontTowerPosition;
    lv_lanePoint = AILaneWaypointConvertWaydistOffsetToPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_lanePosition, 0.0);
    RegionAddRegion(lv_townDefendRegion, RegionCircle(lv_lanePoint, 12.0));
    lv_lanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_lanePosition, 8.0);
    lv_lanePoint = AILaneWaypointConvertWaydistOffsetToPoint(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, lv_lanePosition, 0.0);
    RegionAddRegion(lv_townDefendRegion, RegionCircle(lv_lanePoint, 12.0));
    if ((libNtve_gf_UnitInRegion(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_townDefendRegion) == false)) {
        return false;
    }
    else {
    }
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_townDefendRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((UnitGroupCount(lv_enemies, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsPlayerAttackingTown (int lp_trigPlayer) {
    // Variable Declarations
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyTowers;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyTowers = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane <= 0)) {
        return false;
    }
    else {
    }
    lv_nearbyRegion = RegionCircle(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), 12.0);
    lv_enemies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    lv_enemyTowers = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    if ((UnitGroupCount(lv_enemyTowers, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsPlayerInsideEnemyTown (int lp_trigPlayer) {
    int auto882C4B74_ae;
    int auto882C4B74_ai;

    // Variable Declarations
    playergroup lv_enemyTeam;
    int lv_townIndex;

    // Variable Initialization
    lv_enemyTeam = PlayerGroupEmpty();

    // Implementation
    lv_enemyTeam = libGame_gf_EnemyPlayerGroupOfPlayer(lp_trigPlayer);
    auto882C4B74_ae = libGame_gv_townTownCount;
    auto882C4B74_ai = 1;
    lv_townIndex = 1;
    for ( ; ( (auto882C4B74_ai >= 0 && lv_townIndex <= auto882C4B74_ae) || (auto882C4B74_ai <= 0 && lv_townIndex >= auto882C4B74_ae) ) ; lv_townIndex += auto882C4B74_ai ) {
        if ((libGame_gv_townTownData[lv_townIndex].lv_townHallIndex != -1) && (PlayerGroupHasPlayer(lv_enemyTeam, libGame_gv_townTownData[lv_townIndex].lv_owner) == true) && (UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[libGame_gv_townTownData[lv_townIndex].lv_townHallIndex]) == true) && (RegionContainsPoint(libGame_gv_townTownData[lv_townIndex].lv_townRegion, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit)) == true)) {
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIIsPlayerInsideBase (int lp_trigPlayer) {
    // Variable Declarations
    region lv_baseRegion;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_baseRegion = libCore_gv_mAPOrderBaseRegion;
    }
    else {
        lv_baseRegion = libCore_gv_mAPChaosBaseRegion;
    }
    return libNtve_gf_UnitInRegion(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_baseRegion);
}

bool libAIAI_gf_HeroAIIsPlayerInsideEnemyBase (int lp_trigPlayer) {
    // Variable Declarations
    region lv_baseRegion;

    // Variable Initialization

    // Implementation
    if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
        lv_baseRegion = libCore_gv_mAPChaosBaseRegion;
    }
    else {
        lv_baseRegion = libCore_gv_mAPOrderBaseRegion;
    }
    return libNtve_gf_UnitInRegion(libGame_gv_players[lp_trigPlayer].lv_heroUnit, lv_baseRegion);
}

bool libAIAI_gf_HeroAIIsPlayerAtSpawn (int lp_trigPlayer) {
    // Implementation
    return UnitHasBehavior2(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "NearShop");
}

bool libAIAI_gf_HeroAIIsUnitBehindGate (unit lp_unit) {
    int autoF1A33D95_ae;
    int autoF1A33D95_ai;
    int auto88A5AB35_ae;
    int auto88A5AB35_ai;

    // Variable Declarations
    playergroup lv_allyTeam;
    int lv_townIndex;
    int lv_structureIndex;
    fixed lv_gateToTownDistance;
    fixed lv_unitToTownDistance;
    point lv_townPosition;
    point lv_gatePosition;

    // Variable Initialization
    lv_allyTeam = PlayerGroupEmpty();

    // Implementation
    lv_allyTeam = libGame_gf_AlliedPlayerGroupOfPlayer(UnitGetOwner(lp_unit));
    autoF1A33D95_ae = libGame_gv_townTownCount;
    autoF1A33D95_ai = 1;
    lv_townIndex = 1;
    for ( ; ( (autoF1A33D95_ai >= 0 && lv_townIndex <= autoF1A33D95_ae) || (autoF1A33D95_ai <= 0 && lv_townIndex >= autoF1A33D95_ae) ) ; lv_townIndex += autoF1A33D95_ai ) {
        if ((libGame_gv_townTownData[lv_townIndex].lv_townHallIndex != -1) && (PlayerGroupHasPlayer(lv_allyTeam, libGame_gv_townTownData[lv_townIndex].lv_owner) == true) && (RegionContainsPoint(libGame_gv_townTownData[lv_townIndex].lv_townRegion, UnitGetPosition(lp_unit)) == true)) {
            lv_townPosition = UnitGetPosition(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[libGame_gv_townTownData[lv_townIndex].lv_townHallIndex]);
            auto88A5AB35_ae = libGame_gv_townTownData[lv_townIndex].lv_structureCount;
            auto88A5AB35_ai = 1;
            lv_structureIndex = 1;
            for ( ; ( (auto88A5AB35_ai >= 0 && lv_structureIndex <= auto88A5AB35_ae) || (auto88A5AB35_ai <= 0 && lv_structureIndex >= auto88A5AB35_ae) ) ; lv_structureIndex += auto88A5AB35_ai ) {
                if ((libGame_gv_townTownData[lv_townIndex].lv_structureTypes[lv_structureIndex] == 3) && (UnitIsAlive(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]) == true)) {
                    lv_gatePosition = UnitGetPosition(libGame_gv_townTownData[lv_townIndex].lv_structureUnits[lv_structureIndex]);
                    lv_gateToTownDistance = DistanceBetweenPoints(lv_gatePosition, lv_townPosition);
                    lv_unitToTownDistance = DistanceBetweenPoints(UnitGetPosition(lp_unit), lv_townPosition);
                    if ((lv_unitToTownDistance < lv_gateToTownDistance)) {
                        return true;
                    }
                    else {
                    }
                }
                else {
                }
            }
        }
        else {
        }
    }
    return false;
}

fixed libAIAI_gf_HeroAIEvaluateTarget (int lp_trigPlayer, unit lp_target, fixed lp_distanceWeight) {
    // Variable Declarations
    fixed lv_distance;
    fixed lv_weaponRange;
    fixed lv_healthPercent;

    // Variable Initialization

    // Implementation
    lv_weaponRange = libAIAI_gf_AIGetActiveWeaponRange(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    lv_distance = MaxF((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(lp_target)) - lv_weaponRange), 0.0);
    lv_healthPercent = UnitGetPropertyFixed(lp_target, c_unitPropLifePercent, c_unitPropCurrent);
    return (lv_healthPercent + (lv_distance * lp_distanceWeight));
}

bool libAIAI_gf_HeroAIAIDifficultyLevelShouldUseHero (int lp_player, int lp_heroIndex, bool lp_allowAnyTier) {
    int autoA122FE55_ae;
    int autoA122FE55_ai;
    int auto03AD9844_ae;
    int auto03AD9844_ai;

    // Variable Declarations
    string lv_heroType;
    int lv_maxTier;
    int lv_tierIndex;
    int lv_arrayIndex;

    // Variable Initialization

    // Implementation
    if (((PlayerType(lp_player) == c_playerTypeComputer) || (PlayerStatus(lp_player) == c_playerStatusLeft))) {
        lv_heroType = libCore_gv_dataHeroesHeroData[lp_heroIndex].lv_unitType;
        if ((lp_allowAnyTier == true)) {
            lv_maxTier = libAIAI_gv_heroAINumberofHeroTiers;
        }
        else {
            lv_maxTier = libAIAI_gv_aIHeroHighestHeroSelectTier[(libAIAI_gv_aIHeroes[lp_player].lv_difficulty)];
        }
        autoA122FE55_ae = lv_maxTier;
        autoA122FE55_ai = 1;
        lv_tierIndex = 1;
        for ( ; ( (autoA122FE55_ai >= 0 && lv_tierIndex <= autoA122FE55_ae) || (autoA122FE55_ai <= 0 && lv_tierIndex >= autoA122FE55_ae) ) ; lv_tierIndex += autoA122FE55_ai ) {
            auto03AD9844_ae = libCore_gv_dataHeroesMaxHeroCount;
            auto03AD9844_ai = 1;
            lv_arrayIndex = 1;
            for ( ; ( (auto03AD9844_ai >= 0 && lv_arrayIndex <= auto03AD9844_ae) || (auto03AD9844_ai <= 0 && lv_arrayIndex >= auto03AD9844_ae) ) ; lv_arrayIndex += auto03AD9844_ai ) {
                if ((libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] == null)) {
                    break;
                }
                else {
                }
                if ((libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] == lv_heroType)) {
                    return true;
                }
                else {
                }
            }
        }
        return false;
    }
    else {
    }
    return true;
}

int libAIAI_gf_HeroAIGetAllyTeamIndex (int lp_player) {
    // Implementation
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        return (0);
    }
    else {
        return (1);
    }
}

int libAIAI_gf_HeroAIGetEnemyTeamIndex (int lp_player) {
    // Implementation
    if ((libGame_gv_players[lp_player].lv_faction == 0)) {
        return (1);
    }
    else {
        return (0);
    }
}

int libAIAI_gf_HeroAIGetLaneWithMostAllies (int lp_player) {
    int auto85A92562_ae;
    int auto85A92562_ai;
    int autoC34721D3_ae;
    int autoC34721D3_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_bestLane;
    int lv_bestNumberofAllies;
    int lv_laneToAvoid;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player);
    if ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidPlayer != 0)) {
        lv_laneToAvoid = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_avoidLane;
    }
    else {
    }
    auto85A92562_ae = libGame_gv_laneCount;
    auto85A92562_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (auto85A92562_ai >= 0 && lv_laneIndex <= auto85A92562_ae) || (auto85A92562_ai <= 0 && lv_laneIndex >= auto85A92562_ae) ) ; lv_laneIndex += auto85A92562_ai ) {
        if ((lv_laneIndex != lv_laneToAvoid) && (libGame_gv_laneData[lv_laneIndex].lv_minionSpawningEnabled == true) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player)].lv_laneData[lv_laneIndex].lv_numAllyHumanHeroes > lv_bestNumberofAllies)) {
            lv_bestLane = lv_laneIndex;
            lv_bestNumberofAllies = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player)].lv_laneData[lv_laneIndex].lv_numAllyHumanHeroes;
        }
        else {
        }
    }
    if ((lv_bestLane != 0)) {
        return lv_bestLane;
    }
    else {
    }
    autoC34721D3_ae = libGame_gv_laneCount;
    autoC34721D3_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoC34721D3_ai >= 0 && lv_laneIndex <= autoC34721D3_ae) || (autoC34721D3_ai <= 0 && lv_laneIndex >= autoC34721D3_ae) ) ; lv_laneIndex += autoC34721D3_ai ) {
        if ((lv_laneIndex != lv_laneToAvoid) && (libGame_gv_laneData[lv_laneIndex].lv_minionSpawningEnabled == true) && (libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player)].lv_laneData[lv_laneIndex].lv_numAllyHeroes > lv_bestNumberofAllies)) {
            lv_bestLane = lv_laneIndex;
            lv_bestNumberofAllies = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player)].lv_laneData[lv_laneIndex].lv_numAllyHeroes;
        }
        else {
        }
    }
    if ((lv_bestLane != 0)) {
        return lv_bestLane;
    }
    else {
        return libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_player)].lv_weakestLane;
    }
}

bool libAIAI_gf_HeroAIMercsAttackingLane (int lp_faction, int lp_laneIndex) {
    // Variable Declarations
    int lv_teamIndex;
    point lv_contentionPoint;

    // Variable Initialization

    // Implementation
    if ((lp_laneIndex == 0)) {
        return false;
    }
    else {
    }
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_contentionPoint;
    if ((libCore_gf_TestLocationClosertoFactionSide(lv_contentionPoint, lp_faction, 1.0) == true) && ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemySiegeGiants > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyOgres > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyOgreKings > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_numEnemyDragonKnights > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIInLaneWithAllyMercs (int lp_trigPlayer) {
    // Variable Declarations
    int lv_teamIndex;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0) && ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllySiegeGiants > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllyOgres > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllyOgreKings > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numAllyDragonKnights > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIInLaneWithEnemyMercs (int lp_trigPlayer) {
    // Variable Declarations
    int lv_teamIndex;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0) && ((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemySiegeGiants > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyOgres > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyOgreKings > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane].lv_numEnemyDragonKnights > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAILaneHasAllMeleeHeroes (int lp_faction, int lp_laneIndex) {
    playergroup auto8318C5DE_g;
    int auto8318C5DE_p;

    // Variable Declarations
    int lv_teamIndex;
    int lv_playerIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    auto8318C5DE_g = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lp_laneIndex].lv_allyHeroes; 
    auto8318C5DE_p = 1;
    for ( ; auto8318C5DE_p <= PlayerGroupCount(auto8318C5DE_g) ; auto8318C5DE_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(auto8318C5DE_g, auto8318C5DE_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(auto8318C5DE_g, auto8318C5DE_p);
        if ((libAIAI_gf_HeroAIIsHeroMelee(lv_playerIndex) == false)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAIInLaneWithAllMeleeHeroes (int lp_trigPlayer) {
    playergroup autoE6DE5509_g;
    int autoE6DE5509_p;

    // Variable Declarations
    int lv_laneIndex;
    int lv_teamIndex;
    playergroup lv_alliesInLane;
    int lv_playerIndex;

    // Variable Initialization
    lv_alliesInLane = PlayerGroupEmpty();

    // Implementation
    lv_laneIndex = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_desiredLane;
    if ((lv_laneIndex <= 0)) {
        return false;
    }
    else {
    }
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    libNtve_gf_AddPlayerGroupToPlayerGroup(libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_allyHeroes, lv_alliesInLane);
    PlayerGroupRemove(lv_alliesInLane, lp_trigPlayer);
    if ((PlayerGroupCount(lv_alliesInLane) == 0)) {
        return false;
    }
    else {
    }
    autoE6DE5509_g = lv_alliesInLane; 
    autoE6DE5509_p = 1;
    for ( ; autoE6DE5509_p <= PlayerGroupCount(autoE6DE5509_g) ; autoE6DE5509_p += BoolToInt(lv_playerIndex == PlayerGroupPlayer(autoE6DE5509_g, autoE6DE5509_p)) ) {
        lv_playerIndex = PlayerGroupPlayer(autoE6DE5509_g, autoE6DE5509_p);
        if ((libAIAI_gf_HeroAIIsHeroMelee(lv_playerIndex) == false)) {
            return false;
        }
        else {
        }
    }
    return true;
}

bool libAIAI_gf_HeroAIUnitProtectedByTower (unit lp_unit, fixed lp_towerSearchRadius) {
    unitgroup auto2DF23405_g;
    int auto2DF23405_u;

    // Variable Declarations
    region lv_areaNearUnit;
    unitgroup lv_allies;
    unitgroup lv_allyTowers;
    unit lv_tower;
    region lv_areaNearTower;
    unitgroup lv_enemies;
    unitgroup lv_enemyMinions;

    // Variable Initialization
    lv_allies = UnitGroupEmpty();
    lv_allyTowers = UnitGroupEmpty();
    lv_enemies = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();

    // Implementation
    lv_areaNearUnit = RegionCircle(UnitGetPosition(lp_unit), lp_towerSearchRadius);
    lv_allies = UnitGroupAlliance(UnitGetOwner(lp_unit), c_unitAllianceAlly, lv_areaNearUnit, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_allyTowers = UnitGroupFilter(null, c_playerAny, lv_allies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    auto2DF23405_g = lv_allyTowers;
    auto2DF23405_u = 1;
    for ( ; auto2DF23405_u <= UnitGroupCount(auto2DF23405_g, c_unitCountAll) ; auto2DF23405_u += BoolToInt(lv_tower == UnitGroupUnit(auto2DF23405_g, auto2DF23405_u)) ) {
        lv_tower = UnitGroupUnit(auto2DF23405_g, auto2DF23405_u);
        if ((libAIAI_gf_HeroAIIsTowerAThreat(lp_unit) == false)) {
            continue;
        }
        else {
        }
        lv_areaNearTower = RegionCircle(UnitGetPosition(lv_tower), libAIAI_gv_aIHeroCloseToTowerDistance);
        lv_enemies = UnitGroupAlliance(UnitGetOwner(lv_tower), c_unitAllianceEnemy, lv_areaNearTower, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
        lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
        if ((UnitGroupCount(lv_enemyMinions, c_unitCountAlive) <= 1)) {
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIInRangeOfAnEnemyTower (int lp_player, point lp_position) {
    unitgroup autoE84E49AD_g;
    int autoE84E49AD_u;

    // Variable Declarations
    region lv_region;
    unitgroup lv_enemies;
    unitgroup lv_enemyTowers;
    unit lv_tower;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyTowers = UnitGroupEmpty();

    // Implementation
    lv_region = RegionEmpty();
    RegionAddCircle(lv_region, true, lp_position, 10.0);
    lv_enemies = UnitGroupAlliance(lp_player, c_unitAllianceEnemy, lv_region, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32)) | (1 << (c_targetFilterStunned - 32))), 0);
    lv_enemyTowers = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterArmored) | (1 << c_targetFilterStructure), 0, 0, 0), 0);
    autoE84E49AD_g = lv_enemyTowers;
    autoE84E49AD_u = 1;
    for ( ; autoE84E49AD_u <= UnitGroupCount(autoE84E49AD_g, c_unitCountAll) ; autoE84E49AD_u += BoolToInt(lv_tower == UnitGroupUnit(autoE84E49AD_g, autoE84E49AD_u)) ) {
        lv_tower = UnitGroupUnit(autoE84E49AD_g, autoE84E49AD_u);
        if ((libAIAI_gf_HeroAIIsTowerAThreat(lv_tower) == false)) {
            UnitGroupRemove(lv_enemyTowers, lv_tower);
        }
        else {
        }
    }
    if ((UnitGroupCount(lv_enemyTowers, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAICloseToTowerWithoutMinions (int lp_trigPlayer, unit lp_tower) {
    // Variable Declarations
    unitgroup lv_allies;
    fixed lv_distanceToTower;
    region lv_testRegion;

    // Variable Initialization
    lv_allies = UnitGroupEmpty();

    // Implementation
    lv_distanceToTower = DistanceBetweenPoints(UnitGetPosition(lp_tower), UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    if ((lv_distanceToTower < 12.5)) {
        lv_distanceToTower -= 1.0;
        if ((lv_distanceToTower < 8.0)) {
            lv_distanceToTower = 8.0;
        }
        else {
        }
        lv_testRegion = RegionCircle(UnitGetPosition(lp_tower), lv_distanceToTower);
        lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAllyExcludeSelf, lv_testRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
        if ((UnitGroupCount(lv_allies, c_unitCountAlive) <= 0)) {
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAICloseToAnyTowerWithoutMinions (int lp_trigPlayer) {
    unitgroup autoD14A4108_g;
    int autoD14A4108_u;

    // Variable Declarations
    unitgroup lv_allies;
    fixed lv_distanceToTower;
    region lv_testRegion;
    unit lv_tower;

    // Variable Initialization
    lv_allies = UnitGroupEmpty();

    // Implementation
    autoD14A4108_g = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyTowers;
    autoD14A4108_u = 1;
    for ( ; autoD14A4108_u <= UnitGroupCount(autoD14A4108_g, c_unitCountAll) ; autoD14A4108_u += BoolToInt(lv_tower == UnitGroupUnit(autoD14A4108_g, autoD14A4108_u)) ) {
        lv_tower = UnitGroupUnit(autoD14A4108_g, autoD14A4108_u);
        if ((libAIAI_gf_HeroAIIsTowerAThreat(lv_tower) == true) && (libAIAI_gf_HeroAICloseToTowerWithoutMinions(lp_trigPlayer, lv_tower) == true)) {
            return true;
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIAlliesNearEnemyBuilding (int lp_trigPlayer, unit lp_building) {
    // Variable Declarations
    unitgroup lv_allies;
    fixed lv_distanceToTower;
    region lv_testRegion;

    // Variable Initialization
    lv_allies = UnitGroupEmpty();

    // Implementation
    lv_testRegion = RegionCircle(UnitGetPosition(lp_building), libAIAI_gv_aIHeroNearBuildingRange);
    lv_allies = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceAllyExcludeSelf, lv_testRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((UnitGroupCount(lv_allies, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIEnemiesNearBuilding (unit lp_building) {
    // Variable Declarations
    unitgroup lv_enemies;
    fixed lv_distanceToTower;
    region lv_testRegion;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();

    // Implementation
    lv_testRegion = RegionCircle(UnitGetPosition(lp_building), libAIAI_gv_aIHeroNearBuildingRange);
    lv_enemies = UnitGroupAlliance(UnitGetOwner(lp_building), c_unitAllianceEnemy, lv_testRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    if ((UnitGroupCount(lv_enemies, c_unitCountAlive) > 0)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIIsTowerAThreat (unit lp_tower) {
    // Implementation
    if ((UnitGetPropertyFixed(lp_tower, c_unitPropEnergy, c_unitPropCurrent) <= 2.0)) {
        return false;
    }
    else {
    }
    if ((UnitHasBehavior2(lp_tower, "RavenLordsCurseStructures") == true)) {
        return false;
    }
    else {
    }
    return true;
}

point libAIAI_gf_HeroAIGetPositionBehindContentionPoint (int lp_trigPlayer, int lp_laneIndex, fixed lp_distance, fixed lp_laneOffset) {
    // Variable Declarations
    fixed lv_lanePosition;

    // Variable Initialization

    // Implementation
    lv_lanePosition = libAIAI_gv_heroAITeamData[libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer)].lv_laneData[lp_laneIndex].lv_contentionPointLanePosition;
    lv_lanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, lp_laneIndex, lv_lanePosition, lp_distance);
    return AILaneWaypointConvertWaydistOffsetToPoint(lp_laneIndex, lv_lanePosition, lp_laneOffset);
}

point libAIAI_gf_HeroAIGetRetreatPosition (int lp_trigPlayer, fixed lp_distance) {
    // Variable Declarations
    point lv_heroPosition;
    int lv_laneIndex;
    fixed lv_lanePosition;
    fixed lv_retreatedLanePosition;
    point lv_retreatedPosition;
    point lv_retreatDirection;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAIIsPlayerActive(lp_trigPlayer, 2) == false)) {
        return null;
    }
    else {
    }
    lv_heroPosition = UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit);
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane > 0)) {
        lv_laneIndex = AILaneWaypointGetClosestLane(lv_heroPosition);
        lv_lanePosition = libAIAI_gf_AIGetClosestLanePosition(lv_laneIndex, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
        lv_retreatedLanePosition = libAIAI_gf_AIRetreatLanePosition(libGame_gv_players[lp_trigPlayer].lv_faction, lv_laneIndex, lv_lanePosition, lp_distance);
        lv_retreatDirection = AIGetDirection(lv_heroPosition, AILaneWaypointConvertWaydistOffsetToPoint(lv_laneIndex, lv_retreatedLanePosition, 0.0));
    }
    else {
        lv_retreatDirection = AIGetDirection(lv_heroPosition, libGame_gv_players[lp_trigPlayer].lv_spawnPoint);
    }
    lv_retreatedPosition = libCore_gf_AdvancePointinDirection(lv_heroPosition, lv_retreatDirection, lp_distance);
    return lv_retreatedPosition;
}

unitgroup libAIAI_gf_HeroAIGetEnemyHeroesInRetreatPath (int lp_trigPlayer) {
    unitgroup auto326E261F_g;
    int auto326E261F_u;

    // Variable Declarations
    fixed lv_heroLanePosition;
    fixed lv_enemyLanePosition;
    unit lv_enemyHero;
    unitgroup lv_enemyHeroesInTheWay;

    // Variable Initialization
    lv_enemyHeroesInTheWay = UnitGroupEmpty();

    // Implementation
    if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane == 0)) {
        return null;
    }
    else {
    }
    lv_heroLanePosition = libAIAI_gf_AIGetClosestLanePosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit));
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    auto326E261F_g = libAIAI_gv_aIHeroes[lp_trigPlayer].lv_enemyHeroes;
    auto326E261F_u = 1;
    for ( ; auto326E261F_u <= UnitGroupCount(auto326E261F_g, c_unitCountAll) ; auto326E261F_u += BoolToInt(lv_enemyHero == UnitGroupUnit(auto326E261F_g, auto326E261F_u)) ) {
        lv_enemyHero = UnitGroupUnit(auto326E261F_g, auto326E261F_u);
        lv_heroLanePosition = libAIAI_gf_AIGetClosestLanePosition(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_currentLane, UnitGetPosition(lv_enemyHero));
        if ((libGame_gv_players[lp_trigPlayer].lv_faction == 0)) {
            if ((lv_heroLanePosition < lv_enemyLanePosition)) {
                UnitGroupAdd(lv_enemyHeroesInTheWay, lv_enemyHero);
            }
            else {
            }
        }
        else {
            if ((lv_heroLanePosition > lv_enemyLanePosition)) {
                UnitGroupAdd(lv_enemyHeroesInTheWay, lv_enemyHero);
            }
            else {
            }
        }
    }
    return lv_enemyHeroesInTheWay;
}

bool libAIAI_gf_HeroAIEnemiesInHomeRegion (int lp_faction) {
    // Variable Declarations
    int lv_teamIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    if (((libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numEnemyHeroes > 0) || (libAIAI_gv_heroAITeamData[lv_teamIndex].lv_homeEval.lv_numEnemyMinionsAndSummons > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIShouldUseUltimates (int lp_trigPlayer) {
    // Implementation
    return libAIAI_gv_aIHeroUseUltimates[(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)];
}

bool libAIAI_gf_HeroAIIsAIEnabledForPlayer (int lp_trigPlayer) {
    // Implementation
    if (((lp_trigPlayer <= 0) || (lp_trigPlayer > libCore_gv_bALMaxPlayers))) {
        return false;
    }
    else {
    }
    return (libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState != 0);
}

bool libAIAI_gf_HeroAIIsAllyTargettingUnit (int lp_trigPlayer, unit lp_targetUnit) {
    int auto5EBE71F5_ae;
    int auto5EBE71F5_ai;

    // Variable Declarations
    int lv_playerIndex;
    order lv_heroOrder;

    // Variable Initialization

    // Implementation
    auto5EBE71F5_ae = libCore_gv_bALMaxPlayers;
    auto5EBE71F5_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (auto5EBE71F5_ai >= 0 && lv_playerIndex <= auto5EBE71F5_ae) || (auto5EBE71F5_ai <= 0 && lv_playerIndex >= auto5EBE71F5_ae) ) ; lv_playerIndex += auto5EBE71F5_ai ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction)) {
            lv_heroOrder = UnitOrder(libGame_gv_players[lv_playerIndex].lv_heroUnit, 0);
            if ((lv_heroOrder != null) && (OrderGetTargetType(lv_heroOrder) == c_orderTargetUnit) && (OrderGetTargetUnit(lv_heroOrder) == lp_targetUnit)) {
                return true;
            }
            else {
            }
        }
        else {
        }
    }
    return false;
}

bool libAIAI_gf_HeroAIIsHeroMelee (int lp_trigPlayer) {
    // Implementation
    return libCore_gv_dataHeroesHeroData[libGame_gv_players[lp_trigPlayer].lv_heroIndex].lv_isMelee;
}

bool libAIAI_gf_HeroAIAttackingBadTarget (int lp_trigPlayer) {
    // Variable Declarations
    order lv_currentOrder;
    unit lv_currentTarget;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libGame_gv_players[lp_trigPlayer].lv_activeVehicle) == true)) {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_activeVehicle, 0);
    }
    else {
        lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    }
    if ((lv_currentOrder != null) && (OrderGetAbilityCommand(lv_currentOrder) == AbilityCommand("attack", 0))) {
        lv_currentTarget = OrderGetTargetUnit(lv_currentOrder);
    }
    else {
    }
    if ((lv_currentTarget == null)) {
        return false;
    }
    else {
    }
    if ((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_currentTarget)) == 2)) {
        return true;
    }
    else {
    }
    if ((libAIAI_gv_aIHeroAvoidTargettingFountains[libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty] == true) && (libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_currentTarget)) == 6)) {
        return true;
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIAttackingWeakHumanHero (int lp_trigPlayer, fixed lp_healthPercent) {
    // Variable Declarations
    order lv_currentOrder;
    unit lv_currentTarget;
    int lv_unitOwner;

    // Variable Initialization

    // Implementation
    lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((lv_currentOrder == null) && (OrderGetAbilityCommand(lv_currentOrder) != AbilityCommand("attack", 0))) {
        return false;
    }
    else {
    }
    lv_currentTarget = OrderGetTargetUnit(lv_currentOrder);
    if ((UnitIsValid(lv_currentTarget) == false)) {
        return false;
    }
    else {
    }
    lv_unitOwner = UnitGetOwner(lv_currentTarget);
    if ((lv_currentTarget == libGame_gv_players[lv_unitOwner].lv_heroUnit) && (libAIAI_gf_HeroAIIsPlayerActive(lv_unitOwner, 1) == true) && (UnitGetPropertyFixed(lv_currentTarget, c_unitPropLifePercent, c_unitPropCurrent) <= lp_healthPercent) && (libAIAI_gf_HeroAIInWeaponRangeOfTarget(lp_trigPlayer, lv_currentTarget, 1.0) == true)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIAttackingFountain (int lp_trigPlayer) {
    // Variable Declarations
    order lv_currentOrder;
    unit lv_currentTarget;
    int lv_unitOwner;

    // Variable Initialization

    // Implementation
    lv_currentOrder = UnitOrder(libGame_gv_players[lp_trigPlayer].lv_heroUnit, 0);
    if ((lv_currentOrder == null) && (OrderGetAbilityCommand(lv_currentOrder) != AbilityCommand("attack", 0))) {
        return false;
    }
    else {
    }
    lv_currentTarget = OrderGetTargetUnit(lv_currentOrder);
    if ((UnitIsValid(lv_currentTarget) == false)) {
        return false;
    }
    else {
    }
    if ((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(lv_currentTarget)) == 6) && (libAIAI_gf_HeroAIInWeaponRangeOfTarget(lp_trigPlayer, lv_currentTarget, 1.0) == true)) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIEnemiesNearCore (int lp_faction) {
    // Variable Declarations
    point lv_corePosition;
    int lv_allyComputerPlayer;
    region lv_nearbyRegion;
    unitgroup lv_enemies;
    unitgroup lv_enemyHeroes;
    unitgroup lv_enemyMinions;
    unitgroup lv_enemySummons;

    // Variable Initialization
    lv_enemies = UnitGroupEmpty();
    lv_enemyHeroes = UnitGroupEmpty();
    lv_enemyMinions = UnitGroupEmpty();
    lv_enemySummons = UnitGroupEmpty();

    // Implementation
    if ((lp_faction == 0)) {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core);
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamOrder;
    }
    else {
        lv_corePosition = UnitGetPosition(libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core);
        lv_allyComputerPlayer = libCore_gv_cOMPUTER_TeamChaos;
    }
    lv_nearbyRegion = RegionCircle(lv_corePosition, libAIAI_gv_aIHeroCloseToCoreDistance);
    lv_enemies = UnitGroupAlliance(lv_allyComputerPlayer, c_unitAllianceEnemy, lv_nearbyRegion, UnitFilter(0, 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem) | (1 << c_targetFilterStasis), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32)) | (1 << (c_targetFilterInvulnerable - 32))), 0);
    lv_enemyHeroes = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterHeroic), 0, 0, 0), 0);
    lv_enemyMinions = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter((1 << c_targetFilterBiological), 0, 0, 0), 0);
    lv_enemySummons = UnitGroupFilter(null, c_playerAny, lv_enemies, UnitFilter(0, (1 << (c_targetFilterSummoned - 32)), 0, 0), 0);
    if (((UnitGroupCount(lv_enemyHeroes, c_unitCountAlive) > 0) || (UnitGroupCount(lv_enemyMinions, c_unitCountAlive) > 0) || (UnitGroupCount(lv_enemySummons, c_unitCountAlive) > 0))) {
        return true;
    }
    else {
        return false;
    }
}

bool libAIAI_gf_HeroAIHeroHasBeenAttackedRecently (int lp_trigPlayer, fixed lp_time) {
    // Implementation
    if (((lp_trigPlayer <= 0) || (lp_trigPlayer > libCore_gv_bALMaxPlayers))) {
        return false;
    }
    else {
        return ((libAIAI_gv_heroAIDamageTracking[lp_trigPlayer].lv_lastTimeAttacked + lp_time) > TimerGetElapsed(libGame_gv_gameTimer));
    }
}

bool libAIAI_gf_HeroAITeamHasHumanPlayers (int lp_faction) {
    // Variable Declarations
    int lv_teamIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    return (PlayerGroupCount(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_humanPlayers) > 0);
}

bool libAIAI_gf_HeroAITeamHasAIPlayers (int lp_faction) {
    // Variable Declarations
    int lv_teamIndex;

    // Variable Initialization

    // Implementation
    if ((lp_faction == 0)) {
        lv_teamIndex = (0);
    }
    else {
        lv_teamIndex = (1);
    }
    return (PlayerGroupCount(libAIAI_gv_heroAITeamPlayerData[lv_teamIndex].lv_aIPlayers) > 0);
}

int libAIAI_gf_HeroAITeamIndexOfFaction (int lp_faction) {
    // Implementation
    if ((lp_faction == 0)) {
        return (0);
    }
    else {
        return (1);
    }
}

point libAIAI_gf_HeroAIFindNearbyPathablePoint (int lp_trigPlayer, point lp_point, fixed lp_maxDistance, bool lp_checkVision) {
    int auto6FEAAD6A_ae;
    int auto6FEAAD6A_ai;

    // Variable Declarations
    int lv_testIndex;
    fixed lv_angle;
    point lv_offset;
    point lv_testPoint;
    const int lv_numberOfTestPoints = 10;

    // Variable Initialization

    // Implementation
    if ((PointPathingPassable(lp_point) == true) && ((lp_checkVision == false) || (VisIsVisibleForPlayer(lp_trigPlayer, lp_point) == true))) {
        return lp_point;
    }
    else {
    }
    auto6FEAAD6A_ae = lv_numberOfTestPoints;
    auto6FEAAD6A_ai = 1;
    lv_testIndex = 1;
    for ( ; ( (auto6FEAAD6A_ai >= 0 && lv_testIndex <= auto6FEAAD6A_ae) || (auto6FEAAD6A_ai <= 0 && lv_testIndex >= auto6FEAAD6A_ae) ) ; lv_testIndex += auto6FEAAD6A_ai ) {
        lv_angle = (360.0 * (lv_testIndex / IntToFixed(lv_numberOfTestPoints)));
        lv_offset = Point((lp_maxDistance * Cos(lv_angle)), (lp_maxDistance * Sin(lv_angle)));
        lv_testPoint = Point((PointGetX(lp_point) + PointGetX(lv_offset)), (PointGetY(lp_point) + PointGetY(lv_offset)));
        if ((PointPathingPassable(lv_testPoint) == true) && ((lp_checkVision == false) || (VisIsVisibleForPlayer(lp_trigPlayer, lv_testPoint) == true))) {
            return lv_testPoint;
        }
        else {
        }
    }
    return null;
}

bool libAIAI_gf_HeroAIBeingTargettedByDangerousAbility (int lp_trigPlayer) {
    // Variable Declarations
    order lv_order;

    // Variable Initialization

    // Implementation
    if ((UnitIsValid(libAIAI_gv_heroAIDragonShireDragon) == true) && (libNtve_gf_PlayerIsEnemy(lp_trigPlayer, UnitGetOwner(libAIAI_gv_heroAIDragonShireDragon), 4) == true)) {
        lv_order = UnitOrder(libAIAI_gv_heroAIDragonShireDragon, 0);
        if ((lv_order != null) && (OrderGetAbilityCommand(lv_order) == AbilityCommand("VehicleDragonPunt", 0)) && (OrderGetTargetUnit(lv_order) == libGame_gv_players[lp_trigPlayer].lv_heroUnit) && (UnitHasBehavior2(libAIAI_gv_heroAIDragonShireDragon, "DragonKnightBullRushChanneling") == true)) {
            return true;
        }
        else {
        }
        if ((UnitHasBehavior2(libGame_gv_players[lp_trigPlayer].lv_heroUnit, "DragonKnightBullRushPuntableDummy") == true)) {
            return true;
        }
        else {
        }
    }
    else {
    }
    return false;
}

bool libAIAI_gf_HeroAIHumanAllyNearby (int lp_trigPlayer) {
    // Variable Declarations
    fixed lv_time;

    // Variable Initialization

    // Implementation
    if ((libAIAI_gf_HeroAITeamHasHumanPlayers(libGame_gv_players[lp_trigPlayer].lv_faction) == false)) {
        return false;
    }
    else {
    }
    libAIAI_gf_HeroAIEval(lp_trigPlayer);
    return libAIAI_gv_aIHeroes[lp_trigPlayer].lv_humanAllyHeroNearby;
}

int libAIAI_gf_HeroAINumberofEnemyHeroesNearLocation (int lp_trigPlayer, point lp_location, fixed lp_range) {
    // Variable Declarations
    region lv_enemyRegion;
    unitgroup lv_enemyHeroes;

    // Variable Initialization
    lv_enemyHeroes = UnitGroupEmpty();

    // Implementation
    lv_enemyRegion = RegionEmpty();
    RegionAddRegion(lv_enemyRegion, RegionCircle(lp_location, lp_range));
    lv_enemyHeroes = UnitGroupAlliance(lp_trigPlayer, c_unitAllianceEnemy, lv_enemyRegion, UnitFilter((1 << c_targetFilterHeroic), 0, (1 << c_targetFilterLight) | (1 << c_targetFilterMassive) | (1 << c_targetFilterMissile) | (1 << c_targetFilterItem), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    return UnitGroupCount(lv_enemyHeroes, c_unitCountAlive);
}

unit libAIAI_gf_HeroAIGetRandomAllyHeroInBattle (int lp_trigPlayer, fixed lp_range) {
    int auto22EF4206_ae;

    // Variable Declarations
    int lv_playerIndex;
    fixed lv_heroHealth;
    fixed lv_lowestHeroHealth;
    unit lv_bestHero;

    // Variable Initialization
    lv_lowestHeroHealth = 9999.0;

    // Implementation
    auto22EF4206_ae = libCore_gv_bALMaxPlayers;
    lv_playerIndex = 1;
    for ( ; lv_playerIndex <= auto22EF4206_ae ; lv_playerIndex += 1 ) {
        if ((lv_playerIndex != lp_trigPlayer) && (libAIAI_gf_HeroAIIsPlayerActive(lv_playerIndex, 0) == true) && (libGame_gv_players[lv_playerIndex].lv_faction == libGame_gv_players[lp_trigPlayer].lv_faction) && (DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit)) < lp_range)) {
            libAIAI_gf_HeroAIEval(lv_playerIndex);
            lv_heroHealth = UnitGetPropertyFixed(libGame_gv_players[lv_playerIndex].lv_heroUnit, c_unitPropLifePercent, c_unitPropCurrent);
            if (((libGame_gv_players[lv_playerIndex].lv_isDead == true) || (libAIAI_gv_aIHeroes[lv_playerIndex].lv_enemyHeroEval == 0.0) || (libAIAI_gf_HeroAIHeroHasBeenAttackedRecently(lv_playerIndex, 2.0) == false) || (lv_heroHealth > 80.0))) {
                continue;
            }
            else {
            }
            if ((PointPathingIsConnected(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), UnitGetPosition(libGame_gv_players[lv_playerIndex].lv_heroUnit)) == false)) {
                continue;
            }
            else {
            }
            if ((lv_heroHealth < lv_lowestHeroHealth)) {
                lv_lowestHeroHealth = lv_heroHealth;
                lv_bestHero = libGame_gv_players[lv_playerIndex].lv_heroUnit;
            }
            else {
            }
        }
        else {
        }
    }
    return lv_bestHero;
}

point libAIAI_gf_HeroAIGetRandomContentionPoint (int lp_trigPlayer, fixed lp_range) {
    int autoCD2FBA0E_ae;
    int autoCD2FBA0E_ai;

    // Variable Declarations
    int lv_teamIndex;
    int lv_laneIndex;
    int lv_numberOfCandidatePoints;
    point[libGame_gv_laneMaxCount + 1] lv_candidatePoints;
    point lv_contentionPoint;

    // Variable Initialization

    // Implementation
    lv_teamIndex = libAIAI_gf_HeroAIGetAllyTeamIndex(lp_trigPlayer);
    autoCD2FBA0E_ae = libGame_gv_laneCount;
    autoCD2FBA0E_ai = 1;
    lv_laneIndex = 1;
    for ( ; ( (autoCD2FBA0E_ai >= 0 && lv_laneIndex <= autoCD2FBA0E_ae) || (autoCD2FBA0E_ai <= 0 && lv_laneIndex >= autoCD2FBA0E_ae) ) ; lv_laneIndex += autoCD2FBA0E_ai ) {
        lv_contentionPoint = libAIAI_gv_heroAITeamData[lv_teamIndex].lv_laneData[lv_laneIndex].lv_contentionPoint;
        if ((DistanceBetweenPoints(UnitGetPosition(libGame_gv_players[lp_trigPlayer].lv_heroUnit), lv_contentionPoint) > lp_range)) {
            continue;
        }
        else {
        }
        lv_numberOfCandidatePoints += 1;
        lv_candidatePoints[lv_numberOfCandidatePoints] = lv_contentionPoint;
    }
    if ((lv_numberOfCandidatePoints > 0)) {
        return lv_candidatePoints[RandomInt(1, lv_numberOfCandidatePoints)];
    }
    else {
        return null;
    }
}

void libAIAI_gf_HeroAIUpdateAIStatus (int lp_trigPlayer) {
    // Variable Declarations
    int lv_objective;
    int lv_priority;
    text lv_botStatus;

    // Variable Initialization

    // Implementation
    if ((libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botStatusLabel == c_invalidDialogControlId)) {
        return ;
    }
    else {
    }
    if ((libAIAI_gv_heroAIDisplayAIStatus == true) && (libAIAI_gf_HeroAIIsPlayerActive(lp_trigPlayer, 2) == true)) {
        if ((libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState == 0)) {
            lv_botStatus = StringToText("Disabled");
        }
        else {
            lv_objective = libAIAI_gf_HeroAIGetCurrentObjective(lp_trigPlayer);
            lv_priority = libAIAI_gf_HeroAIGetCurrentPriority(lp_trigPlayer);
            lv_botStatus = (lv_botStatus + StringExternal("Param/Value/lib_AIAI_E8E2A23F"));
            lv_botStatus = (lv_botStatus + StringToText(libAIAI_ge_HeroAIStates_Ident(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_heroState)));
            lv_botStatus = (lv_botStatus + StringExternal("Param/Value/lib_AIAI_63995259"));
            lv_botStatus = (lv_botStatus + StringToText(libAIAI_ge_HeroAIObjective_Ident(lv_objective)));
            lv_botStatus = (lv_botStatus + StringExternal("Param/Value/lib_AIAI_B12155A8"));
            lv_botStatus = (lv_botStatus + IntToText((lv_priority)));
            lv_botStatus = (lv_botStatus + StringExternal("Param/Value/lib_AIAI_921A46FA"));
            lv_botStatus = (lv_botStatus + StringToText(libAIAI_ge_HeroAIPriority_Ident(lv_priority)));
            lv_botStatus = (lv_botStatus + StringExternal("Param/Value/lib_AIAI_85166516"));
            lv_botStatus = (lv_botStatus + StringToText(libAIAI_ge_HeroAIDifficulty_Ident(libAIAI_gv_aIHeroes[lp_trigPlayer].lv_difficulty)));
        }
        TextExpressionSetToken("Param/Expression/lib_AIAI_474E96A8", "A", libAIAI_gf_HeroAIDifficultyDisplayText(lp_trigPlayer));
        libNtve_gf_SetDialogItemText(libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botDifficultyLabel, TextExpressionAssemble("Param/Expression/lib_AIAI_474E96A8"), PlayerGroupAll());
        DialogControlSetVisible(libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botDifficultyLabel, PlayerGroupAll(), true);
        DialogControlSetVisible(libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botStatusLabel, PlayerGroupAll(), true);
        libNtve_gf_SetDialogItemText(libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botStatusLabel, lv_botStatus, PlayerGroupAll());
    }
    else {
        DialogControlSetVisible(libUIUI_gv_uIHeroStatusFrames[lp_trigPlayer].lv_botStatusLabel, PlayerGroupAll(), false);
    }
}

fixed libAIAI_gf_AIGetActiveWeaponRange (unit lp_unit) {
    int autoEDA1BD1C_ae;
    int autoEDA1BD1C_ai;

    // Variable Declarations
    fixed lv_bestRange;
    int lv_weaponIndex;

    // Variable Initialization

    // Implementation
    autoEDA1BD1C_ae = UnitWeaponCount(lp_unit);
    autoEDA1BD1C_ai = 1;
    lv_weaponIndex = 1;
    for ( ; ( (autoEDA1BD1C_ai >= 0 && lv_weaponIndex <= autoEDA1BD1C_ae) || (autoEDA1BD1C_ai <= 0 && lv_weaponIndex >= autoEDA1BD1C_ae) ) ; lv_weaponIndex += autoEDA1BD1C_ai ) {
        if ((UnitWeaponIsEnabled(lp_unit, lv_weaponIndex) == true) && (UnitWeaponRange(lp_unit, lv_weaponIndex) > lv_bestRange)) {
            lv_bestRange = UnitWeaponRange(lp_unit, lv_weaponIndex);
        }
        else {
        }
    }
    return lv_bestRange;
}

fixed libAIAI_gf_AIGetAnyWeaponRangeIncludesNonActive (unit lp_unit) {
    int auto4040C6FA_ae;
    int auto4040C6FA_ai;

    // Variable Declarations
    fixed lv_bestRange;
    int lv_weaponIndex;

    // Variable Initialization

    // Implementation
    auto4040C6FA_ae = UnitWeaponCount(lp_unit);
    auto4040C6FA_ai = 1;
    lv_weaponIndex = 1;
    for ( ; ( (auto4040C6FA_ai >= 0 && lv_weaponIndex <= auto4040C6FA_ae) || (auto4040C6FA_ai <= 0 && lv_weaponIndex >= auto4040C6FA_ae) ) ; lv_weaponIndex += auto4040C6FA_ai ) {
        if ((UnitWeaponRange(lp_unit, lv_weaponIndex) > lv_bestRange)) {
            lv_bestRange = UnitWeaponRange(lp_unit, lv_weaponIndex);
        }
        else {
        }
    }
    return lv_bestRange;
}

fixed libAIAI_gf_AIGetClosestLanePosition (int lp_laneIndex, point lp_point) {
    // Variable Declarations
    int lv_closestIndex;
    int lv_secondaryIndex;
    point lv_closestPoint;

    // Variable Initialization

    // Implementation
    libGame_gf_CalculateClosestLaneDataForLane(lp_point, lp_laneIndex);
    lv_closestIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestIndex;
    lv_secondaryIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_secondaryIndex;
    lv_closestPoint = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestPoint;
    return AILaneWaypointConvertPointToWaydist(lp_laneIndex, lv_closestIndex, lv_secondaryIndex, lv_closestPoint);
}

fixed libAIAI_gf_AIGetLaneOffsetOfPoint (int lp_laneIndex, point lp_testPoint) {
    // Variable Declarations
    int lv_nextIndex;
    int lv_previousIndex;
    point lv_nextPoint;
    point lv_previousPoint;
    point lv_dir;
    point lv_normal;
    point lv_relativePoint;

    // Variable Initialization

    // Implementation
    libGame_gf_CalculateClosestLaneDataForLane(lp_testPoint, lp_laneIndex);
    if ((libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestIndex < libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_secondaryIndex)) {
        lv_previousIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestIndex;
        lv_nextIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_secondaryIndex;
    }
    else {
        lv_previousIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_secondaryIndex;
        lv_nextIndex = libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestIndex;
    }
    lv_nextPoint = libGame_gv_laneData[lp_laneIndex].lv_waypoints[lv_nextIndex];
    lv_previousPoint = libGame_gv_laneData[lp_laneIndex].lv_waypoints[lv_previousIndex];
    lv_dir = AIGetDirection(lv_previousPoint, lv_nextPoint);
    lv_normal = Point(PointGetY(lv_dir), (PointGetX(lv_dir) * -1.0));
    lv_relativePoint = AIGetDirection(lv_previousPoint, lp_testPoint);
    if ((((PointGetX(lv_relativePoint) * PointGetX(lv_normal)) + (PointGetY(lv_relativePoint) * PointGetY(lv_normal))) > 0.0)) {
        return libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestDist;
    }
    else {
        return (-1.0 * libGame_gv_closestLaneData.lv_laneData[lp_laneIndex].lv_closestDist);
    }
}

fixed libAIAI_gf_AIAdvanceLanePosition (int lp_faction, int lp_laneIndex, fixed lp_lanePosition, fixed lp_distance) {
    // Implementation
    if ((lp_faction == 0)) {
        return libAIAI_gf_AIMoveAlongLane(lp_laneIndex, lp_lanePosition, lp_distance);
    }
    else {
        return libAIAI_gf_AIMoveAlongLane(lp_laneIndex, lp_lanePosition, (lp_distance * -1.0));
    }
}

fixed libAIAI_gf_AIRetreatLanePosition (int lp_faction, int lp_laneIndex, fixed lp_lanePosition, fixed lp_distance) {
    // Implementation
    if ((lp_faction == 0)) {
        return libAIAI_gf_AIMoveAlongLane(lp_laneIndex, lp_lanePosition, (lp_distance * -1.0));
    }
    else {
        return libAIAI_gf_AIMoveAlongLane(lp_laneIndex, lp_lanePosition, lp_distance);
    }
}

fixed libAIAI_gf_AIMoveAlongLane (int lp_laneIndex, fixed lp_lanePosition, fixed lp_distance) {
    // Variable Declarations
    fixed lv_distanceLeftToMove;
    point lv_currentPosition;
    int lv_nextWaypoint;
    int lv_waypointAdvance;
    point lv_nextWaypointPosition;
    fixed lv_distanceToNextWaypoint;
    point lv_direction;
    int lv_finalLanePosition;

    // Variable Initialization

    // Implementation
    lv_distanceLeftToMove = AbsF(lp_distance);
    lv_currentPosition = AILaneWaypointConvertWaydistOffsetToPoint(lp_laneIndex, lp_lanePosition, 0.0);
    if ((lp_distance > 0.0)) {
        lv_nextWaypoint = CeilingI(lp_lanePosition);
        lv_waypointAdvance = 1;
    }
    else {
        lv_nextWaypoint = FloorI(lp_lanePosition);
        lv_waypointAdvance = -1;
    }
    while ((lv_distanceLeftToMove > 0.0)) {
        lv_nextWaypointPosition = libGame_gv_laneData[lp_laneIndex].lv_waypoints[lv_nextWaypoint];
        lv_distanceToNextWaypoint = DistanceBetweenPoints(lv_currentPosition, lv_nextWaypointPosition);
        if ((lv_distanceLeftToMove > lv_distanceToNextWaypoint)) {
            lv_currentPosition = lv_nextWaypointPosition;
            lv_distanceLeftToMove -= lv_distanceToNextWaypoint;
            lv_nextWaypoint += lv_waypointAdvance;
            if (((lv_nextWaypoint < 1) || (lv_nextWaypoint > libGame_gv_laneData[lp_laneIndex].lv_waypointCount))) {
                break;
            }
            else {
            }
        }
        else {
            lv_direction = AIGetDirection(lv_currentPosition, lv_nextWaypointPosition);
            lv_currentPosition = libCore_gf_AdvancePointinDirection(lv_currentPosition, lv_direction, lv_distanceLeftToMove);
            lv_distanceLeftToMove = 0.0;
        }
    }
    return libAIAI_gf_AIGetClosestLanePosition(lp_laneIndex, lv_currentPosition);
}

// Triggers
//--------------------------------------------------------------------------------------------------
// Trigger: #Include AI
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_IncludeAI_Func (bool testConds, bool runActions) {
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_IncludeAI_Init () {
    libAIAI_gt_IncludeAI = TriggerCreate("libAIAI_gt_IncludeAI_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: MinionAI - AI Routine
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_MinionAIAIRoutine_Func (bool testConds, bool runActions) {
    int autoE5BAC9A3_ae;
    int autoE5BAC9A3_ai;

    // Variable Declarations
    int lv_firstMinionIndex;
    int lv_minionIndex;
    int lv_oldState;
    int lv_newState;
    order lv_minionOrder;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_firstMinionIndex = ModI(FixedToInt((GameGetMissionTime() * 16.0)), libAIAI_gv_aIWaveIndexMod);
    autoE5BAC9A3_ae = libAIAI_gv_minionAIActiveMinionsUpperBound;
    autoE5BAC9A3_ai = libAIAI_gv_aIWaveIndexMod;
    lv_minionIndex = lv_firstMinionIndex;
    for ( ; ( (autoE5BAC9A3_ai >= 0 && lv_minionIndex <= autoE5BAC9A3_ae) || (autoE5BAC9A3_ai <= 0 && lv_minionIndex >= autoE5BAC9A3_ae) ) ; lv_minionIndex += autoE5BAC9A3_ai ) {
        if ((libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_isAlive == true) && (UnitIsValid(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit) == true) && (UnitTestState(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit, c_unitStateMoveSuppressed) == false)) {
            lv_minionOrder = UnitOrder(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit, 0);
            if ((lv_minionOrder != null) && ((OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("UnderworldBossRoots", 0)) || (OrderGetAbilityCommand(lv_minionOrder) == AbilityCommand("UnderworldBossStun", 0)))) {
                continue;
            }
            else {
            }
            libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_unitPosition = UnitGetPosition(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit);
            lv_oldState = libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state;
            if ((libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_useSpecialOgreKingLogic == true)) {
                lv_newState = libAIAI_gf_MinionAIDetermineStateUsingOgreKingLogic(lv_minionIndex, lv_oldState);
            }
            else {
                lv_newState = libAIAI_gf_MinionAIDetermineState(lv_minionIndex, lv_oldState);
            }
            if (((UnitOrderCount(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_minionUnit) == 0) || (libAIAI_gf_MinionAIAttackingWrongTarget(lv_minionIndex) == true))) {
                libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_forceStateTransition = true;
            }
            else {
            }
            if (((lv_oldState != lv_newState) || (libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_forceStateTransition == true))) {
                libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_state = lv_newState;
                libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_forceStateTransition = false;
                libAIAI_gf_MinionAIUpdateBattleStandardDataForMinion(lv_minionIndex);
                libAIAI_gf_MinionAITransitionMinionIntoState(lv_minionIndex, lv_newState);
            }
            else {
            }
            if (((DistanceBetweenPoints(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_unitPosition, libAIAI_gf_MinionAIGetNextWaypointForMinion(lv_minionIndex)) <= libAIAI_gv_aIMinionWaypointAdvanceDistance) || (libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_battleStandardDistancePercentage > 1.0))) {
                if ((libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_aggressiveLeashing == true) && (DistanceBetweenPoints(libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_unitPosition, libAIAI_gf_MinionAIGetNextWaypointForMinion(lv_minionIndex)) <= libAIAI_gv_aIMinionWaypointAdvanceDistance)) {
                    libAIAI_gv_minionAIActiveMinions[lv_minionIndex].lv_aggressiveLeashing = false;
                }
                else {
                }
                libAIAI_gf_MinionAIAdvanceMinionToNextWaypoint(lv_minionIndex);
                libAIAI_gf_MinionAITransitionMinionIntoState(lv_minionIndex, lv_newState);
            }
            else {
            }
        }
        else {
        }
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_MinionAIAIRoutine_Init () {
    libAIAI_gt_MinionAIAIRoutine = TriggerCreate("libAIAI_gt_MinionAIAIRoutine_Func");
    TriggerEnable(libAIAI_gt_MinionAIAIRoutine, false);
    TriggerAddEventTimePeriodic(libAIAI_gt_MinionAIAIRoutine, 0.0625, c_timeGame);
}

//--------------------------------------------------------------------------------------------------
// Trigger: MinionAI - Gate Dies
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_MinionAIGateDies_Func (bool testConds, bool runActions) {
    // Conditions
    if (testConds) {
        if (!((UnitTypeTestAttribute(UnitGetType(EventUnit()), c_unitAttributeStructure) == true))) {
            return false;
        }

        if (!((libGame_gf_TownGetTownForUnit(EventUnit()) > 0))) {
            return false;
        }

        if (!((libGame_gf_TownGetTownStructurePresetFromUnitID(UnitGetType(EventUnit())) == 3))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gf_MinionAIUpdateLaneInfo();
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_MinionAIGateDies_Init () {
    libAIAI_gt_MinionAIGateDies = TriggerCreate("libAIAI_gt_MinionAIGateDies_Func");
    TriggerEnable(libAIAI_gt_MinionAIGateDies, false);
    TriggerAddEventUnitDied(libAIAI_gt_MinionAIGateDies, null);
}

//--------------------------------------------------------------------------------------------------
// Trigger: MinionAI - Town Data Initialized
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_MinionAITownDataInitialized_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gf_MinionAIUpdateLaneInfo();
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_MinionAITownDataInitialized_Init () {
    libAIAI_gt_MinionAITownDataInitialized = TriggerCreate("libAIAI_gt_MinionAITownDataInitialized_Func");
    TriggerEnable(libAIAI_gt_MinionAITownDataInitialized, false);
    libGame_gf_TownDataInitialized(libAIAI_gt_MinionAITownDataInitialized);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Tower - AI Routine
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_TowerAIRoutine_Func (bool testConds, bool runActions) {
    int autoAA64C2F1_ae;
    unitgroup autoC4927000_g;
    int autoC4927000_u;
    unitgroup auto01FB4449_g;
    int auto01FB4449_u;

    // Variable Declarations
    int lv_i;
    unit lv_u;
    int lv_towerIndex;
    unit lv_towerIndexUnit;
    int lv_currentGameLoopMod;
    unit lv_newTarget;
    fixed lv_rangeToTarget;
    fixed lv_scanRange;
    point lv_towerPosition;
    unitgroup lv_scanGroup;
    unitgroup lv_heroesInRange;
    unitgroup lv_minionsInRange;
    unitgroup lv_summonedUnitsInRange;
    unit lv_summonedUnit;
    unitgroup lv_necromancerSkeletonUnitsInRange;
    unit lv_heroUnit;

    // Variable Initialization
    lv_scanGroup = UnitGroupEmpty();
    lv_heroesInRange = UnitGroupEmpty();
    lv_minionsInRange = UnitGroupEmpty();
    lv_summonedUnitsInRange = UnitGroupEmpty();
    lv_necromancerSkeletonUnitsInRange = UnitGroupEmpty();

    // Actions
    if (!runActions) {
        return true;
    }

    lv_currentGameLoopMod = ModI(FixedToInt((GameGetMissionTime() * 16.0)), libAIAI_gv_aITowerIndexMod);
    autoAA64C2F1_ae = libAIAI_gv_towerTowerCount;
    lv_towerIndex = 1;
    for ( ; lv_towerIndex <= autoAA64C2F1_ae ; lv_towerIndex += 1 ) {
        lv_towerIndexUnit = libAIAI_gv_towerTowers[lv_towerIndex].lv_towerUnit;
        if ((UnitIsAlive(lv_towerIndexUnit) == true) && (UnitBehaviorCount(lv_towerIndexUnit, "TownCannonTowerInvulnerable") == 0)) {
            if ((libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit != null)) {
                if (((UnitIsAlive(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit) == false) || (UnitFilterMatch(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit, UnitGetOwner(lv_towerIndexUnit), libAIAI_gv_uF_TowerAI_Required_Invulnerable) == true) || (UnitFilterMatch(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit, UnitGetOwner(lv_towerIndexUnit), libAIAI_gv_uF_TowerAI_Required_Stasis) == true) || (UnitHasBehavior2(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit, "IgnoredByTowerAI") == true))) {
                    libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = null;
                    UnitIssueOrder(lv_towerIndexUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
                }
                else {
                    lv_rangeToTarget = DistanceBetweenPoints(UnitGetPosition(lv_towerIndexUnit), UnitGetPosition(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit));
                    lv_rangeToTarget -= UnitTypeGetProperty(UnitGetType(lv_towerIndexUnit), c_unitPropRadius);
                    lv_rangeToTarget -= UnitTypeGetProperty(UnitGetType(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit), c_unitPropRadius);
                    if ((lv_rangeToTarget > libAIAI_gv_aITowerRange)) {
                        libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = null;
                        UnitIssueOrder(lv_towerIndexUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
                    }
                    else {
                    }
                }
            }
            else {
            }
            if ((lv_currentGameLoopMod == ModI(lv_towerIndex, libAIAI_gv_aITowerIndexMod)) && (UnitWeaponPeriodRemaining(lv_towerIndexUnit, 1) <= 2.0)) {
                if (((libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit == null) || (UnitTypeTestAttribute(UnitGetType(libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit), c_unitAttributeHeroic) == true))) {
                    lv_scanRange = (libAIAI_gv_aITowerRange + UnitTypeGetProperty(UnitGetType(lv_towerIndexUnit), c_unitPropRadius));
                    lv_towerPosition = UnitGetPosition(lv_towerIndexUnit);
                    lv_scanGroup = UnitGroupSearch(null, UnitGetOwner(lv_towerIndexUnit), lv_towerPosition, lv_scanRange, libAIAI_gv_uF_TowerAI_Scan_Group, 0);
                    if ((UnitGroupCount(lv_scanGroup, c_unitCountAlive) > 0)) {
                        lv_heroesInRange = UnitGroupFilter(null, c_playerAny, lv_scanGroup, libAIAI_gv_uF_TowerAI_Required_Heroic, 0);
                        autoC4927000_g = lv_heroesInRange;
                        autoC4927000_u = 1;
                        for ( ; autoC4927000_u <= UnitGroupCount(autoC4927000_g, c_unitCountAll) ; autoC4927000_u += BoolToInt(lv_heroUnit == UnitGroupUnit(autoC4927000_g, autoC4927000_u)) ) {
                            lv_heroUnit = UnitGroupUnit(autoC4927000_g, autoC4927000_u);
                            if ((UnitHasBehavior2(lv_heroUnit, "IgnoredByTowerAI") == true)) {
                                UnitGroupRemove(lv_heroesInRange, lv_heroUnit);
                            }
                            else {
                            }
                        }
                        if ((UnitHasBehavior2(lv_towerIndexUnit, "ItemTauntDebuff") == true) && (UnitGroupHasUnit(lv_heroesInRange, UnitBehaviorEffectUnit(lv_towerIndexUnit, "ItemTauntDebuff", c_effectUnitSource, 0)) == true)) {
                            UnitIssueOrder(lv_towerIndexUnit, OrderTargetingUnit(AbilityCommand("attack", 0), UnitBehaviorEffectUnit(lv_towerIndexUnit, "ItemTauntDebuff", c_effectUnitSource, 0)), c_orderQueueReplace);
                        }
                        else {
                            lv_necromancerSkeletonUnitsInRange = UnitGroupFilter("NecromancerMinionSkeleton", c_playerAny, lv_scanGroup, libAIAI_gv_uF_TowerAI_Scan_Group, 0);
                            if ((UnitGroupCount(lv_necromancerSkeletonUnitsInRange, c_unitCountAlive) > 0)) {
                                libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = UnitGroupClosestToPoint(lv_necromancerSkeletonUnitsInRange, lv_towerPosition);
                            }
                            else {
                                lv_minionsInRange = UnitGroupFilter(null, c_playerAny, lv_scanGroup, libAIAI_gv_uF_TowerAI_Required_Biological, 0);
                                if ((UnitGroupCount(lv_minionsInRange, c_unitCountAlive) > 0)) {
                                    libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = UnitGroupClosestToPoint(lv_minionsInRange, lv_towerPosition);
                                }
                                else {
                                    lv_summonedUnitsInRange = UnitGroupFilter(null, c_playerAny, lv_scanGroup, libAIAI_gv_uF_TowerAI_Required_Summoned, 0);
                                    auto01FB4449_g = lv_summonedUnitsInRange;
                                    auto01FB4449_u = 1;
                                    for ( ; auto01FB4449_u <= UnitGroupCount(auto01FB4449_g, c_unitCountAll) ; auto01FB4449_u += BoolToInt(lv_summonedUnit == UnitGroupUnit(auto01FB4449_g, auto01FB4449_u)) ) {
                                        lv_summonedUnit = UnitGroupUnit(auto01FB4449_g, auto01FB4449_u);
                                        if ((UnitHasBehavior2(lv_summonedUnit, "IgnoredByTowerAI") == true)) {
                                            UnitGroupRemove(lv_summonedUnitsInRange, lv_summonedUnit);
                                        }
                                        else {
                                        }
                                    }
                                    if ((UnitGroupCount(lv_summonedUnitsInRange, c_unitCountAlive) > 0)) {
                                        libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = UnitGroupClosestToPoint(lv_summonedUnitsInRange, lv_towerPosition);
                                    }
                                    else {
                                        if ((libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit == null) && (UnitGroupCount(lv_heroesInRange, c_unitCountAlive) > 0)) {
                                            libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit = UnitGroupClosestToPoint(lv_heroesInRange, lv_towerPosition);
                                        }
                                        else {
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else {
                    }
                }
                else {
                }
                if ((libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit != null)) {
                    UnitIssueOrder(lv_towerIndexUnit, OrderTargetingUnit(AbilityCommand("attack", 0), libAIAI_gv_towerTowers[lv_towerIndex].lv_targetUnit), c_orderQueueReplace);
                }
                else {
                }
            }
            else {
            }
        }
        else {
            UnitIssueOrder(lv_towerIndexUnit, Order(AbilityCommand("stop", 0)), c_orderQueueReplace);
            UnitIssueOrder(lv_towerIndexUnit, Order(AbilityCommand("TowerDeadMorph", 0)), c_orderQueueReplace);
            if ((lv_towerIndex == libAIAI_gv_towerTowerCount)) {
                libAIAI_gv_towerTowerCount -= 1;
            }
            else {
            }
        }
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_TowerAIRoutine_Init () {
    libAIAI_gt_TowerAIRoutine = TriggerCreate("libAIAI_gt_TowerAIRoutine_Func");
    TriggerEnable(libAIAI_gt_TowerAIRoutine, false);
    TriggerAddEventTimePeriodic(libAIAI_gt_TowerAIRoutine, 0.0625, c_timeGame);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Initialize Tower AI System
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_InitializeTowerAISystem_Func (bool testConds, bool runActions) {
    unitgroup auto3512F4E7_g;
    int auto3512F4E7_u;
    unitgroup autoFEA14C50_g;
    int autoFEA14C50_u;
    unitgroup auto77A004BD_g;
    int auto77A004BD_u;
    unitgroup auto6C543484_g;
    int auto6C543484_u;
    unitgroup auto8C452DFB_g;
    int auto8C452DFB_u;
    unitgroup auto34B4716B_g;
    int auto34B4716B_u;
    unitgroup auto52D1BB47_g;
    int auto52D1BB47_u;
    unitgroup autoAFFCD549_g;
    int autoAFFCD549_u;
    int autoAEB5C0D6_ae;
    int autoAEB5C0D6_ai;

    // Variable Declarations
    int lv_laneIndex;
    int lv_structureIndex;
    unit lv_structureUnit;
    string lv_structureUnitType;
    int lv_structureLevel;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_towerTowerCount = 0;
    libAIAI_gv_towerTowerCount += 1;
    libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = libGame_gv_teams[libGame_gv_teamOrderIndex_C].lv_core;
    libAIAI_gv_towerTowerCount += 1;
    libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = libGame_gv_teams[libGame_gv_teamChaosIndex_C].lv_core;
    auto3512F4E7_g = UnitGroup("TownCannonTowerL3Standalone", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto3512F4E7_u = 1;
    for ( ; auto3512F4E7_u <= UnitGroupCount(auto3512F4E7_g, c_unitCountAll) ; auto3512F4E7_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto3512F4E7_g, auto3512F4E7_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto3512F4E7_g, auto3512F4E7_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    autoFEA14C50_g = UnitGroup("TownCannonTowerL2Standalone", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    autoFEA14C50_u = 1;
    for ( ; autoFEA14C50_u <= UnitGroupCount(autoFEA14C50_g, c_unitCountAll) ; autoFEA14C50_u += BoolToInt(lv_structureUnit == UnitGroupUnit(autoFEA14C50_g, autoFEA14C50_u)) ) {
        lv_structureUnit = UnitGroupUnit(autoFEA14C50_g, autoFEA14C50_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    auto77A004BD_g = UnitGroup("TownTownHallL3", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto77A004BD_u = 1;
    for ( ; auto77A004BD_u <= UnitGroupCount(auto77A004BD_g, c_unitCountAll) ; auto77A004BD_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto77A004BD_g, auto77A004BD_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto77A004BD_g, auto77A004BD_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    auto6C543484_g = UnitGroup("TownCannonTowerL3", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto6C543484_u = 1;
    for ( ; auto6C543484_u <= UnitGroupCount(auto6C543484_g, c_unitCountAll) ; auto6C543484_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto6C543484_g, auto6C543484_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto6C543484_g, auto6C543484_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    auto8C452DFB_g = UnitGroup("TownTownHallL2", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto8C452DFB_u = 1;
    for ( ; auto8C452DFB_u <= UnitGroupCount(auto8C452DFB_g, c_unitCountAll) ; auto8C452DFB_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto8C452DFB_g, auto8C452DFB_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto8C452DFB_g, auto8C452DFB_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    auto34B4716B_g = UnitGroup("TownCannonTowerL2", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto34B4716B_u = 1;
    for ( ; auto34B4716B_u <= UnitGroupCount(auto34B4716B_g, c_unitCountAll) ; auto34B4716B_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto34B4716B_g, auto34B4716B_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto34B4716B_g, auto34B4716B_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    auto52D1BB47_g = UnitGroup("TownTownHallL1", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    auto52D1BB47_u = 1;
    for ( ; auto52D1BB47_u <= UnitGroupCount(auto52D1BB47_g, c_unitCountAll) ; auto52D1BB47_u += BoolToInt(lv_structureUnit == UnitGroupUnit(auto52D1BB47_g, auto52D1BB47_u)) ) {
        lv_structureUnit = UnitGroupUnit(auto52D1BB47_g, auto52D1BB47_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    autoAFFCD549_g = UnitGroup("TownCannonTower", c_playerAny, RegionEntireMap(), UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    autoAFFCD549_u = 1;
    for ( ; autoAFFCD549_u <= UnitGroupCount(autoAFFCD549_g, c_unitCountAll) ; autoAFFCD549_u += BoolToInt(lv_structureUnit == UnitGroupUnit(autoAFFCD549_g, autoAFFCD549_u)) ) {
        lv_structureUnit = UnitGroupUnit(autoAFFCD549_g, autoAFFCD549_u);
        libAIAI_gv_towerTowerCount += 1;
        libAIAI_gv_towerTowers[libAIAI_gv_towerTowerCount].lv_towerUnit = lv_structureUnit;
    }
    autoAEB5C0D6_ae = libAIAI_gv_towerTowerCount;
    autoAEB5C0D6_ai = 1;
    lv_structureIndex = 1;
    for ( ; ( (autoAEB5C0D6_ai >= 0 && lv_structureIndex <= autoAEB5C0D6_ae) || (autoAEB5C0D6_ai <= 0 && lv_structureIndex >= autoAEB5C0D6_ae) ) ; lv_structureIndex += autoAEB5C0D6_ai ) {
        UnitStatusBarOverride(libAIAI_gv_towerTowers[lv_structureIndex].lv_towerUnit, c_unitStatusGroupAll);
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_InitializeTowerAISystem_Init () {
    libAIAI_gt_InitializeTowerAISystem = TriggerCreate("libAIAI_gt_InitializeTowerAISystem_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: DefenderAI - Creeps Attacked
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_DefenderAICreepsAttacked_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_defenderAIIndex;

    // Variable Initialization

    // Conditions
    if (testConds) {
        if (!((EventUnitDamageSourcePlayer() > 0))) {
            return false;
        }

        if (!((EventUnitDamageSourcePlayer() <= libCore_gv_bALMaxPlayers))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    lv_defenderAIIndex = libAIAI_gf_DefenderAIIndexOfUnit(EventUnit());
    if ((lv_defenderAIIndex > 0)) {
        libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_playerIsThreat[EventUnitDamageSourcePlayer()] = true;
        if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_state == 0)) {
            libAIAI_gf_DefenderAITransitionDefenderAIIntoState(lv_defenderAIIndex, 1);
        }
        else if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_state == 2)) {
            libAIAI_gf_DefenderAIUpdateValidTargetList(lv_defenderAIIndex);
            if ((UnitGroupCount(libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_validTargets, c_unitCountAlive) > 0)) {
                libAIAI_gf_DefenderAITransitionDefenderAIIntoState(lv_defenderAIIndex, 1);
            }
            else {
            }
        }
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_DefenderAICreepsAttacked_Init () {
    libAIAI_gt_DefenderAICreepsAttacked = TriggerCreate("libAIAI_gt_DefenderAICreepsAttacked_Func");
    TriggerEnable(libAIAI_gt_DefenderAICreepsAttacked, false);
    TriggerAddEventUnitDamaged(libAIAI_gt_DefenderAICreepsAttacked, null, c_unitDamageTypeAny, c_unitDamageEither, null);
}

//--------------------------------------------------------------------------------------------------
// Trigger: DefenderAI - Defender AI Logic
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_DefenderAIDefenderAILogic_Func (bool testConds, bool runActions) {
    int auto12F5795D_ae;
    int auto12F5795D_ai;

    // Variable Declarations
    int lv_firstDefenderAIIndex;
    int lv_defenderAIIndex;
    int lv_creep;
    int lv_oldState;
    int lv_newState;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_firstDefenderAIIndex = ModI(FixedToInt((GameGetMissionTime() * 16.0)), libAIAI_gv_aIDefenderIndexMod);
    auto12F5795D_ae = libAIAI_gv_defenderAIDefenderAIUpperBound;
    auto12F5795D_ai = libAIAI_gv_aIDefenderIndexMod;
    lv_defenderAIIndex = lv_firstDefenderAIIndex;
    for ( ; ( (auto12F5795D_ai >= 0 && lv_defenderAIIndex <= auto12F5795D_ae) || (auto12F5795D_ai <= 0 && lv_defenderAIIndex >= auto12F5795D_ae) ) ; lv_defenderAIIndex += auto12F5795D_ai ) {
        if ((libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_numberOfDefendersAlive == 0)) {
            continue;
        }
        else {
        }
        lv_oldState = libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_state;
        if (((lv_oldState == 1) || ((lv_oldState == 0) && (libAIAI_gv_defenderAI[lv_defenderAIIndex].lv_aggoRegion != null)))) {
            libAIAI_gf_DefenderAIUpdateValidTargetList(lv_defenderAIIndex);
        }
        else {
        }
        lv_newState = libAIAI_gf_DefenderAIDetermineState(lv_defenderAIIndex, lv_oldState);
        if ((lv_oldState != lv_newState)) {
            libAIAI_gf_DefenderAITransitionDefenderAIIntoState(lv_defenderAIIndex, lv_newState);
        }
        else {
        }
        libAIAI_gf_DefenderAIStateLogic(lv_defenderAIIndex);
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_DefenderAIDefenderAILogic_Init () {
    libAIAI_gt_DefenderAIDefenderAILogic = TriggerCreate("libAIAI_gt_DefenderAIDefenderAILogic_Func");
    TriggerEnable(libAIAI_gt_DefenderAIDefenderAILogic, false);
    TriggerAddEventTimePeriodic(libAIAI_gt_DefenderAIDefenderAILogic, 0.0625, c_timeGame);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Initialize Item Data
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIInitializeItemData_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_index;

    // Variable Initialization
    lv_index = 1;

    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentFirstAid";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 10;
    lv_index = (lv_index + 1);
    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentStoneskin";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 10;
    lv_index = (lv_index + 1);
    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentBloodForBlood";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 1;
    lv_index = (lv_index + 1);
    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentDash";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 10;
    lv_index = (lv_index + 1);
    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentDeafeningRoar";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 3;
    lv_index = (lv_index + 1);
    libAIAI_gv_heroAIItemData[lv_index].lv_item = "TalentRewind";
    libAIAI_gv_heroAIItemData[lv_index].lv_itemType = 11;
    lv_index = (lv_index + 1);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIInitializeItemData_Init () {
    libAIAI_gt_HeroAIInitializeItemData = TriggerCreate("libAIAI_gt_HeroAIInitializeItemData_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Initialize Difficulty Level Data
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIInitializeDifficultyLevelData_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_aIHeroAct2StartLevel[1] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[2] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[3] = 7;
    libAIAI_gv_aIHeroAct2StartLevel[4] = 7;
    libAIAI_gv_aIHeroAct2StartLevel[5] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[6] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[7] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[8] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[9] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[10] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[11] = 10;
    libAIAI_gv_aIHeroAct2StartLevel[12] = 10;
    libAIAI_gv_aIHeroAct3StartLevel[1] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[2] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[3] = 8;
    libAIAI_gv_aIHeroAct3StartLevel[4] = 8;
    libAIAI_gv_aIHeroAct3StartLevel[5] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[6] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[7] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[8] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[9] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[10] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[11] = 13;
    libAIAI_gv_aIHeroAct3StartLevel[12] = 13;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[1] = true;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[2] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[3] = true;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[4] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[5] = true;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[6] = true;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[7] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[8] = true;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[9] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[10] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[11] = false;
    libAIAI_gv_aIHeroAvoidTargettingHeroes[12] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[1] = true;
    libAIAI_gv_aIHeroAvoidTargettingFountains[2] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[3] = true;
    libAIAI_gv_aIHeroAvoidTargettingFountains[4] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[5] = true;
    libAIAI_gv_aIHeroAvoidTargettingFountains[6] = true;
    libAIAI_gv_aIHeroAvoidTargettingFountains[7] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[8] = true;
    libAIAI_gv_aIHeroAvoidTargettingFountains[9] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[10] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[11] = false;
    libAIAI_gv_aIHeroAvoidTargettingFountains[12] = false;
    libAIAI_gv_aIHeroEnterTeamFights[1] = false;
    libAIAI_gv_aIHeroEnterTeamFights[2] = false;
    libAIAI_gv_aIHeroEnterTeamFights[3] = false;
    libAIAI_gv_aIHeroEnterTeamFights[4] = true;
    libAIAI_gv_aIHeroEnterTeamFights[5] = false;
    libAIAI_gv_aIHeroEnterTeamFights[6] = false;
    libAIAI_gv_aIHeroEnterTeamFights[7] = true;
    libAIAI_gv_aIHeroEnterTeamFights[8] = true;
    libAIAI_gv_aIHeroEnterTeamFights[9] = true;
    libAIAI_gv_aIHeroEnterTeamFights[10] = true;
    libAIAI_gv_aIHeroEnterTeamFights[11] = true;
    libAIAI_gv_aIHeroEnterTeamFights[12] = true;
    libAIAI_gv_aIHeroSmartLaneTargetting[1] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[2] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[3] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[4] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[5] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[6] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[7] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[8] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[9] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[10] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[11] = false;
    libAIAI_gv_aIHeroSmartLaneTargetting[12] = true;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[1] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[2] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[3] = 2.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[4] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[5] = 2.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[6] = 2.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[7] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[8] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[9] = 10.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[10] = 33.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[11] = 66.0;
    libAIAI_gv_aIHeroChanceToRetaliateWhenAttacked[12] = 100.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[1] = 3.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[2] = 1.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[3] = 3.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[4] = 1.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[5] = 3.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[6] = 3.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[7] = 2.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[8] = 2.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[9] = 2.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[10] = 1.0;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[11] = 0.5;
    libAIAI_gv_aIHeroRetreatWhenAttackedByHeroResponseDelay[12] = 0.25;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[1] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[2] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[3] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[4] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[5] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[6] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[7] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[8] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[9] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[10] = 5.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[11] = 4.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationMelee[12] = 3.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[1] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[2] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[3] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[4] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[5] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[6] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[7] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[8] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[9] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[10] = 8.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[11] = 7.0;
    libAIAI_gv_aIHeroMinionBattleAttackDurationRanged[12] = 6.0;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[1] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[2] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[3] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[4] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[5] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[6] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[7] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[8] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[9] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[10] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[11] = false;
    libAIAI_gv_aIHeroWatchforMissingEnemyHeroes[12] = true;
    libAIAI_gv_aIHeroDodgeAOEAbilities[1] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[2] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[3] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[4] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[5] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[6] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[7] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[8] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[9] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[10] = false;
    libAIAI_gv_aIHeroDodgeAOEAbilities[11] = true;
    libAIAI_gv_aIHeroDodgeAOEAbilities[12] = true;
    libAIAI_gv_aIHeroFocusWeakHeroes[1] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[2] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[3] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[4] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[5] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[6] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[7] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[8] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[9] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[10] = false;
    libAIAI_gv_aIHeroFocusWeakHeroes[11] = true;
    libAIAI_gv_aIHeroFocusWeakHeroes[12] = true;
    libAIAI_gv_aIHeroFocusWeakCore[1] = false;
    libAIAI_gv_aIHeroFocusWeakCore[2] = true;
    libAIAI_gv_aIHeroFocusWeakCore[3] = false;
    libAIAI_gv_aIHeroFocusWeakCore[4] = true;
    libAIAI_gv_aIHeroFocusWeakCore[5] = true;
    libAIAI_gv_aIHeroFocusWeakCore[6] = false;
    libAIAI_gv_aIHeroFocusWeakCore[7] = true;
    libAIAI_gv_aIHeroFocusWeakCore[8] = false;
    libAIAI_gv_aIHeroFocusWeakCore[9] = true;
    libAIAI_gv_aIHeroFocusWeakCore[10] = true;
    libAIAI_gv_aIHeroFocusWeakCore[11] = true;
    libAIAI_gv_aIHeroFocusWeakCore[12] = true;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[1] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[2] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[3] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[4] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[5] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[6] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[7] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[8] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[9] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[10] = false;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[11] = true;
    libAIAI_gv_aIHeroNoticesCloakedHeroes[12] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[1] = false;
    libAIAI_gv_aIHeroPickUpHealthGlobes[2] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[3] = false;
    libAIAI_gv_aIHeroPickUpHealthGlobes[4] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[5] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[6] = false;
    libAIAI_gv_aIHeroPickUpHealthGlobes[7] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[8] = false;
    libAIAI_gv_aIHeroPickUpHealthGlobes[9] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[10] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[11] = true;
    libAIAI_gv_aIHeroPickUpHealthGlobes[12] = true;
    libAIAI_gv_aIHeroUseMoonwells[1] = false;
    libAIAI_gv_aIHeroUseMoonwells[2] = true;
    libAIAI_gv_aIHeroUseMoonwells[3] = false;
    libAIAI_gv_aIHeroUseMoonwells[4] = true;
    libAIAI_gv_aIHeroUseMoonwells[5] = false;
    libAIAI_gv_aIHeroUseMoonwells[6] = false;
    libAIAI_gv_aIHeroUseMoonwells[7] = false;
    libAIAI_gv_aIHeroUseMoonwells[8] = false;
    libAIAI_gv_aIHeroUseMoonwells[9] = false;
    libAIAI_gv_aIHeroUseMoonwells[10] = true;
    libAIAI_gv_aIHeroUseMoonwells[11] = true;
    libAIAI_gv_aIHeroUseMoonwells[12] = true;
    libAIAI_gv_aIHeroUseUltimates[1] = false;
    libAIAI_gv_aIHeroUseUltimates[2] = false;
    libAIAI_gv_aIHeroUseUltimates[3] = false;
    libAIAI_gv_aIHeroUseUltimates[4] = false;
    libAIAI_gv_aIHeroUseUltimates[5] = false;
    libAIAI_gv_aIHeroUseUltimates[6] = false;
    libAIAI_gv_aIHeroUseUltimates[7] = false;
    libAIAI_gv_aIHeroUseUltimates[8] = false;
    libAIAI_gv_aIHeroUseUltimates[9] = false;
    libAIAI_gv_aIHeroUseUltimates[10] = true;
    libAIAI_gv_aIHeroUseUltimates[11] = true;
    libAIAI_gv_aIHeroUseUltimates[12] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[1] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[2] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[3] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[4] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[5] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[6] = false;
    libAIAI_gv_aIHeroPerformTeamStrategies[7] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[8] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[9] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[10] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[11] = true;
    libAIAI_gv_aIHeroPerformTeamStrategies[12] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[1] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[2] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[3] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[4] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[5] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[6] = true;
    libAIAI_gv_aIHeroNeverEnterLateGame[7] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[8] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[9] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[10] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[11] = false;
    libAIAI_gv_aIHeroNeverEnterLateGame[12] = false;
    libAIAI_gv_aIHeroMinSpellFrequency[1] = 15.0;
    libAIAI_gv_aIHeroMinSpellFrequency[2] = 15.0;
    libAIAI_gv_aIHeroMinSpellFrequency[3] = 15.0;
    libAIAI_gv_aIHeroMinSpellFrequency[4] = 10.0;
    libAIAI_gv_aIHeroMinSpellFrequency[5] = 15.0;
    libAIAI_gv_aIHeroMinSpellFrequency[6] = 15.0;
    libAIAI_gv_aIHeroMinSpellFrequency[7] = 10.0;
    libAIAI_gv_aIHeroMinSpellFrequency[8] = 10.0;
    libAIAI_gv_aIHeroMinSpellFrequency[9] = 10.0;
    libAIAI_gv_aIHeroMinSpellFrequency[10] = 4.0;
    libAIAI_gv_aIHeroMinSpellFrequency[11] = 1.0;
    libAIAI_gv_aIHeroMinSpellFrequency[12] = 0.333;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[1] = 3.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[2] = 3.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[3] = 3.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[4] = 1.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[5] = 3.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[6] = 3.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[7] = 1.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[8] = 1.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[9] = 1.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[10] = 0.5;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[11] = 0.0;
    libAIAI_gv_aIHeroMinTeamSpellFrequency[12] = 0.0;
    libAIAI_gv_aIHeroFudgeTarget[1] = 4.0;
    libAIAI_gv_aIHeroFudgeTarget[2] = 2.0;
    libAIAI_gv_aIHeroFudgeTarget[3] = 4.0;
    libAIAI_gv_aIHeroFudgeTarget[4] = 2.0;
    libAIAI_gv_aIHeroFudgeTarget[5] = 4.0;
    libAIAI_gv_aIHeroFudgeTarget[6] = 4.0;
    libAIAI_gv_aIHeroFudgeTarget[7] = 2.0;
    libAIAI_gv_aIHeroFudgeTarget[8] = 3.5;
    libAIAI_gv_aIHeroFudgeTarget[9] = 2.0;
    libAIAI_gv_aIHeroFudgeTarget[10] = 2.5;
    libAIAI_gv_aIHeroFudgeTarget[11] = 1.5;
    libAIAI_gv_aIHeroFudgeTarget[12] = 1.0;
    libAIAI_gv_aIHeroSkillshotMissRate[1] = 90.0;
    libAIAI_gv_aIHeroSkillshotMissRate[2] = 10.0;
    libAIAI_gv_aIHeroSkillshotMissRate[3] = 90.0;
    libAIAI_gv_aIHeroSkillshotMissRate[4] = 30.0;
    libAIAI_gv_aIHeroSkillshotMissRate[5] = 90.0;
    libAIAI_gv_aIHeroSkillshotMissRate[6] = 90.0;
    libAIAI_gv_aIHeroSkillshotMissRate[7] = 50.0;
    libAIAI_gv_aIHeroSkillshotMissRate[8] = 70.0;
    libAIAI_gv_aIHeroSkillshotMissRate[9] = 50.0;
    libAIAI_gv_aIHeroSkillshotMissRate[10] = 35.0;
    libAIAI_gv_aIHeroSkillshotMissRate[11] = 15.0;
    libAIAI_gv_aIHeroSkillshotMissRate[12] = 0.0;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[1] = false;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[2] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[3] = false;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[4] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[5] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[6] = false;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[7] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[8] = false;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[9] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[10] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[11] = true;
    libAIAI_gv_aIHeroLineUpClearShotForSkillShots[12] = true;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[1] = 40.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[2] = 40.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[3] = 40.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[4] = 40.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[5] = 30.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[6] = 30.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[7] = 30.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[8] = 30.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[9] = 30.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[10] = 20.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[11] = 10.0;
    libAIAI_gv_aIHeroPrioritizeHealingHumanAlliesThreshold[12] = 0.0;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[1] = false;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[2] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[3] = false;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[4] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[5] = false;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[6] = false;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[7] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[8] = false;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[9] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[10] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[11] = true;
    libAIAI_gv_aIHeroCastAbilitiesOnWeakHumanHeroes[12] = true;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[1] = 95.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[2] = 25.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[3] = 95.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[4] = 25.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[5] = 95.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[6] = 95.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[7] = 35.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[8] = 35.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[9] = 35.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[10] = 25.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[11] = 15.0;
    libAIAI_gv_aIHeroEnemyNearbyEvalUnderestimatePercent[12] = 5.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[1] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[2] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[3] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[4] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[5] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[6] = 70.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[7] = 35.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[8] = 35.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[9] = 35.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[10] = 0.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[11] = 0.0;
    libAIAI_gv_aIHeroEnemyLaneEvalUnderestimatePercent[12] = 0.0;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[1] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[2] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[3] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[4] = false;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[5] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[6] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[7] = false;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[8] = true;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[9] = false;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[10] = false;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[11] = false;
    libAIAI_gv_aIHeroDefendObjectivesPoorlyAgainstHumans[12] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[1] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[2] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[3] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[4] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[5] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[6] = true;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[7] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[8] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[9] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[10] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[11] = false;
    libAIAI_gv_aIHeroOnlyInitiateEasyCamps[12] = false;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[1] = 0.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[2] = 0.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[3] = 0.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[4] = 0.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[5] = 0.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[6] = 20.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[7] = 20.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[8] = 20.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[9] = 20.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[10] = 30.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[11] = 60.0;
    libAIAI_gv_aIHeroChanceNearbyMinionCamp[12] = 60.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[1] = 0.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[2] = 0.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[3] = 0.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[4] = 0.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[5] = 0.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[6] = 30.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[7] = 30.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[8] = 30.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[9] = 30.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[10] = 60.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[11] = 80.0;
    libAIAI_gv_aIHeroChanceMiddleMinionCamp[12] = 80.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[1] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[2] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[3] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[4] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[5] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[6] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[7] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[8] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[9] = 0.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[10] = 30.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[11] = 80.0;
    libAIAI_gv_aIHeroChanceFarMinionCamp[12] = 80.0;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[1] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[2] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[3] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[4] = true;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[5] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[6] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[7] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[8] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[9] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[10] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[11] = false;
    libAIAI_gv_aIHeroAlwaysWaitAtCampForHumanPlayer[12] = false;
    libAIAI_gv_aIHeroCampWaitTimeout[1] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[2] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[3] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[4] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[5] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[6] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[7] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[8] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[9] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[10] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[11] = 20.0;
    libAIAI_gv_aIHeroCampWaitTimeout[12] = 20.0;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[1] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[2] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[3] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[4] = true;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[5] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[6] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[7] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[8] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[9] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[10] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[11] = false;
    libAIAI_gv_aIHeroLetHumanPlayerCaptureCampBeacon[12] = false;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[1] = 0.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[2] = 0.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[3] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[4] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[5] = 0.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[6] = 0.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[7] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[8] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[9] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[10] = 25.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[11] = 50.0;
    libAIAI_gv_aIHeroChanceCaptureWatchTower[12] = 50.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[1] = 0.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[2] = 0.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[3] = 25.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[4] = 25.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[5] = 0.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[6] = 0.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[7] = 25.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[8] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[9] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[10] = 60.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[11] = 75.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByHeroPercent[12] = 85.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[1] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[2] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[3] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[4] = 50.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[5] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[6] = 40.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[7] = 50.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[8] = 50.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[9] = 50.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[10] = 60.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[11] = 75.0;
    libAIAI_gv_aIHeroRetreatWhenTargettedByNonHeroPercent[12] = 85.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[1] = 0.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[2] = 0.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[3] = 25.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[4] = 25.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[5] = 0.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[6] = 0.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[7] = 25.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[8] = 35.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[9] = 35.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[10] = 45.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[11] = 50.0;
    libAIAI_gv_aIHeroAlwaysRetreatFromDamagePercent[12] = 60.0;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[1] = false;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[2] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[3] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[4] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[5] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[6] = false;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[7] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[8] = false;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[9] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[10] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[11] = true;
    libAIAI_gv_aIHeroStayBehindMinionsNearTowers[12] = true;
    libAIAI_gv_aIHeroTeleportPercent[1] = -10.0;
    libAIAI_gv_aIHeroTeleportPercent[2] = -10.0;
    libAIAI_gv_aIHeroTeleportPercent[3] = -10.0;
    libAIAI_gv_aIHeroTeleportPercent[4] = 20.0;
    libAIAI_gv_aIHeroTeleportPercent[5] = -10.0;
    libAIAI_gv_aIHeroTeleportPercent[6] = -10.0;
    libAIAI_gv_aIHeroTeleportPercent[7] = 20.0;
    libAIAI_gv_aIHeroTeleportPercent[8] = 20.0;
    libAIAI_gv_aIHeroTeleportPercent[9] = 20.0;
    libAIAI_gv_aIHeroTeleportPercent[10] = 25.0;
    libAIAI_gv_aIHeroTeleportPercent[11] = 30.0;
    libAIAI_gv_aIHeroTeleportPercent[12] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[1] = 0.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[2] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[3] = 0.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[4] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[5] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[6] = 0.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[7] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[8] = 20.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[9] = 30.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[10] = 40.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[11] = 50.0;
    libAIAI_gv_aIHeroMinOffensiveHealth[12] = 50.0;
    libAIAI_gv_aIHeroHighestHeroSelectTier[1] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[2] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[3] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[4] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[5] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[6] = 1;
    libAIAI_gv_aIHeroHighestHeroSelectTier[7] = 2;
    libAIAI_gv_aIHeroHighestHeroSelectTier[8] = 2;
    libAIAI_gv_aIHeroHighestHeroSelectTier[9] = 2;
    libAIAI_gv_aIHeroHighestHeroSelectTier[10] = 2;
    libAIAI_gv_aIHeroHighestHeroSelectTier[11] = 3;
    libAIAI_gv_aIHeroHighestHeroSelectTier[12] = 3;
    libAIAI_gv_aIHeroPathAroundDanger[1] = false;
    libAIAI_gv_aIHeroPathAroundDanger[2] = false;
    libAIAI_gv_aIHeroPathAroundDanger[3] = false;
    libAIAI_gv_aIHeroPathAroundDanger[4] = false;
    libAIAI_gv_aIHeroPathAroundDanger[5] = false;
    libAIAI_gv_aIHeroPathAroundDanger[6] = false;
    libAIAI_gv_aIHeroPathAroundDanger[7] = false;
    libAIAI_gv_aIHeroPathAroundDanger[8] = false;
    libAIAI_gv_aIHeroPathAroundDanger[9] = false;
    libAIAI_gv_aIHeroPathAroundDanger[10] = true;
    libAIAI_gv_aIHeroPathAroundDanger[11] = true;
    libAIAI_gv_aIHeroPathAroundDanger[12] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[1] = false;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[2] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[3] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[4] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[5] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[6] = false;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[7] = false;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[8] = false;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[9] = false;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[10] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[11] = true;
    libAIAI_gv_aIHeroPreemptivelyRetreatFromTowers[12] = true;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[1] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[2] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[3] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[4] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[5] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[6] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[7] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[8] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[9] = 2;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[10] = 3;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[11] = 4;
    libAIAI_gv_aIHeroMaxTributeCaptureAIHeroes[12] = 5;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[1] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[2] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[3] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[4] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[5] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[6] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[7] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[8] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[9] = 1;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[10] = 2;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[11] = 5;
    libAIAI_gv_aIHeroMaxObeliskCaptureAIHeroes[12] = 5;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[1] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[2] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[3] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[4] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[5] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[6] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[7] = 5;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[8] = 2;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[9] = 5;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[10] = 5;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[11] = 5;
    libAIAI_gv_aIHeroMaxDefendCoreAIHeroes[12] = 5;
    libAIAI_gv_aIHeroTributeCaptureDelay[1] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[2] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[3] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[4] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[5] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[6] = 15.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[7] = 10.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[8] = 10.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[9] = 10.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[10] = 5.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[11] = 2.0;
    libAIAI_gv_aIHeroTributeCaptureDelay[12] = 0.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[1] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[2] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[3] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[4] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[5] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[6] = 30.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[7] = 10.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[8] = 20.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[9] = 10.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[10] = 10.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[11] = 3.0;
    libAIAI_gv_aIHeroObeliskRecaptureDelay[12] = 0.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[1] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[2] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[3] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[4] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[5] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[6] = 90.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[7] = 30.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[8] = 30.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[9] = 30.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[10] = 5.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[11] = 0.0;
    libAIAI_gv_aIHeroUseDragonVehicleDelay[12] = 0.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[1] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[2] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[3] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[4] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[5] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[6] = 20.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[7] = 15.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[8] = 15.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[9] = 15.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[10] = 10.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[11] = 5.0;
    libAIAI_gv_aIHeroEnterUnderworldDelay[12] = 0.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[1] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[2] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[3] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[4] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[5] = 5.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[6] = 5.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[7] = 5.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[8] = 3.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[9] = 3.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[10] = 2.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[11] = 1.0;
    libAIAI_gv_aIHeroDoubloonPickupSoloDelay[12] = 0.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[1] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[2] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[3] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[4] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[5] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[6] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[7] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[8] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[9] = 6.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[10] = 5.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[11] = 5.0;
    libAIAI_gv_aIHeroDoubloonPickupHumanDelay[12] = 5.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[1] = 15.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[2] = 12.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[3] = 15.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[4] = 12.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[5] = 10.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[6] = 10.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[7] = 8.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[8] = 8.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[9] = 6.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[10] = 3.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[11] = 1.0;
    libAIAI_gv_aIHeroDoubloonChestDelay[12] = 0.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[1] = 0.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[2] = 0.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[3] = 10.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[4] = 2.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[5] = 0.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[6] = 10.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[7] = 2.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[8] = 5.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[9] = 2.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[10] = 2.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[11] = 0.0;
    libAIAI_gv_aIHeroExtraWaitAfterRespawn[12] = 0.0;
    libAIAI_gv_aIHeroUseMountDelay[1] = 3.0;
    libAIAI_gv_aIHeroUseMountDelay[2] = 0.0;
    libAIAI_gv_aIHeroUseMountDelay[3] = 3.0;
    libAIAI_gv_aIHeroUseMountDelay[4] = 1.5;
    libAIAI_gv_aIHeroUseMountDelay[5] = 3.0;
    libAIAI_gv_aIHeroUseMountDelay[6] = 3.0;
    libAIAI_gv_aIHeroUseMountDelay[7] = 3.0;
    libAIAI_gv_aIHeroUseMountDelay[8] = 1.5;
    libAIAI_gv_aIHeroUseMountDelay[9] = 1.5;
    libAIAI_gv_aIHeroUseMountDelay[10] = 1.0;
    libAIAI_gv_aIHeroUseMountDelay[11] = 0.0;
    libAIAI_gv_aIHeroUseMountDelay[12] = 0.0;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIInitializeDifficultyLevelData_Init () {
    libAIAI_gt_HeroAIInitializeDifficultyLevelData = TriggerCreate("libAIAI_gt_HeroAIInitializeDifficultyLevelData_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Initialize Hero Tier Data
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIInitializeHeroTierData_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_tierIndex;
    int lv_arrayIndex;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_tierIndex += 1;
    lv_arrayIndex = 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroDiablo";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroDemonHunter";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroKerrigan";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroMalfurion";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroMuradin";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroTychus";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroUther";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroRaynor";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroLiLi";
    lv_tierIndex += 1;
    lv_arrayIndex = 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroArthas";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroStitches";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroTassadar";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroTyrande";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroSgtHammer";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroWitchDoctor";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroBarbarian";
    lv_tierIndex += 1;
    lv_arrayIndex = 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroL90ETC";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroFalstad";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroNova";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroTinker";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroTyrael";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroZeratul";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroAbathur";
    lv_arrayIndex += 1;
    libAIAI_gv_heroAIHeroTierData[lv_tierIndex][lv_arrayIndex] = "HeroFaerieDragon";
    libCore_gf_CallRegisteredSegregationTriggers(1);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIInitializeHeroTierData_Init () {
    libAIAI_gt_HeroAIInitializeHeroTierData = TriggerCreate("libAIAI_gt_HeroAIInitializeHeroTierData_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Game Started
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIGameStarted_Func (bool testConds, bool runActions) {
    int auto225B09A6_ae;
    int auto225B09A6_ai;

    // Variable Declarations
    int lv_currentPlayer;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    if (((libCore_gv_sYSGameMode == 2) || (libSprt_gv_performanceTestPerformanceTestRunning == true))) {
        return true;
    }
    else {
    }
    Wait(2.5, c_timeGame);
    auto225B09A6_ae = libCore_gv_bALMaxPlayers;
    auto225B09A6_ai = 1;
    lv_currentPlayer = 1;
    for ( ; ( (auto225B09A6_ai >= 0 && lv_currentPlayer <= auto225B09A6_ae) || (auto225B09A6_ai <= 0 && lv_currentPlayer >= auto225B09A6_ae) ) ; lv_currentPlayer += auto225B09A6_ai ) {
        if ((libAIAI_gf_HeroAIIsPlayerActive(lv_currentPlayer, 2) == true)) {
            libAIAI_gf_HeroAIEnableAIForPlayer(lv_currentPlayer);
            Wait(RandomFixed(0.1, 0.25), c_timeGame);
        }
        else {
        }
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIGameStarted_Init () {
    libAIAI_gt_HeroAIGameStarted = TriggerCreate("libAIAI_gt_HeroAIGameStarted_Func");
    libGame_gf_GameOpenTimerStarted(libAIAI_gt_HeroAIGameStarted);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Run Main Group Loop
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIRunMainGroupLoop_Func (bool testConds, bool runActions) {
    int auto61534A48_ae;
    int auto61534A48_ai;
    int auto9F84E177_val;

    // Variable Declarations
    int lv_timeSpent;
    int lv_currentPlayer;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    while ((libGame_gv_gameOver == false)) {
        lv_timeSpent = 0;
        libAIAI_gv_heroAIDidEval = false;
        auto61534A48_ae = libCore_gv_bALMaxPlayers;
        auto61534A48_ai = 1;
        lv_currentPlayer = 1;
        for ( ; ( (auto61534A48_ai >= 0 && lv_currentPlayer <= auto61534A48_ae) || (auto61534A48_ai <= 0 && lv_currentPlayer >= auto61534A48_ae) ) ; lv_currentPlayer += auto61534A48_ai ) {
            if (((libAIAI_gv_aIHeroes[lv_currentPlayer].lv_heroState == 0) || (AIIsTacticalDisabled(libGame_gv_players[lv_currentPlayer].lv_heroUnit) == true))) {
                continue;
            }
            else {
            }
            if (((libAIAI_gv_heroAIDidEval == true) || (lv_timeSpent > 64))) {
                lv_timeSpent = 0;
                libAIAI_gv_heroAIDidEval = false;
                Wait(0.0625, c_timeGame);
            }
            else {
            }
            auto9F84E177_val = libAIAI_gv_aIHeroes[lv_currentPlayer].lv_heroState;
            if (auto9F84E177_val == 1) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDead(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 2) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAfterDeathAttack(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 3) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIReturnToSpawn(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 4) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIWaitForGameToStart(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 5) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIWaitToHeal(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 6) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIWaitInSpawn(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 7) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAdvanceInLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 8) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIRetreatInLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 9) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAvoidAOE(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 10) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMinionBattleRetreat(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 11) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMinionBattleReposition(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 12) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMinionBattleAttack(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 13) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMinionBattleHarass(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 14) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIHarassSiegeEnemy(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 15) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIWaitForMinions(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 16) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIReturnToLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 17) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIPickUpHealthGlobeJungle(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 18) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIFocusHero(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 19) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIFocusCore(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 20) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDefendCoreAttack(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 21) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDefendCoreLeash(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 22) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIVehicleReturnToLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 23) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIVehicleAdvanceInLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 24) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAICaptureWatchTower(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 25) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITeleportHomeLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 26) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDrinkMoonwell(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 27) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITearOfEluneMoveToTear(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 29) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITearOfEluneGuard(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 28) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITearOfEluneCapture(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 30) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITearOfEluneDefend(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 31) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIPickUpDoubloon(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 32) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITurnInDoubloons(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 33) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITurnInDoubloonsDefend(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 34) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITreasureChestMoveToChest(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 35) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITreasureChestAttackChest(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 36) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITreasureChestDefend(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 37) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMinionCampInit(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 38) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIMoveToCamp(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 39) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIWaitAtCamp(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 40) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAttackSoloCamp(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 41) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAICaptureCampBeacon(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 42) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDefendCampAttack(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 43) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDefendCampLeash(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 44) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIFleeInJungle(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 45) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAITeleportHomeJungle(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 46) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIHarassInJungle(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 47) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIPaceAround(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 48) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIObeliskMoveToObelisk(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 49) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIObeliskCapture(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 50) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIObeliskDefend(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 51) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDragonMoveToDragon(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 52) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDragonEnter(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 54) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDragonGuard(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 53) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIDragonDefend(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 55) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIFollowerGuardLeader(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 56) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIFollowerGuardLeaderLeash(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 57) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldEnter(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 58) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldKillMinions(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 59) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldFocusHero(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 60) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldPickupSkull(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 61) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldMoveToExit(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 62) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldTeleportHome(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 63) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIUnderworldExit(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 64) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAbathurAdvanceInLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 65) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAbathurRetreatInLane(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 66) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAbathurHideInTown(lv_currentPlayer));
            }
            else if (auto9F84E177_val == 67) {
                lv_timeSpent = (lv_timeSpent + libAIAI_gf_HeroAIAbathurChangeLanes(lv_currentPlayer));
            }
            else {
            }
            libAIAI_gf_HeroAIUpdateAIStatus(lv_currentPlayer);
        }
        Wait(0.0625, c_timeGame);
        if ((libAIAI_gf_HeroAIHasGameStarted() == true)) {
            if ((libAIAI_gf_HeroAITeamHasAIPlayers(0) == true)) {
                libAIAI_gf_HeroAITeamLogic(0);
                Wait(0.0625, c_timeGame);
            }
            else {
            }
            if ((libAIAI_gf_HeroAITeamHasAIPlayers(1) == true)) {
                libAIAI_gf_HeroAITeamLogic(1);
                Wait(0.0625, c_timeGame);
            }
            else {
            }
        }
        else {
        }
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIRunMainGroupLoop_Init () {
    libAIAI_gt_HeroAIRunMainGroupLoop = TriggerCreate("libAIAI_gt_HeroAIRunMainGroupLoop_Func");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Take Over Hero
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITakeOverHero_Func (bool testConds, bool runActions) {
    // Conditions
    if (testConds) {
        if (!((libGame_gv_gameOver == false))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gf_HeroAITakeOverHeroForPlayer(EventPlayer());
    libAIAI_gv_aIHeroes[EventPlayer()].lv_allowedToChooseTalentsTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroChooseTalentDelayInCaseOfRejoin);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITakeOverHero_Init () {
    libAIAI_gt_HeroAITakeOverHero = TriggerCreate("libAIAI_gt_HeroAITakeOverHero_Func");
    TriggerEnable(libAIAI_gt_HeroAITakeOverHero, false);
    TriggerAddEventPlayerLeft(libAIAI_gt_HeroAITakeOverHero, c_playerAny, c_gameResultUndecided);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Release Hero Control
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIReleaseHeroControl_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gf_HeroAIReleaseHeroControl(EventPlayer());
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIReleaseHeroControl_Init () {
    libAIAI_gt_HeroAIReleaseHeroControl = TriggerCreate("libAIAI_gt_HeroAIReleaseHeroControl_Func");
    TriggerEnable(libAIAI_gt_HeroAIReleaseHeroControl, false);
    TriggerAddEventPlayerJoin(libAIAI_gt_HeroAIReleaseHeroControl, c_playerAny);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Town Data Initialized
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITownDataInitialized_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gf_HeroAISetupTownData();
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITownDataInitialized_Init () {
    libAIAI_gt_HeroAITownDataInitialized = TriggerCreate("libAIAI_gt_HeroAITownDataInitialized_Func");
    TriggerEnable(libAIAI_gt_HeroAITownDataInitialized, false);
    libGame_gf_TownDataInitialized(libAIAI_gt_HeroAITownDataInitialized);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Tower Dies
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITowerDies_Func (bool testConds, bool runActions) {
    // Conditions
    if (testConds) {
        if (!((UnitTypeTestAttribute(UnitGetType(EventUnit()), c_unitAttributeStructure) == true))) {
            return false;
        }

        if (!((UnitTypeTestAttribute(UnitGetType(EventUnit()), c_unitAttributeArmored) == true))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    if ((UnitGetOwner(EventUnit()) == libCore_gv_cOMPUTER_TeamOrder)) {
        libAIAI_gf_HeroAIUpdateFrontTower(0);
    }
    else {
        libAIAI_gf_HeroAIUpdateFrontTower(1);
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITowerDies_Init () {
    libAIAI_gt_HeroAITowerDies = TriggerCreate("libAIAI_gt_HeroAITowerDies_Func");
    TriggerEnable(libAIAI_gt_HeroAITowerDies, false);
    TriggerAddEventUnitDied(libAIAI_gt_HeroAITowerDies, null);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Follower Command
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIFollowerCommand_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_pingingPlayer;
    unit lv_unitPinged;
    point lv_positionPinged;
    int lv_playerIndex;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_pingingPlayer = EventPlayer();
    lv_unitPinged = EventPingUnit();
    lv_positionPinged = EventPingPoint();
    if ((UnitIsValid(lv_unitPinged) == true) && (UnitTypeTestAttribute(UnitGetType(lv_unitPinged), c_unitAttributeHeroic) == true) && (UnitGetOwner(lv_unitPinged) != lv_pingingPlayer) && (UnitGetOwner(lv_unitPinged) <= libCore_gv_bALMaxPlayers) && (libGame_gv_players[UnitGetOwner(lv_unitPinged)].lv_faction == libGame_gv_players[lv_pingingPlayer].lv_faction) && (libAIAI_gf_HeroAIIsPlayerActive(UnitGetOwner(lv_unitPinged), 2) == true)) {
        if ((libAIAI_gv_aIHeroes[UnitGetOwner(lv_unitPinged)].lv_leaderPlayer == lv_pingingPlayer)) {
            libAIAI_gf_HeroAIStopFollowingLeader(UnitGetOwner(lv_unitPinged));
        }
        else {
            libAIAI_gf_HeroAIStartFollowingLeader(UnitGetOwner(lv_unitPinged), lv_pingingPlayer);
        }
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIFollowerCommand_Init () {
    libAIAI_gt_HeroAIFollowerCommand = TriggerCreate("libAIAI_gt_HeroAIFollowerCommand_Func");
    TriggerEnable(libAIAI_gt_HeroAIFollowerCommand, false);
    TriggerAddEventPing(libAIAI_gt_HeroAIFollowerCommand, c_playerAny);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Hero Takes Damage
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIHeroTakesDamage_Func (bool testConds, bool runActions) {
    int autoDE8C6DB2_ae;
    int autoDE8C6DB2_ai;
    int auto2E99A835_ae;

    // Variable Declarations
    unit lv_targetUnit;
    string lv_effect;
    string lv_behavior;
    int lv_effectIndex;
    int lv_effectCount;
    int lv_periodicEffectCount;
    int lv_periodicEffectIndex;
    string lv_periodicEffect;
    unit lv_damagingUnit;
    int lv_playerIndex;
    int lv_heroOwner;
    int lv_buffIndex;
    bool lv_isDot;
    unit lv_unit;

    // Variable Initialization
    lv_targetUnit = EventPlayerEffectUsedUnit(c_effectUnitTarget);

    // Conditions
    if (testConds) {
        if (!((UnitTypeTestAttribute(UnitGetType(lv_targetUnit), c_unitAttributeHeroic) == true))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    autoDE8C6DB2_ae = libCore_gv_bALMaxPlayers;
    autoDE8C6DB2_ai = 1;
    lv_playerIndex = 1;
    for ( ; ( (autoDE8C6DB2_ai >= 0 && lv_playerIndex <= autoDE8C6DB2_ae) || (autoDE8C6DB2_ai <= 0 && lv_playerIndex >= autoDE8C6DB2_ae) ) ; lv_playerIndex += autoDE8C6DB2_ai ) {
        if ((lv_targetUnit == libGame_gv_players[lv_playerIndex].lv_heroUnit)) {
            lv_heroOwner = lv_playerIndex;
        }
        else {
        }
    }
    if ((lv_heroOwner <= 0)) {
        return true;
    }
    else {
    }
    lv_effect = EventPlayerEffectUsed();
    if ((lv_effect != null)) {
        lv_behavior = EventPlayerEffectUsedSourceBehavior();
        if ((lv_behavior != null)) {
            lv_periodicEffectCount = CatalogFieldValueCount(c_gameCatalogBehavior, lv_behavior, "PeriodicDisplayEffect", c_playerAny);
            auto2E99A835_ae = lv_periodicEffectCount;
            lv_periodicEffectIndex = 1;
            for ( ; lv_periodicEffectIndex <= auto2E99A835_ae ; lv_periodicEffectIndex += 1 ) {
                lv_periodicEffect = (CatalogFieldValueGet(c_gameCatalogBehavior, lv_behavior, "PeriodicDisplayEffect[" + IntToString((lv_periodicEffectIndex - 1)) + "]", c_playerAny));
                if ((lv_effect == lv_periodicEffect)) {
                    return true;
                }
                else {
                }
            }
        }
        else {
        }
    }
    else {
    }
    lv_damagingUnit = EventPlayerEffectUsedUnit(c_effectUnitCaster);
    libAIAI_gv_heroAIDamageTracking[lv_heroOwner].lv_lastAttacker = lv_damagingUnit;
    libAIAI_gv_heroAIDamageTracking[lv_heroOwner].lv_lastTimeAttacked = TimerGetElapsed(libGame_gv_gameTimer);
    if ((libAIAI_gf_HeroAIIsPlayerActive(lv_heroOwner, 2) == true)) {
        libAIAI_gf_HeroAINotifyHeroDamaged(lv_heroOwner, lv_damagingUnit);
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIHeroTakesDamage_Init () {
    libAIAI_gt_HeroAIHeroTakesDamage = TriggerCreate("libAIAI_gt_HeroAIHeroTakesDamage_Func");
    TriggerEnable(libAIAI_gt_HeroAIHeroTakesDamage, false);
    TriggerAddEventPlayerEffectUsedFromScope(libAIAI_gt_HeroAIHeroTakesDamage, c_playerAny, "CEffectDamage");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Hero Enters After Death State
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIHeroEntersAfterDeathState_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_deadPlayer;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_deadPlayer = UnitGetOwner(EventPlayerEffectUsedUnit(c_effectUnitCaster));
    if ((libAIAI_gf_HeroAIIsPlayerActive(lv_deadPlayer, 2) == true)) {
        libAIAI_gf_HeroAILeaveCurrentObjective(lv_deadPlayer);
        libAIAI_gf_HeroAIChangeState(lv_deadPlayer, 2);
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIHeroEntersAfterDeathState_Init () {
    libAIAI_gt_HeroAIHeroEntersAfterDeathState = TriggerCreate("libAIAI_gt_HeroAIHeroEntersAfterDeathState_Func");
    TriggerEnable(libAIAI_gt_HeroAIHeroEntersAfterDeathState, false);
    TriggerAddEventPlayerEffectUsed(libAIAI_gt_HeroAIHeroEntersAfterDeathState, c_playerAny, "SpiritofRedemptionApplyRezDelayBehavior");
    TriggerAddEventPlayerEffectUsed(libAIAI_gt_HeroAIHeroEntersAfterDeathState, c_playerAny, "ArchangelsWrathApplyActiveBehavior");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Hero Dies
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIHeroDies_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_player;

    // Variable Initialization

    // Conditions
    if (testConds) {
        if (!((EventPlayer() >= 1))) {
            return false;
        }

        if (!((EventPlayer() <= libCore_gv_bALMaxPlayers))) {
            return false;
        }

        if (!((EventUnit() == libGame_gv_players[EventPlayer()].lv_heroUnit))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    lv_player = EventPlayer();
    if ((libAIAI_gf_HeroAIIsPlayerActive(lv_player, 2) == true) && (libAIAI_gv_aIHeroes[lv_player].lv_heroState != 0)) {
        libAIAI_gf_HeroAILeaveCurrentObjective(lv_player);
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIHeroDies_Init () {
    libAIAI_gt_HeroAIHeroDies = TriggerCreate("libAIAI_gt_HeroAIHeroDies_Func");
    TriggerEnable(libAIAI_gt_HeroAIHeroDies, false);
    TriggerAddEventUnitDied(libAIAI_gt_HeroAIHeroDies, null);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Human Ally Initiates Fight
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIHumanAllyInitiatesFight_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_casterPlayer;
    unit lv_targetUnit;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_casterPlayer = EventUnitDamageSourcePlayer();
    lv_targetUnit = EventUnit();
    if ((UnitFilterMatch(lv_targetUnit, lv_casterPlayer, UnitFilter((1 << c_targetFilterHeroic), 0, 0, (1 << (c_targetFilterHallucination - 32)))) == true) && (libAIAI_gf_HeroAIIsPlayerActive(lv_casterPlayer, 1) == true)) {
        if ((libAIAI_gf_HeroAIHeroCanBeFocused(lv_targetUnit) == true)) {
            libAIAI_gf_HeroAIStartFocusHero(lv_casterPlayer, lv_targetUnit);
        }
        else {
        }
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIHumanAllyInitiatesFight_Init () {
    libAIAI_gt_HeroAIHumanAllyInitiatesFight = TriggerCreate("libAIAI_gt_HeroAIHumanAllyInitiatesFight_Func");
    TriggerEnable(libAIAI_gt_HeroAIHumanAllyInitiatesFight, false);
    TriggerAddEventUnitDamaged(libAIAI_gt_HeroAIHumanAllyInitiatesFight, null, c_unitDamageTypeAny, c_unitDamageNonFatal, "DemonHunterWeaponDamage");
    TriggerAddEventUnitDamaged(libAIAI_gt_HeroAIHumanAllyInitiatesFight, null, c_unitDamageTypeAny, c_unitDamageNonFatal, "BarbarianLeapDamage");
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Tribute Warning
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITributeWarning_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeWarningPosition = libGame_gf_MapTributeWarningPosition();
    libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState = 1;
    libAIAI_gv_heroAITeamData[(0)].lv_nextTearOfEluneConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTributeCaptureDelay[(libAIAI_gv_heroAITeamData[(0)].lv_difficulty)]);
    libAIAI_gv_heroAITeamData[(1)].lv_nextTearOfEluneConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroTributeCaptureDelay[(libAIAI_gv_heroAITeamData[(1)].lv_difficulty)]);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITributeWarning_Init () {
    libAIAI_gt_HeroAITributeWarning = TriggerCreate("libAIAI_gt_HeroAITributeWarning_Func");
    libGame_gf_MapRavenLordTributeWarning(libAIAI_gt_HeroAITributeWarning);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Tribute Spawned
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITributeSpawned_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeUnit = libGame_gf_MapTributeSpawnedUnit();
    libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState = 2;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITributeSpawned_Init () {
    libAIAI_gt_HeroAITributeSpawned = TriggerCreate("libAIAI_gt_HeroAITributeSpawned_Func");
    libGame_gf_MapRavenLordTributeSpawned(libAIAI_gt_HeroAITributeSpawned);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Tribute Picked Up
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITributePickedUp_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIRavenLordTributeStatus.lv_tributeState = 0;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITributePickedUp_Init () {
    libAIAI_gt_HeroAITributePickedUp = TriggerCreate("libAIAI_gt_HeroAITributePickedUp_Func");
    libGame_gf_MapRavenLordTributePickedUp(libAIAI_gt_HeroAITributePickedUp);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Raven Lord Curse Starts
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIRavenLordCurseStarts_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIRavenLordCurseStatus.lv_activatedTeam = libGame_gf_MapRavenLordCurseActivatedTeam();
    libAIAI_gv_heroAIRavenLordCurseStatus.lv_curseActive = true;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIRavenLordCurseStarts_Init () {
    libAIAI_gt_HeroAIRavenLordCurseStarts = TriggerCreate("libAIAI_gt_HeroAIRavenLordCurseStarts_Func");
    libGame_gf_MapRavenLordCurseStarts(libAIAI_gt_HeroAIRavenLordCurseStarts);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Raven Lord Curse Ends
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIRavenLordCurseEnds_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIRavenLordCurseStatus.lv_curseActive = false;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIRavenLordCurseEnds_Init () {
    libAIAI_gt_HeroAIRavenLordCurseEnds = TriggerCreate("libAIAI_gt_HeroAIRavenLordCurseEnds_Func");
    libGame_gf_MapRavenLordCurseEnds(libAIAI_gt_HeroAIRavenLordCurseEnds);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Ghost Ship Shows Up
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIGhostShipShowsUp_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIGhostShipStatus.lv_beaconUnit = libGame_gf_MapDoubloonsGhostShipShowsUpShip();
    libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus = 1;
    libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamOrderIndex_C] = 0;
    libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamChaosIndex_C] = 0;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIGhostShipShowsUp_Init () {
    libAIAI_gt_HeroAIGhostShipShowsUp = TriggerCreate("libAIAI_gt_HeroAIGhostShipShowsUp_Func");
    libGame_gf_MapDoubloonsGhostShipShowsUp(libAIAI_gt_HeroAIGhostShipShowsUp);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Ghost Ship Shooting Starts
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIGhostShipShootingStarts_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_player;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus = 0;
    lv_player = libGame_gf_MapDoubloonsGhostShipShootingStartPlayer();
    if ((libGame_gv_players[lv_player].lv_faction == 0)) {
        libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamOrderIndex_C] = 0;
    }
    else {
        libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamChaosIndex_C] = 0;
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIGhostShipShootingStarts_Init () {
    libAIAI_gt_HeroAIGhostShipShootingStarts = TriggerCreate("libAIAI_gt_HeroAIGhostShipShootingStarts_Func");
    libGame_gf_MapDoubloonsGhostShipShootingStart(libAIAI_gt_HeroAIGhostShipShootingStarts);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Ghost Ship Shooting Ends
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIGhostShipShootingEnds_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIGhostShipStatus.lv_beaconStatus = 1;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIGhostShipShootingEnds_Init () {
    libAIAI_gt_HeroAIGhostShipShootingEnds = TriggerCreate("libAIAI_gt_HeroAIGhostShipShootingEnds_Func");
    libGame_gf_MapDoubloonsGhostShipShootingEnd(libAIAI_gt_HeroAIGhostShipShootingEnds);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Doubloons Turned In
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIDoubloonsTurnedIn_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_player;
    int lv_count;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_player = libGame_gf_MapDoubloonsDoubloonsTurnedInPlayer();
    lv_count = libGame_gf_MapDoubloonsDoubloonsTurnedInCount();
    if ((libGame_gv_players[lv_player].lv_faction == 0)) {
        libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamOrderIndex_C] += lv_count;
    }
    else {
        libAIAI_gv_heroAIGhostShipStatus.lv_doubloonsTurnedIn[libGame_gv_teamChaosIndex_C] += lv_count;
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIDoubloonsTurnedIn_Init () {
    libAIAI_gt_HeroAIDoubloonsTurnedIn = TriggerCreate("libAIAI_gt_HeroAIDoubloonsTurnedIn_Func");
    libGame_gf_MapDoubloonsDoubloonsTurnedIn(libAIAI_gt_HeroAIDoubloonsTurnedIn);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Treasure Chests Spawns
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAITreasureChestsSpawns_Func (bool testConds, bool runActions) {
    // Variable Declarations
    unit lv_treasureChest;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_treasureChest = libGame_gf_MapChestSpawnedUnit();
    UnitGroupAdd(libAIAI_gv_heroAITreasureChests, lv_treasureChest);
    libAIAI_gv_heroAITeamData[(0)].lv_nextDoubloonChestConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroDoubloonChestDelay[(libAIAI_gv_heroAITeamData[(0)].lv_difficulty)]);
    libAIAI_gv_heroAITeamData[(1)].lv_nextDoubloonChestConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroDoubloonChestDelay[(libAIAI_gv_heroAITeamData[(1)].lv_difficulty)]);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAITreasureChestsSpawns_Init () {
    libAIAI_gt_HeroAITreasureChestsSpawns = TriggerCreate("libAIAI_gt_HeroAITreasureChestsSpawns_Func");
    libGame_gf_MapDoubloonChestSpawned(libAIAI_gt_HeroAITreasureChestsSpawns);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Dragon Shire Obelisks Spawned
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIDragonShireObelisksSpawned_Func (bool testConds, bool runActions) {
    // Variable Declarations
    unit lv_obelisk;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_obelisk = libGame_gf_MapObeliskSpawnedUnit();
    UnitGroupAdd(libAIAI_gv_heroAIDragonShireObelisks, lv_obelisk);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIDragonShireObelisksSpawned_Init () {
    libAIAI_gt_HeroAIDragonShireObelisksSpawned = TriggerCreate("libAIAI_gt_HeroAIDragonShireObelisksSpawned_Func");
    libGame_gf_MapDragonShireObeliskSpawned(libAIAI_gt_HeroAIDragonShireObelisksSpawned);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Dragon Shrire Obelisk Changes Owner
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    if ((libAIAI_gf_HeroAITeamOwnsAllObelisks(0) == true)) {
        libAIAI_gv_heroAITeamData[(0)].lv_nextUseDragonVehicleConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroUseDragonVehicleDelay[(libAIAI_gv_heroAITeamData[(0)].lv_difficulty)]);
        libAIAI_gv_heroAITeamData[(1)].lv_nextObeliskConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroObeliskRecaptureDelay[(libAIAI_gv_heroAITeamData[(1)].lv_difficulty)]);
    }
    else {
    }
    if ((libAIAI_gf_HeroAITeamOwnsAllObelisks(1) == true)) {
        libAIAI_gv_heroAITeamData[(0)].lv_nextObeliskConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroObeliskRecaptureDelay[(libAIAI_gv_heroAITeamData[(0)].lv_difficulty)]);
        libAIAI_gv_heroAITeamData[(1)].lv_nextUseDragonVehicleConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroUseDragonVehicleDelay[(libAIAI_gv_heroAITeamData[(1)].lv_difficulty)]);
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner_Init () {
    libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner = TriggerCreate("libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner_Func");
    libGame_gf_MapDragonShireObeliskOwnershipChange(libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Dragon Shire Dragon Activated
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIDragonShireDragonActivated_Func (bool testConds, bool runActions) {
    // Variable Declarations
    unit lv_dragon;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_dragon = libGame_gf_MapDragonActivatedDragonUnit();
    libAIAI_gv_heroAIDragonShireDragon = lv_dragon;
    UnitGroupClear(libAIAI_gv_heroAIDragonShireObelisks);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIDragonShireDragonActivated_Init () {
    libAIAI_gt_HeroAIDragonShireDragonActivated = TriggerCreate("libAIAI_gt_HeroAIDragonShireDragonActivated_Func");
    libGame_gf_MapDragonShireDragonActivated(libAIAI_gt_HeroAIDragonShireDragonActivated);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Dragon Shire Dragon Ends
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIDragonShireDragonEnds_Func (bool testConds, bool runActions) {
    // Actions
    if (!runActions) {
        return true;
    }

    libAIAI_gv_heroAIDragonShireDragon = null;
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIDragonShireDragonEnds_Init () {
    libAIAI_gt_HeroAIDragonShireDragonEnds = TriggerCreate("libAIAI_gt_HeroAIDragonShireDragonEnds_Func");
    libGame_gf_MapDragonShireDragonEnds(libAIAI_gt_HeroAIDragonShireDragonEnds);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Underworld Undead Spawned
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIUnderworldUndeadSpawned_Func (bool testConds, bool runActions) {
    // Variable Declarations
    region lv_underworldRegion;
    unitgroup lv_entrances;
    int lv_totalSkulls;

    // Variable Initialization
    lv_entrances = UnitGroupEmpty();

    // Actions
    if (!runActions) {
        return true;
    }

    lv_entrances = libGame_gf_MapUnderworldUndeadSpawnedEntrances();
    lv_underworldRegion = libGame_gf_MapUnderworldUndeadSpawnedUnderworldRegion();
    lv_totalSkulls = libGame_gf_MapUnderworldUndeadSpawnedTotalSkull();
    libAIAI_gv_heroAIUnderworldStatus.lv_opened = true;
    libAIAI_gv_heroAIUnderworldStatus.lv_totalSkulls = lv_totalSkulls;
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining = lv_totalSkulls;
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(0)] = 0;
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(1)] = 0;
    libAIAI_gv_heroAIUnderworldStatus.lv_underworldRegion = lv_underworldRegion;
    libAIAI_gv_heroAIUnderworldStatus.lv_entrances = lv_entrances;
    libAIAI_gv_heroAIUnderworldStatus.lv_exits = UnitGroup("HoleLadderUp", c_playerAny, lv_underworldRegion, UnitFilter(0, 0, (1 << c_targetFilterMissile), (1 << (c_targetFilterDead - 32)) | (1 << (c_targetFilterHidden - 32))), 0);
    libAIAI_gv_heroAITeamData[(0)].lv_nextUnderworldConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroEnterUnderworldDelay[(libAIAI_gv_heroAITeamData[(0)].lv_difficulty)]);
    libAIAI_gv_heroAITeamData[(1)].lv_nextUnderworldConsiderTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroEnterUnderworldDelay[(libAIAI_gv_heroAITeamData[(1)].lv_difficulty)]);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIUnderworldUndeadSpawned_Init () {
    libAIAI_gt_HeroAIUnderworldUndeadSpawned = TriggerCreate("libAIAI_gt_HeroAIUnderworldUndeadSpawned_Func");
    libGame_gf_MapUnderworldUndeadSpawned(libAIAI_gt_HeroAIUnderworldUndeadSpawned);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Underworld Skull Collected
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIUnderworldSkullCollected_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_orderSkulls;
    int lv_chaosSkulls;
    int lv_totalSkullsCollected;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_orderSkulls = libGame_gf_MapUnderworldSkullCollectedTeam1Skulls();
    lv_chaosSkulls = libGame_gf_MapUnderworldSkullCollectedTeam2Skulls();
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(0)] = lv_orderSkulls;
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsCollected[(1)] = lv_chaosSkulls;
    libAIAI_gv_heroAIUnderworldStatus.lv_skullsRemaining = (libAIAI_gv_heroAIUnderworldStatus.lv_totalSkulls - lv_orderSkulls - lv_chaosSkulls);
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIUnderworldSkullCollected_Init () {
    libAIAI_gt_HeroAIUnderworldSkullCollected = TriggerCreate("libAIAI_gt_HeroAIUnderworldSkullCollected_Func");
    libGame_gf_MapUnderworldSkullCollected(libAIAI_gt_HeroAIUnderworldSkullCollected);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Underworld Boss Warning
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIUnderworldBossWarning_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_team;
    int lv_lane;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_team = libGame_gf_MapUnderworldBossStartSummoningTeam();
    lv_lane = libGame_gf_MapUnderworldBossStartSummoningLane();
    if ((lv_team == 1)) {
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_lane = lv_lane;
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state = 1;
    }
    else {
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_lane = lv_lane;
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state = 1;
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIUnderworldBossWarning_Init () {
    libAIAI_gt_HeroAIUnderworldBossWarning = TriggerCreate("libAIAI_gt_HeroAIUnderworldBossWarning_Func");
    libGame_gf_MapUnderworldBossStartSummoning(libAIAI_gt_HeroAIUnderworldBossWarning);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Underworld Boss Spawned
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIUnderworldBossSpawned_Func (bool testConds, bool runActions) {
    // Variable Declarations
    unit lv_bossUnit;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    lv_bossUnit = libGame_gf_MapUnderworldBossSummonedBoss();
    if ((libNtve_gf_PlayerIsEnemy(libCore_gv_cOMPUTER_TeamOrder, UnitGetOwner(lv_bossUnit), 0) == true)) {
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_underworldBossUnit = lv_bossUnit;
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state = 2;
    }
    else {
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_underworldBossUnit = lv_bossUnit;
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state = 2;
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIUnderworldBossSpawned_Init () {
    libAIAI_gt_HeroAIUnderworldBossSpawned = TriggerCreate("libAIAI_gt_HeroAIUnderworldBossSpawned_Func");
    libGame_gf_MapUnderworldBossSummoned(libAIAI_gt_HeroAIUnderworldBossSpawned);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Underworld Boss Dies
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIUnderworldBossDies_Func (bool testConds, bool runActions) {
    // Conditions
    if (testConds) {
        if (!((UnitGetType(EventUnit()) == "UnderworldSummonedBoss"))) {
            return false;
        }
    }

    // Actions
    if (!runActions) {
        return true;
    }

    if ((EventUnit() == libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_underworldBossUnit)) {
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_underworldBossUnit = null;
        libAIAI_gv_heroAIUnderworldBossStatus[(0)].lv_state = 0;
    }
    else {
    }
    if ((EventUnit() == libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_underworldBossUnit)) {
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_underworldBossUnit = null;
        libAIAI_gv_heroAIUnderworldBossStatus[(1)].lv_state = 0;
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIUnderworldBossDies_Init () {
    libAIAI_gt_HeroAIUnderworldBossDies = TriggerCreate("libAIAI_gt_HeroAIUnderworldBossDies_Func");
    TriggerAddEventUnitDied(libAIAI_gt_HeroAIUnderworldBossDies, null);
}

//--------------------------------------------------------------------------------------------------
// Trigger: HeroAI - Watch For AOE Ability Casted
//--------------------------------------------------------------------------------------------------
bool libAIAI_gt_HeroAIWatchForAOEAbilityCasted_Func (bool testConds, bool runActions) {
    int autoB253F319_ae;

    // Variable Declarations
    int lv_index;
    unit lv_unit;
    fixed lv_radius;
    fixed lv_duration;
    fixed lv_startOffset;
    point lv_position;
    fixed lv_startTime;
    fixed lv_expireTime;
    bool lv_notifyTeamOrder;
    bool lv_notifyTeamChaos;

    // Variable Initialization

    // Actions
    if (!runActions) {
        return true;
    }

    autoB253F319_ae = libAIAI_gv_heroAINumRegisteredAOEAvoidEffects;
    lv_index = 0;
    for ( ; lv_index <= autoB253F319_ae ; lv_index += 1 ) {
        if ((EventPlayerEffectUsed() == libAIAI_gv_heroAIAOEAvoidEffectList[lv_index].lv_effect)) {
            lv_radius = libAIAI_gv_heroAIAOEAvoidEffectList[lv_index].lv_radius;
            lv_duration = libAIAI_gv_heroAIAOEAvoidEffectList[lv_index].lv_duration;
            lv_startOffset = libAIAI_gv_heroAIAOEAvoidEffectList[lv_index].lv_startOffset;
            if ((libAIAI_gv_heroAIAOEAvoidEffectList[lv_index].lv_followsUnit == true)) {
                lv_unit = EventPlayerEffectUsedUnit(c_effectUnitTarget);
            }
            else {
            }
        }
        else {
        }
    }
    lv_position = EventPlayerEffectUsedPoint(c_effectLocationTargetPoint);
    lv_startTime = (TimerGetElapsed(libGame_gv_gameTimer) + libAIAI_gv_aIHeroAvoidAOEMinResponseTime + lv_startOffset);
    lv_expireTime = (TimerGetElapsed(libGame_gv_gameTimer) + lv_duration + lv_startOffset);
    if ((libNtve_gf_PlayerIsEnemy(libCore_gv_cOMPUTER_TeamOrder, UnitGetOwner(EventPlayerEffectUsedUnit(c_effectUnitCaster)), 4) == true) && (libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas < libAIAI_gv_heroAIMaxNumberofAvoidAreas)) {
        libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas += 1;
        libAIAI_gv_heroAITeamData[(0)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas].lv_unit = lv_unit;
        libAIAI_gv_heroAITeamData[(0)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas].lv_position = lv_position;
        libAIAI_gv_heroAITeamData[(0)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas].lv_radius = lv_radius;
        libAIAI_gv_heroAITeamData[(0)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas].lv_startTime = lv_startTime;
        libAIAI_gv_heroAITeamData[(0)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(0)].lv_numberofAvoidAreas].lv_expireTime = lv_expireTime;
        lv_notifyTeamOrder = true;
    }
    else {
    }
    if ((libNtve_gf_PlayerIsEnemy(libCore_gv_cOMPUTER_TeamChaos, UnitGetOwner(EventPlayerEffectUsedUnit(c_effectUnitCaster)), 4) == true) && (libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas < libAIAI_gv_heroAIMaxNumberofAvoidAreas)) {
        libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas += 1;
        libAIAI_gv_heroAITeamData[(1)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas].lv_unit = lv_unit;
        libAIAI_gv_heroAITeamData[(1)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas].lv_position = lv_position;
        libAIAI_gv_heroAITeamData[(1)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas].lv_radius = lv_radius;
        libAIAI_gv_heroAITeamData[(1)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas].lv_startTime = lv_startTime;
        libAIAI_gv_heroAITeamData[(1)].lv_avoidAreas[libAIAI_gv_heroAITeamData[(1)].lv_numberofAvoidAreas].lv_expireTime = lv_expireTime;
        lv_notifyTeamChaos = true;
    }
    else {
    }
    Wait((libAIAI_gv_aIHeroAvoidAOEMinResponseTime + lv_startOffset), c_timeGame);
    if ((lv_notifyTeamOrder == true)) {
        libAIAI_gf_HeroAINotifyAOEStarting(0, lv_position, lv_radius, lv_expireTime);
    }
    else {
    }
    if ((lv_notifyTeamChaos == true)) {
        libAIAI_gf_HeroAINotifyAOEStarting(1, lv_position, lv_radius, lv_expireTime);
    }
    else {
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void libAIAI_gt_HeroAIWatchForAOEAbilityCasted_Init () {
    libAIAI_gt_HeroAIWatchForAOEAbilityCasted = TriggerCreate("libAIAI_gt_HeroAIWatchForAOEAbilityCasted_Func");
    TriggerEnable(libAIAI_gt_HeroAIWatchForAOEAbilityCasted, false);
}

void libAIAI_InitTriggers () {
    libAIAI_gt_IncludeAI_Init();
    libAIAI_gt_MinionAIAIRoutine_Init();
    libAIAI_gt_MinionAIGateDies_Init();
    libAIAI_gt_MinionAITownDataInitialized_Init();
    libAIAI_gt_TowerAIRoutine_Init();
    libAIAI_gt_InitializeTowerAISystem_Init();
    libAIAI_gt_DefenderAICreepsAttacked_Init();
    libAIAI_gt_DefenderAIDefenderAILogic_Init();
    libAIAI_gt_HeroAIInitializeItemData_Init();
    libAIAI_gt_HeroAIInitializeDifficultyLevelData_Init();
    libAIAI_gt_HeroAIInitializeHeroTierData_Init();
    libAIAI_gt_HeroAIGameStarted_Init();
    libAIAI_gt_HeroAIRunMainGroupLoop_Init();
    libAIAI_gt_HeroAITakeOverHero_Init();
    libAIAI_gt_HeroAIReleaseHeroControl_Init();
    libAIAI_gt_HeroAITownDataInitialized_Init();
    libAIAI_gt_HeroAITowerDies_Init();
    libAIAI_gt_HeroAIFollowerCommand_Init();
    libAIAI_gt_HeroAIHeroTakesDamage_Init();
    libAIAI_gt_HeroAIHeroEntersAfterDeathState_Init();
    libAIAI_gt_HeroAIHeroDies_Init();
    libAIAI_gt_HeroAIHumanAllyInitiatesFight_Init();
    libAIAI_gt_HeroAITributeWarning_Init();
    libAIAI_gt_HeroAITributeSpawned_Init();
    libAIAI_gt_HeroAITributePickedUp_Init();
    libAIAI_gt_HeroAIRavenLordCurseStarts_Init();
    libAIAI_gt_HeroAIRavenLordCurseEnds_Init();
    libAIAI_gt_HeroAIGhostShipShowsUp_Init();
    libAIAI_gt_HeroAIGhostShipShootingStarts_Init();
    libAIAI_gt_HeroAIGhostShipShootingEnds_Init();
    libAIAI_gt_HeroAIDoubloonsTurnedIn_Init();
    libAIAI_gt_HeroAITreasureChestsSpawns_Init();
    libAIAI_gt_HeroAIDragonShireObelisksSpawned_Init();
    libAIAI_gt_HeroAIDragonShrireObeliskChangesOwner_Init();
    libAIAI_gt_HeroAIDragonShireDragonActivated_Init();
    libAIAI_gt_HeroAIDragonShireDragonEnds_Init();
    libAIAI_gt_HeroAIUnderworldUndeadSpawned_Init();
    libAIAI_gt_HeroAIUnderworldSkullCollected_Init();
    libAIAI_gt_HeroAIUnderworldBossWarning_Init();
    libAIAI_gt_HeroAIUnderworldBossSpawned_Init();
    libAIAI_gt_HeroAIUnderworldBossDies_Init();
    libAIAI_gt_HeroAIWatchForAOEAbilityCasted_Init();
}

//--------------------------------------------------------------------------------------------------
// Library Initialization
//--------------------------------------------------------------------------------------------------
bool libAIAI_InitLib_completed = false;

void libAIAI_InitLib () {
    if (libAIAI_InitLib_completed) {
        return;
    }

    libAIAI_InitLib_completed = true;

    libAIAI_InitLibraries();
    libAIAI_InitVariables();
    libAIAI_InitTriggers();
}

include "TriggerLibs/HeroesLib"
include "TriggerLibs/GameLib"
include "TriggerLibs/MapMechanicsLib"
include "TriggerLibs/UILib"
include "TriggerLibs/SoundLib"
include "TriggerLibs/SupportLib"

