46 lines
2.0 KiB
C
46 lines
2.0 KiB
C
// Local sharing of an original squad sighting; only the ordinary radio route
|
|
// can deliver its immutable report to HQ. No observation or force is invented.
|
|
class ERR_HQLocalHandoff
|
|
{
|
|
static bool Valid(SCR_AIGroup source, ERR_HQStatusSampler roster, IEntity witness, ERR_HQRadioNode receiver)
|
|
{
|
|
ERR_GameMode mode = ERR_GameMode.Get();
|
|
if (!roster || !roster.OwnsRoster(source) || !receiver || receiver.Group == source || !receiver.Valid()) return false;
|
|
if (!ERR_EnemyEquipmentRules.Eligible(mode, source, witness) || !ERR_EnemyEquipmentRules.Eligible(mode, receiver.Group, receiver.Carrier)) return false;
|
|
int count = roster.InitialStrength();
|
|
if (count < 1 || count > 32) return false;
|
|
bool original;
|
|
for (int i = 0; i < count; i++)
|
|
if (roster.InitialMember(i) == witness && roster.CanAttribute(i, witness)) original = true;
|
|
if (!original) return false;
|
|
float distance = vector.Distance(witness.GetOrigin(), receiver.Carrier.GetOrigin());
|
|
return distance >= 0 && distance <= 100;
|
|
}
|
|
}
|
|
|
|
// Only a genuinely newer original sighting may be attempted. Old watermarks
|
|
// can expire because the observation capture itself admits at most 500ms age.
|
|
class ERR_HQObservationHistory
|
|
{
|
|
protected ref array<IEntity> m_Targets = {};
|
|
protected ref array<float> m_Times = {};
|
|
bool CanQueue(IEntity target, float observedAt, float now)
|
|
{
|
|
if (!target || !ERR_ForceRules.Finite(now) || !ERR_ForceRules.Finite(observedAt) || observedAt < 0 || now < observedAt || now - observedAt > 500) return false;
|
|
for (int i = m_Targets.Count() - 1; i >= 0; i--)
|
|
{
|
|
if (!m_Targets[i] || now - m_Times[i] > 120000) { m_Targets.Remove(i); m_Times.Remove(i); }
|
|
}
|
|
int index = m_Targets.Find(target);
|
|
if (index >= 0) return observedAt > m_Times[index];
|
|
return m_Targets.Count() < 64;
|
|
}
|
|
void Queued(IEntity target, float observedAt, float now)
|
|
{
|
|
if (!CanQueue(target, observedAt, now)) return;
|
|
int index = m_Targets.Find(target);
|
|
if (index >= 0) m_Times[index] = observedAt;
|
|
else { m_Targets.Insert(target); m_Times.Insert(observedAt); }
|
|
}
|
|
}
|