63 lines
2.4 KiB
C
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);
|
|
}
|
|
}
|