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.
This commit is contained in:
@@ -12,23 +12,24 @@ def cpp(s):
|
||||
('ERR_Settings.','ERR_Settings::'),('Math.','Math::'),('array<string>','Array<string>&')]:s=s.replace(old,new)
|
||||
for typ in ('ERR_GameMode','ERR_ConvoyReceipt','ERR_ConvoyTask','ERR_SiteRuntime','ERR_HQUnit','ERR_AdminProvider'):
|
||||
s=re.sub(r'\b'+typ+r' (?=\w)',typ+'* ',s)
|
||||
for var in ('m_ConvoyStartup','m_Mode','m_Convoys','m_ConvoyPool','m_ConvoyTask','m_HQ','site','unit','receipt','mode','provider'):
|
||||
for var in ('m_SupplyConvoys','m_ConvoyStartup','m_Mode','m_Convoys','m_ConvoyPool','m_ConvoyTask','m_HQ','site','unit','receipt','mode','provider'):
|
||||
s=s.replace(var+'.',var+'->')
|
||||
s=s.replace('site->Definition.', 'site->Definition->')
|
||||
for name in ('GetGame()','GetWorld()','Forces()','Sites()','Settings()'):s=s.replace(name+'.',name+'->')
|
||||
for name in ('GetGame()','GetWorld()','Forces()','Sites()','Settings()','Recon()','AirAssault()','Airfield()','Recovery()'):s=s.replace(name+'.',name+'->')
|
||||
s=s.replace('foreach (ERR_HQUnit* unit : m_Units)','for (ERR_HQUnit* unit : m_Units)')
|
||||
s=s.replace('foreach (ERR_AdminProvider* provider : m_Providers)','for (ERR_AdminProvider* provider : m_Providers)')
|
||||
s=s.replace('foreach (string key : ERR_Settings::Keys())','for (string key : ERR_Settings::Keys())')
|
||||
s=s.replace('mode->Settings()->Get(key).ToString()','string(std::to_string(mode->Settings()->Get(key)))')
|
||||
s=s.replace('bool handled;','bool handled=false;')
|
||||
s=s.replace('Array<string>& parts = {};','Array<string> parts = {};')
|
||||
s=s.replace('Array<string>& parts = {};','Array<string> parts = {};').replace('Array<string>& countParts = {};','Array<string> countParts = {};').replace('ERR_CommandArguments.Selection','ERR_CommandArguments::Selection')
|
||||
s=s.replace('Array<string>& timerParts = {};','Array<string> timerParts = {};')
|
||||
s=s.replace('out int ', 'int& ').replace('ERR_CommandArguments.Integer', 'ERR_CommandArguments::Integer')
|
||||
s=s.replace('value.ToString()', 'string(std::to_string(value))')
|
||||
s=s.replace('"0123456789".IndexOf(', 'string("0123456789").IndexOf(')
|
||||
return s
|
||||
hq='\n'.join(cpp(body(H,s)) for s in ('static bool MissionActive(', 'bool PrepareConvoy(', 'bool StartConvoy(',
|
||||
'bool StartScenarioConvoy(', 'string ConvoyStatus('))
|
||||
provider=cpp(body(P,'protected void ConvoyAutoSetting('))+cpp(body(P,'protected void StingerSetting('))+cpp(body(P,'override bool Execute('))
|
||||
provider=cpp(body(P,'protected void CountSetting('))+cpp(body(P,'protected void ConvoyAutoSetting('))+cpp(body(P,'protected void StingerSetting('))+cpp(body(P,'override bool Execute('))
|
||||
integer=cpp(body(A,'static bool Integer('))
|
||||
validator=cpp(body(BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c','static bool Valid('))
|
||||
extension=cpp(body(A,'protected bool Extension('))
|
||||
@@ -65,6 +66,7 @@ void string::Split(const char* separator,Array<string>& parts,bool skipEmpty)con
|
||||
}
|
||||
}
|
||||
struct ERR_CommandArguments{
|
||||
static bool Selection(string key,string text,int& value){if(key!="convoyCount")return false;if(text=="random"){value=-1;return true;}return Integer(text,value)&&value>=0&&value<=20;}
|
||||
'''+integer+r'''
|
||||
};
|
||||
struct vector{float x=0,y=0,z=0;};
|
||||
@@ -78,10 +80,12 @@ struct ERR_SiteRuntime{struct Definition* Definition=nullptr;};
|
||||
struct Sites{ERR_SiteRuntime* site=nullptr;int finds=0;string last;
|
||||
ERR_SiteRuntime* Find(string id){finds++;last=id;return site;}};
|
||||
struct ERR_Settings{
|
||||
int automatic=1,stinger=15,writes=0;bool saveFails=false;
|
||||
static Array<string> Keys(){return {}; }int Get(string key){return key=="stingerChanceOneIn"?stinger:automatic;}
|
||||
int automatic=1,stinger=15,convoy=3,writes=0;bool saveFails=false;
|
||||
static Array<string> Keys(){return {}; }int Get(string key){if(key=="convoyCount")return convoy;return key=="stingerChanceOneIn"?stinger:automatic;}
|
||||
'''+validator+r'''
|
||||
bool Set(string key,int value){writes++;if(saveFails||!Valid(key,value))return false;
|
||||
static string SelectionText(int value){return value==-1?string("random"):string(std::to_string(value));}
|
||||
bool Set(string key,int value){writes++;if(saveFails||(!Valid(key,value)&&!(key=="convoyCount"&&value==-1)))return false;
|
||||
if(key=="convoyCount"){convoy=value;return true;}
|
||||
if(key=="automaticConvoyEnabled"){automatic=value;return true;}
|
||||
assert(key=="stingerChanceOneIn");stinger=value;return true;}
|
||||
};
|
||||
@@ -118,10 +122,15 @@ struct Service{
|
||||
if(!preflight)return nullptr;
|
||||
receipt->Consumed=true;task.Stopped=partial;task.retained=partial?3:6;return &task;
|
||||
}
|
||||
int Count(){return 0;}ERR_ConvoyTask* At(int){return &task;}
|
||||
string Status(){statusCalls++;return task.Stopped?"stopped; retained vehicles=3":"convoy service status";}
|
||||
};
|
||||
struct Supply{bool StartOne(){return false;}string Status(){return "supply";}};
|
||||
struct ERR_ConvoyStartup{string Status(){return "startup snapshot";}};
|
||||
struct ReconService{string Status(){return "recon";}void Return(){}bool SetDelay(int n){return n>=1&&n<=1440;}};
|
||||
struct HQ{
|
||||
ReconService recon;ReconService* Recon(){return &recon;}ReconService* AirAssault(){return &recon;}ReconService* Airfield(){return &recon;}ReconService* Recovery(){return &recon;}
|
||||
Supply* m_SupplyConvoys=nullptr;bool ConvoyAdmissionReady(){return true;}
|
||||
ERR_ConvoyStartup* m_ConvoyStartup=nullptr;
|
||||
ERR_GameMode* m_Mode;Pool* m_ConvoyPool;Service* m_Convoys;ERR_ConvoyTask* m_ConvoyTask=nullptr;
|
||||
Array<vector>m_ConvoyPositions,m_ConvoyAngles;ERR_ForceRoute* m_ConvoyRoute=nullptr;string m_ConvoyFailure;
|
||||
@@ -246,6 +255,14 @@ int main(){
|
||||
Service consumedService;HQ consumed(&mode,&consumedPool,&consumedService);
|
||||
assert(!consumed.StartScenarioConvoy()&&!consumed.m_ConvoyTask&&consumedService.calls==0);
|
||||
assert(consumed.ConvoyStatus().find("finite convoy allowance")!=string::npos);
|
||||
for(string command:{"convoys set 0","hq convoy count set 20","convoys set random"}){
|
||||
int calls=service.calls;replies.Clear();admin.Execute(&mode,true,command,replies);assert(replies.Count()==1&&replies[0].find("saved for next round")!=std::string::npos&&service.calls==calls);
|
||||
}
|
||||
assert(mode.settings.convoy==-1);writes=mode.settings.writes;admin.Execute(&mode,false,"convoys set 5",replies);assert(mode.settings.convoy==-1&&mode.settings.writes==writes);
|
||||
for(string invalid:{"convoys set 21","convoys set -2","convoys set 1 extra"}){admin.Execute(&mode,true,invalid,replies);assert(mode.settings.convoy==-1);}
|
||||
mode.settings.saveFails=true;admin.Execute(&mode,true,"convoys set 4",replies);assert(mode.settings.convoy==-1);mode.settings.saveFails=false;
|
||||
admin.Execute(&mode,true,"convoys show",replies);assert(replies.Count()==1&&replies[0].find("random")!=std::string::npos);
|
||||
|
||||
}
|
||||
''')
|
||||
for sig in ('bool PrepareConvoy(', 'bool StartConvoy(', 'bool StartScenarioConvoy('):
|
||||
|
||||
Reference in New Issue
Block a user