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:
@@ -0,0 +1,71 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSupplyTransfer.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_MortarSupplyTransfer.c
|
||||
@@ -81,6 +81,13 @@
|
||||
ERR_MortarSupplyState Poll(float now)
|
||||
{
|
||||
if (!Replication.IsServer()) return ERR_MortarSupplyState.FAILED;
|
||||
+ // The exact deleted shell cannot complete later. Match courier settlement:
|
||||
+ // release only uncertainty, never authorize a shot or retry this lost item.
|
||||
+ if (!m_Shell)
|
||||
+ {
|
||||
+ m_Resolved = true; m_Invalidated = true; m_Ready = false;
|
||||
+ return ERR_MortarSupplyState.FAILED;
|
||||
+ }
|
||||
bool valid = Valid(now);
|
||||
bool sourceContains = Contains(m_Source);
|
||||
bool destinationContains = Contains(m_Destination);
|
||||
--- a/tests/test_mortar_transactions.py
|
||||
+++ b/tests/test_mortar_transactions.py
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Actual Enforce policies and transaction observation body under narrow API fakes."""
|
||||
from policy_harness import ROOT, body, run
|
||||
+from pathlib import Path
|
||||
+import os
|
||||
r=ROOT/'addons/core/Scripts/Game/ERR/10_AI'
|
||||
-readiness=r/'ERR_MortarReadiness.c'; transfer=r/'ERR_MortarSupplyTransfer.c'; battery=r/'ERR_MortarBattery.c'
|
||||
+readiness=r/'ERR_MortarReadiness.c'; transfer=Path(os.environ.get('ERR_MORTAR_SUPPLY_TRANSFER_SOURCE',r/'ERR_MortarSupplyTransfer.c')); battery=r/'ERR_MortarBattery.c'
|
||||
policy='\n'.join([body(readiness,'static ERR_MortarSupplyState Population('),body(readiness,'static bool AllocationValid('),body(readiness,'static int CycleGate('),body(transfer,'static bool Authority('),body(transfer,'static bool Proven(')])
|
||||
policy=policy.replace('ERR_MortarSupplyState.','ERR_MortarSupplyState::')
|
||||
run('''#include <cassert>
|
||||
@@ -44,6 +46,7 @@
|
||||
poll=poll.replace('ERR_MortarSupplyState.','ERR_MortarSupplyState::').replace('Replication.IsServer()','Replication::IsServer()').replace('InventoryItemComponent item;','InventoryItemComponent* item=nullptr;').replace('if (m_Shell) item = InventoryItemComponent.Cast(m_Shell.FindComponent(InventoryItemComponent));','if (m_Shell) item = m_Shell;').replace('item.GetParentSlot().GetStorage()','item->GetParentSlot()->GetStorage()').replace('item.GetParentSlot()','item->GetParentSlot()')
|
||||
ack=body(transfer,'void Acknowledge(')
|
||||
run('''#include <cassert>
|
||||
+#include <initializer_list>
|
||||
enum class ERR_MortarSupplyState {FAILED=-1,PENDING,READY};
|
||||
struct Replication { static bool IsServer(){return true;} };
|
||||
struct Slot { void* storage; void* GetStorage(){return storage;} };
|
||||
@@ -57,7 +60,10 @@
|
||||
Slot slot{this}; InventoryItemComponent item{&slot}; InventoryItemComponent* m_Shell=&item;
|
||||
bool Valid(float){return valid&&!m_Invalidated;}
|
||||
bool Contains(int which){return m_Shell && (which==1 ? source : destination);}
|
||||
-'''+ack+poll+'''
|
||||
+'''+ack+body(transfer,'bool Unresolved(')+poll+'''
|
||||
+};
|
||||
+struct Battery {Transfer* m_Transfer=nullptr;
|
||||
+'''+body(battery,'bool SupplyPending(').replace('m_Transfer.Unresolved()', 'm_Transfer->Unresolved()')+'''
|
||||
};
|
||||
int main(){
|
||||
using S=ERR_MortarSupplyState;
|
||||
@@ -76,8 +82,19 @@
|
||||
assert(late.Poll(8000)==S::FAILED); // no deadline-boundary success bypass
|
||||
Transfer failed;failed.Acknowledge(false);failed.Acknowledge(true);
|
||||
assert(failed.Poll(1)==S::FAILED && failed.m_Acknowledgement==-1 && failed.m_Resolved);
|
||||
- Transfer gone;gone.m_Shell=nullptr;gone.Acknowledge(true);
|
||||
- assert(gone.Poll(1)==S::PENDING && !gone.m_Resolved); // ambiguous until deadline, never another move
|
||||
+ // Exact deletion is permanent loss, not an operation that can still arrive.
|
||||
+ for(int ack=0;ack<3;ack++)for(bool invalidated:{false,true}){
|
||||
+ Transfer gone;Battery battery;battery.m_Transfer=&gone;gone.m_Invalidated=invalidated;assert(gone.Unresolved()&&battery.SupplyPending());gone.m_Shell=nullptr;
|
||||
+ if(ack==1)gone.Acknowledge(true);
|
||||
+ if(ack==2)gone.Acknowledge(false);
|
||||
+ assert(gone.Poll(1)==S::FAILED&&gone.m_Resolved&&gone.m_Invalidated&&!gone.m_Ready&&!gone.Unresolved());
|
||||
+ assert(!battery.SupplyPending());
|
||||
+ gone.Acknowledge(true);assert(gone.Poll(90000)==S::FAILED&&!gone.Unresolved()&&!gone.m_Ready);
|
||||
+ }
|
||||
+ // A surviving detached shell, missing inventory or lost authority remains
|
||||
+ // uncertain; only exact identity deletion permits unconditional settlement.
|
||||
+ Transfer detached;detached.source=false;detached.destination=false;detached.Acknowledge(true);
|
||||
+ assert(detached.Poll(1)==S::PENDING&&detached.Unresolved());assert(detached.Poll(8000)==S::FAILED&&detached.Unresolved());
|
||||
Transfer unauthorized;unauthorized.valid=false;
|
||||
assert(unauthorized.Poll(0)==S::FAILED && !unauthorized.m_Resolved);
|
||||
}
|
||||
Reference in New Issue
Block a user