60 lines
3.0 KiB
Python
60 lines
3.0 KiB
Python
"""Compile production travel setup and native spline forwarding for per-trip walking."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/'src/server/game/World/ClientlessTravelMgr.cpp').read_text()
|
|
a=s.index('bool ClientlessTravelMgr::StartTravel(');b=s.index('void ClientlessTravelMgr::CancelTravel(',a)
|
|
start=s[a:b]
|
|
a=s.index(' player->GetMotionMaster()->MoveSmoothPath(');b=s.index(' Position const& segmentEnd',a)
|
|
launch=s[a:b]
|
|
a=s.index(' player->AttackStop();');b=s.index(' player->StopMoving();',a)
|
|
cast_setup=s[a:b]
|
|
code=r'''
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
using uint32=uint32_t;
|
|
#define TC_LOG_INFO(...) ((void)0)
|
|
struct Position{float GetPositionX()const{return 0;}float GetPositionY()const{return 0;}float GetPositionZ()const{return 0;}};
|
|
struct Guid{uint32 GetCounter(){return 26;}};
|
|
struct Motion{bool walk=false;int calls=0;void MoveSmoothPath(uint32,Position const*,std::size_t,bool w){walk=w;++calls;}}motion;
|
|
struct Player{
|
|
bool blocked=false;int castsStopped=0;void AttackStop(){}bool IsMovementPreventedByCasting(){return blocked;}void CastStop(){++castsStopped;}
|
|
bool IsInWorld(){return true;}Guid GetGUID(){return {};}uint32 GetMapId(){return 0;}Motion* GetMotionMaster(){return &motion;}
|
|
};
|
|
enum class ClientlessTravelState{Moving};
|
|
class ClientlessTravelMgr{
|
|
public:
|
|
struct TravelRecord{
|
|
struct{ClientlessTravelState State;uint32 MapId;Position Target;float RemainingDistance=0;}Status;
|
|
bool Walk=false,AllowGroundMount=false,PortalApproach=false;
|
|
std::vector<Position> ActiveSpline;
|
|
};
|
|
std::unordered_map<uint32,TravelRecord> _records;
|
|
bool StartTravel(Player*,Position const&,bool=false,bool=false,bool=false);
|
|
bool LaunchPath(Player* player,TravelRecord& record){
|
|
'''
|
|
code+=launch+r'''
|
|
return true;}
|
|
};
|
|
'''+start+'\nvoid prepareMovement(Player* player){\n'+cast_setup+'\n}\n'+r'''
|
|
int main(){
|
|
ClientlessTravelMgr mgr;Player p;Position goal;
|
|
prepareMovement(&p);assert(p.castsStopped==0); // native move-allowed channel survives
|
|
p.blocked=true;prepareMovement(&p);assert(p.castsStopped==1);p.blocked=false;
|
|
mgr.StartTravel(&p,goal,false,false,true);
|
|
assert(motion.walk&&mgr._records[26].Walk&&!mgr._records[26].AllowGroundMount);
|
|
mgr.LaunchPath(&p,mgr._records[26]);assert(motion.walk); // repath preserves gait
|
|
mgr.StartTravel(&p,goal,true,false,true);assert(motion.walk&&!mgr._records[26].AllowGroundMount);
|
|
mgr.StartTravel(&p,goal,true);assert(!motion.walk&&!mgr._records[26].Walk&&mgr._records[26].AllowGroundMount);
|
|
mgr.StartTravel(&p,goal,false,true);assert(!motion.walk&&mgr._records[26].PortalApproach);
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix='vcore-walk-') as folder:
|
|
cpp=Path(folder)/'test.cpp';binary=Path(folder)/'test';cpp.write_text(code)
|
|
subprocess.run(['c++','-std=c++17',str(cpp),'-o',str(binary)],check=True)
|
|
subprocess.run([str(binary)],check=True)
|
|
print('Production travel gait reaches native spline, survives repaths, prevents mounting and preserves legacy running defaults.')
|