Improve AI garrisons, player recovery and mission administration
This commit is contained in:
@@ -12,7 +12,7 @@ def adapt(s):
|
||||
s=re.sub(r'foreach \((\w+) (\w+) : ([^)]+)\)',r'for (\1 \2 : \3)',s)
|
||||
for n in ('Replication','ERR_Actors','Math','ERR_Resources','ERR_DiscoveryService','SCR_InventoryStorageManagerComponent','SCR_AIGroupUtilityComponent','ERR_MortarSupplyState','ERR_LocationKind','ERR_ObjectiveDefence'):
|
||||
s=s.replace(n+'.',n+'::')
|
||||
for n in ('group','member','actor','request','inventory','known','unit','m_Mode','m_Battery','mode','m_Reroll','home','sites','record','m_Mortars','m_Scouts','m_Recon','m_Airfield'):
|
||||
for n in ('group','member','actor','request','inventory','known','unit','m_Mode','m_Battery','mode','m_Reroll','home','sites','record','m_Mortars','m_Scouts','m_Recon','m_Airfield','m_Hunters','m_Towns'):
|
||||
s=s.replace(n+'.',n+'->')
|
||||
s=s.replace('Actor.FindComponent(', 'Actor->FindComponent(').replace('SCR_InventoryStorageManagerComponent inventory', 'SCR_InventoryStorageManagerComponent* inventory').replace('SCR_AIGroupUtilityComponent utility', 'SCR_AIGroupUtilityComponent* utility')
|
||||
s=s.replace('home->Definition.', 'home->Definition->').replace('Patrol.IsEmpty()', 'Patrol->IsEmpty()').replace('unit->StatusSampler.Bind(', 'unit->StatusSampler.Bind(')
|
||||
@@ -69,7 +69,7 @@ struct Settings{int chance=100;int Runtime(const char*){return chance;}};
|
||||
namespace ERR_LocationKind {enum {RADIO=1};}
|
||||
namespace ERR_ObjectiveDefence {bool Objective(int kind){return kind==1;}}
|
||||
struct Definition{int Kind=3;string Id="site-a";Array<int>* Patrol=nullptr;};
|
||||
struct Site{struct Definition data;struct Definition* Definition=&data;};using ERR_SiteRuntime=Site*;
|
||||
struct Site{SCR_AIGroup Group=nullptr;struct Definition data;struct Definition* Definition=&data;};using ERR_SiteRuntime=Site*;
|
||||
struct Sites{Site home;Site* FindGroup(SCR_AIGroup){return &home;}};using ERR_SiteService=Sites*;
|
||||
struct ForceRecord{string SourceId="site-a";int InitialStrength=4;bool Physical=true,Eliminated=false;};using ERR_ForceRecord=ForceRecord*;
|
||||
struct Forces{ForceRecord record;bool available=false;ForceRecord* FindGroup(SCR_AIGroup){return available?&record:nullptr;}};
|
||||
@@ -91,7 +91,7 @@ struct Recon{SCR_AIGroup owned=nullptr;bool Owns(SCR_AIGroup group){return group
|
||||
struct BodyService:GroupService{void RegisterGroup(SCR_AIGroup g,Sampler& s){assert(s.Bound()&&s.group==g);GroupService::RegisterGroup(g);}};
|
||||
struct Reporting{int initializations=0;void Initialize(int id,float now){assert(id>0&&now==10);initializations++;}};
|
||||
struct Unit{Reporting AmmoReporting;string HomeId,ForceSourceId;bool ReservedForSupport=false;bool HomeGuard=false;float NextStatus=0;Sampler StatusSampler;int Id=0;SCR_AIGroup Group=nullptr;struct Utility* Utility=nullptr;float NextReport=0;};using ERR_HQUnit=Unit*;
|
||||
struct HQ{void BindSpecialSkills(SCR_AIGroup){}void AuditGroup(ERR_HQUnit){}Mode* m_Mode;GroupService m_Equipment;BodyService m_Bodies;int m_NextId=0;Array<ERR_HQUnit> m_Units;Mortars* m_Mortars=nullptr;Scouts* m_Scouts=nullptr;Recon* m_Recon=nullptr;Airfield* m_Airfield=nullptr;
|
||||
struct HQ{void BindSpecialSkills(SCR_AIGroup){}void AuditGroup(ERR_HQUnit){}Mode* m_Mode;GroupService m_Equipment;BodyService m_Bodies;int m_NextId=0;Array<ERR_HQUnit> m_Units;Mortars* m_Mortars=nullptr;Scouts* m_Scouts=nullptr;Recon* m_Recon=nullptr;Airfield* m_Airfield=nullptr;Scouts* m_Hunters=nullptr;Scouts* m_Towns=nullptr;
|
||||
'''+hqbind+hqregister+r'''
|
||||
};
|
||||
Intel* intel_;HQ* hq_;
|
||||
@@ -102,7 +102,7 @@ struct Ready{bool m_Stopped=false,m_Ready=false;Battery* m_Battery;int Finish(Mo
|
||||
'''+handoff+r'''
|
||||
}};
|
||||
int main(){
|
||||
Mode mode;Intel intel{&mode,{},{} };HQ hq{&mode,{},{},0,{}};intel_=&intel;hq_=&hq;Group group;Mortars mortars;mortars.owned=&group;hq.m_Mortars=&mortars;
|
||||
Mode mode;Intel intel{&mode,{},{} };HQ hq{&mode,{},{},0,{}};intel_=&intel;hq_=&hq;Group group;mode.sites.home.Group=&group;Mortars mortars;mortars.owned=&group;hq.m_Mortars=&mortars;
|
||||
hq.RegisterGroup(&group);assert(hq.m_Units.Count()==1&&mode.publications==0&&Math::rolls==0);
|
||||
assert(hq.m_Equipment.ids.Count()==1&&hq.m_Equipment.ids[0]==hq.m_Units[0]->Id&&hq.m_Units[0]->Id==1);
|
||||
assert(!hq.m_Equipment.fits[0]); // Existing mortar readiness owns this group's radio allocation.
|
||||
@@ -140,9 +140,17 @@ int main(){
|
||||
assert(hq.m_Equipment.ids.Count()==3&&hq.m_Equipment.ids[2]==hq.m_Units[2]->Id&&hq.m_Equipment.ids[2]==3&&hq.m_Equipment.fits[2]);
|
||||
// A subsequent missing mortar registry cannot reroll an already bound group's opt-out.
|
||||
hq.RegisterGroup(&group);assert(hq.m_Equipment.ids.Count()==3&&!hq.m_Equipment.fits[0]&&hq.m_NextId==3);
|
||||
Group radioGuards;mode.sites.home.data.Kind=ERR_LocationKind::RADIO;hq.RegisterGroup(&radioGuards);
|
||||
Group radioGuards;mode.sites.home.Group=&radioGuards;mode.sites.home.data.Kind=ERR_LocationKind::RADIO;hq.RegisterGroup(&radioGuards);
|
||||
assert(hq.m_Units[3]->ReservedForSupport && hq.m_Units[3]->HomeGuard);
|
||||
hq.RegisterGroup(&radioGuards);assert(hq.m_Units.Count()==4&&hq.m_Units[3]->ReservedForSupport);
|
||||
// Same home, separate mobile formation: only the permanent defenders are reserved.
|
||||
Group mobile;hq.RegisterGroup(&mobile);
|
||||
assert(!hq.m_Units[4]->ReservedForSupport && !hq.m_Units[4]->HomeGuard && hq.m_Units[4]->HomeId==hq.m_Units[3]->HomeId);
|
||||
Group hunter;Scouts hunters;hunters.owned=&hunter;hq.m_Hunters=&hunters;hq.RegisterGroup(&hunter);
|
||||
assert(hq.m_Equipment.ids.back()==1&&hq.m_Equipment.fits.back()); // every hunter selects physical manpack fitting
|
||||
Group ordinaryAgain;hq.RegisterGroup(&ordinaryAgain);assert(hq.m_Equipment.ids.back()==7); // ordinary fitting remains distributed
|
||||
Group town;Scouts towns;towns.owned=&town;hq.m_Towns=&towns;hq.RegisterGroup(&town);
|
||||
assert(hq.m_Equipment.ids.back()==1&&hq.m_Equipment.fits.back()&&!hq.m_Units.back()->ReservedForSupport&&!hq.m_Units.back()->HomeGuard);
|
||||
}
|
||||
''')
|
||||
print('PASS: actual Intel/HQ methods and one-shot qualified readiness handoff deliver late actors once; duplicate readiness, accepted spawn, pickup/drop, death and original negative rolls do not mint assignments')
|
||||
|
||||
Reference in New Issue
Block a user