using System; using System.Linq; using Content.Shared.Fluids; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Maths; using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; namespace Content.Client.Fluids { [UsedImplicitly] public sealed class PuddleVisualizer : AppearanceVisualizer { [Dependency] private readonly IRobustRandom _random = default!; // Whether the underlying solution color should be used [DataField("recolor")] public bool Recolor; public override void InitializeEntity(EntityUid entity) { base.InitializeEntity(entity); if (!IoCManager.Resolve().TryGetComponent(entity, out SpriteComponent? spriteComponent)) { Logger.Warning($"Missing SpriteComponent for PuddleVisualizer on entityUid = {entity}"); return; } IoCManager.InjectDependencies(this); var maxStates = spriteComponent.BaseRSI?.ToArray(); if (maxStates is not { Length: > 0 }) return; var variant = _random.Next(0, maxStates.Length - 1); spriteComponent.LayerSetState(0, maxStates[variant].StateId); spriteComponent.Rotation = Angle.FromDegrees(_random.Next(0, 359)); } public override void OnChangeData(AppearanceComponent component) { base.OnChangeData(component); var entities = IoCManager.Resolve(); if (component.TryGetData(PuddleVisuals.VolumeScale, out var volumeScale) && entities.TryGetComponent(component.Owner, out var spriteComponent)) { component.TryGetData(PuddleVisuals.ForceWetFloorSprite, out var forceWetFloorSprite); var cappedScale = Math.Min(1.0f, volumeScale * 0.75f +0.25f); UpdateVisual(component, spriteComponent, cappedScale, forceWetFloorSprite); } } private void UpdateVisual(AppearanceComponent component, SpriteComponent spriteComponent, float cappedScale, bool forceWetFloorSprite) { Color newColor; if (Recolor && component.TryGetData(PuddleVisuals.SolutionColor, out var solutionColor)) { newColor = solutionColor.WithAlpha(cappedScale); } else { newColor = spriteComponent.Color.WithAlpha(cappedScale); } spriteComponent.Color = newColor; if (forceWetFloorSprite) { //Change the puddle's sprite to the wet floor sprite spriteComponent.LayerSetRSI(0, "Fluids/wet_floor_sparkles.rsi"); spriteComponent.LayerSetState(0, "sparkles"); spriteComponent.Color = spriteComponent.Color.WithAlpha(0.25f); //should be mostly transparent. } else { spriteComponent.LayerSetRSI(0, "Fluids/smear.rsi"); spriteComponent.LayerSetState(0, "smear-0"); // TODO: need a way to implement the random smears again when the mop creates new puddles. } } } }