69 lines
3.2 KiB
C
69 lines
3.2 KiB
C
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;
|
|
}
|
|
}
|