Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
61 lines
3.8 KiB
Diff
61 lines
3.8 KiB
Diff
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
|
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
|
@@ -698,6 +698,7 @@
|
|
if (m_ERRTestPatrolHQ)
|
|
{
|
|
DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);
|
|
+ if (!ERR_Check(UnlockPrison(m_ERRSmokePlayer) && Phase() == ERR_Phase.RADIO_SEARCH, "patrol HQ fixture leaves prison through canonical admission before observing movement")) return;
|
|
m_ERRHQPatrolMovement = new ERR_NativePatrolProbe(this);
|
|
m_ERRSmokeStep = 130;
|
|
return;
|
|
--- a/tests/test_native_memory_deadlines.py
|
|
+++ b/tests/test_native_memory_deadlines.py
|
|
@@ -52,6 +52,7 @@
|
|
for(float now : {0.0f, 42000.0f}) {
|
|
for(string outcome : {"", "victory", "lost-helicopter"}) assert(deadline(outcome,now)==now+300000);
|
|
for(string outcome : {"escape-route", "normal-escape-route", "player-death", "radio-network", "hq-response", "map-ownership"}) assert(deadline(outcome,now)==now+150000);
|
|
+ assert(deadline("patrol-hq",now)==now+420000);
|
|
assert(deadline("hq-memory",now)==now+360000);
|
|
assert(deadline("hq-body",now)==now+240000);
|
|
assert(deadline("convoy",now)==now+540000);
|
|
@@ -118,3 +119,39 @@
|
|
}
|
|
'''.replace('LEGACY',conditions[0]).replace('FIXED',conditions[1]))
|
|
print('PASS: normal escape route keeps ordinary catalog and generated placement; historical selectors remain unchanged')
|
|
+
|
|
+# Execute the actual patrol-hq admission branch. The existing production
|
|
+# prison-AI/progression tests cover canonical UnlockPrison and phase callbacks;
|
|
+# here native damage, allocation and unlock boundaries are explicit doubles.
|
|
+smoke_path=Path(os.environ.get('ERR_SMOKE_SOURCE',REPO/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c'))
|
|
+smoke_tick=body(smoke_path,'protected void ERR_SmokeTick(')
|
|
+a=smoke_tick.index('if (m_ERRTestPatrolHQ)'); b=smoke_tick.index('{',a); i=b+1; depth=1
|
|
+while depth:
|
|
+ depth+=(smoke_tick[i]=='{')-(smoke_tick[i]=='}');i+=1
|
|
+patrol_branch=smoke_tick[a:i]
|
|
+patrol_branch=patrol_branch.replace('DamageManagerComponent.Cast(m_ERRSmokePlayer.FindComponent(DamageManagerComponent)).EnableDamageHandling(false);','ProtectOriginal(m_ERRSmokePlayer);').replace('ERR_Phase.RADIO_SEARCH','2')
|
|
+run(r'''
|
|
+#include <cassert>
|
|
+#include <string>
|
|
+struct Fixture;
|
|
+struct ERR_NativePatrolProbe {explicit ERR_NativePatrolProbe(Fixture* owner);};
|
|
+struct Fixture {
|
|
+ bool m_ERRTestPatrolHQ=true,allowed=true,wrongPhase=false,active=false;
|
|
+ int m_ERRSmokePlayer=7,phase=1,unlocks=0,failures=0,allocations=0,protections=0,m_ERRSmokeStep=0;
|
|
+ ERR_NativePatrolProbe* m_ERRHQPatrolMovement=nullptr;
|
|
+ ~Fixture(){delete m_ERRHQPatrolMovement;}
|
|
+ void ProtectOriginal(int actor){assert(actor==7);protections++;}
|
|
+ bool UnlockPrison(int actor){assert(actor==7);unlocks++;if(!allowed)return false;if(!wrongPhase){phase=2;active=true;}return true;}
|
|
+ int Phase(){return phase;}
|
|
+ bool ERR_Check(bool ok,std::string){if(!ok)failures++;return ok;}
|
|
+ void Start(){BRANCH}
|
|
+};
|
|
+ERR_NativePatrolProbe::ERR_NativePatrolProbe(Fixture* owner){assert(owner->phase==2&&owner->active&&owner->unlocks==1);owner->allocations++;}
|
|
+int main(){
|
|
+ Fixture healthy;healthy.Start();assert(healthy.m_ERRSmokeStep==130&&healthy.allocations==1&&healthy.failures==0&&healthy.protections==1);
|
|
+ Fixture refused;refused.allowed=false;refused.Start();assert(refused.unlocks==1&&refused.failures==1&&refused.allocations==0&&refused.m_ERRSmokeStep==0&&!refused.active);
|
|
+ Fixture wrong;wrong.wrongPhase=true;wrong.Start();assert(wrong.unlocks==1&&wrong.failures==1&&wrong.allocations==0&&wrong.m_ERRSmokeStep==0);
|
|
+ Fixture other;other.m_ERRTestPatrolHQ=false;other.Start();assert(other.unlocks==0&&other.allocations==0&&other.protections==0&&other.m_ERRSmokeStep==0);
|
|
+}
|
|
+'''.replace('BRANCH',patrol_branch))
|
|
+print('PASS: actual patrol fixture leaves prison before movement observation and refuses failed transition')
|