diff --git a/Blizzard.eai b/Blizzard.eai index 51bf3ebf3..3cda580e2 100644 --- a/Blizzard.eai +++ b/Blizzard.eai @@ -587,24 +587,11 @@ function ZoomUp takes nothing returns nothing endfunction function InitZoom takes nothing returns nothing - local integer i = 0 - if ZoomSetx == null then - set ZoomSetx = CreateTrigger() - set AdjustZoomUp = CreateTrigger() - set AdjustZoomDown = CreateTrigger() - call TriggerAddAction(ZoomSetx, function ZoomSet) - //call TriggerAddAction(AdjustZoomUp , function ZoomUp) - //call TriggerAddAction(AdjustZoomDown , function ZoomDown) - //loop - // exitwhen i >= GetBJMaxPlayers() - //call SetCameraFieldForPlayer( Player(i), CAMERA_FIELD_TARGET_DISTANCE, 2500, 0 ) // not required in latest war3 - if (GetPlayerController(GetLocalPlayer()) != MAP_CONTROL_COMPUTER) or IsPlayerObserver(GetLocalPlayer()) then - call TriggerRegisterPlayerChatEvent( ZoomSetx, GetLocalPlayer(), "-zoom", false ) - //call TriggerRegisterPlayerKeyEventBJ( AdjustZoomUp, Player(i), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_UP ) // not required in latest war3 - //call TriggerRegisterPlayerKeyEventBJ( AdjustZoomDown, Player(i), bj_KEYEVENTTYPE_DEPRESS, bj_KEYEVENTKEY_DOWN ) - endif - // set i = i + 1 - //endloop + set ZoomSetx = CreateTrigger() + call TriggerAddAction(ZoomSetx, function ZoomSet) + if (GetPlayerController(GetLocalPlayer()) != MAP_CONTROL_COMPUTER) and not IsPlayerObserver(GetLocalPlayer()) then + call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,7,"Set Zoom type: |c00d5f038-zoom1850|r") + call TriggerRegisterPlayerChatEvent( ZoomSetx, GetLocalPlayer(), "-zoom", false ) endif endfunction diff --git a/CHANGELOG.md b/CHANGELOG.md index abe6b48b2..c21a2a1e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added opportunities to attempt extreme save behaviour when the AI is struggling e.g Do a militia expansion or ancient expansion (jzy-chitong56) - Some improvements to handle multiple mines at the same base (jzy-chitong56) - Use the cloak of shadows ability in micro actions (jzy-chitong56) +- Maps with multiple mines at the starting location can now be handled. (jzy-chitong56) +- Some expansions when far away or impossible to get to will be attempted with a zeppelin. (jzy-chitong56) ### Changed - Chinese Translation improvements. (jzy-chitong56) @@ -32,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - ROC BLADE MASTER will no longer use mirror image. - DEMON HUNTERS will can now sometimes learn Immolation. - Shredders now replace 10 peons (instead of 8) +- Improvements to worker logic at game start. (jzy-chitong56) ### Removed - (DevTools) Old non-working installer has now been removed now we have new version in place. diff --git a/Jobs.txt b/Jobs.txt index 586ca4a5b..5d9a34342 100644 --- a/Jobs.txt +++ b/Jobs.txt @@ -10,7 +10,7 @@ DETECT_DOUBLE_EXP 10 DetectDoubleExpJob() true 100 120 ZEPPELIN_FOLLOW 20 ZeppelinFollowJob() true 80 100 NEUTRAL_GUARDED 8 NeutralGuardedJob(par) false 0 0 REPAIR_CONTROL 15 RepairControlJob() true 0 10 -WISP_CHECK 10 WispCheckJob() race_manual_loading 200 220 +HARVEST_CHECK 10 HarvestCheckJob() race_manual_loading or ( not race_manual_loading and not race_uses_mine_expansion and first_town_mine == 3) or (race_uses_mine_expansion and first_town_mine != 0) 200 - Min(first_town_mine,1) * 198 220 - Min(first_town_mine,1) * 208 RETREAT_CONTROL 100 RetreatControlJob() false 0 0 CLEANUP_BLOCKS 4 CleanupBlocksJob() true 60 70 RESET_GUARD_POSITION 20 ResetGuardPositionJob(unit_par) false 0 0 diff --git a/Jobs/ANCIENT_EXPANSION.eai b/Jobs/ANCIENT_EXPANSION.eai index ca9f782f3..d92519ce1 100644 --- a/Jobs/ANCIENT_EXPANSION.eai +++ b/Jobs/ANCIENT_EXPANSION.eai @@ -70,7 +70,7 @@ if GetGold() < GetUnitGoldCost2(racial_expansion) or GetWood() < GetUnitWoodCost if ancient_exp_wisp == null or not UnitAlive(ancient_exp_wisp) then set ancient_exp_wisp = GetExpansionPeon() if ancient_exp_wisp == null then - set ancient_exp_wisp = GetExpansionPeon2() + set ancient_exp_wisp = GetExpansionPeon2(ancient_exp_wisp) endif endif if u != null then @@ -122,7 +122,7 @@ elseif ancient_exp_state == 1 then call IssuePointOrderByIdLoc(ancient_exp_wisp, old_id[racial_expansion], ancient_exp_loc) call TQAddJob(5, ANCIENT_EXPANSION, 0) else - set ancient_exp_unit = GetOneOfIdNearLoc(ai_player, old_id[racial_expansion], ancient_exp_loc, 400) + set ancient_exp_unit = GetOneOfIdNearLoc(ancient_exp_unit, ai_player, old_id[racial_expansion], ancient_exp_loc, 400) if ancient_exp_unit == null and TownCount(race_manual_loading_mine) == 0 then // no mine , check all hall set ancient_exp_unit = GetOneOfId(ai_player, old_id[racial_expansion]) if ancient_exp_unit == null then diff --git a/Jobs/FOCUSFIRE_CONTROL.eai b/Jobs/FOCUSFIRE_CONTROL.eai index 198848401..bc020acaf 100644 --- a/Jobs/FOCUSFIRE_CONTROL.eai +++ b/Jobs/FOCUSFIRE_CONTROL.eai @@ -287,7 +287,7 @@ function FocusFireJob takes nothing returns nothing call DisplayToAllJobDebug("FOCUSFIRE_CONTROL JOB START") if major_hero == null or not UnitAlive(major_hero) or IsUnitInGroup(major_hero, unit_healing) then - set major_hero = GetMajorHeroReplacement_k(last_major_hero_loc) + set major_hero = GetMajorHeroReplacement_k(major_hero,last_major_hero_loc) endif //if retreat_controlled and (attack_running or town_threatened) then diff --git a/Jobs/HARVEST_CHECK.eai b/Jobs/HARVEST_CHECK.eai new file mode 100644 index 000000000..90d4e5dcf --- /dev/null +++ b/Jobs/HARVEST_CHECK.eai @@ -0,0 +1,162 @@ +#IFDEF GLOBAL + unit secondmine = null +#ELSE +function PeonMineCheck takes unit mine returns boolean + local group g = CreateGroup() + local group tempg = null + local location unitloc = GetUnitLoc(mine) + local unit u = null + local unit savewisp = null + local integer i = 0 + local integer peon = TownCount(racial_peon) + local integer peond = TownCountDone(racial_peon) + local integer delaywisps = ver_optimal_gold - 1 + call DisplayToAllJobDebug("HARVEST CHECK Job Start") + if peond > 6 then + set delaywisps = ver_optimal_gold + endif + if race_manual_loading then + call GroupEnumUnitsOfPlayer(g, ai_player, null) + set g = SelectById(g, old_id[race_manual_loading_wisp], true) + set g = SelectByAlive(g, true) + set tempg = CreateGroup() + loop + set u = FirstOfGroup(g) + exitwhen u == null + if IsUnitInTransport(u, mine) then + set savewisp = u + set i = i + 1 + elseif not IsUnitHidden(u) then + call GroupAddUnit(tempg, u) + endif + call GroupRemoveUnit(g, u) + endloop + if FoodSpace() <= 0 and i >= 3 then // no foodspace , no peon(at least keep 2 harvest mine) , need one harvest mine peon build Farms + if peon == peond and peon <= 4 then + set delaywisps = 2 + call IssueTargetOrder(mine, "unload", savewisp) + endif + elseif peond < 7 and not hero_built[1] then + set delaywisps = ver_optimal_gold - 2 + endif + if i < delaywisps then + set tempg = SelectByLoaded(tempg, false) + set tempg = SelectUnittype(tempg, UNIT_TYPE_STRUCTURE, false) // Preventing Tree Transformation + set tempg = GetNearestSubGroupOfGroup(tempg, unitloc, delaywisps - i) + //call GroupRemoveGuardPositionInstant(g) // this gets wisps to come off the trees. + //call GroupTargetOrder(g, "harvest", mine) + loop //use accurate quantity control , prevent any wips harvestmine , but mine no vacancies + set u = FirstOfGroup(tempg) + exitwhen u == null or i == delaywisps + call IssueTargetOrder(u, "harvest", mine) + set i = i + 1 + call GroupRemoveUnit(tempg, u) + endloop + endif + call DestroyGroup(tempg) + set tempg = null + set savewisp = null + elseif race_uses_mine_expansion then + set delaywisps = Min(ver_optimal_gold,peond) + call GroupEnumUnitsOfPlayer(g, ai_player, null) + set g = SelectUnittype(g, UNIT_TYPE_PEON, true) + set g = SelectByAlive(g, true) + set g = SelectByHidden(g, false) + set tempg = CreateGroup() + loop + set u = FirstOfGroup(g) + exitwhen u == null or i == delaywisps + if GetUnitCurrentOrder(u) == OrderId("harvest") and DistanceBetweenUnits(u,mine) < 225 then // UD harvest gold max Distance is 221 + set i = i + 1 + elseif GetUnitCurrentOrder(u) == 0 and not IsUnitBuying(u) and not IsUnitInGroup(u, unit_zepplin_move) then + call GroupAddUnit(tempg,u) // prevent the mine harvest peon more than 5 + endif + call GroupRemoveUnit(g, u) + endloop + if i < delaywisps then + loop + set u = FirstOfGroup(tempg) + exitwhen u == null or i == delaywisps + call IssueTargetOrder(u, "harvest", mine) + set i = i + 1 + call GroupRemoveUnit(tempg, u) + endloop + endif + call DestroyGroup(tempg) + set tempg = null + else //human and orc + call GroupEnumUnitsOfPlayer(g, ai_player, null) + set g = SelectUnittype(g, UNIT_TYPE_PEON, true) + set g = SelectByAlive(g, true) + set g = SelectByHidden(g, false) + set g = GetNearestSubGroupOfGroup(g, home_location, 10) + loop + set u = FirstOfGroup(g) + exitwhen u == null or i == delaywisps + if (GetUnitCurrentOrder(u) == 0 or GetUnitCurrentOrder(u) == OrderId("harvest")) and not IsUnitBuying(u) and not IsUnitInGroup(u, unit_zepplin_move) then // no get other order peon , maybe the peon go buy unit or build some + call IssueTargetOrder(u, "harvest", mine) + endif + call GroupRemoveUnit(g, u) + set i = i + 1 + endloop + set i = delaywisps //human and orc no need full + endif + call RemoveLocation(unitloc) + set unitloc = null + call DestroyGroup(g) + set g = null + set u = null + return i < delaywisps +endfunction + +function HarvestCheckJob takes nothing returns nothing + local group g = null + local unit u = null + local integer i = 0 + local boolean mines_not_full = true + // call DisplayToAll("Harvest Start") + if first_town_mine == -1 then + return // home_location no more mine , ORC and HUMAN no need run + endif + set g = CreateGroup() + if race_manual_loading then + call GroupEnumUnitsOfPlayer(g, ai_player, null) + set g = SelectNumberOfId(g, 100, old_id[race_manual_loading_mine]) + elseif not TownThreatened() then + if race_uses_mine_expansion then + call GroupEnumUnitsInRangeOfLoc(g, home_location, 1500, null) + set g = SelectByPlayer(g, ai_player, true) + set g = SelectById(g, old_id[racial_expansion], true) + elseif GetResourceAmount(secondmine) <= 0 and TownCountDone(racial_peon) > 10 then //human and orc + call GroupEnumUnitsInRangeOfLoc(g, home_location, 1500, null) + call GroupRemoveUnit(g,own_town_mine[0]) + set g = SelectById(g, old_id[GOLD_MINE], true) + loop + set u = FirstOfGroup(g) + exitwhen u == null + if GetResourceAmount(u) > i then // find Resource max mine + set i = GetResourceAmount(u) + set secondmine = u + endif + call GroupRemoveUnit(g, u) + endloop + call GroupAddUnit(g, secondmine) // only first take secondmine run PeonMineCheck , Prevention have more peon harvest + endif + endif + loop + set u = FirstOfGroup(g) + exitwhen u == null + if UnitAlive(u) then + set mines_not_full = PeonMineCheck(u) and mines_not_full + endif + call GroupRemoveUnit(g, u) + endloop + call DestroyGroup(g) + set g = null + if mines_not_full then + call TQAddJob(4, HARVEST_CHECK, 0) + else + call TQAddJob(40, HARVEST_CHECK, 0) + endif +endfunction +#ENDIF \ No newline at end of file diff --git a/Jobs/HEALTH_FOUNTAIN.eai b/Jobs/HEALTH_FOUNTAIN.eai index 5642d6eb5..e7d8b8261 100644 --- a/Jobs/HEALTH_FOUNTAIN.eai +++ b/Jobs/HEALTH_FOUNTAIN.eai @@ -60,19 +60,15 @@ local boolean creepsawake = false if distance >= buy_distance then if GetUnitAbilityLevel(u, 'AIhm') > 0 or (GetUnitAbilityLevel(u, 'Ashm') > 0 and GetLocationNonCreepStrength(GetUnitX(u), GetUnitY(u), 800) > 0 and (GetFloatGameState(GAME_STATE_TIME_OF_DAY) >= 18 or GetFloatGameState(GAME_STATE_TIME_OF_DAY) <= 6)) then call IssueImmediateOrder(u, "ambush") - else - if GetUnitCurrentOrder(u) != OrderId("move") then - call IssuePointOrder(u, "move", x, y) - endif + elseif GetUnitCurrentOrder(u) != OrderId("move") then + call IssuePointOrder(u, "move", x, y) endif else if IsUnitInvisible(u, Player(PLAYER_NEUTRAL_AGGRESSIVE)) then //no need do anything elseif GetUnitAbilityLevel(u, 'AIhm') > 0 or (GetUnitAbilityLevel(u, 'Ashm') > 0 and (GetFloatGameState(GAME_STATE_TIME_OF_DAY) >= 18 or GetFloatGameState(GAME_STATE_TIME_OF_DAY) <= 6)) then call IssueImmediateOrder(u, "ambush") - else - if GetUnitCurrentOrder(u) != OrderId("patrol") then - call IssuePointOrder( u, "patrol", x + GetRandomReal(-100,100), y + GetRandomReal(-100,100)) //Prevent units from being blocked by other units coming from behind when leaving - endif + elseif not IsUnitType(u, UNIT_TYPE_FLYING) and GetUnitCurrentOrder(u) != OrderId("patrol") then + call IssuePointOrder( u, "patrol", x + GetRandomReal(-100,100), y + GetRandomReal(-100,100)) //Prevent units from being blocked by other units coming from behind when leaving endif endif call TQAddUnitJob(8, HEALTH_FOUNTAIN, p, u) diff --git a/Jobs/ITEM_EXPANSION.eai b/Jobs/ITEM_EXPANSION.eai index 49fa36b75..6921b7815 100644 --- a/Jobs/ITEM_EXPANSION.eai +++ b/Jobs/ITEM_EXPANSION.eai @@ -29,7 +29,7 @@ function ItemExpansionJob takes nothing returns nothing call Trace("Expansion Distance: " + Int2Str(R2I(GetExpansionDistance()))) call Trace("Expansion state 0: Check Expansion Hero and Location") if itemhero == null then - set exp_item = GetItemOfType(race_item_expansion_item_id) + set exp_item = GetItemOfType(exp_item,race_item_expansion_item_id) if exp_item != null then set itemhero = GetItemHero(exp_item) endif @@ -110,4 +110,4 @@ function ItemExpansionJob takes nothing returns nothing set u = null call TQAddJob(time_next_try, ITEM_EXPANSION, 0) endfunction -#ENDIF \ No newline at end of file +#ENDIF diff --git a/Jobs/MANA_FOUNTAIN.eai b/Jobs/MANA_FOUNTAIN.eai index ac9d68806..e357996e7 100644 --- a/Jobs/MANA_FOUNTAIN.eai +++ b/Jobs/MANA_FOUNTAIN.eai @@ -58,23 +58,19 @@ local boolean creepsawake = false if distance >= buy_distance then if GetUnitAbilityLevel(u, 'AIhm') > 0 or (GetUnitAbilityLevel(u, 'Ashm') > 0 and GetLocationNonCreepStrength(GetUnitX(u), GetUnitY(u), 800) > 0 and (GetFloatGameState(GAME_STATE_TIME_OF_DAY) >= 18 or GetFloatGameState(GAME_STATE_TIME_OF_DAY) <= 6)) then call IssueImmediateOrder(u, "ambush") - else - if GetUnitCurrentOrder(u) != OrderId("move") then - call IssuePointOrder(u, "move", x, y) - endif + elseif GetUnitCurrentOrder(u) != OrderId("move") then + call IssuePointOrder(u, "move", x, y) endif else if IsUnitInvisible(u, Player(PLAYER_NEUTRAL_AGGRESSIVE)) then //no need do anything elseif GetUnitAbilityLevel(u, 'AIhm') > 0 or (GetUnitAbilityLevel(u, 'Ashm') > 0 and (GetFloatGameState(GAME_STATE_TIME_OF_DAY) >= 18 or GetFloatGameState(GAME_STATE_TIME_OF_DAY) <= 6)) then call IssueImmediateOrder(u, "ambush") - else - if GetUnitCurrentOrder(u) != OrderId("patrol") then - call IssuePointOrder( u, "patrol", x + GetRandomReal(-100,100), y + GetRandomReal(-100,100)) //Prevent units from being blocked by other units coming from behind when leaving - endif + elseif not IsUnitType(u, UNIT_TYPE_FLYING) and GetUnitCurrentOrder(u) != OrderId("patrol") then + call IssuePointOrder( u, "patrol", x + GetRandomReal(-100,100), y + GetRandomReal(-100,100)) //Prevent units from being blocked by other units coming from behind when leaving endif endif call TQAddUnitJob(8, MANA_FOUNTAIN, p, u) endif set fountain = null endfunction -#ENDIF \ No newline at end of file +#ENDIF diff --git a/Jobs/MICRO_HERO.eai b/Jobs/MICRO_HERO.eai index b45de3f09..ee29c15af 100644 --- a/Jobs/MICRO_HERO.eai +++ b/Jobs/MICRO_HERO.eai @@ -178,7 +178,7 @@ function SaveHero takes integer hn , integer armyOfHero returns nothing local integer hFountainID = GetHealthFountainID() local integer mFountainID = GetManaFountainID() local location l = GetUnitLoc(hero_unit[hn]) - set healer = GetHealer() + set healer = GetHealer(healer) call ActionListInit(9) #INCLUDE call ExecuteSaveHero(hn, ActionListEval(), healer) @@ -222,11 +222,9 @@ function MicroHeroJob takes integer hn returns nothing set hero_hp[hn] = new_hp call GetDensities(hero_loc[hn], ai_player, hero_radius) set hero_enemy_density[hn] = enemy_density - call RemoveLocation(hero_enemy_loc[hn]) - set hero_enemy_loc[hn] = Location(GetLocationX(enemy_density_loc), GetLocationY(enemy_density_loc)) + call MoveLocation(hero_enemy_loc[hn], GetLocationX(enemy_density_loc), GetLocationY(enemy_density_loc)) set hero_ally_density[hn] = ally_density - call RemoveLocation(hero_ally_loc[hn]) - set hero_ally_loc[hn] = Location(GetLocationX(ally_density_loc), GetLocationY(ally_density_loc)) + call MoveLocation(hero_ally_loc[hn], GetLocationX(ally_density_loc), GetLocationY(ally_density_loc)) if not teleporting and current_order >= 852008 and current_order <= 852013 then if GetItemTypeId(UnitItemInSlot(hero_unit[hn], current_order - 852008)) == old_id[tp_item] then diff --git a/Jobs/MICRO_UNITS.eai b/Jobs/MICRO_UNITS.eai index b52b40732..c1ddedbb3 100644 --- a/Jobs/MICRO_UNITS.eai +++ b/Jobs/MICRO_UNITS.eai @@ -4,9 +4,9 @@ group unit_rescueing = CreateGroup() group unit_harassing = CreateGroup() group unit_zepplin_move = CreateGroup() - group unit_buying_item = CreateGroup() - group unit_buying_merc = CreateGroup() - group unit_buying_tavern = CreateGroup() + group unit_buying_item = CreateGroup() + group unit_buying_merc = CreateGroup() + group unit_buying_tavern = CreateGroup() #ELSE @@ -16,7 +16,7 @@ //function MakeUnitHeal takes unit u returns nothing -// local unit healer = GetHealer() +// local unit healer = GetHealer(healer) // local location unitloc = GetUnitLoc(healer) // local real daytime = GetFloatGameState(GAME_STATE_TIME_OF_DAY) @@ -84,7 +84,7 @@ function SaveUnit takes unit u , integer id returns nothing call IssueImmediateOrder(u, "windwalk") endif endif - set healer = GetHealer() + set healer = GetHealer(healer) // call SetUnitUserData(u, UNIT_GOING_HOME) if healer != null then //and not IsUnitType(u, UNIT_TYPE_MECHANICAL) then //Repetitive judgment set healertepy = healer_type[GetHealerId(GetUnitTypeId(healer))] diff --git a/Jobs/MILITIA_CHECK.eai b/Jobs/MILITIA_CHECK.eai index 7593396a2..283381f3c 100644 --- a/Jobs/MILITIA_CHECK.eai +++ b/Jobs/MILITIA_CHECK.eai @@ -4,9 +4,8 @@ unit militia_hall = null boolean use_militia_only_on_bigger_threats = false #ELSE -function GetMilitiaHall takes nothing returns unit +function GetMilitiaHall takes unit u returns unit local group g = CreateGroup() - local unit u = null call GroupEnumUnitsOfPlayer(g, ai_player, null) loop set u = FirstOfGroup(g) @@ -20,7 +19,7 @@ function GetMilitiaHall takes nothing returns unit endloop call DestroyGroup(g) set g = null - return null + return u endfunction function IsMilitiaAllowed takes nothing returns boolean @@ -35,36 +34,36 @@ function IsMilitiaAllowed takes nothing returns boolean endfunction function MilitiaCheckJob takes nothing returns nothing - local group g = CreateGroup() + local group g =null local unit u = null local integer i = 0 local boolean big_dist = false - local location unitloc = null local integer militiarequired = 0 - call DisplayToAllJobDebug("MILITIA_CHECK JOB START") if militia_hall == null or GetUnitState(militia_hall, UNIT_STATE_LIFE) <= 0 or UnitAlive(militia_hall) == false then - set militia_hall = GetMilitiaHall() - endif + set militia_hall = GetMilitiaHall(militia_hall) + endif + if race_militia_available and (militia_hall == null or towerrush) then + call TQAddJob(30, MILITIA_CHECK, 0) + return + endif if militia_check_enabled and GetUnitState(militia_hall, UNIT_STATE_LIFE) > 0 then set militia_allowed = IsMilitiaAllowed() + set g = CreateGroup() call GroupEnumUnitsOfType(g, race_militia_unitstring, null) set g = SelectByPlayer(g, ai_player, true) loop set u = FirstOfGroup(g) exitwhen u == null - set unitloc = GetUnitLoc(u) - if not militia_allowed or DistanceBetweenPoints(unitloc, home_location) > race_militia_max_distance then + if not militia_allowed or DistanceBetweenPoints_dk(GetUnitLoc(u), home_location) > race_militia_max_distance then call IssueImmediateOrder(u, "militiaoff") endif call GroupRemoveUnit(g,u) - call RemoveLocation(unitloc) - set unitloc = null endloop - set militiarequired = Max(1,GetLocationNonCreepStrength(GetUnitX(militia_hall), GetUnitY(militia_hall), 1500)/2) // Militia are 2 strength so divide total enemy strength by 2 + set militiarequired = Max(1,GetLocationNonCreepStrength(GetUnitX(militia_hall), GetUnitY(militia_hall), 1500)/2) // Militia are 2 strength so divide total enemy strength by 2 call GroupEnumUnitsOfType(g, race_militiaworker_unitstring, null) set g = SelectByPlayer(g, ai_player, true) - set g = SelectByAlive(g, true) + set g = SelectByAlive(g, true) loop set u = FirstOfGroup(g) exitwhen u == null @@ -81,12 +80,12 @@ function MilitiaCheckJob takes nothing returns nothing endif call GroupRemoveUnit(g,u) endloop + call DestroyGroup(g) + set g = null endif - call DestroyGroup(g) - set g = null //if GetUnitAbilityLevel(militia_hall, race_militia_hall_ability) > 0 then if race_militia_available then - call TQAddJob(5, MILITIA_CHECK, 0) + call TQAddJob(5, MILITIA_CHECK, 0) endif endfunction -#ENDIF \ No newline at end of file +#ENDIF diff --git a/Jobs/RETREAT_CONTROL.eai b/Jobs/RETREAT_CONTROL.eai index cf60b0546..bc669a416 100644 --- a/Jobs/RETREAT_CONTROL.eai +++ b/Jobs/RETREAT_CONTROL.eai @@ -7,14 +7,14 @@ location home_location = null real enemy_strength_sum = 0 real ally_strength_sum = 0 - boolean isfleeing = false - integer added_target_aggression = 0 // The current bonus aggression added to current attack specified in the profiles - integer added_racial_aggression = 0 // The current bonus added to current attack based on which race amai is attacking - + boolean isfleeing = false + integer added_target_aggression = 0 // The current bonus aggression added to current attack specified in the profiles + integer added_racial_aggression = 0 // The current bonus added to current attack based on which race amai is attacking + location enemy_loc = Location(0,0) location last_enemy_loc = Location(0,0) location ally_loc = Location(0,0) - location last_ally_loc = Location(0,0) + location last_ally_loc = Location(0,0) #ELSE //============================================================================ @@ -22,7 +22,7 @@ //============================================================================ // function RetreatControlJob takes nothing returns nothing - local group g = CreateGroup() + local group g = null local real ally_sum = 0 local real enemy_sum = 0 local real creep_sum = 0 @@ -36,21 +36,23 @@ function RetreatControlJob takes nothing returns nothing local integer num_units = 0 local real ally_strength = 0 local real enemy_strength = 0 - local location l = null - + local real xa = 0 + local real ya = 0 + local real xe = 0 + local real ye = 0 + // local variables used to calculate roughly where the current enemy army is located at local integer ally_count = 0 - local integer enemy_count = 0 - + local integer enemy_count = 0 call DisplayToAllJobDebug("RETREAT_CONTROL JOB Start") if major_hero == null or not UnitAlive(major_hero) then - set major_hero = GetMajorHeroReplacement_k(last_major_hero_loc) + set major_hero = GetMajorHeroReplacement_k(major_hero,last_major_hero_loc) endif - // call GroupEnumUnitsInRange(g_battle,GetUnitX(major_hero),GetUnitY(major_hero),battle_radius,null) + // call GroupEnumUnitsInRange(g_battle,GetUnitX(major_hero),GetUnitY(major_hero),battle_radius,null) //loop - // set u = FirstOfGroup(g_battle) + // set u = FirstOfGroup(g_battle) // exitwhen u == null // if UnitAlive(u) and IsPlayerAlly(GetOwningPlayer(u), ai_player) and IsUnitType(u, UNIT_TYPE_RANGED_ATTACKER) then // set ally_ranged_strength = ally_ranged_strength + GetUnitStrength(u) @@ -72,7 +74,7 @@ function RetreatControlJob takes nothing returns nothing //call DestroyGroup(g_battle) //set g = null -// if attack_running then +// if attack_running then // if (not (major_hero != null and UnitAlive(major_hero)) and ver_heroes) or CaptainRetreating() or (ally_strength * 3) < enemy_strength then // call DisplayToAll("Retreat control ended") // set break_attack = true @@ -90,7 +92,7 @@ function RetreatControlJob takes nothing returns nothing // // This is if flee control is turned off as the inbuilt unit flee does not help in low hp race mods // call SetUnitsFlee(false) // call SetHeroesFlee(false) -// endif +// endif // else // if (not (major_hero != null and UnitAlive(major_hero)) and ver_heroes) or CaptainRetreating() or (ally_strength * 3) < enemy_strength then // call DisplayToAll("Retreat control ended") @@ -102,106 +104,111 @@ function RetreatControlJob takes nothing returns nothing // if disableretreat then // call SetUnitsFlee(false) // call SetHeroesFlee(false) -// endif +// endif // endif -if not desperation_assault and ((CaptainRetreating() and isfleeing) or town_threatened) then //((major_hero == null or not UnitAlive(major_hero)) and ver_heroes) or then //attack_running and + if not desperation_assault and ((CaptainRetreating() and isfleeing) or town_threatened) then //((major_hero == null or not UnitAlive(major_hero)) and ver_heroes) or then //attack_running and call Trace("===Retreat control ended===") set break_attack = attack_running set retreat_controlled = false call SetGroupsFlee(true) - set l = GetUnitLoc(major_hero) - if DistanceBetweenPoints(home_location, l) < 1250 then - set isfleeing = false // home so no need to be retreating. Also prevents bug in the captainretreating condition - endif - call RemoveLocation(l) - set l = null + if major_hero != null and UnitAlive(major_hero) and DistanceBetweenPoints_kd(home_location, GetUnitLoc(major_hero)) < 1250 then + set isfleeing = false // home so no need to be retreating. Also prevents bug in the captainretreating condition + endif return endif + set g = CreateGroup() if main_army == -1 or army_loc[main_army] == null or (GetLocationX(army_loc[main_army]) == 0 and GetLocationY(army_loc[main_army]) == 0 )then - if major_hero == null then - call Trace("No major hero in retreat control") - endif - call GroupEnumUnitsInRange(g,GetUnitX(major_hero),GetUnitY(major_hero),battle_radius,null) + if major_hero == null or not UnitAlive(major_hero) then + call Trace("No major hero in retreat control") + else + call GroupEnumUnitsInRange(g,GetUnitX(major_hero),GetUnitY(major_hero),battle_radius,null) + endif else - call GroupEnumUnitsInRange(g, GetLocationX(army_loc[main_army]), GetLocationY(army_loc[main_army]), battle_radius, null) + call GroupEnumUnitsInRange(g, GetLocationX(army_loc[main_army]), GetLocationY(army_loc[main_army]), battle_radius, null) endif - - set g = SelectByAlive(g, true) set g = SelectUnittype(g, UNIT_TYPE_STRUCTURE, false) - + set g = SelectByHidden(g, false) + set g = SelectByAlive(g, true) call MoveLocation(last_enemy_loc, GetLocationX(enemy_loc), GetLocationY(enemy_loc)) call MoveLocation(last_ally_loc, GetLocationX(ally_loc), GetLocationY(ally_loc)) - call MoveLocation(enemy_loc, 0,0) - call MoveLocation(ally_loc, 0,0) - + loop set u = FirstOfGroup(g) exitwhen u == null - if GetOwningPlayer(u) != Player(PLAYER_NEUTRAL_AGGRESSIVE) and not IsUnitHidden(u) then - //call Trace("RETREAT_CONTROL: At least 1 unit detected") - set unit_strength = GetUnitStrength(u) - set unit_life = GetUnitState(u, UNIT_STATE_LIFE) - set unit_mana = GetUnitState(u, UNIT_STATE_MANA) - if IsPlayerAlly(GetOwningPlayer(u), ai_player) then - //if GetUnitUserData(u) != UNIT_GOING_HOME then - if not IsUnitInGroup(u, unit_healing) then //and unit_life > RMax(flee_health_percentage * GetUnitState(u, UNIT_STATE_MAX_LIFE), flee_minimum_health) then - set ally_sum = ally_sum + unit_strength - endif - set ally_loc = GetSumLoc_dd(ally_loc, GetUnitLoc(u)) - set ally_count = ally_count + 1 - elseif not (UnitInvis(u) and not IsUnitDetected(u, ai_player)) then - set enemy_sum = enemy_sum + unit_strength - set enemy_loc = GetSumLoc_dd(enemy_loc, GetUnitLoc(u)) - set enemy_count = enemy_count + 1 - endif - elseif GetOwningPlayer(u) == Player(PLAYER_NEUTRAL_AGGRESSIVE) and not IsUnitHidden(u)and not (UnitInvis(u) and not IsUnitDetected(u, ai_player)) then - set unit_strength = GetUnitStrength(u) - set unit_life = GetUnitState(u, UNIT_STATE_LIFE) - set unit_mana = GetUnitState(u, UNIT_STATE_MANA) - set creep_sum = creep_sum + unit_strength - endif + set unit_strength = GetUnitStrength(u) + // set unit_life = GetUnitState(u, UNIT_STATE_LIFE) + // set unit_mana = GetUnitState(u, UNIT_STATE_MANA) + if GetOwningPlayer(u) != Player(PLAYER_NEUTRAL_AGGRESSIVE) then + //call Trace("RETREAT_CONTROL: At least 1 unit detected") + if IsPlayerAlly(GetOwningPlayer(u), ai_player) then + //if GetUnitUserData(u) != UNIT_GOING_HOME then + if not IsUnitInGroup(u, unit_healing) then //and unit_life > RMax(flee_health_percentage * GetUnitState(u, UNIT_STATE_MAX_LIFE), flee_minimum_health) then + set ally_sum = ally_sum + unit_strength + endif + set xa = xa + GetUnitX(u) // Prevent loc exceeding map range + set ya = ya + GetUnitY(u) + //set ally_loc = GetSumLoc_dd(ally_loc, GetUnitLoc(u)) + set ally_count = ally_count + 1 + elseif not (UnitInvis(u) and not IsUnitDetected(u, ai_player)) then + set enemy_sum = enemy_sum + unit_strength + set xe = xe + GetUnitX(u) + set ye = ye + GetUnitY(u) + //set enemy_loc = GetSumLoc_dd(enemy_loc, GetUnitLoc(u)) + set enemy_count = enemy_count + 1 + endif + elseif GetOwningPlayer(u) == Player(PLAYER_NEUTRAL_AGGRESSIVE) and not (UnitInvis(u) and not IsUnitDetected(u, ai_player)) then + // set unit_life = GetUnitState(u, UNIT_STATE_LIFE) + // set unit_mana = GetUnitState(u, UNIT_STATE_MANA) + set creep_sum = creep_sum + unit_strength + endif call GroupRemoveUnit(g,u) endloop call DestroyGroup(g) set g = null - set enemy_loc = GetDivisionLoc_d(enemy_loc, I2R(Max(enemy_count, 1))) - set ally_loc = GetDivisionLoc_d(ally_loc, I2R(Max(ally_count, 1))) -// call SetCaptainHome(0, GetLocationX(ally_loc), GetLocationY(ally_loc)) - + set xe = xe / I2R(Max(enemy_count, 1)) + set ye = ye / I2R(Max(enemy_count, 1)) + set xa = xa / I2R(Max(ally_count, 1)) + set ya = ya / I2R(Max(ally_count, 1)) + call MoveLocation(enemy_loc, xe, ye) + call MoveLocation(ally_loc, xa, ya) + //set enemy_loc = GetDivisionLoc_d(enemy_loc, I2R(Max(enemy_count, 1))) + //set ally_loc = GetDivisionLoc_d(ally_loc, I2R(Max(ally_count, 1))) + // call SetCaptainHome(0, GetLocationX(ally_loc), GetLocationY(ally_loc)) + set enemy_strength_sum = enemy_sum set ally_strength_sum = ally_sum - //call Trace("RETREAT_CONTROL: Our strength: " + Int2Str(R2I(ally_strength_sum))) + //call Trace("RETREAT_CONTROL: Our strength: " + Int2Str(R2I(ally_strength_sum))) //call Trace("RETREAT_CONTROL: Enemy strength: " + Int2Str(R2I(enemy_strength_sum))) - + if not desperation_assault and enemy_sum > LinearInterpolation(ver_low_aggression,ver_high_aggression,ver_flee_multiple2,ver_flee_multiple3,attacking_aggression + added_aggression + added_target_aggression + added_racial_aggression)*ally_sum or (town_threatened and attack_running) then call Trace("RETREAT_CONTROL: Flee!!!!") set break_attack = attack_running - set retreat_controlled = false - call ClearCaptainTargets() - call CaptainGoHome() - set isfleeing = true - return + set retreat_controlled = false + call ClearCaptainTargets() + call CaptainGoHome() + set isfleeing = true + return elseif not desperation_assault and enemy_sum > LinearInterpolation(ver_low_aggression,ver_high_aggression,ver_flee_multiple1,ver_flee_multiple2,attacking_aggression + added_aggression + added_target_aggression + added_racial_aggression)*ally_sum or (battle_radius == creep_battle_radius and creep_sum - 2 > ally_sum ) then call Trace("RETREAT_CONTROL: Allowed to Flee") call SetGroupsFlee(true) - set isfleeing = true - //call ClearCaptainTargets() - //call CaptainGoHome() + set isfleeing = true + //call ClearCaptainTargets() + //call CaptainGoHome() else - //if town_threatened and town_threat[most_threatened_town] >= teleport_high_threat then - - // else -// call Trace("REATREAT_CONTROL: Stay") - call SetGroupsFlee(false) - set isfleeing = false - // endif + //if town_threatened and town_threat[most_threatened_town] >= teleport_high_threat then + + // else + // call Trace("REATREAT_CONTROL: Stay") + call SetGroupsFlee(false) + set isfleeing = false + // endif endif call TQAddJob(2 * sleep_multiplier, RETREAT_CONTROL, 0) endfunction -#ENDIF \ No newline at end of file +#ENDIF diff --git a/Jobs/WISP_CHECK.eai b/Jobs/WISP_CHECK.eai index ab3831b52..b8014ca1b 100644 --- a/Jobs/WISP_CHECK.eai +++ b/Jobs/WISP_CHECK.eai @@ -2,20 +2,21 @@ #ELSE function ElfMineCheck takes unit mine returns boolean local group g = CreateGroup() + local group tempg = null local location unitloc = GetUnitLoc(mine) local unit u = null local unit v = null local integer i = 0 local integer delaywisps = 0 - - call DisplayToAllJobDebug("WISP_CHECK Job Start") - + + call DisplayToAllJobDebug("WISP_CHECK Job Start") + if TownCountDone(race_manual_loading_wisp) > 6 then - set delaywisps = ver_optimal_gold + set delaywisps = ver_optimal_gold else set delaywisps = ver_optimal_gold - 1 endif - + call GroupEnumUnitsOfPlayer(g, ai_player, null) set g = SelectUnittype(g, UNIT_TYPE_PEON, true) loop @@ -23,7 +24,7 @@ function ElfMineCheck takes unit mine returns boolean exitwhen u == null if IsUnitInTransport(u, mine) then set i = i + 1 - //call RecycleGuardPosition(u) + //call RecycleGuardPosition(u) endif call GroupRemoveUnit(g, u) endloop @@ -31,9 +32,13 @@ function ElfMineCheck takes unit mine returns boolean call GroupEnumUnitsOfPlayer(g, ai_player, null) set g = SelectByLoaded(g, false) set g = SelectNumberOfId(g, 100, old_id[race_manual_loading_wisp]) - set g = GetNearestSubGroupOfGroup(g, unitloc, delaywisps - i) + set tempg = CopyGroup(g) + call DestroyGroup(g) + set g = GetNearestSubGroupOfGroup(tempg, unitloc, delaywisps - i) //call GroupRemoveGuardPositionInstant(g) // this gets wisps to come off the trees. call GroupTargetOrder(g, "harvest", mine) + call DestroyGroup(tempg) + set tempg = null endif call RemoveLocation(unitloc) set unitloc = null @@ -65,4 +70,4 @@ function WispCheckJob takes nothing returns nothing call TQAddJob(20, WISP_CHECK, 0) endif endfunction -#ENDIF +#ENDIF \ No newline at end of file diff --git a/README.md b/README.md index 597aacf7a..61837fb7b 100644 --- a/README.md +++ b/README.md @@ -186,10 +186,10 @@ AMAI has built in support to be able to write new strategies and profiles using - Swedish - Zalamander, - German - AIAndy, Sagan, - French - JUJU, WILL THE ALMIGHTY, -- Spanish - Vexorian, Moyack, +- Spanish - Vexorian, Moyack,, Slayer95, - Romanian - Andas_007, - Chinese - Dr Fan, Sheeryiro, KeamSpring, Pixyy -- Russian - RaZ and Darkloke, +- Russian - RaZ and Darkloke, Lolasik011, - Portuguese - imba curisco ghouleh, - Norwegian - Aray diff --git a/common.eai b/common.eai index 18778f074..3cf0a2886 100644 --- a/common.eai +++ b/common.eai @@ -777,7 +777,7 @@ globals location array own_town_loc real array own_town_dist unit array own_town_mine - + integer first_town_mine = 0 location array exist_town integer exist_town_num = 0 @@ -1809,19 +1809,19 @@ endfunction //============================================================================ // Get a peon. Should be used if you really need a peon and GetExpansionPeon failed -function GetExpansionPeon2 takes nothing returns unit - local group g = CreateGroup() - local unit u = null +function GetExpansionPeon2 takes unit u returns unit + local group g = CreateGroup() - call GroupEnumUnitsOfPlayer(g, ai_player, null) - loop - set u = FirstOfGroup(g) - exitwhen u == null or (GetUnitTypeId(u) == old_id[racial_peon] and GetUnitCurrentOrder(u) != OrderId("repair") and GetUnitCurrentOrder(u) != OrderId("build")) - call GroupRemoveUnit(g, u) - endloop - call DestroyGroup(g) - set g = null - return u + call GroupEnumUnitsOfPlayer(g, ai_player, null) + loop + set u = FirstOfGroup(g) + exitwhen u == null + exitwhen GetUnitTypeId(u) == old_id[racial_peon] and UnitAlive(u) and (GetUnitCurrentOrder(u) == OrderId("harvest") or GetUnitCurrentOrder(u) == 0) and not IsUnitHidden(u) and not IsUnitLoaded(u) + call GroupRemoveUnit(g, u) + endloop + call DestroyGroup(g) + set g = null + return u endfunction //============================================================================ @@ -2719,8 +2719,6 @@ endfunction function InitProfile takes nothing returns nothing local integer i = 0 local integer countplayers = 0 - local player p - local player first = null call set_profiles() @@ -2729,7 +2727,7 @@ function InitProfile takes nothing returns nothing else call Sleep((GetPlayerId(ai_player)*0.02)) // Staggered entry into method for thread safety with profile cache - + loop exitwhen not IsProfileUsed(-1) call Sleep(0.01) @@ -2739,43 +2737,6 @@ function InitProfile takes nothing returns nothing call TracePlayer("Has locked profile selection ID:" + Int2Str(GetPlayerId(ai_player)), GetPlayerId(ai_player)) set profile = GetUnusedProfile(ai_player) - - //set countplayers = 1 - //loop - // exitwhen countplayers > GetBJMaxPlayers() or (first != null) - // set p = Player(countplayers) - // if (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_COMPUTER) then - // if first == null then - // set first = p - // endif - // endif - // set countplayers = countplayers + 1 - //endloop - - //if (first == ai_player) then - // set countplayers = 1 - // loop - // exitwhen countplayers > GetBJMaxPlayers() - // set p = Player(countplayers) - // if (GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_COMPUTER) then - // set profile = GetUnusedProfile(p) - // call DisplayToAllFromPlayer("Set initial profiles player " + Int2Str(countplayers) + " profile " + Int2Str(profile), GetPlayerId(ai_player), false) - // call StoreInteger(amaiCache, Int2Str(PROFILE_SELECTION), Int2Str(countplayers), profile) - // endif - // set countplayers = countplayers + 1 - // endloop - - // call SetProfileUsed(-2) // Unlock other AI's - //else - // loop - // exitwhen IsProfileUsed(-2) - // call Sleep(0.01) - // endloop - //endif - - // If first AI determine every players profiles - - //set profile = GetStoredInteger(amaiCache, Int2Str(PROFILE_SELECTION), Int2Str(GetPlayerId(ai_player))) call SetProfileNotUsed(-1) endif @@ -2792,17 +2753,17 @@ function InitProfile takes nothing returns nothing if add_tag == true and not fixedcomputername and not add_skill then set ai_name = "[AMAI]"+ai_name elseif add_tag == true and not fixedcomputername and add_skill then - if MeleeDifficulty() == EASY then + if difficulty == EASY then set ai_name = "[AMAI Easy]"+ai_name - elseif MeleeDifficulty() == HARD then + elseif difficulty == HARD then set ai_name = "[AMAI Insane]"+ai_name else set ai_name = "[AMAI Normal]"+ai_name endif elseif add_skill == true then - if MeleeDifficulty() == EASY then + if difficulty == EASY then set ai_name = ai_name+" (Easy)" - elseif MeleeDifficulty() == HARD then + elseif difficulty == HARD then set ai_name = ai_name+" (Insane)" else set ai_name = ai_name+" (Normal)" @@ -3265,18 +3226,16 @@ function GetTeleportLandPoint takes location l returns location local real x = GetLocationX(l) local real y = GetLocationY(l) call GroupEnumUnitsInRangeOfLoc(g, l, 900, null) - call RemoveLocation(teleportloc) + call RemoveLocation(teleportloc) // set new loc , cannot return teleportloc loop set u = FirstOfGroup(g) exitwhen u == null //Find a enemy unit , land to unit loc , prevent army land to hall , cannot expand if not IsUnitType(u, UNIT_TYPE_FLYING) and not IsUnitInvisible(u, ai_player) and IsPlayerEnemy(ai_player,GetOwningPlayer(u)) and not IsUnitHidden(u) then - set x = GetUnitX(u) - set y = GetUnitY(u) - set teleportloc = Location(x,y) + set teleportloc = GetUnitLoc(u) call DestroyGroup(g) set g = null set u = null - return Location(x,y) + return GetUnitLoc(u) endif call GroupRemoveUnit(g, u) endloop @@ -4038,8 +3997,7 @@ endfunction //========================================================================== // (AMAI) GetOneOfIdNearLoc //========================================================================== -function GetOneOfIdNearLoc takes player p, integer id, location l, real dist returns unit - local unit u = null +function GetOneOfIdNearLoc takes unit u, player p, integer id, location l, real dist returns unit local group g = CreateGroup() call GroupEnumUnitsInRangeOfLoc(g, l, dist, null) set g = SelectByPlayer(g, p, true) @@ -4057,16 +4015,22 @@ function GetOneOfIdNearLoc takes player p, integer id, location l, real dist ret endloop call DestroyGroup(g) set g = null - return null + return u endfunction //========================================================================== // (AMAI) GetMineNearLoc //========================================================================== -function GetMineNearLoc takes location l, real dist returns unit - local unit u = null - local group g = CreateGroup() +function GetMineNearLoc takes unit u, location l, real dist returns unit + local group g = null local integer i = 0 + local real distance = 1500 + if DistanceBetweenPoints(l , home_location) < 500 then + if own_town_mine[0] != null and GetResourceAmount(own_town_mine[0]) > 0 then + return own_town_mine[0] + endif + endif + set g = CreateGroup() call GroupEnumUnitsInRangeOfLoc(g, l, dist, null) //set g = SelectByAlive(g, true) loop @@ -4093,7 +4057,7 @@ function GetMineNearLoc takes location l, real dist returns unit endloop call DestroyGroup(g) set g = null - return null + return u endfunction //========================================================================== @@ -4484,7 +4448,7 @@ endfunction // (AMAI) GetNearestSubGroupOfGroup // NOTE: Function will remove units from the group passed to it //========================================================================== -function GetNearestSubGroupOfGroup takes group g, location l, integer n returns group +function GetNearestSubGroupOfGroup takes group rg, location l, integer n returns group local unit array ua local real array da local integer size = 0 @@ -4492,7 +4456,8 @@ function GetNearestSubGroupOfGroup takes group g, location l, integer n returns local integer ru = 0 local unit u = null local real d = 0 - local group rg = CreateGroup() + local group g = rg + set rg = CreateGroup() loop set u = FirstOfGroup(g) exitwhen u == null @@ -4521,6 +4486,7 @@ function GetNearestSubGroupOfGroup takes group g, location l, integer n returns set ru = ru + 1 endloop call DestroyGroup(g) + set g = null return rg endfunction @@ -4666,21 +4632,20 @@ endfunction //========================================================================== // (AMAI) GetUnusedZeppelin //========================================================================== -function GetUnusedZeppelinNearUnit takes unit nu returns unit +function GetUnusedZeppelinNearUnit takes unit ru, unit nu returns unit local group g = CreateGroup() - local unit u = null local location unitloc = GetUnitLoc(nu) call GroupEnumUnitsOfType(g, "goblinzeppelin", null) set g = SelectByPlayer(g, ai_player, true) set g = SelectByOrderOr(g, 0, order_cancel, true) set g = SelectByUnitStandard(g, true) - set u = GetNearestOfGroup(g, unitloc) - call RemoveLocation(unitloc) + set ru = GetNearestOfGroup(g, unitloc) call DestroyGroup(g) set g = null + call RemoveLocation(unitloc) set unitloc = null - return u + return ru endfunction //========================================================================== @@ -4755,10 +4720,8 @@ function GetUnitHero takes nothing returns unit return null endfunction -function GetUnitHeroReplacement takes location l returns unit +function GetUnitHeroReplacement takes unit u , location l returns unit local group g = CreateGroup() - local unit u = null - call GroupEnumUnitsOfPlayer(g,ai_player,null) set g = SelectByAlive(g, true) set g = SelectByUnitStandard(g, true) @@ -4766,7 +4729,7 @@ function GetUnitHeroReplacement takes location l returns unit set u = FirstOfGroup(g) exitwhen u == null if IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitType(u, UNIT_TYPE_PEON) == false and IsUnitInRangeLoc(u, l, battle_radius) then - call DestroyGroup(g) + call DestroyGroup(g) set g = null return u endif @@ -4774,7 +4737,7 @@ function GetUnitHeroReplacement takes location l returns unit endloop call DestroyGroup(g) set g = null - return null + return u endfunction function GetMajorHero takes nothing returns unit @@ -4791,9 +4754,8 @@ function GetMajorHero takes nothing returns unit endfunction //========================================================================== -function GetMajorHeroReplacement_d takes location l returns unit +function GetMajorHeroReplacement_d takes unit u, location l returns unit local integer i = 1 - local unit u = null loop exitwhen i > 3 @@ -4803,12 +4765,12 @@ function GetMajorHeroReplacement_d takes location l returns unit endif set i = i + 1 endloop - set u = GetUnitHeroReplacement(l) + set u = GetUnitHeroReplacement(u,l) call RemoveLocation(l) return u endfunction -function GetMajorHeroReplacement_k takes location l returns unit +function GetMajorHeroReplacement_k takes unit u, location l returns unit local integer i = 1 loop @@ -4818,7 +4780,7 @@ function GetMajorHeroReplacement_k takes location l returns unit endif set i = i + 1 endloop - return GetUnitHeroReplacement(l) + return GetUnitHeroReplacement(u,l) endfunction //========================================================================== @@ -4877,6 +4839,7 @@ function GetDensities takes location l, player p, real r returns nothing endif call GroupRemoveUnit(g, u) endloop + if ally_density > 0 then set xa = xa / ally_density set ya = ya / ally_density @@ -5131,9 +5094,7 @@ function GetPlayerAntiAirStrength takes player p returns real endloop call DestroyGroup(g) set g = null - set u = null return sum - endfunction //============================================================================ @@ -5530,7 +5491,7 @@ endfunction //============================================================================ function GetLocationInDistanceFromBaseToLoc takes location loc, real d returns location - local real distance = 0 + local real distance = 0 local real x = 0 local real y = 0 local unit u = null @@ -5614,7 +5575,7 @@ function BuildLumberMillAtBase takes nothing returns boolean local boolean b = false if buildloc != null then if peon == null then - set peon = GetExpansionPeon2() + set peon = GetExpansionPeon2(peon) endif set u = CreateUnitAtLoc(Player(PLAYER_NEUTRAL_PASSIVE), old_id[racial_lumber], buildloc, 270.0) call RemoveLocation(buildloc) @@ -5636,106 +5597,164 @@ endfunction // Gets the best location to build a RushCreep building , if use GetCreepCamp , then location cannot control //============================================================================ function BuildBRAtCreep takes nothing returns nothing - local integer i = 0 - local integer r = 0 - local integer s = 0 - local integer ru = 0 - local real distance = 3200 - local group g = CreateGroup() - local unit u = null - local unit array ua - local unit array ub - local unit array uc - local location loc = null - call GroupEnumUnitsInRange(g,GetLocationX(home_location), GetLocationY(home_location),distance,null) - set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_AGGRESSIVE), true) - set g = SelectUnittype(g, UNIT_TYPE_FLYING, false) - set g = SelectByAlive(g, true) - loop - set u = FirstOfGroup(g) - exitwhen u == null or i >= 7 //7 shoul have 2 creepcamp - if GetUnitLevel(u) < 5 and (uc[0] == null or (uc[0] != null and DistanceBetweenUnits(u, uc[0]) > 600) or (uc[1] != null and DistanceBetweenUnits(u, uc[1]) > 600)) then //maybe have same camp creep unit not cleaned up - set ua[i] = CreatePathingUnit(ua[i]) - call IssuePointOrder(ua[i], "move", GetUnitX(u), GetUnitY(u)) - set ub[i] = CreatePathingUnitFull(ub[i],ai_player,groundid,GetUnitX(u), GetUnitY(u)) - call IssueTargetOrder(ub[i], "smart", ua[i]) //go in opposite directions , save time - set uc[i] = u - set i = i + 1 - endif - call GroupRemoveUnit(g,u) - endloop - call DestroyGroup(g) - set g = null - set u = null - if i == 0 then - return - endif - set ru = i - loop - if i == ru then - set i = 0 - endif - exitwhen loc != null or s == ru - if (DistanceBetweenUnits(ua[i], ub[i]) < 200 or DistanceBetweenUnits(ua[i], uc[i]) < 600) and GetUnitState(uc[i], UNIT_STATE_LIFE) > 0 then - set loc = GetUnitLoc(uc[i]) - set rushcreep_target = uc[i] - elseif GetUnitState(ua[i], UNIT_STATE_LIFE) <= 0 or GetUnitCurrentOrder(ua[i]) == OrderId("stop") or GetUnitCurrentOrder(ua[i]) != OrderId("move") or DistanceBetweenPoints_kd(home_location,GetUnitLoc(ua[i])) > 3200 then - set s = s + 1 - elseif GetUnitState(ub[i], UNIT_STATE_LIFE) <= 0 or DistanceBetweenPoints_kd(home_location,GetUnitLoc(ub[i])) > 3200 then - set s = s + 1 - elseif GetUnitState(uc[i], UNIT_STATE_LIFE) <= 0 then - set s = s + 1 - endif - set i = i + 1 - call Sleep(0.05) - endloop - set i = 0 - loop - exitwhen i == ru - call RemoveUnit(ua[i]) - set ua[i] = null - call RemoveUnit(ub[i]) - set ub[i] = null - set uc[i] = null - set i = i + 1 - endloop - if s == ru or loc == null then // fail , not found creep - return - endif - set loc = GetBuildLocationInDistanceFromLoc_d(old_id[racial_rushcreep], loc, 600) - if loc != null and DistanceBetweenPoints(loc, home_location) < distance then //Prevent some islands/shallow water terrain from creating u on the other side of the map - set g = CreateGroup() - call GroupEnumUnitsInRangeOfLoc(g, loc, 510, null) - loop - set u = FirstOfGroup(g) - exitwhen u == null or s == -2 - if IsPlayerEnemy(GetOwningPlayer(u), ai_player) then //if have enemy , cannot build (if use getlocationstrength need judge twice -- creep and player) - set s = -2 - endif - call GroupRemoveUnit(g,u) - endloop - if s != -2 then - set u = GetExpansionPeon2() - if u == null or GetUnitCurrentOrder(u) != OrderId("harvest") then - call GroupClear(g) - call GroupEnumUnitsOfPlayer(g, ai_player, null) - set g = SelectUnittype(g, UNIT_TYPE_PEON, true) - set g = SelectByLoaded(g, true) - set u = FirstOfGroup(g) - call IssueTargetOrder(own_town_mine[0], "unload", u) - call Sleep(0.01) - endif - call RemoveGuardPosition(u) // no need reset guard , the tree can train - call IssuePointOrderByIdLoc(u, old_id[racial_rushcreep], loc) - endif - call DestroyGroup(g) - set g = null - set u = null - endif - call RemoveLocation(loc) - set loc = null + local integer i = 0 + local integer s = 0 + local integer ru = 0 + local real distance = 3200 + local group g = CreateGroup() + local unit u = null + local unit array ua + local unit array ub + local unit array uc + local location loc = null + call GroupEnumUnitsInRange(g,GetLocationX(home_location), GetLocationY(home_location),distance,null) + set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_AGGRESSIVE), true) + set g = SelectUnittype(g, UNIT_TYPE_FLYING, false) + set g = SelectByAlive(g, true) + loop + set u = FirstOfGroup(g) + exitwhen u == null or i >= 7 //7 shoul have 2 creepcamp + if GetUnitLevel(u) < 5 and (uc[0] == null or (uc[0] != null and DistanceBetweenUnits(u, uc[0]) > 600) or (uc[1] != null and DistanceBetweenUnits(u, uc[1]) > 600)) then //maybe have same camp creep unit not cleaned up + set ua[i] = CreatePathingUnit(ua[i]) + call IssuePointOrder(ua[i], "move", GetUnitX(u), GetUnitY(u)) + set ub[i] = CreatePathingUnitFull(ub[i],ai_player,groundid,GetUnitX(u), GetUnitY(u)) + call IssueTargetOrder(ub[i], "smart", ua[i]) //go in opposite directions , save time + set uc[i] = u + set i = i + 1 + endif + call GroupRemoveUnit(g,u) + endloop + call DestroyGroup(g) + set g = null + set u = null + if i == 0 then + return + endif + set ru = i + loop + if i == ru then + set i = 0 + endif + exitwhen loc != null or s == ru + if (DistanceBetweenUnits(ua[i], ub[i]) < 200 or DistanceBetweenUnits(ua[i], uc[i]) < 600) and GetUnitState(uc[i], UNIT_STATE_LIFE) > 0 then + set loc = GetUnitLoc(uc[i]) + set rushcreep_target = uc[i] + elseif GetUnitState(ua[i], UNIT_STATE_LIFE) <= 0 or GetUnitCurrentOrder(ua[i]) == OrderId("stop") or GetUnitCurrentOrder(ua[i]) != OrderId("move") or DistanceBetweenPoints_kd(home_location,GetUnitLoc(ua[i])) > 3200 then + set s = s + 1 + elseif GetUnitState(ub[i], UNIT_STATE_LIFE) <= 0 or DistanceBetweenPoints_kd(home_location,GetUnitLoc(ub[i])) > 3200 then + set s = s + 1 + elseif GetUnitState(uc[i], UNIT_STATE_LIFE) <= 0 then + set s = s + 1 + endif + set i = i + 1 + call Sleep(0.05) + endloop + set i = 0 + loop + exitwhen i == ru + call RemoveUnit(ua[i]) + set ua[i] = null + call RemoveUnit(ub[i]) + set ub[i] = null + set uc[i] = null + set i = i + 1 + endloop + if s == ru or loc == null then // fail , not found creep + return + endif + set loc = GetBuildLocationInDistanceFromLoc_d(old_id[racial_rushcreep], loc, 600) + if loc != null and DistanceBetweenPoints(loc, home_location) < distance then //Prevent some islands/shallow water terrain from creating u on the other side of the map + set g = CreateGroup() + call GroupEnumUnitsInRangeOfLoc(g, loc, 510, null) + loop + set u = FirstOfGroup(g) + exitwhen u == null or s == -2 + if IsPlayerEnemy(GetOwningPlayer(u), ai_player) then //if have enemy , cannot build (if use getlocationstrength need judge twice -- creep and player) + set s = -2 + endif + call GroupRemoveUnit(g,u) + endloop + if s != -2 then + set u = GetExpansionPeon2(u) + if u == null or GetUnitCurrentOrder(u) != OrderId("harvest") then + call GroupClear(g) + call GroupEnumUnitsOfPlayer(g, ai_player, null) + set g = SelectUnittype(g, UNIT_TYPE_PEON, true) + set g = SelectByLoaded(g, true) + set u = FirstOfGroup(g) + call IssueTargetOrder(own_town_mine[0], "unload", u) + call Sleep(0.01) + endif + call RemoveGuardPosition(u) // no need reset guard , the tree can train + call IssuePointOrderByIdLoc(u, old_id[racial_rushcreep], loc) + endif + call DestroyGroup(g) + set g = null + set u = null + endif + call RemoveLocation(loc) + set loc = null endfunction +//home_location have multiple mine +function MultipleMinefix takes nothing returns boolean + local real i = 0 + local real c = 0 + local real distance = 1500 + local group g = null + local unit mine = null + local unit u = null + local boolean b = true + if town_threatened or not hero_built[1] or (GetGold() < 600 and GetWood() < 400) or (not race_manual_loading and not race_uses_mine_expansion) or (race_manual_loading and TownCount(race_manual_loading_mine) > 1) or (race_uses_mine_expansion and TownCount(racial_expansion) > 1) then + return b //no first hero priority build army , human and orc just harvest + endif + call Trace("Check Multiple Mine") + set g = CreateGroup() + call GroupEnumUnitsInRangeOfLoc(g, home_location, 1500, null) + set g = SelectById(g, old_id[GOLD_MINE], true) + set g = SelectByAlive(g, true) + if (BlzGroupGetSize(g) < 2 and not race_manual_loading and not race_uses_mine_expansion) or BlzGroupGetSize(g) < 1 then + call DestroyGroup(g) // 2 is prevent now still have one mine(if BlzGroupGetSize now is 2 or more , have two mine , still need fix) , but human and orc can return to normal + set g = null + set u = null + if not race_manual_loading then + set first_town_mine = -1 //home_location only one or no mine , if not ELF , need end HARVEST CHECK job + else + set first_town_mine = 0 + endif + return false + endif + loop + set u = FirstOfGroup(g) + exitwhen u == null + if GetResourceAmount(u) > 0 then + set i = DistanceBetweenPoints_kd(home_location,GetUnitLoc(u)) + if i <= distance then + set distance = i + set mine = u + endif + set c = c + 1 + endif + call GroupRemoveUnit(g, u) + endloop + call DestroyGroup(g) + set g = null + if race_manual_loading and TownCount(race_manual_loading_mine) < 1 then + set u = GetOneOfIdNearLoc(u,ai_player,old_id[racial_expansion],home_location,1500) + if u != null then + call IssueTargetOrder(u, "entangle", mine) // first entangle , no need build + set u = null + else + set b = false + endif + elseif c > 2 then //prevent build too much TOWNHALL + set current_expansion = mine //expansion mine + set not_taken_expansion = mine + set b = false + endif + set mine = null + return b +endfunction //============================================================================ function CheckExpansionTaken takes unit expa returns boolean @@ -5748,11 +5767,11 @@ function CheckExpansionTaken takes unit expa returns boolean endif set g = CreateGroup() call GroupEnumUnitsInRange(g, GetUnitX(expa), GetUnitY(expa), expansion_taken_radius, null) + call GroupRemoveUnit(g, expa) set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_PASSIVE), false) set g = SelectUnittype(g, UNIT_TYPE_STRUCTURE, true) //set g = SelectByAlive(g, true) set g = SelectByAlive2(g, true) - call GroupRemoveUnit(g, expa) loop set u = FirstOfGroup(g) exitwhen u == null @@ -5839,7 +5858,7 @@ function AddWaterExpansion takes unit u returns nothing endfunction //============================================================== -function GetExpNearestMin takes nothing returns unit +function GetExpNearestMin takes unit ru returns unit // Return the nearest mine, uses old system so computer has a mine as new system can take a while to calculate local real distance = 0 @@ -5877,16 +5896,21 @@ set g = null if secondmine != null then if rand <= 3 then set secondmine = null - return nearmine + set ru = nearmine +set nearmine = null + return ru else set nearmine = null - return secondmine + set ru = secondmine +set secondmine = null + return ru endif else set secondmine = null - return nearmine + set ru = nearmine + set nearmine = null + return ru endif - endfunction //============================================================== @@ -5970,7 +5994,7 @@ function MakeExpansionList takes nothing returns nothing set g = null set tempg = null call Trace("Expansion number: " + Int2Str(expansion_list_length)) - + // loop // set u = FirstOfGroup(g) // exitwhen u == null @@ -6265,7 +6289,7 @@ function ExpansionFormula takes integer exp_d, unit exp_u returns integer //return exp_d + R2I(I2R(GetLocationCreepStrength(GetUnitX(exp_u), GetUnitY(exp_u), expansion_radius)) / 2) return exp_d - + endfunction //============================================================================ @@ -6334,10 +6358,11 @@ endfunction function ChooseExpansion takes nothing returns nothing local integer i = 0 local integer exp_chosen = 0 + local integer gold = 2 * GetUnitGoldCost2(racial_expansion) set exp_number = 0 loop exitwhen i >= expansion_list_length - if GetResourceAmount(expansion_list[i]) > 2 * GetUnitGoldCost2(racial_expansion) and not CheckExpansionTaken(expansion_list[i]) and DistanceBetweenPoints_kd(home_location,GetUnitLoc(expansion_list[i])) > 1500 then + if GetResourceAmount(expansion_list[i]) > gold and not CheckExpansionTaken(expansion_list[i]) and DistanceBetweenPoints_kd(home_location,GetUnitLoc(expansion_list[i])) > 1500 then call add_exp(expansion_list[i], expansion_dist[i], expansion_ancient[i], expansion_creeps[i]) endif set i = i + 1 @@ -6346,7 +6371,7 @@ function ChooseExpansion takes nothing returns nothing set i = 0 loop exitwhen i >= water_expansion_list_length - if not CheckExpansionTaken(water_expansion_list[i]) then + if GetResourceAmount(water_expansion_list[i]) > gold and not CheckExpansionTaken(water_expansion_list[i]) then call add_exp(water_expansion_list[i], 60, null, water_expansion_creeps[i]) endif set i = i + 1 @@ -6454,7 +6479,7 @@ function CheckFastExpansion takes nothing returns nothing //local location l = null //local unit firstexp = null -// set firstexp = GetExpNearestMin() +// call GetExpNearestMin(firstexp) // set l = GetUnitLoc(firstexp) // set timeaway = CanPathToLoc(start_loc, l, PATHING_TYPE_WALKABILITY) // if timeaway > 0 then @@ -6659,15 +6684,14 @@ function GetItemOfTypeOnUnit takes integer id, unit u returns item endfunction //============================================================================ -function GetItemOfType takes integer id returns item - local item it = null +function GetItemOfType takes item t, integer id returns item local integer i = 1 loop exitwhen i > 3 if hero_built[i] then - set it = GetItemOfTypeOnUnit(id, hero_unit[i]) - if it != null then - return it + set t = GetItemOfTypeOnUnit(id, hero_unit[i]) + if t != null then + return t endif endif set i = i + 1 @@ -6710,7 +6734,7 @@ function GetHeroToBuyItem takes unit shop, real limit, boolean is_healing_includ exitwhen i > 3 if hero_built[i] and UnitAlive(hero_unit[i]) then if GetSlotsFreeOnUnit(hero_unit[i]) > 0 and DistanceBetweenUnits(hero_unit[i], shop) < limit and not IsUnitInGroup(hero_unit[i], unit_buying_tavern) and not IsUnitInGroup(hero_unit[i], unit_buying_merc) and not IsUnitInGroup(hero_unit[i], unit_harassing) then - if IsUnitInGroup(hero_unit[i], unit_healing) == is_healing_included then + if is_healing_included == true and IsUnitInGroup(hero_unit[i], unit_healing) then else return hero_unit[i] endif @@ -6809,8 +6833,7 @@ function HealUnit takes unit healer, unit to_heal, boolean hero_heal returns not endfunction //============================================================================ -function GetHealer takes nothing returns unit - local unit u = null +function GetHealer takes unit u returns unit local integer id = 0 loop set u = FirstOfGroup(healer_group) @@ -7661,6 +7684,63 @@ function cmd_loop takes nothing returns nothing endfunction +//=========================================================================== +function InitCheckHarvest takes nothing returns nothing + local group g = CreateGroup() + local unit u = null + local integer i = GOLD_MINE + local integer c = 0 + local integer p = 1 + local real check = 0 + local real distance = 0 + if race_manual_loading then + set i = race_manual_loading_mine + elseif race_uses_mine_expansion then + set i = racial_expansion + endif + call GroupEnumUnitsInRangeOfLoc(g, home_location, 1600, null) + set g = SelectByAlive(g,true) + loop + set u = FirstOfGroup(g) + exitwhen u == null + if GetResourceAmount(u) > 0 then + if GetUnitTypeId(u) == old_id[GOLD_MINE] then + set check = DistanceBetweenPoints_kd(home_location,GetUnitLoc(u)) // human and orc need find closest mine + if check <= distance then + set distance = check + set own_town_mine[0] = u // fix home_location mine + endif + set c = c + 1 + else + if i != GOLD_MINE and GetUnitTypeId(own_town_mine[0]) == old_id[GOLD_MINE] then + set own_town_mine[0] = u // fix home_location mine + endif + endif + endif + if (IsUnitType(u, UNIT_TYPE_TOWNHALL) or GetUnitTypeId(u) == old_id[racial_expansion]) and GetOwningPlayer(u) != ai_player then + set p = p + 1 // have more player , need fix harvest , but maybe no need fix expensive + endif + call GroupRemoveUnit(g, u) + endloop + if p > 1 then // more mine and more player + if c == p and i != GOLD_MINE then + set first_town_mine = 1 // mode one , one player have one mine , and this mine too close (like (4)synergybigpaved.w3x) , just fix UD and ELF harvest + elseif c > p then + set first_town_mine = 2 // mode two , one player have more mine , fix UD and ELF harvest and all race expensive - prior take closest home_location mine + endif + elseif c > p then // more mine and one player + set first_town_mine = 3 // mode three , one player have this mine , fix all race harvest and expensive - prior take closest home_location mine + endif + if first_town_mine == 0 and i != GOLD_MINE then + set first_town_mine = 1 // just one mine , but now cannot harvest , need fix UD harvest + // some map home_location 1500 radius just one mine , but old war3 (maybe 1.24~1.28 , 1.36 no this bug) UD and ELF still cannot harvest(maybe need 2300 radius no more mine) + endif + call DestroyGroup(g) + set g = null + call HarvestGold(0,3) + call HarvestWood(0,2) // Early triggering Harvest , convenient HARVEST_CHECK job check peon +endfunction + //=========================================================================== function InitTownBuilt takes nothing returns nothing local integer i = 1 @@ -7673,7 +7753,7 @@ function InitTownBuilt takes nothing returns nothing set own_town_loc[0] = Location(GetLocationX(home_location), GetLocationY(home_location)) set exist_town[0] = home_location set own_town_dist[0] = 0 - set own_town_mine[0] = GetMineNearLoc(home_location, 1500) + set own_town_mine[0] = GetMineNearLoc(own_town_mine[0] ,home_location, 1500) endfunction //============================================================================ @@ -8029,7 +8109,7 @@ function InitAMAI takes nothing returns nothing #ENDINCLUDE set message_add = c2s(GetPlayerColor(ai_player)) if race_militia_available then - set militia_hall = GetMilitiaHall() + set militia_hall = GetMilitiaHall(militia_hall) endif call InitDigits() set ai_id = Int2Str(GetAiPlayer()) @@ -8080,7 +8160,7 @@ endfunction //============================================================================ function AMAI takes code heroes, code peons, code attacks returns nothing - local boolean isNewbie = (MeleeDifficulty() == EASY) + local boolean isNewbie = (difficulty == EASY) // call sendToNextAI() call SaveBoolean(com, TEAM_STATEGY_INUSE, strategy_type[chosen_strategy], true) @@ -8096,6 +8176,9 @@ function AMAI takes code heroes, code peons, code attacks returns nothing call Trace("Setting hero levels") call SetHeroLevels(heroes) call Trace("heros set") + if GetMinesOwned() > 1 then + call InitCheckHarvest() // now home_location distance 1500 have more mine , ELF and UD cannot harvest (old war3 version distance need 2200+ ), this can fix + endif call Sleep(0.1) // Job Thread call StartThread(function TQLoop) @@ -8598,16 +8681,28 @@ function GetMinesHarvested takes nothing returns integer local integer twm = TownWithMine() local integer i = twm local integer sum = 0 + local integer mine = racial_expansion + if race_manual_loading then + set mine = race_manual_loading_mine + endif + if first_town_mine > 0 or race_manual_loading or race_uses_mine_expansion then //home_location have multiple mine or just one mine but UD and ELF cannot harvested + set twm = TownCountDone(mine) + set i = twm + endif if twm < 0 then return 0 endif - loop - exitwhen i > twm + 3 - if TownHasMine(i) and TownCountEx(racial_expansion,true,i) > 0 then - set sum = sum + 1 - endif - set i = i + 1 - endloop + if race_manual_loading or race_uses_mine_expansion then + return i + else + loop + exitwhen i > twm + 3 + if TownHasMine(i) and TownCountEx(mine,true,i) > 0 then + set sum = sum + 1 + endif + set i = i + 1 + endloop + endif return sum endfunction @@ -9631,7 +9726,7 @@ function BuildAtSpecialLoc takes integer unitid, integer town, integer bloc retu local unit peon = GetExpansionPeon() if peon == null then - set peon = GetExpansionPeon2() // In case we can't get the expansion peon + set peon = GetExpansionPeon2(peon) // In case we can't get the expansion peon endif call RemoveUnit(u) set u = null @@ -9937,17 +10032,6 @@ function BuildMovePeonZeppelin takes unit peon, unit target returns boolean set expansion_peon = peon endif // Disabled just in case - if build_zeppelin == null or not UnitAlive(build_zeppelin) then - if not UnitAlive(build_zeppelin) then - call GroupRemoveUnit(unit_zepplin_move, build_zeppelin) - endif - set build_zeppelin = GetUnusedZeppelinNearUnit(expansion_peon) - if build_zeppelin == null then - call Trace("No Zeppelin found for transporting peon") - return false - endif - call GroupAddUnit(unit_zepplin_move, build_zeppelin) - endif if IsUnitInTransport(expansion_peon, build_zeppelin) then if DistanceBetweenUnits(build_zeppelin, target) > 300 then call IssuePointOrder(build_zeppelin, "move", GetUnitX(target) + GetRandomReal(-200,200), GetUnitY(target) + GetRandomReal(-200,200)) @@ -9984,10 +10068,11 @@ function StartExpansionAM takes integer qty, integer hall returns integer return BUILT_SOME endif - - - - // call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Expansion Taken Checked") + if first_town_mine > 1 then + if MultipleMinefix() then + return BUILT_ALL + endif + endif if current_expansion == null or CheckExpansionTaken(current_expansion) then call ChooseExpansion() @@ -10000,6 +10085,7 @@ function StartExpansionAM takes integer qty, integer hall returns integer set current_expansion = null return BUILT_ALL endif + // call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Expansion Taken Checked") // call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Expansion choosen") @@ -10033,7 +10119,7 @@ function StartExpansionAM takes integer qty, integer hall returns integer set peon = GetExpansionPeon() if peon == null then - set peon = GetExpansionPeon2() + set peon = GetExpansionPeon2(peon) endif // call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Peon Got") @@ -10042,9 +10128,20 @@ function StartExpansionAM takes integer qty, integer hall returns integer endif if peon != null then - if IsWaterExpansion(current_expansion) or IsUnitInGroup(current_expansion, far_expansion) then - if not BuildMovePeonZeppelin(peon, current_expansion) then - call Trace("AMAIStartexpa: Is a water or far expansion") + if IsWaterExpansion(current_expansion) or IsUnitInGroup(current_expansion, far_expansion) and neutral_available[NEUTRAL_OBSERVATORY] then + if build_zeppelin == null or not UnitAlive(build_zeppelin) then + if not UnitAlive(build_zeppelin) then + call GroupRemoveUnit(unit_zepplin_move, build_zeppelin) + endif + set build_zeppelin = GetUnusedZeppelinNearUnit(build_zeppelin, expansion_peon) + if build_zeppelin == null then + call Trace("No Zeppelin found for transporting peon") + else + call GroupAddUnit(unit_zepplin_move, build_zeppelin) + endif + endif + if ((IsWaterExpansion(current_expansion) and build_zeppelin == null) or (IsUnitInGroup(current_expansion, far_expansion) and build_zeppelin != null)) and not BuildMovePeonZeppelin(peon, current_expansion) then + call Trace("AMAIStartexpa: Is a water or far expansion so using zeppelin") set peon = null return BUILT_SOME endif @@ -10094,7 +10191,6 @@ function BuyAllyShopItem takes integer qty, integer id returns boolean local unit u = null local integer i = 0 local integer m = 0 - local integer array per if attack_running then return false endif @@ -10103,17 +10199,17 @@ function BuyAllyShopItem takes integer qty, integer id returns boolean return true endif loop - exitwhen i >= c_ally_total - if GetPlayerSlotState(ally_force[i]) == PLAYER_SLOT_STATE_PLAYING then - set per[m] = i - set m = m + 1 - endif + exitwhen i < 0 or i >= c_ally_total + set m = GetRandomInt(0,c_ally_total-1) set i = i + 1 + if GetPlayerSlotState(ally_force[m]) == PLAYER_SLOT_STATE_PLAYING then + set i = -1 + endif endloop set shop_unit = null if m > 1 then set g = CreateGroup() - call GroupEnumUnitsOfPlayer(g, Player(per[GetRandomInt(0,m-1)]), null) + call GroupEnumUnitsOfPlayer(g, ally_force[m], null) set g = SelectUnittype(g, UNIT_TYPE_STRUCTURE, true) loop set u = FirstOfGroup(g) @@ -10288,6 +10384,11 @@ endfunction //============================================================================ function BuildPeons takes integer number returns nothing + if first_town_mine == 2 and not towerrush then // startloc have more mine compensate + if not race_manual_loading and not race_uses_mine_expansion and not race_has_ghouls then + set number = number + 3 + endif + endif call BuildUnit(number, racial_peon, peon_prio) endfunction @@ -10366,7 +10467,7 @@ local unit u = null if first_expansion_chosen and (current_expansion == null or CheckExpansionTaken(current_expansion)) then call ChooseExpansion() if current_expansion == null then - call Trace("ExpansionBuilder: No mine available") + call Trace("ExpansionBuilder: No mine available") return endif endif @@ -10375,6 +10476,12 @@ if CheckExpansionTaken(current_expansion) then return endif set exp_prepared = false +if first_town_mine > 0 and (race_uses_mine_expansion or race_manual_loading) then //home_location have multiple mine , fix GetMinesOwned bug(ELF and UD) + if race_manual_loading then + set i = race_manual_loading_mine + endif + set mines = Min(TownCount(i),mines) // check actual number of gold mines +endif set i = 2 if active_expansion == true then @@ -10533,7 +10640,7 @@ function LocalizeNewTown takes integer num returns boolean return false endif set own_town_loc[num] = GetUnitLoc(u) - set own_town_mine[num] = GetMineNearLoc(own_town_loc[num], 1500) + set own_town_mine[num] = GetMineNearLoc(own_town_mine[num], own_town_loc[num], 1500) set own_town_dist[num] = DistanceBetweenPoints(home_location, own_town_loc[num]) set exist_town[exist_town_num] = own_town_loc[num] set exist_town_num = exist_town_num + 1 @@ -10903,25 +11010,24 @@ function DoAttackJobs takes nothing returns nothing endfunction //============================================================================ -function GetDistractionTarget takes unit target returns unit +function GetDistractionTarget takes unit ru, unit target returns unit local group g = CreateGroup() local location unitloc = GetUnitLoc(target) - local unit farunit = null - call GroupEnumUnitsOfPlayer(g, GetOwningPlayer(target), null) set g = SelectUnittype(g, UNIT_TYPE_STRUCTURE, true) set g = SelectByLocation(g, unitloc, 3000, false) - set farunit = GetFarestOfGroup(g, unitloc) + set ru = GetFarestOfGroup(g, unitloc) call RemoveLocation(unitloc) set unitloc = null call DestroyGroup(g) set g = null - return farunit + return ru endfunction //============================================================================ function DoDistractionAttack takes unit target returns nothing - local unit d_target = GetDistractionTarget(target) + local unit d_target = null + set d_target = GetDistractionTarget(d_target, target) if d_target == null then return endif @@ -11061,10 +11167,10 @@ function CommonSleepUntilTargetDeadAM takes unit target, boolean iscreeping, boo set g = SelectByAlive(g,true) set g = SelectByEnemy(g,ai_player, true) if not UnitAlive(target) or UnitInvis(target) then - set g = SelectByVisible(g,ai_player,true) + set g = SelectByVisible(g,ai_player,true) // to find enemies that ai has noticed endif if iscreeping then - set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_AGGRESSIVE), true) // if creeping and unit invisible see if any other creeps targetable + set g = SelectByPlayer(g, Player(PLAYER_NEUTRAL_AGGRESSIVE), true) // if creeping and unit invisible see if any other creeps targetable endif set target = FirstOfGroup(g) call DestroyGroup(g) @@ -11309,71 +11415,67 @@ function AttackMoveTowerRush takes nothing returns nothing endfunction //============================================================================ -function GetIntervalCreep takes integer lower, integer upper, integer str, integer anti_air_strength, boolean allow_air, integer sd returns unit - local unit creep = null +function GetIntervalCreep takes unit u, integer lower, integer upper, integer str, integer anti_air_strength, boolean allow_air, integer sd returns unit local integer creepstrength = 0 local integer middle = (lower + upper) / 2 if sd < 0 then return null endif - set creep = GetCreepCamp(1, middle, allow_air) - if creep == null then - return GetIntervalCreep(middle, upper, str, anti_air_strength, allow_air, sd - 1) + set u = GetCreepCamp(1, middle, allow_air) + if u == null then + return GetIntervalCreep(u, middle, upper, str, anti_air_strength, allow_air, sd - 1) else - set creepstrength = GetCreepCampStrength(creep) + 1 + set creepstrength = GetCreepCampStrength(u) + 1 if balancing then //call Trace("Creep strength: " + Int2Str(creepstrength)) - call PingMinimap(GetUnitX(creep), GetUnitY(creep), 1) + call PingMinimap(GetUnitX(u), GetUnitY(u), 1) endif if creepstrength < str then if air_strength <= anti_air_strength then - return creep + return u else - set creep = null - return GetIntervalCreep(lower, upper, str, anti_air_strength, false, sd) + return GetIntervalCreep(u, lower, upper, str, anti_air_strength, false, sd) endif else - set creep = null - return GetIntervalCreep(lower, middle, str, anti_air_strength, allow_air, sd - 1) + return GetIntervalCreep(u, lower, middle, str, anti_air_strength, allow_air, sd - 1) endif endif endfunction //============================================================================ -function GetFittingCreep takes integer str returns unit - local integer anti_air_strength = R2I(GetPlayerAntiAirStrength(ai_player)) - local unit creep = null - local integer creepstrength = 0 - local boolean allow_air = false //anti_air_strength > 25 - local integer lvl = str - - set creep = GetCreepCamp(1, lvl, true) - set air_strength = GetLocationCreepAirStrength(GetUnitX(creep), GetUnitY(creep), creep_camp_radius) - set allow_air = air_strength <= anti_air_strength - - if (not allow_air) then - set creep = GetCreepCamp(1, lvl, false) - endif +function GetFittingCreep takes unit u, integer str returns unit + local integer anti_air_strength = R2I(GetPlayerAntiAirStrength(ai_player)) + local integer creepstrength = 0 + local boolean allow_air = false //anti_air_strength > 25 + local integer lvl = str - if creep == null then - return null - endif + set u = GetCreepCamp(1, lvl, true) + if u != null then + set air_strength = GetLocationCreepAirStrength(GetUnitX(u), GetUnitY(u), creep_camp_radius) + endif + set allow_air = air_strength <= anti_air_strength - //call Trace("Our strength: " + Int2Str(str)) + if (not allow_air) then + set u = GetCreepCamp(1, lvl, false) + endif - set creepstrength = GetCreepCampStrength(creep) - if creepstrength < str and air_strength <= anti_air_strength then - //call Trace("Creep match") - call Trace("Creeping strength: " + Int2Str(creepstrength)) - set air_strength = creepstrength - return creep - else - //call Trace("No Creep ") - return GetIntervalCreep(1,100,str, anti_air_strength, allow_air, camp_scan_depth) - endif + if u == null then + return u + endif - return creep + //call Trace("Our strength: " + Int2Str(str)) + set creepstrength = GetCreepCampStrength(u) + if creepstrength < str and air_strength <= anti_air_strength then + //call Trace("Creep match") + call Trace("Creeping strength: " + Int2Str(creepstrength)) + set air_strength = creepstrength + return u + else + //call Trace("No Creep ") + return GetIntervalCreep(u, 1,100,str, anti_air_strength, allow_air, camp_scan_depth) + endif + return u // set creep = GetCreepCamp(1, camp_last_checked, allow_air) @@ -11386,13 +11488,12 @@ endfunction //============================================================================ function CreepAttack takes integer str returns nothing - local unit target = GetFittingCreep(str) - + local unit target = null + set target = GetFittingCreep(target,str) // Creep camp small is level 1 - 9 // Creep camp medium is level 10 - 19 // Creep camp strong is level 20 - 100 - if target == null then call Trace("No creep target found") call Sleep(20) @@ -11402,7 +11503,6 @@ function CreepAttack takes integer str returns nothing if air_strength > 15 then call SetAllianceTarget(target) endif - call FormGroupAM(3) call AttackMoveKillCreep(target) call SetAllianceTarget(null) @@ -11657,20 +11757,21 @@ function IsTargetGood takes unit target, integer attacker_bonus returns boolean endfunction //============================================================================ -function ChooseEnemyExpansionTarget takes nothing returns unit - local unit target = GetEnemyExpansion() - if target != null and IsTargetGood(target, expansion_target_bonus) then - call Trace("Hardcoded enemy expansion target chosen") - else - set target = null +function ChooseEnemyExpansionTarget takes unit u returns unit + set u = GetEnemyExpansion() + if u != null then + if IsTargetGood(u, expansion_target_bonus) then + call Trace("Hardcoded enemy expansion target chosen") + else + set u = null + endif endif - return target + return u endfunction //============================================================================ -function ChooseEnemyBaseTarget takes nothing returns unit +function ChooseEnemyBaseTarget takes unit u returns unit local integer c = 0 - local unit target = null call StartGetEnemyBase() loop exitwhen not WaitGetEnemyBase() @@ -11680,22 +11781,20 @@ function ChooseEnemyBaseTarget takes nothing returns unit call Sleep(1) set c = c + 1 endloop - set target = GetEnemyBase() - if target != null and IsTargetGood(target, comp_chosen_target_bonus) then + set u = GetEnemyBase() + if u != null and IsTargetGood(u, comp_chosen_target_bonus) then call Trace("Hardcoded Enemy Base Target chosen") - return target + return u endif - set target = null return null endfunction //============================================================================ -function ChooseAnEnemyTarget takes nothing returns unit - local unit target = null +function ChooseAnEnemyTarget takes unit u returns unit local player target_enemy = null local group g = CreateGroup() local location enemy_base = null - + if attacking_strategy == 1 or attacking_strategy == 3 then set target_enemy = GetWeakestEnemy() //call Trace("Chooing Weakest Enemy") @@ -11704,30 +11803,30 @@ function ChooseAnEnemyTarget takes nothing returns unit //call Trace("Choosing Strongest Enemy") elseif attacking_strategy == 5 then set target_enemy = GetFFAEnemy() - //call Trace("Choosing FFA Enemy") + //call Trace("Choosing FFA Enemy") else set target_enemy = GetWeakAndNearEnemy() //call Trace("Choosing weakest closest Enemy") endif call GroupEnumUnitsOfPlayer(g, target_enemy, null) set enemy_base = GetPlayerStartLocationLoc(target_enemy) + set g = SelectByAlive(g, true) set g = SelectUnittype(g, UNIT_TYPE_TOWNHALL, true) set g = SelectByLocation(g, enemy_base, 1000, false) - set g = SelectByAlive(g, true) - set target = FirstOfGroup(g) - if target == null then - set target = GetBuilding(target_enemy) + set u = FirstOfGroup(g) + if u == null then + set u = GetBuilding(target_enemy) endif call DestroyGroup(g) set g = null call RemoveLocation(enemy_base) set enemy_base = null set target_enemy = null - return target + return u endfunction -function ChooseAnyEnemyTarget takes nothing returns unit - local unit u = ChooseAnEnemyTarget() +function ChooseAnyEnemyTarget takes unit u returns unit + set u = ChooseAnEnemyTarget(u) if IsTargetGood(u,0) then call Trace("Enemy Advanced Target Chosen") set alli_target = u @@ -11740,22 +11839,21 @@ function ChooseAnyEnemyTarget takes nothing returns unit endfunction //============================================================================ -function ChooseAttackTarget takes nothing returns unit - local unit target = null +function ChooseAttackTarget takes unit u returns unit //call DisplayToAll("Choosing attack target") if GetRandomReal(0.0,1.0) > comp_chosen_target_rate then - set target = ChooseEnemyExpansionTarget() - if target == null then + set u = ChooseEnemyExpansionTarget(u) + if u == null then //call DisplayToAll("Attack enemy Base") - set target = ChooseEnemyBaseTarget() + set u = ChooseEnemyBaseTarget(u) endif - set alli_target = target + set alli_target = u endif - if target == null then - set target = ChooseAnyEnemyTarget() + if u == null then + set u = ChooseAnyEnemyTarget(u) endif - return target + return u endfunction //============================================================================ @@ -11776,7 +11874,7 @@ function Militia_Expansion takes integer m returns nothing local unit u = null local unit efoe = GetExpFoe() local integer t = 0 - if IsUnitInGroup(current_expansion,water_expansion) then //is WaterExpansion + if efoe == null or IsUnitInGroup(current_expansion,water_expansion) then //is WaterExpansion set efoe = null return endif @@ -11911,7 +12009,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean // Perpetual attack regardless of power or strength if c_ally_total > 0 then call SetLeadAlly() - if MeleeDifficulty() != MELEE_NEWBIE then + if difficulty != EASY then set common = GetAllianceTarget() if common != null then call Trace("===Desperation Attack Alliance Target===") @@ -11926,7 +12024,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean endif endif - set common = ChooseAnEnemyTarget() + set common = ChooseAnEnemyTarget(common) if (common != null) then call Trace("===Desperation Attack Random Enemy Target===") call SetAllianceTarget(common) @@ -12155,7 +12253,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean // if c_ally_total > 0 then call SetLeadAlly() - if MeleeDifficulty() != MELEE_NEWBIE then + if difficulty != EASY then set common = GetAllianceTarget() if common != null then call Trace("Attack Alliance Target") @@ -12174,7 +12272,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean // all-out attack if the player is weak // - if MeleeDifficulty() != MELEE_NEWBIE then + if difficulty != EASY then set mega = GetMegaTarget() if mega != null and UnitAlive(mega) then call Trace("Mega Attack Target") @@ -12193,7 +12291,7 @@ function SingleMeleeAttackAM takes boolean needs_exp, boolean has_siege, boolean if GetHeroXP(hero_unit[1]) < GetRandomInt(50,150) or GetHeroXP(hero_unit[1]) > GetRandomInt(300,850) or GetHeroXP(hero_unit[2]) > 450 or FoodUsed() > GetRandomInt(40,60) then - set hall = ChooseAttackTarget() + set hall = ChooseAttackTarget(hall) if hall != null and UnitAlive(hall) then call SetChatVarsAttack(hall) call Chat(C_Attack) @@ -12506,7 +12604,7 @@ function HealArmy takes nothing returns nothing set mh_item = GetHealingItem() endif if mh_item > 0 then - set mh_i = GetItemOfType(mh_item) + set mh_i = GetItemOfType(mh_i,mh_item) if mh_i != null then set u = GetItemHero(mh_i) if u != null then diff --git a/races.eai b/races.eai index b132e1d9c..e7c60562d 100644 --- a/races.eai +++ b/races.eai @@ -46,8 +46,8 @@ globals integer wave = 1 boolean peons_assigned = false boolean take_all_ghouls_along = false - - + + endglobals //=========================================================================== @@ -126,10 +126,10 @@ function initRacialUnits takes nothing returns nothing #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\bexpansion\b/ set racial_expansion = %1 - if race_uses_mine_expansion then // To get undead type mine systems - set racial_goldmine[minearray] = old_id[racial_expansion] - set minearray = minearray + 1 - endif + if race_uses_mine_expansion then // To get undead type mine systems + set racial_goldmine[minearray] = old_id[racial_expansion] + set minearray = minearray + 1 + endif #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\baltar\b/ set racial_altar = %1 @@ -137,6 +137,11 @@ function initRacialUnits takes nothing returns nothing #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\blumber\b/ set racial_lumber = %1 #ENDINCLUDE +#INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\brushcreep\b/ + if difficulty != EASY then + set racial_rushcreep = %1 // EASY build one , Impact Development + endif +#ENDINCLUDE #INCLUDETABLE <$VER$\$RACE$\Tiers.txt> #DEFINE $TIER$ %1 @@ -144,30 +149,30 @@ function initRacialUnits takes nothing returns nothing set racial_hall[$TIER$] = %1 #ENDINCLUDE #ENDINCLUDE - // Basically if its not a undead type expansion method just make variable the first hall - if racial_expansion == 0 then - set racial_expansion = racial_hall[1] - endif + // Basically if its not a undead type expansion method just make variable the first hall + if racial_expansion == 0 then + set racial_expansion = racial_hall[1] + endif #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\bmine\b/ set racial_goldmine[minearray] = '%2' - set minearray = minearray + 1 + set minearray = minearray + 1 #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "NEUTRAL" and "%4" =~ /\bmine\b/ set racial_goldmine[minearray] = '%2' - set minearray = minearray + 1 + set minearray = minearray + 1 #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\bzigg\b/ - set racial_zigg[ziggarray] = '%2' - set ziggarray = ziggarray + 1 + set racial_zigg[ziggarray] = '%2' + set ziggarray = ziggarray + 1 #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\bfarm\b/ set racial_farm = %1 - if race_sell_ziggurats then - set racial_zigg[ziggarray] = old_id[racial_farm] - set ziggarray = ziggarray + 1 - endif + if race_sell_ziggurats then + set racial_zigg[ziggarray] = old_id[racial_farm] + set ziggarray = ziggarray + 1 + endif #ENDINCLUDE #INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%3" eq "$RACE$" and "%4" =~ /\bshop\b/ @@ -187,34 +192,39 @@ endfunction // and tower rushs etc //============================================================================ function initRacialTraits takes nothing returns nothing - local integer i = 0 - - set i = GetRandomInt(1,100) - set militia = race_militia_expansion_available and i <= 60 - if militia then - call Trace("Militia expansion is true") - endif - set i = GetRandomInt(1, 100) - set race_ancient_expansion_available = (race_ancient_expansion_available and i <= race_ancient_expansion_probability) - set i = GetRandomInt(1, 100) - if race_ancient_expansion_available then - call Trace("Ancient Expansion is true") - endif - set race_towerrush_available = (race_towerrush_available and i <= race_towerrush_probability) - if race_towerrush_available then - call Trace("Towerrush variable is true") - endif + local integer i = 0 + + set i = GetRandomInt(1,100) + set militia = race_militia_expansion_available and i <= 60 + if militia then + call Trace("Militia expansion is true") + endif + set i = GetRandomInt(1, 100) + set race_ancient_expansion_available = (race_ancient_expansion_available and i <= race_ancient_expansion_probability) + if race_ancient_expansion_available then + call Trace("Ancient Expansion is true") + endif + set i = GetRandomInt(1, 100) + set race_item_expansion_available = (race_item_expansion_available and i <= race_item_expansion_probability) + if race_item_expansion_available then + call Trace("Ancient Expansion is true") + endif + set i = GetRandomInt(1, 100) + set race_towerrush_available = (race_towerrush_available and i <= race_towerrush_probability) + if race_towerrush_available then + call Trace("Towerrush variable is true") + endif endfunction function CanTowerRush takes nothing returns nothing local real distance = GetNearestEnemyDistance() local integer i = GetRandomInt(1,100) - + if game_is_ffa then set i = i + 40 // in ffa reduce likly hood of tower rush extremly endif - + if hero_rush_bonus[hero[1]] >= race_towerrush_hero_rush_level then if distance < 8000 then // Total percentage to be choosen is 33% call StartTowerRush(180) @@ -245,13 +255,13 @@ function chooseStrategyRP takes nothing returns nothing set rp_strat[STRAT_%1] = rp_strat[STRAT_%1] + %14 #ENDINCLUDE endif - + if game_is_1on1 then #INCLUDETABLE <$VER$\$RACE$\Strategy.txt> #EFR set rp_strat[STRAT_%1] = rp_strat[STRAT_%1] + %15 #ENDINCLUDE endif - + if game_is_ffa then #INCLUDETABLE <$VER$\$RACE$\Strategy.txt> #EFR set rp_strat[STRAT_%1] = rp_strat[STRAT_%1] + %16 @@ -296,7 +306,7 @@ endfunction //=========================================================================== function StrategyChanger takes nothing returns nothing local real array rp - + if not strat_change_allowed or strategy != chosen_strategy or debug_strategy > -1 or FoodUsed() >= 85 or GetMaximumEnemyStrength() < ver_strat_change_enemy_strength_min then return endif @@ -343,7 +353,7 @@ function AMAI_PickMeleeHero takes nothing returns nothing // recalculate_heros occurs only if hero is a tavern hero but tavern is not pathable if not recalculate_heros and ver_neutral_heroes_available and neutral_available[NEUTRAL_TAVERN] then //and CanPathToLoc(home_location, l, PATHING_TYPE_WALKABILITY) > 0 then call InitNeutralSkills() - //call Trace("PickMeleeHero: Neutral Hero possible") + //call Trace("PickMeleeHero: Neutral Hero possible") else set first_choosable_hero = ver_neutral_hero_number endif @@ -354,12 +364,12 @@ function AMAI_PickMeleeHero takes nothing returns nothing set all_heroes[#EVAL{%row-1}] = %1 set hero_rp[#EVAL{%row-1}] = %2 #ENDINCLUDE - - + + loop - exitwhen i > hero_number + exitwhen i > hero_number set all_heroes_copy[i] = all_heroes[i] - set i = i + 1 + set i = i + 1 endloop call AddFavoriteHeroRP() @@ -372,7 +382,7 @@ function AMAI_PickMeleeHero takes nothing returns nothing set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] + %3 #ENDINCLUDE endif - + if c_enemy[R_RANDOM] > 0 then #INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] + %4 @@ -392,7 +402,7 @@ function AMAI_PickMeleeHero takes nothing returns nothing set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] + %#OEVAL{$X$ + $RACENUM$ + 4} #ENDINCLUDE endif - + #ENDINCLUDE // --------------modify rp for first hero choice----------------------------------- @@ -401,28 +411,28 @@ function AMAI_PickMeleeHero takes nothing returns nothing #ENDINCLUDE set picked_hero = ChooseFirstHero() - + #INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] - %#OEVAL{5 + 2 * $RACENUM$} #ENDINCLUDE // -------------------------------------------------------------------------------- - - + + // increase the rp for those that are better as second or third hero #INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] + %#OEVAL{6 + 2 * $RACENUM$} #ENDINCLUDE - call AddStrategyHeroRP(strategy_second_hero[strategy], strategy_second_hero_bonus[strategy]) + call AddStrategyHeroRP(strategy_second_hero[strategy], strategy_second_hero_bonus[strategy]) call ChooseSecondHero() #INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] - %#OEVAL{6 + 2 * $RACENUM$} -#ENDINCLUDE +#ENDINCLUDE // ------------------------------------------------------------------------------ - -#INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR + + #INCLUDETABLE <$VER$\$RACE$\Heroes.txt> #EFR set hero_rp[#EVAL{%row-1}] = hero_rp[#EVAL{%row-1}] + %#OEVAL{7 + 2 * $RACENUM$} -#ENDINCLUDE +#ENDINCLUDE call AddStrategyHeroRP(strategy_third_hero[strategy], strategy_third_hero_bonus[strategy]) call ChooseRestHeroes() @@ -441,12 +451,12 @@ endfunction function %1Build takes nothing returns nothing local integer cc_%1 = 0 - set cc_%1 = TownCount(%2) - if cc_%1 >= bn_%1 then - set strategy = chosen_strategy - else - call BuildUnit( bn_%1, %2, 90 ) - endif + set cc_%1 = TownCount(%2) + if cc_%1 >= bn_%1 then + set strategy = chosen_strategy + else + call BuildUnit( bn_%1, %2, 90 ) + endif endfunction #ENDINCLUDE @@ -487,16 +497,15 @@ function setup_force takes boolean inj returns nothing call RemoveInjuries() endif - call SetMeleeGroupAM( hero[1] ) - call SetMeleeGroupAM( hero[2] ) - call SetMeleeGroupAM( hero[3] ) + call SetMeleeGroupAM( hero[1] ) + call SetMeleeGroupAM( hero[2] ) + call SetMeleeGroupAM( hero[3] ) // if race_has_ghouls and race_ghouls_attack then // call SetAssaultGroupAM(attacking_ghouls, attacking_ghouls, racial_ghoul) // endif #INCLUDETABLE <$VER$\StandardUnits.txt> #EFR #COND "%3" =~ /\b$RACE$\b/ and "%11" eq "true" - call SetMeleeGroupAM( %1 ) + call SetMeleeGroupAM( %1 ) #ENDINCLUDE - call AttackGroupAddNeutrals() call AttackGroupAddUnknown() @@ -521,6 +530,7 @@ endfunction function setup_ghouls takes nothing returns nothing local integer gn = TownCountDone(racial_ghoul) local integer wood = GetWood() + if wood > minimum_peon_wood then set take_all_ghouls_along = true elseif wood < minimum_peon_wood then @@ -528,22 +538,22 @@ function setup_ghouls takes nothing returns nothing endif if take_all_ghouls_along then set attacking_ghouls = gn - Max(1 - (R2I(shredder_peon_count/2) * TownCountDone(neutral_shredder)), 0) - set harvesting_ghouls = 0 + set harvesting_ghouls = 0 elseif wave <= 4 then set attacking_ghouls = Max(6, gn - 2) - set harvesting_ghouls = 1 + set harvesting_ghouls = 1 //elseif wave==2 then - // set attacking_ghouls = Max(6, gn - 2) - // elseif wood < maximum_peon_wood then + //set attacking_ghouls = Max(6, gn - 2) + //elseif wood < maximum_peon_wood then //set attacking_ghouls = gn - Max((gn - 4) - (4 * TownCountDone(neutral_shredder)), 0) -// set harvesting_ghouls = Max(0,Min(10 - wood / minimum_peon_wood,c_ghoul_done)) -// set attacking_ghouls = gn - (havesting_ghouls - (4 * TownCountDone(neutral_shredder)) + //set harvesting_ghouls = Max(0,Min(10 - wood / minimum_peon_wood,c_ghoul_done)) + //set attacking_ghouls = gn - (havesting_ghouls - (4 * TownCountDone(neutral_shredder)) //elseif wood > maximum_peon_wood and wood < minimum_peon_wood / 2 then - // set attacking_ghouls = gn - Max(2 - (4 * TownCountDone(neutral_shredder)), 0) + //set attacking_ghouls = gn - Max(2 - (4 * TownCountDone(neutral_shredder)), 0) else - //set harvesting_ghouls = Max(0,Min(5 - wood / R2I(maximum_peon_wood*1),gn) - (R2I(shredder_peon_count/2) * TownCountDone(neutral_shredder))) + //set harvesting_ghouls = Max(0,Min(5 - wood / R2I(maximum_peon_wood*1),gn) - (R2I(shredder_peon_count/2) * TownCountDone(neutral_shredder))) set harvesting_ghouls = Max(1,Min(5 - wood / R2I(maximum_peon_wood*1),gn) - (R2I(shredder_peon_count/2) * TownCountDone(neutral_shredder))) - set attacking_ghouls = gn - harvesting_ghouls + set attacking_ghouls = gn - harvesting_ghouls endif set attacking_ghouls = Min(Max(attacking_ghouls, 0), gn) endfunction @@ -568,13 +578,11 @@ endfunction function build_sequence takes nothing returns nothing call global_build_sequence() - - if towerrush then - call AddBlock(2, GRUNT, true, 0, STRONGHOLD, 1000) - call BuildUnit(1, hero[1], 100) - call BuildUnit(1, race_towerrush_requirement, 98) - endif - + if towerrush then + call AddBlock(2, GRUNT, true, 0, STRONGHOLD, 1000) + call BuildUnit(1, hero[1], 100) + call BuildUnit(1, race_towerrush_requirement, 98) + endif if strategy >= rp_strat_length then call cmdBuild() else @@ -587,11 +595,11 @@ endfunction //============================================================================ function attack_sequence_all takes nothing returns nothing - call Trace("Starting Attack Thread Loop") + call Trace("Starting Attack Thread Loop") if ver_heroes then loop - exitwhen TownCountDone(hero[1])>0 or desperation_assault + exitwhen TownCountDone(hero[1]) > 0 or desperation_assault call Sleep(2 * sleep_multiplier) // call Trace("Attack Loop1") endloop @@ -604,7 +612,7 @@ function attack_sequence_all takes nothing returns nothing loop exitwhen not (CaptainRetreating() and isfleeing) or desperation_assault exitwhen player_defeated - call CaptainGoHome() // Seems to prevent the fight and flee behaviour. Still occasions where captain seems to be home instantanously when it retreated + call CaptainGoHome() // Seems to prevent the fight and flee behaviour. Still occasions where captain seems to be home instantanously when it retreated call Sleep(2 * sleep_multiplier) //if break_attack then @@ -615,9 +623,9 @@ function attack_sequence_all takes nothing returns nothing call HealArmy() //call Trace("RACIAL ATTACK: Army Healed") - + //call HeroHealingBugFix() // To hopefully fix bugs with attack system as will keep them running - + if ver_heroes then set creeping_only = AwaitMeleeHeroesAM() endif @@ -630,7 +638,7 @@ function attack_sequence_all takes nothing returns nothing if race_has_ghouls and race_ghouls_attack then call setup_ghouls() - + set peons_assigned = false call Trace("RACIAL ATTACK: Assigning Peons") loop @@ -639,23 +647,23 @@ function attack_sequence_all takes nothing returns nothing endloop call Trace("RACIAL ATTACK: exit Assigning Peons") call Sleep(2) // Seems this helps make sure we do get the ghouls instead of them going back to wood - //call FormGroupAM(2) - endif + //call FormGroupAM(2) + endif - call Trace("RACIAL ATTACK: waiting for troops") + call Trace("RACIAL ATTACK: waiting for troops") loop exitwhen GetOwnStrength() >= minimum_attack_strength or desperation_assault call Sleep(5 * sleep_multiplier) endloop call Trace("RACIAL ATTACK: exit waiting troops") - + // call Trace("About to Attack") call setup_force(false) - call universal_attack_sequence() + call universal_attack_sequence() set attacking_ghouls = 0 endif - + call Sleep(sleep_multiplier) endloop endfunction @@ -664,29 +672,30 @@ endfunction // harvest_gold //============================================================================ function harvest_gold takes integer townid returns nothing - if TownHasMine(townid) then - call HarvestGold(townid,ver_optimal_gold) - endif + if TownHasMine(townid) or GetResourceAmount(own_town_mine[townid]) > 0 then + call HarvestGold(townid,ver_optimal_gold) + endif endfunction //============================================================================ // peon_asignment //============================================================================ function peon_assignment takes nothing returns nothing - call ClearHarvestAI() if desperation_assault then return - endif + endif if race_manual_loading then - if TownHasMine(0) then - call HarvestGold(0, Max(ver_optimal_gold - 1, 0)) - if (TownCountDone(racial_peon) == 5 or TownCountDone(racial_peon) == 6) then - call HarvestWood(0, 2) // 5th and 6th wisp has higher priority onto wood so they free to build other buildings earlier - endif - call HarvestGold(0, 1) + if TownHasMine(0) and first_town_mine == 0 then + if FoodSpace() <= 0 and TownCount(racial_peon) == TownCountDone(racial_peon) and TownCount(racial_peon) <= 4 then + call HarvestGold(0, 2) // no foodspace , no peon , need one harvest mine peon build Farms + elseif not hero_built[1] and TownCountDone(racial_peon) < 7 then // game just started + call HarvestGold(0, 3) // need more wisp HarvestWood , avoidance no wood cannot build and AI stop construction + else + call HarvestGold(0, ver_optimal_gold) + endif endif else call harvest_gold(0) @@ -694,10 +703,9 @@ function peon_assignment takes nothing returns nothing call harvest_gold(2) call harvest_gold(3) endif - if race_has_ghouls then - call HarvestWood(0,Max(TownCountDone(racial_ghoul) - attacking_ghouls, harvesting_ghouls) + TownCountDone(neutral_shredder)) - set peons_assigned = true + call HarvestWood(0,Max(TownCountDone(racial_ghoul) - attacking_ghouls, harvesting_ghouls) - TownCountDone(neutral_shredder)) + set peons_assigned = true elseif race_manual_loading then call HarvestWood(0, 20) endif @@ -711,13 +719,12 @@ function peon_assignment_all takes nothing returns nothing //if race_has_power_build then //call TownHallCheck() //endif - + if (race_has_ghouls and race_ghouls_attack) or race_no_wood_harvest or race_manual_loading then call peon_assignment() else call universal_peon_assignment() endif - endfunction function calculate_strat_timer_seconds takes integer seconds returns integer @@ -746,81 +753,81 @@ function build_sequence_all takes nothing returns nothing call Trace("Starting Build Sequence Loop") loop exitwhen player_defeated - - if recalculate_heros then - call AMAI_PickMeleeHero() - call set_skills() - set recalculate_heros = false - endif - - //call Trace("BUILD SEQUENCE: Running Loop") - call peon_assignment_all() - //call Trace("BUILD SEQUENCE: peon_assignment") - if x > 12 then - set x = 0 - //call Trace("BUILD SEQUENCE: StrategyChanger") - call StrategyChanger() - if strategy <= 49 then - set x = Min(Max(calculate_strat_timer() / 2, -120), -60) // If same strategy persists give more time - set counter_timer = 2 - set reset_counter = true - endif - endif - if last_strategy != strategy then - set last_strategy = strategy - set reportStrategy = true - call SetRaceAggression() - if strategy <= 49 then - set x = calculate_strat_timer() - set counter_timer = R2I(RMin(x/2,-80)) // Don't allow counter to change so soon - set reset_counter = true - endif - //call Trace("BUILD SEQUENCE: InitBuildarray") - call InitBuildArrayAM() - //call Trace("BUILD SEQUENCE: init_strategy") - call init_strategy() - endif - - if (x > counter_timer and counter_timer < 0) or reset_counter then - set chosen_counter = DetermineCounterForce() - if last_counter != chosen_counter and (debugging or GetRandomInt(1,5) == 1) then // Only randomly report counter changes to allies not every single time unless debug mode is on - set reportStrategy = true - endif - set set_counter = true - if reset_counter then - set reset_counter = false - else - set counter_timer = 2 // Once fired don't change again until strategy changes - endif + if recalculate_heros then + call AMAI_PickMeleeHero() + call set_skills() + set recalculate_heros = false + endif + + //call Trace("BUILD SEQUENCE: Running Loop") + call peon_assignment_all() + //call Trace("BUILD SEQUENCE: peon_assignment") + if x > 12 then + set x = 0 + //call Trace("BUILD SEQUENCE: StrategyChanger") + call StrategyChanger() + if strategy <= 49 then + set x = Min(Max(calculate_strat_timer() / 2, -120), -60) // If same strategy persists give more time + set counter_timer = 2 + set reset_counter = true + endif + endif + + if last_strategy != strategy then + set last_strategy = strategy + set reportStrategy = true + call SetRaceAggression() + if strategy <= 49 then + set x = calculate_strat_timer() + set counter_timer = R2I(RMin(x/2,-80)) // Don't allow counter to change so soon + set reset_counter = true endif - - if reportStrategy then - set reportStrategy = false - call DisplayToAlliesImportant( GetCurrentStrategyReport() + GetCurrentDynamicReport()) - call DisplayToObserversImportant( GetCurrentStrategyReport() + GetCurrentDynamicReport()) + //call Trace("BUILD SEQUENCE: InitBuildarray") + call InitBuildArrayAM() + //call Trace("BUILD SEQUENCE: init_strategy") + call init_strategy() + endif + + if (x > counter_timer and counter_timer < 0) or reset_counter then + set chosen_counter = DetermineCounterForce() + if last_counter != chosen_counter and (debugging or GetRandomInt(1,5) == 1) then // Only randomly report counter changes to allies not every single time unless debug mode is on + set reportStrategy = true endif - - set new_tier = GetTier() - if tier != new_tier then - set tier = new_tier - //call Trace("BUILD SEQUENCE: initbuildarray2") - call InitBuildArrayAM() + set set_counter = true + if reset_counter then + set reset_counter = false + else + set counter_timer = 2 // Once fired don't change again until strategy changes endif + endif - //call Trace("BUILD SEQUENCE: build_sequence") - call Sleep(0.05) - call build_sequence() - if set_counter == true then - call DynamicStrategySelector() - set set_counter = false - endif - call Sleep(3 * sleep_multiplier) - //call Trace("BUILD SEQUENCE: peon_assignment 2") - call peon_assignment_all() - call Sleep(3 * sleep_multiplier) - set x = x + Max(R2I(6*sleep_multiplier), 1) - endloop + if reportStrategy then + set reportStrategy = false + call DisplayToAlliesImportant( GetCurrentStrategyReport() + GetCurrentDynamicReport()) + call DisplayToObserversImportant( GetCurrentStrategyReport() + GetCurrentDynamicReport()) + endif + + set new_tier = GetTier() + if tier != new_tier then + set tier = new_tier + //call Trace("BUILD SEQUENCE: initbuildarray2") + call InitBuildArrayAM() + endif + + //call Trace("BUILD SEQUENCE: build_sequence") + call Sleep(0.05) + call build_sequence() + if set_counter == true then + call DynamicStrategySelector() + set set_counter = false + endif + call Sleep(3 * sleep_multiplier) + //call Trace("BUILD SEQUENCE: peon_assignment 2") + call peon_assignment_all() + call Sleep(3 * sleep_multiplier) + set x = x + Max(R2I(6*sleep_multiplier), 1) + endloop endfunction @@ -830,61 +837,61 @@ endfunction //============================================================================ function main takes nothing returns nothing call InitAMAIGameCache() - set IsAMAI = true - set ai_player = Player(GetAiPlayer()) - set home_location = GetPlayerStartLocationLoc(ai_player) // Moved from initAMAI - //call InitAiUnits() // Not actually needed on amai scripts as of course its going to be AMAI - - // start - set tiernum = $TIERNUM$ - - call Trace("Initing racial units") - call initRacialUnits() - - set own_race = R_$RACE$ - - call Trace("initing global settings") - call InitGlobalSettings() - -#INCLUDETABLE <$VER$\$RACE$\Settings.txt> #EFR - set %1 = %2 -#ENDINCLUDE - call Trace("About to init things") - call initRacialTraits() - call Trace("racial traits init done") - call InitStrats() - call Trace("init strats") - call InitAllSkills() - call Trace("init all skills") - call InitBuildings() - call Trace("init buildings") - call InitAMAI() - call Trace("init AMAI") - call InitProfile() - call Trace("About to choose strategy") - call chooseStrategyRP() - call SmallMapsAdd() - call removeNonBeginningStrats() - call display_rp_strat() - set chosen_counter = DetermineCounterForce() - set chosen_strategy = choose_strategy() + set IsAMAI = true + set ai_player = Player(GetAiPlayer()) + set home_location = GetPlayerStartLocationLoc(ai_player) // Moved from initAMAI + //call InitAiUnits() // Not actually needed on amai scripts as of course its going to be AMAI - set strategy = chosen_strategy - call SetChatVar("Strategy", GetCurrentStrategyName()) - call Trace("Strategy chosen") - call AMAI_PickMeleeHero() - if race_towerrush_available then - call CanTowerRush() - endif - call Trace("Hero picked") - call set_skills() - call Trace("hero skills set") - call SetRaceAggression() - call init_strategy() - call Trace("Strategy init") - call AMAI(function SkillArraysAM, function build_sequence_all, function attack_sequence_all) - call Trace("Playing Game") - call PlayGameAM() + // start + set tiernum = $TIERNUM$ + + call Trace("Initing racial units") + call initRacialUnits() + + set own_race = R_$RACE$ + + call Trace("initing global settings") + call InitGlobalSettings() + +#INCLUDETABLE <$VER$\$RACE$\Settings.txt> #EFR + set %1 = %2 +#ENDINCLUDE + call Trace("About to init things") + call initRacialTraits() + call Trace("racial traits init done") + call InitStrats() + call Trace("init strats") + call InitAllSkills() + call Trace("init all skills") + call InitBuildings() + call Trace("init buildings") + call InitAMAI() + call Trace("init AMAI") + call InitProfile() + call Trace("About to choose strategy") + call chooseStrategyRP() + call SmallMapsAdd() + call removeNonBeginningStrats() + call display_rp_strat() + set chosen_counter = DetermineCounterForce() + set chosen_strategy = choose_strategy() + + set strategy = chosen_strategy + call SetChatVar("Strategy", GetCurrentStrategyName()) + call Trace("Strategy chosen") + call AMAI_PickMeleeHero() + if race_towerrush_available then + call CanTowerRush() + endif + call Trace("Hero picked") + call set_skills() + call Trace("hero skills set") + call SetRaceAggression() + call init_strategy() + call Trace("Strategy init") + call AMAI(function SkillArraysAM, function build_sequence_all, function attack_sequence_all) + call Trace("Playing Game") + call PlayGameAM() endfunction