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

84 lines
3.1 KiB
C

// One mission-owned allocator. Reservations include every future native crew body.
class ERR_ConvoyReceipt
{
int Id;
string SourceId;
bool Consumed;
int OutstandingBodies = 19;
int OutstandingGroups = 6;
ref array<int> Records = {-1, -1, -1, -1, -1, -1};
}
class ERR_ConvoyPool
{
protected ERR_GameMode m_Mode;
protected int m_Limit;
protected ref array<ref ERR_ConvoyReceipt> m_Receipts = {};
void ERR_ConvoyPool(ERR_GameMode mode, int maxConvoys)
{
m_Mode = mode; m_Limit = Math.Clamp(maxConvoys, 0, 8);
}
static int CrewCount(int vehicle)
{
if (vehicle == 1) return 1;
if (vehicle == 2) return 9;
if (vehicle == 4) return 3;
if (vehicle == 0 || vehicle == 3 || vehicle == 5) return 2;
return 0;
}
protected bool Current()
{
return Replication.IsServer() && m_Mode && m_Mode == ERR_GameMode.Get() && m_Mode.Active() && m_Mode.Forces();
}
bool Owns(ERR_ConvoyReceipt receipt)
{
return receipt && m_Receipts.Contains(receipt);
}
int CommittedBodies()
{
if (!m_Mode || !m_Mode.Forces()) return 60;
int total;
ERR_ForceLedger ledger = m_Mode.Forces();
for (int i = 0; i < ledger.Count(); i++)
{
ERR_ForceRecord record = ledger.At(i);
if (record && record.Physical && !record.Eliminated) total += record.Strength;
}
foreach (ERR_ConvoyReceipt receipt : m_Receipts) total += receipt.OutstandingBodies;
return total;
}
protected int CommittedGroups()
{
int total = m_Mode.Forces().Count();
foreach (ERR_ConvoyReceipt receipt : m_Receipts) total += receipt.OutstandingGroups;
return total;
}
ERR_ConvoyReceipt Reserve(string sourceId)
{
if (!Current() || sourceId.IsEmpty() || sourceId.Length() > 64) return null;
foreach (ERR_ConvoyReceipt known : m_Receipts) if (known.SourceId == sourceId) return known;
if (m_Receipts.Count() >= m_Limit || CommittedBodies() + 19 > 60 || CommittedGroups() + 6 > 128) return null;
ERR_ConvoyReceipt receipt = new ERR_ConvoyReceipt(); receipt.Id = m_Receipts.Count() + 1; receipt.SourceId = sourceId;
m_Receipts.Insert(receipt);
return receipt;
}
bool Consume(ERR_ConvoyReceipt receipt)
{
if (!Current() || !Owns(receipt) || receipt.Consumed || CommittedBodies() > 60 || CommittedGroups() > 128) return false;
receipt.Consumed = true;
return true;
}
bool BindRecord(ERR_ConvoyReceipt receipt, int vehicle, ERR_ForceRecord record)
{
if (!Current() || !Owns(receipt) || !receipt.Consumed || vehicle < 0 || vehicle >= 6 || !record) return false;
if (receipt.Records[vehicle] >= 0) return receipt.Records[vehicle] == record.Id;
if (m_Mode.Forces().Find(record.Id) != record || record.Kind != ERR_ForceKind.CONVOY || !record.Group || !record.Physical || record.Eliminated) return false;
if (record.SourceId != receipt.SourceId + "-vehicle-" + vehicle.ToString() || record.InitialStrength != CrewCount(vehicle) || record.Strength != record.InitialStrength) return false;
receipt.Records[vehicle] = record.Id;
receipt.OutstandingBodies -= CrewCount(vehicle); receipt.OutstandingGroups--;
return true;
}
// There is intentionally no refund/reset method. A consumed startup attempt
// can retain partial native entities even when a later seat or ledger step fails.
}