Hold independent work while companions regroup and leaders wait
Core tests / core (push) Successful in 36s

This commit is contained in:
Codex
2026-09-24 05:58:16 +12:00
parent 6b8ce612ad
commit 900b926b8e
3 changed files with 50 additions and 16 deletions
+34 -16
View File
@@ -136,7 +136,30 @@ local function sample()
if hp<85 or mana<35 then r.resting=true end
if hp>=95 and mana>=65 then r.resting=false end
local resting=not p:IsInCombat() and (r.resting or now<(r.recoverUntil or 0))
if unsafe or avoid or resting then holdPlans(p,ai,r,now) else releasePlans(p,r) end
-- Decide cohesion before restoring work flags, so native RPG cannot undo a wait/follow.
local leader=g and ai:GetGroupLeader() or nil
local regroup,waiting=false,false
local cohesion=enabled and now-enabledAt<180 and g and not p:IsInCombat() and not p:IsCasting() and not unsafe and not avoid and not resting
if cohesion and leader and managed(leader) and not leader:IsTaxi() then
if leader~=p and leader:GetMapId()==p:GetMapId() and leader:GetPhaseMask()==p:GetPhaseMask() then
local distance=p:GetDistance(leader)
-- Hysteresis prevents alternating independent work and follow at the boundary.
if distance<=6 or distance>=200 then r.catchingUp=false
elseif distance>12 then r.catchingUp=true end
regroup=r.catchingUp and hp>=95 and mana>=65 and not leader:IsInCombat()
elseif leader==p then
local separated=false
for _,m in pairs(peers) do
if m~=p and not m:IsTaxi() and m:GetMapId()==p:GetMapId() and m:GetPhaseMask()==p:GetPhaseMask() and p:GetDistance(m)<200 and (p:GetDistance(m)>15 or m:GetHealthPct()<85 or (m:GetPowerType()==0 and m:GetPowerPct(0)<35)) then separated=true;break end
end
if separated then
r.waitSince=r.waitSince or now
waiting=now-r.waitSince<20
if now-r.waitSince>60 then r.waitSince=now;waiting=true end
else r.waitSince=nil end
end
else r.catchingUp=false;r.waitSince=nil end
if unsafe or avoid or resting or regroup or waiting then holdPlans(p,ai,r,now) else releasePlans(p,r) end
if unsafe and now-(r.retreatAt or 0)>=8 then
r.dangerAt=now;r.retreatAt=now;r.action='retreat requested';r.actionAt=now
if p:IsCasting() then p:StopSpellCast() end
@@ -158,22 +181,17 @@ local function sample()
ai:DoSpecificAction('eat',true);ai:DoSpecificAction('drink',true)
end
end
elseif enabled and now-enabledAt<180 and g and not p:IsInCombat() and not p:IsCasting() then
local leader=ai:GetGroupLeader()
if leader and leader~=p and managed(leader) and not leader:IsInCombat() and not leader:IsTaxi() and leader:GetMapId()==p:GetMapId() and leader:GetPhaseMask()==p:GetPhaseMask() and p:GetDistance(leader)>8 and p:GetDistance(leader)<200 and hp>=95 and mana>=65 and now-(r.followAt or 0)>=8 then
ai:SetMaster(leader);ownedMasters[id]=leader:GetGUIDLow()
ai:ChangeStrategy('-stay',1)
r.followAt=now;r.action='regroup requested';r.actionAt=now;r.accepted=ai:DoSpecificAction('follow',true)
elseif leader==p and hp>=95 then
for _,m in pairs(peers) do
if m~=p and not m:IsInCombat() and not m:IsTaxi() and m:GetMapId()==p:GetMapId() and m:GetPhaseMask()==p:GetPhaseMask() and (p:GetDistance(m)>15 or m:GetHealthPct()<85) and p:GetDistance(m)<200 then
r.waitSince=r.waitSince or now
if now-r.waitSince<20 then p:MoveStop();r.action='waiting for companion';r.actionAt=now
elseif now-r.waitSince>60 then r.waitSince=nil end
break
end
end
elseif regroup then
ai:SetMaster(leader);ownedMasters[id]=leader:GetGUIDLow()
ai:ChangeStrategy('-stay',1)
r.action='regroup requested';r.actionAt=now
if now-(r.followAt or 0)>=8 then
r.followAt=now;r.accepted=ai:DoSpecificAction('follow',true)
if now-(r.cohesionAuditAt or 0)>=30 then audit(p,'regroup-request','accepted='..tostring(r.accepted)..'; distance='..math.floor(p:GetDistance(leader)));r.cohesionAuditAt=now end
end
elseif waiting then
p:MoveStop();r.action='waiting for companion';r.actionAt=now
end
end
end