Harden base progression and cleanup; validate finite physical resupply
This commit is contained in:
@@ -12,10 +12,12 @@ class ERR_HQUnit
|
||||
ref ERR_HQReport Assignment;
|
||||
AIWaypoint Waypoint;
|
||||
bool ReservedForSupport;
|
||||
int LogisticsReservation;
|
||||
ref ERR_MortarSupplyStatus PendingSupplyStatus;
|
||||
|
||||
bool Eligible(ERR_GameMode mode)
|
||||
{
|
||||
if (ReservedForSupport || !Group || !Utility || Group.GetPlayerCount(true) > 0 || Group.IsSlave() || Group.GetFaction() != mode.EnemyFaction()) return false;
|
||||
if (ReservedForSupport || LogisticsReservation > 0 || !Group || !Utility || Group.GetPlayerCount(true) > 0 || Group.IsSlave() || Group.GetFaction() != mode.EnemyFaction()) return false;
|
||||
array<AIAgent> agents = {};
|
||||
Group.GetAgents(agents);
|
||||
bool survivor;
|
||||
@@ -46,6 +48,7 @@ class ERR_HQ : ERR_CommandService
|
||||
{
|
||||
protected ERR_GameMode m_Mode;
|
||||
protected ref ERR_MortarSystem m_Mortars;
|
||||
protected ref ERR_MortarLogistics m_Logistics;
|
||||
protected ref array<ref ERR_HQUnit> m_Units = {};
|
||||
protected ref array<ref ERR_HQReport> m_Contacts = {};
|
||||
protected ref ERR_HQNetwork m_Network = new ERR_HQNetwork();
|
||||
@@ -54,7 +57,7 @@ class ERR_HQ : ERR_CommandService
|
||||
protected float m_NextNetwork;
|
||||
protected float m_NextAssignment;
|
||||
|
||||
void ERR_HQ(ERR_GameMode mode) { m_Mode = mode; m_Mortars = new ERR_MortarSystem(this); }
|
||||
void ERR_HQ(ERR_GameMode mode) { m_Mode = mode; m_Mortars = new ERR_MortarSystem(this); m_Logistics = new ERR_MortarLogistics(this, mode); }
|
||||
static ERR_HQ Get()
|
||||
{
|
||||
ERR_GameMode mode = ERR_GameMode.Get();
|
||||
@@ -72,7 +75,8 @@ class ERR_HQ : ERR_CommandService
|
||||
if (hq) hq.Journal().Write(kind, message, messageId);
|
||||
}
|
||||
ERR_MortarSystem Mortars() { return m_Mortars; }
|
||||
bool PrepareSupport() { return m_Mortars.Prepare(); }
|
||||
bool PrepareSupport() { return m_Mortars.Prepare() && m_Logistics.Prepare(); }
|
||||
ERR_MortarLogistics Logistics() { return m_Logistics; }
|
||||
void ReserveGroup(SCR_AIGroup group)
|
||||
{
|
||||
foreach (ERR_HQUnit unit : m_Units)
|
||||
@@ -82,6 +86,48 @@ class ERR_HQ : ERR_CommandService
|
||||
unit.ReservedForSupport = true;
|
||||
}
|
||||
}
|
||||
// Temporary reservations never alter the permanent support reservation.
|
||||
int LogisticsToken(SCR_AIGroup group)
|
||||
{
|
||||
foreach (ERR_HQUnit unit : m_Units) if (unit.Group == group) return unit.LogisticsReservation;
|
||||
return 0;
|
||||
}
|
||||
bool ReserveLogistics(SCR_AIGroup group, int token)
|
||||
{
|
||||
if (!Replication.IsServer() || token <= 0 || !MissionActive()) return false;
|
||||
foreach (ERR_HQUnit unit : m_Units)
|
||||
{
|
||||
if (unit.Group != group || !unit.Eligible(m_Mode) || !unit.Radio || unit.Assignment || unit.PendingOrder || unit.Downlink || unit.Waypoint) continue;
|
||||
if (unit.Utility.m_Perception && !unit.Utility.m_Perception.m_aTargets.IsEmpty()) continue;
|
||||
unit.LogisticsReservation = token;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ReleaseLogistics(SCR_AIGroup group, int token)
|
||||
{
|
||||
foreach (ERR_HQUnit unit : m_Units)
|
||||
if (unit.Group == group && unit.LogisticsReservation == token) unit.LogisticsReservation = 0;
|
||||
}
|
||||
bool QueueSupplyStatus(ERR_MortarBattery battery, float now)
|
||||
{
|
||||
if (!Replication.IsServer() || !MissionActive() || !battery || !battery.StartupActivated || !battery.Operational() || !m_Logistics.CanSample(battery) || !ERR_MortarLogisticsRules.Need(battery.CountShells())) return false;
|
||||
foreach (ERR_HQUnit unit : m_Units)
|
||||
{
|
||||
if (unit.Group != battery.Group || unit.Uplink || !unit.Radio || unit.Radio != battery.RadioOperator) continue;
|
||||
ERR_HQRoute route = m_Network.Route(unit.Radio);
|
||||
if (!route) return false;
|
||||
ERR_MortarSupplyStatus report = new ERR_MortarSupplyStatus();
|
||||
report.Group = battery.Group; report.Gun = battery.Gun; report.Position = battery.Gun.GetOrigin();
|
||||
report.Shells = battery.CountShells(); report.ObservedAt = now; report.MessageId = m_Journal.Message();
|
||||
route.MessageId = report.MessageId;
|
||||
route.Payload = string.Format("mortar supply status; usable HE=%1; position=%2; sampled=%3", report.Shells, report.Position, report.ObservedAt);
|
||||
unit.PendingSupplyStatus = report; unit.Uplink = route;
|
||||
m_Journal.Write("SUPPLY REPORT", route.Payload, route.MessageId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void PhysicalForces(out array<IEntity> entities)
|
||||
{
|
||||
entities.Clear();
|
||||
@@ -131,7 +177,7 @@ class ERR_HQ : ERR_CommandService
|
||||
ERR_HQJournal Journal() { return m_Journal; }
|
||||
string Status()
|
||||
{
|
||||
return string.Format("HQ: %1 groups, %2 delivered contacts, %3 assignments", m_Units.Count(), m_Contacts.Count(), Assigned()) + "; " + m_Mortars.Status();
|
||||
return string.Format("HQ: %1 groups, %2 delivered contacts, %3 assignments", m_Units.Count(), m_Contacts.Count(), Assigned()) + "; " + m_Mortars.Status() + "; " + m_Logistics.Status();
|
||||
}
|
||||
|
||||
override void RegisterGroup(SCR_AIGroup group)
|
||||
@@ -304,8 +350,12 @@ class ERR_HQ : ERR_CommandService
|
||||
if (unit.Uplink)
|
||||
{
|
||||
int delivered = unit.Uplink.Advance(now, m_Journal);
|
||||
if (delivered == 1) Accept(unit.PendingReport, now);
|
||||
if (delivered != 0) { unit.Uplink = null; unit.PendingReport = null; }
|
||||
if (delivered == 1)
|
||||
{
|
||||
if (unit.PendingSupplyStatus) m_Logistics.Receive(unit.PendingSupplyStatus, now);
|
||||
else Accept(unit.PendingReport, now);
|
||||
}
|
||||
if (delivered != 0) { unit.Uplink = null; unit.PendingReport = null; unit.PendingSupplyStatus = null; }
|
||||
}
|
||||
if (unit.Downlink)
|
||||
{
|
||||
@@ -317,12 +367,14 @@ class ERR_HQ : ERR_CommandService
|
||||
Observe(unit, now);
|
||||
}
|
||||
if (now >= m_NextAssignment) { Assign(now); m_NextAssignment = now + 5000; }
|
||||
m_Logistics.Tick(now);
|
||||
m_Mortars.Tick(now);
|
||||
m_Journal.Flush();
|
||||
}
|
||||
|
||||
override void Stop()
|
||||
{
|
||||
m_Logistics.Stop();
|
||||
m_Mortars.Stop();
|
||||
foreach (ERR_HQUnit unit : m_Units) unit.Release();
|
||||
m_Units.Clear();
|
||||
|
||||
Reference in New Issue
Block a user