Harden base progression and cleanup; validate finite physical resupply
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
class ERR_MortarCourierCallback : ScriptedInventoryOperationCallback
|
||||
{
|
||||
ERR_MortarCourierTransfer Transfer;
|
||||
protected override void OnComplete() { if (Transfer) Transfer.Acknowledge(true); }
|
||||
protected override void OnFailed() { if (Transfer) Transfer.Acknowledge(false); }
|
||||
}
|
||||
// One exact native move belonging to one courier trip. Never retries ambiguous work.
|
||||
class ERR_MortarCourierTransfer
|
||||
{
|
||||
protected ERR_MortarLogistics m_Service;
|
||||
protected IEntity m_Shell;
|
||||
protected IEntity m_From;
|
||||
protected IEntity m_To;
|
||||
protected InventoryStorageManagerComponent m_Source;
|
||||
protected InventoryStorageManagerComponent m_Destination;
|
||||
protected BaseInventoryStorageComponent m_Storage;
|
||||
protected ref ERR_MortarCourierCallback m_Callback;
|
||||
protected int m_Trip;
|
||||
protected int m_Acknowledgement;
|
||||
protected float m_Deadline;
|
||||
protected bool m_Accepted;
|
||||
protected bool m_Invalidated;
|
||||
protected bool m_Resolved;
|
||||
void ERR_MortarCourierTransfer(ERR_MortarLogistics service, int trip, IEntity shell, IEntity from, IEntity to, BaseInventoryStorageComponent storage, float now)
|
||||
{
|
||||
m_Service = service; m_Trip = trip; m_Shell = shell; m_From = from; m_To = to; m_Storage = storage; m_Deadline = now + 8000;
|
||||
m_Source = InventoryStorageManagerComponent.Cast(from.FindComponent(InventoryStorageManagerComponent));
|
||||
m_Destination = InventoryStorageManagerComponent.Cast(to.FindComponent(InventoryStorageManagerComponent));
|
||||
}
|
||||
static bool Proven(bool complete, bool source, bool destination, bool exact) { return complete && !source && destination && exact; }
|
||||
protected bool Contains(InventoryStorageManagerComponent inventory)
|
||||
{
|
||||
if (!inventory || !m_Shell) return false;
|
||||
array<IEntity> items = {}; ERR_Inventory.Items(inventory, items); return items.Contains(m_Shell);
|
||||
}
|
||||
void Acknowledge(bool success)
|
||||
{
|
||||
if (m_Acknowledgement != 0) return;
|
||||
if (success) m_Acknowledgement = 1;
|
||||
else m_Acknowledgement = -1;
|
||||
}
|
||||
bool Begin(float now)
|
||||
{
|
||||
if (m_Callback || !Replication.IsServer() || !m_Service.TransferAllowed(m_Trip, m_Shell, m_From, m_To, now) || !Contains(m_Source) || Contains(m_Destination)) return false;
|
||||
m_Callback = new ERR_MortarCourierCallback(); m_Callback.Transfer = this;
|
||||
m_Accepted = m_Source.TryMoveItemToStorage(m_Shell, m_Storage, -1, m_Callback);
|
||||
if (!m_Accepted) { Acknowledge(false); m_Resolved = true; }
|
||||
return m_Accepted;
|
||||
}
|
||||
void Invalidate() { m_Invalidated = true; }
|
||||
bool Unresolved() { return m_Accepted && !m_Resolved; }
|
||||
IEntity Shell() { return m_Shell; }
|
||||
int Poll(float now)
|
||||
{
|
||||
// A deleted exact entity cannot complete later; close as a permanent loss.
|
||||
if (!m_Shell) { m_Resolved = true; m_Invalidated = true; return -1; }
|
||||
bool exact;
|
||||
InventoryItemComponent item;
|
||||
if (m_Shell) item = InventoryItemComponent.Cast(m_Shell.FindComponent(InventoryItemComponent));
|
||||
if (item && item.GetParentSlot()) exact = item.GetParentSlot().GetStorage() == m_Storage;
|
||||
bool proven = Proven(m_Acknowledgement == 1, Contains(m_Source), Contains(m_Destination), exact);
|
||||
if (proven || m_Acknowledgement < 0) m_Resolved = true;
|
||||
if (m_Invalidated || now >= m_Deadline || !m_Service.TransferAllowed(m_Trip, m_Shell, m_From, m_To, now)) { m_Invalidated = true; return -1; }
|
||||
if (proven) return 1;
|
||||
if (m_Acknowledgement < 0 || !m_Accepted) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user