"""Execute the production intent state machine with deterministic clock/travel doubles.""" from pathlib import Path import subprocess,tempfile root=Path(__file__).resolve().parents[2] s=(root/'src/server/game/World/AdventureBehaviorMgr.cpp').read_text() a=s.index('void AdventureBehaviorMgr::Update(');b=s.index('bool AdventureBehaviorMgr::Command(',a) code=r''' #include "AdventureBehaviorPolicy.h" #include #include #include #include #include using uint32=uint32_t;using uint64=uint64_t; #define TC_LOG_INFO(...) ((void)0) constexpr int SPELL_VISUAL_KIT_DRINK=438,UNIT_NPC_EMOTESTATE=0; struct Position {float x=0;void Relocate(void const*){}}; struct Guid{uint32 GetCounter(){return 26;}bool operator!=(Guid)const{return false;}}; struct Group{Guid GetLeaderGUID(){return {};}}; struct Object{} object; struct Map{Object* GetGameObject(int){return &object;}} map; struct Player { bool combat=false;uint32 area=87,zone=12,mapId=0; Group*GetGroup(){return nullptr;}Guid GetGUID(){return {};}bool IsFlying(){return false;}bool IsInWorld(){return true;}bool IsInCombat(){return combat;} uint32 GetMapId(){return mapId;}uint32 GetAreaId(){return area;}uint32 GetZoneId(){return zone;} float GetPositionX(){return 0;}float GetPositionY(){return 0;}float GetPositionZ(){return 0;} float GetExactDist(Position const&){return 0;}float GetExactDist(float,float,float){return 0;}float GetExactDist(Object*){return 0;} void SendPlaySpellVisualKit(int,int,int){}void SetUInt32Value(int,uint32){} bool IsWithinLOSInMap(Object*){return true;}void SetFacingToObject(Object*){} Map* GetMap(){return ↦} } player; namespace ObjectAccessor{Player*FindPlayer(Guid){return nullptr;}} struct Lua{void UpdateWorldPresence(Player*,std::string const&,bool){}}lua;auto sClientlessLuaEngine=&lua; struct BotGroups{bool BotLed(Player*){return false;}bool FollowMember(Player*){return false;}}botGroups;auto sAdventureGroupMgr=&botGroups; struct Encounters{bool active=false;bool Active(Player*){return active;}}encounters;auto sAdventureEncounterMgr=&encounters; bool unsafe=false;bool Unsafe(Player*){return unsafe;} bool busy=false;bool Busy(uint32){return busy;} time_t now=100;int hour=5; namespace GameTime {time_t GetGameTime(){return now;}} std::tm Local(time_t){std::tm t{};t.tm_year=126;t.tm_mon=9;t.tm_mday=26;t.tm_hour=hour;return t;} uint32 DateOf(std::tm const&){return 20261026;} enum class ClientlessActionExecutionState{Idle,Moving,Completed,Failed}; struct Status {ClientlessActionExecutionState State=ClientlessActionExecutionState::Completed;std::string Detail;}; struct Executor{Status status;auto GetStatus(uint32){return &status;}} executor;auto sClientlessActionExecutorMgr=&executor; struct Manager{uint32 queued=0;uint32 GetQueuedActionCount(uint32){return queued;}} manager;auto sClientlessPlayerMgr=&manager; struct Graph{ bool nearest=true;void EnsureLoaded(){}bool FindNearestNodeToPosition(uint32,float,float,float,std::string& key,float& distance){key="node";distance=10;return nearest;} } graph;auto sClientlessTravelGraphMgr=&graph; struct AdventureLocation{struct{uint32 MapId=0;float X=0,Y=0,Z=0;}Point;bool IsArea=false;uint32 AreaId=12;} location; struct Locations{auto Find(std::string const&){return &location;}} locations;auto sAdventureLocationMgr=&locations; struct Areas{unsigned Revision(){return 0;}} areas;auto sAdventureAreaMgr=&areas; enum class ClientlessTravelState{Moving,Arrived}; struct Travel{struct{ClientlessTravelState State=ClientlessTravelState::Arrived;}status;auto GetStatus(uint32){return &status;}}travel;auto sClientlessTravelMgr=&travel; class AdventureBehaviorMgr { public: enum class Phase{Idle,Travel,OnSite,Switching,Handover}; struct Record{ bool Enabled=true,Schedule=false,Queued=false,Dirty=false; Phase State=Phase::Travel; std::string Intent="social",Location="tavern",WantedIntent="social",WantedLocation="tavern",Detail,Micro,ManualNextIntent,ManualNextLocation; time_t Deadline=1000;uint32 AreaRevision=0,Date=20261026,Timer=0,MicroTimer=0,GestureTimer=0,RetryTimer=0;int Hour=5; struct{bool Active=false;}Social; struct{bool Active=false;}Recovery; struct{bool Active=false;}Instance; struct{bool Active=false,Flying=false,Progressive=false;std::vector Route;size_t Step=0;}Leisure; AdventureBehaviorPolicy::Day Plan;Position Anchor;uint32 AnchorMap=0;int WorkObject=0;uint32 WorkEmote=0;bool WorkPending=false; }; std::unordered_map _records{{26,{}}}; int begun=0,fallbacks=0,micros=0,resets=0,switches=0,queues=0,leisureUpdates=0; bool Allowed(Player*,AdventureLocation const&,std::string const&){return true;} bool AdoptGroup(Player*,Player*){return false;} bool UpdateNavigationRescue(Player*,Record&){return false;} bool UpdateGathering(Player*,Record&,time_t){return false;} void Update(Player*,uint32); void EnterPlayerInstance(Player*); void Generate(Player*,Record&,uint32){} void SetWanted(Player*,Record& r,std::string const&i,std::string const&l,time_t d){++switches;r.WantedIntent=i;r.WantedLocation=l;r.Deadline=d;r.Dirty=true;r.State=Phase::Idle;} void Begin(Player*,Record&){++begun;} void Fallback(Player*,Record&){++fallbacks;} void ResetMicro(Player*,Record&r){++resets;r.Micro.clear();} void Micro(Player*,Record&){++micros;} void FinishInstance(Player*,Record&r){r.Instance.Active=false;} bool UpdateInstance(Player*,Record&,time_t){return false;} bool UpdateLeisure(Player*,Record&,uint32){++leisureUpdates;return true;} bool UpdateSocial(Player*,Record&,uint32){return true;} bool UpdateRecovery(Player*,Record&,uint32){return true;} void Queue(Player*,Record&,std::string const&,std::string const&,std::string const&,bool=false){++queues;} }; ''' start=s.index('void AdventureBehaviorMgr::EnterPlayerInstance(');end=s.index('void AdventureBehaviorMgr::RefreshDay(',start) code+=s[start:end] code+=s[a:b]+r''' int main(){ AdventureBehaviorMgr mgr;auto& r=mgr._records.at(26); r.Instance.Active=true;mgr.EnterPlayerInstance(&player);assert(!r.Instance.Active); encounters.active=true;r.Schedule=true;r.Deadline=1;r.Plan[6]={"profession","mine"};hour=6; mgr.Update(&player,1000);assert(mgr.switches==0 && mgr.micros==0 && r.Hour==5); encounters.active=false;r.Schedule=false;r.Deadline=1000;hour=5; // A completed travel at the exact location opens micro actions. mgr.Update(&player,1000);assert(r.State==AdventureBehaviorMgr::Phase::OnSite&&mgr.micros==1); // Best-effort graph progress must not pretend an area has been reached. r.State=AdventureBehaviorMgr::Phase::Travel;location.IsArea=true; executor.status.Detail="best-effort travel completed at nearest useful reachable point"; mgr.Update(&player,1000);assert(mgr.fallbacks==1); location.IsArea=false;executor.status.Detail=""; // A failed route triggers replacement selection only after the executor finishes. executor.status.State=ClientlessActionExecutionState::Failed; mgr.Update(&player,1000);assert(mgr.fallbacks==2); busy=true;mgr.Update(&player,1000);assert(mgr.fallbacks==2);busy=false; // Hour switch occurs despite an active transport/flight, without starting a new trip. r.Schedule=true;r.Plan[6]={"profession","mine"};hour=6;unsafe=true; mgr.Update(&player,1000);assert(mgr.switches==1&&mgr.begun==0); unsafe=false;r.Schedule=false;r.Deadline=1000; // Safe handover waits for active travel, then queues a hard node destination. r.State=AdventureBehaviorMgr::Phase::Switching;busy=true; mgr.Update(&player,1000);assert(mgr.queues==0);busy=false; mgr.Update(&player,1000);assert(mgr.queues==1&&r.State==AdventureBehaviorMgr::Phase::Handover); // Deadline discards the old intent rather than extending the visit. now=1001;r.State=AdventureBehaviorMgr::Phase::OnSite; mgr.Update(&player,1000);assert(mgr.switches==2&&r.WantedIntent.empty()&&mgr.begun==1); // Leashed companion distance is serviced at world cadence, not the 1 s planning clock. r.Timer=1000;r.Leisure.Active=true;mgr.Update(&player,50); assert(mgr.leisureUpdates==1&&r.Timer==950); // Preparation ends on its deadline without waiting for a full/assembled party. r.Leisure.Active=false;r.Timer=0;r.Intent="groupformation";r.Deadline=now; r.ManualNextIntent="social";r.ManualNextLocation="leader-goal"; mgr.Update(&player,1000); assert(r.WantedIntent=="social"&&r.WantedLocation=="leader-goal"&&r.Deadline==now+3600&&r.ManualNextIntent.empty()); } ''' with tempfile.TemporaryDirectory(prefix='vcore-adventure-state-') as folder: cpp=Path(folder)/'test.cpp';binary=Path(folder)/'test';cpp.write_text(code) subprocess.run(['c++','-std=c++17','-I',str(root/'src/server/game/World'),str(cpp),'-o',str(binary)],check=True) subprocess.run([str(binary)],check=True) print('Production intent arrival, failed/partial travel, deadlines and safe schedule handover passed.')