Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
82 lines
3.8 KiB
C
82 lines
3.8 KiB
C
// Mission-owned finite attempt history. Registration and assignment release
|
|
// never reset it. Values are copied before native work; no live enemy queries.
|
|
class ERR_EngineerMinePost
|
|
{
|
|
ref ERR_ForceRecord Record;
|
|
SCR_AIGroup Group;
|
|
string Source;
|
|
int Strength;
|
|
ref ERR_HQTask Task;
|
|
ref ERR_HQReport Assignment;
|
|
int MessageId;
|
|
int BeliefId;
|
|
int Revision;
|
|
float QueuedAt;
|
|
float ObservedAt;
|
|
vector Post;
|
|
bool HasSite;
|
|
vector Site;
|
|
}
|
|
class ERR_EngineerMinePosts
|
|
{
|
|
protected ref array<ref ERR_EngineerMinePost> m_Posts = {};
|
|
int Count() { return m_Posts.Count(); }
|
|
bool Eligible(ERR_ForceRecord record, string source, ERR_HQTask task, ERR_HQReport assignment, float now)
|
|
{
|
|
if (!record || !record.Group || !record.Physical || record.Eliminated || source.IsEmpty() || record.SourceId != source) return false;
|
|
if (record.InitialStrength < 1 || record.InitialStrength > 32 || !task || !assignment || m_Posts.Count() >= 32) return false;
|
|
if (!task.RoadIntercept || task.ReleaseOnly || task.Investigation() || !task.SecuritySite.IsEmpty()) return false;
|
|
if (task.BeliefId <= 0 || task.BeliefRevision <= 0 || assignment.MessageId <= 0) return false;
|
|
if (!ERR_ForceRules.Finite(now) || !ERR_ForceRules.Finite(task.QueuedAt) || !ERR_ForceRules.Finite(task.ExpiresAt)
|
|
|| !ERR_ForceRules.Finite(assignment.ObservedAt) || assignment.ObservedAt < 0 || task.QueuedAt < assignment.ObservedAt
|
|
|| task.QueuedAt > now || now >= task.ExpiresAt) return false;
|
|
if (!ERR_ForceRules.FiniteVector(task.Destination) || !ERR_ForceRules.FiniteVector(assignment.Position)) return false;
|
|
int used;
|
|
foreach (ERR_EngineerMinePost previous : m_Posts)
|
|
{
|
|
if (!previous) return false;
|
|
float separation = vector.DistanceXZ(task.Destination, previous.Post);
|
|
if (!ERR_ForceRules.Finite(separation) || separation <= 160) return false;
|
|
if (previous.Task == task || previous.Assignment == assignment) return false;
|
|
// Same source or physical group under another record cannot acquire quota.
|
|
if (previous.Record != record)
|
|
{
|
|
if (previous.Source == source || previous.Group == record.Group) return false;
|
|
continue;
|
|
}
|
|
if (previous.Source != source || previous.Group != record.Group || previous.Strength != record.InitialStrength) return false;
|
|
used++;
|
|
if (used >= 5 || task.QueuedAt <= previous.QueuedAt || assignment.ObservedAt <= previous.ObservedAt
|
|
|| assignment.MessageId == previous.MessageId) return false;
|
|
if (task.BeliefId == previous.BeliefId && task.BeliefRevision <= previous.Revision) return false;
|
|
}
|
|
return true;
|
|
}
|
|
// Returns immutable entry index or -1; a refused site/item still consumes it.
|
|
int Consume(ERR_ForceRecord record, string source, ERR_HQTask task, ERR_HQReport assignment, float now)
|
|
{
|
|
if (!Eligible(record, source, task, assignment, now)) return -1;
|
|
ERR_EngineerMinePost entry = new ERR_EngineerMinePost();
|
|
entry.Record = record; entry.Group = record.Group; entry.Source = source; entry.Strength = record.InitialStrength;
|
|
entry.Task = task; entry.Assignment = assignment; entry.MessageId = assignment.MessageId;
|
|
entry.BeliefId = task.BeliefId; entry.Revision = task.BeliefRevision;
|
|
entry.QueuedAt = task.QueuedAt; entry.ObservedAt = assignment.ObservedAt; entry.Post = task.Destination;
|
|
m_Posts.Insert(entry);
|
|
return m_Posts.Count() - 1;
|
|
}
|
|
bool RecordSite(int index, vector site)
|
|
{
|
|
if (index < 0 || index >= m_Posts.Count() || !ERR_ForceRules.FiniteVector(site)) return false;
|
|
ERR_EngineerMinePost entry = m_Posts[index];
|
|
if (!entry || entry.HasSite || !ERR_EngineerMineSite.InBand(entry.Post, site)) return false;
|
|
entry.Site = site; entry.HasSite = true;
|
|
return true;
|
|
}
|
|
void PriorSites(out array<vector> sites)
|
|
{
|
|
sites.Clear();
|
|
foreach (ERR_EngineerMinePost entry : m_Posts)
|
|
if (entry.HasSite) sites.Insert(entry.Site);
|
|
}
|
|
}
|