Fix #4070, Visualizer Edition (#4730)

* Transform the Cloning Pod visualizer into a generic enum visualizer for simple cases like it

...I find it helpful at times like these to remind myself that our true enemy is
code. Code is what makes our programs run and generally is required for all of
these machinations to function in any way at all...

* Give the kitchen/meat spike a visualizer

* GenericEnumVisualizer: Byteify enums, switch to TryGetComponent for sprite
This commit is contained in:
20kdc
2021-10-03 00:43:47 +01:00
committed by GitHub
parent 67c4f49749
commit eb82dd3dae
7 changed files with 107 additions and 53 deletions

View File

@@ -1,41 +0,0 @@
using System;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using static Content.Shared.Cloning.SharedCloningPodComponent;
using static Content.Shared.Cloning.SharedCloningPodComponent.CloningPodStatus;
namespace Content.Client.Cloning
{
[UsedImplicitly]
public class CloningPodVisualizer : AppearanceVisualizer
{
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);
var sprite = component.Owner.GetComponent<ISpriteComponent>();
if (!component.TryGetData(CloningPodVisuals.Status, out CloningPodStatus status)) return;
sprite.LayerSetState(CloningPodVisualLayers.Machine, StatusToMachineStateId(status));
}
private string StatusToMachineStateId(CloningPodStatus status)
{
//TODO: implement NoMind for if the mind is not yet in the body
//TODO: Find a use for GORE POD
switch (status)
{
case CloningPodStatus.Cloning: return "pod_1";
case NoMind: return "pod_e";
case Gore: return "pod_g";
case Idle: return "pod_0";
default:
throw new ArgumentOutOfRangeException(nameof(status), status, "unknown CloningPodStatus");
}
}
public enum CloningPodVisualLayers : byte
{
Machine,
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Linq;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.Visualizer
{
[UsedImplicitly]
public class GenericEnumVisualizer : AppearanceVisualizer, ISerializationHooks
{
public Enum Key { get; set; } = default!;
public Dictionary<object, string> States { get; set; } = default!;
[DataField("layer")]
public int Layer { get; set; } = 0;
[DataField("key", readOnly: true, required: true)]
private string _keyRaw = default!;
[DataField("states", readOnly: true, required: true)]
private Dictionary<string, string> _statesRaw { get; set; } = default!;
void ISerializationHooks.AfterDeserialization()
{
var reflectionManager = IoCManager.Resolve<IReflectionManager>();
object ResolveRef(string raw)
{
if (reflectionManager.TryParseEnumReference(raw, out var @enum))
{
return @enum;
}
else
{
Logger.WarningS("c.c.v.genum", $"Unable to convert enum reference: {raw}");
}
return raw;
}
// It's important that this conversion be done here so that it may "fail-fast".
Key = (Enum) ResolveRef(_keyRaw);
States = _statesRaw.ToDictionary(kvp => ResolveRef(kvp.Key), kvp => kvp.Value);
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);
if (!component.Owner.TryGetComponent(out ISpriteComponent? sprite)) return;
if (!component.TryGetData(Key, out object status)) return;
if (!States.TryGetValue(status, out var val)) return;
sprite.LayerSetState(Layer, val);
}
}
}

View File

@@ -55,10 +55,7 @@ namespace Content.Server.Kitchen.Components
}
else
{
if (Owner.TryGetComponent(out sprite))
{
sprite.LayerSetState(0, "spike");
}
UpdateAppearance();
eventArgs.User.PopupMessage(_meatSource0);
}
@@ -73,6 +70,14 @@ namespace Content.Server.Kitchen.Components
return true;
}
private void UpdateAppearance()
{
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
{
appearance.SetData(KitchenSpikeVisuals.Status, (_meatParts > 0) ? KitchenSpikeStatus.Bloody : KitchenSpikeStatus.Empty);
}
}
private bool Spikeable(IEntity user, IEntity victim, [NotNullWhen(true)] out SharedButcherableComponent? butcherable)
{
butcherable = null;
@@ -150,10 +155,7 @@ namespace Content.Server.Kitchen.Components
_meatName = Loc.GetString("comp-kitchen-spike-meat-name", ("victim", victim));
// TODO: Visualizer
if (Owner.TryGetComponent<SpriteComponent>(out var sprite))
{
sprite.LayerSetState(0, "spikebloody");
}
UpdateAppearance();
Owner.PopupMessageEveryone(Loc.GetString("comp-kitchen-spike-kill", ("user", user), ("victim", victim)));
// TODO: Need to be able to leave them on the spike to do DoT, see ss13.

View File

@@ -44,13 +44,13 @@ namespace Content.Shared.Cloning
}
[Serializable, NetSerializable]
public enum CloningPodVisuals
public enum CloningPodVisuals : byte
{
Status
}
[Serializable, NetSerializable]
public enum CloningPodStatus
public enum CloningPodStatus : byte
{
Idle,
Cloning,

View File

@@ -1,7 +1,9 @@
using System;
using Content.Shared.DragDrop;
using Content.Shared.Nutrition.Components;
using Content.Shared.Sound;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
@@ -31,5 +33,18 @@ namespace Content.Shared.Kitchen.Components
}
public abstract bool DragDropOn(DragDropEvent eventArgs);
[Serializable, NetSerializable]
public enum KitchenSpikeVisuals : byte
{
Status
}
[Serializable, NetSerializable]
public enum KitchenSpikeStatus : byte
{
Empty,
Bloody
}
}
}

View File

@@ -10,7 +10,6 @@
sprite: Structures/Machines/cloning.rsi
layers:
- state: pod_0
map: ["enum.CloningPodVisualLayers.Machine"]
- type: Physics
bodyType: Static
fixtures:
@@ -44,7 +43,14 @@
LayoutId: CloningPod
- type: Appearance
visuals:
- type: CloningPodVisualizer
- type: GenericEnumVisualizer
key: enum.CloningPodVisuals.Status
layer: 0
states:
enum.CloningPodStatus.Cloning: pod_1
enum.CloningPodStatus.NoMind: pod_e
enum.CloningPodStatus.Gore: pod_g
enum.CloningPodStatus.Idle: pod_0
- type: UserInterface
interfaces:
- key: enum.CloningPodUIKey.Key

View File

@@ -32,3 +32,12 @@
- type: KitchenSpike
- type: Anchorable
- type: Pullable
- type: Appearance
visuals:
- type: GenericEnumVisualizer
key: enum.KitchenSpikeVisuals.Status
layer: 0
states:
enum.KitchenSpikeStatus.Empty: spike
enum.KitchenSpikeStatus.Bloody: spikebloody