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,118 @@
|
||||
Prepared mounted rearm second courier leg — NOT integrated gameplay
|
||||
|
||||
Patch scope
|
||||
- NEW ERR_MountedAmmoTransfer.c (transaction plus its callback).
|
||||
- ERR_FiniteMagazineReservation.c: committed flag, exact read-only CommittedFor,
|
||||
one-shot ClaimMountedSwap; all current Reserve/Commit/Release rules preserved.
|
||||
- NEW tests/test_mounted_ammo_transfer.py: actual constructor/method/callback
|
||||
bodies executed with controlled native doubles, not engine coverage.
|
||||
Do not apply only the shared-helper hunk to production: it is consumed by the
|
||||
prepared transaction, which itself needs the courier coordinator below.
|
||||
|
||||
Constructor contract
|
||||
ERR_MountedAmmoTransfer(mode, originalTask, targetVehicleIndex,
|
||||
originalTargetRoster, originalWorkerSlot, originalWeapon, originalMuzzle,
|
||||
originalLoadedMagazineEntity, alreadyCarriedIncomingEntity, committedPickup)
|
||||
|
||||
The coordinator must retain original weapon/muzzle/loaded identities before
|
||||
courier dispatch, from the exact production mounted collector/ownership checks.
|
||||
It must retain the original recipient crew sampler, choose a surviving original
|
||||
member other than the seated original driver, and keep the original vehicle
|
||||
root bound. Construction pins the exact task/receipt/vehicle objects, roots,
|
||||
groups, force records, worker, magazine components, storage managers and slots.
|
||||
It does not discover or bind replacements. Index1 is the original ammo truck;
|
||||
recipient is another original root in the same six-vehicle task.
|
||||
|
||||
Required caller integration (not in this patch)
|
||||
1. Require a fresh delivered mounted-low-ammo report, then validate original
|
||||
task/source binding and acquire exclusive recipient/muzzle/worker orders.
|
||||
2. Select a compatible exact identity from the existing infantry coordinator's
|
||||
original m_Stock/m_Spent arrays. Reserve via ERR_FiniteMagazineReservation;
|
||||
keep the same handle alive across both courier legs.
|
||||
3. Physically move original worker to truck cargo access and perform finite
|
||||
pickup. Existing ERR_InfantryAmmoTransfer cannot be reused unchanged: its
|
||||
Compatible(worker,box) demands the worker's carried small arm uses that box.
|
||||
An AK-equipped crew member carrying a PKM box needs a specific courier pickup
|
||||
contract, preserving donor storage ownership, physical cargo access, exact
|
||||
callback + destination proof and the existing no-duplicate quarantine.
|
||||
4. Commit that handle when pickup is submitted, as for existing infantry.
|
||||
Start the second leg only after pickup reports SUCCEEDED, with its callback
|
||||
and exact ownership both proven. A committed handle alone is not proof of a
|
||||
successful first leg. Keep uncertain pickup claims quarantined.
|
||||
5. Send the same original worker on foot to the exact original mounted slot;
|
||||
keep both original vehicles stationary and original drivers/crew valid.
|
||||
Normal ~35m vehicle spacing does not require moving vehicles together.
|
||||
Constructor/Tick never move anyone, request cargo or bypass mounted-crew hold.
|
||||
The coordinator must authorize ordinary dismount/approach/reboarding and
|
||||
protect these orders from the existing convoy tactics/HQ scheduler.
|
||||
6. Construct this leaf at the rendezvous; Tick accepts milliseconds and has an
|
||||
8000ms monotonic deadline. It is not a navigation timer. The original loaded
|
||||
box must still be <=25% full and incoming must carry more rounds.
|
||||
7. The caller must hold a strong ref ERR_MountedAmmoTransfer while a native
|
||||
callback or quarantine is live; the callback Transfer backlink is weak.
|
||||
Keep both exact items/slots and the recipient claim reserved while Unresolved
|
||||
is true, including after Stop, failure, deadline or mission end. Polling proof
|
||||
after late callback can settle quarantine, but never restarts or succeeds a
|
||||
stopped/failed transaction. A false native return without callback stays
|
||||
conservatively unresolved. Never refund the incoming finite identity.
|
||||
8. Success leaves the original outgoing box carried by the worker. It is not
|
||||
automatically new usable stock, nor is it returned remotely to the truck.
|
||||
A later physical return/reboarding/cleanup stage is still needed.
|
||||
|
||||
Leaf behavior
|
||||
- Context rechecks current server/active mode, exact consumed receipt/record
|
||||
identity, six original task slots, original root/crew bindings, worker roster,
|
||||
on-foot conscious enemy ownership, alive stationary truck and recipient.
|
||||
- Source is the original worker's managed deposit storage, <=64 storages and
|
||||
<=128 inventory identities. Incoming and outgoing must both be absent from
|
||||
the original truck inventory. No same-item swap, remote truck swap or reload
|
||||
fallback. Original gun/mount/muzzle relation and exact parent slots retained.
|
||||
- Reach is <=4m from worker aiming position to the exact authored mounted
|
||||
InventoryStorageSlot.GetWorldTransform position, with finite coordinates and
|
||||
WORLD|ENTS camera-layer trace. Only worker and actual gun hierarchies are
|
||||
excluded; original vehicle hull and unrelated objects remain occluders.
|
||||
- Only native mutation is one TrySwapItemStorages(incoming,outgoing,callback)
|
||||
through the original worker manager, preceded by CanSwapItemStorages. The
|
||||
committed finite reservation grants at most one mounted native submission
|
||||
across competing transaction objects, consumed before calling native code.
|
||||
- No content mutation, chamber manipulation, spawn, delete, replacement,
|
||||
teleport, retry or reservation refund. Native swap handles existing contents.
|
||||
- Callback alone is insufficient. Success requires BOTH exact parent/attached
|
||||
slots exchanged, actual muzzle magazine switched, and worker inventory
|
||||
contains outgoing but not incoming. Callback failure remains sticky; partial
|
||||
movement stays quarantined. Inline success + native false is accepted only
|
||||
with ordinary proof; no late callback changes terminal gameplay state.
|
||||
|
||||
Established native APIs and remaining evidence
|
||||
- generated/InventorySystem/InventoryStorageManagerComponent.c lines35-37:
|
||||
CanSwapItemStorages(itemA,itemB), TrySwapItemStorages(itemA,itemB,cb).
|
||||
- generated/InventorySystem/InventoryTask/ScriptedInventoryOperationCallback.c:
|
||||
OnComplete/OnFailed for an operation; OnAllComplete/OnAllFailed described for
|
||||
multiple spawns. Both success notifications may be accepted here because
|
||||
exact two-item slot proof is mandatory; no assumption of per-item ordering.
|
||||
- generated/InventorySystem/InventoryStorageSlot.c -> EntitySlotInfo ->
|
||||
generated/PointInfo.c: GetWorldTransform(out vector[4]). All above installed
|
||||
references under /tmp/erri-vanilla-stock/scripts/Game.
|
||||
- /tmp/erri-horn-read/MG_PKM_base.et authors magazine pivot/context around
|
||||
lines289-294. Stock support-station action scripts use their support/resupply
|
||||
framework; this leaf never invokes or simulates those resource-based actions.
|
||||
- Prior native dry query proved original PKM slot/storage and compatible initial
|
||||
truck box can be swapped, without mutation. It did NOT prove worker-carried
|
||||
CanSwap, authored slot reach, collision result, actual native swap, callback
|
||||
sequence, worker carrying capacity, outgoing return or multiplayer behavior.
|
||||
Those require an explicit bounded native courier fixture after integration.
|
||||
|
||||
Focused validation (all PASS with proposed shared helper)
|
||||
PYTHONPATH=/home/jakub/devel/escapistsrereintroduced/tests \
|
||||
ERR_MOUNTED_TRANSFER_SOURCE=/tmp/erri-mounted-transfer/addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c \
|
||||
ERR_FINITE_RESERVATION_SOURCE=/tmp/erri-mounted-transfer/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c \
|
||||
python3 /tmp/erri-mounted-transfer/tests/test_mounted_ammo_transfer.py
|
||||
ERR_FINITE_RESERVATION_SOURCE=/tmp/erri-mounted-transfer/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c \
|
||||
python3 /home/jakub/devel/escapistsrereintroduced/tests/test_finite_magazine_reservation.py
|
||||
ERR_FINITE_RESERVATION_SOURCE=/tmp/erri-mounted-transfer/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c \
|
||||
python3 /home/jakub/devel/escapistsrereintroduced/tests/test_infantry_ammo_transfer.py
|
||||
|
||||
No target source writes, native sessions, staging or full-suite run by this task.
|
||||
|
||||
Independent read-only review: hq_memory_review found no concrete blocker and
|
||||
independently executed the actual transfer regression successfully.
|
||||
+456
@@ -0,0 +1,456 @@
|
||||
diff --git a/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c b/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c
|
||||
--- a/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c
|
||||
@@ -7,6 +7,8 @@
|
||||
protected IEntity m_Item;
|
||||
protected bool m_Owned;
|
||||
protected bool m_Closed;
|
||||
+ protected bool m_Committed;
|
||||
+ protected bool m_MountedClaimed;
|
||||
void ERR_FiniteMagazineReservation(array<IEntity> original, array<IEntity> spent, IEntity item)
|
||||
{
|
||||
m_Original = original; m_Spent = spent; m_Item = item;
|
||||
@@ -25,7 +27,20 @@
|
||||
bool Commit()
|
||||
{
|
||||
if (!m_Owned || m_Closed) return false;
|
||||
- m_Closed = true;
|
||||
+ m_Closed = true; m_Committed = true;
|
||||
+ return true;
|
||||
+ }
|
||||
+ // A courier continuation consumes the same committed pickup claim, not a new
|
||||
+ // stock reservation. A released/stale handle can never authorize this leg.
|
||||
+ bool CommittedFor(IEntity exact)
|
||||
+ {
|
||||
+ return exact && exact == m_Item && m_Owned && m_Committed && m_Original && m_Spent
|
||||
+ && m_Original.Count() <= 96 && m_Spent.Count() <= 96 && m_Original.Contains(exact) && m_Spent.Contains(exact);
|
||||
+ }
|
||||
+ bool ClaimMountedSwap(IEntity exact)
|
||||
+ {
|
||||
+ if (m_MountedClaimed || !CommittedFor(exact)) return false;
|
||||
+ m_MountedClaimed = true;
|
||||
return true;
|
||||
}
|
||||
// Caller may release only when no native operation was submitted. Closing
|
||||
diff --git a/addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c b/addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c
|
||||
@@ -0,0 +1,238 @@
|
||||
+enum ERR_MountedAmmoTransferState { FAILED = -1, PENDING, SUCCEEDED }
|
||||
+
|
||||
+class ERR_MountedAmmoCallback : ScriptedInventoryOperationCallback
|
||||
+{
|
||||
+ ERR_MountedAmmoTransfer Transfer;
|
||||
+ protected override void OnComplete() { if (Transfer) Transfer.Acknowledge(true); }
|
||||
+ protected override void OnAllComplete() { if (Transfer) Transfer.Acknowledge(true); }
|
||||
+ protected override void OnFailed() { if (Transfer) Transfer.Acknowledge(false); }
|
||||
+ protected override void OnAllFailed() { if (Transfer) Transfer.Acknowledge(false); }
|
||||
+}
|
||||
+
|
||||
+// Second courier leg only. The caller retains the original gun/muzzle/loaded
|
||||
+// identities before dispatch, the original worker roster, and the committed
|
||||
+// finite pickup reservation. Fresh delivered demand and exclusive HQ orders
|
||||
+// remain caller responsibilities. This class never picks up from a remote truck.
|
||||
+class ERR_MountedAmmoTransfer
|
||||
+{
|
||||
+ protected ERR_GameMode m_Mode;
|
||||
+ protected ERR_ConvoyTask m_Task;
|
||||
+ protected ERR_ConvoyReceipt m_Receipt;
|
||||
+ protected ERR_ConvoyVehicle m_Donor;
|
||||
+ protected ERR_ConvoyVehicle m_Target;
|
||||
+ protected Vehicle m_Truck;
|
||||
+ protected Vehicle m_Root;
|
||||
+ protected SCR_AIGroup m_DonorGroup;
|
||||
+ protected SCR_AIGroup m_TargetGroup;
|
||||
+ protected ERR_ForceRecord m_DonorRecord;
|
||||
+ protected ERR_ForceRecord m_TargetRecord;
|
||||
+ protected ERR_HQStatusSampler m_Roster;
|
||||
+ protected int m_Index;
|
||||
+ protected int m_WorkerSlot;
|
||||
+ protected IEntity m_Worker;
|
||||
+ protected BaseWeaponComponent m_Weapon;
|
||||
+ protected WeaponSlotComponent m_Mount;
|
||||
+ protected InventoryStorageSlot m_WeaponSlot;
|
||||
+ protected BaseMuzzleComponent m_Muzzle;
|
||||
+ protected IEntity m_Loaded;
|
||||
+ protected IEntity m_Incoming;
|
||||
+ protected BaseMagazineComponent m_OldMagazine;
|
||||
+ protected BaseMagazineComponent m_NewMagazine;
|
||||
+ protected InventoryStorageSlot m_FromSlot;
|
||||
+ protected InventoryStorageSlot m_ToSlot;
|
||||
+ protected BaseInventoryStorageComponent m_FromStorage;
|
||||
+ protected BaseInventoryStorageComponent m_ToStorage;
|
||||
+ protected InventoryStorageManagerComponent m_Carried;
|
||||
+ protected InventoryStorageManagerComponent m_TruckInventory;
|
||||
+ protected ref ERR_FiniteMagazineReservation m_Reservation;
|
||||
+ protected ref ERR_MountedAmmoCallback m_Callback;
|
||||
+ protected bool m_Submitted;
|
||||
+ protected int m_Acknowledgement;
|
||||
+ protected float m_Started = -1;
|
||||
+ protected float m_LastTick = -1;
|
||||
+ protected ERR_MountedAmmoTransferState m_State = ERR_MountedAmmoTransferState.PENDING;
|
||||
+ protected string m_Reason;
|
||||
+ void ERR_MountedAmmoTransfer(ERR_GameMode mode, ERR_ConvoyTask task, int vehicleIndex, ERR_HQStatusSampler originalRoster, int workerSlot, BaseWeaponComponent originalWeapon, BaseMuzzleComponent originalMuzzle, IEntity originalLoaded, IEntity carriedIncoming, ERR_FiniteMagazineReservation committedPickup)
|
||||
+ {
|
||||
+ m_Mode = mode; m_Task = task; m_Index = vehicleIndex; m_Roster = originalRoster; m_WorkerSlot = workerSlot;
|
||||
+ m_Weapon = originalWeapon; m_Muzzle = originalMuzzle; m_Loaded = originalLoaded; m_Incoming = carriedIncoming; m_Reservation = committedPickup;
|
||||
+ if (!mode || !mode.Forces() || !task || task.Vehicles.Count() != 6 || vehicleIndex < 0 || vehicleIndex >= 6 || vehicleIndex == 1 || !originalRoster) return;
|
||||
+ m_Receipt = task.Receipt; m_Donor = task.Vehicles[1]; m_Target = task.Vehicles[vehicleIndex];
|
||||
+ if (!m_Donor || !m_Target) return;
|
||||
+ m_Truck = m_Donor.Entity; m_Root = m_Target.Entity; m_DonorGroup = m_Donor.Group; m_TargetGroup = m_Target.Group;
|
||||
+ if (!m_Truck || !m_Root || !m_DonorGroup || !m_TargetGroup) return;
|
||||
+ m_DonorRecord = mode.Forces().FindGroup(m_DonorGroup); m_TargetRecord = mode.Forces().FindGroup(m_TargetGroup);
|
||||
+ m_Worker = originalRoster.InitialMember(workerSlot);
|
||||
+ if (!m_Worker || !m_Weapon || !m_Weapon.GetOwner() || !m_Loaded || !m_Incoming || m_Loaded == m_Incoming) return;
|
||||
+ InventoryItemComponent gunItem = InventoryItemComponent.Cast(m_Weapon.GetOwner().FindComponent(InventoryItemComponent));
|
||||
+ InventoryItemComponent loadedItem = InventoryItemComponent.Cast(m_Loaded.FindComponent(InventoryItemComponent));
|
||||
+ InventoryItemComponent incomingItem = InventoryItemComponent.Cast(m_Incoming.FindComponent(InventoryItemComponent));
|
||||
+ if (!gunItem || !loadedItem || !incomingItem) return;
|
||||
+ m_WeaponSlot = gunItem.GetParentSlot(); m_ToSlot = loadedItem.GetParentSlot(); m_FromSlot = incomingItem.GetParentSlot();
|
||||
+ if (!m_WeaponSlot || !m_ToSlot || !m_FromSlot) return;
|
||||
+ m_Mount = WeaponSlotComponent.Cast(m_WeaponSlot.GetParentContainer());
|
||||
+ m_FromStorage = m_FromSlot.GetStorage(); m_ToStorage = m_ToSlot.GetStorage();
|
||||
+ m_OldMagazine = BaseMagazineComponent.Cast(m_Loaded.FindComponent(BaseMagazineComponent));
|
||||
+ m_NewMagazine = BaseMagazineComponent.Cast(m_Incoming.FindComponent(BaseMagazineComponent));
|
||||
+ m_Carried = InventoryStorageManagerComponent.Cast(m_Worker.FindComponent(InventoryStorageManagerComponent));
|
||||
+ m_TruckInventory = InventoryStorageManagerComponent.Cast(m_Truck.FindComponent(InventoryStorageManagerComponent));
|
||||
+ }
|
||||
+ bool Submitted() { return m_Submitted; }
|
||||
+ string Reason() { return m_Reason; }
|
||||
+ // A failure remains sticky; success notification alone proves neither item.
|
||||
+ void Acknowledge(bool success)
|
||||
+ {
|
||||
+ if (!m_Submitted) return;
|
||||
+ if (!success) m_Acknowledgement = -1;
|
||||
+ else if (m_Acknowledgement == 0) m_Acknowledgement = 1;
|
||||
+ }
|
||||
+ protected ERR_MountedAmmoTransferState Fail(string reason)
|
||||
+ {
|
||||
+ if (m_State == ERR_MountedAmmoTransferState.PENDING) { m_State = ERR_MountedAmmoTransferState.FAILED; m_Reason = reason; }
|
||||
+ return m_State;
|
||||
+ }
|
||||
+ void Stop() { Fail("courier authority stopped; submitted swaps cannot be cancelled or refunded"); }
|
||||
+ protected static bool Stationary(Vehicle vehicle)
|
||||
+ {
|
||||
+ if (!vehicle || !ERR_Actors.Alive(vehicle) || !vehicle.GetPhysics()) return false;
|
||||
+ float speed = vehicle.GetPhysics().GetVelocity().Length();
|
||||
+ float angular = vehicle.GetPhysics().GetAngularVelocity().Length();
|
||||
+ return speed >= 0 && speed <= 0.25 && angular >= 0 && angular <= 0.1;
|
||||
+ }
|
||||
+ protected bool Context()
|
||||
+ {
|
||||
+ if (!Replication.IsServer() || SCR_Global.IsEditMode() || !m_Mode || m_Mode != ERR_GameMode.Get() || !m_Mode.Active() || !m_Mode.Forces()) return false;
|
||||
+ if (!m_Task || !m_Task.Ready || m_Task.Stopped || !m_Receipt || m_Task.Receipt != m_Receipt || !m_Receipt.Consumed
|
||||
+ || m_Task.Vehicles.Count() != 6 || m_Receipt.Records.Count() < 6 || m_Index < 0 || m_Index >= 6 || m_Index == 1) return false;
|
||||
+ if (!m_Donor || !m_Target || m_Task.Vehicles[1] != m_Donor || m_Task.Vehicles[m_Index] != m_Target
|
||||
+ || m_Donor.Index != 1 || m_Target.Index != m_Index || m_Donor.Entity != m_Truck || m_Target.Entity != m_Root
|
||||
+ || m_Donor.Group != m_DonorGroup || m_Target.Group != m_TargetGroup || m_Donor.Released || m_Target.Released
|
||||
+ || !m_Donor.Registered || !m_Target.Registered || !m_Donor.CrewValid(m_Mode) || !m_Target.CrewValid(m_Mode)) return false;
|
||||
+ if (!m_DonorRecord || !m_TargetRecord || m_Mode.Forces().FindGroup(m_DonorGroup) != m_DonorRecord
|
||||
+ || m_Mode.Forces().FindGroup(m_TargetGroup) != m_TargetRecord || m_DonorRecord.Id != m_Receipt.Records[1]
|
||||
+ || m_TargetRecord.Id != m_Receipt.Records[m_Index]) return false;
|
||||
+ ERR_HQ hq = ERR_HQ.Cast(m_Mode.Command());
|
||||
+ if (!hq || !hq.ValidateBoundVehicle(m_DonorGroup, m_Truck) || !hq.ValidateBoundVehicle(m_TargetGroup, m_Root)) return false;
|
||||
+ if (!m_Roster || !m_Roster.OwnsRoster(m_TargetGroup) || !m_Roster.ValidateBoundVehicle(m_Root)
|
||||
+ || !m_Roster.CanAttribute(m_WorkerSlot, m_Worker, false) || !m_Target.Members.Contains(m_Worker)
|
||||
+ || !ERR_EnemyEquipmentRules.Eligible(m_Mode, m_TargetGroup, m_Worker) || !ERR_Actors.CanFight(m_Worker)
|
||||
+ || CompartmentAccessComponent.GetVehicleIn(m_Worker)) return false;
|
||||
+ if (!m_Reservation || !m_Reservation.CommittedFor(m_Incoming) || !Stationary(m_Truck) || !Stationary(m_Root)) return false;
|
||||
+ if (InventoryStorageManagerComponent.Cast(m_Worker.FindComponent(InventoryStorageManagerComponent)) != m_Carried
|
||||
+ || InventoryStorageManagerComponent.Cast(m_Truck.FindComponent(InventoryStorageManagerComponent)) != m_TruckInventory) return false;
|
||||
+ return TargetShape();
|
||||
+ }
|
||||
+ protected bool TargetShape()
|
||||
+ {
|
||||
+ if (!m_Root || !m_Weapon || !m_Weapon.GetOwner() || !m_Mount || !m_WeaponSlot || !m_Muzzle || !m_ToSlot || !m_ToStorage) return false;
|
||||
+ IEntity gun = m_Weapon.GetOwner();
|
||||
+ InventoryItemComponent item = InventoryItemComponent.Cast(gun.FindComponent(InventoryItemComponent));
|
||||
+ if (!item || item.GetParentSlot() != m_WeaponSlot || m_Mount.GetSlotInfo() != m_WeaponSlot || m_Mount.GetWeaponEntity() != gun
|
||||
+ || m_WeaponSlot.GetAttachedEntity() != gun || m_WeaponSlot.GetParentContainer() != m_Mount
|
||||
+ || !ERR_ConvoyRules.PartOf(m_Mount.GetOwner(), m_Root) || !ERR_ConvoyRules.PartOf(m_Muzzle.GetOwner(), m_Root)
|
||||
+ || m_ToSlot.GetParentContainer() != m_Muzzle || m_ToSlot.GetStorage() != m_ToStorage || m_ToStorage.GetOwner() != gun
|
||||
+ || m_Muzzle.GetMuzzleType() != EMuzzleType.MT_BaseMuzzle) return false;
|
||||
+ array<BaseMuzzleComponent> muzzles = {}; m_Weapon.GetMuzzlesList(muzzles);
|
||||
+ return muzzles.Count() <= 8 && muzzles.Contains(m_Muzzle);
|
||||
+ }
|
||||
+ protected bool MagazineValid(BaseMagazineComponent magazine)
|
||||
+ {
|
||||
+ if (!magazine || !m_Muzzle || !magazine.GetMagazineWell() || !m_Muzzle.GetMagazineWell()
|
||||
+ || !magazine.GetMagazineWell().IsInherited(m_Muzzle.GetMagazineWell().Type())) return false;
|
||||
+ int capacity = magazine.GetMaxAmmoCount(); int rounds = magazine.GetAmmoCount();
|
||||
+ return capacity > 0 && capacity <= 100000 && rounds >= 0 && rounds <= capacity;
|
||||
+ }
|
||||
+ protected bool CarriedStorage()
|
||||
+ {
|
||||
+ if (!m_Carried || !m_Worker || m_Carried.GetOwner() != m_Worker || !m_FromStorage
|
||||
+ || !m_FromSlot || m_FromSlot.GetStorage() != m_FromStorage || !ERR_InfantryAmmoTransfer.StoredUnder(m_FromStorage.GetOwner(), m_Worker)) return false;
|
||||
+ array<BaseInventoryStorageComponent> storages = {}; m_Carried.GetStorages(storages, EStoragePurpose.PURPOSE_DEPOSIT);
|
||||
+ return storages.Count() <= 64 && storages.Contains(m_FromStorage);
|
||||
+ }
|
||||
+ protected int Owned(InventoryStorageManagerComponent inventory, IEntity item)
|
||||
+ {
|
||||
+ if (!inventory || !item) return -1;
|
||||
+ array<IEntity> items = {}; inventory.GetItems(items, EStoragePurpose.PURPOSE_DEPOSIT);
|
||||
+ if (items.Count() > 128) return -1;
|
||||
+ if (items.Contains(item)) return 1;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ protected bool InSlot(IEntity entity, InventoryStorageSlot slot)
|
||||
+ {
|
||||
+ if (!entity || !slot || slot.GetAttachedEntity() != entity) return false;
|
||||
+ InventoryItemComponent item = InventoryItemComponent.Cast(entity.FindComponent(InventoryItemComponent));
|
||||
+ return item && item.GetParentSlot() == slot;
|
||||
+ }
|
||||
+ // Exact two-way proof remains observable after Stop, loss or mission end.
|
||||
+ protected bool OriginalProof()
|
||||
+ {
|
||||
+ return TargetShape() && CarriedStorage() && m_Muzzle.GetMagazine() == m_OldMagazine
|
||||
+ && InSlot(m_Incoming, m_FromSlot) && InSlot(m_Loaded, m_ToSlot)
|
||||
+ && Owned(m_Carried, m_Incoming) == 1 && Owned(m_Carried, m_Loaded) == 0;
|
||||
+ }
|
||||
+ protected bool SwappedProof()
|
||||
+ {
|
||||
+ return TargetShape() && CarriedStorage() && m_Muzzle.GetMagazine() == m_NewMagazine
|
||||
+ && InSlot(m_Incoming, m_ToSlot) && InSlot(m_Loaded, m_FromSlot)
|
||||
+ && Owned(m_Carried, m_Incoming) == 0 && Owned(m_Carried, m_Loaded) == 1;
|
||||
+ }
|
||||
+ bool Unresolved()
|
||||
+ {
|
||||
+ if (!m_Submitted) return false;
|
||||
+ if (m_Acknowledgement == 1 && SwappedProof()) return false;
|
||||
+ if (m_Acknowledgement < 0 && OriginalProof()) return false;
|
||||
+ // Even a false submission result without callback cannot authorize another
|
||||
+ // swap of these slots. Keep both identities and the target claim quarantined.
|
||||
+ return true;
|
||||
+ }
|
||||
+ protected bool AccessFilter(notnull IEntity entity)
|
||||
+ {
|
||||
+ return !ERR_ConvoyRules.PartOf(entity, m_Worker) && !ERR_ConvoyRules.PartOf(entity, m_Weapon.GetOwner());
|
||||
+ }
|
||||
+ protected bool Reach()
|
||||
+ {
|
||||
+ ChimeraCharacter character = ChimeraCharacter.Cast(m_Worker);
|
||||
+ if (!character || !m_ToSlot || !m_Weapon || !GetGame() || !GetGame().GetWorld()) return false;
|
||||
+ vector matrix[4]; m_ToSlot.GetWorldTransform(matrix);
|
||||
+ vector start = character.AimingPosition(); vector point = matrix[3];
|
||||
+ if (!ERR_ForceRules.FiniteVector(start) || !ERR_ForceRules.FiniteVector(point)) return false;
|
||||
+ float distance = vector.Distance(start, point);
|
||||
+ if (!(distance >= 0.05 && distance <= 4)) return false;
|
||||
+ TraceParam trace = new TraceParam(); trace.Start = start; trace.End = point;
|
||||
+ trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS; trace.LayerMask = TRACE_LAYER_CAMERA;
|
||||
+ // The original vehicle hull remains an occluder. This is reach to the exact
|
||||
+ // authored magazine slot, not a support-station action or a vehicle-center test.
|
||||
+ return GetGame().GetWorld().TraceMove(trace, AccessFilter) == 1;
|
||||
+ }
|
||||
+ ERR_MountedAmmoTransferState Tick(float now)
|
||||
+ {
|
||||
+ if (m_State != ERR_MountedAmmoTransferState.PENDING) return m_State;
|
||||
+ if (!ERR_ForceRules.Finite(now) || now < 0) return Fail("invalid swap clock");
|
||||
+ if (m_Started < 0) m_Started = now;
|
||||
+ if (now < m_LastTick || now - m_Started >= 8000) return Fail("mounted swap deadline expired");
|
||||
+ m_LastTick = now;
|
||||
+ if (!Context() || !Reach()) return Fail("original convoy, worker, bound mount or unobstructed physical reach lost");
|
||||
+ if (!m_Submitted)
|
||||
+ {
|
||||
+ if (!OriginalProof() || !m_OldMagazine || !m_NewMagazine || m_OldMagazine.GetOwner() != m_Loaded || m_NewMagazine.GetOwner() != m_Incoming
|
||||
+ || !MagazineValid(m_OldMagazine) || !MagazineValid(m_NewMagazine) || m_NewMagazine.IsUsed()
|
||||
+ || m_NewMagazine.GetAmmoCount() <= m_OldMagazine.GetAmmoCount() || m_OldMagazine.GetAmmoCount() > m_OldMagazine.GetMaxAmmoCount() * 0.25
|
||||
+ || m_FromSlot == m_ToSlot || m_FromSlot.IsLocked() || m_ToSlot.IsLocked()
|
||||
+ || !m_TruckInventory || m_TruckInventory.GetOwner() != m_Truck || Owned(m_TruckInventory, m_Incoming) != 0 || Owned(m_TruckInventory, m_Loaded) != 0)
|
||||
+ return Fail("exact carried finite stock or original low mounted magazine unavailable");
|
||||
+ if (!m_Carried.CanSwapItemStorages(m_Incoming, m_Loaded)) return Fail("native slot swap preflight refused");
|
||||
+ if (!m_Reservation.ClaimMountedSwap(m_Incoming)) return Fail("committed pickup already claimed by another mounted swap");
|
||||
+ m_Callback = new ERR_MountedAmmoCallback(); m_Callback.Transfer = this;
|
||||
+ m_Submitted = true;
|
||||
+ bool accepted = m_Carried.TrySwapItemStorages(m_Incoming, m_Loaded, m_Callback);
|
||||
+ if (!accepted && m_Acknowledgement != 1) return Fail("native swap refused; exact committed identity will not be retried");
|
||||
+ }
|
||||
+ if (m_Acknowledgement < 0) return Fail("native swap failure; partial or unproved movement remains quarantined");
|
||||
+ if (m_Acknowledgement == 1 && SwappedProof())
|
||||
+ {
|
||||
+ m_State = ERR_MountedAmmoTransferState.SUCCEEDED;
|
||||
+ m_Reason = "callback plus exact mounted and carried slots confirm one two-way physical magazine exchange";
|
||||
+ }
|
||||
+ return m_State;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/tests/test_mounted_ammo_transfer.py b/tests/test_mounted_ammo_transfer.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/tests/test_mounted_ammo_transfer.py
|
||||
@@ -0,0 +1,174 @@
|
||||
+"""Execute the proposed exact carried-to-mounted swap; no engine coverage claim."""
|
||||
+import os,re
|
||||
+from pathlib import Path
|
||||
+from policy_harness import ROOT,run
|
||||
+from test_finite_magazine_reservation import translated_reservation
|
||||
+p=Path(os.environ.get('ERR_MOUNTED_TRANSFER_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c'))
|
||||
+s=p.read_text()
|
||||
+for forbidden in ('TrySpawn','SetAmmoCount','SetOrigin','SetTransform','DeleteEntity','TryMove','TryInsert','TryRemove','PerformAction'):
|
||||
+ assert forbidden not in s,forbidden
|
||||
+assert s.count('TrySwapItemStorages(')==1
|
||||
+code=s[s.index('class ERR_MountedAmmoTransfer\n'):]
|
||||
+code=re.sub(r'//[^\n]*','',code).replace('protected ','').replace('notnull ','').replace('ref ','').replace('class ','struct ')
|
||||
+code=code.replace('void ERR_MountedAmmoTransfer(','ERR_MountedAmmoTransfer(')
|
||||
+code=code.replace('array<','Array<').replace('null','nullptr')
|
||||
+# Only engine component lookup/casts are doubled; all transaction methods execute.
|
||||
+cast_types={'InventoryItemComponent':'item','BaseMagazineComponent':'magazine','InventoryStorageManagerComponent':'inventory'}
|
||||
+for kind,field in cast_types.items():
|
||||
+ code=re.sub(kind+r'\.Cast\(([^;\n]*?)\.FindComponent\('+kind+r'\)\)',lambda m:m[1]+'.'+field,code)
|
||||
+code=code.replace('WeaponSlotComponent.Cast(m_WeaponSlot.GetParentContainer())','dynamic_cast<Mount*>(m_WeaponSlot.GetParentContainer())')
|
||||
+code=code.replace('ERR_HQ.Cast(m_Mode.Command())','m_Mode.Command()').replace('ChimeraCharacter.Cast(m_Worker)','m_Worker')
|
||||
+for name in ('ERR_GameMode','ERR_MountedAmmoTransferState','ERR_ForceRules','ERR_Actors','ERR_ConvoyRules','ERR_EnemyEquipmentRules','ERR_InfantryAmmoTransfer','Replication','SCR_Global','CompartmentAccessComponent','EMuzzleType','EStoragePurpose','vector','TraceFlags'):
|
||||
+ code=code.replace(name+'.',name+'::')
|
||||
+for name in ('m_Mode','mode','task','originalRoster','m_Task','m_Receipt','m_Donor','m_Target','m_Truck','m_Root','m_DonorRecord','m_TargetRecord','m_Roster','m_Weapon','m_WeaponSlot','m_Muzzle','m_Loaded','m_Incoming','m_Mount','m_FromStorage','m_ToStorage','m_OldMagazine','m_NewMagazine','m_Carried','m_TruckInventory','m_Reservation','m_Callback','m_Worker','gunItem','loadedItem','incomingItem','gun','item','hq','vehicle','entity','slot','inventory','magazine','character','trace','m_FromSlot','m_ToSlot'):
|
||||
+ code=re.sub(r'\b'+name+r'\.',name+'->',code)
|
||||
+code=code.replace(').',' )->')
|
||||
+# Physics/vector return values, unlike components, are not pointers.
|
||||
+code=code.replace('GetVelocity( )->Length()', 'GetVelocity().Length()').replace('GetAngularVelocity( )->Length()', 'GetAngularVelocity().Length()')
|
||||
+code=code.replace('ERR_FiniteMagazineReservation m_Reservation','ERR_FiniteMagazineReservation* m_Reservation').replace('ERR_FiniteMagazineReservation committedPickup','ERR_FiniteMagazineReservation* committedPickup')
|
||||
+code=code.replace('ERR_MountedAmmoCallback m_Callback','ERR_MountedAmmoCallback* m_Callback')
|
||||
+code=code.replace('TraceParam trace = new TraceParam()', 'TraceParam* trace = new TraceParam()')
|
||||
+code=code.replace('TraceMove(trace, AccessFilter)', 'TraceMove(trace, [this](IEntity e){return AccessFilter(e);})')
|
||||
+code=re.sub(r'\b(bool|int|IEntity|Vehicle|ERR_GameMode|ERR_ConvoyTask|ERR_ConvoyReceipt|ERR_ConvoyVehicle|SCR_AIGroup|ERR_ForceRecord|ERR_HQStatusSampler|BaseWeaponComponent|WeaponSlotComponent|InventoryStorageSlot|BaseMuzzleComponent|BaseMagazineComponent|BaseInventoryStorageComponent|InventoryStorageManagerComponent|ERR_FiniteMagazineReservation\*|ERR_MountedAmmoCallback\*) (\w+);',r'\1 \2{};',code)
|
||||
+code=code.replace('\n}\n','\n};\n')
|
||||
+callbacks=[]
|
||||
+for name in ('OnComplete','OnAllComplete','OnFailed','OnAllFailed'):
|
||||
+ m=re.search('protected override void '+name+r'\(\) (\{[^\n]+\})',s)
|
||||
+ callbacks.append('void ERR_MountedAmmoCallback::'+name+'() '+m[1].replace('Transfer.','Transfer->'))
|
||||
+pre=r'''
|
||||
+#include <cassert>
|
||||
+#include <cmath>
|
||||
+#include <string>
|
||||
+#include <vector>
|
||||
+#include <algorithm>
|
||||
+#include <functional>
|
||||
+#include <limits>
|
||||
+using string=std::string;
|
||||
+template<class T>struct Array:std::vector<T>{using std::vector<T>::vector;int Count(){return this->size();}bool Contains(T x){return std::find(this->begin(),this->end(),x)!=this->end();}void Insert(T x){this->push_back(x);}void RemoveItem(T x){this->erase(std::remove(this->begin(),this->end(),x),this->end());}};
|
||||
+struct vector{float x=0,y=0,z=0;float Length(){return std::sqrt(x*x+y*y+z*z);}static float Distance(vector a,vector b){return vector{a.x-b.x,a.y-b.y,a.z-b.z}.Length();}};
|
||||
+struct Entity;struct Group;struct Mode;struct Task;struct Receipt;struct ConvoyVehicle;struct Record;struct Roster;struct Weapon;struct Mount;struct Slot;struct Muzzle;struct Magazine;struct Storage;struct Inventory;struct HQ;
|
||||
+using IEntity=Entity*;using Vehicle=Entity*;using ChimeraCharacter=Entity*;using SCR_AIGroup=Group*;using ERR_GameMode=Mode*;using ERR_ConvoyTask=Task*;using ERR_ConvoyReceipt=Receipt*;using ERR_ConvoyVehicle=ConvoyVehicle*;using ERR_ForceRecord=Record*;using ERR_HQStatusSampler=Roster*;using BaseWeaponComponent=Weapon*;using WeaponSlotComponent=Mount*;using InventoryStorageSlot=Slot*;using BaseMuzzleComponent=Muzzle*;using BaseMagazineComponent=Magazine*;using BaseInventoryStorageComponent=Storage*;using InventoryStorageManagerComponent=Inventory*;using ERR_HQ=HQ*;
|
||||
+struct Component{virtual ~Component()=default;};
|
||||
+struct Item{Slot*slot=nullptr;Slot*GetParentSlot(){return slot;}};using InventoryItemComponent=Item*;
|
||||
+struct Physics{vector velocity,angular;vector GetVelocity(){return velocity;}vector GetAngularVelocity(){return angular;}};
|
||||
+struct Entity{Entity*parent=nullptr;bool alive=true,eligible=true,awake=true;IEntity seated=nullptr;Item*item=nullptr;Magazine*magazine=nullptr;Inventory*inventory=nullptr;Physics*physics=nullptr;vector position;Physics*GetPhysics(){return physics;}vector AimingPosition(){return position;}};
|
||||
+struct Slot{Storage*storage=nullptr;Component*container=nullptr;IEntity attached=nullptr;bool locked=false;vector point{1,0,0};Storage*GetStorage(){return storage;}Component*GetParentContainer(){return container;}IEntity GetAttachedEntity(){return attached;}bool IsLocked(){return locked;}void GetWorldTransform(vector mat[4]){mat[3]=point;}};
|
||||
+struct Storage{IEntity owner=nullptr;IEntity GetOwner(){return owner;}};
|
||||
+struct Well{int type=1;int Type(){return type;}bool IsInherited(int t){return t==type;}};
|
||||
+struct Magazine{IEntity owner=nullptr;Well*well=nullptr;int rounds=100,capacity=100;bool used=false;IEntity GetOwner(){return owner;}Well*GetMagazineWell(){return well;}int GetAmmoCount(){return rounds;}int GetMaxAmmoCount(){return capacity;}bool IsUsed(){return used;}};
|
||||
+struct Muzzle:Component{IEntity owner=nullptr;Magazine*mag=nullptr;Well*well=nullptr;int kind=0;IEntity GetOwner(){return owner;}Magazine*GetMagazine(){return mag;}Well*GetMagazineWell(){return well;}int GetMuzzleType(){return kind;}};
|
||||
+struct Weapon{IEntity owner=nullptr;Array<Muzzle*>muzzles;IEntity GetOwner(){return owner;}void GetMuzzlesList(Array<Muzzle*>&a){a=muzzles;}};
|
||||
+struct Mount:Component{IEntity owner=nullptr;IEntity gun=nullptr;Slot*slot=nullptr;IEntity GetOwner(){return owner;}IEntity GetWeaponEntity(){return gun;}Slot*GetSlotInfo(){return slot;}};
|
||||
+struct Group{};
|
||||
+struct Record{string Id;};
|
||||
+struct Ledger{SCR_AIGroup donor=nullptr,target=nullptr;Record*d=nullptr,*t=nullptr;Record*FindGroup(SCR_AIGroup g){return g==donor?d:g==target?t:nullptr;}};
|
||||
+struct HQ{bool valid=true;bool ValidateBoundVehicle(SCR_AIGroup g,IEntity e){return valid&&g&&e;}};
|
||||
+struct Mode{inline static Mode*current=nullptr;bool active=true;Ledger*ledger=nullptr;HQ*hq=nullptr;static Mode*Get(){return current;}bool Active(){return active;}Ledger*Forces(){return ledger;}HQ*Command(){return hq;}};
|
||||
+struct Receipt{bool Consumed=true;Array<string>Records;};
|
||||
+struct ConvoyVehicle{int Index=0;IEntity Entity=nullptr;SCR_AIGroup Group=nullptr;bool Released=false,Registered=true,crew=true;Array<IEntity>Members;bool CrewValid(ERR_GameMode){return crew;}};
|
||||
+struct Task{bool Ready=true,Stopped=false;ERR_ConvoyReceipt Receipt=nullptr;Array<ERR_ConvoyVehicle>Vehicles;};
|
||||
+struct Roster{SCR_AIGroup group=nullptr;IEntity root=nullptr,worker=nullptr;bool valid=true;IEntity InitialMember(int slot){return slot==1?worker:nullptr;}bool OwnsRoster(SCR_AIGroup g){return valid&&g==group;}bool ValidateBoundVehicle(IEntity e){return valid&&e==root;}bool CanAttribute(int slot,IEntity e,bool observe){assert(!observe);return valid&&slot==1&&e==worker;}};
|
||||
+struct Replication{inline static bool server=true;static bool IsServer(){return server;}};struct SCR_Global{inline static bool editor=false;static bool IsEditMode(){return editor;}};
|
||||
+struct ERR_Actors{static bool Alive(IEntity e){return e&&e->alive;}static bool CanFight(IEntity e){return e&&e->alive&&e->awake;}};
|
||||
+struct ERR_ConvoyRules{static bool PartOf(IEntity e,IEntity root){for(int i=0;e&&i<32;i++,e=e->parent)if(e==root)return true;return false;}};
|
||||
+struct ERR_InfantryAmmoTransfer{static bool StoredUnder(IEntity e,IEntity root){return ERR_ConvoyRules::PartOf(e,root);}};
|
||||
+struct ERR_EnemyEquipmentRules{static bool Eligible(ERR_GameMode m,SCR_AIGroup g,IEntity e){return m&&g&&e&&e->eligible;}};
|
||||
+struct CompartmentAccessComponent{static IEntity GetVehicleIn(IEntity e){return e?e->seated:nullptr;}};
|
||||
+struct ERR_ForceRules{static bool Finite(float x){return std::isfinite(x);}static bool FiniteVector(vector v){return Finite(v.x)&&Finite(v.y)&&Finite(v.z);}};
|
||||
+struct EMuzzleType{static const int MT_BaseMuzzle=0;};struct EStoragePurpose{static const int PURPOSE_DEPOSIT=1;};
|
||||
+struct TraceParam{vector Start,End;int Flags=0,LayerMask=0;};struct TraceFlags{static const int WORLD=1,ENTS=2;};const int TRACE_LAYER_CAMERA=4;
|
||||
+struct World{float fraction=1;Array<IEntity>blockers;int calls=0;float TraceMove(TraceParam*t,std::function<bool(IEntity)>filter){assert(t->Flags==3&&t->LayerMask==4);calls++;for(auto*e:blockers)if(filter(e))return 0;return fraction;}};
|
||||
+struct Game{World*world=nullptr;World*GetWorld(){return world;}};Game*game=nullptr;Game*GetGame(){return game;}
|
||||
+struct ScriptedInventoryOperationCallback{virtual void OnComplete(){}virtual void OnAllComplete(){}virtual void OnFailed(){}virtual void OnAllFailed(){}virtual ~ScriptedInventoryOperationCallback()=default;};
|
||||
+struct ERR_MountedAmmoTransfer;
|
||||
+struct ERR_MountedAmmoCallback:ScriptedInventoryOperationCallback{ERR_MountedAmmoTransfer*Transfer=nullptr;void OnComplete()override;void OnAllComplete()override;void OnFailed()override;void OnAllFailed()override;};
|
||||
+struct Inventory{IEntity owner=nullptr;Array<IEntity>items;Array<Storage*>storages;bool allow=true,accept=true;int queries=0,calls=0,ack=0;ScriptedInventoryOperationCallback*last=nullptr;std::function<void()>effect;
|
||||
+ IEntity GetOwner(){return owner;}void GetItems(Array<IEntity>&a,int p){assert(p==1);a=items;}void GetStorages(Array<Storage*>&a,int p){assert(p==1);a=storages;}
|
||||
+ bool CanSwapItemStorages(IEntity a,IEntity b){assert(a&&b&&a!=b);queries++;return allow;}
|
||||
+ bool TrySwapItemStorages(IEntity a,IEntity b,ScriptedInventoryOperationCallback*cb){assert(a&&b&&a!=b);calls++;last=cb;if(effect)effect();if(ack==1)cb->OnComplete();if(ack==-1)cb->OnFailed();return accept;}};
|
||||
+enum ERR_MountedAmmoTransferState{FAILED=-1,PENDING,SUCCEEDED};
|
||||
+'''
|
||||
+# ERR_GameMode aliases are pointer types; the static call uses the doubled class.
|
||||
+code=code.replace('ERR_GameMode::Get()', 'Mode::Get()')
|
||||
+main=r'''
|
||||
+struct Fixture{
|
||||
+ Mode mode;Ledger ledger;HQ hq;Group dg,tg;Record dr{"donor"},tr{"target"};Receipt receipt;Task task;ConvoyVehicle donor,target;Roster roster;
|
||||
+ Entity truck,root,worker,gun,loaded,incoming,foreign;Physics dp,tp;Item gunItem,oldItem,newItem;Slot weaponSlot,fromSlot,toSlot;Storage carryStorage,gunStorage;Inventory carried,truckInventory;
|
||||
+ Well well;Weapon weapon;Mount mount;Muzzle muzzle;Magazine oldMag,newMag;Array<IEntity>stock,spent;ERR_FiniteMagazineReservation reservation;World world;Game game_;
|
||||
+ Fixture():reservation(&stock,&spent,&incoming){Mode::current=&mode;mode.ledger=&ledger;mode.hq=&hq;ledger.donor=&dg;ledger.target=&tg;ledger.d=&dr;ledger.t=&tr;
|
||||
+ receipt.Records={"target","donor","2","3","4","5"};task.Receipt=&receipt;task.Vehicles.resize(6,nullptr);task.Vehicles[0]=⌖task.Vehicles[1]=&donor;
|
||||
+ donor.Index=1;donor.Entity=&truck;donor.Group=&dg;target.Entity=&root;target.Group=&tg;target.Members={&worker};truck.physics=&dp;root.physics=&tp;
|
||||
+ roster.group=&tg;roster.root=&root;roster.worker=&worker;gun.parent=&root;loaded.parent=&gun;gun.item=&gunItem;loaded.item=&oldItem;incoming.item=&newItem;
|
||||
+ gunItem.slot=&weaponSlot;oldItem.slot=&toSlot;newItem.slot=&fromSlot;weaponSlot.attached=&gun;weaponSlot.container=&mount;mount.slot=&weaponSlot;mount.gun=&gun;mount.owner=&root;
|
||||
+ weapon.owner=&gun;weapon.muzzles={&muzzle};muzzle.owner=&gun;muzzle.mag=&oldMag;muzzle.well=&well;oldMag.owner=&loaded;oldMag.rounds=25;oldMag.used=true;newMag.owner=&incoming;oldMag.well=&well;newMag.well=&well;
|
||||
+ loaded.magazine=&oldMag;incoming.magazine=&newMag;toSlot.attached=&loaded;toSlot.container=&muzzle;toSlot.storage=&gunStorage;gunStorage.owner=&gun;
|
||||
+ fromSlot.attached=&incoming;fromSlot.storage=&carryStorage;carryStorage.owner=&worker;carried.owner=&worker;carried.items={&incoming};carried.storages={&carryStorage};worker.inventory=&carried;
|
||||
+ truckInventory.owner=&truck;truck.inventory=&truckInventory;stock={&incoming};assert(reservation.Reserve()&&reservation.Commit());game_.world=&world;game=&game_;}
|
||||
+ ERR_MountedAmmoTransfer Job(){return ERR_MountedAmmoTransfer(&mode,&task,0,&roster,1,&weapon,&muzzle,&loaded,&incoming,&reservation);}
|
||||
+ void Swap(){fromSlot.attached=&loaded;toSlot.attached=&incoming;oldItem.slot=&fromSlot;newItem.slot=&toSlot;muzzle.mag=&newMag;carried.items={&loaded};}
|
||||
+};
|
||||
+int main(){
|
||||
+ {Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING&&t.Submitted()&&t.Unresolved());assert(f.carried.calls==1);
|
||||
+ f.carried.last->OnComplete();assert(t.Tick(1)==PENDING&&t.Unresolved());f.Swap();assert(t.Tick(2)==SUCCEEDED&&!t.Unresolved());
|
||||
+ assert(t.Tick(9000)==SUCCEEDED&&f.carried.calls==1&&f.spent.Count()==1&&f.oldMag.rounds==25&&f.newMag.rounds==100);}
|
||||
+ {Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);f.Swap();assert(t.Tick(1)==PENDING);f.carried.last->OnAllComplete();assert(t.Tick(2)==SUCCEEDED);}
|
||||
+ // Inline success plus false native return is still accepted when exact proof agrees.
|
||||
+ {Fixture f;f.carried.accept=false;f.carried.ack=1;f.carried.effect=[&]{f.Swap();};auto t=f.Job();assert(t.Tick(0)==SUCCEEDED&&!t.Unresolved()&&f.carried.calls==1);}
|
||||
+ // Two transactions sharing a committed pickup can never submit two native swaps.
|
||||
+ {Fixture f;auto a=f.Job();auto b=f.Job();assert(a.Tick(0)==PENDING&&b.Tick(0)==FAILED&&!b.Submitted()&&f.carried.calls==1);}
|
||||
+ // No callback, even on false native return, is conservatively quarantined.
|
||||
+ {Fixture f;f.carried.accept=false;auto t=f.Job();assert(t.Tick(0)==FAILED&&t.Submitted()&&t.Unresolved());f.carried.last->OnFailed();assert(!t.Unresolved());assert(t.Tick(1)==FAILED&&f.carried.calls==1);}
|
||||
+ {Fixture f;auto t=f.Job();assert(t.Tick(0)==PENDING);f.carried.last->OnComplete();f.carried.last->OnFailed();assert(t.Tick(1)==FAILED&&!t.Unresolved());f.carried.last->OnAllComplete();assert(t.Tick(2)==FAILED);}
|
||||
+ // A partial native failure cannot free target slots or either magazine identity.
|
||||
+ {Fixture f;auto t=f.Job();t.Tick(0);f.newItem.slot=&f.toSlot;f.toSlot.attached=&f.incoming;f.carried.last->OnFailed();assert(t.Tick(1)==FAILED&&t.Unresolved());}
|
||||
+ // Stop never launches/replays; late exact completion resolves quarantine only.
|
||||
+ {Fixture f;auto t=f.Job();t.Stop();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0&&f.spent.Count()==1);}
|
||||
+ {Fixture f;auto t=f.Job();t.Tick(0);t.Stop();f.mode.active=false;f.Swap();f.carried.last->OnComplete();assert(!t.Unresolved()&&t.Tick(1)==FAILED&&f.carried.calls==1);}
|
||||
+ {Fixture f;auto t=f.Job();t.Tick(0);assert(t.Tick(8000)==FAILED&&t.Unresolved()&&f.carried.calls==1);}
|
||||
+ {Fixture f;auto t=f.Job();t.Tick(10);assert(t.Tick(9)==FAILED&&f.carried.calls==1);}
|
||||
+ // Physical target changes, outgoing capacity/content guards, source inventory bounds.
|
||||
+ for(int k=0;k<34;k++){Fixture f;auto t=f.Job();
|
||||
+ switch(k){case 0:f.task.Stopped=true;break;case 1:f.task.Ready=false;break;case 2:f.donor.Released=true;break;case 3:f.target.Released=true;break;
|
||||
+ case 4:f.receipt.Consumed=false;break;case 5:f.roster.valid=false;break;case 6:f.worker.seated=&f.root;break;case 7:f.worker.awake=false;break;
|
||||
+ case 8:f.worker.eligible=false;break;case 9:f.hq.valid=false;break;case 10:f.dp.velocity.x=0.3;break;case 11:f.tp.angular.x=0.2;break;
|
||||
+ case 12:f.target.crew=false;break;case 13:f.mount.gun=&f.foreign;break;case 14:f.muzzle.mag=nullptr;break;case 15:f.fromSlot.locked=true;break;
|
||||
+ case 16:f.toSlot.locked=true;break;case 17:f.newMag.used=true;break;case 18:f.oldMag.rounds=26;break;case 19:f.newMag.rounds=25;break;
|
||||
+ case 20:f.newMag.capacity=0;break;case 21:f.oldMag.rounds=-1;break;case 22:f.newMag.rounds=101;break;case 23:f.carried.allow=false;break;
|
||||
+ case 24:f.truckInventory.items={&f.incoming};break;case 25:f.carried.items.resize(129,&f.foreign);break;case 26:f.carried.storages.resize(65,&f.gunStorage);break;
|
||||
+ case 27:f.gunStorage.owner=&f.foreign;break;case 28:f.fromSlot.storage=&f.gunStorage;break;case 29:f.task.Vehicles[0]=&f.donor;break;
|
||||
+ case 30:f.worker.inventory=&f.truckInventory;break;case 31:f.weapon.muzzles.resize(9,&f.muzzle);break;case 32:f.ledger.t=&f.dr;break;case 33:f.target.Members.clear();break;}
|
||||
+ assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0&&f.spent.Count()==1);}
|
||||
+ // Partial constructor state fails closed before native inventory access.
|
||||
+ for(int k=0;k<9;k++){Fixture f;
|
||||
+ switch(k){case 0:f.donor.Entity=nullptr;break;case 1:f.target.Entity=nullptr;break;case 2:f.donor.Group=nullptr;break;
|
||||
+ case 3:f.target.Group=nullptr;break;case 4:f.task.Vehicles[1]=nullptr;break;case 5:f.task.Vehicles[0]=nullptr;break;
|
||||
+ case 6:f.roster.worker=nullptr;break;case 7:f.incoming.item=nullptr;break;case 8:f.gun.item=nullptr;break;}
|
||||
+ auto t=f.Job();assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0);}
|
||||
+ // A released handle cannot authorize even when another handle reclaims its exact item.
|
||||
+ {Fixture f;Array<IEntity> stock{&f.incoming},spent;ERR_FiniteMagazineReservation released(&stock,&spent,&f.incoming);
|
||||
+ assert(released.Reserve()&&released.ReleaseUnsubmitted());ERR_FiniteMagazineReservation other(&stock,&spent,&f.incoming);
|
||||
+ assert(other.Reserve()&&other.Commit());auto t=ERR_MountedAmmoTransfer(&f.mode,&f.task,0,&f.roster,1,&f.weapon,&f.muzzle,&f.loaded,&f.incoming,&released);
|
||||
+ assert(t.Tick(0)==FAILED&&!t.Submitted()&&f.carried.calls==0);}
|
||||
+ // Truck is stationary but need not be beside the mount during the carried leg.
|
||||
+ {Fixture f;f.truck.position={35,0,0};auto t=f.Job();assert(t.Tick(0)==PENDING&&f.carried.calls==1);}
|
||||
+ // Context loss after accepted operation is terminal while exact late proof can settle quarantine.
|
||||
+ for(int k=0;k<5;k++){Fixture f;auto t=f.Job();t.Tick(0);switch(k){case 0:f.target.Released=true;break;case 1:f.donor.Released=true;break;
|
||||
+ case 2:f.roster.valid=false;break;case 3:f.worker.awake=false;break;case 4:f.task.Stopped=true;break;}
|
||||
+ assert(t.Tick(1)==FAILED&&t.Unresolved());f.Swap();f.carried.last->OnComplete();assert(!t.Unresolved()&&t.Tick(2)==FAILED&&f.carried.calls==1);}
|
||||
+ // Existing reservation has already spent the pickup. Released/foreign/duplicate handles fail.
|
||||
+ {Fixture f;assert(f.reservation.CommittedFor(&f.incoming)&&!f.reservation.CommittedFor(&f.loaded));assert(!f.reservation.ReleaseUnsubmitted());}
|
||||
+ {Fixture f;Array<IEntity> stock{&f.loaded},spent;ERR_FiniteMagazineReservation r(&stock,&spent,&f.loaded);assert(r.Reserve()&&r.ReleaseUnsubmitted());
|
||||
+ ERR_FiniteMagazineReservation next(&stock,&spent,&f.loaded);assert(next.Reserve()&&next.Commit());assert(!r.CommittedFor(&f.loaded)&&!r.ClaimMountedSwap(&f.loaded));}
|
||||
+ // Authored slot reach executes real distance/trace logic, retaining vehicle hull occlusion.
|
||||
+ for(int k=0;k<7;k++){Fixture f;auto t=f.Job();switch(k){case 0:f.toSlot.point.x=4.01;break;case 1:f.toSlot.point.x=0.01;break;
|
||||
+ case 2:f.toSlot.point.x=std::numeric_limits<float>::quiet_NaN();break;case 3:f.worker.position.x=std::numeric_limits<float>::infinity();break;
|
||||
+ case 4:f.world.blockers={&f.root};break;case 5:f.world.blockers={&f.foreign};break;case 6:f.world.fraction=0.5;break;}
|
||||
+ assert(t.Tick(0)==FAILED&&!t.Submitted());}
|
||||
+ {Fixture f;f.world.blockers={&f.worker,&f.gun,&f.loaded};f.toSlot.point.x=4;auto t=f.Job();assert(t.Tick(0)==PENDING&&f.world.calls==1);}
|
||||
+ // Invalid clock/server/editor guards never consume the second-leg claim.
|
||||
+ for(int k=0;k<4;k++){Fixture f;auto t=f.Job();if(k==0)Replication::server=false;if(k==1)SCR_Global::editor=true;
|
||||
+ assert(t.Tick(k==2?-1:k==3?std::numeric_limits<float>::quiet_NaN():0)==FAILED&&!t.Submitted());Replication::server=true;SCR_Global::editor=false;}
|
||||
+}
|
||||
+'''
|
||||
+run(pre+translated_reservation()+code+'\n'+'\n'.join(callbacks)+main)
|
||||
+print('PASS: actual carried-mounted swap, shared committed claim, physical slot reach, exact two-way proof, uncertainty and terminal cleanup')
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"integrated": false,
|
||||
"native_tested": false,
|
||||
"scope": "Prepared second courier leg only, not production gameplay",
|
||||
"review": "Independent exact-method regression and ownership/callback/access review found no concrete blocker under the stated caller contract.",
|
||||
"required_before_integration": [
|
||||
"Real successful finite pickup to an original courier, without requiring the courier to carry a matching personal firearm",
|
||||
"Fresh delivered mounted-low-ammunition demand and exact original task/root/worker lineage",
|
||||
"Shared finite stock/spent arrays and exclusive worker/muzzle orders",
|
||||
"Strong retention while callbacks or uncertain custody remain outstanding",
|
||||
"Physical approach, mounted slot access, return/reboarding and cleanup",
|
||||
"Native carried-inventory swap and callback/custody qualification"
|
||||
]
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_FiniteMagazineReservation.c": {
|
||||
"base_sha256": "062e922a4e3e9f1465feb76e7406cf4cb4210b684e93d8bfe148b4ed50195fbb",
|
||||
"proposed_sha256": "8278590ced1936d618905b0cbd0b5aebddda238d426a6a2a52e455fc36bbb502"
|
||||
},
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_MountedAmmoTransfer.c": {
|
||||
"base_sha256": null,
|
||||
"proposed_sha256": "4e20f259c275025e143686f7327dcc7d62e3e2be4950701bda663c3eecbf4c99"
|
||||
},
|
||||
"tests/test_mounted_ammo_transfer.py": {
|
||||
"base_sha256": null,
|
||||
"proposed_sha256": "e9e0d3916110c6476fbe94df1a27556ffea933d07911e024bca2d82fedc5daae"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual bounded pursuit roles/objectives/scores, stale search degradation, physical/busy/home guards, finite lifetime and two-bearing escape gap; no hidden player reads or spawning
|
||||
@@ -0,0 +1,19 @@
|
||||
check: /tmp/err-policy-j1ehn18e/check.cpp:209: int main(): Assertion `PlannerRole(belief,10,slot)==Role::SEARCH' failed.
|
||||
Traceback (most recent call last):
|
||||
File "/tmp/erri-hq-planner-heading/test_hq_pursuit.py", line 21, in <module>
|
||||
run(r'''
|
||||
~~~^^^^^
|
||||
#include <cassert>
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
...<159 lines>...
|
||||
}
|
||||
^
|
||||
''')
|
||||
^^^^
|
||||
File "/home/jakub/devel/escapistsrereintroduced/tests/policy_harness.py", line 14, in run
|
||||
subprocess.run([str(p/'check')],check=True)
|
||||
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/usr/lib/python3.14/subprocess.py", line 578, in run
|
||||
raise CalledProcessError(retcode, process.args,
|
||||
output=stdout, stderr=stderr)
|
||||
subprocess.CalledProcessError: Command '['/tmp/err-policy-j1ehn18e/check']' died with <Signals.SIGABRT: 6>.
|
||||
@@ -0,0 +1,550 @@
|
||||
PASS: missing, child-only, malformed, zero and duplicate prefab root IDs rejected
|
||||
PASS: delayed scene/inventory arrival, deferred preload, identity checks, stale replies, timeout and observer cleanup
|
||||
PASS: actual inventory manifest, delayed/missing/wrong-owner item links, finite cap, consumed-stock refresh and preload ordering
|
||||
PASS: spawn scene remains held through final acknowledgement and nearby use; leaving, reassignment, disconnect and teardown release it
|
||||
PASS: production prison AI hold/release, repeat activation, authority/faction/player exclusion, dead actor and stop cleanup
|
||||
PASS: actual infantry search suspension, quiet grace, finite resume, expiry/replacement and defensive/ownership boundaries
|
||||
PASS: infantry combat gate precedes radio delivery and preserves non-task transports
|
||||
PASS: actual HQ contact transition wakes only fit squad members, cancels only task orders and logs changes once
|
||||
PASS: actual finite medicine grants, authored stock deduction, full-backpack refusal/pouch fallback, no loot replenishment, unresolved-operation quarantine and ownership/stop guards
|
||||
PASS: only recent native detected/identified threats suspend hunter travel; stale/disarmed/destroyed contacts cannot strand patrols
|
||||
PASS: actual hunter combat transition cancels only its travel once, holds through renewed contact and resumes after quiet; unregistered startup preserved
|
||||
PASS: captured sighting retention, immutable details, expiry, replay rejection, bounded sound uncertainty/cooldown, radio loss, priority and overdue-status fairness
|
||||
PASS: arrow press/release, held keys, opposing keys, disabled/menu input and firearm-only retention
|
||||
PASS: town trigger and hard 700m exclusion for all observers, empty/invalid positions and final-check crossings
|
||||
PASS: exact finite site squads, invalid roster/count rejection, committed-site spacing and safe fallback boundary
|
||||
PASS: mortar couriers use the mobile site team and refuse permanent-only garrisons
|
||||
PASS: omitted preferred mortar depot selects a surviving owned camp/mobile team; no camp, foreign cache and permanent-only sites are unavailable; historical priority retained
|
||||
PASS: real-session mortar deadline, failed-support convoy admission and hunter survivor/recovery gates
|
||||
PASS: native-route retry preserves delivered target, limits attempts and suspends during combat
|
||||
PASS: stale/deleted AI utility cannot receive Complete; mortar HQ preflight withholds unsafe orders; mounted convoy cover never creates infantry Defend
|
||||
PASS: flight crew affiliation and group precede native boarding; preparation remains bounded even while passengers wait
|
||||
PASS: factionless/deleted map targets do not abort perception; faction lookup tolerates teardown; deleting helicopter releases without capture/engine access
|
||||
PASS: shoot adapter waits for a physical round; bounded same-shell retries, interrupted/never-started loads, committed no-retry, order/owner changes and normal native delegation
|
||||
PASS: missing/invalid faction crew defers before any native spawn or allowance insertion; all registered RHS factions have explicit soldier and medic profiles
|
||||
PASS: vehicle radio issued once; pending, refusal and looting cannot duplicate or fabricate a physical radio link
|
||||
PASS: actual vehicle-radio link requires the original seated crew, physical manpack and live uncaptured mission vehicle; looting, dismount, release and teardown remove it
|
||||
PASS: actual hunter release preserves survivors/HQ, releases driving ownership once, delegates capture/teardown, and excludes prison/patrol/mortar from generic objective defence
|
||||
PASS: real opening road geometry enforces wide azimuths; fresh delivered contact preempts patrol cooldown, respects radio failures and does not starve in-flight interception
|
||||
PASS: actual scoped 10% tighter REGULAR aim error and alert perception; preserves equipment multiplier and restores vanilla behavior when unbound
|
||||
PASS: physical inspection and parent-wreck retention; server-only searched/report delivery unlocks native cleanup once with a 300-second delay
|
||||
PASS: bounded same-group empty-spawn retries, no casualty refill, queue retirement, delivery-gated intel, prepared-team reuse, throttled diagnostics and LOD release
|
||||
PASS: production airborne memory confidence, persistence, ground coverage, confirmed losses, artillery veto, cooldown and invalid-input rules
|
||||
PASS: production cover retains the carried HQ target until its deadline; airport reload waits until the drop pass and cover have finished
|
||||
PASS: air logistics reservation preserves delivered search until radio handoff, excludes guards/combat/in-flight orders, and quarantines unresolved native loads/moves
|
||||
PASS: actual ammunition cargo selector handles empty rifle/machinegun/sniper magazines, preserves loaded variants, excludes auxiliary launchers and tolerates missing native metadata
|
||||
PASS: original 15-minute launch/loss cadence, active/captured timer disarm, saved delay reset, stop, 300m orbit and bounded close-contact standoff at 30/60/120 Hz
|
||||
PASS: actual aircraft-removal notification guards owner/server/active/stop and schedules one full delay without replay extension
|
||||
PASS: hill prominence/elevation, actual road edges/heights/bends and server-only finite scout admission, pending stock, timeout and no replacements/refills
|
||||
PASS: mortar duty scope excludes players, other crews, stopped/client/inactive states; only destruction releases an active assignment, while the gunner may approach the gun
|
||||
PASS: random mode restrictions, full numeric ranges, independent calendar dates and strict daylight boundaries
|
||||
PASS: actual killais eligibility includes the 1000m boundary, excludes players/retained bodies/dead/non-character entities and checks full 3D distance
|
||||
PASS: actual generation scheduler bounds each tick, enforces deadline/candidate ceiling, validates fallback, commits only accepted positions, skips only dispensable sites, preserves required objectives/intel, and resets the next search budget
|
||||
PASS: terrain placement samples world bounds, retains streaming candidates, bounds waits/work, rejects foreign fallbacks, preserves objectives/intel and validates completion
|
||||
PASS: actual navigation readiness supports static meshes, yields only for loadable streaming tiles and refuses unreachable positions
|
||||
PASS: terrain adapter resources, dependencies, stable IDs, native nav configs, missing-nav visibility, path validation and overwrite protection
|
||||
PASS: airfield detection accepts physical runways/towers and bounded authored markers, rejects unrelated props, water and out-of-world markers, and samples terrain height
|
||||
PASS: actual faction resolution reserves explicit roles, samples without replacement, substitutes disabled selections, and rejects duplicate/unknown/missing choices and insufficient pools
|
||||
PASS: Random all submits persistent random roles immediately; manual mixed choices, stale/unauthorized UI guards and debounce preserved
|
||||
PASS: actual content policy gates parent packs, individual factions, faction identity and finite group rotation with vanilla fallback
|
||||
PASS: actual delivered road eligibility, ahead projection without chords, reservations, stock road query bounds, terrain/water/obstruction refusal and clean outputs
|
||||
PASS: actual delivered-task lineage, expiry, old-order retention, native commit, release, road precision expiry and duplicate delivery
|
||||
PASS: actual original-roster local handoff,100m3D bound,busy carrier/budget exclusion,origin interruption including deletedsource,normal radio delivery and per-source replay history
|
||||
PASS: actual visual intake retains source/time/position/id, rejects replay, prefers usable own route, excludes simultaneous callers and conservatively resets negative-sweep dwell
|
||||
PASS: actual fixture local/radio gating, immutable source/time/position, interrupted-report exclusion and exact-owner cleanup
|
||||
PASS: local-handoff runner refuses wrong project/round count/insufficient deadline before runtime work
|
||||
PASS: actual fixture allocator terminal/unsubmitted guard, original-group lookup and both candidate gates
|
||||
PASS: actual report-derived waypoint insertion/order and tighter positive radii; no formation navigation claim
|
||||
PASS: actual Place/Stop waits native pose update, bounds four attempts, preserves original position, restores pending/settled placement and respects ownership/accepted-move quarantine
|
||||
PASS: actual fixture current/original recipient ownership, unresolved transfer cleanup, exact-token release and idempotent Stop
|
||||
PASS: actual fixture phased-cargo readiness, bounded callbacks, captured-stock mixed-caliber selection/continuation, reservation cleanup and component magazine counts
|
||||
PASS: actual inventory-fixture setup uses ordinary prison unlock before constructing its convoy-waiting probe; failed unlock cannot run fixture
|
||||
PASS: actual authored storage anchors, native trace flags, own-hierarchy exclusion, external wall/vehicle obstruction, range, unknown geometry and bounded context refusal
|
||||
PASS: actual convoy binding, finite identities, disjoint tokens, shared report replay/cooldown, original recipients and HQ cleanup
|
||||
PASS: actual finite convoy supply pool; immutable slots, shared demand state, sparse/capped discovery and permanent shutdown
|
||||
PASS: actual HQ rotates finite donors, skips unavailable/contacted trucks, uses delivered reports and dispatches at most one trip per planning cadence
|
||||
PASS: actual original turret identity, native/canonical guards, scoped maximum-skill profile, reset, dismount/reboard, requested-skill preservation and restoration
|
||||
PASS: bounded HQ startup/memory windows and outcome-specific full-route deadlines
|
||||
PASS: explicit escape-route skips only administrator stress, preserving original full-fixture wait/failure paths
|
||||
PASS: normal escape route keeps ordinary catalog and generated placement; historical selectors remain unchanged
|
||||
PASS: actual read migrates old valid settings, preserves explicit disabled state, rejects invalid data; next-round feedback and fixed menu remain honest
|
||||
PASS: actual automatic convoy timing/authority/admission/one-attempt/manual-task/stop policy; native deployment unproved
|
||||
PASS: late authoritative failure reason refreshes open result; detach, mode change and success subscriptions preserved
|
||||
infantry resupply actual rules, radio transitions, owned cleanup and unresolved-operation tests passed
|
||||
PASS: actual resupply Roster preserves permanent release, original slot mapping and bounded ownership
|
||||
PASS: actual bounded empty-return and finite delivery; phase-isolated callbacks, exact ownership proof, stop quarantine and original actor/vehicle boundaries
|
||||
PASS: actual shared finite identity reservation; competing consumers, submission permanence, stale cleanup and96-item bound
|
||||
PASS: actual carried/mounted early ammunition policy and status-first shared uplink; complete threshold, phases, cooldown, failures and requested check-ins
|
||||
PASS: actual group radio startup preservation, finite native grants, callback quarantine, frozen selection/actor ownership and bounded observation
|
||||
PASS: actual maintenance native-stock check rejects missing/duplicate/wrong-identity/unowned/depleted/malformed stock and is read-only; native runtime not executed
|
||||
..................
|
||||
----------------------------------------------------------------------
|
||||
Ran 18 tests in 0.248s
|
||||
|
||||
OK
|
||||
PASS: actual radio node rejects current incapacitation, death, ownership and faction changes despite cached inventory; one-second capability refresh remains explicit
|
||||
PASS: one optional Southern transport, unchanged finite clue/maintenance stock, and airfield-only extraction config
|
||||
PASS: optional transport deferred behind required readiness, bounded once-only spawn/omission, isolated cleanup, occupied-candidate retention and required-default preservation
|
||||
PASS: actual diagnostic fallback runs only on failed missing-context call, derives unique native pilot door, preserves stock eligibility and restores prior index on success/failure; diagnostics mutate no game state.
|
||||
PASS: actual native-prelude cleanup restores only original changed damage, refuses stale/incapacitated/aboard teleport; bounded five-seat/four-door fixture wiring checked. Native execution remains pending.
|
||||
PASS: actual CreateTransport requires successful scoped Configure after handbrake, preserves ordinary vehicles, tracks spawned entity before failures and never treats failed lock registration as ready.
|
||||
PASS: actual preparation Configure guards/idempotence/breach preservation, security eligibility/final current-body server mutation and all scoped action guards; all five seat/four door resource overrides. Native hold, prefab merge, replication and boarding remain unverified.
|
||||
PASS: production vehicle alarm single trigger/replica completion/no replay, fixed deadline/readiness wait, failed audio, dedicated server, moving exact handle, destruction/native end/deletion/clock and mission teardown. Native sound and multiplayer delivery require engine qualification.
|
||||
PASS: production alarm emitter/receiver original time/location, explicit native queue only, 32-entry cap, 50m local witness eligibility, bound perception, native-super preservation; actual engine broadcast/hearing remains unverified.
|
||||
PASS: actual bounded native mounted proof/detached payload/deadline/cleanup methods, production-only setup and isolated runner selector
|
||||
PASS: actual one-existing-convoy candidate readiness, sender-root identity, incomplete cargo refusal and fixed three-candidate bound
|
||||
PASS: actual once-only native dry query, exact before/after slots, native refusal, shutdown; shared bounded discovery and distinct opt-in verdict
|
||||
PASS: actual completion selector and pre-cleanup variant capture preserve separate radio and eligibility verdicts
|
||||
PASS: actual cargo diagnostic stages separate absent/foreign magazines, used/empty/invalid rounds, well mismatch and exact truck storage/attachment without mutation
|
||||
PASS: actual arranged native alarm fixture deadline, single emit, natural-route observation, original timestamp/area/detail assertions, natural observer proximity/activation wait, failure cleanup and independent canonical-body restoration; native delivery itself remains unqualified.
|
||||
PASS: actual convoy cover observation/snapshot/uplink/HOLD/RESUME/cleanup transitions; native boundaries mocked, non-convoy runner opt-in refused
|
||||
Enemy optics actual-service ownership, preservation, callback, deadline and bounded-inspection policies passed
|
||||
PASS: actual delivered cover freshness/lineage/replay and canonical executor; owned waypoint-only hold, one resume at preserved route index, invalid ownership/crew/ledger refusal and fail-closed native recreation
|
||||
PASS: actual Stinger show/set/help state precise actor-roll effects; read-only help, bounded values, malformed syntax and failed-save preservation; no rerolls/gameplay edits and no native persistence claim
|
||||
PASS: new/retasked search and radio delivery ammo gates; active tasks and delivered release preserved
|
||||
HQ convoy delivered-report planning and downlink regressions passed
|
||||
PASS: actual own-inventory ammo inspection deduplicates loaded/carried/shared wells, separates chambers/launchers, freezes scalar snapshots and treats unsupported/capped/foreign inventory as unknown
|
||||
PASS: actual mounted hierarchy sampling, ownership exclusion, deduplication, completeness/caps, quarter threshold and detached validation; no runtime policy or ammunition mutation
|
||||
PASS: actual HQ original convoy-root admission rejects wrong force/server/group and never supplies replacement lookup
|
||||
PASS: production mounted structural seat scan ignores >128 carried/cargo descendants, shares exact native mount/magazine ownership, preserves attachment seats and exact occupants, rejects unknown/cyclic/oversize structures; native binding still requires qualification.
|
||||
PASS: native body fixture uses existing immutable actors, real production LOS/queued uplink, pre-delivery isolation, actual status overlap, bounded cleanup and no fabricated reports/spawns
|
||||
PASS: actual native fixture lookup selects exact BODY kind/identity/message from bounded evaluations, never sighting-only Get
|
||||
PASS: actual ammo snapshot comparison checks every scalar/category flag; native probe requires real roster rescan, loaded-round lower bound and separate immutable pending/Watch objects
|
||||
PASS: actual delivered slot-union bodies preserve overlap/disjoint evidence, replay idempotence, status subset integrity, full-wipe closure and formation-local bounds
|
||||
test_review_added_allowed_media_invalidates_snapshot (__main__.ReviewTests.test_review_added_allowed_media_invalidates_snapshot) ... ok
|
||||
test_review_added_source_directory_rejected (__main__.ReviewTests.test_review_added_source_directory_rejected) ... ok
|
||||
test_review_loose_root_resource_and_symlink_rejected (__main__.ReviewTests.test_review_loose_root_resource_and_symlink_rejected) ... ok
|
||||
test_review_metadata_media_and_sidecars_remain_allowed_and_bound (__main__.ReviewTests.test_review_metadata_media_and_sidecars_remain_allowed_and_bound) ... ok
|
||||
test_review_missing_link_rejected (__main__.ReviewTests.test_review_missing_link_rejected) ... ok
|
||||
test_review_package_guard_sees_new_scripts (__main__.ReviewTests.test_review_package_guard_sees_new_scripts) ... ok
|
||||
test_review_retargeted_private_link_rejected (__main__.ReviewTests.test_review_retargeted_private_link_rejected) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 7 tests in 0.059s
|
||||
|
||||
OK
|
||||
PASS: actual report methods reproduce old starvation; status-first scheduler delivers check-ins and requires 30s without combat or actual visible contacts before negative reports
|
||||
PASS: actual actor group lookup retains controlled character membership when seated/inherited vehicle agents differ; missing control or parent refuses
|
||||
.................
|
||||
----------------------------------------------------------------------
|
||||
Ran 17 tests in 3.109s
|
||||
|
||||
OK
|
||||
PASS: actual convoy motion thresholds, native-only proof boundaries, physical cargo/crew ownership and pre-launch runner restrictions
|
||||
PASS: actual filled rotated-footprint TraceBox and nine terrain/water samples; broad tree/cable bounds alone accepted, actual collision/nonfinite trace refused, nonzero sweep and ENTS/OCEAN flags, bounded diagnostic query and reset
|
||||
PASS: actual road interpolation/projection/orientation, six35m starts,200m forward tail, preserved bends, short/far/degenerate/nonfinite/overdense/hairpin refusal and deterministic candidate ties
|
||||
PASS: actual authenticated convoy dispatch, active/ready admission gates, canonical receipt, safe unconsumed preflight retry, pool refusal, retained partial failure and consumed no-retry
|
||||
PASS: actual native readiness exact membership, one-time per-vehicle ledger admission/reservation, partial readiness retry without duplicate records and one-pass56-item cargo allocation without replenishment
|
||||
PASS: actual per-vehicle readiness reasons, native agent/activity counts, intended-seat diagnostics, five-second throttle and read-only observation
|
||||
PASS: actual convoy dispatch validates before receipt consumption, consumes once before native mutation, retains all12 partial-failure paths, accepts the selected non-USSR enemy, and allocates exact19 bodies without capacity shrinking
|
||||
PASS: own memberless prefab disables automatic spawn before initialization; actual admission rejects populated, immediate or authored-slot templates before finite crew creation
|
||||
PASS: actual native seated-group arrival outside35m, native waypoint removal, idempotent advance, and convoy waypoint idempotence/arrival/deadline, missing/dead/captured/reparented crew refusal, failed native waypoint release, original vehicle/member preservation and no replacement
|
||||
PASS: actual convoy receipt identity/one-use, shared60-body and128-formation caps, outstanding/native-ledger accounting, exact19-body composition, source reuse, mode/client guards and no consumed receipt refunds
|
||||
PASS: actual supply route cycling/arrival/stops, finite startup bounds, contact freshness, dismount hold, quiet interval, interrupted boarding, timeout and lost-truck release
|
||||
PASS: moving-convoy perception boundaries and scoped individual/group abandonment priorities
|
||||
PASS: actual supply startup reasons expose unchanged body budget/requirement, journal only failure changes, preserve retry cadence/caps and report the true final refusal
|
||||
PASS: actual StartOne plus actual pool preserve unconsumed receipt retry, reject consumed replay, skip impossible new-budget surveys, retain equality, retry caps and journal dedup; no FPS claim
|
||||
PASS: actual admission seeds use exact installed loaded prefab, reject replacement/foreign/projectile paths and preserve bounded immutable identity
|
||||
PASS: actual primary-before-mounted one-shot batch, shared96/128 caps, physical snapshot headroom, original ownership, callback refusal and admission pinning
|
||||
PASS: actual bounded HQ query validates only existing original binding without admission or replacement lookup
|
||||
PASS: production convoy spacing, physical arrival, stable follower targets, supply ownership, leader promotion and bounded stuck recovery
|
||||
PASS: convoy combat keeps native manoeuvres for unchanged contacts and refreshes when contact moves
|
||||
PASS: native convoy proof excludes pre-departure movement and ends via explicit fixture reset, not prohibited player death
|
||||
PASS: boarding retries only after approach/seat progress stops, capped at three, with delayed native reissue and completed-team preservation
|
||||
PASS: slow only owned vehicles near fit dismounted infantry; ignore passengers, casualties and released teams/vehicles
|
||||
PASS: restore missing native driving registration only for healthy owned seated crews; preserve existing association and refuse invalid/released vehicles
|
||||
PASS: actual body observer enforces owned physical roster, local death-only candidates, native trace gating, budget/cadence/caps, immutable body-only snapshots, radio retries and confirmed suppression
|
||||
PASS: own initial roster, explicit retained corpse evidence, unconscious/missing/ref transfer guards, fixed strength, no replacement adoption, detached samples, surviving radio sender, immutable convoy root/ledger, mounted capture release and lost-root unknown
|
||||
PASS: delivered-only status snapshots, two missed check-ins/reply deadline, last reported coordinates, episode/replay guards, confirmed-loss idempotence, detached/validated mounted payload replacement and 256-record cap
|
||||
PASS: actual assignment cancellation/release preserves radio ownership, native waypoint lifecycle and failed-order retry boundaries
|
||||
PASS: actual force ledger, finite casualties/identity/cap, routes/arrival/elevation/overshoot, server and physical guards, staggered 256-record simulated hour without world queries
|
||||
PASS: actual equipment coordinator registration dedupe, startup delay, five member scans, finite component retries, unregister/stop terminal behavior and 256-group bound
|
||||
PASS: actual percentage selection, native/preferred launcher preservation, failure/removal fallback, pending-operation quarantine, capture, finite two-mine grants and no replenishment
|
||||
PASS: actual objective heading/threat/approach rules, persistent doctrine weight, fresh-contact coverage invalidation, stale-sweep rejection and atomic radio retask ownership
|
||||
PASS: actual bounded delivered-negative coverage, replay/freshness/expiry/invalid guards, oldest eviction, small-circle and nearest-unswept selection, reserved-cell exclusion and cleanup
|
||||
PASS: actual bounded pursuit roles/objectives/scores, stale search degradation, physical/busy/home guards, finite lifetime and two-bearing escape gap; no hidden player reads or spawning
|
||||
PASS: actual HQ memory rules/service preserve delivered snapshots, chronology, replay bounds, decay, motion limits, identity and negative-search revisions
|
||||
.......
|
||||
----------------------------------------------------------------------
|
||||
Ran 7 tests in 0.022s
|
||||
|
||||
OK
|
||||
PASS: actual session Tick + journal router delivers each grant completion and new HQ line once, without repeats on empty/unavailable feeds or unauthorized ticks
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 0.331s
|
||||
|
||||
OK
|
||||
PASS: actual current-controller/admin/mode authorization, per-round anti-replay, token-rotation refusal, command/snapshot throttles and client scope; owner-only replies and player-tool cleanup wiring
|
||||
PASS: mission provider registration is idempotent, optional dispatch is ordered, status aggregates, journals preserve cursors, aliases stay with their addons and topic help is bounded
|
||||
PASS: actual menu command routing covers all fourteen settings, rejects unsupported keys, gates companions, and matches unique authored widgets
|
||||
PASS: explicit weapon retention buttons use the same ready/authorized server command path
|
||||
PASS: actual summaries preserve queued/delivered meaning, clear counts and IDs; raw records, legacy display, cursor gaps and RPC limits remain intact
|
||||
PASS: actual admin body authorization, god restoration, vanilla item deposit, callback completion/failure, timeout quarantine and stop/revocation paths
|
||||
PASS: same-body revoke/regrant preserves pending insertions and timeout quarantine; new-body binding isolates late callbacks and never inherits god mode
|
||||
PASS: actual Intel commands distinguish status/start/failure, preserve authorization gate and reject malformed requests; spent ledger is idempotent, server-only and bounded
|
||||
PASS: actual reroll snapshot, authority, cancellation, ownership, accepted operations, quarantine, bounded work and stop methods; no native runtime claim
|
||||
PASS: production Intel feedback coalescing, rough secrecy, rate limit, bounded dedupe, local/remote delivery and round cleanup; native UI/RPC not exercised
|
||||
PASS: actual per-squad bounded report selector rotates visible targets, survives ordering/turnover, records only queued attempts, and preserves radio intake ordering
|
||||
PASS: actual action denial/clearing, server request failure, single submitted-result feedback, current rescuer identity and terminal/stop suppression; native UI/RPC pending
|
||||
PASS: actual physical denial precedence and transport-seat occupancy/reservation/access/lock checks
|
||||
PASS: actual initial admission exhaustion and ServerTick grace; new/pending/empty/controller/life guards, normal death preserved
|
||||
......................
|
||||
----------------------------------------------------------------------
|
||||
Ran 22 tests in 0.232s
|
||||
|
||||
OK
|
||||
......................
|
||||
----------------------------------------------------------------------
|
||||
Ran 22 tests in 24.707s
|
||||
|
||||
OK
|
||||
..................
|
||||
----------------------------------------------------------------------
|
||||
Ran 18 tests in 3.000s
|
||||
|
||||
OK
|
||||
.........
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 2.363s
|
||||
|
||||
OK
|
||||
...............
|
||||
----------------------------------------------------------------------
|
||||
Ran 15 tests in 1.146s
|
||||
|
||||
OK
|
||||
PASS: actual field result/braking observer and Chat dispatch rules; one finite fixed candidate, deferred callback failure and guarded cleanup; no native measurement
|
||||
PASS: actual opt-in terrain audit records one fixed1681-point grid, preserves original survey refusal/success and exact no-allocation scope; malformed heights stop without retry; no native data acquired
|
||||
....
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 0.633s
|
||||
|
||||
OK
|
||||
PASS: actual field PI/ramp/vector caps, antiwindup, braking hypothesis, immutable admission limits and segment bounds; no native physics tested
|
||||
PASS: actual100m whole-field survey sampling/4096cap, rotated coverage, all-node terrain and native trace refusal; original certificate lineage retained; no native qualification
|
||||
PASS: actual QualifyField preserves original identity/footprint/time, orders complete surveys before issuance, and refuses failed stages/moved body/expired or changed world; native boundaries faked
|
||||
PASS: WORKBENCH first-refusal diagnostics preserve ordinary predicates, query order/count/budget and opt-in scope; no native logging run
|
||||
PASS: actual field startup delegation, immutable lease/target, braking/settling/cancel transitions, early abort, callback scope, physical terminal policy and shared landing demand; native boundaries faked
|
||||
PASS: actual inherited airborne pre-CLIMB cancellation enables verified native autohover once, refuses failed enable and never writes after capture
|
||||
PASS: actual Core maintenance/default/tick/stop methods; empty/populated authority, terminal reentry, no tactical resume or new scheduler; native boundaries substituted
|
||||
PASS: actual finite registration, unique claims/tokens, retention/cancel/stop, readiness gating, capture/expiry retirement and bounded cross-kind order history and typed field/route construction; native boundaries faked
|
||||
PASS: actual WORKBENCH route observer returns exact retained route subtype and refuses absent/field controllers
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 0.659s
|
||||
|
||||
OK
|
||||
......................
|
||||
----------------------------------------------------------------------
|
||||
Ran 22 tests in 0.181s
|
||||
|
||||
OK
|
||||
................
|
||||
----------------------------------------------------------------------
|
||||
Ran 16 tests in 10.482s
|
||||
|
||||
OK
|
||||
......
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in 0.018s
|
||||
|
||||
OK
|
||||
PASS: actual production bridge lookup, lease/world/mode/seat/capture guards, no allocation, native super ordering and read-only fixture hooks
|
||||
...............
|
||||
----------------------------------------------------------------------
|
||||
Ran 15 tests in 0.055s
|
||||
|
||||
OK
|
||||
.............
|
||||
----------------------------------------------------------------------
|
||||
Ran 13 tests in 4.951s
|
||||
|
||||
OK
|
||||
PASS: actual route gain/caps/braking, callback selection, old landing/cancellation control and matching read-only telemetry
|
||||
..............................
|
||||
----------------------------------------------------------------------
|
||||
Ran 30 tests in 0.409s
|
||||
|
||||
OK
|
||||
..............
|
||||
----------------------------------------------------------------------
|
||||
Ran 14 tests in 0.210s
|
||||
|
||||
OK
|
||||
.........
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 0.119s
|
||||
|
||||
OK
|
||||
PASS: actual gate observer binds native registered action/context and current life, reads accumulated progress, refuses stale bindings and never revives outside original bounds
|
||||
PASS: actual read-only look observer methods enforce explicit scope, pinned native camera/body/identity, normalized pose, terminal cancellation and original sample/time bounds
|
||||
...........
|
||||
----------------------------------------------------------------------
|
||||
Ran 11 tests in 0.069s
|
||||
|
||||
OK
|
||||
.......................
|
||||
----------------------------------------------------------------------
|
||||
Ran 23 tests in 0.034s
|
||||
|
||||
OK
|
||||
PASS: actual initial WAITING task/guide copy, configured duration, unchanged interruption and rounded progress; native task assertion pending
|
||||
........
|
||||
----------------------------------------------------------------------
|
||||
Ran 8 tests in 0.011s
|
||||
|
||||
OK
|
||||
PASS: actual inventory adapter scope, grid placement, sole compatible host, refresh reuse, rollback, foreign hierarchy refusal and exactly-once native delegation; native compatibility pending
|
||||
.................................................................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 81 tests in 0.539s
|
||||
|
||||
OK
|
||||
......
|
||||
----------------------------------------------------------------------
|
||||
Ran 6 tests in 0.077s
|
||||
|
||||
OK
|
||||
.................
|
||||
----------------------------------------------------------------------
|
||||
Ran 17 tests in 0.004s
|
||||
|
||||
OK
|
||||
...........
|
||||
----------------------------------------------------------------------
|
||||
Ran 11 tests in 0.083s
|
||||
|
||||
OK
|
||||
.........
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 0.341s
|
||||
|
||||
OK
|
||||
PASS: actual observer nonce, admission pins, baseline/menu sequencing, snapshots, bounded clocks/samples, cleanup and one-attempt latch; native untested
|
||||
PASS: actual corridor caps/height/hold and whole-rectangle survey bounds, terrain refusal, native trace refusal and exact certificate lineage; native route unqualified
|
||||
PASS: actual route entry, fixed corridor/target, hover hold, cancellation landing freeze, shared lease/capture/deadline gate and unchanged native startup/tick sequence
|
||||
PASS: finite opt-in route fixture, original native input order, meaningful physical-arrival evidence and guarded cleanup; no native launch
|
||||
PASS: actual Chat route step result dispatch and scoped completion/cleanup wiring; six real early-parser refusal paths leave no prefix/profile output
|
||||
PASS: actual retained-service fixture entry, immutable controller/token/deadline/count bindings, observer getter and cleanup ownership ordering; native route validation pending
|
||||
PASS: actual measured cancellation gate, one-shot retained service Stop, no premature drain, immutable lease, fresh real controller readback and separate physical cancellation result policy
|
||||
PASS: actual rough-intel objective selection, exact precedence, source grid dimensions and unchanged other-phase dispatch; native UI pending
|
||||
.................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 33 tests in 0.095s
|
||||
|
||||
OK
|
||||
...............
|
||||
----------------------------------------------------------------------
|
||||
Ran 15 tests in 0.038s
|
||||
|
||||
OK
|
||||
PASS: actual preparation status scope, persistent updates, spinner restoration, placeholder replacement/deletion/destruction, native observation persistence/timeout; rendering remains native-pending
|
||||
PASS: actual guide/observer monitors retry native refusal, cache successful delivery, deduplicate and preserve living/preparing/spectator boundaries; native UI not exercised
|
||||
PASS: actual native-end shutdown, existing terminal snapshots, reentrancy, unchanged native end data and stale preparation guards
|
||||
....
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 1.396s
|
||||
|
||||
OK
|
||||
PASS: actual three-state result wording and UI refresh; stale winner IDs never manufacture escape
|
||||
...........
|
||||
----------------------------------------------------------------------
|
||||
Ran 11 tests in 0.112s
|
||||
|
||||
OK
|
||||
PASS: actual immutable target, bounded autohover demand, drift refusal, five-second hold and unchanged qualification/deadline
|
||||
PASS: actual admission attempt budget bounds blocked/missing prerequisites; preparation, spent life and async pending remain protected
|
||||
PASS: delayed admission retry retains controller ownership across same-account recycled connection IDs
|
||||
PASS: actual scene deadline overrides delayed native preload only for rejection; late completion cannot assign, ordinary verified admission preserved
|
||||
PASS: actual action permission matrix unchanged; useful phase/intel/consciousness denials, stale reason cleared, native door denial preserved; no native UI claim
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 0.255s
|
||||
|
||||
OK
|
||||
PASS: actual aircraft cancellation/stage rules, ground-only completion, expiry/capture faults, input ownership and no physical shortcuts
|
||||
PASS: actual exact-instance single-use qualification, native-clock staleness/movement refusal, footprint bounds and ownership-safe ground/fault cleanup
|
||||
PASS: actual optional screenshot helper flag/identity/world/life revalidation, one queued attempt, delayed capture and mission/world cleanup; no native image/presentation claim
|
||||
PASS: actual yard diagnostic exact registered prison ownership, eight native-bound corner projections, no root-sibling escape, bounded duplicate/deep/wide hierarchy traversal; native projection/mask still unmeasured
|
||||
PASS: actual CurrentActor, SpawnPosition and observer-selection methods reject pending/unregistered/replaced/recycled/foreign/dead bodies; canonical selection/cycling, unconscious following and prison/geometry fallback preserved; native boundaries adapted
|
||||
PASS: actual native-map fixture ownership, cleanup and callback evidence fail closed; native execution remains separate
|
||||
PASS: actual shared-map callbacks bind exact map/config/root, preserve replacement UI/camera, defer focus, and remove only owned delayed work
|
||||
PASS: actual Intel/HQ methods and one-shot qualified readiness handoff deliver late actors once; duplicate readiness, accepted spawn, pickup/drop, death and original negative rolls do not mint assignments
|
||||
PASS: Workbench-only read accessor rejects unknown/nonserver identities; Chat observes all distinct ready crew before existing shell-depletion mutation
|
||||
PASS: actual native-event latch survives deselection, requires exact activity/order, detaches before cleanup, preserves failure/timeout and never infers completion from physical shot count
|
||||
.........
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 0.117s
|
||||
|
||||
OK
|
||||
PASS: actual refresh-fixture gates pin immutable observations/actual downlinks/original activity, reject unaccepted or relabelled commits, stop queueing early and require all queued contacts claimed before replay
|
||||
..........................
|
||||
----------------------------------------------------------------------
|
||||
Ran 26 tests in 0.214s
|
||||
|
||||
OK
|
||||
PASS: actual refresh scheduler/delivery/cancellation/projectile methods reject interrupted or replayed reports, retain committed ownership, preserve immutable snapshots/aim geometry and isolate stopped or replaced orders; native radio/crew behavior remains separate
|
||||
.....................
|
||||
----------------------------------------------------------------------
|
||||
Ran 21 tests in 0.037s
|
||||
|
||||
OK
|
||||
...........
|
||||
----------------------------------------------------------------------
|
||||
Ran 11 tests in 0.035s
|
||||
|
||||
OK
|
||||
PASS: actual full-salvo gates require eight fresh committed physical launches, natural closure and exact finite inventory; reject partial/extra/replayed events
|
||||
PASS: actual reason/availability guidance and refresh matrix; no-target copy omits cycling, hint retry retained, existing command/admin paths unchanged; native UI pending
|
||||
PASS: actual client camera policy closes immediately on healing or mission end; late unconscious metadata cannot keep the view active
|
||||
PASS: actual input dispatch, one press per edge, menu-held suppression; actual revival camera handoff with editor close/retry, missing camera, replacement body and stopped round
|
||||
PASS: first-person pose survives missing samples without drift, follows body motion/rotation, resumes fresh pose and cannot leak between targets
|
||||
................usage: test_native_package.py [-h] [--project {core}] --session SESSION
|
||||
--compat COMPAT [--steam STEAM]
|
||||
[--timeout TIMEOUT]
|
||||
[--external-addons EXTERNAL_ADDONS]
|
||||
[--silent-workbench | --exit-after-init]
|
||||
[--continue-on-failure]
|
||||
test_native_package.py: error: argument --exit-after-init: not allowed with argument --silent-workbench
|
||||
................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 48 tests in 12.269s
|
||||
|
||||
OK
|
||||
.......
|
||||
----------------------------------------------------------------------
|
||||
Ran 7 tests in 0.276s
|
||||
|
||||
OK
|
||||
..............
|
||||
----------------------------------------------------------------------
|
||||
Ran 14 tests in 2.321s
|
||||
|
||||
OK
|
||||
....
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 0.333s
|
||||
|
||||
OK
|
||||
....
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 0.062s
|
||||
|
||||
OK
|
||||
PASS: actual finite-courier age, token, exact ownership/callback and delivered-status admission reject stale, replayed, captured, canceled and ambiguous work
|
||||
PASS: actual native-gun ownership gate rejects player/foreign/replaced/dead occupant, faction change, missing seat and missing registry
|
||||
PASS: four-battery courier selection preserves pending trip/report/transfer identity, skips unavailable crews, and selects the next depleted battery without new stock
|
||||
PASS: 64 bounded distinct storage candidates; native gates, five-store barrier and finite-stock ownership retained; native placement pending
|
||||
PASS: 128 coarse+80 local refinement+169 airport grid candidates retain all native clearance gates; real terrain untested
|
||||
PASS: actual prison registration/crossing policies reject missing/duplicate/destroyed initial gate, incomplete ownership/scan, outside-only body, jumps and stale samples; physical exit independent of later gate damage
|
||||
PASS: actual prison door execution blocks direct AI/UI bypass while locked and delegates unchanged native action once after unlock and permission approval
|
||||
..................
|
||||
----------------------------------------------------------------------
|
||||
Ran 18 tests in 2.273s
|
||||
|
||||
OK
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 1.232s
|
||||
|
||||
OK
|
||||
PASS: native local-admission snapshot rejects changed life/key/body/participant/pending state; authentication is not simulated
|
||||
PASS: actual mortar report ledger prevents duplicate response after cancellation, expiry and interleaved reports; native scheduler separate
|
||||
.........
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 0.014s
|
||||
|
||||
OK
|
||||
....
|
||||
----------------------------------------------------------------------
|
||||
Ran 4 tests in 0.166s
|
||||
|
||||
OK
|
||||
PASS: actual aim renewal requires fresh same-report solve and original-command equivalence; native firing untested
|
||||
........
|
||||
----------------------------------------------------------------------
|
||||
Ran 8 tests in 0.013s
|
||||
|
||||
OK
|
||||
PASS: actual startup/generation/ownership/timeout/callback policies and native-counter wait; integration preserves one-shot allocation and pending-crew cancellation
|
||||
PASS: rapid mortar cycle counts eight physical rounds once and waits for native completion without a ninth aim or shell
|
||||
PASS: actual probe binds native events to fresh immutable commits, permits delayed emission, rejects unrelated expiry closure and premature stop
|
||||
PASS: actual noSplash Load body requires both explicit diagnostic and noSplash, preserves vanilla otherwise, and handles repeated Load/reload
|
||||
PASS: actual fixture method permits one native resilience operation and restores either prior protection state, including failure paths
|
||||
PASS: actual safe-exit boundary policy, native action/door selection, stop/cache cleanup, separate old mechanism and opt-in runner contracts
|
||||
PASS: actual one-shot deadline/stability policies and preparation ownership, fuel, cleanup integration contracts
|
||||
PASS: pending-only cancellation retires copied instance intent, preserves physical/control actors, and stops once
|
||||
PASS: actual short-cast hit, upward support normal, no self support and no dynamic support
|
||||
PASS: actual committed-ticket structure preserves reservation after death, rejects missing bodies/seats and ends at observation expiry
|
||||
PASS: actual pending callback expires an empty-server reservation once, preserves its full lease, and cancels on completion/Stop
|
||||
PASS: rescue lease expiry/reordering, fresh five-second settling, independent rescue ranges and grounded upright aircraft motion boundaries
|
||||
PASS: requested guard population requires complete physical conscious membership before deadline
|
||||
......................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 38 tests in 0.018s
|
||||
|
||||
OK
|
||||
..........
|
||||
----------------------------------------------------------------------
|
||||
Ran 10 tests in 0.002s
|
||||
|
||||
OK
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 0.956s
|
||||
|
||||
OK
|
||||
PASS: authored radio/optional-site bounds and physical horizontal/vertical boundaries
|
||||
...
|
||||
----------------------------------------------------------------------
|
||||
Ran 3 tests in 0.001s
|
||||
|
||||
OK
|
||||
PASS: all phase transitions, terminal states, defence boundaries, stale/future observations, intel discovery
|
||||
PASS: Core document-discovery alias, companion-only alias exclusion, strict integer parsing and setting boundaries
|
||||
PASS: player admission phase/life/identity/controller matrix, preload displacement limits, pending reservation overlap and owner exclusion
|
||||
PASS: actual gate and pre-inventory document guards reject noncanonical/faction/life/disconnect/server mismatches; canonical reconnect and unconscious carried intel preserved
|
||||
PASS: WB-only native fault injection restores both body mutations before checks/returns and requires eligible held-document negative/positive proof; runtime pending
|
||||
PASS: actual discovery coordinates disclose stable 500m cell center until identified, then exact point, including negative/boundary coordinates
|
||||
PASS: actual local admission context/selection/latch, same-round late identity, replacement/mode failure, fresh round and untouched network path
|
||||
PASS: prison search packs 16 unique 3m-spaced inside-wall centers, prioritizes inner/edge positions and never bypasses clearance
|
||||
PASS: physical body occupancy rejects overlap, permits diagonal neighboring slots, and excludes own body and unrelated broad-phase bounds
|
||||
PASS: recovery state excludes dead bodies, preserves reservations, requires controlled rescuers and distinguishes empty/all-dead teams
|
||||
PASS: authority-scoped slow recovery, bleeding pauses resilience, medicine unaffected, player-only lethal damage cap without healing
|
||||
PASS: bleeding severity survives low health, retains armour, causes no knockout and restores the actual damage/blood-loss cap
|
||||
PASS: viable passive recovery survives native delay; bleeding, disabled/full effects and low-blood resilience do not block defeat
|
||||
PASS: every minute round-trips, malformed clocks rejected, defaults limited to added keys, progression bounds and day duration aligned
|
||||
PASS: native settings policy matches calendar boundaries 1900-2050, date/profile parsing is strict, authored defaults preserve old worlds
|
||||
PASS: view-distance bounds, default, save failures, command parsing, temporary ownership, server/platform limits and lifecycle wiring
|
||||
.....
|
||||
----------------------------------------------------------------------
|
||||
Ran 5 tests in 0.616s
|
||||
|
||||
OK
|
||||
.
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 0.428s
|
||||
|
||||
OK
|
||||
PASS: radio authorization/discovery/phase matrix, exact distance limits, defender handover, interruption, empty samples, clock regression and duration boundary
|
||||
PASS: actual radio feedback policy, initial wait, interruption persistence, resumption and terminal/new-round reset
|
||||
...............
|
||||
----------------------------------------------------------------------
|
||||
Ran 15 tests in 2.278s
|
||||
|
||||
OK
|
||||
..............................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 46 tests in 0.937s
|
||||
|
||||
OK
|
||||
PASS: legacy values preserved, unsupported fields reported, invalid data rejected, existing files protected, runtime bounds aligned
|
||||
PASS: failed initial settings promotion leaves defaults writable after restart; prior/fallback saves survive copy, readback and mismatch faults
|
||||
PASS: real-carrier shortest-hop paths, 500m boundary, three-hop cap, no-manpack failure, three-second originating-call interruption, unchanged downlink hop timing, completed-hop survival, interrupted final uplink, radio loss, capture, motion, timeout, reset and network bounds
|
||||
PASS: migrated aircraft availability policy (controller migration still pending)
|
||||
PASS: migrated salvo offsets are deterministic, spread and bounded (native firing and complete salvo qualification are separate)
|
||||
PASS: 33 prefabs have unique saved root entity IDs
|
||||
PASS: 299 original script entries tracked across 18 unfinished responsibilities
|
||||
PASS: 1 isolated addons, acyclic dependencies, 54 unique resources, exact vanilla/authorized external references
|
||||
All repository checks passed. Native compilation and multiplayer tests are separate requirements.
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"scope": "Core admission and report-driven HQ correctness; no new package or release",
|
||||
"regression_programs": 251,
|
||||
"full_suite_passed": true,
|
||||
"reproduced_fixes": [
|
||||
"Expired scene ticket now rejects despite delayed native preload completion; no actor assignment on timeout",
|
||||
"Containment delivery rechecks precision authorization while preserving previous task on refusal",
|
||||
"Planner requires actual valid heading rather than merely HasVelocity",
|
||||
"Eligible original mounted vehicle contributes its current physical position to detached status; invalid roots never queried",
|
||||
"Negative search requires an original fit on-foot member physically present; ineligible gaps reset continuous thirty-second dwell"
|
||||
],
|
||||
"independent_review": "Production guards reviewed; planner and delayed admission have archived red-before/green-after logs. Mounted position and physical Sweep exact-patch-copy regressions pass.",
|
||||
"native": {
|
||||
"evidence": "../native-2026-10-01-mission-hq-fixes/report.json",
|
||||
"fixture": "normal-escape-route",
|
||||
"assertions": 55,
|
||||
"completions": 1,
|
||||
"script_or_runtime_failures": 0,
|
||||
"installed_errors": 13,
|
||||
"strict_qualified": false,
|
||||
"source_manifest_sha256": "0682325f7bb023779885c83b7e1998458d19420c98895c02eb4436979e3053d9",
|
||||
"source_external_unchanged": true,
|
||||
"cleanup_confirmed": true,
|
||||
"scope": "Scripted normal generated route through lockpick, carried intel, interrupted radio defence, physical helicopter occupancy, victory and result screen; not human input, remote multiplayer or flight skill."
|
||||
},
|
||||
"preservation": {
|
||||
"preexisting_unstaged_files": 52,
|
||||
"exception": "Only this increment test registration in tools/check.py; all other original bytes preserved.",
|
||||
"reference_sources_unchanged": 533,
|
||||
"packages_unchanged": true
|
||||
},
|
||||
"mounted_transfer_proposal": "mounted-transfer-proposal/INTEGRATION.txt; deliberately not applied to production",
|
||||
"remaining": [
|
||||
"Remote stalled-preload and reconnect testing",
|
||||
"Ordinary player completion and multiplayer",
|
||||
"Mounted courier pickup/coordinator and physical two-way rearm",
|
||||
"Measured equal-workload performance",
|
||||
"Strict native packaging and release qualification"
|
||||
],
|
||||
"source_sha256": {
|
||||
"addons/core/Scripts/Game/ERR/00_Core/ERR_SpawnFinalization.c": "c949642366ad124dd2abc4111cd598eb94aa257fbae01b6fb3a0f1882a23e83e",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQ.c": "810aa21406cd6bfb3ade1e0dd4d1c03961503d662c24b8b577ebff06e4f74b7d",
|
||||
"addons/core/Scripts/Game/ERR/10_AI/ERR_HQStatusSampler.c": "59a026529c9189c7f45c8e9f9f55677377a9b27fef4e97365daa72702bced11e",
|
||||
"tests/test_spawn_scene.py": "d89ef752906c1cf27c4cc7292997a4d793ddb3b56a6dfbdeff837978350167be",
|
||||
"tests/test_spawn_preload_timeout.py": "db3a3aa42c20f047da90cac6755cb283d15cb3de6a22a57a6e1f352e9b4511dc",
|
||||
"tests/test_hq_delivered_task.py": "122ea0ff988abd30820f2854011c42846cc3ab1c95c94f54849269c44de3b210",
|
||||
"tests/test_hq_status_sampler.py": "b238cc69888b2c0ff82abfaa170b062cb6ec355715135b2ce43abd80376e8972",
|
||||
"tests/test_hq_uplink_fairness.py": "cf6de4c5bad2a288689f3d9fe4c7da6946ee21d8ddace4cd5388e57562925ecc",
|
||||
"tests/test_hq_pursuit.py": "7ccbf51c7317097d9db6a66cc5be4bec67e542187f0fce5b4f3750bdc4311733"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
PASS: actual scene deadline overrides delayed native preload only for rejection; late completion cannot assign, ordinary verified admission preserved
|
||||
@@ -0,0 +1,19 @@
|
||||
check: /tmp/err-policy-yptms2ne/check.cpp:102: int main(): Assertion `h.CanFinalize_S(&request,&data,&actor)' failed.
|
||||
Traceback (most recent call last):
|
||||
File "/tmp/erri-spawn-preload-timeout/tests/test_spawn_preload_timeout.py", line 20, in <module>
|
||||
run(r'''
|
||||
~~~^^^^^
|
||||
#include <cassert>
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
...<66 lines>...
|
||||
}
|
||||
^
|
||||
''')
|
||||
^^^^
|
||||
File "/home/jakub/devel/escapistsrereintroduced/tests/policy_harness.py", line 14, in run
|
||||
subprocess.run([str(p/'check')],check=True)
|
||||
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/usr/lib/python3.14/subprocess.py", line 578, in run
|
||||
raise CalledProcessError(retcode, process.args,
|
||||
output=stdout, stderr=stderr)
|
||||
subprocess.CalledProcessError: Command '['/tmp/err-policy-yptms2ne/check']' died with <Signals.SIGABRT: 6>.
|
||||
Reference in New Issue
Block a user