Files
EscapistsReintroduced/addons/ai/Scripts/Game/ERR/ERR_InfantryAmmoAccess.c
T

63 lines
2.4 KiB
C

// Physical reach to authored donor storage contexts; no inventory mutation here.
class ERR_InfantryAmmoAccess
{
protected IEntity m_Donor;
protected IEntity m_Recipient;
// Exact hierarchy exclusion prevents the truck's own cargo shell or recipient
// equipment from occluding an interior-authored anchor. Other entities collide.
protected bool Filter(notnull IEntity entity)
{
return !ERR_ConvoyRules.PartOf(entity, m_Donor) && !ERR_ConvoyRules.PartOf(entity, m_Recipient);
}
static bool Points(Vehicle donor, out array<vector> points)
{
points = {};
if (!donor) return false;
ActionsManagerComponent manager = ActionsManagerComponent.Cast(donor.FindComponent(ActionsManagerComponent));
if (!manager || !manager.IsEnabled()) return false;
array<UserActionContext> contexts = {}; manager.GetContextList(contexts);
if (contexts.IsEmpty() || contexts.Count() > 64) return false;
foreach (UserActionContext context : contexts)
{
if (!context) return false;
array<BaseUserAction> actions = {}; context.GetActionsList(actions);
if (actions.Count() > 16) return false;
bool storage;
foreach (BaseUserAction action : actions)
if (action && action.GetOwner() == donor && SCR_OpenVehicleStorageAction.Cast(action)) storage = true;
if (!storage) continue;
vector matrix[4];
if (!context.GetTransformationWorld(matrix) || !ERR_ForceRules.FiniteVector(matrix[3])) return false;
points.Insert(matrix[3]);
}
return !points.IsEmpty();
}
bool Check(Vehicle donor, IEntity recipient)
{
ChimeraCharacter character = ChimeraCharacter.Cast(recipient);
if (!donor || !character || !GetGame() || !GetGame().GetWorld()) return false;
array<vector> points;
if (!Points(donor, points)) return false;
vector start = character.AimingPosition();
if (!ERR_ForceRules.FiniteVector(start)) return false;
m_Donor = donor; m_Recipient = recipient;
foreach (vector point : points)
{
float distance = vector.Distance(start, point);
if (!(distance >= 0.05 && distance <= 4)) continue;
TraceParam trace = new TraceParam();
trace.Start = start; trace.End = point;
trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
trace.LayerMask = TRACE_LAYER_CAMERA;
float fraction = GetGame().GetWorld().TraceMove(trace, Filter);
if (fraction == 1) return true;
}
return false;
}
static bool Clear(Vehicle donor, IEntity recipient)
{
ERR_InfantryAmmoAccess access = new ERR_InfantryAmmoAccess();
return access.Check(donor, recipient);
}
}