Enhanced loot drops system

This commit is contained in:
MaddoScientisto 2026-03-01 19:14:34 +01:00
commit acc61f9a0e
12 changed files with 661 additions and 443 deletions

View file

@ -7,16 +7,70 @@ namespace Cirno.Scripts.Interactables;
public partial class ItemPickup3D : Interactable3D
{
private const float GravityAccel = 9.8f;
// How far below the item to probe for the floor each physics step.
private const float FloorProbeDistance = 10f;
[Export] public Array<LootItem> LootTable = [];
/// <summary>
/// Distance from the item's origin to its bottom edge.
/// Lifts the item above the floor surface so it doesn't clip into it.
/// Default matches the GenericItem3D collision shape: offset (0.065) + half cylinder height (0.269).
/// </summary>
[Export] public float GroundOffset { get; set; } = 0.204f;
private bool _autoPickup = false;
private bool _simulating = false;
private Vector3 _velocity = Vector3.Zero;
public bool AutoPickup => _autoPickup;
public override void _Ready()
{
_autoPickup = LootTable.Any(x => x.AutoPickup);
}
/// <summary>
/// Applies an initial velocity and enables gravity simulation so the pickup
/// arcs through the air and settles on the floor.
/// </summary>
public void Launch(Vector3 velocity)
{
_velocity = velocity;
_simulating = true;
}
public override void _PhysicsProcess(double delta)
{
if (!_simulating) return;
_velocity.Y -= GravityAccel * (float)delta;
var nextPosition = GlobalPosition + _velocity * (float)delta;
// Cast downward to detect the floor so we don't sink through it.
var spaceState = GetWorld3D()?.DirectSpaceState;
var query = PhysicsRayQueryParameters3D.Create(
GlobalPosition,
GlobalPosition + Vector3.Down * FloorProbeDistance,
// Exclude the item's own collision layer (layer 32 per scene) and hit static geometry only.
0b1
);
query.Exclude = [GetRid()];
var hit = spaceState?.IntersectRay(query) ?? [];
if (hit.Count > 0)
{
var floorY = hit["position"].AsVector3().Y;
if (nextPosition.Y - GroundOffset <= floorY)
{
nextPosition.Y = floorY + GroundOffset;
_simulating = false;
_velocity = Vector3.Zero;
}
}
GlobalPosition = nextPosition;
}
public override bool Activate(ActivationType activationType = ActivationType.Toggle)