Update trivial components to use auto comp states (#20539)

This commit is contained in:
DrSmugleaf
2023-09-28 16:20:29 -07:00
committed by GitHub
parent 14cfe44ece
commit a44fa86b68
158 changed files with 806 additions and 2866 deletions

View File

@@ -1,7 +1,7 @@
using Content.Shared.Access;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.AccessOverriderComponent; using static Content.Shared.Access.Components.AccessOverriderComponent;
@@ -23,7 +23,7 @@ namespace Content.Client.Access.UI
{ {
base.Open(); base.Open();
List<string> accessLevels; List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<AccessOverriderComponent>(Owner, out var accessOverrider)) if (EntMan.TryGetComponent<AccessOverriderComponent>(Owner, out var accessOverrider))
{ {
@@ -33,7 +33,7 @@ namespace Content.Client.Access.UI
else else
{ {
accessLevels = new List<string>(); accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!"); _accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!");
} }

View File

@@ -21,7 +21,7 @@ namespace Content.Client.Access.UI
private readonly Dictionary<string, Button> _accessButtons = new(); private readonly Dictionary<string, Button> _accessButtons = new();
public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager, public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager,
List<string> accessLevels) List<ProtoId<AccessLevelPrototype>> accessLevels)
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -31,7 +31,7 @@ namespace Content.Client.Access.UI
foreach (var access in accessLevels) foreach (var access in accessLevels)
{ {
if (!prototypeManager.TryIndex<AccessLevelPrototype>(access, out var accessLevel)) if (!prototypeManager.TryIndex(access, out var accessLevel))
{ {
_logMill.Error($"Unable to find accesslevel for {access}"); _logMill.Error($"Unable to find accesslevel for {access}");
continue; continue;

View File

@@ -1,8 +1,8 @@
using Content.Shared.Access;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Content.Shared.CrewManifest; using Content.Shared.CrewManifest;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.IdCardConsoleComponent; using static Content.Shared.Access.Components.IdCardConsoleComponent;
@@ -23,7 +23,7 @@ namespace Content.Client.Access.UI
protected override void Open() protected override void Open()
{ {
base.Open(); base.Open();
List<string> accessLevels; List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<IdCardConsoleComponent>(Owner, out var idCard)) if (EntMan.TryGetComponent<IdCardConsoleComponent>(Owner, out var idCard))
{ {
@@ -32,7 +32,7 @@ namespace Content.Client.Access.UI
} }
else else
{ {
accessLevels = new List<string>(); accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_idCardConsoleSystem.Log.Error($"No IdCardConsole component found for {EntMan.ToPrettyString(Owner)}!"); _idCardConsoleSystem.Log.Error($"No IdCardConsole component found for {EntMan.ToPrettyString(Owner)}!");
} }

View File

@@ -28,7 +28,7 @@ namespace Content.Client.Access.UI
private string? _lastJobProto; private string? _lastJobProto;
public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager, public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager,
List<string> accessLevels) List<ProtoId<AccessLevelPrototype>> accessLevels)
{ {
RobustXamlLoader.Load(this); RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);

View File

@@ -1,10 +1,8 @@
using System.Linq; using System.Linq;
using Content.Shared.Alert; using Content.Shared.Alert;
using Content.Shared.Mobs.Systems;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Client.Alerts; namespace Content.Client.Alerts;
@@ -27,7 +25,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached); SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached); SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, ComponentHandleState>(ClientAlertsHandleState); SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
} }
protected override void LoadPrototypes() protected override void LoadPrototypes()
{ {
@@ -65,16 +63,10 @@ public sealed class ClientAlertsSystem : AlertsSystem
SyncAlerts?.Invoke(this, alertsComponent.Alerts); SyncAlerts?.Invoke(this, alertsComponent.Alerts);
} }
private void ClientAlertsHandleState(EntityUid uid, AlertsComponent component, ref ComponentHandleState args) private void ClientAlertsHandleState(EntityUid uid, AlertsComponent component, ref AfterAutoHandleStateEvent args)
{ {
var componentAlerts = (args.Current as AlertsComponentState)?.Alerts;
if (componentAlerts == null)
return;
component.Alerts = new Dictionary<AlertKey, AlertState>(componentAlerts);
if (_playerManager.LocalPlayer?.ControlledEntity == uid) if (_playerManager.LocalPlayer?.ControlledEntity == uid)
SyncAlerts?.Invoke(this, componentAlerts); SyncAlerts?.Invoke(this, component.Alerts);
} }
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args) private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args)

View File

@@ -1,7 +1,6 @@
using Content.Shared.BarSign; using Content.Shared.BarSign;
using Content.Shared.Power; using Content.Shared.Power;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Client.BarSign; namespace Content.Client.BarSign;
@@ -13,33 +12,29 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<BarSignComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<BarSignComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
} }
private void OnHandleState(EntityUid uid, BarSignComponent component, ref ComponentHandleState args) private void OnAfterAutoHandleState(EntityUid uid, BarSignComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not BarSignComponentState state) UpdateAppearance(uid, component);
return;
component.CurrentSign = state.CurrentSign;
UpdateAppearance(component);
} }
protected override void OnAppearanceChange(EntityUid uid, BarSignComponent component, ref AppearanceChangeEvent args) protected override void OnAppearanceChange(EntityUid uid, BarSignComponent component, ref AppearanceChangeEvent args)
{ {
UpdateAppearance(component, args.Component, args.Sprite); UpdateAppearance(uid, component, args.Component, args.Sprite);
} }
private void UpdateAppearance(BarSignComponent sign, AppearanceComponent? appearance = null, SpriteComponent? sprite = null) private void UpdateAppearance(EntityUid id, BarSignComponent sign, AppearanceComponent? appearance = null, SpriteComponent? sprite = null)
{ {
if (!Resolve(sign.Owner, ref appearance, ref sprite)) if (!Resolve(id, ref appearance, ref sprite))
return; return;
AppearanceSystem.TryGetData<bool>(sign.Owner, PowerDeviceVisuals.Powered, out var powered, appearance); AppearanceSystem.TryGetData<bool>(id, PowerDeviceVisuals.Powered, out var powered, appearance);
if (powered if (powered
&& sign.CurrentSign != null && sign.Current != null
&& _prototypeManager.TryIndex(sign.CurrentSign, out BarSignPrototype? proto)) && _prototypeManager.TryIndex(sign.Current, out BarSignPrototype? proto))
{ {
sprite.LayerSetState(0, proto.Icon); sprite.LayerSetState(0, proto.Icon);
sprite.LayerSetShader(0, "unshaded"); sprite.LayerSetShader(0, "unshaded");

View File

@@ -3,7 +3,6 @@ using Content.Shared.Buckle;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
using Content.Shared.Vehicle.Components; using Content.Shared.Vehicle.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
namespace Content.Client.Buckle; namespace Content.Client.Buckle;
@@ -15,20 +14,12 @@ internal sealed class BuckleSystem : SharedBuckleSystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<BuckleComponent, ComponentHandleState>(OnBuckleHandleState); SubscribeLocalEvent<BuckleComponent, AfterAutoHandleStateEvent>(OnBuckleAfterAutoHandleState);
SubscribeLocalEvent<BuckleComponent, AppearanceChangeEvent>(OnAppearanceChange); SubscribeLocalEvent<BuckleComponent, AppearanceChangeEvent>(OnAppearanceChange);
} }
private void OnBuckleHandleState(EntityUid uid, BuckleComponent component, ref ComponentHandleState args) private void OnBuckleAfterAutoHandleState(EntityUid uid, BuckleComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not BuckleComponentState state)
return;
component.Buckled = state.Buckled;
component.BuckledTo = EnsureEntity<BuckleComponent>(state.BuckledTo, uid);
component.LastEntityBuckledTo = EnsureEntity<BuckleComponent>(state.LastEntityBuckledTo, uid);
component.DontCollide = state.DontCollide;
ActionBlocker.UpdateCanMove(uid); ActionBlocker.UpdateCanMove(uid);
if (!TryComp<SpriteComponent>(uid, out var ownerSprite)) if (!TryComp<SpriteComponent>(uid, out var ownerSprite))

View File

@@ -3,7 +3,6 @@ using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems; using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Client.Clothing.Systems; namespace Content.Client.Clothing.Systems;
@@ -27,7 +26,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<ChameleonClothingComponent, ComponentHandleState>(HandleState); SubscribeLocalEvent<ChameleonClothingComponent, AfterAutoHandleStateEvent>(HandleState);
PrepareAllVariants(); PrepareAllVariants();
_proto.PrototypesReloaded += OnProtoReloaded; _proto.PrototypesReloaded += OnProtoReloaded;
@@ -44,12 +43,8 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
PrepareAllVariants(); PrepareAllVariants();
} }
private void HandleState(EntityUid uid, ChameleonClothingComponent component, ref ComponentHandleState args) private void HandleState(EntityUid uid, ChameleonClothingComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not ChameleonClothingComponentState state)
return;
component.SelectedId = state.SelectedId;
UpdateVisuals(uid, component); UpdateVisuals(uid, component);
} }

View File

@@ -17,15 +17,6 @@ public sealed class CuffableSystem : SharedCuffableSystem
SubscribeLocalEvent<CuffableComponent, ComponentShutdown>(OnCuffableShutdown); SubscribeLocalEvent<CuffableComponent, ComponentShutdown>(OnCuffableShutdown);
SubscribeLocalEvent<CuffableComponent, ComponentHandleState>(OnCuffableHandleState); SubscribeLocalEvent<CuffableComponent, ComponentHandleState>(OnCuffableHandleState);
SubscribeLocalEvent<HandcuffComponent, ComponentHandleState>(OnHandcuffHandleState);
}
private void OnHandcuffHandleState(EntityUid uid, HandcuffComponent component, ref ComponentHandleState args)
{
if (args.Current is not HandcuffComponentState state)
return;
component.OverlayIconState = state.IconState;
} }
private void OnCuffableShutdown(EntityUid uid, CuffableComponent component, ComponentShutdown args) private void OnCuffableShutdown(EntityUid uid, CuffableComponent component, ComponentShutdown args)

View File

@@ -1,14 +1,10 @@
using System.Linq;
using Content.Shared.Ghost;
using Content.Shared.Humanoid; using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes; using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid; namespace Content.Client.Humanoid;
@@ -21,34 +17,20 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<HumanoidAppearanceComponent, AfterAutoHandleStateEvent>(OnHandleState);
} }
private void OnHandleState(EntityUid uid, HumanoidAppearanceComponent component, ref ComponentHandleState args) private void OnHandleState(EntityUid uid, HumanoidAppearanceComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not HumanoidAppearanceState state) UpdateSprite(component, Comp<SpriteComponent>(uid));
return;
ApplyState(uid, component, Comp<SpriteComponent>(uid), state);
} }
private void ApplyState(EntityUid uid, HumanoidAppearanceComponent component, SpriteComponent sprite, HumanoidAppearanceState state) private void UpdateSprite(HumanoidAppearanceComponent component, SpriteComponent sprite)
{ {
component.Sex = state.Sex;
component.Species = state.Species;
component.Age = state.Age;
component.SkinColor = state.SkinColor;
component.EyeColor = state.EyeColor;
component.HiddenLayers = new(state.HiddenLayers);
component.PermanentlyHidden = new(state.PermanentlyHidden);
component.CustomBaseLayers = state.CustomBaseLayers.ShallowClone();
UpdateLayers(component, sprite); UpdateLayers(component, sprite);
ApplyMarkingSet(component, sprite);
ApplyMarkingSet(uid, state.Markings, component, sprite); sprite[sprite.LayerMapReserveBlank(HumanoidVisualLayers.Eyes)].Color = component.EyeColor;
sprite[sprite.LayerMapReserveBlank(HumanoidVisualLayers.Eyes)].Color = state.EyeColor;
} }
private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer) private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer)
@@ -60,7 +42,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
component.BaseLayers.Clear(); component.BaseLayers.Clear();
// add default species layers // add default species layers
var speciesProto = _prototypeManager.Index<SpeciesPrototype>(component.Species); var speciesProto = _prototypeManager.Index(component.Species);
var baseSprites = _prototypeManager.Index<HumanoidSpeciesBaseSpritesPrototype>(speciesProto.SpriteSet); var baseSprites = _prototypeManager.Index<HumanoidSpeciesBaseSpritesPrototype>(speciesProto.SpriteSet);
foreach (var (key, id) in baseSprites.Sprites) foreach (var (key, id) in baseSprites.Sprites)
{ {
@@ -73,7 +55,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
foreach (var (key, info) in component.CustomBaseLayers) foreach (var (key, info) in component.CustomBaseLayers)
{ {
oldLayers.Remove(key); oldLayers.Remove(key);
SetLayerData(component, sprite, key, info.ID, sexMorph: false, color: info.Color); ; SetLayerData(component, sprite, key, info.Id, sexMorph: false, color: info.Color);
} }
// hide old layers // hide old layers
@@ -161,12 +143,14 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
// We need to ensure hair before applying it or coloring can try depend on markings that can be invalid // We need to ensure hair before applying it or coloring can try depend on markings that can be invalid
var hairColor = _markingManager.MustMatchSkin(profile.Species, HumanoidVisualLayers.Hair, out var hairAlpha, _prototypeManager) var hairColor = _markingManager.MustMatchSkin(profile.Species, HumanoidVisualLayers.Hair, out var hairAlpha, _prototypeManager)
? profile.Appearance.SkinColor.WithAlpha(hairAlpha) : profile.Appearance.HairColor; ? profile.Appearance.SkinColor.WithAlpha(hairAlpha)
: profile.Appearance.HairColor;
var hair = new Marking(profile.Appearance.HairStyleId, var hair = new Marking(profile.Appearance.HairStyleId,
new[] { hairColor }); new[] { hairColor });
var facialHairColor = _markingManager.MustMatchSkin(profile.Species, HumanoidVisualLayers.FacialHair, out var facialHairAlpha, _prototypeManager) var facialHairColor = _markingManager.MustMatchSkin(profile.Species, HumanoidVisualLayers.FacialHair, out var facialHairAlpha, _prototypeManager)
? profile.Appearance.SkinColor.WithAlpha(facialHairAlpha) : profile.Appearance.FacialHairColor; ? profile.Appearance.SkinColor.WithAlpha(facialHairAlpha)
: profile.Appearance.FacialHairColor;
var facialHair = new Marking(profile.Appearance.FacialHairStyleId, var facialHair = new Marking(profile.Appearance.FacialHairStyleId,
new[] { facialHairColor }); new[] { facialHairColor });
@@ -200,69 +184,60 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
DebugTools.Assert(IsClientSide(uid)); DebugTools.Assert(IsClientSide(uid));
var state = new HumanoidAppearanceState(markings, humanoid.MarkingSet = markings;
new(), humanoid.PermanentlyHidden = new HashSet<HumanoidVisualLayers>();
new(), humanoid.HiddenLayers = new HashSet<HumanoidVisualLayers>();
customBaseLayers, humanoid.CustomBaseLayers = customBaseLayers;
profile.Sex, humanoid.Sex = profile.Sex;
profile.Gender, humanoid.Gender = profile.Gender;
profile.Age, humanoid.Age = profile.Age;
profile.Species, humanoid.Species = profile.Species;
profile.Appearance.SkinColor, humanoid.SkinColor = profile.Appearance.SkinColor;
profile.Appearance.EyeColor); humanoid.EyeColor = profile.Appearance.EyeColor;
ApplyState(uid, humanoid, Comp<SpriteComponent>(uid), state); UpdateSprite(humanoid, Comp<SpriteComponent>(uid));
} }
private void ApplyMarkingSet(EntityUid uid, private void ApplyMarkingSet(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
MarkingSet newMarkings,
HumanoidAppearanceComponent humanoid,
SpriteComponent sprite)
{ {
// skip this entire thing if both sets are empty
if (humanoid.MarkingSet.Markings.Count == 0 && newMarkings.Markings.Count == 0)
return;
// I am lazy and I CBF resolving the previous mess, so I'm just going to nuke the markings. // I am lazy and I CBF resolving the previous mess, so I'm just going to nuke the markings.
// Really, markings should probably be a separate component altogether. // Really, markings should probably be a separate component altogether.
ClearAllMarkings(humanoid, sprite);
ClearAllMarkings(uid, humanoid, sprite);
humanoid.MarkingSet = new(newMarkings);
foreach (var markingList in humanoid.MarkingSet.Markings.Values) foreach (var markingList in humanoid.MarkingSet.Markings.Values)
{ {
foreach (var marking in markingList) foreach (var marking in markingList)
{ {
if (_markingManager.TryGetMarking(marking, out var markingPrototype)) if (_markingManager.TryGetMarking(marking, out var markingPrototype))
ApplyMarking(uid, markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite); ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite);
}
} }
} }
private void ClearAllMarkings(EntityUid uid, HumanoidAppearanceComponent humanoid, humanoid.ClientOldMarkings = new MarkingSet(humanoid.MarkingSet);
SpriteComponent sprite) }
private void ClearAllMarkings(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
{ {
foreach (var markingList in humanoid.ClientOldMarkings.Markings.Values)
{
foreach (var marking in markingList)
{
RemoveMarking(marking, sprite);
}
}
humanoid.ClientOldMarkings.Clear();
foreach (var markingList in humanoid.MarkingSet.Markings.Values) foreach (var markingList in humanoid.MarkingSet.Markings.Values)
{ {
foreach (var marking in markingList) foreach (var marking in markingList)
{ {
RemoveMarking(uid, marking, sprite); RemoveMarking(marking, sprite);
} }
} }
} }
private void ClearMarkings(EntityUid uid, List<Marking> markings, HumanoidAppearanceComponent humanoid, private void RemoveMarking(Marking marking, SpriteComponent spriteComp)
SpriteComponent spriteComp)
{
foreach (var marking in markings)
{
RemoveMarking(uid, marking, spriteComp);
}
}
private void RemoveMarking(EntityUid uid, Marking marking,
SpriteComponent spriteComp)
{ {
if (!_markingManager.TryGetMarking(marking, out var prototype)) if (!_markingManager.TryGetMarking(marking, out var prototype))
{ {
@@ -286,8 +261,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
spriteComp.RemoveLayer(index); spriteComp.RemoveLayer(index);
} }
} }
private void ApplyMarking(EntityUid uid, private void ApplyMarking(MarkingPrototype markingPrototype,
MarkingPrototype markingPrototype,
IReadOnlyList<Color>? colors, IReadOnlyList<Color>? colors,
bool visible, bool visible,
HumanoidAppearanceComponent humanoid, HumanoidAppearanceComponent humanoid,
@@ -393,7 +367,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
foreach (var marking in markingList) foreach (var marking in markingList)
{ {
if (_markingManager.TryGetMarking(marking, out var markingPrototype) && markingPrototype.BodyPart == layer) if (_markingManager.TryGetMarking(marking, out var markingPrototype) && markingPrototype.BodyPart == layer)
ApplyMarking(uid, markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite); ApplyMarking(markingPrototype, marking.MarkingColors, marking.Visible, humanoid, sprite);
} }
} }
} }

View File

@@ -1,7 +1,5 @@
using Content.Shared.Humanoid; using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Markings;
using Robust.Client.GameObjects;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid; namespace Content.Client.Humanoid;

View File

@@ -6,7 +6,6 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid; namespace Content.Client.Humanoid;
@@ -76,7 +75,7 @@ public sealed partial class HumanoidMarkingModifierWindow : DefaultWindow
continue; continue;
} }
modifier.SetState(true, layerInfo.ID ?? string.Empty, layerInfo.Color ?? Color.White); modifier.SetState(true, layerInfo.Id ?? string.Empty, layerInfo.Color ?? Color.White);
} }
var eyesColor = Color.White; var eyesColor = Color.White;

View File

@@ -2,7 +2,6 @@
using Content.Client.Items; using Content.Client.Items;
using Content.Shared.Implants; using Content.Shared.Implants;
using Content.Shared.Implants.Components; using Content.Shared.Implants.Components;
using Robust.Shared.GameStates;
namespace Content.Client.Implants; namespace Content.Client.Implants;
@@ -12,17 +11,12 @@ public sealed class ImplanterSystem : SharedImplanterSystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<ImplanterComponent, ComponentHandleState>(OnHandleImplanterState); SubscribeLocalEvent<ImplanterComponent, AfterAutoHandleStateEvent>(OnHandleImplanterState);
SubscribeLocalEvent<ImplanterComponent, ItemStatusCollectMessage>(OnItemImplanterStatus); SubscribeLocalEvent<ImplanterComponent, ItemStatusCollectMessage>(OnItemImplanterStatus);
} }
private void OnHandleImplanterState(EntityUid uid, ImplanterComponent component, ref ComponentHandleState args) private void OnHandleImplanterState(EntityUid uid, ImplanterComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not ImplanterComponentState state)
return;
component.CurrentMode = state.CurrentMode;
component.ImplantOnly = state.ImplantOnly;
component.UiUpdateNeeded = true; component.UiUpdateNeeded = true;
} }

View File

@@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Content.Shared.FixedPoint;
using Content.Shared.Lathe; using Content.Shared.Lathe;
using Content.Shared.Materials; using Content.Shared.Materials;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
@@ -24,7 +23,7 @@ public sealed partial class LatheMenu : DefaultWindow
public event Action<BaseButton.ButtonEventArgs>? OnServerListButtonPressed; public event Action<BaseButton.ButtonEventArgs>? OnServerListButtonPressed;
public event Action<string, int>? RecipeQueueAction; public event Action<string, int>? RecipeQueueAction;
public event Action<string, int>? OnEjectPressed; public event Action<string, int>? OnEjectPressed;
public List<string> Recipes = new(); public List<ProtoId<LatheRecipePrototype>> Recipes = new();
/// <summary> /// <summary>
/// Default volume for a sheet if the material's entity prototype has no material composition. /// Default volume for a sheet if the material's entity prototype has no material composition.
@@ -115,7 +114,7 @@ public sealed partial class LatheMenu : DefaultWindow
var recipesToShow = new List<LatheRecipePrototype>(); var recipesToShow = new List<LatheRecipePrototype>();
foreach (var recipe in Recipes) foreach (var recipe in Recipes)
{ {
if (!_prototypeManager.TryIndex<LatheRecipePrototype>(recipe, out var proto)) if (!_prototypeManager.TryIndex(recipe, out var proto))
continue; continue;
if (SearchBar.Text.Trim().Length != 0) if (SearchBar.Text.Trim().Length != 0)

View File

@@ -1,7 +1,6 @@
using Content.Client.Interactable; using Content.Client.Interactable;
using Content.Shared.Climbing; using Content.Shared.Climbing;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Robust.Shared.GameStates;
namespace Content.Client.Movement.Systems; namespace Content.Client.Movement.Systems;
@@ -12,19 +11,9 @@ public sealed class ClimbSystem : SharedClimbSystem
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<ClimbingComponent, ComponentHandleState>(OnClimbingState);
SubscribeLocalEvent<ClimbableComponent, CanDropTargetEvent>(OnCanDragDropOn); SubscribeLocalEvent<ClimbableComponent, CanDropTargetEvent>(OnCanDragDropOn);
} }
private static void OnClimbingState(EntityUid uid, ClimbingComponent component, ref ComponentHandleState args)
{
if (args.Current is not ClimbingComponent.ClimbModeComponentState climbModeState)
return;
component.IsClimbing = climbModeState.Climbing;
component.OwnerIsTransitioning = climbModeState.IsTransitioning;
}
protected override void OnCanDragDropOn(EntityUid uid, ClimbableComponent component, ref CanDropTargetEvent args) protected override void OnCanDragDropOn(EntityUid uid, ClimbableComponent component, ref CanDropTargetEvent args)
{ {
base.OnCanDragDropOn(uid, component, ref args); base.OnCanDragDropOn(uid, component, ref args);

View File

@@ -3,7 +3,6 @@ using Content.Client.Message;
using Content.Shared.Points; using Content.Shared.Points;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameStates;
namespace Content.Client.Points; namespace Content.Client.Points;
@@ -17,17 +16,12 @@ public sealed class PointSystem : SharedPointSystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<PointManagerComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<PointManagerComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<CharacterInfoSystem.GetCharacterInfoControlsEvent>(OnGetCharacterInfoControls); SubscribeLocalEvent<CharacterInfoSystem.GetCharacterInfoControlsEvent>(OnGetCharacterInfoControls);
} }
private void OnHandleState(EntityUid uid, PointManagerComponent component, ref ComponentHandleState args) private void OnHandleState(EntityUid uid, PointManagerComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not PointManagerComponentState state)
return;
component.Points = new(state.Points);
component.Scoreboard = state.Scoreboard;
_characterInfo.RequestCharacterInfo(); _characterInfo.RequestCharacterInfo();
} }

View File

@@ -2,10 +2,6 @@ using Content.Client.Items;
using Content.Client.Radiation.UI; using Content.Client.Radiation.UI;
using Content.Shared.Radiation.Components; using Content.Shared.Radiation.Components;
using Content.Shared.Radiation.Systems; using Content.Shared.Radiation.Systems;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
namespace Content.Client.Radiation.Systems; namespace Content.Client.Radiation.Systems;
@@ -14,19 +10,12 @@ public sealed class GeigerSystem : SharedGeigerSystem
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<GeigerComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<GeigerComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<GeigerComponent, ItemStatusCollectMessage>(OnGetStatusMessage); SubscribeLocalEvent<GeigerComponent, ItemStatusCollectMessage>(OnGetStatusMessage);
} }
private void OnHandleState(EntityUid uid, GeigerComponent component, ref ComponentHandleState args) private void OnHandleState(EntityUid uid, GeigerComponent component, ref AfterAutoHandleStateEvent args)
{ {
if (args.Current is not GeigerComponentState state)
return;
component.CurrentRadiation = state.CurrentRadiation;
component.DangerLevel = state.DangerLevel;
component.IsEnabled = state.IsEnabled;
component.User = EnsureEntity<GeigerComponent>(state.User, uid);
component.UiUpdateNeeded = true; component.UiUpdateNeeded = true;
} }

View File

@@ -11,7 +11,6 @@ using Robust.Client.Input;
using Robust.Client.Player; using Robust.Client.Player;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameStates;
using Robust.Shared.Input; using Robust.Shared.Input;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -49,7 +48,6 @@ namespace Content.Client.Tabletop
.Register<TabletopSystem>(); .Register<TabletopSystem>();
SubscribeNetworkEvent<TabletopPlayEvent>(OnTabletopPlay); SubscribeNetworkEvent<TabletopPlayEvent>(OnTabletopPlay);
SubscribeLocalEvent<TabletopDraggableComponent, ComponentHandleState>(HandleComponentState);
SubscribeLocalEvent<TabletopDraggableComponent, ComponentRemove>(HandleDraggableRemoved); SubscribeLocalEvent<TabletopDraggableComponent, ComponentRemove>(HandleDraggableRemoved);
SubscribeLocalEvent<TabletopDraggableComponent, AppearanceChangeEvent>(OnAppearanceChange); SubscribeLocalEvent<TabletopDraggableComponent, AppearanceChangeEvent>(OnAppearanceChange);
} }
@@ -148,13 +146,6 @@ namespace Content.Client.Tabletop
_window.OnClose += OnWindowClose; _window.OnClose += OnWindowClose;
} }
private void HandleComponentState(EntityUid uid, TabletopDraggableComponent component, ref ComponentHandleState args)
{
if (args.Current is not TabletopDraggableComponentState state) return;
component.DraggingPlayer = state.DraggingPlayer;
}
private void OnWindowClose() private void OnWindowClose()
{ {
if (_table != null) if (_table != null)

View File

@@ -39,7 +39,7 @@ public sealed partial class GunSystem
else if (component.UnspawnedCount > 0) else if (component.UnspawnedCount > 0)
{ {
component.UnspawnedCount--; component.UnspawnedCount--;
ent = Spawn(component.FillProto, coordinates); ent = Spawn(component.Proto, coordinates);
EnsureShootable(ent.Value); EnsureShootable(ent.Value);
} }

View File

@@ -1,15 +1,15 @@
using System.Linq;
using Content.Server.Popups;
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs; using Content.Shared.Administration.Logs;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using System.Linq;
using static Content.Shared.Access.Components.AccessOverriderComponent; using static Content.Shared.Access.Components.AccessOverriderComponent;
using Content.Server.Popups;
using Content.Shared.DoAfter;
namespace Content.Server.Access.Systems; namespace Content.Server.Access.Systems;
@@ -46,7 +46,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
if (!_interactionSystem.InRangeUnobstructed(args.User, (EntityUid) args.Target)) if (!_interactionSystem.InRangeUnobstructed(args.User, (EntityUid) args.Target))
return; return;
var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.DoAfterTime, new AccessOverriderDoAfterEvent(), uid, target: args.Target, used: uid) var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.DoAfter, new AccessOverriderDoAfterEvent(), uid, target: args.Target, used: uid)
{ {
BreakOnTargetMove = true, BreakOnTargetMove = true,
BreakOnUserMove = true, BreakOnUserMove = true,

View File

@@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using Content.Shared.BarSign; using Content.Shared.BarSign;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
@@ -15,17 +14,11 @@ namespace Content.Server.BarSign.Systems
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<BarSignComponent, ComponentGetState>(OnGetState);
}
private void OnGetState(EntityUid uid, BarSignComponent component, ref ComponentGetState args)
{
args.State = new BarSignComponentState(component.CurrentSign);
} }
private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent args) private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent args)
{ {
if (component.CurrentSign != null) if (component.Current != null)
return; return;
var prototypes = _prototypeManager var prototypes = _prototypeManager
@@ -40,7 +33,7 @@ namespace Content.Server.BarSign.Systems
_metaData.SetEntityName(uid, Loc.GetString(name), meta); _metaData.SetEntityName(uid, Loc.GetString(name), meta);
_metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta); _metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta);
component.CurrentSign = newPrototype.ID; component.Current = newPrototype.ID;
Dirty(component); Dirty(component);
} }
} }

View File

@@ -21,7 +21,6 @@ using Content.Shared.Popups;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes; using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
@@ -62,7 +61,6 @@ public sealed class ClimbSystem : SharedClimbSystem
SubscribeLocalEvent<ClimbingComponent, ClimbDoAfterEvent>(OnDoAfter); SubscribeLocalEvent<ClimbingComponent, ClimbDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<ClimbingComponent, EndCollideEvent>(OnClimbEndCollide); SubscribeLocalEvent<ClimbingComponent, EndCollideEvent>(OnClimbEndCollide);
SubscribeLocalEvent<ClimbingComponent, BuckleChangeEvent>(OnBuckleChange); SubscribeLocalEvent<ClimbingComponent, BuckleChangeEvent>(OnBuckleChange);
SubscribeLocalEvent<ClimbingComponent, ComponentGetState>(OnClimbingGetState);
SubscribeLocalEvent<GlassTableComponent, ClimbedOnEvent>(OnGlassClimbed); SubscribeLocalEvent<GlassTableComponent, ClimbedOnEvent>(OnGlassClimbed);
} }
@@ -366,11 +364,6 @@ public sealed class ClimbSystem : SharedClimbSystem
StopClimb(uid, component); StopClimb(uid, component);
} }
private static void OnClimbingGetState(EntityUid uid, ClimbingComponent component, ref ComponentGetState args)
{
args.State = new ClimbingComponent.ClimbModeComponentState(component.IsClimbing, component.OwnerIsTransitioning);
}
private void OnGlassClimbed(EntityUid uid, GlassTableComponent component, ClimbedOnEvent args) private void OnGlassClimbed(EntityUid uid, GlassTableComponent component, ClimbedOnEvent args)
{ {
if (TryComp<PhysicsComponent>(args.Climber, out var physics) && physics.Mass <= component.MassLimit) if (TryComp<PhysicsComponent>(args.Climber, out var physics) && physics.Mass <= component.MassLimit)

View File

@@ -5,7 +5,6 @@ using Content.Shared.IdentityManagement.Components;
using Content.Shared.Prototypes; using Content.Shared.Prototypes;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -22,22 +21,13 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<ChameleonClothingComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<ChameleonClothingComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ChameleonClothingComponent, ComponentGetState>(GetState);
SubscribeLocalEvent<ChameleonClothingComponent, GetVerbsEvent<InteractionVerb>>(OnVerb); SubscribeLocalEvent<ChameleonClothingComponent, GetVerbsEvent<InteractionVerb>>(OnVerb);
SubscribeLocalEvent<ChameleonClothingComponent, ChameleonPrototypeSelectedMessage>(OnSelected); SubscribeLocalEvent<ChameleonClothingComponent, ChameleonPrototypeSelectedMessage>(OnSelected);
} }
private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args) private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args)
{ {
SetSelectedPrototype(uid, component.SelectedId, true, component); SetSelectedPrototype(uid, component.Default, true, component);
}
private void GetState(EntityUid uid, ChameleonClothingComponent component, ref ComponentGetState args)
{
args.State = new ChameleonClothingComponentState
{
SelectedId = component.SelectedId
};
} }
private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent<InteractionVerb> args) private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent<InteractionVerb> args)
@@ -72,7 +62,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
return; return;
var state = new ChameleonBoundUserInterfaceState(component.Slot, component.SelectedId); var state = new ChameleonBoundUserInterfaceState(component.Slot, component.Default);
_uiSystem.TrySetUiState(uid, ChameleonUiKey.Key, state); _uiSystem.TrySetUiState(uid, ChameleonUiKey.Key, state);
} }
@@ -87,7 +77,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
// check that wasn't already selected // check that wasn't already selected
// forceUpdate on component init ignores this check // forceUpdate on component init ignores this check
if (component.SelectedId == protoId && !forceUpdate) if (component.Default == protoId && !forceUpdate)
return; return;
// make sure that it is valid change // make sure that it is valid change
@@ -95,7 +85,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
return; return;
if (!IsValidTarget(proto, component.Slot)) if (!IsValidTarget(proto, component.Slot))
return; return;
component.SelectedId = protoId; component.Default = protoId;
UpdateIdentityBlocker(uid, component, proto); UpdateIdentityBlocker(uid, component, proto);
UpdateVisuals(uid, component); UpdateVisuals(uid, component);

View File

@@ -1,6 +1,6 @@
using Content.Shared.Cuffs; using Content.Shared.Cuffs;
using JetBrains.Annotations;
using Content.Shared.Cuffs.Components; using Content.Shared.Cuffs.Components;
using JetBrains.Annotations;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
namespace Content.Server.Cuffs namespace Content.Server.Cuffs
@@ -12,15 +12,9 @@ namespace Content.Server.Cuffs
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<HandcuffComponent, ComponentGetState>(OnHandcuffGetState);
SubscribeLocalEvent<CuffableComponent, ComponentGetState>(OnCuffableGetState); SubscribeLocalEvent<CuffableComponent, ComponentGetState>(OnCuffableGetState);
} }
private void OnHandcuffGetState(EntityUid uid, HandcuffComponent component, ref ComponentGetState args)
{
args.State = new HandcuffComponentState(component.OverlayIconState);
}
private void OnCuffableGetState(EntityUid uid, CuffableComponent component, ref ComponentGetState args) private void OnCuffableGetState(EntityUid uid, CuffableComponent component, ref ComponentGetState args)
{ {
// there are 2 approaches i can think of to handle the handcuff overlay on players // there are 2 approaches i can think of to handle the handcuff overlay on players
@@ -34,7 +28,7 @@ namespace Content.Server.Cuffs
args.State = new CuffableComponentState(component.CuffedHandCount, args.State = new CuffableComponentState(component.CuffedHandCount,
component.CanStillInteract, component.CanStillInteract,
cuffs?.CuffedRSI, cuffs?.CuffedRSI,
$"{cuffs?.OverlayIconState}-{component.CuffedHandCount}", $"{cuffs?.BodyIconState}-{component.CuffedHandCount}",
cuffs?.Color); cuffs?.Color);
// the iconstate is formatted as blah-2, blah-4, blah-6, etc. // the iconstate is formatted as blah-2, blah-4, blah-6, etc.
// the number corresponds to how many hands are cuffed. // the number corresponds to how many hands are cuffed.

View File

@@ -1,22 +1,19 @@
using Content.Server.Access; using Content.Server.Access;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.Server.Power.EntitySystems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Doors;
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Content.Shared.Emag.Systems; using Content.Shared.Emag.Systems;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Prying.Components;
using Content.Shared.Prying.Systems;
using Content.Shared.Tools.Systems;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Content.Server.Administration.Logs;
using Content.Server.Power.EntitySystems;
using Content.Shared.Tools;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Events;
using Content.Shared.DoAfter;
using Content.Shared.Prying.Systems;
using Content.Shared.Prying.Components;
using Content.Shared.Tools.Systems;
namespace Content.Server.Doors.Systems; namespace Content.Server.Doors.Systems;
@@ -25,8 +22,6 @@ public sealed class DoorSystem : SharedDoorSystem
[Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly IAdminLogManager _adminLog = default!;
[Dependency] private readonly DoorBoltSystem _bolts = default!; [Dependency] private readonly DoorBoltSystem _bolts = default!;
[Dependency] private readonly AirtightSystem _airtightSystem = default!; [Dependency] private readonly AirtightSystem _airtightSystem = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly PryingSystem _pryingSystem = default!; [Dependency] private readonly PryingSystem _pryingSystem = default!;
public override void Initialize() public override void Initialize()

View File

@@ -210,7 +210,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
return; return;
var siemens = TryComp<InsulatedComponent>(args.Used, out var insulation) var siemens = TryComp<InsulatedComponent>(args.Used, out var insulation)
? insulation.SiemensCoefficient ? insulation.Coefficient
: 1; : 1;
TryDoElectrifiedAct(uid, args.User, siemens, electrified); TryDoElectrifiedAct(uid, args.User, siemens, electrified);

View File

@@ -8,7 +8,6 @@ using Content.Shared.Interaction;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Server.Implants; namespace Content.Server.Implants;
@@ -24,7 +23,6 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem
InitializeImplanted(); InitializeImplanted();
SubscribeLocalEvent<ImplanterComponent, AfterInteractEvent>(OnImplanterAfterInteract); SubscribeLocalEvent<ImplanterComponent, AfterInteractEvent>(OnImplanterAfterInteract);
SubscribeLocalEvent<ImplanterComponent, ComponentGetState>(OnImplanterGetState);
SubscribeLocalEvent<ImplanterComponent, ImplantEvent>(OnImplant); SubscribeLocalEvent<ImplanterComponent, ImplantEvent>(OnImplant);
SubscribeLocalEvent<ImplanterComponent, DrawEvent>(OnDraw); SubscribeLocalEvent<ImplanterComponent, DrawEvent>(OnDraw);
@@ -109,11 +107,6 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem
} }
private void OnImplanterGetState(EntityUid uid, ImplanterComponent component, ref ComponentGetState args)
{
args.State = new ImplanterComponentState(component.CurrentMode, component.ImplantOnly);
}
private void OnImplant(EntityUid uid, ImplanterComponent component, ImplantEvent args) private void OnImplant(EntityUid uid, ImplanterComponent component, ImplantEvent args)
{ {
if (args.Cancelled || args.Handled || args.Target == null || args.Used == null) if (args.Cancelled || args.Handled || args.Target == null || args.Used == null)

View File

@@ -107,11 +107,11 @@ namespace Content.Server.Lathe
{ {
if (args.Storage != uid) if (args.Storage != uid)
return; return;
var materialWhitelist = new List<string>(); var materialWhitelist = new List<ProtoId<MaterialPrototype>>();
var recipes = GetAllBaseRecipes(component); var recipes = GetAllBaseRecipes(component);
foreach (var id in recipes) foreach (var id in recipes)
{ {
if (!_proto.TryIndex<LatheRecipePrototype>(id, out var proto)) if (!_proto.TryIndex(id, out var proto))
continue; continue;
foreach (var (mat, _) in proto.RequiredMaterials) foreach (var (mat, _) in proto.RequiredMaterials)
{ {
@@ -127,7 +127,7 @@ namespace Content.Server.Lathe
} }
[PublicAPI] [PublicAPI]
public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List<string>? recipes, [NotNullWhen(true)] LatheComponent? component = null) public bool TryGetAvailableRecipes(EntityUid uid, [NotNullWhen(true)] out List<ProtoId<LatheRecipePrototype>>? recipes, [NotNullWhen(true)] LatheComponent? component = null)
{ {
recipes = null; recipes = null;
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
@@ -136,17 +136,17 @@ namespace Content.Server.Lathe
return true; return true;
} }
public List<string> GetAvailableRecipes(EntityUid uid, LatheComponent component) public List<ProtoId<LatheRecipePrototype>> GetAvailableRecipes(EntityUid uid, LatheComponent component)
{ {
var ev = new LatheGetRecipesEvent(uid) var ev = new LatheGetRecipesEvent(uid)
{ {
Recipes = new List<string>(component.StaticRecipes) Recipes = new List<ProtoId<LatheRecipePrototype>>(component.StaticRecipes)
}; };
RaiseLocalEvent(uid, ev); RaiseLocalEvent(uid, ev);
return ev.Recipes; return ev.Recipes;
} }
public static List<string> GetAllBaseRecipes(LatheComponent component) public static List<ProtoId<LatheRecipePrototype>> GetAllBaseRecipes(LatheComponent component)
{ {
return component.StaticRecipes.Union(component.DynamicRecipes).ToList(); return component.StaticRecipes.Union(component.DynamicRecipes).ToList();
} }
@@ -300,7 +300,7 @@ namespace Content.Server.Lathe
private void OnPartsRefresh(EntityUid uid, LatheComponent component, RefreshPartsEvent args) private void OnPartsRefresh(EntityUid uid, LatheComponent component, RefreshPartsEvent args)
{ {
var printTimeRating = args.PartRatings[component.MachinePartPrintTime]; var printTimeRating = args.PartRatings[component.MachinePartPrintSpeed];
var materialUseRating = args.PartRatings[component.MachinePartMaterialUse]; var materialUseRating = args.PartRatings[component.MachinePartMaterialUse];
component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1); component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1);

View File

@@ -5,7 +5,6 @@ using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Server.GameStates; using Robust.Server.GameStates;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.GameStates;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Server.Points; namespace Content.Server.Points;
@@ -22,7 +21,6 @@ public sealed class PointSystem : SharedPointSystem
base.Initialize(); base.Initialize();
SubscribeLocalEvent<PointManagerComponent, ComponentStartup>(OnStartup); SubscribeLocalEvent<PointManagerComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<PointManagerComponent, ComponentGetState>(OnGetState);
} }
private void OnStartup(EntityUid uid, PointManagerComponent component, ComponentStartup args) private void OnStartup(EntityUid uid, PointManagerComponent component, ComponentStartup args)
@@ -30,11 +28,6 @@ public sealed class PointSystem : SharedPointSystem
_pvsOverride.AddGlobalOverride(uid); _pvsOverride.AddGlobalOverride(uid);
} }
private void OnGetState(EntityUid uid, PointManagerComponent component, ref ComponentGetState args)
{
args.State = new PointManagerComponentState(component.Points, component.Scoreboard);
}
/// <summary> /// <summary>
/// Adds the specified point value to a player. /// Adds the specified point value to a player.
/// </summary> /// </summary>

View File

@@ -5,8 +5,6 @@ using Content.Shared.Interaction;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Radiation.Components; using Content.Shared.Radiation.Components;
using Content.Shared.Radiation.Systems; using Content.Shared.Radiation.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Server.Player; using Robust.Server.Player;
@@ -32,7 +30,6 @@ public sealed class GeigerSystem : SharedGeigerSystem
SubscribeLocalEvent<GeigerComponent, GotUnequippedHandEvent>(OnUnequippedHand); SubscribeLocalEvent<GeigerComponent, GotUnequippedHandEvent>(OnUnequippedHand);
SubscribeLocalEvent<RadiationSystemUpdatedEvent>(OnUpdate); SubscribeLocalEvent<RadiationSystemUpdatedEvent>(OnUpdate);
SubscribeLocalEvent<GeigerComponent, ComponentGetState>(OnGetState);
} }
private void OnActivate(EntityUid uid, GeigerComponent component, ActivateInWorldEvent args) private void OnActivate(EntityUid uid, GeigerComponent component, ActivateInWorldEvent args)
@@ -86,17 +83,6 @@ public sealed class GeigerSystem : SharedGeigerSystem
} }
} }
private void OnGetState(EntityUid uid, GeigerComponent component, ref ComponentGetState args)
{
args.State = new GeigerComponentState
{
CurrentRadiation = component.CurrentRadiation,
DangerLevel = component.DangerLevel,
IsEnabled = component.IsEnabled,
User = GetNetEntity(component.User)
};
}
private void SetCurrentRadiation(EntityUid uid, GeigerComponent component, float rads) private void SetCurrentRadiation(EntityUid uid, GeigerComponent component, float rads)
{ {
// check that it's approx equal // check that it's approx equal

View File

@@ -110,7 +110,7 @@ public sealed class EnergySwordSystem : EntitySystem
{ {
weaponComp.HitSound = comp.OnHitOff; weaponComp.HitSound = comp.OnHitOff;
if (comp.Secret) if (comp.Secret)
weaponComp.HideFromExamine = true; weaponComp.Hidden = true;
} }
if (comp.IsSharp) if (comp.IsSharp)
@@ -135,7 +135,7 @@ public sealed class EnergySwordSystem : EntitySystem
{ {
weaponComp.HitSound = comp.OnHitOn; weaponComp.HitSound = comp.OnHitOn;
if (comp.Secret) if (comp.Secret)
weaponComp.HideFromExamine = false; weaponComp.Hidden = false;
} }
if (TryComp<DisarmMalusComponent>(uid, out var malus)) if (TryComp<DisarmMalusComponent>(uid, out var malus))

View File

@@ -8,11 +8,13 @@ using Content.Server.Chemistry.EntitySystems;
using Content.Server.CombatMode.Disarm; using Content.Server.CombatMode.Disarm;
using Content.Server.Contests; using Content.Server.Contests;
using Content.Server.Movement.Systems; using Content.Server.Movement.Systems;
using Content.Shared.Administration.Components;
using Content.Shared.Actions.Events; using Content.Shared.Actions.Events;
using Content.Shared.Administration.Components;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
using Content.Shared.Damage.Events; using Content.Shared.Damage.Events;
using Content.Shared.Damage.Systems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Effects;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement; using Content.Shared.IdentityManagement;
@@ -29,8 +31,6 @@ using Robust.Shared.Map;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Players; using Robust.Shared.Players;
using Robust.Shared.Random; using Robust.Shared.Random;
using Content.Shared.Effects;
using Content.Shared.Damage.Systems;
namespace Content.Server.Weapons.Melee; namespace Content.Server.Weapons.Melee;
@@ -57,7 +57,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args) private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args)
{ {
if (component.HideFromExamine) if (component.Hidden)
return; return;
var damageSpec = GetDamage(uid, args.User, component); var damageSpec = GetDamage(uid, args.User, component);

View File

@@ -22,7 +22,7 @@ public sealed partial class GunSystem
else if (component.UnspawnedCount > 0) else if (component.UnspawnedCount > 0)
{ {
component.UnspawnedCount--; component.UnspawnedCount--;
ent = Spawn(component.FillProto, coordinates); ent = Spawn(component.Proto, coordinates);
EnsureShootable(ent.Value); EnsureShootable(ent.Value);
} }

View File

@@ -54,12 +54,12 @@ public sealed partial class GunSystem : SharedGunSystem
private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent component, ref PriceCalculationEvent args) private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent component, ref PriceCalculationEvent args)
{ {
if (string.IsNullOrEmpty(component.FillProto) || component.UnspawnedCount == 0) if (string.IsNullOrEmpty(component.Proto) || component.UnspawnedCount == 0)
return; return;
if (!ProtoManager.TryIndex<EntityPrototype>(component.FillProto, out var proto)) if (!ProtoManager.TryIndex<EntityPrototype>(component.Proto, out var proto))
{ {
Log.Error($"Unable to find fill prototype for price on {component.FillProto} on {ToPrettyString(uid)}"); Log.Error($"Unable to find fill prototype for price on {component.Proto} on {ToPrettyString(uid)}");
return; return;
} }

View File

@@ -12,7 +12,6 @@ using Content.Server.NPC;
using Content.Server.NPC.Components; using Content.Server.NPC.Components;
using Content.Server.NPC.HTN; using Content.Server.NPC.HTN;
using Content.Server.NPC.Systems; using Content.Server.NPC.Systems;
using Content.Server.Nutrition.Components;
using Content.Server.Roles; using Content.Server.Roles;
using Content.Server.Speech.Components; using Content.Server.Speech.Components;
using Content.Server.Temperature.Components; using Content.Server.Temperature.Components;
@@ -113,7 +112,7 @@ namespace Content.Server.Zombies
//This is the actual damage of the zombie. We assign the visual appearance //This is the actual damage of the zombie. We assign the visual appearance
//and range here because of stuff we'll find out later //and range here because of stuff we'll find out later
var melee = EnsureComp<MeleeWeaponComponent>(target); var melee = EnsureComp<MeleeWeaponComponent>(target);
melee.ClickAnimation = zombiecomp.AttackAnimation; melee.Animation = zombiecomp.AttackAnimation;
melee.WideAnimation = zombiecomp.AttackAnimation; melee.WideAnimation = zombiecomp.AttackAnimation;
melee.Range = 1.2f; melee.Range = 1.2f;

View File

@@ -255,7 +255,7 @@ namespace Content.Server.Zombies
foreach (var (layer, info) in zombiecomp.BeforeZombifiedCustomBaseLayers) foreach (var (layer, info) in zombiecomp.BeforeZombifiedCustomBaseLayers)
{ {
_humanoidAppearance.SetBaseLayerColor(target, layer, info.Color); _humanoidAppearance.SetBaseLayerColor(target, layer, info.Color);
_humanoidAppearance.SetBaseLayerId(target, layer, info.ID); _humanoidAppearance.SetBaseLayerId(target, layer, info.Id);
} }
if(TryComp<HumanoidAppearanceComponent>(target, out var appcomp)) if(TryComp<HumanoidAppearanceComponent>(target, out var appcomp))
{ {

View File

@@ -2,22 +2,22 @@ using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Access.Components; namespace Content.Shared.Access.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAccessOverriderSystem))] [Access(typeof(SharedAccessOverriderSystem))]
public sealed partial class AccessOverriderComponent : Component public sealed partial class AccessOverriderComponent : Component
{ {
public static string PrivilegedIdCardSlotId = "AccessOverrider-privilegedId"; public static string PrivilegedIdCardSlotId = "AccessOverrider-privilegedId";
[DataField("privilegedIdSlot")] [DataField]
public ItemSlot PrivilegedIdSlot = new(); public ItemSlot PrivilegedIdSlot = new();
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("denialSound")] [DataField]
public SoundSpecifier? DenialSound; public SoundSpecifier? DenialSound;
public EntityUid TargetAccessReaderId = new(); public EntityUid TargetAccessReaderId = new();
@@ -33,12 +33,12 @@ public sealed partial class AccessOverriderComponent : Component
} }
} }
[DataField("accessLevels", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))] [DataField, AutoNetworkedField(true)]
public List<string> AccessLevels = new(); public List<ProtoId<AccessLevelPrototype>> AccessLevels = new();
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("doAfter")] [DataField]
public float DoAfterTime = 0f; public float DoAfter;
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class AccessOverriderBoundUserInterfaceState : BoundUserInterfaceState public sealed class AccessOverriderBoundUserInterfaceState : BoundUserInterfaceState

View File

@@ -1,12 +1,12 @@
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Access.Components; namespace Content.Shared.Access.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedIdCardConsoleSystem))] [Access(typeof(SharedIdCardConsoleSystem))]
public sealed partial class IdCardConsoleComponent : Component public sealed partial class IdCardConsoleComponent : Component
{ {
@@ -16,10 +16,10 @@ public sealed partial class IdCardConsoleComponent : Component
public static string PrivilegedIdCardSlotId = "IdCardConsole-privilegedId"; public static string PrivilegedIdCardSlotId = "IdCardConsole-privilegedId";
public static string TargetIdCardSlotId = "IdCardConsole-targetId"; public static string TargetIdCardSlotId = "IdCardConsole-targetId";
[DataField("privilegedIdSlot")] [DataField]
public ItemSlot PrivilegedIdSlot = new(); public ItemSlot PrivilegedIdSlot = new();
[DataField("targetIdSlot")] [DataField]
public ItemSlot TargetIdSlot = new(); public ItemSlot TargetIdSlot = new();
[Serializable, NetSerializable] [Serializable, NetSerializable]
@@ -41,8 +41,8 @@ public sealed partial class IdCardConsoleComponent : Component
// Put this on shared so we just send the state once in PVS range rather than every time the UI updates. // Put this on shared so we just send the state once in PVS range rather than every time the UI updates.
[DataField("accessLevels", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))] [DataField, AutoNetworkedField]
public List<string> AccessLevels = new() public List<ProtoId<AccessLevelPrototype>> AccessLevels = new()
{ {
"Armory", "Armory",
"Atmospherics", "Atmospherics",

View File

@@ -2,7 +2,6 @@ using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter; using Content.Shared.DoAfter;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Access.Systems namespace Content.Shared.Access.Systems
@@ -23,19 +22,6 @@ namespace Content.Shared.Access.Systems
SubscribeLocalEvent<AccessOverriderComponent, ComponentInit>(OnComponentInit); SubscribeLocalEvent<AccessOverriderComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<AccessOverriderComponent, ComponentRemove>(OnComponentRemove); SubscribeLocalEvent<AccessOverriderComponent, ComponentRemove>(OnComponentRemove);
SubscribeLocalEvent<AccessOverriderComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<AccessOverriderComponent, ComponentHandleState>(OnHandleState);
}
private void OnHandleState(EntityUid uid, AccessOverriderComponent component, ref ComponentHandleState args)
{
if (args.Current is not AccessOverriderComponentState state) return;
component.AccessLevels = state.AccessLevels;
}
private void OnGetState(EntityUid uid, AccessOverriderComponent component, ref ComponentGetState args)
{
args.State = new AccessOverriderComponentState(component.AccessLevels);
} }
private void OnComponentInit(EntityUid uid, AccessOverriderComponent component, ComponentInit args) private void OnComponentInit(EntityUid uid, AccessOverriderComponent component, ComponentInit args)
@@ -48,17 +34,6 @@ namespace Content.Shared.Access.Systems
_itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot); _itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot);
} }
[Serializable, NetSerializable]
private sealed class AccessOverriderComponentState : ComponentState
{
public List<string> AccessLevels;
public AccessOverriderComponentState(List<string> accessLevels)
{
AccessLevels = accessLevels;
}
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed partial class AccessOverriderDoAfterEvent : DoAfterEvent public sealed partial class AccessOverriderDoAfterEvent : DoAfterEvent
{ {

View File

@@ -1,8 +1,6 @@
using Content.Shared.Access.Components; using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Access.Systems namespace Content.Shared.Access.Systems
{ {
@@ -22,19 +20,6 @@ namespace Content.Shared.Access.Systems
SubscribeLocalEvent<IdCardConsoleComponent, ComponentInit>(OnComponentInit); SubscribeLocalEvent<IdCardConsoleComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<IdCardConsoleComponent, ComponentRemove>(OnComponentRemove); SubscribeLocalEvent<IdCardConsoleComponent, ComponentRemove>(OnComponentRemove);
SubscribeLocalEvent<IdCardConsoleComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<IdCardConsoleComponent, ComponentHandleState>(OnHandleState);
}
private void OnHandleState(EntityUid uid, IdCardConsoleComponent component, ref ComponentHandleState args)
{
if (args.Current is not IdCardConsoleComponentState state) return;
component.AccessLevels = state.AccessLevels;
}
private void OnGetState(EntityUid uid, IdCardConsoleComponent component, ref ComponentGetState args)
{
args.State = new IdCardConsoleComponentState(component.AccessLevels);
} }
private void OnComponentInit(EntityUid uid, IdCardConsoleComponent component, ComponentInit args) private void OnComponentInit(EntityUid uid, IdCardConsoleComponent component, ComponentInit args)
@@ -48,16 +33,5 @@ namespace Content.Shared.Access.Systems
_itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot); _itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot);
_itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot); _itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot);
} }
[Serializable, NetSerializable]
private sealed class IdCardConsoleComponentState : ComponentState
{
public List<string> AccessLevels;
public IdCardConsoleComponentState(List<string> accessLevels)
{
AccessLevels = accessLevels;
}
}
} }
} }

View File

@@ -6,11 +6,12 @@ namespace Content.Shared.Alert;
/// Handles the icons on the right side of the screen. /// Handles the icons on the right side of the screen.
/// Should only be used for player-controlled entities. /// Should only be used for player-controlled entities.
/// </summary> /// </summary>
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[NetworkedComponent]
public sealed partial class AlertsComponent : Component public sealed partial class AlertsComponent : Component
{ {
[ViewVariables] public Dictionary<AlertKey, AlertState> Alerts = new(); [ViewVariables]
[AutoNetworkedField]
public Dictionary<AlertKey, AlertState> Alerts = new();
public override bool SendOnlyToOwner => true; public override bool SendOnlyToOwner => true;
} }

View File

@@ -1,14 +0,0 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Alert;
[Serializable, NetSerializable]
public sealed class AlertsComponentState : ComponentState
{
public Dictionary<AlertKey, AlertState> Alerts;
public AlertsComponentState(Dictionary<AlertKey, AlertState> alerts)
{
Alerts = alerts;
}
}

View File

@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Shared.Alert; namespace Content.Shared.Alert;
@@ -170,7 +169,6 @@ public abstract class AlertsSystem : EntitySystem
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup); SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown); SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
SubscribeLocalEvent<AlertsComponent, ComponentGetState>(ClientAlertsGetState);
SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert); SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert);
LoadPrototypes(); LoadPrototypes();
@@ -243,9 +241,4 @@ public abstract class AlertsSystem : EntitySystem
alert.OnClick?.AlertClicked(player.Value); alert.OnClick?.AlertClicked(player.Value);
} }
private static void ClientAlertsGetState(EntityUid uid, AlertsComponent component, ref ComponentGetState args)
{
args.State = new AlertsComponentState(component.Alerts);
}
} }

View File

@@ -2,7 +2,6 @@ using System.Numerics;
using Content.Shared.Damage; using Content.Shared.Damage;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Anomaly.Components; namespace Content.Shared.Anomaly.Components;
@@ -14,7 +13,8 @@ namespace Content.Shared.Anomaly.Components;
/// ///
/// Anomalies and their related components were designed here: https://hackmd.io/@ss14-design/r1sQbkJOs /// Anomalies and their related components were designed here: https://hackmd.io/@ss14-design/r1sQbkJOs
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAnomalySystem))]
public sealed partial class AnomalyComponent : Component public sealed partial class AnomalyComponent : Component
{ {
/// <summary> /// <summary>
@@ -27,7 +27,7 @@ public sealed partial class AnomalyComponent : Component
/// Note that this doesn't refer to stability as a percentage: This is an arbitrary /// Note that this doesn't refer to stability as a percentage: This is an arbitrary
/// value that only matters in relation to the <see cref="GrowthThreshold"/> and <see cref="DecayThreshold"/> /// value that only matters in relation to the <see cref="GrowthThreshold"/> and <see cref="DecayThreshold"/>
/// </remarks> /// </remarks>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Stability = 0f; public float Stability = 0f;
/// <summary> /// <summary>
@@ -39,7 +39,7 @@ public sealed partial class AnomalyComponent : Component
/// <remarks> /// <remarks>
/// Wacky-Stability scale lives on in my heart. - emo /// Wacky-Stability scale lives on in my heart. - emo
/// </remarks> /// </remarks>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Severity = 0f; public float Severity = 0f;
#region Health #region Health
@@ -49,7 +49,7 @@ public sealed partial class AnomalyComponent : Component
/// When the health of an anomaly reaches 0, it is destroyed without ever /// When the health of an anomaly reaches 0, it is destroyed without ever
/// reaching a supercritical point. /// reaching a supercritical point.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Health = 1f; public float Health = 1f;
/// <summary> /// <summary>
@@ -85,25 +85,26 @@ public sealed partial class AnomalyComponent : Component
/// <summary> /// <summary>
/// The time at which the next artifact pulse will occur. /// The time at which the next artifact pulse will occur.
/// </summary> /// </summary>
[DataField("nextPulseTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan NextPulseTime = TimeSpan.Zero; public TimeSpan NextPulseTime = TimeSpan.Zero;
/// <summary> /// <summary>
/// The minimum interval between pulses. /// The minimum interval between pulses.
/// </summary> /// </summary>
[DataField("minPulseLength")] [DataField]
public TimeSpan MinPulseLength = TimeSpan.FromMinutes(1); public TimeSpan MinPulseLength = TimeSpan.FromMinutes(1);
/// <summary> /// <summary>
/// The maximum interval between pulses. /// The maximum interval between pulses.
/// </summary> /// </summary>
[DataField("maxPulseLength")] [DataField]
public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(2); public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(2);
/// <summary> /// <summary>
/// A percentage by which the length of a pulse might vary. /// A percentage by which the length of a pulse might vary.
/// </summary> /// </summary>
[DataField("pulseVariation")] [DataField]
public float PulseVariation = 0.1f; public float PulseVariation = 0.1f;
/// <summary> /// <summary>
@@ -112,19 +113,19 @@ public sealed partial class AnomalyComponent : Component
/// <remarks> /// <remarks>
/// This is more likely to trend upwards than donwards, because that's funny /// This is more likely to trend upwards than donwards, because that's funny
/// </remarks> /// </remarks>
[DataField("pulseStabilityVariation")] [DataField]
public Vector2 PulseStabilityVariation = new(-0.1f, 0.15f); public Vector2 PulseStabilityVariation = new(-0.1f, 0.15f);
/// <summary> /// <summary>
/// The sound played when an anomaly pulses /// The sound played when an anomaly pulses
/// </summary> /// </summary>
[DataField("pulseSound")] [DataField]
public SoundSpecifier? PulseSound = new SoundCollectionSpecifier("RadiationPulse"); public SoundSpecifier? PulseSound = new SoundCollectionSpecifier("RadiationPulse");
/// <summary> /// <summary>
/// The sound plays when an anomaly goes supercritical /// The sound plays when an anomaly goes supercritical
/// </summary> /// </summary>
[DataField("supercriticalSound")] [DataField]
public SoundSpecifier? SupercriticalSound = new SoundCollectionSpecifier("explosion"); public SoundSpecifier? SupercriticalSound = new SoundCollectionSpecifier("explosion");
#endregion #endregion
@@ -134,7 +135,7 @@ public sealed partial class AnomalyComponent : Component
/// <remarks> /// <remarks>
/// +/- 0.2 from perfect stability (0.5) /// +/- 0.2 from perfect stability (0.5)
/// </remarks> /// </remarks>
[DataField("initialStabilityRange")] [DataField]
public (float, float) InitialStabilityRange = (0.4f, 0.6f); public (float, float) InitialStabilityRange = (0.4f, 0.6f);
/// <summary> /// <summary>
@@ -143,25 +144,25 @@ public sealed partial class AnomalyComponent : Component
/// <remarks> /// <remarks>
/// Between 0 and 0.5, which should be all mild effects /// Between 0 and 0.5, which should be all mild effects
/// </remarks> /// </remarks>
[DataField("initialSeverityRange")] [DataField]
public (float, float) InitialSeverityRange = (0.1f, 0.5f); public (float, float) InitialSeverityRange = (0.1f, 0.5f);
/// <summary> /// <summary>
/// The particle type that increases the severity of the anomaly. /// The particle type that increases the severity of the anomaly.
/// </summary> /// </summary>
[DataField("severityParticleType")] [DataField]
public AnomalousParticleType SeverityParticleType; public AnomalousParticleType SeverityParticleType;
/// <summary> /// <summary>
/// The particle type that destabilizes the anomaly. /// The particle type that destabilizes the anomaly.
/// </summary> /// </summary>
[DataField("destabilizingParticleType")] [DataField]
public AnomalousParticleType DestabilizingParticleType; public AnomalousParticleType DestabilizingParticleType;
/// <summary> /// <summary>
/// The particle type that weakens the anomalys health. /// The particle type that weakens the anomalys health.
/// </summary> /// </summary>
[DataField("weakeningParticleType")] [DataField]
public AnomalousParticleType WeakeningParticleType; public AnomalousParticleType WeakeningParticleType;
#region Points and Vessels #region Points and Vessels
@@ -197,14 +198,14 @@ public sealed partial class AnomalyComponent : Component
/// The amount of damage dealt when either a player touches the anomaly /// The amount of damage dealt when either a player touches the anomaly
/// directly or by hitting the anomaly. /// directly or by hitting the anomaly.
/// </summary> /// </summary>
[DataField("anomalyContactDamage", required: true)] [DataField(required: true)]
public DamageSpecifier AnomalyContactDamage = default!; public DamageSpecifier AnomalyContactDamage = default!;
/// <summary> /// <summary>
/// The sound effect played when a player /// The sound effect played when a player
/// burns themselves on an anomaly via contact. /// burns themselves on an anomaly via contact.
/// </summary> /// </summary>
[DataField("anomalyContactDamageSound")] [DataField]
public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg"); public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
#region Floating Animation #region Floating Animation
@@ -226,23 +227,6 @@ public sealed partial class AnomalyComponent : Component
#endregion #endregion
} }
[Serializable, NetSerializable]
public sealed class AnomalyComponentState : ComponentState
{
public float Severity;
public float Stability;
public float Health;
public TimeSpan NextPulseTime;
public AnomalyComponentState(float severity, float stability, float health, TimeSpan nextPulseTime)
{
Severity = severity;
Stability = stability;
Health = health;
NextPulseTime = nextPulseTime;
}
}
/// <summary> /// <summary>
/// Event raised at regular intervals on an anomaly to do whatever its effect is. /// Event raised at regular intervals on an anomaly to do whatever its effect is.
/// </summary> /// </summary>

View File

@@ -1,5 +1,4 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Anomaly.Components; namespace Content.Shared.Anomaly.Components;
@@ -7,31 +6,27 @@ namespace Content.Shared.Anomaly.Components;
/// <summary> /// <summary>
/// Tracks anomalies going supercritical /// Tracks anomalies going supercritical
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAnomalySystem))]
public sealed partial class AnomalySupercriticalComponent : Component public sealed partial class AnomalySupercriticalComponent : Component
{ {
/// <summary> /// <summary>
/// The time when the supercritical animation ends and it does whatever effect. /// The time when the supercritical animation ends and it does whatever effect.
/// </summary> /// </summary>
[DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan EndTime; public TimeSpan EndTime;
/// <summary> /// <summary>
/// The length of the animation before it goes supercritical. /// The length of the animation before it goes supercritical.
/// </summary> /// </summary>
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan SupercriticalDuration = TimeSpan.FromSeconds(10); public TimeSpan SupercriticalDuration = TimeSpan.FromSeconds(10);
/// <summary> /// <summary>
/// The maximum size the anomaly scales to while going supercritical /// The maximum size the anomaly scales to while going supercritical
/// </summary> /// </summary>
[DataField("maxScaleAmount")] [DataField]
public float MaxScaleAmount = 3; public float MaxScaleAmount = 3;
} }
[Serializable, NetSerializable]
public sealed class AnomalySupercriticalComponentState : ComponentState
{
public TimeSpan EndTime;
public TimeSpan Duration;
}

View File

@@ -5,7 +5,6 @@ using Content.Shared.Database;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.GameStates;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Timing; using Robust.Shared.Timing;
@@ -30,10 +29,6 @@ public abstract class SharedAnomalySystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<AnomalyComponent, ComponentGetState>(OnAnomalyGetState);
SubscribeLocalEvent<AnomalyComponent, ComponentHandleState>(OnAnomalyHandleState);
SubscribeLocalEvent<AnomalySupercriticalComponent, ComponentGetState>(OnSupercriticalGetState);
SubscribeLocalEvent<AnomalySupercriticalComponent, ComponentHandleState>(OnSupercriticalHandleState);
SubscribeLocalEvent<AnomalyComponent, InteractHandEvent>(OnInteractHand); SubscribeLocalEvent<AnomalyComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<AnomalyComponent, AttackedEvent>(OnAttacked); SubscribeLocalEvent<AnomalyComponent, AttackedEvent>(OnAttacked);
@@ -44,43 +39,6 @@ public abstract class SharedAnomalySystem : EntitySystem
_sawmill = Logger.GetSawmill("anomaly"); _sawmill = Logger.GetSawmill("anomaly");
} }
private void OnAnomalyGetState(EntityUid uid, AnomalyComponent component, ref ComponentGetState args)
{
args.State = new AnomalyComponentState(
component.Severity,
component.Stability,
component.Health,
component.NextPulseTime);
}
private void OnAnomalyHandleState(EntityUid uid, AnomalyComponent component, ref ComponentHandleState args)
{
if (args.Current is not AnomalyComponentState state)
return;
component.Severity = state.Severity;
component.Stability = state.Stability;
component.Health = state.Health;
component.NextPulseTime = state.NextPulseTime;
}
private void OnSupercriticalGetState(EntityUid uid, AnomalySupercriticalComponent component, ref ComponentGetState args)
{
args.State = new AnomalySupercriticalComponentState
{
EndTime = component.EndTime,
Duration = component.SupercriticalDuration
};
}
private void OnSupercriticalHandleState(EntityUid uid, AnomalySupercriticalComponent component, ref ComponentHandleState args)
{
if (args.Current is not AnomalySupercriticalComponentState state)
return;
component.EndTime = state.EndTime;
component.SupercriticalDuration = state.Duration;
}
private void OnInteractHand(EntityUid uid, AnomalyComponent component, InteractHandEvent args) private void OnInteractHand(EntityUid uid, AnomalyComponent component, InteractHandEvent args)
{ {
DoAnomalyBurnDamage(uid, args.User, component); DoAnomalyBurnDamage(uid, args.User, component);

View File

@@ -1,24 +1,10 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.BarSign namespace Content.Shared.BarSign;
{
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class BarSignComponent : Component public sealed partial class BarSignComponent : Component
{ {
[DataField("current", customTypeSerializer:typeof(PrototypeIdSerializer<BarSignPrototype>))] [DataField, AutoNetworkedField] public ProtoId<BarSignPrototype>? Current;
public string? CurrentSign;
}
[Serializable, NetSerializable]
public sealed class BarSignComponentState : ComponentState
{
public string? CurrentSign;
public BarSignComponentState(string? current)
{
CurrentSign = current;
}
}
} }

View File

@@ -4,18 +4,17 @@ using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Body.Components; namespace Content.Shared.Body.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedBodySystem))] [Access(typeof(SharedBodySystem))]
public sealed partial class BodyComponent : Component public sealed partial class BodyComponent : Component
{ {
/// <summary> /// <summary>
/// Relevant template to spawn for this body. /// Relevant template to spawn for this body.
/// </summary> /// </summary>
[DataField] [DataField, AutoNetworkedField]
public ProtoId<BodyPrototype>? Prototype; public ProtoId<BodyPrototype>? Prototype;
/// <summary> /// <summary>
@@ -29,35 +28,17 @@ public sealed partial class BodyComponent : Component
[ViewVariables] [ViewVariables]
public string RootPartSlot => RootContainer.ID; public string RootPartSlot => RootContainer.ID;
[DataField] public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib"); [DataField, AutoNetworkedField]
public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib");
/// <summary> /// <summary>
/// The amount of legs required to move at full speed. /// The amount of legs required to move at full speed.
/// If 0, then legs do not impact speed. /// If 0, then legs do not impact speed.
/// </summary> /// </summary>
[DataField] public int RequiredLegs; [DataField, AutoNetworkedField]
public int RequiredLegs;
[ViewVariables] [ViewVariables]
[DataField] [DataField, AutoNetworkedField]
public HashSet<EntityUid> LegEntities = new(); public HashSet<EntityUid> LegEntities = new();
} }
[Serializable, NetSerializable]
public sealed class BodyComponentState : ComponentState
{
public string? Prototype;
public string? RootPartSlot;
public SoundSpecifier GibSound;
public int RequiredLegs;
public HashSet<NetEntity> LegNetEntities;
public BodyComponentState(string? prototype, string? rootPartSlot, SoundSpecifier gibSound,
int requiredLegs, HashSet<NetEntity> legNetEntities)
{
Prototype = prototype;
RootPartSlot = rootPartSlot;
GibSound = gibSound;
RequiredLegs = requiredLegs;
LegNetEntities = legNetEntities;
}
}

View File

@@ -6,9 +6,7 @@ using Content.Shared.Body.Part;
using Content.Shared.Body.Prototypes; using Content.Shared.Body.Prototypes;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map; using Robust.Shared.Map;
using MapInitEvent = Robust.Shared.GameObjects.MapInitEvent;
namespace Content.Shared.Body.Systems; namespace Content.Shared.Body.Systems;
@@ -30,8 +28,6 @@ public partial class SharedBodySystem
SubscribeLocalEvent<BodyComponent, ComponentInit>(OnBodyInit); SubscribeLocalEvent<BodyComponent, ComponentInit>(OnBodyInit);
SubscribeLocalEvent<BodyComponent, MapInitEvent>(OnBodyMapInit); SubscribeLocalEvent<BodyComponent, MapInitEvent>(OnBodyMapInit);
SubscribeLocalEvent<BodyComponent, CanDragEvent>(OnBodyCanDrag); SubscribeLocalEvent<BodyComponent, CanDragEvent>(OnBodyCanDrag);
SubscribeLocalEvent<BodyComponent, ComponentGetState>(OnBodyGetState);
SubscribeLocalEvent<BodyComponent, ComponentHandleState>(OnBodyHandleState);
} }
private void OnBodyInserted(EntityUid uid, BodyComponent component, EntInsertedIntoContainerMessage args) private void OnBodyInserted(EntityUid uid, BodyComponent component, EntInsertedIntoContainerMessage args)
@@ -82,28 +78,6 @@ public partial class SharedBodySystem
} }
} }
private void OnBodyHandleState(EntityUid uid, BodyComponent component, ref ComponentHandleState args)
{
if (args.Current is not BodyComponentState state)
return;
component.Prototype = state.Prototype != null ? state.Prototype : null!;
component.GibSound = state.GibSound;
component.RequiredLegs = state.RequiredLegs;
component.LegEntities = EntityManager.EnsureEntitySet<BodyComponent>(state.LegNetEntities, uid);
}
private void OnBodyGetState(EntityUid uid, BodyComponent component, ref ComponentGetState args)
{
args.State = new BodyComponentState(
component.Prototype,
component.RootPartSlot,
component.GibSound,
component.RequiredLegs,
EntityManager.GetNetEntitySet(component.LegEntities)
);
}
private void OnBodyInit(EntityUid bodyId, BodyComponent body, ComponentInit args) private void OnBodyInit(EntityUid bodyId, BodyComponent body, ComponentInit args)
{ {
// Setup the initial container. // Setup the initial container.

View File

@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Buckle.Components; namespace Content.Shared.Buckle.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedBuckleSystem))] [Access(typeof(SharedBuckleSystem))]
public sealed partial class BuckleComponent : Component public sealed partial class BuckleComponent : Component
{ {
@@ -13,7 +13,7 @@ public sealed partial class BuckleComponent : Component
/// Separated from normal interaction range to fix the "someone buckled to a strap /// Separated from normal interaction range to fix the "someone buckled to a strap
/// across a table two tiles away" problem. /// across a table two tiles away" problem.
/// </summary> /// </summary>
[DataField("range")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float Range = SharedInteractionSystem.InteractionRange / 1.4f; public float Range = SharedInteractionSystem.InteractionRange / 1.4f;
@@ -21,32 +21,34 @@ public sealed partial class BuckleComponent : Component
/// True if the entity is buckled, false otherwise. /// True if the entity is buckled, false otherwise.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public bool Buckled; public bool Buckled;
[ViewVariables] [ViewVariables]
[AutoNetworkedField]
public EntityUid? LastEntityBuckledTo; public EntityUid? LastEntityBuckledTo;
/// <summary> /// <summary>
/// Whether or not collisions should be possible with the entity we are strapped to /// Whether or not collisions should be possible with the entity we are strapped to
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("dontCollide")] [DataField, AutoNetworkedField]
public bool DontCollide; public bool DontCollide;
/// <summary> /// <summary>
/// Whether or not we should be allowed to pull the entity we are strapped to /// Whether or not we should be allowed to pull the entity we are strapped to
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("pullStrap")] [DataField]
public bool PullStrap; public bool PullStrap;
/// <summary> /// <summary>
/// The amount of time that must pass for this entity to /// The amount of time that must pass for this entity to
/// be able to unbuckle after recently buckling. /// be able to unbuckle after recently buckling.
/// </summary> /// </summary>
[DataField("delay")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan UnbuckleDelay = TimeSpan.FromSeconds(0.25f); public TimeSpan Delay = TimeSpan.FromSeconds(0.25f);
/// <summary> /// <summary>
/// The time that this entity buckled at. /// The time that this entity buckled at.
@@ -58,39 +60,21 @@ public sealed partial class BuckleComponent : Component
/// The strap that this component is buckled to. /// The strap that this component is buckled to.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
[AutoNetworkedField]
public EntityUid? BuckledTo; public EntityUid? BuckledTo;
/// <summary> /// <summary>
/// The amount of space that this entity occupies in a /// The amount of space that this entity occupies in a
/// <see cref="StrapComponent"/>. /// <see cref="StrapComponent"/>.
/// </summary> /// </summary>
[DataField("size")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public int Size = 100; public int Size = 100;
/// <summary> /// <summary>
/// Used for client rendering /// Used for client rendering
/// </summary> /// </summary>
[ViewVariables] [ViewVariables] public int? OriginalDrawDepth;
public int? OriginalDrawDepth;
}
[Serializable, NetSerializable]
public sealed class BuckleComponentState : ComponentState
{
public BuckleComponentState(bool buckled, NetEntity? buckledTo, NetEntity? lastEntityBuckledTo,
bool dontCollide)
{
Buckled = buckled;
BuckledTo = buckledTo;
LastEntityBuckledTo = lastEntityBuckledTo;
DontCollide = dontCollide;
}
public readonly bool Buckled;
public readonly NetEntity? BuckledTo;
public readonly NetEntity? LastEntityBuckledTo;
public readonly bool DontCollide;
} }
[ByRefEvent] [ByRefEvent]

View File

@@ -8,28 +8,29 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Buckle.Components; namespace Content.Shared.Buckle.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedBuckleSystem), typeof(SharedVehicleSystem))] [Access(typeof(SharedBuckleSystem), typeof(SharedVehicleSystem))]
public sealed partial class StrapComponent : Component public sealed partial class StrapComponent : Component
{ {
/// <summary> /// <summary>
/// The entities that are currently buckled /// The entities that are currently buckled
/// </summary> /// </summary>
[AutoNetworkedField(true)]
[ViewVariables] // TODO serialization [ViewVariables] // TODO serialization
public readonly HashSet<EntityUid> BuckledEntities = new(); public HashSet<EntityUid> BuckledEntities = new();
/// <summary> /// <summary>
/// Entities that this strap accepts and can buckle /// Entities that this strap accepts and can buckle
/// If null it accepts any entity /// If null it accepts any entity
/// </summary> /// </summary>
[DataField("allowedEntities")] [DataField]
[ViewVariables] [ViewVariables]
public EntityWhitelist? AllowedEntities; public EntityWhitelist? AllowedEntities;
/// <summary> /// <summary>
/// The change in position to the strapped mob /// The change in position to the strapped mob
/// </summary> /// </summary>
[DataField("position")] [DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public StrapPosition Position = StrapPosition.None; public StrapPosition Position = StrapPosition.None;
@@ -43,7 +44,7 @@ public sealed partial class StrapComponent : Component
/// whereas the server doesnt, thus the client tries to unbuckle like 15 times because it passes the strap null check /// whereas the server doesnt, thus the client tries to unbuckle like 15 times because it passes the strap null check
/// This is why this needs to be above 0.1 to make the InRange check fail in both client and server. /// This is why this needs to be above 0.1 to make the InRange check fail in both client and server.
/// </remarks> /// </remarks>
[DataField("maxBuckleDistance", required: false)] [DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float MaxBuckleDistance = 0.2f; public float MaxBuckleDistance = 0.2f;
@@ -51,8 +52,8 @@ public sealed partial class StrapComponent : Component
/// Gets and clamps the buckle offset to MaxBuckleDistance /// Gets and clamps the buckle offset to MaxBuckleDistance
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public Vector2 BuckleOffset => Vector2.Clamp( public Vector2 BuckleOffsetClamped => Vector2.Clamp(
BuckleOffsetUnclamped, BuckleOffset,
Vector2.One * -MaxBuckleDistance, Vector2.One * -MaxBuckleDistance,
Vector2.One * MaxBuckleDistance); Vector2.One * MaxBuckleDistance);
@@ -60,21 +61,21 @@ public sealed partial class StrapComponent : Component
/// The buckled entity will be offset by this amount from the center of the strap object. /// The buckled entity will be offset by this amount from the center of the strap object.
/// If this offset it too big, it will be clamped to <see cref="MaxBuckleDistance"/> /// If this offset it too big, it will be clamped to <see cref="MaxBuckleDistance"/>
/// </summary> /// </summary>
[DataField("buckleOffset", required: false)] [DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public Vector2 BuckleOffsetUnclamped = Vector2.Zero; public Vector2 BuckleOffset = Vector2.Zero;
/// <summary> /// <summary>
/// The angle in degrees to rotate the player by when they get strapped /// The angle in degrees to rotate the player by when they get strapped
/// </summary> /// </summary>
[DataField("rotation")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public int Rotation; public int Rotation;
/// <summary> /// <summary>
/// The size of the strap which is compared against when buckling entities /// The size of the strap which is compared against when buckling entities
/// </summary> /// </summary>
[DataField("size")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public int Size = 100; public int Size = 100;
@@ -87,58 +88,39 @@ public sealed partial class StrapComponent : Component
/// <summary> /// <summary>
/// You can specify the offset the entity will have after unbuckling. /// You can specify the offset the entity will have after unbuckling.
/// </summary> /// </summary>
[DataField("unbuckleOffset", required: false)] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public Vector2 UnbuckleOffset = Vector2.Zero; public Vector2 UnbuckleOffset = Vector2.Zero;
/// <summary> /// <summary>
/// The sound to be played when a mob is buckled /// The sound to be played when a mob is buckled
/// </summary> /// </summary>
[DataField("buckleSound")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier BuckleSound = new SoundPathSpecifier("/Audio/Effects/buckle.ogg"); public SoundSpecifier BuckleSound = new SoundPathSpecifier("/Audio/Effects/buckle.ogg");
/// <summary> /// <summary>
/// The sound to be played when a mob is unbuckled /// The sound to be played when a mob is unbuckled
/// </summary> /// </summary>
[DataField("unbuckleSound")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier UnbuckleSound = new SoundPathSpecifier("/Audio/Effects/unbuckle.ogg"); public SoundSpecifier UnbuckleSound = new SoundPathSpecifier("/Audio/Effects/unbuckle.ogg");
/// <summary> /// <summary>
/// ID of the alert to show when buckled /// ID of the alert to show when buckled
/// </summary> /// </summary>
[DataField("buckledAlertType")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public AlertType BuckledAlertType = AlertType.Buckled; public AlertType BuckledAlertType = AlertType.Buckled;
/// <summary> /// <summary>
/// The sum of the sizes of all the buckled entities in this strap /// The sum of the sizes of all the buckled entities in this strap
/// </summary> /// </summary>
[AutoNetworkedField]
[ViewVariables] [ViewVariables]
public int OccupiedSize; public int OccupiedSize;
} }
[Serializable, NetSerializable]
public sealed class StrapComponentState : ComponentState
{
public readonly StrapPosition Position;
public readonly float MaxBuckleDistance;
public readonly Vector2 BuckleOffsetClamped;
public readonly HashSet<NetEntity> BuckledEntities;
public readonly int OccupiedSize;
public StrapComponentState(StrapPosition position, Vector2 offset, HashSet<NetEntity> buckled,
float maxBuckleDistance, int occupiedSize)
{
Position = position;
BuckleOffsetClamped = offset;
BuckledEntities = buckled;
MaxBuckleDistance = maxBuckleDistance;
OccupiedSize = occupiedSize;
}
}
public enum StrapPosition public enum StrapPosition
{ {
/// <summary> /// <summary>

View File

@@ -12,14 +12,12 @@ using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Events; using Content.Shared.Movement.Events;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Content.Shared.Pulling.Events;
using Content.Shared.Standing; using Content.Shared.Standing;
using Content.Shared.Storage.Components; using Content.Shared.Storage.Components;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using Content.Shared.Vehicle.Components; using Content.Shared.Vehicle.Components;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Events;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -32,7 +30,6 @@ public abstract partial class SharedBuckleSystem
{ {
SubscribeLocalEvent<BuckleComponent, ComponentStartup>(OnBuckleComponentStartup); SubscribeLocalEvent<BuckleComponent, ComponentStartup>(OnBuckleComponentStartup);
SubscribeLocalEvent<BuckleComponent, ComponentShutdown>(OnBuckleComponentShutdown); SubscribeLocalEvent<BuckleComponent, ComponentShutdown>(OnBuckleComponentShutdown);
SubscribeLocalEvent<BuckleComponent, ComponentGetState>(OnBuckleComponentGetState);
SubscribeLocalEvent<BuckleComponent, MoveEvent>(OnBuckleMove); SubscribeLocalEvent<BuckleComponent, MoveEvent>(OnBuckleMove);
SubscribeLocalEvent<BuckleComponent, InteractHandEvent>(OnBuckleInteractHand); SubscribeLocalEvent<BuckleComponent, InteractHandEvent>(OnBuckleInteractHand);
SubscribeLocalEvent<BuckleComponent, GetVerbsEvent<InteractionVerb>>(AddUnbuckleVerb); SubscribeLocalEvent<BuckleComponent, GetVerbsEvent<InteractionVerb>>(AddUnbuckleVerb);
@@ -58,11 +55,6 @@ public abstract partial class SharedBuckleSystem
component.BuckleTime = default; component.BuckleTime = default;
} }
private void OnBuckleComponentGetState(EntityUid uid, BuckleComponent component, ref ComponentGetState args)
{
args.State = new BuckleComponentState(component.Buckled, GetNetEntity(component.BuckledTo), GetNetEntity(component.LastEntityBuckledTo), component.DontCollide);
}
private void OnBuckleMove(EntityUid uid, BuckleComponent component, ref MoveEvent ev) private void OnBuckleMove(EntityUid uid, BuckleComponent component, ref MoveEvent ev)
{ {
if (component.BuckledTo is not {} strapUid) if (component.BuckledTo is not {} strapUid)
@@ -434,7 +426,7 @@ public abstract partial class SharedBuckleSystem
if (attemptEvent.Cancelled) if (attemptEvent.Cancelled)
return false; return false;
if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.UnbuckleDelay) if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.Delay)
return false; return false;
if (!_interaction.InRangeUnobstructed(userUid, strapUid, buckleComp.Range, popup: true)) if (!_interaction.InRangeUnobstructed(userUid, strapUid, buckleComp.Range, popup: true))

View File

@@ -7,7 +7,6 @@ using Content.Shared.Interaction;
using Content.Shared.Storage; using Content.Shared.Storage;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Shared.Buckle; namespace Content.Shared.Buckle;
@@ -19,9 +18,6 @@ public abstract partial class SharedBuckleSystem
SubscribeLocalEvent<StrapComponent, ComponentShutdown>(OnStrapShutdown); SubscribeLocalEvent<StrapComponent, ComponentShutdown>(OnStrapShutdown);
SubscribeLocalEvent<StrapComponent, ComponentRemove>((_, c, _) => StrapRemoveAll(c)); SubscribeLocalEvent<StrapComponent, ComponentRemove>((_, c, _) => StrapRemoveAll(c));
SubscribeLocalEvent<StrapComponent, ComponentGetState>(OnStrapGetState);
SubscribeLocalEvent<StrapComponent, ComponentHandleState>(OnStrapHandleState);
SubscribeLocalEvent<StrapComponent, EntInsertedIntoContainerMessage>(OnStrapEntModifiedFromContainer); SubscribeLocalEvent<StrapComponent, EntInsertedIntoContainerMessage>(OnStrapEntModifiedFromContainer);
SubscribeLocalEvent<StrapComponent, EntRemovedFromContainerMessage>(OnStrapEntModifiedFromContainer); SubscribeLocalEvent<StrapComponent, EntRemovedFromContainerMessage>(OnStrapEntModifiedFromContainer);
SubscribeLocalEvent<StrapComponent, GetVerbsEvent<InteractionVerb>>(AddStrapVerbs); SubscribeLocalEvent<StrapComponent, GetVerbsEvent<InteractionVerb>>(AddStrapVerbs);
@@ -50,24 +46,6 @@ public abstract partial class SharedBuckleSystem
StrapRemoveAll(component); StrapRemoveAll(component);
} }
private void OnStrapGetState(EntityUid uid, StrapComponent component, ref ComponentGetState args)
{
args.State = new StrapComponentState(component.Position, component.BuckleOffset, GetNetEntitySet(component.BuckledEntities), component.MaxBuckleDistance, component.OccupiedSize);
}
private void OnStrapHandleState(EntityUid uid, StrapComponent component, ref ComponentHandleState args)
{
if (args.Current is not StrapComponentState state)
return;
component.Position = state.Position;
component.BuckleOffsetUnclamped = state.BuckleOffsetClamped;
component.BuckledEntities.Clear();
component.BuckledEntities.UnionWith(EnsureEntitySet<StrapComponent>(state.BuckledEntities, uid));
component.MaxBuckleDistance = state.MaxBuckleDistance;
component.OccupiedSize = state.OccupiedSize;
}
private void OnStrapEntModifiedFromContainer(EntityUid uid, StrapComponent component, ContainerModifiedMessage message) private void OnStrapEntModifiedFromContainer(EntityUid uid, StrapComponent component, ContainerModifiedMessage message)
{ {
if (_gameTiming.ApplyingState) if (_gameTiming.ApplyingState)

View File

@@ -65,7 +65,7 @@ public abstract partial class SharedBuckleSystem : EntitySystem
|| !Resolve(buckleUid, ref buckleComp, false)) || !Resolve(buckleUid, ref buckleComp, false))
return; return;
_transform.SetCoordinates(buckleUid, new EntityCoordinates(strapUid, strapComp.BuckleOffset)); _transform.SetCoordinates(buckleUid, new EntityCoordinates(strapUid, strapComp.BuckleOffsetClamped));
var buckleTransform = Transform(buckleUid); var buckleTransform = Transform(buckleUid);

View File

@@ -1,65 +1,43 @@
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Cabinet; namespace Content.Shared.Cabinet;
/// <summary> /// <summary>
/// Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets. /// Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ItemCabinetComponent : Component public sealed partial class ItemCabinetComponent : Component
{ {
/// <summary> /// <summary>
/// Sound to be played when the cabinet door is opened. /// Sound to be played when the cabinet door is opened.
/// </summary> /// </summary>
[DataField("doorSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier? DoorSound; public SoundSpecifier? DoorSound;
/// <summary> /// <summary>
/// The <see cref="ItemSlot"/> that stores the actual item. The entity whitelist, sounds, and other /// The <see cref="ItemSlot"/> that stores the actual item. The entity whitelist, sounds, and other
/// behaviours are specified by this <see cref="ItemSlot"/> definition. /// behaviours are specified by this <see cref="ItemSlot"/> definition.
/// </summary> /// </summary>
[DataField("cabinetSlot"), ViewVariables] [DataField, ViewVariables]
public ItemSlot CabinetSlot = new(); public ItemSlot CabinetSlot = new();
/// <summary> /// <summary>
/// Whether the cabinet is currently open or not. /// Whether the cabinet is currently open or not.
/// </summary> /// </summary>
[DataField("opened")] [DataField, AutoNetworkedField]
public bool Opened; public bool Opened;
/// <summary> /// <summary>
/// The state for when the cabinet is open /// The state for when the cabinet is open
/// </summary> /// </summary>
[DataField("openState"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public string? OpenState; public string? OpenState;
/// <summary> /// <summary>
/// The state for when the cabinet is closed /// The state for when the cabinet is closed
/// </summary> /// </summary>
[DataField("closedState"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public string? ClosedState; public string? ClosedState;
} }
[Serializable, NetSerializable]
public sealed class ItemCabinetComponentState : ComponentState
{
public SoundSpecifier? DoorSound;
public bool Opened;
public string? OpenState;
public string? ClosedState;
public ItemCabinetComponentState(SoundSpecifier? doorSound, bool opened, string? openState, string? closedState)
{
DoorSound = doorSound;
Opened = opened;
OpenState = openState;
ClosedState = closedState;
}
}

View File

@@ -4,7 +4,6 @@ using Content.Shared.Lock;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -19,9 +18,6 @@ public abstract class SharedItemCabinetSystem : EntitySystem
/// <inheritdoc/> /// <inheritdoc/>
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<ItemCabinetComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<ItemCabinetComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit); SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove); SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove);
SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup); SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup);
@@ -35,24 +31,6 @@ public abstract class SharedItemCabinetSystem : EntitySystem
SubscribeLocalEvent<ItemCabinetComponent, LockToggleAttemptEvent>(OnLockToggleAttempt); SubscribeLocalEvent<ItemCabinetComponent, LockToggleAttemptEvent>(OnLockToggleAttempt);
} }
private void OnGetState(EntityUid uid, ItemCabinetComponent component, ref ComponentGetState args)
{
args.State = new ItemCabinetComponentState(component.DoorSound,
component.Opened,
component.OpenState,
component.ClosedState);
}
private void OnHandleState(EntityUid uid, ItemCabinetComponent component, ref ComponentHandleState args)
{
if (args.Current is not ItemCabinetComponentState state)
return;
component.DoorSound = state.DoorSound;
component.Opened = state.Opened;
component.OpenState = state.OpenState;
component.ClosedState = state.ClosedState;
}
private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args) private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args)
{ {
_itemSlots.AddItemSlot(uid, "ItemCabinet", cabinet.CabinetSlot); _itemSlots.AddItemSlot(uid, "ItemCabinet", cabinet.CabinetSlot);

View File

@@ -7,25 +7,19 @@ namespace Content.Shared.CartridgeLoader;
/// <summary> /// <summary>
/// This is used for defining values used for displaying in the program ui in yaml /// This is used for defining values used for displaying in the program ui in yaml
/// </summary> /// </summary>
[NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[RegisterComponent]
public sealed partial class CartridgeComponent : Component public sealed partial class CartridgeComponent : Component
{ {
[DataField("programName", required: true)] [DataField(required: true)]
public string ProgramName = "default-program-name"; public string ProgramName = "default-program-name";
[DataField("icon")] [DataField]
public SpriteSpecifier? Icon; public SpriteSpecifier? Icon;
[AutoNetworkedField]
public InstallationStatus InstallationStatus = InstallationStatus.Cartridge; public InstallationStatus InstallationStatus = InstallationStatus.Cartridge;
} }
[Serializable, NetSerializable]
public sealed class CartridgeComponentState : ComponentState
{
public InstallationStatus InstallationStatus;
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public enum InstallationStatus public enum InstallationStatus
{ {

View File

@@ -1,7 +1,5 @@
using Content.Shared.Containers.ItemSlots; using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Network; using Robust.Shared.Network;
namespace Content.Shared.CartridgeLoader; namespace Content.Shared.CartridgeLoader;
@@ -24,10 +22,6 @@ public abstract class SharedCartridgeLoaderSystem : EntitySystem
SubscribeLocalEvent<CartridgeLoaderComponent, EntInsertedIntoContainerMessage>(OnItemInserted); SubscribeLocalEvent<CartridgeLoaderComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
SubscribeLocalEvent<CartridgeLoaderComponent, EntRemovedFromContainerMessage>(OnItemRemoved); SubscribeLocalEvent<CartridgeLoaderComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
SubscribeLocalEvent<CartridgeComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<CartridgeComponent, ComponentHandleState>(OnHandleState);
} }
private void OnComponentInit(EntityUid uid, CartridgeLoaderComponent loader, ComponentInit args) private void OnComponentInit(EntityUid uid, CartridgeLoaderComponent loader, ComponentInit args)
@@ -55,22 +49,6 @@ public abstract class SharedCartridgeLoaderSystem : EntitySystem
UpdateAppearanceData(uid, loader); UpdateAppearanceData(uid, loader);
} }
private void OnGetState(EntityUid uid, CartridgeComponent component, ref ComponentGetState args)
{
var state = new CartridgeComponentState();
state.InstallationStatus = component.InstallationStatus;
args.State = state;
}
private void OnHandleState(EntityUid uid, CartridgeComponent component, ref ComponentHandleState args)
{
if (args.Current is not CartridgeComponentState state)
return;
component.InstallationStatus = state.InstallationStatus;
}
private void UpdateAppearanceData(EntityUid uid, CartridgeLoaderComponent loader) private void UpdateAppearanceData(EntityUid uid, CartridgeLoaderComponent loader)
{ {
_appearanceSystem.SetData(uid, CartridgeLoaderVisuals.CartridgeInserted, loader.CartridgeSlot.HasItem); _appearanceSystem.SetData(uid, CartridgeLoaderVisuals.CartridgeInserted, loader.CartridgeSlot.HasItem);

View File

@@ -1,39 +1,22 @@
using Robust.Shared.Serialization;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
namespace Content.Shared.Chemistry.Components namespace Content.Shared.Chemistry.Components
{ {
//TODO: refactor movement modifier component because this is a pretty poor solution //TODO: refactor movement modifier component because this is a pretty poor solution
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[NetworkedComponent]
public sealed partial class MovespeedModifierMetabolismComponent : Component public sealed partial class MovespeedModifierMetabolismComponent : Component
{ {
[ViewVariables] [AutoNetworkedField, ViewVariables]
public float WalkSpeedModifier { get; set; } public float WalkSpeedModifier { get; set; }
[ViewVariables] [AutoNetworkedField, ViewVariables]
public float SprintSpeedModifier { get; set; } public float SprintSpeedModifier { get; set; }
/// <summary> /// <summary>
/// When the current modifier is expected to end. /// When the current modifier is expected to end.
/// </summary> /// </summary>
[ViewVariables] [AutoNetworkedField, ViewVariables]
public TimeSpan ModifierTimer { get; set; } = TimeSpan.Zero; public TimeSpan ModifierTimer { get; set; } = TimeSpan.Zero;
[Serializable, NetSerializable]
public sealed class MovespeedModifierMetabolismComponentState : ComponentState
{
public float WalkSpeedModifier { get; }
public float SprintSpeedModifier { get; }
public TimeSpan ModifierTimer { get; }
public MovespeedModifierMetabolismComponentState(float walkSpeedModifier, float sprintSpeedModifier, TimeSpan modifierTimer)
{
WalkSpeedModifier = walkSpeedModifier;
SprintSpeedModifier = sprintSpeedModifier;
ModifierTimer = modifierTimer;
}
}
} }
} }

View File

@@ -1,9 +1,6 @@
using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
using static Content.Shared.Chemistry.Components.MovespeedModifierMetabolismComponent; using Robust.Shared.Timing;
namespace Content.Shared.Chemistry namespace Content.Shared.Chemistry
{ {
@@ -21,30 +18,10 @@ namespace Content.Shared.Chemistry
UpdatesOutsidePrediction = true; UpdatesOutsidePrediction = true;
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentHandleState>(OnMovespeedHandleState);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentStartup>(AddComponent); SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentStartup>(AddComponent);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed); SubscribeLocalEvent<MovespeedModifierMetabolismComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
} }
private void OnGetState(EntityUid uid, MovespeedModifierMetabolismComponent component, ref ComponentGetState args)
{
args.State = new MovespeedModifierMetabolismComponentState(
component.WalkSpeedModifier,
component.SprintSpeedModifier,
component.ModifierTimer);
}
private void OnMovespeedHandleState(EntityUid uid, MovespeedModifierMetabolismComponent component, ref ComponentHandleState args)
{
if (args.Current is not MovespeedModifierMetabolismComponentState cast)
return;
component.WalkSpeedModifier = cast.WalkSpeedModifier;
component.SprintSpeedModifier = cast.SprintSpeedModifier;
component.ModifierTimer = cast.ModifierTimer;
}
private void OnRefreshMovespeed(EntityUid uid, MovespeedModifierMetabolismComponent component, RefreshMovementSpeedModifiersEvent args) private void OnRefreshMovespeed(EntityUid uid, MovespeedModifierMetabolismComponent component, RefreshMovementSpeedModifiersEvent args)
{ {
args.ModifySpeed(component.WalkSpeedModifier, component.SprintSpeedModifier); args.ModifySpeed(component.WalkSpeedModifier, component.SprintSpeedModifier);

View File

@@ -1,21 +1,20 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Climbing; namespace Content.Shared.Climbing;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ClimbingComponent : Component public sealed partial class ClimbingComponent : Component
{ {
/// <summary> /// <summary>
/// Whether the owner is climbing on a climbable entity. /// Whether the owner is climbing on a climbable entity.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables, AutoNetworkedField]
public bool IsClimbing { get; set; } public bool IsClimbing { get; set; }
/// <summary> /// <summary>
/// Whether the owner is being moved onto the climbed entity. /// Whether the owner is being moved onto the climbed entity.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables, AutoNetworkedField]
public bool OwnerIsTransitioning { get; set; } public bool OwnerIsTransitioning { get; set; }
/// <summary> /// <summary>
@@ -25,17 +24,4 @@ public sealed partial class ClimbingComponent : Component
[ViewVariables] [ViewVariables]
public Dictionary<string, int> DisabledFixtureMasks { get; } = new(); public Dictionary<string, int> DisabledFixtureMasks { get; } = new();
[Serializable, NetSerializable]
public sealed class ClimbModeComponentState : ComponentState
{
public ClimbModeComponentState(bool climbing, bool isTransitioning)
{
Climbing = climbing;
IsTransitioning = isTransitioning;
}
public bool Climbing { get; }
public bool IsTransitioning { get; }
}
} }

View File

@@ -3,14 +3,13 @@ using Content.Shared.Inventory;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Clothing.Components; namespace Content.Shared.Clothing.Components;
/// <summary> /// <summary>
/// Allow players to change clothing sprite to any other clothing prototype. /// Allow players to change clothing sprite to any other clothing prototype.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedChameleonClothingSystem))] [Access(typeof(SharedChameleonClothingSystem))]
public sealed partial class ChameleonClothingComponent : Component public sealed partial class ChameleonClothingComponent : Component
{ {
@@ -18,15 +17,15 @@ public sealed partial class ChameleonClothingComponent : Component
/// Filter possible chameleon options by their slot flag. /// Filter possible chameleon options by their slot flag.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadOnly)] [ViewVariables(VVAccess.ReadOnly)]
[DataField("slot", required: true)] [DataField(required: true)]
public SlotFlags Slot; public SlotFlags Slot;
/// <summary> /// <summary>
/// EntityPrototype id that chameleon item is trying to mimic. /// EntityPrototype id that chameleon item is trying to mimic.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadOnly)] [ViewVariables(VVAccess.ReadOnly)]
[DataField("default", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] [DataField(required: true), AutoNetworkedField]
public string? SelectedId; public EntProtoId? Default;
/// <summary> /// <summary>
/// Current user that wears chameleon clothing. /// Current user that wears chameleon clothing.
@@ -35,12 +34,6 @@ public sealed partial class ChameleonClothingComponent : Component
public EntityUid? User; public EntityUid? User;
} }
[Serializable, NetSerializable]
public sealed class ChameleonClothingComponentState : ComponentState
{
public string? SelectedId;
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class ChameleonBoundUserInterfaceState : BoundUserInterfaceState public sealed class ChameleonBoundUserInterfaceState : BoundUserInterfaceState
{ {

View File

@@ -38,8 +38,8 @@ public abstract class SharedChameleonClothingSystem : EntitySystem
// This 100% makes sure that server and client have exactly same data. // This 100% makes sure that server and client have exactly same data.
protected void UpdateVisuals(EntityUid uid, ChameleonClothingComponent component) protected void UpdateVisuals(EntityUid uid, ChameleonClothingComponent component)
{ {
if (string.IsNullOrEmpty(component.SelectedId) || if (string.IsNullOrEmpty(component.Default) ||
!_proto.TryIndex(component.SelectedId, out EntityPrototype? proto)) !_proto.TryIndex(component.Default, out EntityPrototype? proto))
return; return;
// world sprite icon // world sprite icon

View File

@@ -1,66 +1,49 @@
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Conveyor; namespace Content.Shared.Conveyor;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ConveyorComponent : Component public sealed partial class ConveyorComponent : Component
{ {
/// <summary> /// <summary>
/// The angle to move entities by in relation to the owner's rotation. /// The angle to move entities by in relation to the owner's rotation.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("angle")] [DataField, AutoNetworkedField]
public Angle Angle = Angle.Zero; public Angle Angle = Angle.Zero;
/// <summary> /// <summary>
/// The amount of units to move the entity by per second. /// The amount of units to move the entity by per second.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("speed")] [DataField, AutoNetworkedField]
public float Speed = 2f; public float Speed = 2f;
/// <summary> /// <summary>
/// The current state of this conveyor /// The current state of this conveyor
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public ConveyorState State; public ConveyorState State;
[ViewVariables] [ViewVariables, AutoNetworkedField]
public bool Powered; public bool Powered;
[DataField("forwardPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))] [DataField]
public string ForwardPort = "Forward"; public ProtoId<SinkPortPrototype> ForwardPort = "Forward";
[DataField("reversePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))] [DataField]
public string ReversePort = "Reverse"; public ProtoId<SinkPortPrototype> ReversePort = "Reverse";
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))] [DataField]
public string OffPort = "Off"; public ProtoId<SinkPortPrototype> OffPort = "Off";
[ViewVariables] [ViewVariables]
public readonly HashSet<EntityUid> Intersecting = new(); public readonly HashSet<EntityUid> Intersecting = new();
} }
[Serializable, NetSerializable]
public sealed class ConveyorComponentState : ComponentState
{
public bool Powered;
public Angle Angle;
public float Speed;
public ConveyorState State;
public ConveyorComponentState(Angle angle, float speed, ConveyorState state, bool powered)
{
Angle = angle;
Speed = speed;
State = state;
Powered = powered;
}
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public enum ConveyorVisuals : byte public enum ConveyorVisuals : byte
{ {

View File

@@ -2,53 +2,50 @@ using Content.Shared.Damage;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
namespace Content.Shared.Cuffs.Components; namespace Content.Shared.Cuffs.Components;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedCuffableSystem))] [Access(typeof(SharedCuffableSystem))]
public sealed partial class HandcuffComponent : Component public sealed partial class HandcuffComponent : Component
{ {
/// <summary> /// <summary>
/// The time it takes to cuff an entity. /// The time it takes to cuff an entity.
/// </summary> /// </summary>
[DataField("cuffTime"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float CuffTime = 3.5f; public float CuffTime = 3.5f;
/// <summary> /// <summary>
/// The time it takes to uncuff an entity. /// The time it takes to uncuff an entity.
/// </summary> /// </summary>
[DataField("uncuffTime"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float UncuffTime = 3.5f; public float UncuffTime = 3.5f;
/// <summary> /// <summary>
/// The time it takes for a cuffed entity to uncuff itself. /// The time it takes for a cuffed entity to uncuff itself.
/// </summary> /// </summary>
[DataField("breakoutTime"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float BreakoutTime = 30f; public float BreakoutTime = 30f;
/// <summary> /// <summary>
/// If an entity being cuffed is stunned, this amount of time is subtracted from the time it takes to add/remove their cuffs. /// If an entity being cuffed is stunned, this amount of time is subtracted from the time it takes to add/remove their cuffs.
/// </summary> /// </summary>
[DataField("stunBonus"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float StunBonus = 2f; public float StunBonus = 2f;
/// <summary> /// <summary>
/// Will the cuffs break when removed? /// Will the cuffs break when removed?
/// </summary> /// </summary>
[DataField("breakOnRemove"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public bool BreakOnRemove; public bool BreakOnRemove;
/// <summary> /// <summary>
/// Will the cuffs break when removed? /// Will the cuffs break when removed?
/// </summary> /// </summary>
[DataField("brokenPrototype", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public string? BrokenPrototype; public EntProtoId? BrokenPrototype;
[DataField("damageOnResist"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier DamageOnResist = new() public DamageSpecifier DamageOnResist = new()
{ {
DamageDict = new() DamageDict = new()
@@ -60,48 +57,37 @@ public sealed partial class HandcuffComponent : Component
/// <summary> /// <summary>
/// The path of the RSI file used for the player cuffed overlay. /// The path of the RSI file used for the player cuffed overlay.
/// </summary> /// </summary>
[DataField("cuffedRSI"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public string? CuffedRSI = "Objects/Misc/handcuffs.rsi"; public string? CuffedRSI = "Objects/Misc/handcuffs.rsi";
/// <summary> /// <summary>
/// The iconstate used with the RSI file for the player cuffed overlay. /// The iconstate used with the RSI file for the player cuffed overlay.
/// </summary> /// </summary>
[DataField("bodyIconState"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public string? OverlayIconState = "body-overlay"; public string? BodyIconState = "body-overlay";
/// <summary> /// <summary>
/// An opptional color specification for <see cref="OverlayIconState"/> /// An opptional color specification for <see cref="BodyIconState"/>
/// </summary> /// </summary>
[DataField("color"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public Color Color = Color.White; public Color Color = Color.White;
[DataField("startCuffSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier StartCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_start.ogg"); public SoundSpecifier StartCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_start.ogg");
[DataField("endCuffSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier EndCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_end.ogg"); public SoundSpecifier EndCuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_end.ogg");
[DataField("startBreakoutSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier StartBreakoutSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_breakout_start.ogg"); public SoundSpecifier StartBreakoutSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_breakout_start.ogg");
[DataField("startUncuffSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier StartUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_start.ogg"); public SoundSpecifier StartUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_start.ogg");
[DataField("endUncuffSound"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier EndUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_end.ogg"); public SoundSpecifier EndUncuffSound = new SoundPathSpecifier("/Audio/Items/Handcuffs/cuff_takeoff_end.ogg");
} }
[Serializable, NetSerializable]
public sealed class HandcuffComponentState : ComponentState
{
public readonly string? IconState;
public HandcuffComponentState(string? iconState)
{
IconState = iconState;
}
}
/// <summary> /// <summary>
/// Event fired on the User when the User attempts to cuff the Target. /// Event fired on the User when the User attempts to cuff the Target.
/// Should generate popups on the User. /// Should generate popups on the User.

View File

@@ -6,48 +6,48 @@ namespace Content.Shared.Damage.Components;
/// <summary> /// <summary>
/// Add to an entity to paralyze it whenever it reaches critical amounts of Stamina DamageType. /// Add to an entity to paralyze it whenever it reaches critical amounts of Stamina DamageType.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class StaminaComponent : Component public sealed partial class StaminaComponent : Component
{ {
/// <summary> /// <summary>
/// Have we reached peak stamina damage and been paralyzed? /// Have we reached peak stamina damage and been paralyzed?
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("critical")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool Critical; public bool Critical;
/// <summary> /// <summary>
/// How much stamina reduces per second. /// How much stamina reduces per second.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("decay")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float Decay = 3f; public float Decay = 3f;
/// <summary> /// <summary>
/// How much time after receiving damage until stamina starts decreasing. /// How much time after receiving damage until stamina starts decreasing.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("cooldown")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float DecayCooldown = 3f; public float Cooldown = 3f;
/// <summary> /// <summary>
/// How much stamina damage this entity has taken. /// How much stamina damage this entity has taken.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("staminaDamage")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float StaminaDamage; public float StaminaDamage;
/// <summary> /// <summary>
/// How much stamina damage is required to entire stam crit. /// How much stamina damage is required to entire stam crit.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("critThreshold")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float CritThreshold = 100f; public float CritThreshold = 100f;
/// <summary> /// <summary>
/// How long will this mob be stunned for? /// How long will this mob be stunned for?
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("stunTime")] [ViewVariables(VVAccess.ReadWrite), DataField]
public TimeSpan StunTime = TimeSpan.FromSeconds(6); public TimeSpan StunTime = TimeSpan.FromSeconds(6);
/// <summary> /// <summary>
/// To avoid continuously updating our data we track the last time we updated so we can extrapolate our current stamina. /// To avoid continuously updating our data we track the last time we updated so we can extrapolate our current stamina.
/// </summary> /// </summary>
[DataField("nextUpdate", customTypeSerializer:typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
public TimeSpan NextUpdate = TimeSpan.Zero; public TimeSpan NextUpdate = TimeSpan.Zero;
} }

View File

@@ -16,11 +16,9 @@ using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee.Events; using Content.Shared.Weapons.Melee.Events;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Shared.Damage.Systems; namespace Content.Shared.Damage.Systems;
@@ -52,8 +50,7 @@ public sealed partial class StaminaSystem : EntitySystem
SubscribeLocalEvent<StaminaComponent, EntityUnpausedEvent>(OnStamUnpaused); SubscribeLocalEvent<StaminaComponent, EntityUnpausedEvent>(OnStamUnpaused);
SubscribeLocalEvent<StaminaComponent, ComponentStartup>(OnStartup); SubscribeLocalEvent<StaminaComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<StaminaComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<StaminaComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<StaminaComponent, ComponentGetState>(OnStamGetState); SubscribeLocalEvent<StaminaComponent, AfterAutoHandleStateEvent>(OnStamHandleState);
SubscribeLocalEvent<StaminaComponent, ComponentHandleState>(OnStamHandleState);
SubscribeLocalEvent<StaminaComponent, DisarmedEvent>(OnDisarmed); SubscribeLocalEvent<StaminaComponent, DisarmedEvent>(OnDisarmed);
SubscribeLocalEvent<StaminaComponent, RejuvenateEvent>(OnRejuvenate); SubscribeLocalEvent<StaminaComponent, RejuvenateEvent>(OnRejuvenate);
@@ -67,31 +64,8 @@ public sealed partial class StaminaSystem : EntitySystem
component.NextUpdate += args.PausedTime; component.NextUpdate += args.PausedTime;
} }
private void OnStamGetState(EntityUid uid, StaminaComponent component, ref ComponentGetState args) private void OnStamHandleState(EntityUid uid, StaminaComponent component, ref AfterAutoHandleStateEvent args)
{ {
args.State = new StaminaComponentState()
{
Critical = component.Critical,
Decay = component.Decay,
CritThreshold = component.CritThreshold,
DecayCooldown = component.DecayCooldown,
LastUpdate = component.NextUpdate,
StaminaDamage = component.StaminaDamage,
};
}
private void OnStamHandleState(EntityUid uid, StaminaComponent component, ref ComponentHandleState args)
{
if (args.Current is not StaminaComponentState state)
return;
component.Critical = state.Critical;
component.Decay = state.Decay;
component.CritThreshold = state.CritThreshold;
component.DecayCooldown = state.DecayCooldown;
component.NextUpdate = state.LastUpdate;
component.StaminaDamage = state.StaminaDamage;
if (component.Critical) if (component.Critical)
EnterStamCrit(uid, component); EnterStamCrit(uid, component);
else else
@@ -283,7 +257,7 @@ public sealed partial class StaminaSystem : EntitySystem
// Reset the decay cooldown upon taking damage. // Reset the decay cooldown upon taking damage.
if (oldDamage < component.StaminaDamage) if (oldDamage < component.StaminaDamage)
{ {
var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.DecayCooldown); var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.Cooldown);
if (component.NextUpdate < nextUpdate) if (component.NextUpdate < nextUpdate)
component.NextUpdate = nextUpdate; component.NextUpdate = nextUpdate;
@@ -419,18 +393,6 @@ public sealed partial class StaminaSystem : EntitySystem
Dirty(component); Dirty(component);
_adminLogger.Add(LogType.Stamina, LogImpact.Low, $"{ToPrettyString(uid):user} recovered from stamina crit"); _adminLogger.Add(LogType.Stamina, LogImpact.Low, $"{ToPrettyString(uid):user} recovered from stamina crit");
} }
[Serializable, NetSerializable]
private sealed class StaminaComponentState : ComponentState
{
public bool Critical;
public float Decay;
public float DecayCooldown;
public float StaminaDamage;
public float CritThreshold;
public TimeSpan LastUpdate;
}
} }
/// <summary> /// <summary>

View File

@@ -1,53 +1,36 @@
using Content.Shared.DeviceNetwork.Systems; using Content.Shared.DeviceNetwork.Systems;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.DeviceNetwork.Components; namespace Content.Shared.DeviceNetwork.Components;
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[NetworkedComponent]
[Access(typeof(SharedDeviceListSystem))] [Access(typeof(SharedDeviceListSystem))]
public sealed partial class DeviceListComponent : Component public sealed partial class DeviceListComponent : Component
{ {
/// <summary> /// <summary>
/// The list of devices can or can't connect to, depending on the <see cref="IsAllowList"/> field. /// The list of devices can or can't connect to, depending on the <see cref="IsAllowList"/> field.
/// </summary> /// </summary>
[DataField("devices")] [DataField, AutoNetworkedField]
public HashSet<EntityUid> Devices = new(); public HashSet<EntityUid> Devices = new();
/// <summary> /// <summary>
/// The limit of devices that can be linked to this device list. /// The limit of devices that can be linked to this device list.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("deviceLimit")] [DataField]
public int DeviceLimit = 32; public int DeviceLimit = 32;
/// <summary> /// <summary>
/// Whether the device list is used as an allow or deny list /// Whether the device list is used as an allow or deny list
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("isAllowList")] [DataField, AutoNetworkedField]
public bool IsAllowList = true; public bool IsAllowList = true;
/// <summary> /// <summary>
/// Whether this device list also handles incoming device net packets /// Whether this device list also handles incoming device net packets
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("handleIncoming")] [DataField, AutoNetworkedField]
public bool HandleIncomingPackets = false; public bool HandleIncomingPackets;
}
[Serializable, NetSerializable]
public sealed class DeviceListComponentState : ComponentState
{
public readonly HashSet<NetEntity> Devices;
public readonly bool IsAllowList;
public readonly bool HandleIncomingPackets;
public DeviceListComponentState(HashSet<NetEntity> devices, bool isAllowList, bool handleIncomingPackets)
{
Devices = devices;
IsAllowList = isAllowList;
HandleIncomingPackets = handleIncomingPackets;
}
} }

View File

@@ -2,72 +2,57 @@ using Content.Shared.DeviceLinking;
using Content.Shared.DeviceNetwork.Systems; using Content.Shared.DeviceNetwork.Systems;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.DeviceNetwork.Components; namespace Content.Shared.DeviceNetwork.Components;
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[NetworkedComponent]
[Access(typeof(SharedNetworkConfiguratorSystem))] [Access(typeof(SharedNetworkConfiguratorSystem))]
public sealed partial class NetworkConfiguratorComponent : Component public sealed partial class NetworkConfiguratorComponent : Component
{ {
/// <summary> /// <summary>
/// Determines whether the configurator is in linking mode or list mode /// Determines whether the configurator is in linking mode or list mode
/// </summary> /// </summary>
[DataField("linkModeActive")] [DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public bool LinkModeActive = true; public bool LinkModeActive = true;
/// <summary> /// <summary>
/// The entity containing a <see cref="DeviceListComponent"/> this configurator is currently interacting with /// The entity containing a <see cref="DeviceListComponent"/> this configurator is currently interacting with
/// </summary> /// </summary>
[DataField("activeDeviceList")] [DataField, AutoNetworkedField]
public EntityUid? ActiveDeviceList = null; public EntityUid? ActiveDeviceList;
/// <summary> /// <summary>
/// The entity containing a <see cref="DeviceLinkSourceComponent"/> or <see cref="DeviceLinkSinkComponent"/> this configurator is currently interacting with.<br/> /// The entity containing a <see cref="DeviceLinkSourceComponent"/> or <see cref="DeviceLinkSinkComponent"/> this configurator is currently interacting with.<br/>
/// If this is set the configurator is in linking mode. /// If this is set the configurator is in linking mode.
/// </summary> /// </summary>
[DataField("activeDeviceLink")] [DataField]
public EntityUid? ActiveDeviceLink = null; public EntityUid? ActiveDeviceLink;
/// <summary> /// <summary>
/// The target device this configurator is currently linking with the <see cref="ActiveDeviceLink"/> /// The target device this configurator is currently linking with the <see cref="ActiveDeviceLink"/>
/// </summary> /// </summary>
[DataField("deviceLinkTarget")] [DataField]
public EntityUid? DeviceLinkTarget = null; public EntityUid? DeviceLinkTarget;
/// <summary> /// <summary>
/// The list of devices stored in the configurator /// The list of devices stored in the configurator
/// </summary> /// </summary>
[DataField("devices")] [DataField]
public Dictionary<string, EntityUid> Devices = new(); public Dictionary<string, EntityUid> Devices = new();
[DataField("useDelay")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan UseDelay = TimeSpan.FromSeconds(0.5); public TimeSpan UseDelay = TimeSpan.FromSeconds(0.5);
[DataField("lastUseAttempt", customTypeSerializer:typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan LastUseAttempt; public TimeSpan LastUseAttempt;
[DataField("soundNoAccess")] [DataField]
public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg"); public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg");
[DataField("soundSwitchMode")] [DataField]
public SoundSpecifier SoundSwitchMode = new SoundPathSpecifier("/Audio/Machines/quickbeep.ogg"); public SoundSpecifier SoundSwitchMode = new SoundPathSpecifier("/Audio/Machines/quickbeep.ogg");
} }
[Serializable, NetSerializable]
public sealed class NetworkConfiguratorComponentState : ComponentState
{
public readonly NetEntity? ActiveDeviceList;
public readonly bool LinkModeActive;
public NetworkConfiguratorComponentState(NetEntity? activeDeviceList, bool linkModeActive)
{
ActiveDeviceList = activeDeviceList;
LinkModeActive = linkModeActive;
}
}

View File

@@ -1,17 +1,10 @@
using System.Linq; using System.Linq;
using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Components;
using Robust.Shared.GameStates;
namespace Content.Shared.DeviceNetwork.Systems; namespace Content.Shared.DeviceNetwork.Systems;
public abstract class SharedDeviceListSystem : EntitySystem public abstract class SharedDeviceListSystem : EntitySystem
{ {
public override void Initialize()
{
SubscribeLocalEvent<DeviceListComponent, ComponentGetState>(GetDeviceListState);
SubscribeLocalEvent<DeviceListComponent, ComponentHandleState>(HandleDeviceListState);
}
/// <summary> /// <summary>
/// Updates the device list stored on this entity. /// Updates the device list stored on this entity.
/// </summary> /// </summary>
@@ -57,23 +50,6 @@ public abstract class SharedDeviceListSystem : EntitySystem
protected virtual void UpdateShutdownSubscription(EntityUid uid, List<EntityUid> devicesList, List<EntityUid> oldDevices) protected virtual void UpdateShutdownSubscription(EntityUid uid, List<EntityUid> devicesList, List<EntityUid> oldDevices)
{ {
} }
private void GetDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentGetState args)
{
args.State = new DeviceListComponentState(GetNetEntitySet(comp.Devices), comp.IsAllowList, comp.HandleIncomingPackets);
}
private void HandleDeviceListState(EntityUid uid, DeviceListComponent comp, ref ComponentHandleState args)
{
if (args.Current is not DeviceListComponentState state)
{
return;
}
comp.Devices = EnsureEntitySet<DeviceListComponent>(state.Devices, uid);
comp.HandleIncomingPackets = state.HandleIncomingPackets;
comp.IsAllowList = state.IsAllowList;
}
} }
public sealed class DeviceListUpdateEvent : EntityEventArgs public sealed class DeviceListUpdateEvent : EntityEventArgs

View File

@@ -1,37 +1,10 @@
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.DeviceNetwork.Components;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.DeviceNetwork.Systems; namespace Content.Shared.DeviceNetwork.Systems;
public abstract class SharedNetworkConfiguratorSystem : EntitySystem public abstract class SharedNetworkConfiguratorSystem : EntitySystem
{ {
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NetworkConfiguratorComponent, ComponentGetState>(GetNetworkConfiguratorState);
SubscribeLocalEvent<NetworkConfiguratorComponent, ComponentHandleState>(HandleNetworkConfiguratorState);
}
private void GetNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp,
ref ComponentGetState args)
{
args.State = new NetworkConfiguratorComponentState(GetNetEntity(comp.ActiveDeviceList), comp.LinkModeActive);
}
private void HandleNetworkConfiguratorState(EntityUid uid, NetworkConfiguratorComponent comp,
ref ComponentHandleState args)
{
if (args.Current is not NetworkConfiguratorComponentState state)
{
return;
}
comp.ActiveDeviceList = EnsureEntity<NetworkConfiguratorComponent>(state.ActiveDeviceList, uid);
comp.LinkModeActive = state.LinkModeActive;
}
} }
public sealed partial class ClearAllOverlaysEvent : InstantActionEvent public sealed partial class ClearAllOverlaysEvent : InstantActionEvent

View File

@@ -1,7 +1,6 @@
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Doors.Components; namespace Content.Shared.Doors.Components;
@@ -9,16 +8,17 @@ namespace Content.Shared.Doors.Components;
/// <summary> /// <summary>
/// Companion component to DoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing. /// Companion component to DoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAirlockSystem), Friend = AccessPermissions.ReadWriteExecute, Other = AccessPermissions.Read)] [Access(typeof(SharedAirlockSystem), Friend = AccessPermissions.ReadWriteExecute, Other = AccessPermissions.Read)]
public sealed partial class AirlockComponent : Component public sealed partial class AirlockComponent : Component
{ {
// Need to network airlock safety state to avoid mis-predicts when a door auto-closes as the client walks through the door.
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("safety")] [DataField, AutoNetworkedField]
public bool Safety = true; public bool Safety = true;
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("emergencyAccess")] [DataField]
public bool EmergencyAccess = false; public bool EmergencyAccess = false;
/// <summary> /// <summary>
@@ -26,20 +26,20 @@ public sealed partial class AirlockComponent : Component
/// Most anything that can pry powered has a pry speed bonus, /// Most anything that can pry powered has a pry speed bonus,
/// so this default is closer to 6 effectively on e.g. jaws (9 seconds when applied to other default.) /// so this default is closer to 6 effectively on e.g. jaws (9 seconds when applied to other default.)
/// </summary> /// </summary>
[DataField("poweredPryModifier")] [DataField]
public float PoweredPryModifier = 9f; public float PoweredPryModifier = 9f;
/// <summary> /// <summary>
/// Whether the maintenance panel should be visible even if the airlock is opened. /// Whether the maintenance panel should be visible even if the airlock is opened.
/// </summary> /// </summary>
[DataField("openPanelVisible")] [DataField]
public bool OpenPanelVisible = false; public bool OpenPanelVisible = false;
/// <summary> /// <summary>
/// Whether the airlock should stay open if the airlock was clicked. /// Whether the airlock should stay open if the airlock was clicked.
/// If the airlock was bumped into it will still auto close. /// If the airlock was bumped into it will still auto close.
/// </summary> /// </summary>
[DataField("keepOpenIfClicked")] [DataField]
public bool KeepOpenIfClicked = false; public bool KeepOpenIfClicked = false;
/// <summary> /// <summary>
@@ -51,7 +51,7 @@ public sealed partial class AirlockComponent : Component
/// <summary> /// <summary>
/// Delay until an open door automatically closes. /// Delay until an open door automatically closes.
/// </summary> /// </summary>
[DataField("autoCloseDelay")] [DataField]
public TimeSpan AutoCloseDelay = TimeSpan.FromSeconds(5f); public TimeSpan AutoCloseDelay = TimeSpan.FromSeconds(5f);
/// <summary> /// <summary>
@@ -64,7 +64,7 @@ public sealed partial class AirlockComponent : Component
/// <summary> /// <summary>
/// The receiver port for turning off automatic closing. /// The receiver port for turning off automatic closing.
/// </summary> /// </summary>
[DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))] [DataField(customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string AutoClosePort = "AutoClose"; public string AutoClosePort = "AutoClose";
#region Graphics #region Graphics
@@ -72,79 +72,68 @@ public sealed partial class AirlockComponent : Component
/// <summary> /// <summary>
/// Whether the door lights should be visible. /// Whether the door lights should be visible.
/// </summary> /// </summary>
[DataField("openUnlitVisible")] [DataField]
public bool OpenUnlitVisible = false; public bool OpenUnlitVisible = false;
/// <summary> /// <summary>
/// Whether the door should display emergency access lights. /// Whether the door should display emergency access lights.
/// </summary> /// </summary>
[DataField("emergencyAccessLayer")] [DataField]
public bool EmergencyAccessLayer = true; public bool EmergencyAccessLayer = true;
/// <summary> /// <summary>
/// Whether or not to animate the panel when the door opens or closes. /// Whether or not to animate the panel when the door opens or closes.
/// </summary> /// </summary>
[DataField("animatePanel")] [DataField]
public bool AnimatePanel = true; public bool AnimatePanel = true;
/// <summary> /// <summary>
/// The sprite state used to animate the airlock frame when the airlock opens. /// The sprite state used to animate the airlock frame when the airlock opens.
/// </summary> /// </summary>
[DataField("openingSpriteState")] [DataField]
public string OpeningSpriteState = "opening_unlit"; public string OpeningSpriteState = "opening_unlit";
/// <summary> /// <summary>
/// The sprite state used to animate the airlock panel when the airlock opens. /// The sprite state used to animate the airlock panel when the airlock opens.
/// </summary> /// </summary>
[DataField("openingPanelSpriteState")] [DataField]
public string OpeningPanelSpriteState = "panel_opening"; public string OpeningPanelSpriteState = "panel_opening";
/// <summary> /// <summary>
/// The sprite state used to animate the airlock frame when the airlock closes. /// The sprite state used to animate the airlock frame when the airlock closes.
/// </summary> /// </summary>
[DataField("closingSpriteState")] [DataField]
public string ClosingSpriteState = "closing_unlit"; public string ClosingSpriteState = "closing_unlit";
/// <summary> /// <summary>
/// The sprite state used to animate the airlock panel when the airlock closes. /// The sprite state used to animate the airlock panel when the airlock closes.
/// </summary> /// </summary>
[DataField("closingPanelSpriteState")] [DataField]
public string ClosingPanelSpriteState = "panel_closing"; public string ClosingPanelSpriteState = "panel_closing";
/// <summary> /// <summary>
/// The sprite state used for the open airlock lights. /// The sprite state used for the open airlock lights.
/// </summary> /// </summary>
[DataField("openSpriteState")] [DataField]
public string OpenSpriteState = "open_unlit"; public string OpenSpriteState = "open_unlit";
/// <summary> /// <summary>
/// The sprite state used for the closed airlock lights. /// The sprite state used for the closed airlock lights.
/// </summary> /// </summary>
[DataField("closedSpriteState")] [DataField]
public string ClosedSpriteState = "closed_unlit"; public string ClosedSpriteState = "closed_unlit";
/// <summary> /// <summary>
/// The sprite state used for the 'access denied' lights animation. /// The sprite state used for the 'access denied' lights animation.
/// </summary> /// </summary>
[DataField("denySpriteState")] [DataField]
public string DenySpriteState = "deny_unlit"; public string DenySpriteState = "deny_unlit";
/// <summary> /// <summary>
/// How long the animation played when the airlock denies access is in seconds. /// How long the animation played when the airlock denies access is in seconds.
/// </summary> /// </summary>
[DataField("denyAnimationTime")] [DataField]
public float DenyAnimationTime = 0.3f; public float DenyAnimationTime = 0.3f;
#endregion Graphics #endregion Graphics
} }
[Serializable, NetSerializable]
public sealed class AirlockComponentState : ComponentState
{
public readonly bool Safety;
public AirlockComponentState(bool safety)
{
Safety = safety;
}
}

View File

@@ -1,20 +1,18 @@
using System.Runtime.InteropServices;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Content.Shared.Tools; using Content.Shared.Tools;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth; using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
namespace Content.Shared.Doors.Components; namespace Content.Shared.Doors.Components;
[NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[RegisterComponent]
public sealed partial class DoorComponent : Component public sealed partial class DoorComponent : Component
{ {
/// <summary> /// <summary>
@@ -24,7 +22,7 @@ public sealed partial class DoorComponent : Component
/// This should never be set directly, use <see cref="SharedDoorSystem.SetState(EntityUid, DoorState, DoorComponent?)"/> instead. /// This should never be set directly, use <see cref="SharedDoorSystem.SetState(EntityUid, DoorState, DoorComponent?)"/> instead.
/// </remarks> /// </remarks>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("state")] [DataField, AutoNetworkedField]
[Access(typeof(SharedDoorSystem))] [Access(typeof(SharedDoorSystem))]
public DoorState State = DoorState.Closed; public DoorState State = DoorState.Closed;
@@ -35,46 +33,47 @@ public sealed partial class DoorComponent : Component
/// <summary> /// <summary>
/// Closing time until impassable. Total time is this plus <see cref="CloseTimeTwo"/>. /// Closing time until impassable. Total time is this plus <see cref="CloseTimeTwo"/>.
/// </summary> /// </summary>
[DataField("closeTimeOne")] [DataField]
public TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.4f); public TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.4f);
/// <summary> /// <summary>
/// Closing time until fully closed. Total time is this plus <see cref="CloseTimeOne"/>. /// Closing time until fully closed. Total time is this plus <see cref="CloseTimeOne"/>.
/// </summary> /// </summary>
[DataField("closeTimeTwo")] [DataField]
public TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.2f); public TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.2f);
/// <summary> /// <summary>
/// Opening time until passable. Total time is this plus <see cref="OpenTimeTwo"/>. /// Opening time until passable. Total time is this plus <see cref="OpenTimeTwo"/>.
/// </summary> /// </summary>
[DataField("openTimeOne")] [DataField]
public TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.4f); public TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.4f);
/// <summary> /// <summary>
/// Opening time until fully open. Total time is this plus <see cref="OpenTimeOne"/>. /// Opening time until fully open. Total time is this plus <see cref="OpenTimeOne"/>.
/// </summary> /// </summary>
[DataField("openTimeTwo")] [DataField]
public TimeSpan OpenTimeTwo = TimeSpan.FromSeconds(0.2f); public TimeSpan OpenTimeTwo = TimeSpan.FromSeconds(0.2f);
/// <summary> /// <summary>
/// Interval between deny sounds & visuals; /// Interval between deny sounds & visuals;
/// </summary> /// </summary>
[DataField("denyDuration")] [DataField]
public TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f); public TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f);
[DataField("emagDuration")] [DataField]
public TimeSpan EmagDuration = TimeSpan.FromSeconds(0.8f); public TimeSpan EmagDuration = TimeSpan.FromSeconds(0.8f);
/// <summary> /// <summary>
/// When the door is active, this is the time when the state will next update. /// When the door is active, this is the time when the state will next update.
/// </summary> /// </summary>
[AutoNetworkedField]
public TimeSpan? NextStateChange; public TimeSpan? NextStateChange;
/// <summary> /// <summary>
/// Whether the door is currently partially closed or open. I.e., when the door is "closing" and is already opaque, /// Whether the door is currently partially closed or open. I.e., when the door is "closing" and is already opaque,
/// but not yet actually closed. /// but not yet actually closed.
/// </summary> /// </summary>
[DataField("partial")] [DataField, AutoNetworkedField]
public bool Partial; public bool Partial;
#endregion #endregion
@@ -115,30 +114,30 @@ public sealed partial class DoorComponent : Component
/// This is how long a door-crush will stun you. This also determines how long it takes the door to open up /// This is how long a door-crush will stun you. This also determines how long it takes the door to open up
/// again. Total stun time is actually given by this plus <see cref="OpenTimeOne"/>. /// again. Total stun time is actually given by this plus <see cref="OpenTimeOne"/>.
/// </summary> /// </summary>
[DataField("doorStunTime")] [DataField]
public TimeSpan DoorStunTime = TimeSpan.FromSeconds(2f); public TimeSpan DoorStunTime = TimeSpan.FromSeconds(2f);
[DataField("crushDamage")] [DataField]
public DamageSpecifier? CrushDamage; public DamageSpecifier? CrushDamage;
/// <summary> /// <summary>
/// If false, this door is incapable of crushing entities. This just determines whether it will apply damage and /// If false, this door is incapable of crushing entities. This just determines whether it will apply damage and
/// stun, not whether it can close despite entities being in the way. /// stun, not whether it can close despite entities being in the way.
/// </summary> /// </summary>
[DataField("canCrush")] [DataField]
public bool CanCrush = true; public bool CanCrush = true;
/// <summary> /// <summary>
/// Whether to check for colliding entities before closing. This may be overridden by other system by subscribing to /// Whether to check for colliding entities before closing. This may be overridden by other system by subscribing to
/// <see cref="BeforeDoorClosedEvent"/>. For example, hacked airlocks will set this to false. /// <see cref="BeforeDoorClosedEvent"/>. For example, hacked airlocks will set this to false.
/// </summary> /// </summary>
[DataField("performCollisionCheck")] [DataField]
public bool PerformCollisionCheck = true; public bool PerformCollisionCheck = true;
/// <summary> /// <summary>
/// List of EntityUids of entities we're currently crushing. Cleared in OnPartialOpen(). /// List of EntityUids of entities we're currently crushing. Cleared in OnPartialOpen().
/// </summary> /// </summary>
[DataField("currentlyCrushing")] [DataField, AutoNetworkedField]
public HashSet<EntityUid> CurrentlyCrushing = new(); public HashSet<EntityUid> CurrentlyCrushing = new();
#endregion #endregion
@@ -152,7 +151,7 @@ public sealed partial class DoorComponent : Component
/// <summary> /// <summary>
/// The sprite state used for the door when it's open. /// The sprite state used for the door when it's open.
/// </summary> /// </summary>
[DataField("openSpriteState")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public string OpenSpriteState = "open"; public string OpenSpriteState = "open";
@@ -165,7 +164,7 @@ public sealed partial class DoorComponent : Component
/// <summary> /// <summary>
/// The sprite state used for the door when it's closed. /// The sprite state used for the door when it's closed.
/// </summary> /// </summary>
[DataField("closedSpriteState")] [DataField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public string ClosedSpriteState = "closed"; public string ClosedSpriteState = "closed";
@@ -178,37 +177,37 @@ public sealed partial class DoorComponent : Component
/// <summary> /// <summary>
/// The sprite state used for the door when it's opening. /// The sprite state used for the door when it's opening.
/// </summary> /// </summary>
[DataField("openingSpriteState")] [DataField]
public string OpeningSpriteState = "opening"; public string OpeningSpriteState = "opening";
/// <summary> /// <summary>
/// The sprite state used for the door when it's closing. /// The sprite state used for the door when it's closing.
/// </summary> /// </summary>
[DataField("closingSpriteState")] [DataField]
public string ClosingSpriteState = "closing"; public string ClosingSpriteState = "closing";
/// <summary> /// <summary>
/// The sprite state used for the door when it's being emagged. /// The sprite state used for the door when it's being emagged.
/// </summary> /// </summary>
[DataField("emaggingSpriteState")] [DataField]
public string EmaggingSpriteState = "emagging"; public string EmaggingSpriteState = "emagging";
/// <summary> /// <summary>
/// The sprite state used for the door when it's open. /// The sprite state used for the door when it's open.
/// </summary> /// </summary>
[DataField("openingAnimationTime")] [DataField]
public float OpeningAnimationTime = 0.8f; public float OpeningAnimationTime = 0.8f;
/// <summary> /// <summary>
/// The sprite state used for the door when it's open. /// The sprite state used for the door when it's open.
/// </summary> /// </summary>
[DataField("closingAnimationTime")] [DataField]
public float ClosingAnimationTime = 0.8f; public float ClosingAnimationTime = 0.8f;
/// <summary> /// <summary>
/// The sprite state used for the door when it's open. /// The sprite state used for the door when it's open.
/// </summary> /// </summary>
[DataField("emaggingAnimationTime")] [DataField]
public float EmaggingAnimationTime = 1.5f; public float EmaggingAnimationTime = 1.5f;
/// <summary> /// <summary>
@@ -237,7 +236,7 @@ public sealed partial class DoorComponent : Component
/// <summary> /// <summary>
/// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored. /// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored.
/// </summary> /// </summary>
[DataField("SecondsUntilStateChange")] [DataField]
private float? SecondsUntilStateChange private float? SecondsUntilStateChange
{ {
[UsedImplicitly] [UsedImplicitly]
@@ -262,46 +261,46 @@ public sealed partial class DoorComponent : Component
} }
#endregion #endregion
[DataField("canPry"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public bool CanPry = true; public bool CanPry = true;
[DataField("pryingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))] [DataField]
public string PryingQuality = "Prying"; public ProtoId<ToolQualityPrototype> PryingQuality = "Prying";
/// <summary> /// <summary>
/// Default time that the door should take to pry open. /// Default time that the door should take to pry open.
/// </summary> /// </summary>
[DataField("pryTime"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float PryTime = 1.5f; public float PryTime = 1.5f;
[DataField("changeAirtight")] [DataField]
public bool ChangeAirtight = true; public bool ChangeAirtight = true;
/// <summary> /// <summary>
/// Whether the door blocks light. /// Whether the door blocks light.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("occludes")] [DataField]
public bool Occludes = true; public bool Occludes = true;
/// <summary> /// <summary>
/// Whether the door will open when it is bumped into. /// Whether the door will open when it is bumped into.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("bumpOpen")] [DataField]
public bool BumpOpen = true; public bool BumpOpen = true;
/// <summary> /// <summary>
/// Whether the door will open when it is activated or clicked. /// Whether the door will open when it is activated or clicked.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("clickOpen")] [DataField]
public bool ClickOpen = true; public bool ClickOpen = true;
[DataField("openDrawDepth", customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))] [DataField(customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int OpenDrawDepth = (int) DrawDepth.DrawDepth.Doors; public int OpenDrawDepth = (int) DrawDepth.DrawDepth.Doors;
[DataField("closedDrawDepth", customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))] [DataField(customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int ClosedDrawDepth = (int) DrawDepth.DrawDepth.Doors; public int ClosedDrawDepth = (int) DrawDepth.DrawDepth.Doors;
} }
@@ -335,20 +334,3 @@ public enum DoorVisualLayers : byte
BaseBolted, BaseBolted,
BaseEmergencyAccess, BaseEmergencyAccess,
} }
[Serializable, NetSerializable]
public sealed class DoorComponentState : ComponentState
{
public readonly DoorState DoorState;
public readonly HashSet<NetEntity> CurrentlyCrushing;
public readonly TimeSpan? NextStateChange;
public readonly bool Partial;
public DoorComponentState(DoorComponent door, HashSet<NetEntity> currentlyCrushing)
{
DoorState = door.State;
CurrentlyCrushing = currentlyCrushing;
NextStateChange = door.NextStateChange;
Partial = door.Partial;
}
}

View File

@@ -1,6 +1,5 @@
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Shared.GameStates;
namespace Content.Shared.Doors.Systems; namespace Content.Shared.Doors.Systems;
@@ -14,32 +13,15 @@ public abstract class SharedAirlockSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<AirlockComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<AirlockComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<AirlockComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed); SubscribeLocalEvent<AirlockComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed);
} }
private void OnGetState(EntityUid uid, AirlockComponent airlock, ref ComponentGetState args)
{
// Need to network airlock safety state to avoid mis-predicts when a door auto-closes as the client walks through the door.
args.State = new AirlockComponentState(airlock.Safety);
}
private void OnHandleState(EntityUid uid, AirlockComponent airlock, ref ComponentHandleState args)
{
if (args.Current is not AirlockComponentState state)
return;
airlock.Safety = state.Safety;
}
protected virtual void OnBeforeDoorClosed(EntityUid uid, AirlockComponent airlock, BeforeDoorClosedEvent args) protected virtual void OnBeforeDoorClosed(EntityUid uid, AirlockComponent airlock, BeforeDoorClosedEvent args)
{ {
if (!airlock.Safety) if (!airlock.Safety)
args.PerformCollisionCheck = false; args.PerformCollisionCheck = false;
} }
public void UpdateEmergencyLightStatus(EntityUid uid, AirlockComponent component) public void UpdateEmergencyLightStatus(EntityUid uid, AirlockComponent component)
{ {
Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess); Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess);

View File

@@ -10,7 +10,6 @@ using Content.Shared.Physics;
using Content.Shared.Stunnable; using Content.Shared.Stunnable;
using Content.Shared.Tag; using Content.Shared.Tag;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Systems;
@@ -55,8 +54,7 @@ public abstract partial class SharedDoorSystem : EntitySystem
SubscribeLocalEvent<DoorComponent, ComponentInit>(OnComponentInit); SubscribeLocalEvent<DoorComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove); SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<DoorComponent, ComponentGetState>(OnGetState); SubscribeLocalEvent<DoorComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<DoorComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate); SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate);
@@ -102,29 +100,14 @@ public abstract partial class SharedDoorSystem : EntitySystem
} }
#region StateManagement #region StateManagement
private void OnGetState(EntityUid uid, DoorComponent door, ref ComponentGetState args) private void OnHandleState(EntityUid uid, DoorComponent door, ref AfterAutoHandleStateEvent args)
{ {
args.State = new DoorComponentState(door, GetNetEntitySet(door.CurrentlyCrushing)); if (door.NextStateChange == null)
}
private void OnHandleState(EntityUid uid, DoorComponent door, ref ComponentHandleState args)
{
if (args.Current is not DoorComponentState state)
return;
door.CurrentlyCrushing.Clear();
door.CurrentlyCrushing.UnionWith(EnsureEntitySet<DoorComponent>(state.CurrentlyCrushing, uid));
door.State = state.DoorState;
door.NextStateChange = state.NextStateChange;
door.Partial = state.Partial;
if (state.NextStateChange == null)
_activeDoors.Remove(door); _activeDoors.Remove(door);
else else
_activeDoors.Add(door); _activeDoors.Add(door);
RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State), false); RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State));
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State); AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
} }

View File

@@ -1,29 +1,17 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Electrocution namespace Content.Shared.Electrocution
{ {
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedElectrocutionSystem))] [Access(typeof(SharedElectrocutionSystem))]
[RegisterComponent, NetworkedComponent]
public sealed partial class InsulatedComponent : Component public sealed partial class InsulatedComponent : Component
{ {
// Technically, people could cheat and figure out which budget insulated gloves are gud and which ones are bad.
// We might want to rethink this a little bit.
/// <summary> /// <summary>
/// Siemens coefficient. Zero means completely insulated. /// Siemens coefficient. Zero means completely insulated.
/// </summary> /// </summary>
[DataField("coefficient")] [DataField, AutoNetworkedField]
public float SiemensCoefficient { get; set; } = 0f; public float Coefficient { get; set; } = 0f;
}
// Technically, people could cheat and figure out which budget insulated gloves are gud and which ones are bad.
// We might want to rethink this a little bit.
[NetSerializable, Serializable]
public sealed class InsulatedComponentState : ComponentState
{
public float SiemensCoefficient { get; private set; }
public InsulatedComponentState(float siemensCoefficient)
{
SiemensCoefficient = siemensCoefficient;
}
} }
} }

View File

@@ -1,6 +1,5 @@
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Robust.Shared.GameStates;
namespace Content.Shared.Electrocution namespace Content.Shared.Electrocution
{ {
@@ -13,8 +12,6 @@ namespace Content.Shared.Electrocution
SubscribeLocalEvent<InsulatedComponent, ElectrocutionAttemptEvent>(OnInsulatedElectrocutionAttempt); SubscribeLocalEvent<InsulatedComponent, ElectrocutionAttemptEvent>(OnInsulatedElectrocutionAttempt);
// as long as legally distinct electric-mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer). // as long as legally distinct electric-mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer).
SubscribeLocalEvent<InsulatedComponent, InventoryRelayedEvent<ElectrocutionAttemptEvent>>((e, c, ev) => OnInsulatedElectrocutionAttempt(e, c, ev.Args)); SubscribeLocalEvent<InsulatedComponent, InventoryRelayedEvent<ElectrocutionAttemptEvent>>((e, c, ev) => OnInsulatedElectrocutionAttempt(e, c, ev.Args));
SubscribeLocalEvent<InsulatedComponent, ComponentGetState>(OnInsulatedGetState);
SubscribeLocalEvent<InsulatedComponent, ComponentHandleState>(OnInsulatedHandleState);
} }
public void SetInsulatedSiemensCoefficient(EntityUid uid, float siemensCoefficient, InsulatedComponent? insulated = null) public void SetInsulatedSiemensCoefficient(EntityUid uid, float siemensCoefficient, InsulatedComponent? insulated = null)
@@ -22,7 +19,7 @@ namespace Content.Shared.Electrocution
if (!Resolve(uid, ref insulated)) if (!Resolve(uid, ref insulated))
return; return;
insulated.SiemensCoefficient = siemensCoefficient; insulated.Coefficient = siemensCoefficient;
Dirty(insulated); Dirty(insulated);
} }
@@ -45,21 +42,7 @@ namespace Content.Shared.Electrocution
private void OnInsulatedElectrocutionAttempt(EntityUid uid, InsulatedComponent insulated, ElectrocutionAttemptEvent args) private void OnInsulatedElectrocutionAttempt(EntityUid uid, InsulatedComponent insulated, ElectrocutionAttemptEvent args)
{ {
args.SiemensCoefficient *= insulated.SiemensCoefficient; args.SiemensCoefficient *= insulated.Coefficient;
} }
private void OnInsulatedGetState(EntityUid uid, InsulatedComponent insulated, ref ComponentGetState args)
{
args.State = new InsulatedComponentState(insulated.SiemensCoefficient);
}
private void OnInsulatedHandleState(EntityUid uid, InsulatedComponent insulated, ref ComponentHandleState args)
{
if (args.Current is not InsulatedComponentState state)
return;
insulated.SiemensCoefficient = state.SiemensCoefficient;
}
} }
} }

View File

@@ -1,8 +1,5 @@
using Robust.Shared.GameStates; namespace Content.Shared.Emoting;
using Robust.Shared.Serialization;
namespace Content.Shared.Emoting
{
public sealed class EmoteSystem : EntitySystem public sealed class EmoteSystem : EntitySystem
{ {
public override void Initialize() public override void Initialize()
@@ -10,8 +7,6 @@ namespace Content.Shared.Emoting
base.Initialize(); base.Initialize();
SubscribeLocalEvent<EmoteAttemptEvent>(OnEmoteAttempt); SubscribeLocalEvent<EmoteAttemptEvent>(OnEmoteAttempt);
SubscribeLocalEvent<EmotingComponent, ComponentGetState>(OnEmotingGetState);
SubscribeLocalEvent<EmotingComponent, ComponentHandleState>(OnEmotingHandleState);
} }
public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null) public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null)
@@ -27,34 +22,9 @@ namespace Content.Shared.Emoting
Dirty(component); Dirty(component);
} }
private void OnEmotingHandleState(EntityUid uid, EmotingComponent component, ref ComponentHandleState args)
{
if (args.Current is not EmotingComponentState state)
return;
component.Enabled = state.Enabled;
}
private void OnEmotingGetState(EntityUid uid, EmotingComponent component, ref ComponentGetState args)
{
args.State = new EmotingComponentState(component.Enabled);
}
private void OnEmoteAttempt(EmoteAttemptEvent args) private void OnEmoteAttempt(EmoteAttemptEvent args)
{ {
if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled) if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled)
args.Cancel(); args.Cancel();
} }
[Serializable, NetSerializable]
private sealed class EmotingComponentState : ComponentState
{
public bool Enabled { get; }
public EmotingComponentState(bool enabled)
{
Enabled = enabled;
}
}
}
} }

View File

@@ -1,12 +1,11 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
namespace Content.Shared.Emoting namespace Content.Shared.Emoting;
{
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class EmotingComponent : Component public sealed partial class EmotingComponent : Component
{ {
[DataField("enabled"), Access(typeof(EmoteSystem), [DataField, AutoNetworkedField]
Friend = AccessPermissions.ReadWrite, [Access(typeof(EmoteSystem), Friend = AccessPermissions.ReadWrite, Other = AccessPermissions.Read)]
Other = AccessPermissions.Read)] public bool Enabled = true; public bool Enabled = true;
}
} }

View File

@@ -6,10 +6,10 @@ namespace Content.Shared.Follower.Components;
/// <summary> /// <summary>
/// Attached to entities that are currently being followed by a ghost. /// Attached to entities that are currently being followed by a ghost.
/// </summary> /// </summary>
[RegisterComponent, Access(typeof(FollowerSystem))] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[NetworkedComponent] [Access(typeof(FollowerSystem))]
public sealed partial class FollowedComponent : Component public sealed partial class FollowedComponent : Component
{ {
[DataField("following")] [DataField, AutoNetworkedField]
public HashSet<EntityUid> Following = new(); public HashSet<EntityUid> Following = new();
} }

View File

@@ -8,14 +8,12 @@ using Content.Shared.Physics.Pull;
using Content.Shared.Tag; using Content.Shared.Tag;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Events; using Robust.Shared.Map.Events;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Utility;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization; using Robust.Shared.Utility;
namespace Content.Shared.Follower; namespace Content.Shared.Follower;
@@ -38,25 +36,6 @@ public sealed class FollowerSystem : EntitySystem
SubscribeLocalEvent<FollowerComponent, GotEquippedHandEvent>(OnGotEquippedHand); SubscribeLocalEvent<FollowerComponent, GotEquippedHandEvent>(OnGotEquippedHand);
SubscribeLocalEvent<FollowedComponent, EntityTerminatingEvent>(OnFollowedTerminating); SubscribeLocalEvent<FollowedComponent, EntityTerminatingEvent>(OnFollowedTerminating);
SubscribeLocalEvent<BeforeSaveEvent>(OnBeforeSave); SubscribeLocalEvent<BeforeSaveEvent>(OnBeforeSave);
SubscribeLocalEvent<FollowedComponent, ComponentGetState>(OnFollowedGetState);
SubscribeLocalEvent<FollowedComponent, ComponentHandleState>(OnFollowedHandleState);
}
private void OnFollowedGetState(EntityUid uid, FollowedComponent component, ref ComponentGetState args)
{
args.State = new FollowedComponentState()
{
Following = GetNetEntitySet(component.Following),
};
}
private void OnFollowedHandleState(EntityUid uid, FollowedComponent component, ref ComponentHandleState args)
{
if (args.Current is not FollowedComponentState state)
return;
component.Following = EnsureEntitySet<FollowedComponent>(state.Following, uid);
} }
private void OnBeforeSave(BeforeSaveEvent ev) private void OnBeforeSave(BeforeSaveEvent ev)
@@ -242,12 +221,6 @@ public sealed class FollowerSystem : EntitySystem
StopFollowingEntity(player, uid, followed); StopFollowingEntity(player, uid, followed);
} }
} }
[Serializable, NetSerializable]
private sealed class FollowedComponentState : ComponentState
{
public HashSet<NetEntity> Following = new();
}
} }
public abstract class FollowEvent : EntityEventArgs public abstract class FollowEvent : EntityEventArgs

View File

@@ -1,10 +1,9 @@
using System.Numerics; using System.Numerics;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Gravity; namespace Content.Shared.Gravity;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedFloatingVisualizerSystem))] [Access(typeof(SharedFloatingVisualizerSystem))]
public sealed partial class FloatingVisualsComponent : Component public sealed partial class FloatingVisualsComponent : Component
{ {
@@ -12,33 +11,19 @@ public sealed partial class FloatingVisualsComponent : Component
/// How long it takes to go from the bottom of the animation to the top. /// How long it takes to go from the bottom of the animation to the top.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("animationTime")] [DataField, AutoNetworkedField]
public float AnimationTime = 2f; public float AnimationTime = 2f;
/// <summary> /// <summary>
/// How far it goes in any direction. /// How far it goes in any direction.
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("offset")] [DataField, AutoNetworkedField]
public Vector2 Offset = new(0, 0.2f); public Vector2 Offset = new(0, 0.2f);
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public bool CanFloat = false; public bool CanFloat = false;
public readonly string AnimationKey = "gravity"; public readonly string AnimationKey = "gravity";
} }
[Serializable, NetSerializable]
public sealed class SharedFloatingVisualsComponentState : ComponentState
{
public float AnimationTime;
public Vector2 Offset;
public bool HasGravity;
public SharedFloatingVisualsComponentState(float animationTime, Vector2 offset, bool hasGravity)
{
AnimationTime = animationTime;
Offset = offset;
HasGravity = hasGravity;
}
}

View File

@@ -6,12 +6,12 @@ namespace Content.Shared.Gravity;
/// <summary> /// <summary>
/// Indicates this entity is shaking due to gravity changes. /// Indicates this entity is shaking due to gravity changes.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class GravityShakeComponent : Component public sealed partial class GravityShakeComponent : Component
{ {
[ViewVariables(VVAccess.ReadWrite), DataField("shakeTimes")] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public int ShakeTimes; public int ShakeTimes;
[DataField("nextShake", customTypeSerializer:typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
public TimeSpan NextShake; public TimeSpan NextShake;
} }

View File

@@ -1,5 +1,4 @@
using System.Numerics; using System.Numerics;
using Robust.Shared.GameStates;
using Robust.Shared.Map; using Robust.Shared.Map;
namespace Content.Shared.Gravity; namespace Content.Shared.Gravity;
@@ -18,8 +17,6 @@ public abstract class SharedFloatingVisualizerSystem : EntitySystem
SubscribeLocalEvent<FloatingVisualsComponent, ComponentStartup>(OnComponentStartup); SubscribeLocalEvent<FloatingVisualsComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<GravityChangedEvent>(OnGravityChanged); SubscribeLocalEvent<GravityChangedEvent>(OnGravityChanged);
SubscribeLocalEvent<FloatingVisualsComponent, EntParentChangedMessage>(OnEntParentChanged); SubscribeLocalEvent<FloatingVisualsComponent, EntParentChangedMessage>(OnEntParentChanged);
SubscribeLocalEvent<FloatingVisualsComponent, ComponentGetState>(OnComponentGetState);
SubscribeLocalEvent<FloatingVisualsComponent, ComponentHandleState>(OnComponentHandleState);
} }
/// <summary> /// <summary>
@@ -71,19 +68,4 @@ public abstract class SharedFloatingVisualizerSystem : EntitySystem
if (CanFloat(uid, component, transform)) if (CanFloat(uid, component, transform))
FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime); FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime);
} }
private void OnComponentGetState(EntityUid uid, FloatingVisualsComponent component, ref ComponentGetState args)
{
args.State = new SharedFloatingVisualsComponentState(component.AnimationTime, component.Offset, component.CanFloat);
}
private void OnComponentHandleState(EntityUid uid, FloatingVisualsComponent component, ref ComponentHandleState args)
{
if (args.Current is not SharedFloatingVisualsComponentState state)
return;
component.AnimationTime = state.AnimationTime;
component.Offset = state.Offset;
component.CanFloat = state.HasGravity;
}
} }

View File

@@ -1,6 +1,3 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Gravity; namespace Content.Shared.Gravity;
public abstract partial class SharedGravitySystem public abstract partial class SharedGravitySystem
@@ -11,8 +8,6 @@ public abstract partial class SharedGravitySystem
private void InitializeShake() private void InitializeShake()
{ {
SubscribeLocalEvent<GravityShakeComponent, EntityUnpausedEvent>(OnShakeUnpaused); SubscribeLocalEvent<GravityShakeComponent, EntityUnpausedEvent>(OnShakeUnpaused);
SubscribeLocalEvent<GravityShakeComponent, ComponentGetState>(OnShakeGetState);
SubscribeLocalEvent<GravityShakeComponent, ComponentHandleState>(OnShakeHandleState);
} }
private void OnShakeUnpaused(EntityUid uid, GravityShakeComponent component, ref EntityUnpausedEvent args) private void OnShakeUnpaused(EntityUid uid, GravityShakeComponent component, ref EntityUnpausedEvent args)
@@ -63,29 +58,4 @@ public abstract partial class SharedGravitySystem
} }
protected virtual void ShakeGrid(EntityUid uid, GravityComponent? comp = null) {} protected virtual void ShakeGrid(EntityUid uid, GravityComponent? comp = null) {}
private void OnShakeHandleState(EntityUid uid, GravityShakeComponent component, ref ComponentHandleState args)
{
if (args.Current is not GravityShakeComponentState state)
return;
component.ShakeTimes = state.ShakeTimes;
component.NextShake = state.NextShake;
}
private void OnShakeGetState(EntityUid uid, GravityShakeComponent component, ref ComponentGetState args)
{
args.State = new GravityShakeComponentState()
{
ShakeTimes = component.ShakeTimes,
NextShake = component.NextShake,
};
}
[Serializable, NetSerializable]
protected sealed class GravityShakeComponentState : ComponentState
{
public int ShakeTimes;
public TimeSpan NextShake;
}
} }

View File

@@ -4,31 +4,31 @@ using Robust.Shared.Enums;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid; namespace Content.Shared.Humanoid;
[NetworkedComponent, RegisterComponent] [NetworkedComponent, RegisterComponent, AutoGenerateComponentState(true)]
public sealed partial class HumanoidAppearanceComponent : Component public sealed partial class HumanoidAppearanceComponent : Component
{ {
[DataField("markingSet")] public MarkingSet ClientOldMarkings = new();
[DataField]
public MarkingSet MarkingSet = new(); public MarkingSet MarkingSet = new();
[DataField("baseLayers")] [DataField]
public Dictionary<HumanoidVisualLayers, HumanoidSpeciesSpriteLayer> BaseLayers = new(); public Dictionary<HumanoidVisualLayers, HumanoidSpeciesSpriteLayer> BaseLayers = new();
[DataField("permanentlyHidden")] [DataField, AutoNetworkedField(true)]
public HashSet<HumanoidVisualLayers> PermanentlyHidden = new(); public HashSet<HumanoidVisualLayers> PermanentlyHidden = new();
// Couldn't these be somewhere else? // Couldn't these be somewhere else?
[DataField("gender")] [DataField, AutoNetworkedField]
[ViewVariables] public Gender Gender = default!; public Gender Gender;
[DataField("age")] [DataField, AutoNetworkedField]
[ViewVariables] public int Age = 18; public int Age = 18;
/// <summary> /// <summary>
/// Any custom base layers this humanoid might have. See: /// Any custom base layers this humanoid might have. See:
@@ -36,39 +36,39 @@ public sealed partial class HumanoidAppearanceComponent : Component
/// Stored on the server, this is merged in the client into /// Stored on the server, this is merged in the client into
/// all layer settings. /// all layer settings.
/// </summary> /// </summary>
[DataField("customBaseLayers")] [DataField, AutoNetworkedField(true)]
public Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> CustomBaseLayers = new(); public Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> CustomBaseLayers = new();
/// <summary> /// <summary>
/// Current species. Dictates things like base body sprites, /// Current species. Dictates things like base body sprites,
/// base humanoid to spawn, etc. /// base humanoid to spawn, etc.
/// </summary> /// </summary>
[DataField("species", customTypeSerializer: typeof(PrototypeIdSerializer<SpeciesPrototype>), required: true)] [DataField(required: true), AutoNetworkedField]
public string Species { get; set; } = default!; public ProtoId<SpeciesPrototype> Species { get; set; }
/// <summary> /// <summary>
/// The initial profile and base layers to apply to this humanoid. /// The initial profile and base layers to apply to this humanoid.
/// </summary> /// </summary>
[DataField("initial", customTypeSerializer: typeof(PrototypeIdSerializer<HumanoidProfilePrototype>))] [DataField]
public string? Initial { get; private set; } public ProtoId<HumanoidProfilePrototype>? Initial { get; private set; }
/// <summary> /// <summary>
/// Skin color of this humanoid. /// Skin color of this humanoid.
/// </summary> /// </summary>
[DataField("skinColor")] [DataField, AutoNetworkedField]
public Color SkinColor { get; set; } = Color.FromHex("#C0967F"); public Color SkinColor { get; set; } = Color.FromHex("#C0967F");
/// <summary> /// <summary>
/// Visual layers currently hidden. This will affect the base sprite /// Visual layers currently hidden. This will affect the base sprite
/// on this humanoid layer, and any markings that sit above it. /// on this humanoid layer, and any markings that sit above it.
/// </summary> /// </summary>
[DataField("hiddenLayers")] [DataField, AutoNetworkedField(true)]
public HashSet<HumanoidVisualLayers> HiddenLayers = new(); public HashSet<HumanoidVisualLayers> HiddenLayers = new();
[DataField("sex")] [DataField, AutoNetworkedField]
public Sex Sex = Sex.Male; public Sex Sex = Sex.Male;
[DataField("eyeColor")] [DataField, AutoNetworkedField]
public Color EyeColor = Color.Brown; public Color EyeColor = Color.Brown;
/// <summary> /// <summary>
@@ -84,44 +84,6 @@ public sealed partial class HumanoidAppearanceComponent : Component
public Color? CachedFacialHairColor; public Color? CachedFacialHairColor;
} }
[Serializable, NetSerializable]
public sealed partial class HumanoidAppearanceState : ComponentState
{
public readonly MarkingSet Markings;
public readonly HashSet<HumanoidVisualLayers> PermanentlyHidden;
public readonly HashSet<HumanoidVisualLayers> HiddenLayers;
public readonly Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> CustomBaseLayers;
public readonly Sex Sex;
public readonly Gender Gender;
public readonly int Age = 18;
public readonly string Species;
public readonly Color SkinColor;
public readonly Color EyeColor;
public HumanoidAppearanceState(
MarkingSet currentMarkings,
HashSet<HumanoidVisualLayers> permanentlyHidden,
HashSet<HumanoidVisualLayers> hiddenLayers,
Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> customBaseLayers,
Sex sex,
Gender gender,
int age,
string species,
Color skinColor,
Color eyeColor)
{
Markings = currentMarkings;
PermanentlyHidden = permanentlyHidden;
HiddenLayers = hiddenLayers;
CustomBaseLayers = customBaseLayers;
Sex = sex;
Gender = gender;
Age = age;
Species = species;
SkinColor = skinColor;
EyeColor = eyeColor;
}
[DataDefinition] [DataDefinition]
[Serializable, NetSerializable] [Serializable, NetSerializable]
public readonly partial struct CustomBaseLayerInfo public readonly partial struct CustomBaseLayerInfo
@@ -129,20 +91,19 @@ public sealed partial class HumanoidAppearanceState : ComponentState
public CustomBaseLayerInfo(string? id, Color? color = null) public CustomBaseLayerInfo(string? id, Color? color = null)
{ {
DebugTools.Assert(id == null || IoCManager.Resolve<IPrototypeManager>().HasIndex<HumanoidSpeciesSpriteLayer>(id)); DebugTools.Assert(id == null || IoCManager.Resolve<IPrototypeManager>().HasIndex<HumanoidSpeciesSpriteLayer>(id));
ID = id; Id = id;
Color = color; Color = color;
} }
/// <summary> /// <summary>
/// ID of this custom base layer. Must be a <see cref="HumanoidSpeciesSpriteLayer"/>. /// ID of this custom base layer. Must be a <see cref="HumanoidSpeciesSpriteLayer"/>.
/// </summary> /// </summary>
[DataField("id", customTypeSerializer: typeof(PrototypeIdSerializer<HumanoidSpeciesSpriteLayer>))] [DataField]
public string? ID { init; get; } public ProtoId<HumanoidSpeciesSpriteLayer>? Id { get; init; }
/// <summary> /// <summary>
/// Color of this custom base layer. Null implies skin colour if the corresponding <see cref="HumanoidSpeciesSpriteLayer"/> is set to match skin. /// Color of this custom base layer. Null implies skin colour if the corresponding <see cref="HumanoidSpeciesSpriteLayer"/> is set to match skin.
/// </summary> /// </summary>
[DataField("color")] [DataField]
public Color? Color { init; get; } public Color? Color { get; init; }
}
} }

View File

@@ -1,6 +1,5 @@
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid.Prototypes; namespace Content.Shared.Humanoid.Prototypes;

View File

@@ -1,11 +1,10 @@
using System.Linq;
using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes; using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using System.Linq;
using Content.Shared.Preferences; using Content.Shared.Preferences;
using Robust.Shared.GameObjects.Components.Localization; using Robust.Shared.GameObjects.Components.Localization;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Prototypes;
namespace Content.Shared.Humanoid; namespace Content.Shared.Humanoid;
@@ -31,7 +30,6 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentInit>(OnInit); SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentGetState>(OnGetState);
} }
private void OnInit(EntityUid uid, HumanoidAppearanceComponent humanoid, ComponentInit args) private void OnInit(EntityUid uid, HumanoidAppearanceComponent humanoid, ComponentInit args)
@@ -57,20 +55,6 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
LoadProfile(uid, startingSet.Profile, humanoid); LoadProfile(uid, startingSet.Profile, humanoid);
} }
private void OnGetState(EntityUid uid, HumanoidAppearanceComponent component, ref ComponentGetState args)
{
args.State = new HumanoidAppearanceState(component.MarkingSet,
component.PermanentlyHidden,
component.HiddenLayers,
component.CustomBaseLayers,
component.Sex,
component.Gender,
component.Age,
component.Species,
component.SkinColor,
component.EyeColor);
}
/// <summary> /// <summary>
/// Toggles a humanoid's sprite layer visibility. /// Toggles a humanoid's sprite layer visibility.
/// </summary> /// </summary>
@@ -211,7 +195,7 @@ public abstract class SharedHumanoidAppearanceSystem : EntitySystem
return; return;
if (humanoid.CustomBaseLayers.TryGetValue(layer, out var info)) if (humanoid.CustomBaseLayers.TryGetValue(layer, out var info))
humanoid.CustomBaseLayers[layer] = info with { ID = id }; humanoid.CustomBaseLayers[layer] = info with { Id = id };
else else
humanoid.CustomBaseLayers[layer] = new(id); humanoid.CustomBaseLayers[layer] = new(id);

View File

@@ -1,6 +1,5 @@
using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Markings;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid; namespace Content.Shared.Humanoid;

View File

@@ -1,10 +1,7 @@
using System.Threading; using Content.Shared.Containers.ItemSlots;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Implants.Components; namespace Content.Shared.Implants.Components;
/// <summary> /// <summary>
@@ -12,7 +9,7 @@ namespace Content.Shared.Implants.Components;
/// Some can be single use (implant only) or some can draw out an implant /// Some can be single use (implant only) or some can draw out an implant
/// </summary> /// </summary>
//TODO: Rework drawing to work with implant cases when surgery is in //TODO: Rework drawing to work with implant cases when surgery is in
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class ImplanterComponent : Component public sealed partial class ImplanterComponent : Component
{ {
public const string ImplanterSlotId = "implanter_slot"; public const string ImplanterSlotId = "implanter_slot";
@@ -21,15 +18,14 @@ public sealed partial class ImplanterComponent : Component
/// <summary> /// <summary>
/// Used for implanters that start with specific implants /// Used for implanters that start with specific implants
/// </summary> /// </summary>
[ViewVariables] [DataField]
[DataField("implant", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))] public EntProtoId? Implant;
public string? Implant;
/// <summary> /// <summary>
/// The time it takes to implant someone else /// The time it takes to implant someone else
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("implantTime")] [DataField]
public float ImplantTime = 5f; public float ImplantTime = 5f;
//TODO: Remove when surgery is a thing //TODO: Remove when surgery is a thing
@@ -38,54 +34,37 @@ public sealed partial class ImplanterComponent : Component
/// It's excessively long to deter from implant checking any antag /// It's excessively long to deter from implant checking any antag
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
[DataField("drawTime")] [DataField]
public float DrawTime = 60f; public float DrawTime = 60f;
/// <summary> /// <summary>
/// Good for single-use injectors /// Good for single-use injectors
/// </summary> /// </summary>
[ViewVariables] [DataField, AutoNetworkedField]
[DataField("implantOnly")] public bool ImplantOnly;
public bool ImplantOnly = false;
/// <summary> /// <summary>
/// The current mode of the implanter /// The current mode of the implanter
/// Mode is changed automatically depending if it implants or draws /// Mode is changed automatically depending if it implants or draws
/// </summary> /// </summary>
[ViewVariables] [DataField, AutoNetworkedField]
[DataField("currentMode")]
public ImplanterToggleMode CurrentMode; public ImplanterToggleMode CurrentMode;
/// <summary> /// <summary>
/// The name and description of the implant to show on the implanter /// The name and description of the implant to show on the implanter
/// </summary> /// </summary>
[ViewVariables] [DataField]
[DataField("implantData")]
public (string, string) ImplantData; public (string, string) ImplantData;
/// <summary> /// <summary>
/// The <see cref="ItemSlot"/> for this implanter /// The <see cref="ItemSlot"/> for this implanter
/// </summary> /// </summary>
[ViewVariables] [DataField(required: true)]
[DataField("implanterSlot", required:true)]
public ItemSlot ImplanterSlot = new(); public ItemSlot ImplanterSlot = new();
public bool UiUpdateNeeded; public bool UiUpdateNeeded;
} }
[Serializable, NetSerializable]
public sealed class ImplanterComponentState : ComponentState
{
public ImplanterToggleMode CurrentMode;
public bool ImplantOnly;
public ImplanterComponentState(ImplanterToggleMode currentMode, bool implantOnly)
{
CurrentMode = currentMode;
ImplantOnly = implantOnly;
}
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
public enum ImplanterToggleMode : byte public enum ImplanterToggleMode : byte
{ {

View File

@@ -1,5 +1,4 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Interaction.Components; namespace Content.Shared.Interaction.Components;
@@ -10,27 +9,13 @@ namespace Content.Shared.Interaction.Components;
/// ///
/// Note that extreme caution should be taken when using this, as this will probably bypass many normal can-interact checks. /// Note that extreme caution should be taken when using this, as this will probably bypass many normal can-interact checks.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedInteractionSystem))] [Access(typeof(SharedInteractionSystem))]
public sealed partial class InteractionRelayComponent : Component public sealed partial class InteractionRelayComponent : Component
{ {
/// <summary> /// <summary>
/// The entity the interactions are being relayed to. /// The entity the interactions are being relayed to.
/// </summary> /// </summary>
[ViewVariables] [ViewVariables, AutoNetworkedField]
public EntityUid? RelayEntity; public EntityUid? RelayEntity;
} }
/// <summary>
/// Contains network state for <see cref="InteractionRelayComponent"/>
/// </summary>
[Serializable, NetSerializable]
public sealed class InteractionRelayComponentState : ComponentState
{
public NetEntity? RelayEntity;
public InteractionRelayComponentState(NetEntity? relayEntity)
{
RelayEntity = relayEntity;
}
}

View File

@@ -1,35 +1,15 @@
using Content.Shared.Interaction.Components; using Content.Shared.Interaction.Components;
using Robust.Shared.GameStates;
namespace Content.Shared.Interaction; namespace Content.Shared.Interaction;
public abstract partial class SharedInteractionSystem public abstract partial class SharedInteractionSystem
{ {
public void InitializeRelay()
{
SubscribeLocalEvent<InteractionRelayComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<InteractionRelayComponent, ComponentHandleState>(OnHandleState);
}
private void OnGetState(EntityUid uid, InteractionRelayComponent component, ref ComponentGetState args)
{
args.State = new InteractionRelayComponentState(GetNetEntity(component.RelayEntity));
}
private void OnHandleState(EntityUid uid, InteractionRelayComponent component, ref ComponentHandleState args)
{
if (args.Current is not InteractionRelayComponentState state)
return;
component.RelayEntity = EnsureEntity<InteractionRelayComponent>(state.RelayEntity, uid);
}
public void SetRelay(EntityUid uid, EntityUid? relayEntity, InteractionRelayComponent? component = null) public void SetRelay(EntityUid uid, EntityUid? relayEntity, InteractionRelayComponent? component = null)
{ {
if (!Resolve(uid, ref component)) if (!Resolve(uid, ref component))
return; return;
component.RelayEntity = relayEntity; component.RelayEntity = relayEntity;
Dirty(component); Dirty(uid, component);
} }
} }

View File

@@ -1,4 +1,3 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
@@ -7,7 +6,6 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Administration.Managers; using Content.Shared.Administration.Managers;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Ghost;
using Content.Shared.Hands; using Content.Shared.Hands;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Input; using Content.Shared.Input;
@@ -28,7 +26,6 @@ using Content.Shared.Verbs;
using Content.Shared.Wall; using Content.Shared.Wall;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Input; using Robust.Shared.Input;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -99,7 +96,6 @@ namespace Content.Shared.Interaction
new PointerInputCmdHandler(HandleTryPullObject)) new PointerInputCmdHandler(HandleTryPullObject))
.Register<SharedInteractionSystem>(); .Register<SharedInteractionSystem>();
InitializeRelay();
InitializeBlocking(); InitializeBlocking();
} }

View File

@@ -1,33 +1,20 @@
using System.Numerics; using System.Numerics;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Jittering namespace Content.Shared.Jittering;
{
[Access(typeof(SharedJitteringSystem))] [Access(typeof(SharedJitteringSystem))]
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class JitteringComponent : Component public sealed partial class JitteringComponent : Component
{ {
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float Amplitude { get; set; } public float Amplitude { get; set; }
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float Frequency { get; set; } public float Frequency { get; set; }
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public Vector2 LastJitter { get; set; } public Vector2 LastJitter { get; set; }
} }
[Serializable, NetSerializable]
public sealed class JitteringComponentState : ComponentState
{
public float Amplitude { get; }
public float Frequency { get; }
public JitteringComponentState(float amplitude, float frequency)
{
Amplitude = amplitude;
Frequency = frequency;
}
}
}

View File

@@ -1,6 +1,5 @@
using Content.Shared.Rejuvenate; using Content.Shared.Rejuvenate;
using Content.Shared.StatusEffect; using Content.Shared.StatusEffect;
using Robust.Shared.GameStates;
using Robust.Shared.Timing; using Robust.Shared.Timing;
namespace Content.Shared.Jittering namespace Content.Shared.Jittering
@@ -21,25 +20,9 @@ namespace Content.Shared.Jittering
public override void Initialize() public override void Initialize()
{ {
SubscribeLocalEvent<JitteringComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<JitteringComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<JitteringComponent, RejuvenateEvent>(OnRejuvenate); SubscribeLocalEvent<JitteringComponent, RejuvenateEvent>(OnRejuvenate);
} }
private void OnGetState(EntityUid uid, JitteringComponent component, ref ComponentGetState args)
{
args.State = new JitteringComponentState(component.Amplitude, component.Frequency);
}
private void OnHandleState(EntityUid uid, JitteringComponent component, ref ComponentHandleState args)
{
if (args.Current is not JitteringComponentState jitteringState)
return;
component.Amplitude = jitteringState.Amplitude;
component.Frequency = jitteringState.Frequency;
}
private void OnRejuvenate(EntityUid uid, JitteringComponent component, RejuvenateEvent args) private void OnRejuvenate(EntityUid uid, JitteringComponent component, RejuvenateEvent args)
{ {
EntityManager.RemoveComponentDeferred<JitteringComponent>(uid); EntityManager.RemoveComponentDeferred<JitteringComponent>(uid);

View File

@@ -2,42 +2,42 @@ using Content.Shared.Construction.Prototypes;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Lathe namespace Content.Shared.Lathe
{ {
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class LatheComponent : Component public sealed partial class LatheComponent : Component
{ {
/// <summary> /// <summary>
/// All of the recipes that the lathe has by default /// All of the recipes that the lathe has by default
/// </summary> /// </summary>
[DataField("staticRecipes", customTypeSerializer: typeof(PrototypeIdListSerializer<LatheRecipePrototype>))] [DataField]
public List<string> StaticRecipes = new(); public List<ProtoId<LatheRecipePrototype>> StaticRecipes = new();
/// <summary> /// <summary>
/// All of the recipes that the lathe is capable of researching /// All of the recipes that the lathe is capable of researching
/// </summary> /// </summary>
[DataField("dynamicRecipes", customTypeSerializer: typeof(PrototypeIdListSerializer<LatheRecipePrototype>))] [DataField]
public List<string> DynamicRecipes = new(); public List<ProtoId<LatheRecipePrototype>> DynamicRecipes = new();
/// <summary> /// <summary>
/// The lathe's construction queue /// The lathe's construction queue
/// </summary> /// </summary>
[DataField("queue")] [DataField]
public List<LatheRecipePrototype> Queue = new(); public List<LatheRecipePrototype> Queue = new();
/// <summary> /// <summary>
/// The sound that plays when the lathe is producing an item, if any /// The sound that plays when the lathe is producing an item, if any
/// </summary> /// </summary>
[DataField("producingSound")] [DataField]
public SoundSpecifier? ProducingSound; public SoundSpecifier? ProducingSound;
#region Visualizer info #region Visualizer info
[DataField("idleState", required: true)] [DataField(required: true)]
public string IdleState = default!; public string IdleState = default!;
[DataField("runningState", required: true)] [DataField(required: true)]
public string RunningState = default!; public string RunningState = default!;
#endregion #endregion
@@ -50,7 +50,7 @@ namespace Content.Shared.Lathe
/// <summary> /// <summary>
/// Whether the lathe can eject the materials stored within it /// Whether the lathe can eject the materials stored within it
/// </summary> /// </summary>
[DataField("canEjectStoredMaterials")] [DataField]
public bool CanEjectStoredMaterials = true; public bool CanEjectStoredMaterials = true;
#region MachineUpgrading #region MachineUpgrading
@@ -63,31 +63,31 @@ namespace Content.Shared.Lathe
/// <summary> /// <summary>
/// The machine part that reduces how long it takes to print a recipe. /// The machine part that reduces how long it takes to print a recipe.
/// </summary> /// </summary>
[DataField("machinePartPrintSpeed", customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))] [DataField]
public string MachinePartPrintTime = "Manipulator"; public ProtoId<MachinePartPrototype> MachinePartPrintSpeed = "Manipulator";
/// <summary> /// <summary>
/// The value that is used to calculate the modified <see cref="TimeMultiplier"/> /// The value that is used to calculate the modified <see cref="TimeMultiplier"/>
/// </summary> /// </summary>
[DataField("partRatingPrintTimeMultiplier")] [DataField]
public float PartRatingPrintTimeMultiplier = 0.5f; public float PartRatingPrintTimeMultiplier = 0.5f;
/// <summary> /// <summary>
/// A modifier that changes how much of a material is needed to print a recipe /// A modifier that changes how much of a material is needed to print a recipe
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float MaterialUseMultiplier = 1; public float MaterialUseMultiplier = 1;
/// <summary> /// <summary>
/// The machine part that reduces how much material it takes to print a recipe. /// The machine part that reduces how much material it takes to print a recipe.
/// </summary> /// </summary>
[DataField("machinePartMaterialUse", customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>))] [DataField]
public string MachinePartMaterialUse = "MatterBin"; public ProtoId<MachinePartPrototype> MachinePartMaterialUse = "MatterBin";
/// <summary> /// <summary>
/// The value that is used to calculate the modifier <see cref="MaterialUseMultiplier"/> /// The value that is used to calculate the modifier <see cref="MaterialUseMultiplier"/>
/// </summary> /// </summary>
[DataField("partRatingMaterialUseMultiplier")] [DataField]
public float PartRatingMaterialUseMultiplier = DefaultPartRatingMaterialUseMultiplier; public float PartRatingMaterialUseMultiplier = DefaultPartRatingMaterialUseMultiplier;
public const float DefaultPartRatingMaterialUseMultiplier = 0.85f; public const float DefaultPartRatingMaterialUseMultiplier = 0.85f;
@@ -98,7 +98,7 @@ namespace Content.Shared.Lathe
{ {
public readonly EntityUid Lathe; public readonly EntityUid Lathe;
public List<string> Recipes = new(); public List<ProtoId<LatheRecipePrototype>> Recipes = new();
public LatheGetRecipesEvent(EntityUid lathe) public LatheGetRecipesEvent(EntityUid lathe)
{ {

View File

@@ -1,4 +1,5 @@
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Lathe; namespace Content.Shared.Lathe;
@@ -6,13 +7,13 @@ namespace Content.Shared.Lathe;
[Serializable, NetSerializable] [Serializable, NetSerializable]
public sealed class LatheUpdateState : BoundUserInterfaceState public sealed class LatheUpdateState : BoundUserInterfaceState
{ {
public List<string> Recipes; public List<ProtoId<LatheRecipePrototype>> Recipes;
public List<LatheRecipePrototype> Queue; public List<LatheRecipePrototype> Queue;
public LatheRecipePrototype? CurrentlyProducing; public LatheRecipePrototype? CurrentlyProducing;
public LatheUpdateState(List<string> recipes, List<LatheRecipePrototype> queue, LatheRecipePrototype? currentlyProducing = null) public LatheUpdateState(List<ProtoId<LatheRecipePrototype>> recipes, List<LatheRecipePrototype> queue, LatheRecipePrototype? currentlyProducing = null)
{ {
Recipes = recipes; Recipes = recipes;
Queue = queue; Queue = queue;

View File

@@ -2,10 +2,7 @@ using Content.Shared.Emag.Systems;
using Content.Shared.Materials; using Content.Shared.Materials;
using Content.Shared.Research.Prototypes; using Content.Shared.Research.Prototypes;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using System.Net.Mail;
namespace Content.Shared.Lathe; namespace Content.Shared.Lathe;
@@ -21,23 +18,9 @@ public abstract class SharedLatheSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<LatheComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<LatheComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<EmagLatheRecipesComponent, GotEmaggedEvent>(OnEmagged); SubscribeLocalEvent<EmagLatheRecipesComponent, GotEmaggedEvent>(OnEmagged);
} }
private void OnGetState(EntityUid uid, LatheComponent component, ref ComponentGetState args)
{
args.State = new LatheComponentState(component.MaterialUseMultiplier);
}
private void OnHandleState(EntityUid uid, LatheComponent component, ref ComponentHandleState args)
{
if (args.Current is not LatheComponentState state)
return;
component.MaterialUseMultiplier = state.MaterialUseMultiplier;
}
[PublicAPI] [PublicAPI]
public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null) public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null)
{ {
@@ -71,14 +54,3 @@ public abstract class SharedLatheSystem : EntitySystem
protected abstract bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component); protected abstract bool HasRecipe(EntityUid uid, LatheRecipePrototype recipe, LatheComponent component);
} }
[Serializable, NetSerializable]
public sealed class LatheComponentState : ComponentState
{
public float MaterialUseMultiplier;
public LatheComponentState(float materialUseMultiplier)
{
MaterialUseMultiplier = materialUseMultiplier;
}
}

View File

@@ -1,31 +1,18 @@
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Materials; namespace Content.Shared.Materials;
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class InsertingMaterialStorageComponent : Component public sealed partial class InsertingMaterialStorageComponent : Component
{ {
/// <summary> /// <summary>
/// The time when insertion ends. /// The time when insertion ends.
/// </summary> /// </summary>
[DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan EndTime; public TimeSpan EndTime;
[ViewVariables] [ViewVariables, AutoNetworkedField]
public Color? MaterialColor; public Color? MaterialColor;
} }
[Serializable, NetSerializable]
public sealed class InsertingMaterialStorageComponentState : ComponentState
{
public TimeSpan EndTime;
public Color? MaterialColor;
public InsertingMaterialStorageComponentState(TimeSpan endTime, Color? materialColor)
{
EndTime = endTime;
MaterialColor = materialColor;
}
}

View File

@@ -3,9 +3,9 @@ using Content.Shared.Construction.Prototypes;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Materials; namespace Content.Shared.Materials;
@@ -13,27 +13,28 @@ namespace Content.Shared.Materials;
/// This is a machine that handles converting entities /// This is a machine that handles converting entities
/// into the raw materials and chemicals that make them up. /// into the raw materials and chemicals that make them up.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedMaterialReclaimerSystem))] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedMaterialReclaimerSystem))]
public sealed partial class MaterialReclaimerComponent : Component public sealed partial class MaterialReclaimerComponent : Component
{ {
/// <summary> /// <summary>
/// Whether or not the machine has power. We put it here /// Whether or not the machine has power. We put it here
/// so we can network and predict it. /// so we can network and predict it.
/// </summary> /// </summary>
[DataField("powered"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public bool Powered; public bool Powered;
/// <summary> /// <summary>
/// An "enable" toggle for things like interfacing with machine linking /// An "enable" toggle for things like interfacing with machine linking
/// </summary> /// </summary>
[DataField("enabled"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public bool Enabled = true; public bool Enabled = true;
/// <summary> /// <summary>
/// How efficiently the materials are reclaimed. /// How efficiently the materials are reclaimed.
/// In practice, a multiplier per material when calculating the output of the reclaimer. /// In practice, a multiplier per material when calculating the output of the reclaimer.
/// </summary> /// </summary>
[DataField("efficiency"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float Efficiency = 1f; public float Efficiency = 1f;
/// <summary> /// <summary>
@@ -41,46 +42,46 @@ public sealed partial class MaterialReclaimerComponent : Component
/// speed scales with the amount of materials being processed /// speed scales with the amount of materials being processed
/// or if it's just <see cref="MinimumProcessDuration"/> /// or if it's just <see cref="MinimumProcessDuration"/>
/// </summary> /// </summary>
[DataField("scaleProcessSpeed")] [DataField]
public bool ScaleProcessSpeed = true; public bool ScaleProcessSpeed = true;
/// <summary> /// <summary>
/// How quickly it takes to consume X amount of materials per second. /// How quickly it takes to consume X amount of materials per second.
/// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process. /// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process.
/// </summary> /// </summary>
[DataField("baseMaterialProcessRate"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float BaseMaterialProcessRate = 100f; public float BaseMaterialProcessRate = 100f;
/// <summary> /// <summary>
/// How quickly it takes to consume X amount of materials per second. /// How quickly it takes to consume X amount of materials per second.
/// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process. /// For example, with a rate of 50, an entity with 100 total material takes 2 seconds to process.
/// </summary> /// </summary>
[DataField("materialProcessRate"), ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public float MaterialProcessRate = 100f; public float MaterialProcessRate = 100f;
/// <summary> /// <summary>
/// Machine part whose rating modifies <see cref="MaterialProcessRate"/> /// Machine part whose rating modifies <see cref="MaterialProcessRate"/>
/// </summary> /// </summary>
[DataField("machinePartProcessRate", customTypeSerializer: typeof(PrototypeIdSerializer<MachinePartPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public string MachinePartProcessRate = "Manipulator"; public ProtoId<MachinePartPrototype> MachinePartProcessRate = "Manipulator";
/// <summary> /// <summary>
/// How much the machine part quality affects the <see cref="MaterialProcessRate"/> /// How much the machine part quality affects the <see cref="MaterialProcessRate"/>
/// </summary> /// </summary>
[DataField("partRatingProcessRateMultiplier"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public float PartRatingProcessRateMultiplier = 1.5f; public float PartRatingProcessRateMultiplier = 1.5f;
/// <summary> /// <summary>
/// The minimum amount fo time it can take to process an entity. /// The minimum amount fo time it can take to process an entity.
/// this value supercedes the calculated one using <see cref="MaterialProcessRate"/> /// this value supercedes the calculated one using <see cref="MaterialProcessRate"/>
/// </summary> /// </summary>
[DataField("minimumProcessDuration"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public TimeSpan MinimumProcessDuration = TimeSpan.FromSeconds(0.5f); public TimeSpan MinimumProcessDuration = TimeSpan.FromSeconds(0.5f);
/// <summary> /// <summary>
/// The id of our output solution /// The id of our output solution
/// </summary> /// </summary>
[DataField("solutionContainerId"), ViewVariables(VVAccess.ReadWrite)] [DataField, ViewVariables(VVAccess.ReadWrite)]
public string SolutionContainerId = "output"; public string SolutionContainerId = "output";
/// <summary> /// <summary>
@@ -92,37 +93,37 @@ public sealed partial class MaterialReclaimerComponent : Component
/// <summary> /// <summary>
/// a whitelist for what entities can be inserted into this reclaimer /// a whitelist for what entities can be inserted into this reclaimer
/// </summary> /// </summary>
[DataField("whitelist")] [DataField]
public EntityWhitelist? Whitelist; public EntityWhitelist? Whitelist;
/// <summary> /// <summary>
/// a blacklist for what entities cannot be inserted into this reclaimer /// a blacklist for what entities cannot be inserted into this reclaimer
/// </summary> /// </summary>
[DataField("blacklist")] [DataField]
public EntityWhitelist? Blacklist; public EntityWhitelist? Blacklist;
/// <summary> /// <summary>
/// The sound played when something is being processed. /// The sound played when something is being processed.
/// </summary> /// </summary>
[DataField("sound")] [DataField]
public SoundSpecifier? Sound; public SoundSpecifier? Sound;
/// <summary> /// <summary>
/// whether or not we cut off the sound early when the reclaiming ends. /// whether or not we cut off the sound early when the reclaiming ends.
/// </summary> /// </summary>
[DataField("cutOffSound")] [DataField]
public bool CutOffSound = true; public bool CutOffSound = true;
/// <summary> /// <summary>
/// When the next sound will be allowed to be played. Used to prevent spam. /// When the next sound will be allowed to be played. Used to prevent spam.
/// </summary> /// </summary>
[DataField("nextSound", customTypeSerializer: typeof(TimeOffsetSerializer))] [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextSound; public TimeSpan NextSound;
/// <summary> /// <summary>
/// Minimum time inbetween each <see cref="Sound"/> /// Minimum time inbetween each <see cref="Sound"/>
/// </summary> /// </summary>
[DataField("soundCooldown")] [DataField]
public TimeSpan SoundCooldown = TimeSpan.FromSeconds(0.8f); public TimeSpan SoundCooldown = TimeSpan.FromSeconds(0.8f);
public IPlayingAudioStream? Stream; public IPlayingAudioStream? Stream;
@@ -133,30 +134,10 @@ public sealed partial class MaterialReclaimerComponent : Component
/// <remarks> /// <remarks>
/// I saw this on the recycler and i'm porting it because it's cute af /// I saw this on the recycler and i'm porting it because it's cute af
/// </remarks> /// </remarks>
[DataField("itemsProcessed")] [DataField, AutoNetworkedField]
public int ItemsProcessed; public int ItemsProcessed;
} }
[Serializable, NetSerializable]
public sealed class MaterialReclaimerComponentState : ComponentState
{
public bool Powered;
public bool Enabled;
public float MaterialProcessRate;
public int ItemsProcessed;
public MaterialReclaimerComponentState(bool powered, bool enabled, float materialProcessRate, int itemsProcessed)
{
Powered = powered;
Enabled = enabled;
MaterialProcessRate = materialProcessRate;
ItemsProcessed = itemsProcessed;
}
}
[NetSerializable, Serializable] [NetSerializable, Serializable]
public enum RecyclerVisuals public enum RecyclerVisuals
{ {

Some files were not shown because too many files have changed in this diff Show More