Merge owned systems into one addon while preserving resource identities. Gate player admission on the replicated prison scene, restore the original framed door, and hold enemy AI until escape. Correct scenario branding and author metadata, include publishing assets, and retain regression and native verification evidence.
85 lines
4.6 KiB
Python
85 lines
4.6 KiB
Python
"""Source policy and actual fixture completion checks; not an engine test."""
|
|
from pathlib import Path
|
|
import unittest
|
|
from policy_harness import body, run
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SOURCE = ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_NativeMortarTransferProbe.c'
|
|
|
|
class NativeMortarTransferChecks(unittest.TestCase):
|
|
def test_original_identity_conservation_policy(self):
|
|
method = body(SOURCE, 'static bool Conservation(')
|
|
run(method + '''
|
|
#include <cassert>
|
|
int main() {
|
|
for(int original=0;original<30;original++) for(int actual=0;actual<30;actual++)
|
|
for(int all=0;all<2;all++) for(int unique=0;unique<2;unique++)
|
|
assert(Conservation(original,actual,all,unique)==(original==27 && actual==27 && all && unique));
|
|
}
|
|
''')
|
|
def test_actual_move_completion_requires_callback_slot_and_deadline(self):
|
|
method=body(SOURCE, 'protected int MoveResult(').replace('protected int','int').replace('InventoryItemComponent item;', 'InventoryItemComponent* item;').replace('InventoryItemComponent item =', 'InventoryItemComponent* item =').replace('InventoryItemComponent.Cast','InventoryItemComponent::Cast').replace('FindComponent(InventoryItemComponent)','FindComponent(0)').replace('null','nullptr')
|
|
for name in ('m_MoveCallback','m_MoveShell','m_MoveDestination','item'):
|
|
method=method.replace(name+'.',name+'->')
|
|
method=method.replace('GetParentSlot().', 'GetParentSlot()->')
|
|
run('''
|
|
#include <cassert>
|
|
struct Entity;
|
|
struct Storage { bool has=false; bool Contains(Entity*) { return has; } };
|
|
struct Slot { Storage* storage=nullptr; Storage* GetStorage() { return storage; } };
|
|
struct InventoryItemComponent {
|
|
Slot* slot=nullptr;
|
|
static InventoryItemComponent* Cast(InventoryItemComponent* x) { return x; }
|
|
Slot* GetParentSlot() { return slot; }
|
|
};
|
|
struct Entity { InventoryItemComponent* item=nullptr; InventoryItemComponent* FindComponent(int) { return item; } };
|
|
struct Callback { int Result=0; };
|
|
struct Probe {
|
|
Callback* m_MoveCallback=nullptr; Entity* m_MoveShell=nullptr;
|
|
Storage* m_MoveDestination=nullptr; float m_MoveDeadline=100;
|
|
''' + method + '''
|
|
};
|
|
int main() {
|
|
Probe p; Callback cb; Entity shell; Storage target,wrong; Slot slot; InventoryItemComponent item;
|
|
p.m_MoveCallback=&cb; p.m_MoveShell=&shell; p.m_MoveDestination=⌖
|
|
assert(p.MoveResult(99)==0); // acceptance alone is not completion
|
|
cb.Result=1; assert(p.MoveResult(99)==0); // callback alone is insufficient
|
|
target.has=true; assert(p.MoveResult(99)==0); // exact item metadata required
|
|
shell.item=&item; item.slot=&slot; slot.storage=&wrong;
|
|
assert(p.MoveResult(99)==0); // apparent membership in wrong storage is insufficient
|
|
slot.storage=⌖ assert(p.MoveResult(100)==-1); // bounded deadline
|
|
assert(p.m_MoveCallback==&cb); // failure retains pending operation and borrowed shell
|
|
cb.Result=-1; assert(p.MoveResult(99)==-1);
|
|
cb.Result=1; assert(p.MoveResult(99)==1);
|
|
assert(!p.m_MoveCallback && !p.m_MoveShell && !p.m_MoveDestination);
|
|
assert(p.MoveResult(99)==1); // completion cannot replay an inventory operation
|
|
}
|
|
''')
|
|
def test_no_shell_creation_or_mutation_and_safe_cleanup(self):
|
|
source=SOURCE.read_text()
|
|
self.assertEqual(source.count('ERR_Actors.Spawn('),1)
|
|
self.assertIn('ERR_Actors.Spawn(STORE,',source)
|
|
for forbidden in ('TrySpawnPrefab', 'SetHealth(', 'ForceUnconsciousness', 'DeleteRplEntity', 'TotalShots++', 'LoadMagazine', 'GetShootingLogic'):
|
|
self.assertNotIn(forbidden,source)
|
|
self.assertNotRegex(source,r'TotalShots\s*=(?!=)')
|
|
stop=body(SOURCE,'void Stop()')
|
|
self.assertIn('if (!m_MoveCallback)',stop)
|
|
self.assertIn('storage && items.IsEmpty()',stop)
|
|
self.assertIn('m_System.Stop()',stop)
|
|
self.assertEqual(source.count('ERR_Actors.DeleteSpawned('),1)
|
|
def test_scoped_hook_cancel_and_exact_request_capture(self):
|
|
source=SOURCE.read_text()
|
|
self.assertTrue(source.startswith('#ifdef WORKBENCH'))
|
|
self.assertIn('outcome == "mortar-transfer"',source)
|
|
self.assertIn('if (m_ERRTransferFixture) return;',source)
|
|
self.assertIn('super.Tick(now);',source)
|
|
self.assertIn('m_CallbackAtCancel = m_ObservedTransfer.ERR_CallbackState()',source)
|
|
self.assertIn('m_ObservedTransfer.CapturedOrder() == m_Battery.OrderId',source)
|
|
self.assertIn('m_Battery.OrderId != m_CancelOrder',source)
|
|
self.assertIn('m_Battery.ERR_TransferAttempts() != m_AttemptsAtStart + 2',source)
|
|
self.assertIn('late callback timing not exercised',source)
|
|
self.assertIn('Has(entry.OriginalOwner, entry.Shell)',source)
|
|
self.assertEqual(body(SOURCE,'protected bool BeginMove(').count('TryMoveItemToStorage('),1)
|
|
self.assertIn('return BeginMove(shell, storage, now)',body(SOURCE,'protected bool Stash('))
|
|
|
|
if __name__=='__main__': unittest.main()
|