b4638eb60b
Made-with: Cursor
83 lines
2.8 KiB
C#
83 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
|
|
namespace Mappy.Data;
|
|
|
|
/// <summary>Single point on the movement trail (Carbonite-style).</summary>
|
|
public record MovementTrailPoint(uint Territory, uint Map, float X, float Y, double TimeStamp);
|
|
|
|
/// <summary>Config and storage for the movement trail (where you've been on the map).</summary>
|
|
public class MovementTrailConfig
|
|
{
|
|
private readonly List<MovementTrailPoint> _points = [];
|
|
private int _nextIndex;
|
|
private float _lastX = float.MinValue;
|
|
private float _lastY = float.MinValue;
|
|
private uint _lastTerritory;
|
|
|
|
public int MaxPoints { get; set; } = 100;
|
|
public float MinDistance { get; set; } = 2f;
|
|
public float FadeTimeSeconds { get; set; } = 60f;
|
|
public Vector4 TrailColor { get; set; } = new(1f, 0f, 0f, 0.9f); // Red like Carbonite
|
|
|
|
public IReadOnlyList<MovementTrailPoint> Points => _points;
|
|
|
|
private float EffectiveMinDistance => Mappy.System.SystemConfig?.MovementTrailMinDistance ?? MinDistance;
|
|
private float EffectiveFadeTime => Mappy.System.SystemConfig?.MovementTrailFadeTimeSeconds ?? FadeTimeSeconds;
|
|
private int EffectiveMaxPoints => Mappy.System.SystemConfig?.MovementTrailMaxPoints ?? MaxPoints;
|
|
|
|
public void Clear()
|
|
{
|
|
_points.Clear();
|
|
_nextIndex = 0;
|
|
_lastX = float.MinValue;
|
|
_lastY = float.MinValue;
|
|
}
|
|
|
|
/// <summary>Record a new trail point if the player has moved enough. Call from Framework.Update.</summary>
|
|
public void TryAddPoint(uint territory, uint map, float x, float y)
|
|
{
|
|
// Reset when changing territory
|
|
if (territory != _lastTerritory)
|
|
{
|
|
Clear();
|
|
_lastTerritory = territory;
|
|
}
|
|
|
|
var dx = x - _lastX;
|
|
var dy = y - _lastY;
|
|
var moveDist = MathF.Sqrt(dx * dx + dy * dy);
|
|
|
|
if (moveDist < EffectiveMinDistance && _lastX > float.MinValue)
|
|
return;
|
|
|
|
_lastX = x;
|
|
_lastY = y;
|
|
|
|
var now = DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
|
|
|
|
var max = EffectiveMaxPoints;
|
|
if (_points.Count < max)
|
|
{
|
|
_points.Add(new MovementTrailPoint(territory, map, x, y, now));
|
|
}
|
|
else
|
|
{
|
|
_points[_nextIndex] = new MovementTrailPoint(territory, map, x, y, now);
|
|
_nextIndex = (_nextIndex + 1) % max;
|
|
}
|
|
}
|
|
|
|
/// <summary>Get points for the current map that haven't faded yet.</summary>
|
|
public IEnumerable<MovementTrailPoint> GetVisiblePoints(uint territoryId, uint mapId)
|
|
{
|
|
var now = DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
|
|
var fade = EffectiveFadeTime;
|
|
return _points
|
|
.Where(p => p.Territory == territoryId && p.Map == mapId && (now - p.TimeStamp) < fade)
|
|
.ToList();
|
|
}
|
|
}
|