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:
@@ -2,6 +2,23 @@
|
||||
import re
|
||||
from policy_harness import ROOT, body, run
|
||||
core=ROOT/'addons/core/Scripts/Game/ERR/00_Core'
|
||||
shared=body(core/'ERR_SiteDefinition.c','static int SharedRoster(')
|
||||
run('#include <cassert>\n'+shared+r'''
|
||||
int main(){
|
||||
for(int sites=9;sites<=24;sites++){
|
||||
int fixed=0,mobile=0;
|
||||
for(int i=0;i<sites;i++){
|
||||
int guards=SharedRoster(32,sites,i),responders=SharedRoster(16,sites,i);
|
||||
assert(guards>=1&&guards<=4&&responders>=0&&responders<=2);
|
||||
fixed+=guards;mobile+=responders;
|
||||
}
|
||||
assert(fixed==32&&mobile==16);
|
||||
}
|
||||
assert(SharedRoster(32,0,0)==0&&SharedRoster(-1,12,0)==0);
|
||||
assert(SharedRoster(32,12,-1)==0&&SharedRoster(32,12,12)==0);
|
||||
}
|
||||
''')
|
||||
print('PASS: increased site populations preserve the 32 fixed / 16 mobile field-soldier budget, with guards at every site')
|
||||
roster=body(core/'ERR_SiteSquads.c','static array<ResourceName> Roster(')
|
||||
roster=roster.replace('static array<ResourceName>', 'Array<Text>').replace('array<ResourceName> source','Array<Text>* source').replace('array<ResourceName>','Array<Text>').replace('ResourceName member','Text member').replace('source.', 'source->').replace('source[index % source->Count()]','(*source)[index % source->Count()]').replace('foreach (','for (').replace('member : source','member : *source')
|
||||
spacing=body(core/'ERR_GeneratedSites.c','protected bool Separated(').replace('protected ', '').replace('ERR_SiteDefinition candidate','Site* candidate').replace('ERR_SiteDefinition other','Site* other').replace('vector position','Vec position').replace('foreach (','for (')
|
||||
@@ -53,3 +70,45 @@ int main(){
|
||||
}
|
||||
''')
|
||||
print('PASS: mortar couriers use the mobile site team and refuse permanent-only garrisons')
|
||||
|
||||
# Execute the actual depot selection against surviving site runtimes. Optional
|
||||
# terrain omissions must not retain a dependency on one authored camp ID.
|
||||
select=body(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarLogistics.c','static ERR_SiteRuntime FindDepot(')
|
||||
select=select.replace('static ERR_SiteRuntime', 'Site*').replace('ERR_SiteService sites','Sites* sites').replace('ERR_SiteRuntime ', 'Site* ')
|
||||
select=select.replace('ERR_LocationKind.', 'Kind::').replace('null','nullptr')
|
||||
for name in ('sites','site','crew'):
|
||||
select=select.replace(name+'.',name+'->')
|
||||
select=select.replace('site->Definition.', 'site->Definition->')
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
namespace Kind{enum{PRISON,RADIO,EXTRACTION,OUTPOST,DEPOT,MORTAR,HOSPITAL};}
|
||||
struct Definition {int Kind=Kind::OUTPOST;};
|
||||
struct Site {Site* Responders=nullptr;bool PatrolCycle=false;bool Group=false;void* Container=nullptr;struct Definition* Definition=nullptr;std::string Id;};
|
||||
struct Sites {
|
||||
std::vector<Site*> rows;void* owned=nullptr;
|
||||
Site* Find(std::string id){for(auto s:rows)if(s&&s->Id==id)return s;return nullptr;}
|
||||
int Count(){return rows.size();}Site* At(int i){return rows[i];}
|
||||
bool Owns(void* item){return item&&item==owned;}
|
||||
};
|
||||
'''+courier+select+r'''
|
||||
int main(){
|
||||
Sites sites;assert(FindDepot(&sites)==nullptr);
|
||||
int cache;Definition definition;Site permanent,mobile,camp,preferred,legacy,hospital;
|
||||
camp.Id="everon-camp-2";camp.Definition=&definition;camp.Container=&cache;camp.Responders=&mobile;
|
||||
sites.rows={nullptr,&permanent,&camp};sites.owned=&cache;
|
||||
assert(FindDepot(&sites)==nullptr); // missing mobile group
|
||||
mobile.Group=true;assert(FindDepot(&sites)==&camp); // preferred camp omitted
|
||||
sites.owned=nullptr;assert(FindDepot(&sites)==nullptr);sites.owned=&cache;
|
||||
camp.Responders=nullptr;assert(FindDepot(&sites)==nullptr); // do not borrow permanent defenders
|
||||
camp.Responders=&mobile;definition.Kind=Kind::HOSPITAL;assert(FindDepot(&sites)==nullptr);
|
||||
definition.Kind=Kind::DEPOT;assert(FindDepot(&sites)==&camp);
|
||||
definition.Kind=Kind::OUTPOST;
|
||||
preferred.Id="everon-outpost-1";legacy.Id="everon-supply-2";
|
||||
sites.rows.push_back(&preferred);assert(FindDepot(&sites)==&preferred);
|
||||
sites.rows.push_back(&legacy);assert(FindDepot(&sites)==&legacy);
|
||||
sites.rows.clear();assert(FindDepot(&sites)==nullptr); // all optional camps omitted
|
||||
}
|
||||
''')
|
||||
print('PASS: omitted preferred mortar depot selects a surviving owned camp/mobile team; no camp, foreign cache and permanent-only sites are unavailable; historical priority retained')
|
||||
|
||||
Reference in New Issue
Block a user