Files
EscapistsReintroduced/tests/test_content_policy.py
T
jakub 1b1a8b5173 Add mission customization, HQ support and aggression-driven AI
Integrate faction and random settings menus, generated objectives, scouts, convoys, air support, mortar stations and body-intel recovery. Add identified-body aggression, finite hunter UAZ deployment, dedicated objective defence and maximum AI skill with separate reduced aim accuracy. Include policy tests, native probes, evidence and documentation.
2026-09-23 15:07:14 +02:00

49 lines
3.3 KiB
Python

"""Exercise production content selection bodies with small engine boundary doubles.
Native preference I/O, group membership and UI have separate Workbench probes.
"""
from policy_harness import ROOT, body, run
import re
p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ContentPolicy.c'
def cpp(sig):
s=body(p,sig).replace('ResourceName ', 'string ').replace('Faction faction','Faction* faction')
s=s.replace('ERR_ContentRegistry.Definition().Find(pack)','registry.Find(pack)')
s=s.replace('ERR_ContentRegistry.Definition().Options','registry.Options')
s=s.replace('ERR_ContentOption option', 'Option* option').replace('foreach (','for (')
s=s.replace('array<ResourceName> groups', 'Array<string> groups')
s=s.replace('option.', 'option->').replace('faction.', 'faction->')
return s
run(r'''
#include <cassert>
#include <map>
#include <string>
#include <vector>
struct string:std::string {using std::string::string;string(std::string s):std::string(s){} bool IsEmpty(){return empty();}};
template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;void Insert(T v){this->push_back(v);}bool IsEmpty(){return this->empty();}int Count(){return this->size();}};
struct Flags:std::map<string,bool>{using std::map<string,bool>::operator=;bool Contains(string k){return count(k);}bool Get(string k){return (*this)[k];}};
struct Option{string Id,Parent,NativeFactionKey,GuardGroup;};
struct Registry{std::vector<Option*> Options;Option* Find(string id){for(auto*o:Options)if(o->Id==id)return o;return nullptr;}};
struct Faction{string key;string GetFactionKey(){return key;}};
struct Policy{int m_GuardOffset=0;Flags m_Active;Registry registry;
'''+'\n'.join(cpp(sig) for sig in ('bool Enabled(', 'ResourceName GuardGroup(', 'bool Enemy('))+r'''
};
int main(){
Option pack{"rhs","","",""}, a{"usmc","rhs","RHS_USAF","usmc-group"}, b{"afrf","rhs","RHS_AFRF","afrf-group"};
Policy p;p.registry.Options={&pack,&a,&b};p.m_Active={{"rhs",true},{"usmc",true},{"afrf",true}};
Faction usa{"RHS_USAF"},ru{"RHS_AFRF"},other{"US"};
assert(p.Enabled("")&&!p.Enabled("unknown"));assert(p.Enemy(&usa)&&p.Enemy(&ru)&&!p.Enemy(&other)&&!p.Enemy(nullptr));
assert(p.GuardGroup(0)=="usmc-group"&&p.GuardGroup(1)=="afrf-group"&&p.GuardGroup(2)=="usmc-group");
p.m_GuardOffset=1;assert(p.GuardGroup(0)=="afrf-group"&&p.GuardGroup(1)=="usmc-group");
p.m_Active["rhs"]=false;assert(!p.Enabled("rhs")&&!p.Enabled("usmc")&&!p.Enabled("afrf"));assert(p.GuardGroup(0).empty()&&!p.Enemy(&usa));
p.m_Active["rhs"]=true;p.m_Active["usmc"]=false;assert(!p.Enabled("usmc")&&p.Enabled("afrf"));
assert(p.GuardGroup(0)=="afrf-group"&&p.GuardGroup(10)=="afrf-group"&&!p.Enemy(&usa)&&p.Enemy(&ru));
p.m_Active["afrf"]=false;assert(p.GuardGroup(0).empty());
}
''')
# Config-driven labels, IDs and exact source resources; no fixed RHS row in UI.
registry=(ROOT/'addons/core/Configs/ERR/Content/Registry.conf').read_text()
assert re.findall(r'\bId "([^"]+)"',registry)==['rhs','rhs_usmc','rhs_afrf','rhs_ion']
assert len(re.findall(r'\bGuardGroup ',registry))==3
assert 'ERR_ContentRegistry.Ids()' in (ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ContentMenu.c').read_text()
assert 'PrisonBackpack.et' in (ROOT/'addons/core/Configs/ERR/EveronSites.conf').read_text()
print('PASS: actual content policy gates parent packs, individual factions, faction identity and finite group rotation with vanilla fallback')