Serialization v3 content PR (#3491)

* serv3 in shared pt 1

* beginning of deepclone api

* progress in implementing ideepclone & serv3 in content

* adds target

* its cant hurt you it cant hurt you

* more changes to content.server

* adds dataclasses

* almost there

* renamed & edited entry

* finishes refactoring content to use serv3

* gasmixture runtimes, next: reagentunit

* fucin hell that was an annoying one

* adds flags

* fixes some yaml errors

* removes comment

* fixes generic components for now

* removes todo
actually clones values my god paul
fixes bug involving resolving custom data classes from other proj
renames dataclass
fixes spritecomp
adds WithFormat.Constants support

* adds deepclone to ResistanceSet

* adds a bunch of deepclone implementations
adds a deepclone analyzer (TODO)
adds a deep clone fallback for classes & structs

* fixes a bunch of runtimes

* adds deepclone to entityuid

* adds generator to sln

* gets rid of warnings

* fixes

* argh

* componentdata refactors

* more deepclone impl

* heck me i reworked all of content deepclone

* renames custom dataclasstarget

* misc

* reworks prototypes

* deepclone nuke

* renamed customdataclass attribute

* fixes everything

* misc fixed

* the killcommit

* getting there

* changed yamlfieldattribute namespace

* adds back iselfserialize

* renames everything to data(field/definition)

* ouch

* Fix most errors on content

* Fix more errors in content

* Fix some components

* work on tests

* fixes some customdataclasses

* fuggin shit

* yes

* yeas

* Remove data classes

* Data field naming fixes

* arg

* Git resetti RobustToolbox

* Merge fixes

* General fixes

* Fix startup serialization errors

* Fix DamageContainerPrototype when supported classes or types are null

* Implement construction graph step type serializer

* Fix up construction serialization

* Fix up construction serialization part 2

* Fix null list in technology database component

* Fix body serialization

* Fix entity storage serialization

* Fix actions serialization

* Fix AI serialization

* Fix reaction serialization

* Fix body serialization

* Fix grid atmosphere serialization

* Rename IServ3Manager to ISerializationManager

* Convert every non generic serializer to the new format, general fixes

* Serialization and body system fix

* pushinheritance fix

* Update all prototypes to have a parent and have consistent id/parent properties

* Merge fixes

* smh my head

* cuddling slaps

* Content commit for engine PR

* stuff

* more fixes

* argh

* yes even you are fixed

* changelog fixes

* fixes seeds

* argh

* Test fixes

* Add writing for alert order prototype

* Fix alert order writing

* FIX

* its been alot ok

* Fix the rest of the visualizers

* Fix server alerts component tests

* Fix alert prototype tests not using the read value

* Fix alert prototype tests initializing serialization multiple times

* THIS IS AN AMERICAN CODEBASE GOD BLESS THE USA

* Add ImplicitDataDefinitionForInheritors to IMechanismBehavior
Fixes the behaviors not being found

* Fix NRE in strap component
Good night to the 1 buckle optimization

* Fix clothing component slot flags serialization tag

* Fix body component in all components test

* Merge fixes

* ffs

* Make construction graph prototype use serialization hooks

* human yaml linted

* a

* Do the thing for construction

* stuff

* a

* monke see yaml linter

* LINT HARDER

* Remove redundant todo

* yes

* Add skip hook argument to readers and copiers

* we gamin

* test/datafield fixes

* adds more verbose validation

* moves linter to action

* Improve construction graph step type serializer error message

* Fix ammo box component NRE

* gamin

* some updates to the linter

* yes

* removes that test

* misc fixes

* array fix
priority fix
misc fixes

* adds proper info the validation

* adds alwaysrelevant usa

* Make yaml linter take half as long to run (~50% less)

* Make yaml linter 5 times faster (~80% less execution time)

* based vera being based

* fixes mapsaving

* warning cleanup & moves surpressor

* removes old msbuild targets

* Revert "Make yaml linter 5 times faster (~80% less execution time)"

This reverts commit 3e6091359a26252c3e98828199553de668031c63.

* Add -nowarn to yaml linter run configuration

* Improve yaml linter message feedback

* Make dependencies an argument instead of a property on the serialization manager

* yamllinting slaps

* Clean up type serializers

* Move yaml linter code to its own method

* Fix yaml errors

* Change yaml linter action name and remove -nowarn

* yaml linter please shut

* Git resetti robust toolbox

Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
Paul Ritter
2021-03-05 01:08:38 +01:00
committed by GitHub
parent 05d4d9692c
commit 5c50b1f6ed
545 changed files with 4547 additions and 6650 deletions

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,9 +11,13 @@ namespace Content.Client.GameObjects.Components.Atmos
[UsedImplicitly]
public class FireVisualizer : AppearanceVisualizer
{
[DataField("fireStackAlternateState")]
private int _fireStackAlternateState = 3;
[DataField("normalState")]
private string _normalState;
[DataField("alternateState")]
private string _alternateState;
[DataField("sprite")]
private string _sprite;
public override void InitializeEntity(IEntity entity)
@@ -25,31 +30,6 @@ namespace Content.Client.GameObjects.Components.Atmos
sprite.LayerSetVisible(FireVisualLayers.Fire, false);
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("sprite", out var sprite))
{
_sprite = sprite.AsString();
}
if (node.TryGetNode("fireStackAlternateState", out var fireStack))
{
_fireStackAlternateState = fireStack.AsInt();
}
if (node.TryGetNode("normalState", out var normalState))
{
_normalState = normalState.AsString();
}
if (node.TryGetNode("alternateState", out var alternateState))
{
_alternateState = alternateState.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -1,6 +1,7 @@
using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -9,17 +10,11 @@ namespace Content.Client.GameObjects.Components.Atmos
[UsedImplicitly]
public class GasAnalyzerVisualizer : AppearanceVisualizer
{
[DataField("state_off")]
private string _stateOff;
[DataField("state_working")]
private string _stateWorking;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateOff = node.GetNode("state_off").AsString();
_stateWorking = node.GetNode("state_working").AsString();
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -1,6 +1,7 @@
using Content.Shared.GameObjects.Components.Atmos;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -8,18 +9,11 @@ namespace Content.Client.GameObjects.Components.Atmos
{
public class GasCanisterVisualizer : AppearanceVisualizer
{
[DataField("stateConnected")]
private string _stateConnected;
[DataField("pressureStates")]
private string[] _statePressure = new string[] {"", "", "", ""};
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateConnected = node.GetNode("stateConnected").AsString();
for (int i = 0; i < _statePressure.Length; i++)
_statePressure[i] = node.GetNode("stateO" + i).AsString();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -3,22 +3,15 @@ using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
[UsedImplicitly]
[DataDefinition]
public class GasFilterVisualizer : AppearanceVisualizer
{
private string _filterEnabledState = default!;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _filterEnabledState, "filterEnabledState", "gasFilterOn");
}
[DataField("filterEnabledState")] private string _filterEnabledState = "gasFilterOn";
public override void InitializeEntity(IEntity entity)
{

View File

@@ -9,26 +9,27 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using YamlDotNet.RepresentationModel;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
[UsedImplicitly]
public class PipeConnectorVisualizer : AppearanceVisualizer
public class PipeConnectorVisualizer : AppearanceVisualizer, ISerializationHooks
{
private string _baseState = string.Empty;
[DataField("rsi")]
private string _rsi = "Constructible/Atmos/pipe.rsi";
[DataField("baseState")]
private string _baseState = "pipeConnector";
private RSI? _connectorRsi;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _baseState, "baseState", "pipeConnector");
var rsiString = SharedSpriteComponent.TextureRoot / serializer.ReadDataField("rsi", "Constructible/Atmos/pipe.rsi");
var rsiString = SharedSpriteComponent.TextureRoot / _rsi;
var resourceCache = IoCManager.Resolve<IResourceCache>();
if (resourceCache.TryGetResource(rsiString, out RSIResource? rsi))
_connectorRsi = rsi.RSI;
else

View File

@@ -1,4 +1,5 @@
#nullable enable
using System;
using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
@@ -8,29 +9,29 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
/// <summary>
/// Sets the state of the sprite based on what shape of pipe it is.
/// </summary>
[UsedImplicitly]
public class PipeVisualizer : AppearanceVisualizer
[DataDefinition]
public class PipeVisualizer : AppearanceVisualizer, ISerializationHooks
{
[DataField("rsi")] private string _rsiString = "Constructible/Atmos/pipe.rsi";
private RSI? _pipeRSI;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
var rsiString = SharedSpriteComponent.TextureRoot / serializer.ReadDataField("rsi", "Constructible/Atmos/pipe.rsi");
var rsiPath = SharedSpriteComponent.TextureRoot / _rsiString;
var resourceCache = IoCManager.Resolve<IResourceCache>();
if (resourceCache.TryGetResource(rsiString, out RSIResource? rsi))
if (resourceCache.TryGetResource(rsiPath, out RSIResource? rsi))
{
_pipeRSI = rsi.RSI;
else
Logger.Error($"{nameof(PipeVisualizer)} could not load to load RSI {rsiString}.");
}
}
public override void InitializeEntity(IEntity entity)

View File

@@ -2,23 +2,15 @@ using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
[UsedImplicitly]
[DataDefinition]
public class PumpVisualizer : AppearanceVisualizer
{
private string _pumpEnabledState;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _pumpEnabledState, "pumpEnabledState", "pumpPressureOn");
}
[DataField("pumpEnabledState")] private string _pumpEnabledState = "pumpPressureOn";
public override void InitializeEntity(IEntity entity)
{

View File

@@ -1,24 +1,16 @@
using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Content.Shared.GameObjects.Components.Atmos;
using Robust.Shared.GameObjects;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
[UsedImplicitly]
[DataDefinition]
public class SiphonVisualizer : AppearanceVisualizer
{
private string _siphonOnState;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _siphonOnState, "siphonOnState", "scrubOn");
}
[DataField("siphonOnState")] private string _siphonOnState = "scrubOn";
public override void InitializeEntity(IEntity entity)
{

View File

@@ -1,24 +1,16 @@
using Content.Shared.GameObjects.Components.Atmos;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Content.Shared.GameObjects.Components.Atmos;
using Robust.Shared.GameObjects;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
namespace Content.Client.GameObjects.Components.Atmos.Piping
{
[UsedImplicitly]
[DataDefinition]
public class VentVisualizer : AppearanceVisualizer
{
private string _ventOnstate;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _ventOnstate, "ventOnState", "ventOn");
}
[DataField("ventOnState")] private string _ventOnState = "ventOn";
public override void InitializeEntity(IEntity entity)
{
@@ -28,7 +20,7 @@ namespace Content.Client.GameObjects.Components.Atmos
sprite.LayerMapReserveBlank(Layer.VentEnabled);
var layer = sprite.LayerMapGet(Layer.VentEnabled);
sprite.LayerSetState(layer, _ventOnstate);
sprite.LayerSetState(layer, _ventOnState);
}
public override void OnChangeData(AppearanceComponent component)

View File

@@ -4,40 +4,32 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Atmos
{
[UsedImplicitly]
public class VaporVisualizer : AppearanceVisualizer
public class VaporVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "flick_animation";
[DataField("animation_time")]
private float _delay = 0.25f;
[DataField("animation_state")]
private string _state = "chempuff";
private Animation VaporFlick;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var delay = 0.25f;
var state = "chempuff";
if (node.TryGetNode("animation_time", out var delayNode))
{
delay = delayNode.AsFloat();
}
if (node.TryGetNode("animation_state", out var stateNode))
{
state = stateNode.AsString();
}
VaporFlick = new Animation {Length = TimeSpan.FromSeconds(delay)};
VaporFlick = new Animation {Length = TimeSpan.FromSeconds(_delay)};
{
var flick = new AnimationTrackSpriteFlick();
VaporFlick.AnimationTracks.Add(flick);
flick.LayerKey = VaporVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(state, 0f));
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(_state, 0f));
}
}

View File

@@ -22,7 +22,7 @@ namespace Content.Client.GameObjects.Components.Cargo
base.HandleComponentState(curState, nextState);
if (curState is not GalacticMarketState state)
return;
_products.Clear();
_productIds.Clear();
foreach (var productId in state.Products)
{
if (!_prototypeManager.TryIndex(productId, out CargoProductPrototype product))

View File

@@ -5,38 +5,31 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Chemistry
{
[UsedImplicitly]
public class FoamVisualizer : AppearanceVisualizer
public class FoamVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "foamdissolve_animation";
[DataField("animationTime")]
private float _delay = 0.6f;
[DataField("animationState")]
private string _state = "foam-dissolve";
private Animation _foamDissolve = new();
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var delay = 0.6f;
var state = "foam-dissolve";
if (node.TryGetNode("animationTime", out var delayNode))
{
delay = delayNode.AsFloat();
}
if (node.TryGetNode("animationState", out var stateNode))
{
state = stateNode.AsString();
}
_foamDissolve = new Animation {Length = TimeSpan.FromSeconds(delay)};
_foamDissolve = new Animation {Length = TimeSpan.FromSeconds(_delay)};
var flick = new AnimationTrackSpriteFlick();
_foamDissolve.AnimationTracks.Add(flick);
flick.LayerKey = FoamVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(state, 0f));
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(_state, 0f));
}
public override void OnChangeData(AppearanceComponent component)

View File

@@ -6,7 +6,7 @@ using Robust.Client.Utility;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components
@@ -18,14 +18,7 @@ namespace Content.Client.GameObjects.Components
[Dependency] private readonly IClickMapManager _clickMapManager = default!;
[ViewVariables] private DirBoundData _data = default!;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _data, "bounds", DirBoundData.Default);
}
[ViewVariables] [DataField("bounds")] private DirBoundData _data = DirBoundData.Default;
/// <summary>
/// Used to check whether a click worked.
@@ -131,24 +124,16 @@ namespace Content.Client.GameObjects.Components
return found;
}
private sealed class DirBoundData : IExposeData
[DataDefinition]
public sealed class DirBoundData
{
[ViewVariables] public Box2 All;
[ViewVariables] public Box2 North;
[ViewVariables] public Box2 South;
[ViewVariables] public Box2 East;
[ViewVariables] public Box2 West;
[ViewVariables] [DataField("all")] public Box2 All;
[ViewVariables] [DataField("north")] public Box2 North;
[ViewVariables] [DataField("south")] public Box2 South;
[ViewVariables] [DataField("east")] public Box2 East;
[ViewVariables] [DataField("west")] public Box2 West;
public static DirBoundData Default { get; } = new();
void IExposeData.ExposeData(ObjectSerializer serializer)
{
serializer.DataField(ref All, "all", default);
serializer.DataField(ref North, "north", default);
serializer.DataField(ref South, "south", default);
serializer.DataField(ref East, "east", default);
serializer.DataField(ref West, "west", default);
}
}
}
}

View File

@@ -1,7 +1,7 @@
#nullable enable
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components
{
@@ -13,15 +13,9 @@ namespace Content.Client.GameObjects.Components
{
public override string Name => "ClientEntitySpawner";
private List<string> _prototypes = default!;
[DataField("prototypes")] private List<string> _prototypes = new() { "HVDummyWire" };
private List<IEntity> _entity = new();
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _prototypes, "prototypes", new List<string> { "HVDummyWire" });
}
private readonly List<IEntity> _entity = new();
public override void Initialize()
{

View File

@@ -7,7 +7,7 @@ using Content.Shared.GameObjects.Components.Items;
using Robust.Client.Graphics;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Clothing
@@ -17,13 +17,15 @@ namespace Content.Client.GameObjects.Components.Clothing
[ComponentReference(typeof(IItemComponent))]
public class ClothingComponent : ItemComponent
{
private FemaleClothingMask _femaleMask;
[DataField("femaleMask")]
private FemaleClothingMask _femaleMask = FemaleClothingMask.UniformFull;
public override string Name => "Clothing";
public override uint? NetID => ContentNetIDs.CLOTHING;
private string? _clothingEquippedPrefix;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("ClothingPrefix")]
public string? ClothingEquippedPrefix
{
get => _clothingEquippedPrefix;
@@ -34,6 +36,8 @@ namespace Content.Client.GameObjects.Components.Clothing
_clothingEquippedPrefix = value;
if(!Initialized) return;
if (!Owner.TryGetContainer(out IContainer? container))
return;
if (!container.Owner.TryGetComponent(out ClientInventoryComponent? inventory))
@@ -45,6 +49,12 @@ namespace Content.Client.GameObjects.Components.Clothing
}
}
public override void Initialize()
{
base.Initialize();
ClothingEquippedPrefix = ClothingEquippedPrefix;
}
[ViewVariables(VVAccess.ReadWrite)]
public FemaleClothingMask FemaleMask
{
@@ -52,14 +62,6 @@ namespace Content.Client.GameObjects.Components.Clothing
set => _femaleMask = value;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _femaleMask, "femaleMask", FemaleClothingMask.UniformFull);
serializer.DataField(this, p => p.ClothingEquippedPrefix, "ClothingPrefix", null);
}
public (RSI rsi, RSI.StateId stateId)? GetEquippedStateInfo(EquipmentSlotDefines.SlotFlags slot)
{
if (RsiPath == null)

View File

@@ -2,6 +2,7 @@ using Content.Shared.GameObjects.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,37 +11,16 @@ namespace Content.Client.GameObjects.Components
[UsedImplicitly]
public sealed class ComputerVisualizer : AppearanceVisualizer
{
[DataField("key")]
private string KeyboardState = "generic_key";
[DataField("screen")]
private string ScreenState = "generic";
[DataField("body")]
private string BodyState = "computer";
[DataField("bodyBroken")]
private string BodyBrokenState = "broken";
private string ScreenBroken = "computer_broken";
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("key", out var scalar))
{
KeyboardState = scalar.AsString();
}
if (node.TryGetNode("screen", out scalar))
{
ScreenState = scalar.AsString();
}
if (node.TryGetNode("body", out scalar))
{
BodyState = scalar.AsString();
}
if (node.TryGetNode("bodyBroken", out scalar))
{
BodyBrokenState = scalar.AsString();
}
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -3,6 +3,7 @@ using Content.Shared.GameObjects.Components.Conveyor;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -11,8 +12,11 @@ namespace Content.Client.GameObjects.Components.Conveyor
[UsedImplicitly]
public class ConveyorVisualizer : AppearanceVisualizer
{
[DataField("state_running")]
private string _stateRunning;
[DataField("state_stopped")]
private string _stateStopped;
[DataField("state_reversed")]
private string _stateReversed;
private void ChangeState(AppearanceComponent appearance)
@@ -35,15 +39,6 @@ namespace Content.Client.GameObjects.Components.Conveyor
sprite.LayerSetState(0, texture);
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateRunning = node.GetNode("state_running").AsString();
_stateStopped = node.GetNode("state_stopped").AsString();
_stateReversed = node.GetNode("state_reversed").AsString();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,8 +11,11 @@ namespace Content.Client.GameObjects.Components.Conveyor
[UsedImplicitly]
public class TwoWayLeverVisualizer : AppearanceVisualizer
{
[DataField("state_forward")]
private string _stateForward;
[DataField("state_off")]
private string _stateOff;
[DataField("state_reversed")]
private string _stateReversed;
private void ChangeState(AppearanceComponent appearance)
@@ -34,15 +38,6 @@ namespace Content.Client.GameObjects.Components.Conveyor
sprite.LayerSetState(0, texture);
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateForward = node.GetNode("state_forward").AsString();
_stateOff = node.GetNode("state_off").AsString();
_stateReversed = node.GetNode("state_reversed").AsString();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -5,6 +5,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;

View File

@@ -3,28 +3,63 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using static Content.Shared.GameObjects.Components.Disposal.SharedDisposalUnitComponent;
namespace Content.Client.GameObjects.Components.Disposal
{
[UsedImplicitly]
public class DisposalUnitVisualizer : AppearanceVisualizer
public class DisposalUnitVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "disposal_unit_animation";
[DataField("state_anchored", required: true)]
private string _stateAnchored;
[DataField("state_unanchored", required: true)]
private string _stateUnAnchored;
[DataField("state_charging", required: true)]
private string _stateCharging;
[DataField("overlay_charging", required: true)]
private string _overlayCharging;
[DataField("overlay_ready", required: true)]
private string _overlayReady;
[DataField("overlay_full", required: true)]
private string _overlayFull;
[DataField("overlay_engaged", required: true)]
private string _overlayEngaged;
[DataField("state_flush", required: true)]
private string _stateFlush;
[DataField("flush_sound", required: true)]
private string _flushSound;
[DataField("flush_time", required: true)]
private float _flushTime;
private Animation _flushAnimation;
void ISerializationHooks.AfterDeserialization()
{
_flushAnimation = new Animation {Length = TimeSpan.FromSeconds(_flushTime)};
var flick = new AnimationTrackSpriteFlick();
_flushAnimation.AnimationTracks.Add(flick);
flick.LayerKey = DisposalUnitVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(_stateFlush, 0));
var sound = new AnimationTrackPlaySound();
_flushAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_flushSound, 0));
}
private void ChangeState(AppearanceComponent appearance)
{
if (!appearance.TryGetData(Visuals.VisualState, out VisualState state))
@@ -106,34 +141,6 @@ namespace Content.Client.GameObjects.Components.Disposal
}
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateAnchored = node.GetNode("state_anchored").AsString();
_stateUnAnchored = node.GetNode("state_unanchored").AsString();
_stateCharging = node.GetNode("state_charging").AsString();
_overlayCharging = node.GetNode("overlay_charging").AsString();
_overlayReady = node.GetNode("overlay_ready").AsString();
_overlayFull = node.GetNode("overlay_full").AsString();
_overlayEngaged = node.GetNode("overlay_engaged").AsString();
_stateFlush = node.GetNode("state_flush").AsString();
var flushSound = node.GetNode("flush_sound").AsString();
var flushTime = node.GetNode("flush_time").AsFloat();
_flushAnimation = new Animation {Length = TimeSpan.FromSeconds(flushTime)};
var flick = new AnimationTrackSpriteFlick();
_flushAnimation.AnimationTracks.Add(flick);
flick.LayerKey = DisposalUnitVisualLayers.Base;
flick.KeyFrames.Add(new AnimationTrackSpriteFlick.KeyFrame(_stateFlush, 0));
var sound = new AnimationTrackPlaySound();
_flushAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(flushSound, 0));
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -3,6 +3,7 @@ using Content.Shared.GameObjects.Components.Disposal;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -11,8 +12,11 @@ namespace Content.Client.GameObjects.Components.Disposal
[UsedImplicitly]
public class DisposalVisualizer : AppearanceVisualizer
{
[DataField("state_free")]
private string _stateFree;
[DataField("state_anchored")]
private string _stateAnchored;
[DataField("state_broken")]
private string _stateBroken;
private void ChangeState(AppearanceComponent appearance)
@@ -47,15 +51,6 @@ namespace Content.Client.GameObjects.Components.Disposal
}
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_stateFree = node.GetNode("state_free").AsString();
_stateAnchored = node.GetNode("state_anchored").AsString();
_stateBroken = node.GetNode("state_broken").AsString();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -7,35 +7,35 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Doors
{
[UsedImplicitly]
public class AirlockVisualizer : AppearanceVisualizer
public class AirlockVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "airlock_animation";
[DataField("open_sound", required: true)]
private string _openSound = default!;
[DataField("close_sound", required: true)]
private string _closeSound = default!;
[DataField("deny_sound", required: true)]
private string _denySound = default!;
[DataField("animation_time")]
private float _delay = 0.8f;
private Animation CloseAnimation = default!;
private Animation OpenAnimation = default!;
private Animation DenyAnimation = default!;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var delay = 0.8f;
var openSound = node.GetNode("open_sound").AsString();
var closeSound = node.GetNode("close_sound").AsString();
var denySound = node.GetNode("deny_sound").AsString();
if (node.TryGetNode("animation_time", out var yamlNode))
{
delay = yamlNode.AsFloat();
}
CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(delay)};
CloseAnimation = new Animation {Length = TimeSpan.FromSeconds(_delay)};
{
var flick = new AnimationTrackSpriteFlick();
CloseAnimation.AnimationTracks.Add(flick);
@@ -54,10 +54,10 @@ namespace Content.Client.GameObjects.Components.Doors
var sound = new AnimationTrackPlaySound();
CloseAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(closeSound, 0));
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_closeSound, 0));
}
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(delay)};
OpenAnimation = new Animation {Length = TimeSpan.FromSeconds(_delay)};
{
var flick = new AnimationTrackSpriteFlick();
OpenAnimation.AnimationTracks.Add(flick);
@@ -76,7 +76,7 @@ namespace Content.Client.GameObjects.Components.Doors
var sound = new AnimationTrackPlaySound();
OpenAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(openSound, 0));
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_openSound, 0));
}
DenyAnimation = new Animation {Length = TimeSpan.FromSeconds(0.3f)};
@@ -88,7 +88,7 @@ namespace Content.Client.GameObjects.Components.Doors
var sound = new AnimationTrackPlaySound();
DenyAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(denySound, 0, () => AudioHelpers.WithVariation(0.05f)));
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_denySound, 0, () => AudioHelpers.WithVariation(0.05f)));
}
}

View File

@@ -1,6 +1,7 @@
using Content.Shared.GameObjects.Components.Explosion;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,17 +11,9 @@ namespace Content.Client.GameObjects.Components.Explosion
// ReSharper disable once InconsistentNaming
public class ClusterFlashVisualizer : AppearanceVisualizer
{
[DataField("state")]
private string _state;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state", out var state))
{
_state = state.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -1,6 +1,7 @@
using Content.Shared.GameObjects.Components.Fluids;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -9,24 +10,11 @@ namespace Content.Client.GameObjects.Components.Fluids
[UsedImplicitly]
public class SprayVisualizer : AppearanceVisualizer
{
[DataField("safety_on_state")]
private string _safetyOnState;
[DataField("safety_off_state")]
private string _safetyOffState;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("safety_on_state", out var safetyOn))
{
_safetyOnState = safetyOn.AsString();
}
if (node.TryGetNode("safety_off_state", out var safetyOff))
{
_safetyOffState = safetyOff.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -6,14 +6,39 @@ using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using YamlDotNet.RepresentationModel;
namespace Content.Client.GameObjects.Components.Gravity
{
[UsedImplicitly]
public class GravityGeneratorVisualizer : AppearanceVisualizer
public class GravityGeneratorVisualizer : AppearanceVisualizer, ISerializationHooks
{
private readonly Dictionary<GravityGeneratorStatus, string> _spriteMap = new();
[DataField("spritemap")]
private Dictionary<string, string> _rawSpriteMap = new();
private Dictionary<GravityGeneratorStatus, string> _spriteMap = new();
void ISerializationHooks.BeforeSerialization()
{
_rawSpriteMap = new Dictionary<string, string>();
foreach (var (status, sprite) in _spriteMap)
{
_rawSpriteMap.Add(status.ToString().ToLower(), sprite);
}
}
void ISerializationHooks.AfterDeserialization()
{
// Get Sprites for each status
foreach (var status in (GravityGeneratorStatus[]) Enum.GetValues(typeof(GravityGeneratorStatus)))
{
if (_rawSpriteMap.TryGetValue(status.ToString().ToLower(), out var sprite))
{
_spriteMap[status] = sprite;
}
}
}
public override void InitializeEntity(IEntity entity)
{
@@ -26,20 +51,6 @@ namespace Content.Client.GameObjects.Components.Gravity
sprite.LayerMapReserveBlank(GravityGeneratorVisualLayers.Core);
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
// Get Sprites for each status
foreach (var status in (GravityGeneratorStatus[]) Enum.GetValues(typeof(GravityGeneratorStatus)))
{
if (node.TryGetNode(status.ToString().ToLower(), out var sprite))
{
_spriteMap[status] = sprite.AsString();
}
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -28,6 +28,7 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
[ViewVariables] public InventoryInterfaceController InterfaceController { get; private set; } = default!;
[ComponentDependency]
private ISpriteComponent? _sprite;
private bool _playerAttached = false;
@@ -52,7 +53,7 @@ namespace Content.Client.GameObjects.Components.HUD.Inventory
InterfaceController = DynamicTypeFactory.CreateInstance<InventoryInterfaceController>(controllerType, args);
InterfaceController.Initialize();
if (Owner.TryGetComponent(out _sprite))
if (_sprite != null)
{
foreach (var mask in InventoryInstance.SlotMasks.OrderBy(s => InventoryInstance.SlotDrawingOrder(s)))
{

View File

@@ -6,7 +6,9 @@ using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using static Robust.Client.GameObjects.SpriteComponent;
namespace Content.Client.GameObjects.Components.IconSmoothing
@@ -25,9 +27,12 @@ namespace Content.Client.GameObjects.Components.IconSmoothing
[RegisterComponent]
public class IconSmoothComponent : Component
{
private string _smoothKey;
private string _stateBase;
private IconSmoothingMode _mode;
[DataField("key")]
private string _smoothKey = default;
[DataField("base")]
private string _stateBase = "";
[DataField("mode")]
private IconSmoothingMode _mode = IconSmoothingMode.Corners;
public override string Name => "IconSmooth";
@@ -63,15 +68,6 @@ namespace Content.Client.GameObjects.Components.IconSmoothing
Sprite = Owner.GetComponent<ISpriteComponent>();
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataFieldCached(ref _stateBase, "base", "");
serializer.DataFieldCached(ref _smoothKey, "key", null);
serializer.DataFieldCached(ref _mode, "mode", IconSmoothingMode.Corners);
}
/// <inheritdoc />
protected override void Startup()
{

View File

@@ -11,8 +11,8 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Instruments
@@ -35,19 +35,24 @@ namespace Content.Client.GameObjects.Components.Instruments
private InstrumentSystem _instrumentSystem = default!;
[DataField("program")]
private byte _instrumentProgram = 1;
[DataField("bank")]
private byte _instrumentBank;
private uint _sequenceDelay;
private uint _sequenceStartTick;
[DataField("allowPercussion")]
private bool _allowPercussion;
[DataField("allowProgramChange")]
private bool _allowProgramChange;
private bool _respectMidiLimits;
[DataField("respectMidiLimits")]
private bool _respectMidiLimits = true;
/// <summary>
/// A queue of MidiEvents to be sent to the server.
@@ -137,6 +142,7 @@ namespace Content.Client.GameObjects.Components.Instruments
/// Whether this instrument is handheld or not.
/// </summary>
[ViewVariables]
[DataField("handheld")]
public bool Handheld { get; set; } // TODO: Replace this by simply checking if the entity has an ItemComponent.
/// <summary>
@@ -263,17 +269,6 @@ namespace Content.Client.GameObjects.Components.Instruments
EndRenderer();
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(this, x => x.Handheld, "handheld", false);
serializer.DataField(ref _instrumentProgram, "program", (byte) 1);
serializer.DataField(ref _instrumentBank, "bank", (byte) 0);
serializer.DataField(ref _allowPercussion, "allowPercussion", false);
serializer.DataField(ref _allowProgramChange, "allowProgramChange", false);
serializer.DataField(ref _respectMidiLimits, "respectMidiLimits", true);
}
public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null)
{
base.HandleNetworkMessage(message, channel, session);

View File

@@ -5,7 +5,9 @@ using Content.Shared.GameObjects.Components.Interactable;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Timing;
using Robust.Shared.ViewVariables;
@@ -15,7 +17,8 @@ namespace Content.Client.GameObjects.Components.Interactable
public class MultiToolComponent : Component, IItemStatus
{
private ToolQuality _behavior;
private bool _statusShowBehavior;
[DataField("statusShowBehavior")]
private bool _statusShowBehavior = true;
[ViewVariables(VVAccess.ReadWrite)] private bool _uiUpdateNeeded;
[ViewVariables] public bool StatusShowBehavior => _statusShowBehavior;
@@ -24,12 +27,6 @@ namespace Content.Client.GameObjects.Components.Interactable
public override string Name => "MultiTool";
public override uint? NetID => ContentNetIDs.MULTITOOLS;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _statusShowBehavior, "statusShowBehavior", true);
}
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);

View File

@@ -26,10 +26,6 @@ namespace Content.Client.GameObjects.Components.Interactable
[ViewVariables] public bool Activated { get; private set; }
[ViewVariables] public override ToolQuality Qualities => _behavior;
public override void ExposeData(ObjectSerializer serializer)
{
}
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
base.HandleComponentState(curState, nextState);

View File

@@ -8,7 +8,9 @@ using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -23,10 +25,15 @@ namespace Content.Client.GameObjects.Components.Items
public override string Name => "Item";
public override uint? NetID => ContentNetIDs.ITEM;
[ViewVariables] protected ResourcePath RsiPath;
[ViewVariables]
[DataField("sprite")]
protected ResourcePath RsiPath;
[ViewVariables(VVAccess.ReadWrite)] protected Color Color;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("color")]
protected Color Color = Color.White;
[DataField("HeldPrefix")]
private string _equippedPrefix;
[ViewVariables(VVAccess.ReadWrite)]
@@ -60,15 +67,6 @@ namespace Content.Client.GameObjects.Components.Items
return null;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataFieldCached(ref Color, "color", Color.White);
serializer.DataFieldCached(ref RsiPath, "sprite", null);
serializer.DataFieldCached(ref _equippedPrefix, "HeldPrefix", null);
}
protected RSI GetRSI()
{
return _resourceCache.GetResource<RSIResource>(SharedSpriteComponent.TextureRoot / RsiPath).RSI;

View File

@@ -1,6 +1,6 @@
#nullable enable
using Content.Shared.GameObjects.Components.Kitchen;
using Content.Shared.Interfaces.GameObjects.Components;
using Content.Shared.Kitchen;
using Robust.Shared.GameObjects;
namespace Content.Client.GameObjects.Components.Kitchen

View File

@@ -12,6 +12,7 @@ using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components
@@ -22,37 +23,43 @@ namespace Content.Client.GameObjects.Components
/// This AnimationTrack derivative does not rely on keyframes since it often needs to have a randomized duration.
/// </summary>
[Serializable]
public abstract class LightBehaviourAnimationTrack : AnimationTrackProperty, IExposeData
[ImplicitDataDefinitionForInheritors]
public abstract class LightBehaviourAnimationTrack : AnimationTrackProperty
{
[ViewVariables] public string ID { get; set; }
[ViewVariables] public string Property { get; protected set; }
[ViewVariables] public bool IsLooped { get; set; }
[ViewVariables] public bool Enabled { get; set; }
[ViewVariables] public float StartValue { get; set; }
[ViewVariables] public float EndValue { get; set; }
[ViewVariables] public float MinDuration { get; set; }
[ViewVariables] public float MaxDuration { get; set; }
[ViewVariables] public AnimationInterpolationMode InterpolateMode { get; set; }
[DataField("id")] [ViewVariables] public string ID { get; set; } = string.Empty;
[DataField("property")]
[ViewVariables]
public virtual string Property { get; protected set; } = "Radius";
[DataField("isLooped")] [ViewVariables] public bool IsLooped { get; set; }
[DataField("enabled")] [ViewVariables] public bool Enabled { get; set; }
[DataField("startValue")] [ViewVariables] public float StartValue { get; set; }
[DataField("endValue")]
[ViewVariables]
public float EndValue { get; set; } = 2f;
[DataField("minDuration")]
[ViewVariables]
public float MinDuration { get; set; } = -1f;
[DataField("maxDuration")]
[ViewVariables]
public float MaxDuration { get; set; } = 2f;
[DataField("interpolate")]
[ViewVariables]
public AnimationInterpolationMode InterpolateMode { get; set; } = AnimationInterpolationMode.Linear;
[ViewVariables] protected float MaxTime { get; set; }
protected PointLightComponent Light = default;
protected IRobustRandom RobustRandom = default;
protected PointLightComponent Light;
protected IRobustRandom RobustRandom;
private float _maxTime = default;
public virtual void ExposeData(ObjectSerializer serializer)
{
serializer.DataField(this, x => x.ID, "id", string.Empty);
serializer.DataField(this, x => x.IsLooped, "isLooped", false);
serializer.DataField(this, x => x.Enabled, "enabled", false);
serializer.DataField(this, x => x.StartValue, "startValue", 0f);
serializer.DataField(this, x => x.EndValue, "endValue", 2f);
serializer.DataField(this, x => x.MinDuration, "minDuration", -1f);
serializer.DataField(this, x => x.MaxDuration, "maxDuration", 2f);
serializer.DataField(this, x => x.Property, "property", "Radius");
serializer.DataField(this, x => x.InterpolateMode, "interpolate", AnimationInterpolationMode.Linear);
}
public void Initialize(PointLightComponent light)
{
Light = light;
@@ -212,10 +219,10 @@ namespace Content.Client.GameObjects.Components
[UsedImplicitly]
public class RandomizeBehaviour : LightBehaviourAnimationTrack
{
private object _randomValue1 = default;
private object _randomValue2 = default;
private object _randomValue3 = default;
private object _randomValue4 = default;
private object _randomValue1;
private object _randomValue2;
private object _randomValue3;
private object _randomValue4;
public override void OnInitialize()
{
@@ -275,11 +282,16 @@ namespace Content.Client.GameObjects.Components
/// A light behaviour that cycles through a list of colors.
/// </summary>
[UsedImplicitly]
public class ColorCycleBehaviour : LightBehaviourAnimationTrack
[DataDefinition]
public class ColorCycleBehaviour : LightBehaviourAnimationTrack, ISerializationHooks
{
public List<Color> ColorsToCycle { get; set; }
[DataField("property")]
[ViewVariables]
public override string Property { get; protected set; } = "Color";
private int _colorIndex = 0;
[DataField("colors")] public List<Color> ColorsToCycle { get; set; } = new();
private int _colorIndex;
public override void OnStart()
{
@@ -320,23 +332,13 @@ namespace Content.Client.GameObjects.Components
return (-1, playingTime);
}
public override void ExposeData(ObjectSerializer serializer)
void ISerializationHooks.AfterDeserialization()
{
serializer.DataField(this, x => x.ID, "id", string.Empty);
serializer.DataField(this, x => x.IsLooped, "isLooped", false);
serializer.DataField(this, x => x.Enabled, "enabled", false);
serializer.DataField(this, x => x.MinDuration, "minDuration", -1f);
serializer.DataField(this, x => x.MaxDuration, "maxDuration", 2f);
serializer.DataField(this, x => x.InterpolateMode, "interpolate", AnimationInterpolationMode.Linear);
ColorsToCycle = serializer.ReadDataField("colors", new List<Color>());
Property = "Color";
if (ColorsToCycle.Count < 2)
{
throw new InvalidOperationException($"{nameof(ColorCycleBehaviour)} has less than 2 colors to cycle");
}
}
}
#endregion
@@ -344,11 +346,11 @@ namespace Content.Client.GameObjects.Components
/// A component which applies a specific behaviour to a PointLightComponent on its owner.
/// </summary>
[RegisterComponent]
public class LightBehaviourComponent : SharedLightBehaviourComponent
public class LightBehaviourComponent : SharedLightBehaviourComponent, ISerializationHooks
{
private const string KeyPrefix = nameof(LightBehaviourComponent);
private class AnimationContainer
public class AnimationContainer
{
public AnimationContainer(int key, Animation animation, LightBehaviourAnimationTrack track)
{
@@ -363,16 +365,36 @@ namespace Content.Client.GameObjects.Components
public LightBehaviourAnimationTrack LightBehaviour { get; set; }
}
[ViewVariables(VVAccess.ReadOnly)]
[DataField("behaviours")]
public readonly List<LightBehaviourAnimationTrack> Behaviours = new();
[ViewVariables(VVAccess.ReadOnly)]
private readonly List<AnimationContainer> _animations = new();
private float _originalRadius = default;
private float _originalEnergy = default;
private Angle _originalRotation = default;
private Color _originalColor = default;
private bool _originalEnabled = default;
private PointLightComponent _lightComponent = default;
private AnimationPlayerComponent _animationPlayer = default;
private float _originalRadius;
private float _originalEnergy;
private Angle _originalRotation;
private Color _originalColor;
private bool _originalEnabled;
private PointLightComponent _lightComponent;
private AnimationPlayerComponent _animationPlayer;
void ISerializationHooks.AfterDeserialization()
{
var key = 0;
foreach (var behaviour in Behaviours)
{
var animation = new Animation()
{
AnimationTracks = { behaviour }
};
_animations.Add(new AnimationContainer(key, animation, behaviour));
key++;
}
}
protected override void Startup()
{
@@ -380,7 +402,7 @@ namespace Content.Client.GameObjects.Components
CopyLightSettings();
_animationPlayer = Owner.EnsureComponent<AnimationPlayerComponent>();
_animationPlayer.AnimationCompleted += s => OnAnimationCompleted(s);
_animationPlayer.AnimationCompleted += OnAnimationCompleted;
foreach (var container in _animations)
{
@@ -516,24 +538,5 @@ namespace Content.Client.GameObjects.Components
StartLightBehaviour(behaviour.ID);
}
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
var behaviours = serializer.ReadDataField("behaviours", new List<LightBehaviourAnimationTrack>());
var key = 0;
foreach (LightBehaviourAnimationTrack behaviour in behaviours)
{
var animation = new Animation()
{
AnimationTracks = { behaviour }
};
_animations.Add(new AnimationContainer(key, animation, behaviour));
key++;
}
}
}
}

View File

@@ -29,7 +29,8 @@ namespace Content.Client.GameObjects.Components.Mobs
private Vector2 _currentKick;
private float _lastKickTime;
[ComponentDependency] private readonly EyeComponent? _eye = null;
[ComponentDependency]
private readonly EyeComponent? _eye = default;
// Basically I needed a way to chain this effect for the attack lunge animation.
// Sorry!

View File

@@ -1,36 +1,52 @@
#nullable enable
using System.Collections.Generic;
using Content.Shared.GameObjects;
using Content.Shared.GameObjects.Components.Mobs;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Client.GameObjects.Components.Mobs
{
[UsedImplicitly]
public sealed class DamageStateVisualizer : AppearanceVisualizer
public sealed class DamageStateVisualizer : AppearanceVisualizer, ISerializationHooks
{
private DamageState _data = DamageState.Alive;
private readonly Dictionary<DamageState, string> _stateMap = new();
private Dictionary<DamageState, string> _stateMap = new();
private int? _originalDrawDepth;
public override void LoadData(YamlMappingNode node)
[DataField("normal")]
private string? normal;
[DataField("crit")]
private string? crit;
[DataField("dead")]
private string? dead;
void ISerializationHooks.BeforeSerialization()
{
base.LoadData(node);
if (node.TryGetNode("normal", out var normal))
_stateMap.TryGetValue(DamageState.Alive, out normal);
_stateMap.TryGetValue(DamageState.Critical, out crit);
_stateMap.TryGetValue(DamageState.Dead, out dead);
}
void ISerializationHooks.AfterDeserialization()
{
if (normal != null)
{
_stateMap.Add(DamageState.Alive, normal.AsString());
_stateMap.Add(DamageState.Alive, normal);
}
if (node.TryGetNode("crit", out var crit))
if (crit != null)
{
_stateMap.Add(DamageState.Critical, crit.AsString());
_stateMap.Add(DamageState.Critical, crit);
}
if (node.TryGetNode("dead", out var dead))
if (dead != null)
{
_stateMap.Add(DamageState.Dead, dead.AsString());
_stateMap.Add(DamageState.Dead, dead);
}
}

View File

@@ -2,6 +2,7 @@
using Content.Shared.GameObjects.Components.Morgue;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,35 +11,16 @@ namespace Content.Client.GameObjects.Components.Morgue
[UsedImplicitly]
public sealed class CrematoriumVisualizer : AppearanceVisualizer
{
[DataField("state_open")]
private string _stateOpen = "";
[DataField("state_closed")]
private string _stateClosed = "";
[DataField("light_contents")]
private string _lightContents = "";
[DataField("light_burning")]
private string _lightBurning = "";
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state_open", out var child))
{
_stateOpen = child.AsString();
}
if (node.TryGetNode("state_closed", out child))
{
_stateClosed = child.AsString();
}
if (node.TryGetNode("light_contents", out child))
{
_lightContents = child.AsString();
}
if (node.TryGetNode("light_burning", out child))
{
_lightBurning = child.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -1,6 +1,8 @@
#nullable enable
using System.Runtime.CompilerServices;
using Content.Shared.GameObjects.Components.Morgue;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -8,40 +10,18 @@ namespace Content.Client.GameObjects.Components.Storage
{
public sealed class MorgueVisualizer : AppearanceVisualizer
{
[DataField("state_open")]
private string _stateOpen = "";
[DataField("state_closed")]
private string _stateClosed = "";
[DataField("light_contents")]
private string _lightContents = "";
[DataField("light_mob")]
private string _lightMob = "";
[DataField("light_soul")]
private string _lightSoul = "";
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state_open", out var child))
{
_stateOpen = child.AsString();
}
if (node.TryGetNode("state_closed", out child))
{
_stateClosed = child.AsString();
}
if (node.TryGetNode("light_contents", out child))
{
_lightContents = child.AsString();
}
if (node.TryGetNode("light_mob", out child))
{
_lightMob = child.AsString();
}
if (node.TryGetNode("light_soul", out child))
{
_lightSoul = child.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -1,4 +1,6 @@
using System;
using Content.Client.GameObjects.Components.Items;
using Content.Shared.GameObjects.Components.Movement;
using Content.Shared.GameObjects.Components.Portal;
using JetBrains.Annotations;
using Robust.Client.GameObjects;

View File

@@ -1,6 +1,7 @@
using Content.Shared.GameObjects.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -9,30 +10,13 @@ namespace Content.Client.GameObjects.Components.Nutrition
[UsedImplicitly]
public class BurnStateVisualizer : AppearanceVisualizer
{
[DataField("burntIcon")]
private string _burntIcon = "burnt-icon";
[DataField("litIcon")]
private string _litIcon = "lit-icon";
[DataField("unlitIcon")]
private string _unlitIcon = "icon";
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("unlitIcon", out var unlitIcon))
{
_unlitIcon = unlitIcon.AsString();
}
if (node.TryGetNode("litIcon", out var litIcon))
{
_litIcon = litIcon.AsString();
}
if (node.TryGetNode("burntIcon", out var burntIcon))
{
_burntIcon = burntIcon.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);
@@ -62,4 +46,4 @@ namespace Content.Client.GameObjects.Components.Nutrition
}
}
}
}
}

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,6 +11,7 @@ namespace Content.Client.GameObjects.Components.Nutrition
[UsedImplicitly]
public class CreamPiedVisualizer : AppearanceVisualizer
{
[DataField("state")]
private string _state;
public override void InitializeEntity(IEntity entity)
@@ -23,16 +25,6 @@ namespace Content.Client.GameObjects.Components.Nutrition
sprite.LayerSetVisible(CreamPiedVisualLayers.Pie, false);
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state", out var otherNode))
{
_state = otherNode.AsString();
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Nutrition;
using Content.Shared.Utility;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -12,25 +13,12 @@ namespace Content.Client.GameObjects.Components.Nutrition
[UsedImplicitly]
public sealed class FoodContainerVisualizer : AppearanceVisualizer
{
[DataField("base_state", required: true)]
private string _baseState;
[DataField("steps", required: true)]
private int _steps;
private FoodContainerVisualMode _mode;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_baseState = node.GetNode("base_state").AsString();
_steps = node.GetNode("steps").AsInt();
try
{
_mode = node.GetNode("mode").AsEnum<FoodContainerVisualMode>();
}
catch (KeyNotFoundException)
{
_mode = FoodContainerVisualMode.Rounded;
}
}
[DataField("mode")]
private FoodContainerVisualMode _mode = FoodContainerVisualMode.Rounded;
public override void OnChangeData(AppearanceComponent component)
{

View File

@@ -2,6 +2,7 @@ using Content.Shared.GameObjects.Components.Nutrition;
using Content.Shared.Utility;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,15 +11,9 @@ namespace Content.Client.GameObjects.Components.Nutrition
[UsedImplicitly]
public sealed class DrinkFoodVisualizer : AppearanceVisualizer
{
[DataField("steps")]
private int _steps;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_steps = node.GetNode("steps").AsInt();
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -14,6 +15,7 @@ namespace Content.Client.GameObjects.Components.PDA
/// <summary>
/// The base PDA sprite state, eg. "pda", "pda-clown"
/// </summary>
[DataField("state")]
private string _state;
private enum PDAVisualLayers : byte
@@ -23,15 +25,6 @@ namespace Content.Client.GameObjects.Components.PDA
IDLight
}
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state", out var child))
{
_state = child.AsString();
}
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);
@@ -62,7 +55,5 @@ namespace Content.Client.GameObjects.Components.PDA
}
}
}
}

View File

@@ -4,32 +4,26 @@ using Content.Shared.GameObjects.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components
{
[UsedImplicitly]
public class ParticleAcceleratorPartVisualizer : AppearanceVisualizer
[DataDefinition]
public class ParticleAcceleratorPartVisualizer : AppearanceVisualizer, ISerializationHooks
{
private readonly Dictionary<ParticleAcceleratorVisualState, string> _states = new();
[DataField("baseState", required: true)]
private string _baseState;
private Dictionary<ParticleAcceleratorVisualState, string> _states = new();
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
if (!serializer.TryReadDataField<string>("baseState", out var baseState))
{
throw new PrototypeLoadException("No baseState property specified for ParticleAcceleratorPartVisualizer");
}
_states.Add(ParticleAcceleratorVisualState.Powered, baseState+"p");
_states.Add(ParticleAcceleratorVisualState.Level0, baseState+"p0");
_states.Add(ParticleAcceleratorVisualState.Level1, baseState+"p1");
_states.Add(ParticleAcceleratorVisualState.Level2, baseState+"p2");
_states.Add(ParticleAcceleratorVisualState.Level3, baseState+"p3");
_states.Add(ParticleAcceleratorVisualState.Powered, _baseState+"p");
_states.Add(ParticleAcceleratorVisualState.Level0, _baseState+"p0");
_states.Add(ParticleAcceleratorVisualState.Level1, _baseState+"p1");
_states.Add(ParticleAcceleratorVisualState.Level2, _baseState+"p2");
_states.Add(ParticleAcceleratorVisualState.Level3, _baseState+"p3");
}
public override void InitializeEntity(IEntity entity)

View File

@@ -9,32 +9,21 @@ using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Power.ApcNetComponents.PowerReceiverUsers
{
[UsedImplicitly]
public class PoweredLightVisualizer : AppearanceVisualizer
{
private float _minBlinkingTime;
private float _maxBlinkingTime;
private string? _blinkingSound;
[DataField("minBlinkingTime")] private float _minBlinkingTime = 0.5f;
[DataField("maxBlinkingTime")] private float _maxBlinkingTime = 2;
[DataField("blinkingSound")] private string? _blinkingSound;
private bool _wasBlinking;
private Action<string>? _blinkingCallback;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
var serializer = YamlObjectSerializer.NewReader(node);
serializer.DataField(ref _minBlinkingTime, "minBlinkingTime", 0.5f);
serializer.DataField(ref _maxBlinkingTime, "maxBlinkingTime", 2.0f);
serializer.DataField(ref _blinkingSound, "blinkingSound", null);
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);

View File

@@ -20,10 +20,8 @@ namespace Content.Client.GameObjects.Components.Power
private Animation _insertingPlasmaAnimation;
private Animation _insertingPlasticAnimation;
public override void LoadData(YamlMappingNode node)
public AutolatheVisualizer()
{
base.LoadData(node);
_buildingAnimation = PopulateAnimation("building", "building_unlit", 0.5f);
_insertingMetalAnimation = PopulateAnimation("inserting_metal", "inserting_unlit", 0.5f);
_insertingGlassAnimation = PopulateAnimation("inserting_glass", "inserting_unlit", 0.5f);
@@ -123,6 +121,7 @@ namespace Content.Client.GameObjects.Components.Power
var glowingPartsVisible = !(component.TryGetData(PowerDeviceVisuals.Powered, out bool powered) && !powered);
sprite.LayerSetVisible(AutolatheVisualLayers.BaseUnlit, glowingPartsVisible);
}
public enum AutolatheVisualLayers : byte
{
Base,

View File

@@ -1,7 +1,9 @@
using System.Diagnostics;
using Content.Shared.GameObjects.Components.Power;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,15 +12,9 @@ namespace Content.Client.GameObjects.Components.Power
[UsedImplicitly]
public class PowerCellVisualizer : AppearanceVisualizer
{
[DataField("prefix")]
private string _prefix;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_prefix = node.GetNode("prefix").AsString();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -20,10 +20,8 @@ namespace Content.Client.GameObjects.Components.Power
private Animation _insertingPlasmaAnimation;
private Animation _insertingPlasticAnimation;
public override void LoadData(YamlMappingNode node)
public ProtolatheVisualizer()
{
base.LoadData(node);
_buildingAnimation = PopulateAnimation("building", "building_unlit", 0.8f);
_insertingMetalAnimation = PopulateAnimation("inserting_metal", "inserting_unlit", 0.8f);
_insertingGlassAnimation = PopulateAnimation("inserting_glass", "inserting_unlit", 0.8f);
@@ -123,6 +121,7 @@ namespace Content.Client.GameObjects.Components.Power
var glowingPartsVisible = !(component.TryGetData(PowerDeviceVisuals.Powered, out bool powered) && !powered);
sprite.LayerSetVisible(ProtolatheVisualLayers.BaseUnlit, glowingPartsVisible);
}
public enum ProtolatheVisualLayers : byte
{
Base,

View File

@@ -4,19 +4,19 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
namespace Content.Client.GameObjects.Components
{
[UsedImplicitly]
public class RadiationCollectorVisualizer : AppearanceVisualizer
public class RadiationCollectorVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "radiationcollector_animation";
private Animation ActivateAnimation;
private Animation DeactiveAnimation;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
ActivateAnimation = new Animation {Length = TimeSpan.FromSeconds(0.8f)};
{
@@ -51,7 +51,6 @@ namespace Content.Client.GameObjects.Components
}
}
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);
@@ -91,7 +90,6 @@ namespace Content.Client.GameObjects.Components
break;
}
}
}
public enum RadiationCollectorVisualLayers : byte
{

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,24 +11,11 @@ namespace Content.Client.GameObjects.Components.Recycling
[UsedImplicitly]
public class RecyclerVisualizer : AppearanceVisualizer
{
[DataField("state_clean")]
private string _stateClean;
[DataField("state_bloody")]
private string _stateBloody;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state_clean", out var child))
{
_stateClean = child.AsString();
}
if (node.TryGetNode("state_bloody", out child))
{
_stateBloody = child.AsString();
}
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -1,6 +1,8 @@
using Content.Client.GameObjects.Components.IconSmoothing;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
using static Robust.Client.GameObjects.SpriteComponent;
@@ -13,14 +15,8 @@ namespace Content.Client.GameObjects.Components
public override string Name => "ReinforcedWall";
[ViewVariables(VVAccess.ReadWrite)]
private string _reinforcedStateBase;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _reinforcedStateBase, "reinforcedBase", null);
}
[DataField("reinforcedBase")]
private string _reinforcedStateBase = default;
protected override void Startup()
{

View File

@@ -8,7 +8,7 @@ using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Sound
{
@@ -19,6 +19,13 @@ namespace Content.Client.GameObjects.Components.Sound
private readonly Dictionary<ScheduledSound, IPlayingAudioStream> _audioStreams = new();
[DataField("schedules", true)]
private List<ScheduledSound> _scheduledSounds
{
set => value.ForEach(AddScheduledSound);
get => new();
}
public override void StopAllSounds()
{
foreach (var kvp in _audioStreams)
@@ -94,15 +101,5 @@ namespace Content.Client.GameObjects.Components.Sound
base.Initialize();
SoundSystem.OcclusionCollisionMask = (int) CollisionGroup.Impassable;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataReadFunction(
"schedules",
new List<ScheduledSound>(),
schedules => schedules.ForEach(AddScheduledSound));
}
}
}

View File

@@ -6,6 +6,7 @@ using Content.Shared.Utility;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -59,6 +60,7 @@ namespace Content.Client.GameObjects.Components
/// Sprite layers used in stack visualizer. Sprites first in layer correspond to lower stack states
/// e.g. <code>_spriteLayers[0]</code> is lower stack level than <code>_spriteLayers[1]</code>.
/// </summary>
[DataField("stackLayers")]
private readonly List<string> _spriteLayers = new();
/// <summary>
@@ -74,32 +76,11 @@ namespace Content.Client.GameObjects.Components
/// </list>
///
/// </summary>
[DataField("composite")]
private bool _isComposite;
[DataField("sprite")]
private ResourcePath? _spritePath;
public override void LoadData(YamlMappingNode mapping)
{
base.LoadData(mapping);
if (mapping.TryGetNode<YamlSequenceNode>("stackLayers", out var spriteSequenceNode))
{
foreach (var yamlNode in spriteSequenceNode)
{
_spriteLayers.Add(((YamlScalarNode) yamlNode).Value!);
}
}
if (mapping.TryGetNode<YamlScalarNode>("composite", out var transparent))
{
_isComposite = transparent.AsBool();
}
if (mapping.TryGetNode<YamlScalarNode>("sprite", out var spritePath))
{
_spritePath = spritePath.AsResourcePath();
}
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -5,6 +5,8 @@ using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using static Robust.Shared.Utility.SpriteSpecifier;
@@ -12,21 +14,15 @@ using static Robust.Shared.Utility.SpriteSpecifier;
namespace Content.Client.GameObjects.Components.Storage
{
[UsedImplicitly]
public class BagOpenCloseVisualizer : AppearanceVisualizer
public class BagOpenCloseVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string OpenIcon = "openIcon";
[DataField(OpenIcon)]
private string? _openIcon;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
if (node.TryGetNode<YamlScalarNode>(OpenIcon, out var openIconNode))
{
_openIcon = openIconNode.Value;
}
else
{
if(_openIcon == null){
Logger.Warning("BagOpenCloseVisualizer is useless with no `openIcon`");
}
}

View File

@@ -2,6 +2,7 @@
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -10,30 +11,13 @@ namespace Content.Client.GameObjects.Components.Storage
[UsedImplicitly]
public sealed class StorageVisualizer : AppearanceVisualizer
{
[DataField("state")]
private string _stateBase;
[DataField("state_open")]
private string _stateOpen;
[DataField("state_closed")]
private string _stateClosed;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
if (node.TryGetNode("state", out var child))
{
_stateBase = child.AsString();
}
if (node.TryGetNode("state_open", out child))
{
_stateOpen = child.AsString();
}
if (node.TryGetNode("state_closed", out child))
{
_stateClosed = child.AsString();
}
}
public override void InitializeEntity(IEntity entity)
{
if (!entity.TryGetComponent(out ISpriteComponent sprite))

View File

@@ -4,25 +4,23 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.GameObjects.Components.Trigger
{
[UsedImplicitly]
public class TimerTriggerVisualizer : AppearanceVisualizer
public class TimerTriggerVisualizer : AppearanceVisualizer, ISerializationHooks
{
private const string AnimationKey = "priming_animation";
[DataField("countdown_sound", required: true)]
private string _countdownSound;
private Animation PrimingAnimation;
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
var countdownSound = node.GetNode("countdown_sound").AsString();
PrimingAnimation = new Animation { Length = TimeSpan.MaxValue };
{
var flick = new AnimationTrackSpriteFlick();
@@ -32,7 +30,7 @@ namespace Content.Client.GameObjects.Components.Trigger
var sound = new AnimationTrackPlaySound();
PrimingAnimation.AnimationTracks.Add(sound);
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(countdownSound, 0));
sound.KeyFrames.Add(new AnimationTrackPlaySound.KeyFrame(_countdownSound, 0));
}
}

View File

@@ -4,14 +4,14 @@ using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using static Content.Shared.GameObjects.Components.VendingMachines.SharedVendingMachineComponent;
namespace Content.Client.GameObjects.Components.VendingMachines
{
[UsedImplicitly]
public sealed class VendingMachineVisualizer : AppearanceVisualizer
public sealed class VendingMachineVisualizer : AppearanceVisualizer, ISerializationHooks
{
// TODO: Should default to off or broken if damaged
//
@@ -37,41 +37,53 @@ namespace Content.Client.GameObjects.Components.VendingMachines
{"broken", VendingMachineVisualLayers.Unlit},
};
[DataField("screen")]
private bool _screen;
[DataField("normal")]
private bool _normal;
[DataField("normalUnshaded")]
private bool _normalUnshaded;
[DataField("eject")]
private bool _eject;
[DataField("ejectUnshaded")]
private bool _ejectUnshaded;
[DataField("deny")]
private bool _deny;
[DataField("denyUnshaded")]
private bool _denyUnshaded;
[DataField("broken")]
private bool _broken;
[DataField("brokenUnshaded")]
private bool _brokenUnshaded;
private readonly Dictionary<string, Animation> _animations = new();
public override void LoadData(YamlMappingNode node)
void ISerializationHooks.AfterDeserialization()
{
base.LoadData(node);
_baseStates = new Dictionary<string, bool>
// Used a dictionary so the yaml can adhere to the style-guide and the texture states can be clear
var states = new Dictionary<string, bool>
{
{"off", true},
{"screen", _screen},
{"normal", _normal},
{"normal-unshaded", _normalUnshaded},
{"eject", _eject},
{"eject-unshaded", _ejectUnshaded},
{"deny", _deny},
{"deny-unshaded", _denyUnshaded},
{"broken", _broken},
{"broken-unshaded", _brokenUnshaded},
};
// Used a dictionary so the yaml can adhere to the style-guide and the texture states can be clear
var states = new Dictionary<string, string>
{
{"screen", "screen"},
{"normal", "normal"},
{"normalUnshaded", "normal-unshaded"},
{"eject", "eject"},
{"ejectUnshaded", "eject-unshaded"},
{"deny", "deny"},
{"denyUnshaded", "deny-unshaded"},
{"broken", "broken"},
{"brokenUnshaded", "broken-unshaded"},
};
foreach (var (state, textureState) in states)
{
if (!node.TryGetNode(state, out var yamlNode))
{
_baseStates[textureState] = false;
continue;
}
_baseStates.Add(textureState, yamlNode.AsBool());
}
_baseStates = states;
if (_baseStates["deny"])
{

View File

@@ -13,7 +13,9 @@ using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
@@ -87,14 +89,7 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels
[ViewVariables]
public (int count, int max)? MagazineCount { get; private set; }
[ViewVariables(VVAccess.ReadWrite)] private bool _isLmgAlarmAnimation;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _isLmgAlarmAnimation, "lmg_alarm_animation", false);
}
[ViewVariables(VVAccess.ReadWrite)] [DataField("lmg_alarm_animation")] private bool _isLmgAlarmAnimation = default;
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{

View File

@@ -3,6 +3,7 @@ using Content.Shared.Utility;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
@@ -12,18 +13,13 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged.Barrels.Visualize
public sealed class MagVisualizer : AppearanceVisualizer
{
private bool _magLoaded;
[DataField("magState")]
private string _magState;
[DataField("steps")]
private int _magSteps;
[DataField("zeroVisible")]
private bool _zeroVisible;
public override void LoadData(YamlMappingNode node)
{
base.LoadData(node);
_magState = node.GetNode("magState").AsString();
_magSteps = node.GetNode("steps").AsInt();
_zeroVisible = node.GetNode("zeroVisible").AsBool();
}
public override void InitializeEntity(IEntity entity)
{
base.InitializeEntity(entity);

View File

@@ -3,7 +3,7 @@ using Content.Client.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using static Content.Client.GameObjects.Components.IconSmoothing.IconSmoothComponent;
namespace Content.Client.GameObjects.Components
@@ -12,7 +12,8 @@ namespace Content.Client.GameObjects.Components
[ComponentReference(typeof(SharedWindowComponent))]
public sealed class WindowComponent : SharedWindowComponent
{
private string _stateBase;
[DataField("base")]
private string _stateBase = default;
private ISpriteComponent _sprite;
private SnapGridComponent _snapGrid;
@@ -101,13 +102,6 @@ namespace Content.Client.GameObjects.Components
return null;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _stateBase, "base", null);
}
}
[SuppressMessage("ReSharper", "InconsistentNaming")]