26 lines
2.5 KiB
TypeScript
26 lines
2.5 KiB
TypeScript
import type {Bot,Decision,IntentCheck} from './types';
|
|
export function startIntentCheck(bot:Bot,decision:Decision,commandId:string,now:number,partyPeer?:string):IntentCheck|undefined{
|
|
const w=bot.world;if(!w||now-w.at>90||now<w.at)return;
|
|
return {id:commandId,action:decision.action,startedAt:now,baselineAt:w.at,status:'pending',detail:'Waiting for a fresh game observation; command submission is not completion.',partyPeer,baseline:{level:bot.level,xp:w.xp,map:w.mapId,x:w.x,y:w.y,hp:w.healthPct,mana:w.manaPct,food:w.foodCount,drink:w.drinkCount,durability:w.minDurabilityPct,readinessAt:w.readinessAt,groupNames:[...w.groupNames]}};
|
|
}
|
|
export function observeIntentChecks(bot:Bot){
|
|
const w=bot.world;if(!w)return;
|
|
for(const c of bot.autonomy?.intentChecks??[]){
|
|
if(c.status!=='pending'||w.at<=c.baselineAt||w.at<c.startedAt)continue;
|
|
const finish=(status:IntentCheck['status'],detail:string)=>{c.status=status;c.detail=detail;c.checkedAt=w.at;};
|
|
if(w.isDead||w.isGhost){finish('interrupted','Death interrupted the intention; native resurrection takes priority.');continue;}
|
|
if(w.humanControlled){finish('interrupted','Human control took priority.');continue;}
|
|
const b=c.baseline,elapsed=w.at-c.startedAt;
|
|
if(c.action==='quest'&&(bot.level>b.level||(w.xp!==undefined&&b.xp!==undefined&&w.xp>b.xp))){finish('observed','Experience or level increased after the intention; this alone does not prove a quest turn-in.');continue;}
|
|
if(c.action==='explore'&&(w.mapId!==b.map||Math.hypot(w.x-b.x,w.y-b.y)>=20)){finish('observed','Travel of at least 20 yards or a map change observed.');continue;}
|
|
if(c.action==='rest'&&!w.inCombat&&(w.healthPct??0)>=95&&(w.manaPct===undefined||w.manaPct>=65)){
|
|
finish('observed','Recovered health and sufficient mana observed out of combat.');continue;
|
|
}
|
|
if(c.action==='trade'&&(w.readinessAt??0)>(b.readinessAt??0)&&((w.foodCount??0)>(b.food??Infinity)||(w.drinkCount??0)>(b.drink??Infinity)||(w.minDurabilityPct??0)>(b.durability??Infinity))){finish('observed','Supplies or equipment condition improved; purchase attribution is not established.');continue;}
|
|
if(c.action==='socialize'&&c.partyPeer&&w.groupId&&w.groupNames.includes(c.partyPeer)){
|
|
finish('observed','Party membership with '+c.partyPeer+' verified in the game.');continue;
|
|
}
|
|
if(elapsed>=600)finish('no_progress',c.action==='socialize'&&!c.partyPeer?'No measurable party objective was attached; dialogue is counted separately.':'No matching outcome observed within ten minutes. This is not proof of an engine failure.');
|
|
}
|
|
}
|