Мини реворк системы следов

This commit is contained in:
Vigers Ray 2024-12-05 20:34:00 +03:00
parent 92722e7670
commit 6455ba2d7d
4 changed files with 74 additions and 68 deletions

View file

@ -1,14 +1,16 @@
using Content.Server.Atmos.Components;
using Content.Shared._Sunrise.Footprints;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Robust.Shared.Map;
using Robust.Shared.Random;
using System.Linq;
using Content.Shared.GameTicking;
using Robust.Shared.Prototypes;
namespace Content.Server._Sunrise.Footprints;
@ -24,6 +26,7 @@ public sealed class FootprintSystem : EntitySystem
[Dependency] private readonly SharedSolutionContainerSystem _solutionSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
#endregion
#region Entity Queries
@ -32,6 +35,8 @@ public sealed class FootprintSystem : EntitySystem
private EntityQuery<AppearanceComponent> _appearanceQuery;
#endregion
public static readonly float FootsVolume = 5;
// Dictionary to track footprints per tile to prevent overcrowding
private readonly Dictionary<(EntityUid GridId, Vector2i TilePosition), HashSet<EntityUid>> _tileFootprints = new();
private const int MaxFootprintsPerTile = 2; // Maximum footprints allowed per tile
@ -51,6 +56,12 @@ public sealed class FootprintSystem : EntitySystem
SubscribeLocalEvent<FootprintEmitterComponent, ComponentStartup>(OnEmitterStartup);
SubscribeLocalEvent<FootprintEmitterComponent, MoveEvent>(OnEntityMove);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<FootprintEmitterComponent, ComponentInit>(OnFootprintEmitterInit);
}
private void OnFootprintEmitterInit(Entity<FootprintEmitterComponent> entity, ref ComponentInit args)
{
_solutionSystem.EnsureSolution(entity.Owner, entity.Comp.SolutionName, out _, FixedPoint2.New(FootsVolume));
}
/// <summary>
@ -70,10 +81,14 @@ public sealed class FootprintSystem : EntitySystem
private void OnEntityMove(EntityUid uid, FootprintEmitterComponent emitter, ref MoveEvent args)
{
// Check if footprints should be created
if (emitter.TrackColor.A <= 0f
|| !_transformQuery.TryComp(uid, out var transform)
if (!_transformQuery.TryComp(uid, out var transform)
|| !_mobStateQuery.TryComp(uid, out var mobState)
|| !_mapManager.TryFindGridAt(_transformSystem.GetMapCoordinates((uid, transform)), out var gridUid, out var grid))
|| !_mapManager.TryFindGridAt(_transformSystem.GetMapCoordinates((uid, transform)), out var gridUid, out var grid)
|| !TryComp<SolutionContainerManagerComponent>(uid, out var container)
|| !_solutionSystem.ResolveSolution((uid, container), emitter.SolutionName, ref emitter.Solution, out var emitterSolution))
return;
if (emitterSolution.Volume <= 0)
return;
var isBeingDragged =
@ -95,7 +110,7 @@ public sealed class FootprintSystem : EntitySystem
emitter.IsRightStep = !emitter.IsRightStep;
// Create new footprint entity
var footprintEntity = SpawnFootprint(gridUid, emitter, uid, transform, isBeingDragged);
var footprintEntity = SpawnFootprint(gridUid, emitter, emitterSolution, uid, transform, isBeingDragged);
// Add the new footprint to tile tracking
if (!_tileFootprints.ContainsKey(tileKey))
@ -104,7 +119,7 @@ public sealed class FootprintSystem : EntitySystem
_tileFootprints[tileKey].Add(footprintEntity);
// Update footprint and emitter state
UpdateFootprint(footprintEntity, emitter, transform, isBeingDragged);
UpdateFootprint(footprintEntity, (uid, emitter), emitterSolution, emitter.Solution.Value, transform, isBeingDragged);
// Update emitter state.
UpdateEmitterState(emitter, transform);
@ -124,6 +139,7 @@ public sealed class FootprintSystem : EntitySystem
private EntityUid SpawnFootprint(
EntityUid gridUid,
FootprintEmitterComponent emitter,
Solution emitterSolution,
EntityUid emitterOwner,
TransformComponent transform,
bool isDragging)
@ -142,9 +158,11 @@ public sealed class FootprintSystem : EntitySystem
DetermineVisualState(emitterOwner, isDragging),
appearance);
var alpha = Math.Clamp(emitterSolution.Volume.Float() / emitterSolution.MaxVolume.Float(), 0f, 1f);
_appearanceSystem.SetData(entity,
FootprintVisualParameter.TrackColor,
emitter.TrackColor,
emitterSolution.GetColor(_prototypeManager).WithAlpha(alpha),
appearance);
}
@ -156,7 +174,9 @@ public sealed class FootprintSystem : EntitySystem
/// </summary>
private void UpdateFootprint(
EntityUid footprintEntity,
FootprintEmitterComponent emitter,
Entity<FootprintEmitterComponent> emitter,
Solution emitterSolution,
Entity<SolutionComponent> emitterEntSolution,
TransformComponent transform,
bool isDragging)
{
@ -164,10 +184,10 @@ public sealed class FootprintSystem : EntitySystem
return;
footprintTransform.LocalRotation = isDragging
? (transform.LocalPosition - emitter.LastStepPosition).ToAngle() + Angle.FromDegrees(-90f)
? (transform.LocalPosition - emitter.Comp.LastStepPosition).ToAngle() + Angle.FromDegrees(-90f)
: transform.LocalRotation + Angle.FromDegrees(180f);
TransferReagents(footprintEntity, emitter);
TransferReagents(footprintEntity, emitter, emitterEntSolution);
}
#endregion
@ -177,29 +197,25 @@ public sealed class FootprintSystem : EntitySystem
/// </summary>
private void UpdateEmitterState(FootprintEmitterComponent emitter, TransformComponent transform)
{
emitter.TrackColor = emitter.TrackColor.WithAlpha(Math.Max(0f, emitter.TrackColor.A - emitter.ColorFadeRate));
emitter.LastStepPosition = transform.LocalPosition;
}
/// <summary>
/// Transfers reagents from emitter to footprint if applicable.
/// </summary>
private void TransferReagents(EntityUid footprintEntity, FootprintEmitterComponent emitter)
private void TransferReagents(EntityUid footprintEntity, Entity<FootprintEmitterComponent> emitter, Entity<SolutionComponent> emitterSolution)
{
if (!TryComp<SolutionContainerManagerComponent>(footprintEntity, out var container)
|| !TryComp<FootprintComponent>(footprintEntity, out var footprint)
|| !_solutionSystem.ResolveSolution((footprintEntity, container),
footprint.ContainerName,
ref footprint.SolutionContainer,
out var solution)
|| string.IsNullOrWhiteSpace(emitter.CurrentReagent)
|| solution.Volume >= 1)
out var solution))
return;
_solutionSystem.TryAddReagent(footprint.SolutionContainer.Value,
emitter.CurrentReagent,
1,
out _);
var splitSolution = _solutionSystem.SplitSolution(emitterSolution, emitter.Comp.TransferVolume);
_solutionSystem.AddSolution(footprint.SolutionContainer.Value, splitSolution);
}
#endregion

View file

@ -2,7 +2,6 @@
using Content.Shared._Sunrise.Footprints;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Fluids;
using Content.Shared.Fluids.Components;
using Robust.Shared.Physics.Events;
@ -27,35 +26,37 @@ public sealed class PuddleFootprintSystem : EntitySystem
/// Handles puddle interaction and footprint creation when entity exits the puddle
/// </summary>
private void OnPuddleInteraction(EntityUid uid, PuddleFootprintComponent component, ref EndCollideEvent args)
{
if (!TryComp<AppearanceComponent>(uid, out var appearance)
|| !TryComp<PuddleComponent>(uid, out var puddle)
|| !TryComp<FootprintEmitterComponent>(args.OtherEntity, out var emitter)
|| !TryComp<SolutionContainerManagerComponent>(uid, out var solutionManager)
|| !_solutionSystem.ResolveSolution((uid, solutionManager), puddle.SolutionName, ref puddle.Solution, out var solutions))
return;
{
if (!TryComp<AppearanceComponent>(uid, out var appearance)
|| !TryComp<PuddleComponent>(uid, out var puddle)
|| !TryComp<FootprintEmitterComponent>(args.OtherEntity, out var emitter)
|| !TryComp<SolutionContainerManagerComponent>(uid, out var solutionManager)
|| !_solutionSystem.ResolveSolution((uid, solutionManager), puddle.SolutionName, ref puddle.Solution, out var puddleSolutions)
|| !TryComp<SolutionContainerManagerComponent>(args.OtherEntity, out var emitterSolutionManager)
|| !_solutionSystem.ResolveSolution((args.OtherEntity, emitterSolutionManager), emitter.SolutionName, ref emitter.Solution, out var emitterSolutions))
return;
var totalSolutionQuantity = solutions.Contents.Sum(sol => (float)sol.Quantity);
var waterQuantity = (from sol in solutions.Contents where sol.Reagent.Prototype == "Water" select (float)sol.Quantity).FirstOrDefault();
var totalSolutionQuantity = puddleSolutions.Contents.Sum(sol => (float)sol.Quantity);
var waterQuantity = (from sol in puddleSolutions.Contents where sol.Reagent.Prototype == "Water" select (float)sol.Quantity).FirstOrDefault();
if (waterQuantity / (totalSolutionQuantity / 100f) > component.WaterThresholdPercent || solutions.Contents.Count <= 0)
return;
if (waterQuantity / (totalSolutionQuantity / 100f) > component.WaterThresholdPercent || puddleSolutions.Contents.Count <= 0)
return;
emitter.CurrentReagent = solutions.Contents.Aggregate((l, r) => l.Quantity > r.Quantity ? l : r).Reagent.Prototype;
var availableSpace = emitterSolutions.MaxVolume.Float() - emitterSolutions.Volume.Float();
if (_appearanceSystem.TryGetData(uid, PuddleVisuals.SolutionColor, out var color, appearance)
&& _appearanceSystem.TryGetData(uid, PuddleVisuals.CurrentVolume, out var volume, appearance))
UpdateTrackColor((Color)color, (float)volume * component.ColorTransferRatio, emitter);
if (availableSpace <= 0)
return;
_solutionSystem.RemoveEachReagent(puddle.Solution.Value, 0.5f);
}
var transferVolume = Math.Min(component.TransferVolume, availableSpace);
/// <summary>
/// Updates the color of footprints based on puddle properties
/// </summary>
private void UpdateTrackColor(Color color, float quantity, FootprintEmitterComponent emitter)
{
emitter.TrackColor = emitter.AccumulatedColor == 0f ? color : Color.InterpolateBetween(emitter.TrackColor, color, emitter.ColorBlendFactor);
emitter.AccumulatedColor += quantity;
}
if (puddleSolutions.Volume < transferVolume)
transferVolume = puddleSolutions.Volume.Float();
if (transferVolume <= 0)
return;
var splitSolution = _solutionSystem.SplitSolution(puddle.Solution.Value, transferVolume);
_solutionSystem.AddSolution(emitter.Solution.Value, splitSolution);
}
}

View file

@ -42,7 +42,7 @@ public sealed partial class PuddleFootprintComponent : Component
/// Ratio determining how much of puddle's color transfers to footprints
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float ColorTransferRatio = 0.5f;
public float TransferVolume = 2.5f;
/// <summary>
/// Percentage of water content above which footprints won't be created
@ -106,12 +106,6 @@ public sealed partial class FootprintEmitterComponent : Component
[ViewVariables(VVAccess.ReadOnly), DataField]
public EntProtoId<FootprintComponent> FootprintPrototype = "Footstep";
/// <summary>
/// Current color of footprints
/// </summary>
[ViewVariables(VVAccess.ReadOnly), DataField]
public Color TrackColor = Color.FromHex("#00000000");
/// <summary>
/// Distance between footprints when walking
/// </summary>
@ -124,11 +118,14 @@ public sealed partial class FootprintEmitterComponent : Component
[DataField]
public float DragMarkInterval = 0.5f;
/// <summary>
/// Amount of color accumulated from puddles
/// </summary>
[DataField]
public float AccumulatedColor;
[ViewVariables(VVAccess.ReadOnly), DataField("solution")]
public string SolutionName = "foots";
[ViewVariables(VVAccess.ReadOnly), DataField("solutionRef")]
public Entity<SolutionComponent>? Solution;
[ViewVariables(VVAccess.ReadWrite)]
public float TransferVolume = 0.1f;
/// <summary>
/// Rate at which footprint color fades
@ -136,12 +133,6 @@ public sealed partial class FootprintEmitterComponent : Component
[DataField]
public float ColorFadeRate = 0.05f;
/// <summary>
/// Current reagent being transferred to footprints
/// </summary>
[DataField]
public string? CurrentReagent;
/// <summary>
/// Offset from entity center for footprint placement
/// </summary>
@ -157,11 +148,6 @@ public sealed partial class FootprintEmitterComponent : Component
/// Position of last footprint
/// </summary>
public Vector2 LastStepPosition = Vector2.Zero;
/// <summary>
/// Factor for interpolating between colors when mixing
/// </summary>
public float ColorBlendFactor = 0.2f;
}
/// <summary>

View file

@ -232,6 +232,9 @@
abstract: true
components:
- type: SolutionContainerManager
solutions:
foots:
maxVol: 5
- type: InjectableSolution
solution: chemicals
- type: Bloodstream