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:
@@ -6,9 +6,12 @@ SOURCE=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PreparationStatus.c'
|
||||
def cpp(s):
|
||||
s=s.replace('protected ','').replace('override ','').replace('null','nullptr')
|
||||
s=s.replace('ERR_GameMode mode = ERR_GameMode.Get();','ERR_GameMode* mode = ERR_GameMode::Get();')
|
||||
s=s.replace('ERR_GameMode current = ERR_GameMode::Get();','ERR_GameMode* current = ERR_GameMode::Get();')
|
||||
s=s.replace('ERR_GameMode current = ERR_GameMode.Get();','ERR_GameMode* current = ERR_GameMode::Get();')
|
||||
s=s.replace('current.Phase()', 'current->Phase()')
|
||||
s=s.replace('ERR_GameMode mode,','ERR_GameMode* mode,')
|
||||
s=s.replace('ERR_GameMode mode)', 'ERR_GameMode* mode)')
|
||||
for name in ['System','ERR_GameMode','ERR_Phase','ERR_ObjectiveText']:s=s.replace(name+'.',name+'::')
|
||||
for name in ['System','ERR_GameMode','ERR_Phase','ERR_ObjectiveText','ERR_MissionRules']:s=s.replace(name+'.',name+'::')
|
||||
s=s.replace('TextWidget.Cast(','CastText(').replace('Widget widget)', 'Widget* widget)').replace('widget.', 'widget->')
|
||||
for name in ['mode','m_wLoadingPlaceholder','m_ERRPreparationSpinner','m_ERRPreparationRoot','m_ERRPreparationTitle','m_ERRPreparationDescription']:
|
||||
s=s.replace(name+'.',name+'->')
|
||||
@@ -22,6 +25,7 @@ run(r'''
|
||||
using string=std::string;
|
||||
namespace System{bool console=false;bool IsConsoleApp(){return console;}}
|
||||
namespace ERR_Phase{enum{PREPARING,PRISON,RADIO_SEARCH,RADIO_DEFENCE,EXTRACTION,VICTORY,DEFEAT};}
|
||||
namespace ERR_MissionRules{bool Terminal(int p){return p==ERR_Phase::VICTORY||p==ERR_Phase::DEFEAT;}}
|
||||
struct ERR_GameMode{static ERR_GameMode* current;int phase=ERR_Phase::PREPARING;string error;static ERR_GameMode* Get(){return current;}int Phase(){return phase;}bool Active(){return phase>=ERR_Phase::PRISON&&phase<=ERR_Phase::EXTRACTION;}string PreparationError(){return error;}};ERR_GameMode* ERR_GameMode::current=nullptr;
|
||||
namespace ERR_ObjectiveText{string Description(ERR_GameMode* mode,bool){return mode->error.empty()?"Preparing sites":"Mission failed; ask an administrator to correct and restart";}}
|
||||
struct Widget{Widget* parent=nullptr;bool visible=true,removed=false,textWidget=false;string text;int textWrites=0,visibilityWrites=0;float width=900,height=170;std::map<string,Widget*> children;
|
||||
@@ -48,9 +52,12 @@ int main(){
|
||||
f.mode.phase=ERR_Phase::PRISON;f.p.UpdateLoadingPlaceholder(.1f);assert(!root->removed&&!f.parent.removed&&f.spinner.visible&&f.p.ERR_ProbePreparationVisible(&f.mode,false));
|
||||
assert(description->text=="Please wait while your spawn area and equipment finish loading. You will take control when preparation is complete.");
|
||||
for(int phase=ERR_Phase::PRISON;phase<=ERR_Phase::EXTRACTION;phase++){f.mode.phase=phase;for(int i=0;i<200;i++)f.p.UpdateLoadingPlaceholder(.1f);assert(f.p.m_ERRPreparationRoot==root&&f.p.ERR_ProbePreparationVisible(&f.mode,false));}
|
||||
f.mode.phase=ERR_Phase::VICTORY;f.p.UpdateLoadingPlaceholder(.1f);assert(root->removed&&!f.parent.removed&&f.spinner.visible&&!f.p.m_ERRPreparationRoot);
|
||||
f.mode.phase=ERR_Phase::VICTORY;f.p.UpdateLoadingPlaceholder(.1f);assert(root->removed&&f.parent.removed&&f.spinner.visible&&!f.p.m_ERRPreparationRoot&&f.p.destroys==1);
|
||||
}
|
||||
for(int mismatch=0;mismatch<6;mismatch++){Fixture f;ERR_GameMode other;if(mismatch==0)ERR_GameMode::current=nullptr;if(mismatch==1)f.p.m_pGameMode=&other;if(mismatch==2)f.mode.phase=ERR_Phase::VICTORY;if(mismatch==3)System::console=true;if(mismatch==4)f.p.m_wLoadingPlaceholder=nullptr;if(mismatch==5)f.p.m_pGameMode=nullptr;f.p.UpdateLoadingPlaceholder(.1f);assert(game.workspace.creates==0&&f.p.nativeUpdates==1&&!f.parent.removed&&f.spinner.visibilityWrites==0);}
|
||||
for(int phase : {ERR_Phase::VICTORY,ERR_Phase::DEFEAT}){Fixture f;f.p.UpdateLoadingPlaceholder(.1f);f.p.ERR_KeepSpawnSceneLoading(true);f.mode.phase=phase;f.p.UpdateLoadingPlaceholder(.1f);assert(f.parent.removed&&!f.p.m_ERRKeepSpawnSceneLoading&&f.p.destroys==1);}
|
||||
{Fixture f;f.p.ERR_KeepSpawnSceneLoading(true);ERR_GameMode replacement;ERR_GameMode::current=&replacement;f.p.DestroyLoadingPlaceholder();assert(f.parent.removed&&f.p.destroys==1);}
|
||||
{Fixture f;f.p.ERR_KeepSpawnSceneLoading(true);ERR_GameMode::current=nullptr;f.p.DestroyLoadingPlaceholder();assert(f.parent.removed&&f.p.destroys==1);}
|
||||
for(int mismatch=0;mismatch<6;mismatch++){Fixture f;ERR_GameMode other;if(mismatch==0)ERR_GameMode::current=nullptr;if(mismatch==1)f.p.m_pGameMode=&other;if(mismatch==2)f.mode.phase=-1;if(mismatch==3)System::console=true;if(mismatch==4)f.p.m_wLoadingPlaceholder=nullptr;if(mismatch==5)f.p.m_pGameMode=nullptr;f.p.UpdateLoadingPlaceholder(.1f);assert(game.workspace.creates==0&&f.p.nativeUpdates==1&&!f.parent.removed&&f.spinner.visibilityWrites==0);}
|
||||
{Fixture f;f.mode.phase=ERR_Phase::PRISON;f.p.UpdateLoadingPlaceholder(.1f);assert(f.p.ERR_ProbePreparationVisible(&f.mode,false));Widget* root=f.p.m_ERRPreparationRoot;f.p.DestroyLoadingPlaceholder();assert(root->removed&&f.parent.removed&&!f.p.m_ERRPreparationRoot&&f.p.destroys==1);f.p.UpdateLoadingPlaceholder(.1f);assert(game.workspace.creates==1);}
|
||||
{Fixture f;f.mode.error="bad";f.spinner.visible=false;f.p.UpdateLoadingPlaceholder(.1f);assert(f.p.ERR_ProbePreparationVisible(&f.mode,true));f.p.ERR_ClearPreparationStatus();assert(!f.spinner.visible);}
|
||||
{Fixture f;f.mode.error="bad";f.p.UpdateLoadingPlaceholder(.1f);Widget* old=f.p.m_ERRPreparationRoot;Widget newParent,newSpinner;newParent.children["Spinner"]=&newSpinner;newSpinner.parent=&newParent;f.p.m_wLoadingPlaceholder=&newParent;f.p.UpdateLoadingPlaceholder(.1f);assert(old->removed&&f.spinner.visible&&!newSpinner.visible&&f.p.m_ERRPreparationParent==&newParent&&game.workspace.creates==2);f.p.DestroyLoadingPlaceholder();assert(newParent.removed&&!f.parent.removed&&newSpinner.visible&&!f.p.m_ERRPreparationRoot&&f.p.destroys==1);}
|
||||
@@ -93,3 +100,26 @@ base=(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_NativeBaseSmoke.c').read_te
|
||||
assert 'ERR_NativePreparationStatusProbe.Tick(this, now)' in base
|
||||
assert 'native-end-active' in base and 'native-end-preparing' in base
|
||||
print('PASS: actual preparation status scope, persistent updates, spinner restoration, placeholder replacement/deletion/destruction, native observation persistence/timeout; rendering remains native-pending')
|
||||
|
||||
# Execute the production world-system rebind that restores frame delivery.
|
||||
source=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_TerrainTakeoverManagers.c'
|
||||
bind=body(source,'void ERR_BindEscapeRespawn(').replace('SCR_RespawnSystemComponent respawn','Respawn* respawn').replace('ERR_GameMode mode = ERR_GameMode.Get();','Mode* mode = Mode::current;').replace('SCR_RespawnSystemComponent.Cast(mode.FindComponent(SCR_RespawnSystemComponent))','mode->respawn')
|
||||
run(r"""
|
||||
#include <cassert>
|
||||
struct Respawn{int frames=0;};struct Mode{inline static Mode* current=nullptr;Respawn* respawn=nullptr;};void Print(const char*){}
|
||||
struct System{Respawn* m_RespawnSystem=nullptr;bool m_bReady=true,enabled=false;int enables=0;void Enable(bool value){enabled=value;enables++;}
|
||||
"""+bind+r"""
|
||||
void Frame(){if(enabled&&m_RespawnSystem)m_RespawnSystem->frames++;}
|
||||
};
|
||||
int main(){System system;Mode mode;Respawn original,replacement,unrelated;Mode::current=&mode;mode.respawn=&replacement;system.m_RespawnSystem=&original;
|
||||
system.ERR_BindEscapeRespawn(&unrelated);assert(system.enables==0&&system.m_RespawnSystem==&original);
|
||||
system.ERR_BindEscapeRespawn(nullptr);assert(system.enables==0);
|
||||
system.ERR_BindEscapeRespawn(&replacement);assert(system.enabled&&!system.m_bReady&&system.m_RespawnSystem==&replacement);system.Frame();assert(replacement.frames==1&&original.frames==0);
|
||||
system.m_bReady=true;system.ERR_BindEscapeRespawn(&replacement);assert(system.m_bReady); // Idempotent: keep current deploy readiness.
|
||||
Mode::current=nullptr;system.ERR_BindEscapeRespawn(&original);assert(system.m_RespawnSystem==&replacement);
|
||||
}
|
||||
""")
|
||||
create=body(SOURCE,'protected override void CreateLoadingPlaceholder(')
|
||||
assert create.index('super.CreateLoadingPlaceholder()') < create.index('ERR_BindEscapeRespawn(this)')
|
||||
assert 'm_fAutoReloadTime 10' in prefab
|
||||
print('PASS: replaced respawn system receives frame updates, disabled updater wakes, stale/non-Escape binding refused; terminal and stale preload leases release black overlay')
|
||||
|
||||
Reference in New Issue
Block a user