Add danger-aware companion selection and native survival assistance
Core tests / core (push) Successful in 39s
Core tests / core (push) Successful in 39s
This commit is contained in:
@@ -37,3 +37,14 @@ test('offline party members are protected when their identity cannot be checked
|
||||
assert.match(compileCommunityAction('party',bot('A'),bot('B')),/Party has offline members/);
|
||||
assert.match(compileCommunityAction('leave',bot('A')),/Party has offline members/);
|
||||
});
|
||||
test('recent danger encourages shy companions without overriding hostility or human control',()=>{
|
||||
const {partyDecision}=require('../.test-build/community.js');const a=bot('A'),b=bot('B');a.personality.sociability=0;b.personality.sociability=0;
|
||||
assert.equal(partyDecision(a,b).accepted,false);a.world.dangerAt=now();assert.equal(partyDecision(a,b).accepted,true);
|
||||
b.relationships=[{targetId:'A',affinity:-1}];assert.equal(partyDecision(a,b).accepted,false);b.relationships=[];
|
||||
b.world.humanControlled=true;assert.equal(partyDecision(a,b).accepted,false);b.world.humanControlled=false;
|
||||
a.world.dangerAt=now()-601;assert.equal(partyDecision(a,b).accepted,false);
|
||||
});
|
||||
test('companion ranking prefers complementary native roles and shared active quests',()=>{
|
||||
const {companionScore}=require('../.test-build/community.js');const a=bot('A'),b=bot('B'),c=bot('C');a.world.combatRole='tank';b.world.combatRole='healer';c.world.combatRole='damage';assert.ok(companionScore(a,b)>companionScore(a,c));
|
||||
b.world.combatRole='damage';a.world.quests=[1,2];c.world.quests=[1,2];assert.ok(companionScore(a,c)>companionScore(a,b));
|
||||
});
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
from pathlib import Path
|
||||
from lupa import LuaRuntime
|
||||
setup='''
|
||||
now=1000;os.time=function()return now end;calls={};people={}
|
||||
function AuthDBQuery(sql)local i=1;return {GetUInt32=function(_,n)return n==0 and i or 10+i end,GetString=function()return i==1 and 'A' or 'B'end,NextRow=function()i=i+1;return i<=2 end} end
|
||||
function GetPlayersInWorld()return people end
|
||||
function CreateLuaEvent(fn)tick=fn end
|
||||
function PrintInfo()end
|
||||
function PrintError(s)error(s)end
|
||||
function make(id,name)
|
||||
local p={id=id,name=name,hp=100,distance=25,ai={}}
|
||||
function p:GetGUIDLow()return self.id end;function p:GetName()return self.name end;function p:GetAccountId()return 10+self.id end
|
||||
function p:IsPlayerbot()return not self.human end;function p:IsDead()return self.dead end;function p:GetBotAI()return self.ai end
|
||||
function p:GetHealthPct()return self.hp end;function p:IsInCombat()return self.combat end
|
||||
function p:IsTaxi()return self.taxi end;function p:IsCasting()return self.cast end;function p:IsRooted()return false end
|
||||
function p:GetGroup()return self.group end;function p:GetVictim()return self.enemy end;function p:GetLevel()return 5 end
|
||||
function p:GetDistance()return self.distance end;function p:GetMapId()return 0 end;function p:GetPhaseMask()return 1 end
|
||||
function p.ai:GetMaster()return p.master end;function p.ai:SetMaster(m)p.master=m end
|
||||
function p.ai:HasGameClientMaster()return p.controlled end;function p.ai:IsMovementImpaired()return false end
|
||||
function p.ai:GetGroupLeader()return leader end;function p.ai:ChangeStrategy(s,state)end
|
||||
function p.ai:DoSpecificAction(s)table.insert(calls,s);return true end
|
||||
return p
|
||||
end
|
||||
A=make(1,'A');B=make(2,'B');people={A,B};leader=A
|
||||
function group() local g={GetMembers=function()return {A,B}end,GetMembersCount=function()return 2 end,IsRaidGroup=function()return false end};A.group=g;B.group=g end
|
||||
function step(n)now=now+n;tick()end
|
||||
'''
|
||||
def new():
|
||||
l=LuaRuntime();l.execute(setup);l.execute((Path(__file__).resolve().parents[1]/'ale/azerothai_survival.lua').read_text());l.execute('AzerothAISetSurvivalEnabled(true)');return l
|
||||
l=new();l.execute("A.combat=true;A.hp=20;step(0);assert(calls[1]=='flee');step(10);assert(#calls==1);step(10);assert(#calls==2)")
|
||||
l=new();l.execute("group();A.human=true;B.combat=true;B.hp=20;step(0);assert(#calls==0)")
|
||||
l=new();l.execute("group();step(0);assert(calls[1]=='follow' and B.master==A)")
|
||||
l=new();l.execute("group();B.distance=100;step(0);assert(#calls==0)")
|
||||
l=new();l.execute("A.combat=true;A.hp=20;A.controlled=true;step(0);assert(#calls==0)")
|
||||
l=new();l.execute("A.combat=true;A.hp=20;step(0);A.combat=false;step(20);assert(calls[2]=='eat' and calls[3]=='drink')")
|
||||
l=new();l.execute("group();AzerothAISetSurvivalEnabled(false);step(0);assert(#calls==0)")
|
||||
print('Native survival: retreat cooldown, recovery, regroup range, human-party protection, and disabled grouping passed')
|
||||
Reference in New Issue
Block a user