84 lines
3.1 KiB
C
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.
|
|
}
|