Files
EscapistsReintroduced/addons/ai/Scripts/Game/ERR/ERR_MortarCourierTransfer.c
T

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;
}
}