v1.0.0.14: Movement Trail (Carbonite-style) - red dots show where you've been
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,16 @@ public class SystemConfig : CharacterConfiguration
|
||||
/// <summary>Icon ID for other players on the minimap (default 60403, distinct from party 60421). Override if you prefer a different look.</summary>
|
||||
public uint MinimapOtherPlayerIconId = 60403;
|
||||
|
||||
// Movement Trail (Carbonite-style: show where you've been)
|
||||
/// <summary>Draw a red trail of dots on the map showing where you've been.</summary>
|
||||
public bool ShowMovementTrail = false;
|
||||
/// <summary>Minimum distance (world units) before adding a new trail point.</summary>
|
||||
public float MovementTrailMinDistance = 2f;
|
||||
/// <summary>How long (seconds) trail points stay visible before fading out.</summary>
|
||||
public float MovementTrailFadeTimeSeconds = 60f;
|
||||
/// <summary>Maximum number of trail points to keep.</summary>
|
||||
public int MovementTrailMaxPoints = 100;
|
||||
|
||||
// Do not persist this setting
|
||||
[JsonIgnore]
|
||||
public bool DebugMode = false;
|
||||
|
||||
Reference in New Issue
Block a user