2026-10-07 14:52:12 +02:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using CultMath;
|
|
|
|
|
using static CultMath.math;
|
|
|
|
|
using float2 = CultMath.float2;
|
|
|
|
|
|
|
|
|
|
// A free-floating body in a zone: a floating item or a mine. Zone-scoped and never reused within a zone;
|
|
|
|
|
// runtime state only, never saved.
|
|
|
|
|
public readonly struct FloatingBodyId : IEquatable<FloatingBodyId>
|
|
|
|
|
{
|
|
|
|
|
public readonly uint Value;
|
|
|
|
|
public FloatingBodyId(uint value) => Value = value;
|
|
|
|
|
public bool Equals(FloatingBodyId other) => Value == other.Value;
|
|
|
|
|
public override bool Equals(object obj) => obj is FloatingBodyId other && Equals(other);
|
|
|
|
|
public override int GetHashCode() => (int) Value;
|
|
|
|
|
public override string ToString() => Value.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The one drift integrator of every free body in a zone. A launch velocity decays on its own drag; the zone's
|
|
|
|
|
// force accumulates into a separate drift velocity that has its own drag, so a body settles to
|
|
|
|
|
// force * gravity / drag. Engine-free: the caller supplies dt and the zone force at the body's position.
|
|
|
|
|
public struct KinematicBody
|
|
|
|
|
{
|
|
|
|
|
public float2 Position;
|
|
|
|
|
// The launch velocity, decaying.
|
|
|
|
|
public float2 Velocity;
|
|
|
|
|
public float2 Drift;
|
|
|
|
|
|
|
|
|
|
// What a presenter draws ahead with.
|
|
|
|
|
public float2 TotalVelocity => Velocity + Drift;
|
|
|
|
|
|
|
|
|
|
public void Step(float dt, float2 force, GameplaySettings s)
|
|
|
|
|
{
|
|
|
|
|
Velocity *= exp(-s.FloatingBodyLaunchDrag * dt);
|
|
|
|
|
Drift += force * s.FloatingBodyGravity * dt;
|
|
|
|
|
Drift *= exp(-s.FloatingBodyDrag * dt);
|
|
|
|
|
Position += (Velocity + Drift) * dt;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-12 04:00:08 +02:00
|
|
|
|
|
|
|
|
// An item adrift in a zone: a death drop or jettisoned cargo. Zone.Release is its only adder; Zone's floating-item
|
2026-10-13 05:00:22 +02:00
|
|
|
// step (expiry) and TryPickUp are its only removers. Zone.TryHold and Free are the only writers of Holder, the
|
|
|
|
|
// entity grabbing it with a tractor beam; a held item is placed by Zone, not drifted. Runtime state, never saved.
|
2026-10-12 04:00:08 +02:00
|
|
|
public sealed class FloatingItem
|
|
|
|
|
{
|
|
|
|
|
public FloatingBodyId Id;
|
|
|
|
|
public ItemInstance Item;
|
|
|
|
|
public KinematicBody Body;
|
|
|
|
|
public double ReleasedAt;
|
|
|
|
|
public float Lifetime;
|
2026-10-13 05:00:22 +02:00
|
|
|
// The entity holding it, or null when it floats free; HeldFrom is where it was claimed and HeldProgress how far
|
|
|
|
|
// along its pull to the holder (0..1).
|
|
|
|
|
public Entity Holder;
|
|
|
|
|
public float2 HeldFrom;
|
|
|
|
|
public float HeldProgress;
|
2026-10-12 04:00:08 +02:00
|
|
|
}
|