Skip to content

Commit

Permalink
Add self preservation healing micros #376
Browse files Browse the repository at this point in the history
And fixed a bug with the healing group management
  • Loading branch information
SMUnlimited committed Dec 7, 2024
1 parent a64f75b commit 46a1838
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 50 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Added
- Elf players now have a 50% chance to perform an Ancient Barracks creep rush, various issues in its original introduction now fixed.
- Added self preservation micro support for burrowing, stoneform, healing wards, healing wave, healing spray and rejuvination. (jzy-chitong56)
- (DevTools) New block available for strategies. E.g `SetTierBlock(1, 0.75, 60, true)` that blocks tiering up from tier 1 unless more than 75% of higher priority units are built. Unlocks if over 60 food. Final argument prevents tier up while expanding if set to true. Tier block overrides previous tier level block if repeated in a strategy.

### Changed
Expand Down Expand Up @@ -40,6 +41,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fixed an issue where undead would try and tier up due to base defense instead of tiering up through the strategy.
- Fixed an issue where when attack forces went home they didn't run to the place where town defense is required.
- Fixed an issue where night elf wisps would end up doing nothing as they were flagged for hardcoded gold harvesting but our custom logic had already put wood wisps in the mine.
- Fix that could mean healer units were not fully considered before use.
- Multiple mine control fixes (jzy-chitong56)
- Fixed 4th mine chance was evaluated incorrectly. (jzy-chitong56)
- (Classic) Include missing hero harass attacks that are applicable from reforged scripts.
Expand Down
90 changes: 47 additions & 43 deletions Jobs/MICRO_UNITS.eai
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,17 @@ function SaveUnit takes unit u , integer id returns nothing
call IssuePointOrder(u, "move", GetLocationX(home_location), GetLocationY(home_location))
return
endif
call RemoveGuardPosition(u) //no Remove 'hphx'
call RemoveGuardPosition(u) //no Remove 'hphx' phoenix or militia
if GetUnitAbilityLevel(u, 'AOwk') > 0 or GetUnitAbilityLevel(u, 'ANwk') > 0 then
if not IsUnitInvisible(u, Player(PLAYER_NEUTRAL_AGGRESSIVE)) then
if not IsUnitInvisibleAM(u, Player(PLAYER_NEUTRAL_AGGRESSIVE)) then
call IssueImmediateOrder(u, "windwalk")
endif
endif
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))]
if not CaptainInCombat(true) or (healertepy == HEALER_TYPE_NO_TARGET or healertepy == HEALER_TYPE_WARD or GetUnitState(u, UNIT_STATE_LIFE) > GetUnitState(u, UNIT_STATE_MAX_LIFE) * 55) then
if not attack_running or (healertepy == HEALER_TYPE_NO_TARGET or healertepy == HEALER_TYPE_WARD or GetUnitState(u, UNIT_STATE_LIFE) > GetUnitState(u, UNIT_STATE_MAX_LIFE) * 55) then
call CreateDebugTag("Going to Healer", 10, u, 3.00, 1.50)
// Captain In Combat , if healer no Immediate and extensive treatment , urgent healing need go home , avoid staying on the battlefield
set unitloc = GetUnitLoc(healer)
Expand Down Expand Up @@ -182,11 +182,11 @@ endfunction
//============================================================================
function MicroUnitsJob takes nothing returns nothing
local group g = CreateGroup()
local group g2 = null
local unit u = null
local real unit_life = 0
local real unit_life_max = 0
local real unit_mana = 0
local group new_healer_group = CreateGroup()
local boolean ward_check = false
local boolean prev_ward = ward_cast
//local boolean deny = (GetGold() > 600 and GetWood() > 400) or GetGoldOwned() > 3000
Expand All @@ -195,35 +195,60 @@ function MicroUnitsJob takes nothing returns nothing
local integer count = 0
local real unit_health_ratio = 0.0
local integer id = 0
local integer hid = -1
local integer i = 0
if major_hero == null or not UnitAlive(major_hero) then
set major_hero = GetMajorHero(major_hero)
endif
//call DisplayToAllJobDebug("MICRO_UNITS Job Started")

//call GroupEnumUnitsInRange(g,GetUnitX(major_hero),GetUnitY(major_hero),battle_radius,null)
call GroupClear(healer_group)
call GroupEnumUnitsOfPlayer(g, ai_player, null)
set g = SelectUnittype(g,UNIT_TYPE_PEON,false)
set g = SelectUnittype(g,UNIT_TYPE_STRUCTURE,false)
set g = SelectByIllusion(g, false)
set g = SelectByUnitStandard(g, true)
//set g = SelectUnittype(g,UNIT_TYPE_SUMMONED,false) // need search 'ohwd' and 'hphx'
//call DisplayToAll("MICRO_UNITS: Group made")
set g2 = CopyGroup(g)
loop
set u = FirstOfGroup(g)
set u = FirstOfGroup(g2)
exitwhen u == null
set unit_life = GetUnitState(u, UNIT_STATE_LIFE)
set unit_life_max = GetUnitState(u, UNIT_STATE_MAX_LIFE)
set unit_mana = GetUnitState(u, UNIT_STATE_MANA)
if (ModuloInteger(i, 200) == 0) then
call TQSleep(0.1)
if UnitAlive(u) and not IsUnitType(u, UNIT_TYPE_PEON) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and IsStandardUnit(u) and not IsUnitBuying(u) then
set id = GetUnitTypeId(u)
if id == 'ohwd' then
set ward_check = true
endif
if not IsUnitType(u, UNIT_TYPE_MECHANICAL) and (id == 'hphx' or not IsUnitType(u, UNIT_TYPE_SUMMONED)) and GetUnitState(u, UNIT_STATE_LIFE) < RMax(flee_health_percentage * GetUnitState(u, UNIT_STATE_MAX_LIFE), flee_minimum_health) then
// leave in group to heal
else
call GroupRemoveUnit(g, u)
#INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%4" =~ /\bstatue\b/
if id == o%1 then
//call DisplayToAllJobDebug("MICRO_UNITS: Statue Control")
if attack_running and GetLocationX(last_enemy_loc) != 0 and GetLocationY(last_enemy_loc) != 0 then
call StatueControl(u)
endif
//call DisplayToAllJobDebug("MICRO_UNITS: Statue Control end")
endif
#ENDINCLUDE
set hid = GetHealerId(id)
if hid != -1 and GetUnitState(u, UNIT_STATE_MANA) >= (healer_mana_cost[hid] * 2) / 3 and ((healer_upg_id[hid] == 0) or (GetUpgradeLevel(healer_upg_id[hid]) >= healer_upg_level[hid])) then
call GroupAddUnit(healer_group, u)
endif
endif
endif
call GroupRemoveUnit(g2, u)
endloop
call DestroyGroup(g2)
set g2 = null
// These units now just those that need saving
loop
set u = FirstOfGroup(g)
exitwhen u == null
//if (ModuloInteger(i, 200) == 0) then
// call TQSleep(0.1)
//endif
set id = GetUnitTypeId(u)
if id == 'ohwd' then
// call GroupAddUnit(new_healer_group, u)
set ward_check = true
endif
if unit_life > 0 then
//if unit_life > 0 then
call SaveUnit(u,id)
//endif
//call DisplayToAllJobDebug("MICRO_UNITS: Main Loop")
//set unitloc = GetUnitLoc(u)
//if (attack_running or town_threatened) then //and DistanceBetweenUnits(major_hero, u) <= battle_radius then
Expand All @@ -233,25 +258,8 @@ function MicroUnitsJob takes nothing returns nothing
// if deny == true and not IsUnitType(u, UNIT_TYPE_HERO) and unit_life < RMin(0.1 * unit_life_max, 24) then
// call DenyUnit(u,id)
// endif
if not IsUnitType(u, UNIT_TYPE_MECHANICAL) and (id == 'hphx' or not IsUnitType(u, UNIT_TYPE_SUMMONED)) and unit_life < RMax(flee_health_percentage * unit_life_max, flee_minimum_health) then
call SaveUnit(u,id)
else
#INCLUDETABLE <$VER$\StandardUnits.txt> #COND "%4" =~ /\bstatue\b/
if id == o%1 then
//call DisplayToAllJobDebug("MICRO_UNITS: Statue Control")
if attack_running and GetLocationX(last_enemy_loc) != 0 and GetLocationY(last_enemy_loc) != 0 then
call StatueControl(u)
endif
//call DisplayToAllJobDebug("MICRO_UNITS: Statue Control end")
endif
#ENDINCLUDE
if IsUnitHealer(u) then
call GroupAddUnit(new_healer_group, u)
endif
//if GetUnitFoodUsed(u) > 0 and unit_mana < RMax(0.35 * GetUnitState(u, UNIT_STATE_MAX_MANA), 50) then
//call GetMana(u, id)
//endif
endif
// hphz = phoenix

//else
//endif
//else
Expand Down Expand Up @@ -282,7 +290,6 @@ function MicroUnitsJob takes nothing returns nothing
// endif
//endif
//endif
endif
call GroupRemoveUnit(g,u)
set i = i + 1
//call RemoveLocation(unitloc)
Expand All @@ -294,9 +301,6 @@ function MicroUnitsJob takes nothing returns nothing
set ward_cast = ward_check
endif

call DestroyGroup(healer_group)
set healer_group = new_healer_group
set new_healer_group = null
call DestroyGroup(g)
set g = null
call TQAddJob(1.5 * sleep_multiplier, MICRO_UNITS, 0)
Expand Down
29 changes: 28 additions & 1 deletion Jobs/SEND_HOME.eai
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@ function SendUnitHomeJob takes unit u, integer p returns nothing
call RemoveGuardPosition(u)
call IssueImmediateOrder(u, "ambush")
call CreateDebugTag("SEND_HOME hide", 10, u, 3.00, 1.50)
elseif GetUnitAbilityLevel(u, 'Abur') > 0 and not IsUnitInvisibleAM(u, Player(PLAYER_NEUTRAL_AGGRESSIVE)) then
call RemoveGuardPosition(u)
call IssueImmediateOrder(u, "burrow")
call CreateDebugTag("SEND_HOME burrow", 10, u, 3.00, 1.50)
elseif GetUnitAbilityLevel(u, 'Astn') > 0 and GetUnitAbilityLevel(u, 'ACmi') == 0 then
call RemoveGuardPosition(u)
call IssueImmediateOrder(u, "stoneform")
call CreateDebugTag("SEND_HOME stone", 10, u, 3.00, 1.50)
elseif GetUnitCurrentOrder(u) != OrderId("cannibalize") and (GetUnitAbilityLevel(u, 'Acn2') > 0 or GetUnitAbilityLevel(u, 'Acan') > 0 or GetUnitAbilityLevel(u, 'ACcn') > 0) then
set g = CreateGroup()
call GroupEnumUnitsInRangeOfLoc(g, exist_town[p], 1000, null)
Expand Down Expand Up @@ -186,7 +194,26 @@ function SendUnitHomeJob takes unit u, integer p returns nothing
call DestroyGroup(g)
set g = null
endif
endif
// Below attempt to heal myself
elseif (GetUnitAbilityLevel(u, 'Ahwd') > 0 or GetUnitAbilityLevel(u, 'AChw') > 0) and not ward_cast then
call RemoveGuardPosition(u)
set ward_cast = IssuePointOrder(u, "healingward", GetUnitX(u), GetUnitY(u))
call CreateDebugTag("SEND_HOME use healingward " + B2S(ward_cast), 10, u, 3.00, 1.50)
elseif GetUnitAbilityLevel(u, 'AChv') > 0 or (IsUnitType(u, UNIT_TYPE_HERO) and (GetUnitAbilityLevel(u, 'AOhw') > 0 or GetUnitAbilityLevel(u, 'ANhw') > 0)) then
call RemoveGuardPosition(u)
call IssueTargetOrder(u, "healingwave", u)
call CreateDebugTag("SEND_HOME heal wave", 10, u, 3.00, 1.50)
elseif GetUnitAbilityLevel(u, 'ANhs') > 0 then
call RemoveGuardPosition(u)
call IssuePointOrder(u, "healingspray", GetUnitX(u), GetUnitY(u))
call CreateDebugTag("SEND_HOME heal spray", 10, u, 3.00, 1.50)
elseif GetUnitAbilityLevel(u, 'Abrf') > 0 or GetUnitAbilityLevel(u, 'Arej') > 0 or GetUnitAbilityLevel(u, 'ACrj') > 0 or GetUnitAbilityLevel(u, 'ACr2') > 0 then
call RemoveGuardPosition(u)
if GetUnitAbilityLevel(u, 'Abrf') > 0 then
call IssueImmediateOrder(u, "unbearform")
endif
call IssueTargetOrder(u, "rejuvination", u)
endif
endif
call TQAddUnitJob(4, SEND_HOME, p, u)
//call DisplayToAllJobDebug("SEND_HOME: JOB Finished!!!! ")
Expand Down
7 changes: 1 addition & 6 deletions common.eai
Original file line number Diff line number Diff line change
Expand Up @@ -7423,7 +7423,7 @@ function GetHealer takes unit u returns unit
set u = FirstOfGroup(rg)
exitwhen u == null
set id = GetHealerId(GetUnitTypeId(u))
if id != -1 and not IsUnitLoaded(u) and UnitAlive(u) and GetUnitState(u, UNIT_STATE_MANA) >= healer_mana_cost[id] and ((healer_upg_id[id] == 0) or (GetUpgradeLevel(healer_upg_id[id]) >= healer_upg_level[id])) and not IsUnitInGroup(u, unit_healing) then
if id != -1 and not IsUnitLoaded(u) and UnitAlive(u) and GetUnitState(u, UNIT_STATE_MANA) >= healer_mana_cost[id] and ((healer_upg_id[id] == 0) or (GetUpgradeLevel(healer_upg_id[id]) >= healer_upg_level[id])) and IsStandardUnit(u) and not IsUnitBuying(u) then
call DestroyGroup(rg)
set rg = null
return u
Expand Down Expand Up @@ -13515,7 +13515,6 @@ function GetArmyHealthState takes nothing returns real
local integer hid = 0
local integer hFountainID = GetHealthFountainID()
local integer id = 0
call GroupClear(healer_group)
call GroupClear(urgent_healing_group)
call GroupClear(medium_healing_group)
call GroupClear(small_healing_group)
Expand All @@ -13540,10 +13539,6 @@ function GetArmyHealthState takes nothing returns real
set health_sum = health_sum + uhs
endif
set count = count + 1
set hid = GetHealerId(id)
if hid != -1 and GetUnitState(u, UNIT_STATE_MANA) >= (healer_mana_cost[hid] * 2) / 3 and ((healer_upg_id[hid] == 0) or (GetUpgradeLevel(healer_upg_id[hid]) >= healer_upg_level[hid])) then
call GroupAddUnit(healer_group, u)
endif
if uhs < 0.5 then
call GroupAddUnit(urgent_healing_group, u)
set urgent_healing_count = urgent_healing_count + 1
Expand Down

0 comments on commit 46a1838

Please sign in to comment.