Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
"""Execute actual rescue asset/crew selection; native capacity remains a separate check."""
|
||||
from policy_harness import ROOT, body, run
|
||||
import re
|
||||
|
||||
source = ROOT / 'addons/core/Scripts/Game/ERR/10_AI/ERR_RescueAssets.c'
|
||||
s = '\n'.join(body(source, signature) for signature in (
|
||||
'static bool Western(', 'static int TransportCount(', 'static int TransportSeats(',
|
||||
'static ResourceName Aircraft(', 'static ResourceName Pilot(', 'static ResourceName Crew('))
|
||||
s = s.replace('ResourceName', 'std::string').replace('string faction', 'std::string faction')
|
||||
s = s.replace('ERR_GameMode mode', 'ERR_GameMode* mode')
|
||||
s = s.replace('ERR_FactionChoice choice', 'ERR_FactionChoice* choice')
|
||||
s = s.replace('Resource group', 'Resource* group').replace('IEntitySource source', 'IEntitySource* source')
|
||||
s = s.replace('array<std::string>', 'Array<std::string>')
|
||||
s = s.replace('mode.PlayerFaction().GetFactionKey()', 'mode->PlayerFaction()->GetFactionKey()')
|
||||
s = s.replace('mode.FactionSelection().Choice(', 'mode->FactionSelection()->Choice(')
|
||||
s = s.replace('group.GetResource().ToEntitySource()', 'group->GetResource()->ToEntitySource()')
|
||||
for name in ('mode', 'choice', 'group', 'source'):
|
||||
s = re.sub(r'\b' + name + r'\.', name + '->', s)
|
||||
s = s.replace('pilot.IsEmpty()', 'pilot.empty()').replace('Resource.Load(', 'Resource::Load(')
|
||||
run(r'''
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
template<class T> struct Array : std::vector<T> {
|
||||
using std::vector<T>::vector;
|
||||
bool IsEmpty(){return this->empty();}
|
||||
};
|
||||
struct Faction {std::string key;std::string GetFactionKey(){return key;}};
|
||||
struct ERR_FactionChoice {std::string Key, Group;};
|
||||
struct Selection {
|
||||
ERR_FactionChoice* choice=nullptr;
|
||||
ERR_FactionChoice* Choice(std::string role){assert(role=="escapists");return choice;}
|
||||
};
|
||||
struct ERR_GameMode {
|
||||
Faction* faction=nullptr;Selection* selection=nullptr;
|
||||
Faction* PlayerFaction(){return faction;}Selection* FactionSelection(){return selection;}
|
||||
};
|
||||
struct IEntitySource {
|
||||
Array<std::string> members;bool available=true;
|
||||
bool Get(std::string property,Array<std::string>& out){assert(property=="m_aUnitPrefabSlots");out=members;return available;}
|
||||
};
|
||||
struct Resource {
|
||||
bool valid=true;IEntitySource* source=nullptr;
|
||||
static inline std::map<std::string,Resource*> resources;
|
||||
static Resource* Load(std::string name){return resources[name];}
|
||||
bool IsValid(){return valid;}Resource* GetResource(){return this;}
|
||||
IEntitySource* ToEntitySource(){return source;}
|
||||
};
|
||||
struct Assets {
|
||||
''' + s + r'''
|
||||
};
|
||||
int main(){
|
||||
for (std::string key : {"US","USSR","FIA","RHS_USAF","RHS_AFRF","RHS_ION"}) {
|
||||
int count=Assets::TransportCount(key),capacity=Assets::TransportSeats(key);
|
||||
assert(count*capacity>=12);
|
||||
if(key=="US"||key=="RHS_USAF"||key=="RHS_ION")assert(count==2&&capacity==8);
|
||||
else assert(count==1&&capacity>=12);
|
||||
assert(!Assets::Aircraft(key,false).empty()&&!Assets::Aircraft(key,true).empty());
|
||||
}
|
||||
assert(Assets::Aircraft("US",false).find("RescueHelicopterWest.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("US",true).find("RescueEscortWest.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("RHS_USAF",false)==Assets::Aircraft("US",false));
|
||||
assert(Assets::Aircraft("USSR",false).find("RescueHelicopter.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("FIA",false).find("RescueHelicopterFIA.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("RHS_AFRF",false).find("RescueHelicopterAFRF.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("RHS_ION",false).find("RescueHelicopterION.et")!=std::string::npos);
|
||||
assert(Assets::Aircraft("RHS_ION",true).find("RescueEscortION.et")!=std::string::npos);
|
||||
Selection selection;Faction faction{"US"};ERR_GameMode mode{&faction,&selection};
|
||||
for (std::string key : {"US","USSR","RHS_USAF","RHS_AFRF"}) {
|
||||
faction.key=key;assert(!Assets::Pilot(key).empty());assert(Assets::Crew(&mode)==Assets::Pilot(key));
|
||||
}
|
||||
assert(Assets::Pilot("FIA").empty()&&Assets::Pilot("RHS_ION").empty());
|
||||
ERR_FactionChoice choice{"FIA","selected-group"};selection.choice=&choice;
|
||||
IEntitySource source{{"faction-specific-first-member","second-member"}};Resource group{true,&source};
|
||||
Resource::resources[choice.Group]=&group;
|
||||
for(std::string key : {"FIA","RHS_ION","custom-friendly"}){
|
||||
faction.key=key;choice.Key=key;assert(Assets::Crew(&mode)=="faction-specific-first-member");
|
||||
}
|
||||
choice.Key="USSR";assert(Assets::Crew(&mode).empty()); // A mismatched role never falls back to Soviet pilots.
|
||||
choice.Key=faction.key;group.valid=false;assert(Assets::Crew(&mode).empty());group.valid=true;
|
||||
source.available=false;assert(Assets::Crew(&mode).empty());source.available=true;
|
||||
source.members.clear();assert(Assets::Crew(&mode).empty());
|
||||
group.source=nullptr;assert(Assets::Crew(&mode).empty());
|
||||
Resource::resources.clear();assert(Assets::Crew(&mode).empty());
|
||||
selection.choice=nullptr;assert(Assets::Crew(&mode).empty());
|
||||
mode.selection=nullptr;assert(Assets::Crew(&mode).empty());
|
||||
mode.faction=nullptr;assert(Assets::Crew(&mode).empty());assert(Assets::Crew(nullptr).empty());
|
||||
}
|
||||
''')
|
||||
print('PASS: faction aircraft profiles provide 12+ cargo capacity; FIA/ION crew comes only from the selected faction')
|
||||
Reference in New Issue
Block a user