Build independent Everon successor foundation and native regressions
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
// A radio's category is protected in the stock gadget component.
|
||||
modded class SCR_RadioComponent
|
||||
{
|
||||
bool ERR_IsHQManpack()
|
||||
{
|
||||
return m_iRadioCategory == ERadioCategory.MANPACK;
|
||||
}
|
||||
}
|
||||
|
||||
class ERR_HQRadio
|
||||
{
|
||||
// 0: no radio, 1: basic radio, 2: manpack. Inventory is checked live.
|
||||
static int Capability(IEntity character)
|
||||
{
|
||||
if (!ERR_Actors.CanFight(character))
|
||||
return 0;
|
||||
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(character.FindComponent(InventoryStorageManagerComponent));
|
||||
if (!inventory)
|
||||
return 0;
|
||||
array<IEntity> items = {};
|
||||
inventory.GetItems(items);
|
||||
int result;
|
||||
foreach (IEntity item : items)
|
||||
{
|
||||
if (!item || !item.FindComponent(BaseRadioComponent))
|
||||
continue;
|
||||
result = 1;
|
||||
SCR_RadioComponent gadget = SCR_RadioComponent.Cast(item.FindComponent(SCR_RadioComponent));
|
||||
if (gadget && gadget.ERR_IsHQManpack())
|
||||
return 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// HQ uses entity identity only for matching observations, never for its origin.
|
||||
// Visible details are captured at intake and copied as scalar snapshots.
|
||||
// Reports and orders contain immutable observed coordinates and timestamps.
|
||||
class ERR_HQReport
|
||||
{
|
||||
int MessageId;
|
||||
IEntity Target;
|
||||
SCR_AIGroup Source;
|
||||
vector Position;
|
||||
vector Velocity;
|
||||
float ObservedAt = -1;
|
||||
float LastSent = -60000;
|
||||
float PerceptionStamp = -1;
|
||||
bool HasVelocity;
|
||||
bool Engaged;
|
||||
bool Distress;
|
||||
int SeenEscapists = -1;
|
||||
string TravelMode = "unknown";
|
||||
string SeenWeapons = "unknown";
|
||||
float DetailsObservedAt = -1;
|
||||
|
||||
ERR_HQReport Snapshot()
|
||||
{
|
||||
ERR_HQReport copy = new ERR_HQReport();
|
||||
copy.MessageId = MessageId;
|
||||
copy.Target = Target;
|
||||
copy.Source = Source;
|
||||
copy.Position = Position;
|
||||
copy.Velocity = Velocity;
|
||||
copy.ObservedAt = ObservedAt;
|
||||
copy.Engaged = Engaged;
|
||||
copy.Distress = Distress;
|
||||
copy.HasVelocity = HasVelocity;
|
||||
copy.SeenEscapists = SeenEscapists;
|
||||
copy.TravelMode = TravelMode;
|
||||
copy.SeenWeapons = SeenWeapons;
|
||||
copy.DetailsObservedAt = DetailsObservedAt;
|
||||
return copy;
|
||||
}
|
||||
|
||||
string TravelDirection()
|
||||
{
|
||||
if (!HasVelocity)
|
||||
return "unknown";
|
||||
if (Velocity.Length() < 0.5)
|
||||
return "stationary";
|
||||
float x = Math.AbsFloat(Velocity[0]);
|
||||
float z = Math.AbsFloat(Velocity[2]);
|
||||
string northSouth = "N";
|
||||
string eastWest = "E";
|
||||
if (Velocity[2] < 0)
|
||||
northSouth = "S";
|
||||
if (Velocity[0] < 0)
|
||||
eastWest = "W";
|
||||
if (x < z * 0.414214)
|
||||
return northSouth;
|
||||
if (z < x * 0.414214)
|
||||
return eastWest;
|
||||
return northSouth + eastWest;
|
||||
}
|
||||
|
||||
string Description(float now, bool brief = false)
|
||||
{
|
||||
if (Distress)
|
||||
return string.Format("Distress at friendly X=%1 Z=%2; enemy details unknown (%3s ago)", Math.Round(Position[0]), Math.Round(Position[2]), Math.Round(Math.Max(0, now - ObservedAt) / 1000));
|
||||
string count = "count unknown";
|
||||
if (SeenEscapists >= 0)
|
||||
count = "at least " + SeenEscapists.ToString() + " spotted nearby";
|
||||
string motion = "speed/direction unknown";
|
||||
if (HasVelocity)
|
||||
{
|
||||
float speed = Math.Round(Velocity.Length() * 10) / 10.0;
|
||||
float azimuth = Math.Atan2(Velocity[0], Velocity[2]) * Math.RAD2DEG;
|
||||
if (azimuth < 0)
|
||||
azimuth += 360;
|
||||
int heading = Math.Round(azimuth);
|
||||
motion = string.Format("%1 km/h, azimuth %2 degrees (%3)", Math.Round(speed * 3.6), heading % 360, TravelDirection());
|
||||
}
|
||||
string details = count + "; " + TravelMode + "; " + motion + "; seen weapons: " + SeenWeapons;
|
||||
if (brief)
|
||||
return details;
|
||||
string velocity = "unknown";
|
||||
if (HasVelocity)
|
||||
velocity = string.Format("[%1,%2] m/s", Math.Round(Velocity[0] * 10) / 10.0, Math.Round(Velocity[2] * 10) / 10.0);
|
||||
return string.Format("X=%1 Z=%2: %3; vector X/Z=%4 (%5s ago)", Math.Round(Position[0]), Math.Round(Position[2]), details, velocity, Math.Round(Math.Max(0, now - ObservedAt) / 1000));
|
||||
}
|
||||
|
||||
static vector Predict(vector position, vector velocity, float seconds)
|
||||
{
|
||||
vector offset = velocity * Math.Clamp(seconds, 0, 20);
|
||||
offset[1] = 0;
|
||||
if (offset.Length() > 300)
|
||||
offset = offset.Normalized() * 300;
|
||||
return position + offset;
|
||||
}
|
||||
|
||||
int Priority(float now)
|
||||
{
|
||||
if (Distress)
|
||||
return 0;
|
||||
if (now - ObservedAt <= 15000)
|
||||
{
|
||||
if (Engaged)
|
||||
return 3;
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user