Files
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

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')