67 lines
4.9 KiB
Python
67 lines
4.9 KiB
Python
"""Execute production leader-plan inheritance without modifying members' own days."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/'src/server/game/World/AdventureBehaviorMgr.cpp').read_text()
|
|
sig='std::string AdventureBehaviorMgr::InteractionSchedule('
|
|
start=s.index(sig);begin=s.index('{',start);end=begin+1;depth=1
|
|
while depth:depth+=(s[end]=='{')-(s[end]=='}');end+=1
|
|
schedule=s[start:end]
|
|
a=s.index('AdventureGroupPlan AdventureBehaviorMgr::GroupPlan(')
|
|
code=r'''
|
|
#include "AdventureBehaviorPolicy.h"
|
|
#include "AdventureGroupPolicy.h"
|
|
#include "AdventureInstancePolicy.h"
|
|
#include <cassert>
|
|
#include <ctime>
|
|
#include <unordered_map>
|
|
using uint32=unsigned;
|
|
struct Guid{unsigned id;unsigned GetCounter(){return id;}};
|
|
struct Player{Guid guid;Guid GetGUID(){return guid;}};
|
|
struct AdventureGroupPlan{bool Enabled=false,Forming=false;std::string Intent,Location,NextIntent,NextLocation;time_t Deadline=0,NextDeadline=0;unsigned Capacity=0,Mode=0;bool EarlyDeparture=false;};
|
|
namespace GameTime{time_t GetGameTime(){return 100;}}
|
|
std::tm Local(time_t){std::tm tm{};tm.tm_hour=5;return tm;}unsigned DateOf(std::tm){return 1;}
|
|
struct Location{unsigned InstanceCapacity=5,InstanceDifficulty=1;};struct Locations{Location l;Location*Find(std::string const&){return &l;}}locations;auto sAdventureLocationMgr=&locations;
|
|
struct AdventureBehaviorMgr{
|
|
struct Record{bool Enabled=true,Schedule=true,GroupOverride=false,Dirty=false;int Hour=-1;unsigned Date=1;std::string Intent,Location,WantedIntent,WantedLocation,ManualNextIntent,ManualNextLocation;std::string PersonalIntent,PersonalLocation;time_t PersonalDeadline=0;time_t Deadline=3600;AdventureBehaviorPolicy::Day Plan;AdventureInstancePolicy::Visit Instance;AdventureGroupPolicy::Departure Departure;};
|
|
bool allowed=true;bool Allowed(Player*,::Location const&,std::string const&){return allowed;}
|
|
std::unordered_map<unsigned,Record>_records;int changes=0;
|
|
void Generate(Player*,Record&r,unsigned date){r.Date=date;}
|
|
void SetWanted(Player*,Record&r,std::string const&i,std::string const&l,time_t end){++changes;r.WantedIntent=i;r.WantedLocation=l;r.Deadline=end;}
|
|
std::string InteractionSchedule(Player*);void ResumePersonalPlan(Player*);AdventureGroupPlan GroupPlan(Player*);bool AdoptGroup(Player*,Player*);
|
|
};
|
|
'''+schedule+'\n'+s[a:]+r'''
|
|
int main(){
|
|
AdventureBehaviorMgr mgr;Player leader{{29}},member{{31}};auto& a=mgr._records[29];auto& b=mgr._records[31];
|
|
a.Intent="groupformation";a.Location="leader-capital";a.Plan[5]={"groupformation","leader-capital"};a.Plan[6]={"instance","deadmines"};
|
|
b.Intent="groupformation";b.Location="other-capital";b.Plan[5]={"groupformation","other-capital"};b.Plan[6]={"instance","shadowfang"};
|
|
mgr.allowed=false;assert(!mgr.GroupPlan(&member).Enabled);mgr.allowed=true;
|
|
auto plan=mgr.GroupPlan(&member);assert(plan.Forming&&plan.NextIntent=="instance"&&plan.NextLocation=="shadowfang");
|
|
assert(mgr.AdoptGroup(&member,&leader));assert(b.WantedLocation=="leader-capital"&&b.Deadline==a.Deadline&&b.Schedule);
|
|
assert(b.Plan[6].Location=="shadowfang"); // own future plan remains available after departure
|
|
a.Intent="instance";a.Location="deadmines";a.Deadline=7200;
|
|
assert(mgr.AdoptGroup(&member,&leader));assert(b.WantedIntent=="instance"&&b.WantedLocation=="deadmines"&&b.Deadline==7200);
|
|
b.Instance.Active=true;b.Instance.Stage=AdventureInstancePolicy::Phase::Inside;a.Location="other";
|
|
int changes=mgr.changes;assert(mgr.AdoptGroup(&member,&leader)&&mgr.changes==changes);
|
|
b.Instance.Stage=AdventureInstancePolicy::Phase::Travel;mgr.AdoptGroup(&member,&leader);assert(b.WantedLocation=="other");
|
|
a.Enabled=false;assert(!mgr.AdoptGroup(&member,&leader));
|
|
b.Instance.Active=false;mgr.ResumePersonalPlan(&member);
|
|
assert(!b.GroupOverride&&b.WantedIntent=="groupformation"&&b.WantedLocation=="other-capital");
|
|
b.Schedule=false;b.Intent="groupformation";b.ManualNextIntent="raid";b.ManualNextLocation="molten-core";
|
|
plan=mgr.GroupPlan(&member);assert(plan.Forming&&plan.NextIntent=="raid"&&plan.NextLocation=="molten-core");
|
|
// Different goals are inherited without inventing a personal intent change.
|
|
b.GroupOverride=false;b.Instance.Active=false;b.Intent=b.WantedIntent="social";
|
|
b.Location=b.WantedLocation="personal-place";b.Deadline=2000;
|
|
a.Enabled=true;a.Intent="social";a.Location="leader-place";
|
|
assert(mgr.AdoptGroup(&member,&leader));b.Location="leader-place";
|
|
assert(mgr.InteractionSchedule(&member)=="social:personal-place");
|
|
mgr.ResumePersonalPlan(&member);
|
|
assert(b.WantedLocation=="personal-place"&&mgr.InteractionSchedule(&member)=="social:personal-place");
|
|
}
|
|
'''
|
|
with tempfile.TemporaryDirectory() as d:
|
|
p=Path(d);(p/'plan.cpp').write_text(code)
|
|
subprocess.run(['g++','-std=c++17','-I'+str(root/'src/server/game/World'),str(p/'plan.cpp'),'-o',str(p/'plan')],check=True)
|
|
subprocess.run([str(p/'plan')],check=True)
|
|
print('Production group plans: leader meeting/goal/deadline inheritance, untouched personal day, manual preparation and instance-state guards passed.')
|