"""Exercise native sleep-space and candidate adapters with map/object fixtures.""" from pathlib import Path import subprocess,tempfile root=Path(__file__).resolve().parents[2] source=(root/'src/server/game/World/AdventureBehaviorMgr.cpp').read_text() def function(signature): start=source.index(signature);body=source.index('{',start);end=body+1;depth=1 while depth: depth+=(source[end]=='{')-(source[end]=='}');end+=1 return source[start:end] code=r''' #include "AdventureRestSpace.h" #include #include #include using uint32=uint32_t; #define TC_LOG_INFO(...) ((void)0) constexpr float INVALID_HEIGHT=-100000; constexpr int GAMEOBJECT_TYPE_CHAIR=7, LINEOFSIGHT_ALL_CHECKS=0; namespace VMAP{enum class ModelIgnoreFlags{Nothing};} struct Position{ float x=0,y=0,z=10,o=0; Position()=default;Position(float a,float b,float c,float d=0):x(a),y(b),z(c),o(d){} float GetPositionX()const{return x;}float GetPositionY()const{return y;} float GetPositionZ()const{return z;}float GetOrientation()const{return o;} float GetExactDist(float a,float b,float c)const{return std::sqrt((x-a)*(x-a)+(y-b)*(y-b)+(z-c)*(z-c));} float GetExactDist2d(float a,float b)const{return std::hypot(x-a,y-b);} }; struct GameObject:Position{ std::string name="Wooden Chair";bool phase=true,spawned=true;int type=7; bool isSpawned(){return spawned;}auto GetName(){return name;}int GetGoType(){return type;} float GetObjectScale(){return 1;} }; struct Creature:Position{bool phase=true;float GetBoundaryRadius(){return 0.5f;}}; struct PositionFullTerrainStatus{bool outdoors=false;}; struct Terrain{ bool outdoors=false; void GetFullTerrainStatusForPosition(int,int,float,float,float,PositionFullTerrainStatus& t){t.outdoors=outdoors;} }; struct Map{ Terrain terrain;bool water=false,bed=false;float level=10; float GetHeight(int,float x,float y,float probe,bool,float){ float h=bed && std::fabs(x-4)<2.1f && std::fabs(y)<0.95f?10.7f:level; return probe>=h?h:level; } float GetWaterLevel(int,float,float){return water?12:-100000;} bool isInLineOfSight(int,float,float,float,float,float,float,int,VMAP::ModelIgnoreFlags){return true;} Terrain* GetTerrain(){return &terrain;} }; struct Player:Position{ bool phase=true;Map map;std::vector objects;std::vector people;std::vector creatures; struct Guid{uint32 GetCounter(){return 26;}};Guid GetGUID(){return {};} Map* GetMap(){return ↦}int GetPhaseShift(){return 0;}int GetMapId(){return 0;} float GetCollisionHeight(){return 2;} templatebool IsInPhase(T* p){return p->phase;} void GetGameObjectListWithEntryInGrid(std::vector& v,int,float){v=objects;} void GetPlayerListInGrid(std::vector& v,float){v=people;} void GetCreatureListWithEntryInGrid(std::vector& v,int,float){v=creatures;} }; ''' code+=function(' bool SleepSpace(')+'\n'+function(' std::vector SleepCandidates(') code+=r''' int main(){ Player p;Position anchor(0,0,10);GameObject chair;p.objects={&chair}; assert(!SleepSpace(&p,anchor)); chair.phase=false;assert(SleepSpace(&p,anchor));chair.phase=true; chair.spawned=false;assert(SleepSpace(&p,anchor));chair.spawned=true; chair.z=3;assert(SleepSpace(&p,anchor));chair.z=10; auto candidates=SleepCandidates(&p,anchor,true); assert(!candidates.empty()); // shift off the chair, rather than merely reject the marker for(auto const& c:candidates){assert(c.GetExactDist2d(0,0)>1);assert(std::fabs(c.z-10)<0.01f);} p.map.terrain.outdoors=true;assert(SleepCandidates(&p,anchor,true).empty());p.map.terrain.outdoors=false; p.map.water=true;assert(SleepCandidates(&p,anchor,true).empty());p.map.water=false; p.map.level=3;assert(SleepCandidates(&p,anchor,true).empty());p.map.level=10; // not the storey below p.objects.clear();Player visitor;visitor.x=1;p.people={&visitor};assert(!SleepSpace(&p,anchor));p.people.clear(); Creature npc;npc.x=1;p.creatures={&npc};assert(!SleepSpace(&p,anchor));p.creatures.clear(); GameObject bed;bed.name="Hospital Bed";bed.type=5;bed.x=4;p.objects={&bed};p.map.bed=true; candidates=SleepCandidates(&p,anchor,true);assert(!candidates.empty()); assert(candidates.front().x==4 && std::fabs(candidates.front().z-10.7f)<0.01f); // real bed before floor p.objects.clear();candidates=SleepCandidates(&p,anchor,true);assert(!candidates.empty()); assert(std::fabs(candidates.front().z-10.7f)<0.01f); // static raised surface before floor } ''' with tempfile.TemporaryDirectory() as tmp: src=Path(tmp)/'targets.cpp';src.write_text(code);exe=Path(tmp)/'targets' subprocess.run(['g++','-std=c++17','-Wall','-Wextra','-Werror','-I'+str(root/'src/server/game/World'),str(src),'-o',str(exe)],check=True) subprocess.run([str(exe)],check=True) print('Native sleep targets: chair exclusion, phase, despawn, floor search, indoors, water, storey, occupancy, bed/surface preference passed.')