Reconcile radio-delivered body and status casualties by original roster identity
This commit is contained in:
@@ -3,6 +3,10 @@
|
||||
class ERR_HQBodyCandidate
|
||||
{
|
||||
IEntity Corpse;
|
||||
ref ERR_HQStatusSampler Roster;
|
||||
string SourceId;
|
||||
int Slot = -1;
|
||||
int Strength;
|
||||
bool Confirmed;
|
||||
float ReportAfter;
|
||||
}
|
||||
@@ -67,9 +71,9 @@ class ERR_HQBodyObserver
|
||||
for (int i = m_Groups.Count() - 1; i >= 0; i--)
|
||||
if (!m_Groups[i].Group) m_Groups.Remove(i);
|
||||
}
|
||||
void RegisterGroup(SCR_AIGroup group)
|
||||
void RegisterGroup(SCR_AIGroup group, ERR_HQStatusSampler sampler)
|
||||
{
|
||||
if (!Replication.IsServer() || !OwnedPhysical(group)) return;
|
||||
if (!Replication.IsServer() || !OwnedPhysical(group) || !sampler || !sampler.OwnsRoster(group)) return;
|
||||
Prune();
|
||||
bool known;
|
||||
foreach (ERR_HQBodyScan scan : m_Groups) if (scan.Group == group) known = true;
|
||||
@@ -79,17 +83,18 @@ class ERR_HQBodyObserver
|
||||
ERR_HQBodyScan created = new ERR_HQBodyScan(); created.Group = group;
|
||||
m_Groups.Insert(created);
|
||||
}
|
||||
array<AIAgent> agents = {}; group.GetAgents(agents);
|
||||
for (int member = 0; member < agents.Count() && member < 32; member++)
|
||||
// Slot identity comes only from the immutable sampler bind, never current agent order.
|
||||
for (int member = 0; member < sampler.InitialStrength(); member++)
|
||||
{
|
||||
AIAgent agent = agents[member];
|
||||
if (!agent || !agent.GetControlledEntity()) continue;
|
||||
IEntity actor = agent.GetControlledEntity();
|
||||
IEntity actor = sampler.InitialMember(member);
|
||||
if (!sampler.CanAttribute(member, actor)) continue;
|
||||
bool found;
|
||||
foreach (ERR_HQBodyCandidate entry : m_Roster) if (entry.Corpse == actor) found = true;
|
||||
if (found) continue;
|
||||
if (m_Roster.Count() >= 128) { Cap(); return; }
|
||||
ERR_HQBodyCandidate candidate = new ERR_HQBodyCandidate(); candidate.Corpse = actor;
|
||||
candidate.Roster = sampler; candidate.SourceId = sampler.InitialSourceId();
|
||||
candidate.Slot = member; candidate.Strength = sampler.InitialStrength();
|
||||
m_Roster.Insert(candidate);
|
||||
}
|
||||
}
|
||||
@@ -171,6 +176,7 @@ class ERR_HQBodyObserver
|
||||
if (state.Cursor >= count) state.Cursor = 0;
|
||||
ERR_HQBodyCandidate candidate = m_Bodies[state.Cursor++];
|
||||
if (!candidate.Corpse || candidate.Confirmed || now < candidate.ReportAfter || !Dead(candidate.Corpse)) continue;
|
||||
if (!candidate.Roster || !candidate.Roster.CanAttribute(candidate.Slot, candidate.Corpse)) continue;
|
||||
for (int member = 0; member < agents.Count() && member < 32; member++)
|
||||
{
|
||||
if (m_Traces <= 0) return false;
|
||||
@@ -181,6 +187,8 @@ class ERR_HQBodyObserver
|
||||
report = new ERR_HQReport();
|
||||
report.Target = candidate.Corpse; report.Source = group;
|
||||
report.Position = position; report.ObservedAt = now; report.TravelMode = "body";
|
||||
report.CasualtySourceId = candidate.SourceId; report.CasualtySlot = candidate.Slot;
|
||||
report.CasualtyStrength = candidate.Strength;
|
||||
// Local throttling only. A lost radio call can be retried after fresh LOS.
|
||||
candidate.ReportAfter = now + 15000;
|
||||
return true;
|
||||
@@ -188,7 +196,7 @@ class ERR_HQBodyObserver
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Call only after a radio-delivered body snapshot was accepted by HQ memory.
|
||||
// Call only after the radio-delivered immutable body attribution was accepted by HQ.
|
||||
void ConfirmDelivered(IEntity body)
|
||||
{
|
||||
if (!Replication.IsServer() || !body) return;
|
||||
|
||||
Reference in New Issue
Block a user