Reuse formation performances while waiting for dungeon, raid or PvP admission, and accept compatible formation invitations without active recruitment or interrupting battleground offers. Require the full low-population wait for every participating queue entry and acknowledge connected clientless members during native group teleportation. Add regression coverage and document builds, live Yarumak/Seraellin checks and separately preserved shutdown crash findings.
53 lines
3.5 KiB
Python
53 lines
3.5 KiB
Python
"""Run the shared performance executor with a real waiting-state action selector."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile,re
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/'src/server/game/World/AdventureBehaviorMgr.cpp').read_text()
|
|
a=s.index('void AdventureBehaviorMgr::UpdateActivities(');z=s.index('\nbool AdventureBehaviorMgr::Command',a)
|
|
selector=re.search(r'auto w = a.Intents.find\([^;]+;',s).group()
|
|
code=r'''
|
|
#include <cassert>
|
|
#include <map>
|
|
#include <string>
|
|
using uint32=unsigned;
|
|
constexpr int SPELL_VISUAL_KIT_DRINK=1,UNIT_NPC_EMOTESTATE=1;
|
|
struct Object{bool IsWithinLOSInMap(Object*){return true;}}object;
|
|
struct Map{unsigned id=1;Object*GetGameObject(unsigned){return &object;}}map;
|
|
struct Guid{unsigned GetCounter(){return 44;}};
|
|
struct Player{Guid GetGUID(){return {};}unsigned mapid=1;unsigned GetMapId(){return mapid;}Map*GetMap(){return ↦}float GetExactDist(Object*){return 1;}bool IsWithinLOSInMap(Object*){return true;}void SetFacingToObject(Object*){}void SetUInt32Value(int,unsigned){}void SendPlaySpellVisualKit(int,int,int){}};
|
|
enum class ClientlessTravelState{Moving,Arrived};
|
|
struct Travel{struct Status{ClientlessTravelState State=ClientlessTravelState::Arrived;}status;Status*GetStatus(unsigned){return &status;}}travel;auto sClientlessTravelMgr=&travel;
|
|
struct Group{bool FollowMember(Player*){return false;}}group;auto sAdventureGroupMgr=&group;
|
|
struct AdventureBehaviorMgr{
|
|
enum class Phase{WaitingGroup,OnSite};struct Record{Phase State=Phase::WaitingGroup;std::string Intent="instance",Location="remote-dungeon",Micro,Detail;unsigned AnchorMap=1,MicroTimer=0,GestureTimer=0,WorkObject=0,WorkEmote=0;bool WorkPending=false;struct{bool Active=false;}Recovery,Social;};
|
|
unsigned calls=0,resets=0;std::string action;
|
|
void UpdateActivities(Player*,Record&);
|
|
void ResetMicro(Player*,Record&r){++resets;r.Micro.clear();r.Recovery.Active=r.Social.Active=false;}
|
|
bool UpdateRecovery(Player*,Record&,unsigned){return false;}bool UpdateSocial(Player*,Record&,unsigned){return true;}
|
|
void Fallback(Player*,Record&){assert(false);}
|
|
void Micro(Player*,Record&r){
|
|
struct{std::map<std::string,int>Intents{{"groupformation",1},{"pvp",2},{"adventure",3},{"instance",4}};}a;
|
|
'''+selector+r'''
|
|
action=w->first;++calls;r.Micro="performative";r.MicroTimer=5000;
|
|
}
|
|
};
|
|
'''+s[a:z]+r'''
|
|
int main(){
|
|
AdventureBehaviorMgr mgr;AdventureBehaviorMgr::Record r;Player p;
|
|
mgr.UpdateActivities(&p,r);assert(mgr.calls==1&&mgr.action=="groupformation"&&r.Intent=="instance"&&r.Location=="remote-dungeon");
|
|
mgr.UpdateActivities(&p,r);assert(mgr.calls==1); // ongoing action is not restarted
|
|
r.MicroTimer=0;travel.status.State=ClientlessTravelState::Moving;mgr.UpdateActivities(&p,r);assert(mgr.calls==1);
|
|
travel.status.State=ClientlessTravelState::Arrived;mgr.UpdateActivities(&p,r);assert(mgr.calls==2&&mgr.resets==1);
|
|
r.Social.Active=true;mgr.UpdateActivities(&p,r);assert(mgr.calls==2);
|
|
r.Social.Active=false;r.Micro.clear();r.MicroTimer=0;r.Intent="pvp";
|
|
mgr.UpdateActivities(&p,r);assert(mgr.action=="groupformation"&&r.Intent=="pvp");
|
|
r.Micro.clear();r.MicroTimer=0;r.State=AdventureBehaviorMgr::Phase::OnSite;r.Intent="pvp";
|
|
mgr.UpdateActivities(&p,r);assert(mgr.action=="adventure");
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
p=Path(folder);(p/'test.cpp').write_text(code)
|
|
subprocess.run(['c++','-std=c++17',str(p/'test.cpp'),'-o',str(p/'test')],check=True)
|
|
subprocess.run([str(p/'test')],check=True)
|
|
print('Waiting activities: formation catalog selected without changing dungeon intent/destination; action, movement and social lifetimes preserved.')
|