using ProjectI.Combat;
using UnityEngine;
namespace ProjectI.Runs
{
/// Accepted foot/body volume, bounded sweep and solid-world visibility. Warps never create swept pickups.
public static class CorePickupRules
{
public const float Radius = 2;
public const float MaximumSweep = 12;
private static readonly int WorldMask = ~LayerMask.GetMask("Players", "CombatTargets");
public static bool TryCandidate(Vector3 previous, Vector3 current, Vector3 core, bool continuous, out Vector3 bodyOrigin)
{
bodyOrigin = current + Vector3.up;
if (!Finite(previous) || !Finite(current) || !Finite(core)) return false;
Vector3 segment = current - previous;
if (!continuous || segment.sqrMagnitude > MaximumSweep * MaximumSweep) previous = current;
segment = current - previous;
float horizontalSquared = segment.x * segment.x + segment.z * segment.z;
float t = horizontalSquared > .0001f ? Mathf.Clamp01(((core.x - previous.x) * segment.x + (core.z - previous.z) * segment.z) / horizontalSquared) : 1;
Vector3 foot = previous + segment * t;
bodyOrigin = foot + Vector3.up;
float vertical = core.y - foot.y;
Vector3 delta = core - foot; delta.y = 0;
return vertical >= -.25f && vertical <= 2.25f && delta.sqrMagnitude <= Radius * Radius;
}
public static bool IsVisible(Vector3 origin, Vector3 point, RaycastHit[] hits)
{
if (!Finite(origin) || !Finite(point) || hits == null || hits.Length == 0) return false;
Vector3 delta = point - origin;
if (delta.sqrMagnitude < .000001f) return true;
int count = Physics.RaycastNonAlloc(origin, delta.normalized, hits, delta.magnitude,
WorldMask, QueryTriggerInteraction.Ignore);
if (count == hits.Length) return false;
for (int i = 0; i < count; i++)
if (hits[i].collider != null && hits[i].collider.GetComponentInParent() == null) return false;
return true;
}
private static bool Finite(Vector3 v) => !float.IsNaN(v.x) && !float.IsInfinity(v.x) && !float.IsNaN(v.y) && !float.IsInfinity(v.y) && !float.IsNaN(v.z) && !float.IsInfinity(v.z);
}
}