Files
Viano-Core/tests/clientless/test_shared_group_route.py
T
Nico d6fea6ee68
clang PCH / build (push) Canceled after 0s
GCC PCH / build (push) Canceled after 0s
Add AdventureBot groups, raid preparation and shared travel
Implement native bot recruitment and player admission, leader-owned destinations, intent-specific capacities, preparation scheduling and shared graph and flight travel. Support native group instance visits and separate raid entrances.

Include pending personality-driven faction PvP and solo fleeing, preserving the absolute group fleeing exclusion. Add regression fixtures, migration, documentation and test-server evidence.
2026-10-28 15:00:41 +01:00

53 lines
3.9 KiB
Python

"""Run the generic production route-copy function (no AdventureBot dependency)."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
s=(root/'src/server/game/World/ClientlessActionExecutorMgr.cpp').read_text()
a=s.index('bool ClientlessActionExecutorMgr::AdoptRoute(')
code=r'''
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <string>
#include <vector>
#include <unordered_map>
using uint32=unsigned;
#define TC_LOG_INFO(...) ((void)0)
struct Guid{unsigned id=0;unsigned GetCounter(){return id;}};
struct Position{float x,y,z;void Relocate(float a,float b,float c){x=a;y=b;z=c;}};
struct Group{Guid leader{29};Guid GetLeaderGUID(){return leader;}}group;
struct Player{bool grouped=true;unsigned map=0;Guid GetGUID(){return {31};}Group*GetGroup(){return grouped?&group:nullptr;}unsigned GetMapId(){return map;}float GetExactDist(Position const&p){return std::hypot(p.x,p.y);}};
struct ClientlessAction{std::string Name;std::unordered_map<std::string,std::string>Parameters;};
struct ClientlessTravelRouteStep{std::string NodeKey,EdgeType;unsigned EdgeDatabaseId=0,MapId=0;float X=0,Y=0,Z=0;};
struct Graph{bool allowed=true;bool PlanAdaptiveRoute(Player*,std::string const&node,int,int,std::vector<ClientlessTravelRouteStep>&r,bool&complete,std::string&,std::string&){complete=true;r={{node,"start"}};return allowed;}}graph;auto sClientlessTravelGraphMgr=&graph;
struct ClientlessActionExecutorMgr{
struct Record{std::vector<ClientlessTravelRouteStep>Route;size_t RouteStep=0;bool FinalLocalLegPending=false,RouteComplete=true,HardDestination=false,Active=false;
unsigned FinalMapId=0,FinalDatabaseId=0;float FinalX=0,FinalY=0,FinalZ=0,FinalO=0;std::string FinalLocationId,PlannedDestinationNode,AdaptiveReachedNode;};
std::unordered_map<unsigned,Record>_records;int starts=0;bool StartRouteStep(Player*,unsigned,Record&){++starts;return true;}
bool AdoptRoute(Player*,ClientlessAction const&,Record&);
};
'''+s[a:]+r'''
int main(){
ClientlessActionExecutorMgr mgr;Player p;ClientlessAction a;a.Name="travel_to_location";a.Parameters={{"id","destination"},{"route_source","29"}};
auto& lead=mgr._records[29];lead.Route={{"start","start",0,0,0,0,0},{"taxi_end","taxi",18,0,30,0,0},{"flight_end","free_flight",0,0,80,0,0}};
lead.RouteStep=1;lead.FinalLocationId="destination";lead.FinalDatabaseId=77;lead.FinalX=90;lead.FinalLocalLegPending=true;
ClientlessActionExecutorMgr::Record peer;
assert(mgr.AdoptRoute(&p,a,peer));assert(peer.Route.size()==3&&peer.Route[1].EdgeType=="taxi"&&peer.Route[1].EdgeDatabaseId==18&&peer.Route[2].EdgeType=="free_flight");
assert(peer.FinalLocationId=="destination"&&peer.FinalLocalLegPending&&peer.FinalX==90&&peer.FinalDatabaseId==77);
assert(peer.RouteStep==0&&peer.Active&&lead.RouteStep==1);peer.Route[1].NodeKey="changed";assert(lead.Route[1].NodeKey=="taxi_end");
// Late arrival joins the active route at its previous reached node.
lead.RouteStep=2;assert(mgr.AdoptRoute(&p,a,peer));assert(peer.Route.size()==2&&peer.Route[0].NodeKey=="taxi_end"&&peer.Route[0].EdgeType=="start"&&peer.Route[1].EdgeType=="free_flight");
p.map=1;assert(mgr.AdoptRoute(&p,a,peer));graph.allowed=false;assert(!mgr.AdoptRoute(&p,a,peer));graph.allowed=true;p.map=0;
// No cross-group route copying and no stale destination reuse.
group.leader={32};assert(!mgr.AdoptRoute(&p,a,peer));group.leader={29};p.grouped=false;assert(!mgr.AdoptRoute(&p,a,peer));p.grouped=true;
a.Parameters["id"]="different";assert(!mgr.AdoptRoute(&p,a,peer));a.Parameters["id"]="destination";
lead.Route.clear();assert(!mgr.AdoptRoute(&p,a,peer));
}
'''
with tempfile.TemporaryDirectory() as d:
p=Path(d);(p/'route.cpp').write_text(code)
subprocess.run(['g++','-std=c++17',str(p/'route.cpp'),'-o',str(p/'route')],check=True)
subprocess.run([str(p/'route')],check=True)
print('Production generic shared routes: same edges/taxi/free flight, independent execution state, final local goal, late catch-up, permissions and stale-goal rejection passed.')