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:
@@ -9,7 +9,7 @@ A=BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c'
|
||||
def cpp(s):
|
||||
for old,new in [('protected ',''),('override ',''),('null','nullptr'),('Replication.','Replication::'),
|
||||
('ERR_GameMode.','ERR_GameMode::'),('ERR_ConvoyRoadPlan.','ERR_ConvoyRoadPlan::'),
|
||||
('ERR_Settings.','ERR_Settings::'),('Math.','Math::'),('array<string>','Array<string>&')]:s=s.replace(old,new)
|
||||
('ERR_AdminMenuFields.','ERR_AdminMenuFields::'),('ERR_Settings.','ERR_Settings::'),('ERR_TimeService.','ERR_TimeService::'),('ERR_EnvironmentService.','ERR_EnvironmentService::'),('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_SupplyConvoys','m_ConvoyStartup','m_Mode','m_Convoys','m_ConvoyPool','m_ConvoyTask','m_HQ','site','unit','receipt','mode','provider'):
|
||||
@@ -32,6 +32,8 @@ hq='\n'.join(cpp(body(H,s)) for s in ('static bool MissionActive(', 'bool Prepar
|
||||
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('))
|
||||
selection=cpp(body(A,'static bool Selection('))
|
||||
selection_rules='\n'.join(cpp(body(BASE/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c',sig)) for sig in ('static bool Randomizable(', 'static bool ValidSelection(', 'static string SelectionText('))
|
||||
extension=cpp(body(A,'protected bool Extension('))
|
||||
# Execute the exact complete auth/normalization/extension-dispatch region.
|
||||
# Unrelated settings/help parsers after this boundary are covered by their own suites.
|
||||
@@ -65,10 +67,6 @@ void string::Split(const char* separator,Array<string>& parts,bool skipEmpty)con
|
||||
begin=end+width;
|
||||
}
|
||||
}
|
||||
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;};
|
||||
struct Math{static int Max(int a,int b){return std::max(a,b);}};
|
||||
struct Replication{inline static bool server=true;static bool IsServer(){return server;}};
|
||||
@@ -83,18 +81,26 @@ struct ERR_Settings{
|
||||
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=="antiAirChancePercent"?stinger:automatic;}
|
||||
'''+validator+r'''
|
||||
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;
|
||||
'''+selection_rules+r'''
|
||||
bool Set(string key,int value){writes++;if(saveFails||!ValidSelection(key,value))return false;
|
||||
if(key=="convoyCount"){convoy=value;return true;}
|
||||
if(key=="automaticConvoyEnabled"){automatic=value;return true;}
|
||||
assert(key=="antiAirChancePercent");stinger=value;return true;}
|
||||
};
|
||||
// Settings listing is outside these convoy assertions (Keys is empty); its actual formatter is covered by test_start_settings.
|
||||
struct ERR_AdminMenuFields{static string Display(string,string v){return v;}static string StartSummary(int,int){return "start summary";}};
|
||||
// Date/time branches are unrelated to these commands and deliberately refuse.
|
||||
struct ERR_TimeService{static bool ParseClock(string,int&){return false;}};
|
||||
struct ERR_EnvironmentService{static bool ParseDate(string,int&){return false;}static bool ParseProfile(string,int&){return false;}};
|
||||
struct ERR_CommandArguments{
|
||||
'''+integer+selection+r'''
|
||||
};
|
||||
struct ERR_GameMode{
|
||||
inline static ERR_GameMode* current=nullptr;bool active=true,settingsReady=true;Ledger ledger;
|
||||
struct Sites sites;ERR_Settings settings;bool sitesReady=true;
|
||||
static ERR_GameMode* Get(){return current;}bool Active(){return active;}Ledger* Forces(){return &ledger;}
|
||||
struct Sites* Sites(){return sitesReady?&sites:nullptr;}ERR_Settings* Settings(){return settingsReady?&settings:nullptr;}
|
||||
string Status(){return "mission";}bool AbandonRound(){return false;}
|
||||
int StartMode(){return 0;}string Status(){return "mission";}bool AbandonRound(){return false;}
|
||||
};
|
||||
struct Clock{float GetWorldTime(){return 123000;}Clock* GetWorld(){return this;}}clock_;
|
||||
Clock* GetGame(){return &clock_;}
|
||||
@@ -129,6 +135,7 @@ 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& Roadblocks(){return recon;}
|
||||
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;
|
||||
@@ -190,6 +197,25 @@ int main(){
|
||||
admin.Execute(&mode,true,"hq stinger set 1junk",replies);assert(mode.settings.writes==writes&&mode.settings.stinger==0);
|
||||
admin.Execute(&mode,true,"hq stinger set 10001",replies);assert(mode.settings.stinger==0&&replies[0].find("previous setting retained")!=string::npos);
|
||||
replies.Clear();assert(unavailable.Execute(&mode,"hq stinger set 1",replies)&&replies[0]=="HQ unavailable.");
|
||||
// Random uses the same parser and validation as numeric Stinger and convoy settings.
|
||||
writes=mode.settings.writes;
|
||||
admin.Execute(&mode,false,"hq stinger set random",replies);
|
||||
assert(mode.settings.writes==writes&&mode.settings.stinger==0&&replies[0]=="Administrator access required.");
|
||||
Replication::server=false;admin.Execute(&mode,true,"hq stinger set random",replies);
|
||||
assert(mode.settings.writes==writes&&replies.IsEmpty());Replication::server=true;
|
||||
admin.Execute(&mode,true," HQ STINGER SET RANDOM ",replies);
|
||||
assert(mode.settings.writes==writes+1&&mode.settings.stinger==-1&&replies[0].find("antiAirChancePercent=Random saved.")!=string::npos);
|
||||
admin.Execute(&mode,true,"hq stinger show",replies);assert(replies[0].find("antiAirChancePercent=Random.")!=string::npos);
|
||||
writes=mode.settings.writes;
|
||||
for(string bad:{"-1","random-day","random day","1junk"}){
|
||||
admin.Execute(&mode,true,"hq stinger set "+bad,replies);assert(mode.settings.writes==writes&&mode.settings.stinger==-1);
|
||||
}
|
||||
admin.Execute(&mode,true,"hq stinger set 101",replies);assert(mode.settings.stinger==-1&&replies[0].find("previous setting retained")!=string::npos);
|
||||
mode.settings.saveFails=true;admin.Execute(&mode,true,"hq stinger set 0",replies);assert(mode.settings.stinger==-1);
|
||||
mode.settings.saveFails=false;admin.Execute(&mode,true,"hq stinger set 0",replies);assert(mode.settings.stinger==0);
|
||||
mode.settings.saveFails=true;admin.Execute(&mode,true,"hq stinger set random",replies);
|
||||
assert(mode.settings.stinger==0&&replies[0].find("previous setting retained")!=string::npos);mode.settings.saveFails=false;
|
||||
assert(pool.calls==0&&service.calls==0&&ERR_ConvoyRoadPlan::calls==0);
|
||||
// New automatic switch is saved only: it does not scan, reserve or launch now.
|
||||
writes=mode.settings.writes;
|
||||
admin.Execute(&mode,false,"hq convoy auto set 0",replies);assert(mode.settings.writes==writes&&mode.settings.automatic==1);
|
||||
@@ -261,7 +287,7 @@ int main(){
|
||||
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);
|
||||
admin.Execute(&mode,true,"convoys show",replies);assert(replies.Count()==1&&replies[0].find("Random")!=std::string::npos);
|
||||
|
||||
}
|
||||
''')
|
||||
|
||||
Reference in New Issue
Block a user