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.Systems;
using Content.Shared.Containers.ItemSlots;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.AccessOverriderComponent;
@@ -23,7 +23,7 @@ namespace Content.Client.Access.UI
{
base.Open();
List<string> accessLevels;
List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<AccessOverriderComponent>(Owner, out var accessOverrider))
{
@@ -33,7 +33,7 @@ namespace Content.Client.Access.UI
else
{
accessLevels = new List<string>();
accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_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();
public AccessOverriderWindow(AccessOverriderBoundUserInterface owner, IPrototypeManager prototypeManager,
List<string> accessLevels)
List<ProtoId<AccessLevelPrototype>> accessLevels)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
@@ -31,7 +31,7 @@ namespace Content.Client.Access.UI
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}");
continue;

View File

@@ -1,8 +1,8 @@
using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.CrewManifest;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.IdCardConsoleComponent;
@@ -23,7 +23,7 @@ namespace Content.Client.Access.UI
protected override void Open()
{
base.Open();
List<string> accessLevels;
List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<IdCardConsoleComponent>(Owner, out var idCard))
{
@@ -32,7 +32,7 @@ namespace Content.Client.Access.UI
}
else
{
accessLevels = new List<string>();
accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_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;
public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager,
List<string> accessLevels)
List<ProtoId<AccessLevelPrototype>> accessLevels)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

View File

@@ -1,10 +1,8 @@
using System.Linq;
using Content.Shared.Alert;
using Content.Shared.Mobs.Systems;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Client.Alerts;
@@ -27,7 +25,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, ComponentHandleState>(ClientAlertsHandleState);
SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
}
protected override void LoadPrototypes()
{
@@ -65,16 +63,10 @@ public sealed class ClientAlertsSystem : AlertsSystem
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)
SyncAlerts?.Invoke(this, componentAlerts);
SyncAlerts?.Invoke(this, component.Alerts);
}
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args)

View File

@@ -1,7 +1,6 @@
using Content.Shared.BarSign;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Client.BarSign;
@@ -13,33 +12,29 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
public override void 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)
return;
component.CurrentSign = state.CurrentSign;
UpdateAppearance(component);
UpdateAppearance(uid, component);
}
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;
AppearanceSystem.TryGetData<bool>(sign.Owner, PowerDeviceVisuals.Powered, out var powered, appearance);
AppearanceSystem.TryGetData<bool>(id, PowerDeviceVisuals.Powered, out var powered, appearance);
if (powered
&& sign.CurrentSign != null
&& _prototypeManager.TryIndex(sign.CurrentSign, out BarSignPrototype? proto))
&& sign.Current != null
&& _prototypeManager.TryIndex(sign.Current, out BarSignPrototype? proto))
{
sprite.LayerSetState(0, proto.Icon);
sprite.LayerSetShader(0, "unshaded");

View File

@@ -3,7 +3,6 @@ using Content.Shared.Buckle;
using Content.Shared.Buckle.Components;
using Content.Shared.Vehicle.Components;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
namespace Content.Client.Buckle;
@@ -15,20 +14,12 @@ internal sealed class BuckleSystem : SharedBuckleSystem
{
base.Initialize();
SubscribeLocalEvent<BuckleComponent, ComponentHandleState>(OnBuckleHandleState);
SubscribeLocalEvent<BuckleComponent, AfterAutoHandleStateEvent>(OnBuckleAfterAutoHandleState);
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);
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.Inventory;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Client.Clothing.Systems;
@@ -27,7 +26,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ChameleonClothingComponent, ComponentHandleState>(HandleState);
SubscribeLocalEvent<ChameleonClothingComponent, AfterAutoHandleStateEvent>(HandleState);
PrepareAllVariants();
_proto.PrototypesReloaded += OnProtoReloaded;
@@ -44,12 +43,8 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
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);
}

View File

@@ -17,15 +17,6 @@ public sealed class CuffableSystem : SharedCuffableSystem
SubscribeLocalEvent<CuffableComponent, ComponentShutdown>(OnCuffableShutdown);
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)

View File

@@ -1,14 +1,10 @@
using System.Linq;
using Content.Shared.Ghost;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid;
@@ -21,34 +17,20 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
{
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)
return;
ApplyState(uid, component, Comp<SpriteComponent>(uid), state);
UpdateSprite(component, Comp<SpriteComponent>(uid));
}
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);
ApplyMarkingSet(component, sprite);
ApplyMarkingSet(uid, state.Markings, component, sprite);
sprite[sprite.LayerMapReserveBlank(HumanoidVisualLayers.Eyes)].Color = state.EyeColor;
sprite[sprite.LayerMapReserveBlank(HumanoidVisualLayers.Eyes)].Color = component.EyeColor;
}
private static bool IsHidden(HumanoidAppearanceComponent humanoid, HumanoidVisualLayers layer)
@@ -60,7 +42,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
component.BaseLayers.Clear();
// add default species layers
var speciesProto = _prototypeManager.Index<SpeciesPrototype>(component.Species);
var speciesProto = _prototypeManager.Index(component.Species);
var baseSprites = _prototypeManager.Index<HumanoidSpeciesBaseSpritesPrototype>(speciesProto.SpriteSet);
foreach (var (key, id) in baseSprites.Sprites)
{
@@ -73,7 +55,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
foreach (var (key, info) in component.CustomBaseLayers)
{
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
@@ -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
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,
new[] { hairColor });
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,
new[] { facialHairColor });
@@ -200,69 +184,60 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
DebugTools.Assert(IsClientSide(uid));
var state = new HumanoidAppearanceState(markings,
new(),
new(),
customBaseLayers,
profile.Sex,
profile.Gender,
profile.Age,
profile.Species,
profile.Appearance.SkinColor,
profile.Appearance.EyeColor);
humanoid.MarkingSet = markings;
humanoid.PermanentlyHidden = new HashSet<HumanoidVisualLayers>();
humanoid.HiddenLayers = new HashSet<HumanoidVisualLayers>();
humanoid.CustomBaseLayers = customBaseLayers;
humanoid.Sex = profile.Sex;
humanoid.Gender = profile.Gender;
humanoid.Age = profile.Age;
humanoid.Species = profile.Species;
humanoid.SkinColor = profile.Appearance.SkinColor;
humanoid.EyeColor = profile.Appearance.EyeColor;
ApplyState(uid, humanoid, Comp<SpriteComponent>(uid), state);
UpdateSprite(humanoid, Comp<SpriteComponent>(uid));
}
private void ApplyMarkingSet(EntityUid uid,
MarkingSet newMarkings,
HumanoidAppearanceComponent humanoid,
SpriteComponent sprite)
private void ApplyMarkingSet(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.
// Really, markings should probably be a separate component altogether.
ClearAllMarkings(uid, humanoid, sprite);
humanoid.MarkingSet = new(newMarkings);
ClearAllMarkings(humanoid, sprite);
foreach (var markingList in humanoid.MarkingSet.Markings.Values)
{
foreach (var marking in markingList)
{
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,
SpriteComponent sprite)
humanoid.ClientOldMarkings = new MarkingSet(humanoid.MarkingSet);
}
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 marking in markingList)
{
RemoveMarking(uid, marking, sprite);
RemoveMarking(marking, sprite);
}
}
}
private void ClearMarkings(EntityUid uid, List<Marking> markings, HumanoidAppearanceComponent humanoid,
SpriteComponent spriteComp)
{
foreach (var marking in markings)
{
RemoveMarking(uid, marking, spriteComp);
}
}
private void RemoveMarking(EntityUid uid, Marking marking,
SpriteComponent spriteComp)
private void RemoveMarking(Marking marking, SpriteComponent spriteComp)
{
if (!_markingManager.TryGetMarking(marking, out var prototype))
{
@@ -286,8 +261,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
spriteComp.RemoveLayer(index);
}
}
private void ApplyMarking(EntityUid uid,
MarkingPrototype markingPrototype,
private void ApplyMarking(MarkingPrototype markingPrototype,
IReadOnlyList<Color>? colors,
bool visible,
HumanoidAppearanceComponent humanoid,
@@ -393,7 +367,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
foreach (var marking in markingList)
{
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.Markings;
using Robust.Client.GameObjects;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid;

View File

@@ -6,7 +6,6 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid;
@@ -76,7 +75,7 @@ public sealed partial class HumanoidMarkingModifierWindow : DefaultWindow
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;

View File

@@ -2,7 +2,6 @@
using Content.Client.Items;
using Content.Shared.Implants;
using Content.Shared.Implants.Components;
using Robust.Shared.GameStates;
namespace Content.Client.Implants;
@@ -12,17 +11,12 @@ public sealed class ImplanterSystem : SharedImplanterSystem
{
base.Initialize();
SubscribeLocalEvent<ImplanterComponent, ComponentHandleState>(OnHandleImplanterState);
SubscribeLocalEvent<ImplanterComponent, AfterAutoHandleStateEvent>(OnHandleImplanterState);
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;
}

View File

@@ -1,6 +1,5 @@
using System.Linq;
using System.Text;
using Content.Shared.FixedPoint;
using Content.Shared.Lathe;
using Content.Shared.Materials;
using Content.Shared.Research.Prototypes;
@@ -24,7 +23,7 @@ public sealed partial class LatheMenu : DefaultWindow
public event Action<BaseButton.ButtonEventArgs>? OnServerListButtonPressed;
public event Action<string, int>? RecipeQueueAction;
public event Action<string, int>? OnEjectPressed;
public List<string> Recipes = new();
public List<ProtoId<LatheRecipePrototype>> Recipes = new();
/// <summary>
/// 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>();
foreach (var recipe in Recipes)
{
if (!_prototypeManager.TryIndex<LatheRecipePrototype>(recipe, out var proto))
if (!_prototypeManager.TryIndex(recipe, out var proto))
continue;
if (SearchBar.Text.Trim().Length != 0)

View File

@@ -1,7 +1,6 @@
using Content.Client.Interactable;
using Content.Shared.Climbing;
using Content.Shared.DragDrop;
using Robust.Shared.GameStates;
namespace Content.Client.Movement.Systems;
@@ -12,19 +11,9 @@ public sealed class ClimbSystem : SharedClimbSystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ClimbingComponent, ComponentHandleState>(OnClimbingState);
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)
{
base.OnCanDragDropOn(uid, component, ref args);

View File

@@ -3,7 +3,6 @@ using Content.Client.Message;
using Content.Shared.Points;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameStates;
namespace Content.Client.Points;
@@ -17,17 +16,12 @@ public sealed class PointSystem : SharedPointSystem
{
base.Initialize();
SubscribeLocalEvent<PointManagerComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<PointManagerComponent, AfterAutoHandleStateEvent>(OnHandleState);
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();
}

View File

@@ -2,10 +2,6 @@ using Content.Client.Items;
using Content.Client.Radiation.UI;
using Content.Shared.Radiation.Components;
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;
@@ -14,19 +10,12 @@ public sealed class GeigerSystem : SharedGeigerSystem
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GeigerComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<GeigerComponent, AfterAutoHandleStateEvent>(OnHandleState);
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;
}

View File

@@ -11,7 +11,6 @@ using Robust.Client.Input;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameStates;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
@@ -49,7 +48,6 @@ namespace Content.Client.Tabletop
.Register<TabletopSystem>();
SubscribeNetworkEvent<TabletopPlayEvent>(OnTabletopPlay);
SubscribeLocalEvent<TabletopDraggableComponent, ComponentHandleState>(HandleComponentState);
SubscribeLocalEvent<TabletopDraggableComponent, ComponentRemove>(HandleDraggableRemoved);
SubscribeLocalEvent<TabletopDraggableComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
@@ -148,13 +146,6 @@ namespace Content.Client.Tabletop
_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()
{
if (_table != null)

View File

@@ -39,7 +39,7 @@ public sealed partial class GunSystem
else if (component.UnspawnedCount > 0)
{
component.UnspawnedCount--;
ent = Spawn(component.FillProto, coordinates);
ent = Spawn(component.Proto, coordinates);
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.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using System.Linq;
using static Content.Shared.Access.Components.AccessOverriderComponent;
using Content.Server.Popups;
using Content.Shared.DoAfter;
namespace Content.Server.Access.Systems;
@@ -46,7 +46,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
if (!_interactionSystem.InRangeUnobstructed(args.User, (EntityUid) args.Target))
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,
BreakOnUserMove = true,

View File

@@ -1,6 +1,5 @@
using System.Linq;
using Content.Shared.BarSign;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -15,17 +14,11 @@ namespace Content.Server.BarSign.Systems
public override void Initialize()
{
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)
{
if (component.CurrentSign != null)
if (component.Current != null)
return;
var prototypes = _prototypeManager
@@ -40,7 +33,7 @@ namespace Content.Server.BarSign.Systems
_metaData.SetEntityName(uid, Loc.GetString(name), meta);
_metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta);
component.CurrentSign = newPrototype.ID;
component.Current = newPrototype.ID;
Dirty(component);
}
}

View File

@@ -21,7 +21,6 @@ using Content.Shared.Popups;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
@@ -62,7 +61,6 @@ public sealed class ClimbSystem : SharedClimbSystem
SubscribeLocalEvent<ClimbingComponent, ClimbDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<ClimbingComponent, EndCollideEvent>(OnClimbEndCollide);
SubscribeLocalEvent<ClimbingComponent, BuckleChangeEvent>(OnBuckleChange);
SubscribeLocalEvent<ClimbingComponent, ComponentGetState>(OnClimbingGetState);
SubscribeLocalEvent<GlassTableComponent, ClimbedOnEvent>(OnGlassClimbed);
}
@@ -366,11 +364,6 @@ public sealed class ClimbSystem : SharedClimbSystem
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)
{
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.Verbs;
using Robust.Server.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
@@ -22,22 +21,13 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
{
base.Initialize();
SubscribeLocalEvent<ChameleonClothingComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ChameleonClothingComponent, ComponentGetState>(GetState);
SubscribeLocalEvent<ChameleonClothingComponent, GetVerbsEvent<InteractionVerb>>(OnVerb);
SubscribeLocalEvent<ChameleonClothingComponent, ChameleonPrototypeSelectedMessage>(OnSelected);
}
private void OnMapInit(EntityUid uid, ChameleonClothingComponent component, MapInitEvent args)
{
SetSelectedPrototype(uid, component.SelectedId, true, component);
}
private void GetState(EntityUid uid, ChameleonClothingComponent component, ref ComponentGetState args)
{
args.State = new ChameleonClothingComponentState
{
SelectedId = component.SelectedId
};
SetSelectedPrototype(uid, component.Default, true, component);
}
private void OnVerb(EntityUid uid, ChameleonClothingComponent component, GetVerbsEvent<InteractionVerb> args)
@@ -72,7 +62,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
if (!Resolve(uid, ref component))
return;
var state = new ChameleonBoundUserInterfaceState(component.Slot, component.SelectedId);
var state = new ChameleonBoundUserInterfaceState(component.Slot, component.Default);
_uiSystem.TrySetUiState(uid, ChameleonUiKey.Key, state);
}
@@ -87,7 +77,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
// check that wasn't already selected
// forceUpdate on component init ignores this check
if (component.SelectedId == protoId && !forceUpdate)
if (component.Default == protoId && !forceUpdate)
return;
// make sure that it is valid change
@@ -95,7 +85,7 @@ public sealed class ChameleonClothingSystem : SharedChameleonClothingSystem
return;
if (!IsValidTarget(proto, component.Slot))
return;
component.SelectedId = protoId;
component.Default = protoId;
UpdateIdentityBlocker(uid, component, proto);
UpdateVisuals(uid, component);

View File

@@ -1,6 +1,6 @@
using Content.Shared.Cuffs;
using JetBrains.Annotations;
using Content.Shared.Cuffs.Components;
using JetBrains.Annotations;
using Robust.Shared.GameStates;
namespace Content.Server.Cuffs
@@ -12,15 +12,9 @@ namespace Content.Server.Cuffs
{
base.Initialize();
SubscribeLocalEvent<HandcuffComponent, ComponentGetState>(OnHandcuffGetState);
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)
{
// 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,
component.CanStillInteract,
cuffs?.CuffedRSI,
$"{cuffs?.OverlayIconState}-{component.CuffedHandCount}",
$"{cuffs?.BodyIconState}-{component.CuffedHandCount}",
cuffs?.Color);
// the iconstate is formatted as blah-2, blah-4, blah-6, etc.
// the number corresponds to how many hands are cuffed.

View File

@@ -1,22 +1,19 @@
using Content.Server.Access;
using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Power.EntitySystems;
using Content.Shared.Database;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Emag.Systems;
using Content.Shared.Interaction;
using Content.Shared.Prying.Components;
using Content.Shared.Prying.Systems;
using Content.Shared.Tools.Systems;
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.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;
@@ -25,8 +22,6 @@ public sealed class DoorSystem : SharedDoorSystem
[Dependency] private readonly IAdminLogManager _adminLog = default!;
[Dependency] private readonly DoorBoltSystem _bolts = 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!;
public override void Initialize()

View File

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

View File

@@ -8,7 +8,6 @@ using Content.Shared.Interaction;
using Content.Shared.Mobs.Components;
using Content.Shared.Popups;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Server.Implants;
@@ -24,7 +23,6 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem
InitializeImplanted();
SubscribeLocalEvent<ImplanterComponent, AfterInteractEvent>(OnImplanterAfterInteract);
SubscribeLocalEvent<ImplanterComponent, ComponentGetState>(OnImplanterGetState);
SubscribeLocalEvent<ImplanterComponent, ImplantEvent>(OnImplant);
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)
{
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)
return;
var materialWhitelist = new List<string>();
var materialWhitelist = new List<ProtoId<MaterialPrototype>>();
var recipes = GetAllBaseRecipes(component);
foreach (var id in recipes)
{
if (!_proto.TryIndex<LatheRecipePrototype>(id, out var proto))
if (!_proto.TryIndex(id, out var proto))
continue;
foreach (var (mat, _) in proto.RequiredMaterials)
{
@@ -127,7 +127,7 @@ namespace Content.Server.Lathe
}
[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;
if (!Resolve(uid, ref component))
@@ -136,17 +136,17 @@ namespace Content.Server.Lathe
return true;
}
public List<string> GetAvailableRecipes(EntityUid uid, LatheComponent component)
public List<ProtoId<LatheRecipePrototype>> GetAvailableRecipes(EntityUid uid, LatheComponent component)
{
var ev = new LatheGetRecipesEvent(uid)
{
Recipes = new List<string>(component.StaticRecipes)
Recipes = new List<ProtoId<LatheRecipePrototype>>(component.StaticRecipes)
};
RaiseLocalEvent(uid, ev);
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();
}
@@ -300,7 +300,7 @@ namespace Content.Server.Lathe
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];
component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1);

View File

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

View File

@@ -5,8 +5,6 @@ using Content.Shared.Interaction;
using Content.Shared.Inventory.Events;
using Content.Shared.Radiation.Components;
using Content.Shared.Radiation.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@@ -32,7 +30,6 @@ public sealed class GeigerSystem : SharedGeigerSystem
SubscribeLocalEvent<GeigerComponent, GotUnequippedHandEvent>(OnUnequippedHand);
SubscribeLocalEvent<RadiationSystemUpdatedEvent>(OnUpdate);
SubscribeLocalEvent<GeigerComponent, ComponentGetState>(OnGetState);
}
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)
{
// check that it's approx equal

View File

@@ -110,7 +110,7 @@ public sealed class EnergySwordSystem : EntitySystem
{
weaponComp.HitSound = comp.OnHitOff;
if (comp.Secret)
weaponComp.HideFromExamine = true;
weaponComp.Hidden = true;
}
if (comp.IsSharp)
@@ -135,7 +135,7 @@ public sealed class EnergySwordSystem : EntitySystem
{
weaponComp.HitSound = comp.OnHitOn;
if (comp.Secret)
weaponComp.HideFromExamine = false;
weaponComp.Hidden = false;
}
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.Contests;
using Content.Server.Movement.Systems;
using Content.Shared.Administration.Components;
using Content.Shared.Actions.Events;
using Content.Shared.Administration.Components;
using Content.Shared.CombatMode;
using Content.Shared.Damage.Events;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Effects;
using Content.Shared.FixedPoint;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
@@ -29,8 +31,6 @@ using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Random;
using Content.Shared.Effects;
using Content.Shared.Damage.Systems;
namespace Content.Server.Weapons.Melee;
@@ -57,7 +57,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args)
{
if (component.HideFromExamine)
if (component.Hidden)
return;
var damageSpec = GetDamage(uid, args.User, component);

View File

@@ -22,7 +22,7 @@ public sealed partial class GunSystem
else if (component.UnspawnedCount > 0)
{
component.UnspawnedCount--;
ent = Spawn(component.FillProto, coordinates);
ent = Spawn(component.Proto, coordinates);
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)
{
if (string.IsNullOrEmpty(component.FillProto) || component.UnspawnedCount == 0)
if (string.IsNullOrEmpty(component.Proto) || component.UnspawnedCount == 0)
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;
}

View File

@@ -12,7 +12,6 @@ using Content.Server.NPC;
using Content.Server.NPC.Components;
using Content.Server.NPC.HTN;
using Content.Server.NPC.Systems;
using Content.Server.Nutrition.Components;
using Content.Server.Roles;
using Content.Server.Speech.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
//and range here because of stuff we'll find out later
var melee = EnsureComp<MeleeWeaponComponent>(target);
melee.ClickAnimation = zombiecomp.AttackAnimation;
melee.Animation = zombiecomp.AttackAnimation;
melee.WideAnimation = zombiecomp.AttackAnimation;
melee.Range = 1.2f;

View File

@@ -255,7 +255,7 @@ namespace Content.Server.Zombies
foreach (var (layer, info) in zombiecomp.BeforeZombifiedCustomBaseLayers)
{
_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))
{

View File

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

View File

@@ -1,12 +1,12 @@
using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Access.Components;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedIdCardConsoleSystem))]
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 TargetIdCardSlotId = "IdCardConsole-targetId";
[DataField("privilegedIdSlot")]
[DataField]
public ItemSlot PrivilegedIdSlot = new();
[DataField("targetIdSlot")]
[DataField]
public ItemSlot TargetIdSlot = new();
[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.
[DataField("accessLevels", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))]
public List<string> AccessLevels = new()
[DataField, AutoNetworkedField]
public List<ProtoId<AccessLevelPrototype>> AccessLevels = new()
{
"Armory",
"Atmospherics",

View File

@@ -2,7 +2,6 @@ using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Access.Systems
@@ -23,19 +22,6 @@ namespace Content.Shared.Access.Systems
SubscribeLocalEvent<AccessOverriderComponent, ComponentInit>(OnComponentInit);
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)
@@ -48,17 +34,6 @@ namespace Content.Shared.Access.Systems
_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]
public sealed partial class AccessOverriderDoAfterEvent : DoAfterEvent
{

View File

@@ -1,8 +1,6 @@
using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Access.Systems
{
@@ -22,19 +20,6 @@ namespace Content.Shared.Access.Systems
SubscribeLocalEvent<IdCardConsoleComponent, ComponentInit>(OnComponentInit);
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)
@@ -48,16 +33,5 @@ namespace Content.Shared.Access.Systems
_itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot);
_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.
/// Should only be used for player-controlled entities.
/// </summary>
[RegisterComponent]
[NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
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;
}

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 Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.Alert;
@@ -170,7 +169,6 @@ public abstract class AlertsSystem : EntitySystem
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
SubscribeLocalEvent<AlertsComponent, ComponentGetState>(ClientAlertsGetState);
SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert);
LoadPrototypes();
@@ -243,9 +241,4 @@ public abstract class AlertsSystem : EntitySystem
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 Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
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
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAnomalySystem))]
public sealed partial class AnomalyComponent : Component
{
/// <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
/// value that only matters in relation to the <see cref="GrowthThreshold"/> and <see cref="DecayThreshold"/>
/// </remarks>
[ViewVariables(VVAccess.ReadWrite)]
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Stability = 0f;
/// <summary>
@@ -39,7 +39,7 @@ public sealed partial class AnomalyComponent : Component
/// <remarks>
/// Wacky-Stability scale lives on in my heart. - emo
/// </remarks>
[ViewVariables(VVAccess.ReadWrite)]
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Severity = 0f;
#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
/// reaching a supercritical point.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Health = 1f;
/// <summary>
@@ -85,25 +85,26 @@ public sealed partial class AnomalyComponent : Component
/// <summary>
/// The time at which the next artifact pulse will occur.
/// </summary>
[DataField("nextPulseTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan NextPulseTime = TimeSpan.Zero;
/// <summary>
/// The minimum interval between pulses.
/// </summary>
[DataField("minPulseLength")]
[DataField]
public TimeSpan MinPulseLength = TimeSpan.FromMinutes(1);
/// <summary>
/// The maximum interval between pulses.
/// </summary>
[DataField("maxPulseLength")]
[DataField]
public TimeSpan MaxPulseLength = TimeSpan.FromMinutes(2);
/// <summary>
/// A percentage by which the length of a pulse might vary.
/// </summary>
[DataField("pulseVariation")]
[DataField]
public float PulseVariation = 0.1f;
/// <summary>
@@ -112,19 +113,19 @@ public sealed partial class AnomalyComponent : Component
/// <remarks>
/// This is more likely to trend upwards than donwards, because that's funny
/// </remarks>
[DataField("pulseStabilityVariation")]
[DataField]
public Vector2 PulseStabilityVariation = new(-0.1f, 0.15f);
/// <summary>
/// The sound played when an anomaly pulses
/// </summary>
[DataField("pulseSound")]
[DataField]
public SoundSpecifier? PulseSound = new SoundCollectionSpecifier("RadiationPulse");
/// <summary>
/// The sound plays when an anomaly goes supercritical
/// </summary>
[DataField("supercriticalSound")]
[DataField]
public SoundSpecifier? SupercriticalSound = new SoundCollectionSpecifier("explosion");
#endregion
@@ -134,7 +135,7 @@ public sealed partial class AnomalyComponent : Component
/// <remarks>
/// +/- 0.2 from perfect stability (0.5)
/// </remarks>
[DataField("initialStabilityRange")]
[DataField]
public (float, float) InitialStabilityRange = (0.4f, 0.6f);
/// <summary>
@@ -143,25 +144,25 @@ public sealed partial class AnomalyComponent : Component
/// <remarks>
/// Between 0 and 0.5, which should be all mild effects
/// </remarks>
[DataField("initialSeverityRange")]
[DataField]
public (float, float) InitialSeverityRange = (0.1f, 0.5f);
/// <summary>
/// The particle type that increases the severity of the anomaly.
/// </summary>
[DataField("severityParticleType")]
[DataField]
public AnomalousParticleType SeverityParticleType;
/// <summary>
/// The particle type that destabilizes the anomaly.
/// </summary>
[DataField("destabilizingParticleType")]
[DataField]
public AnomalousParticleType DestabilizingParticleType;
/// <summary>
/// The particle type that weakens the anomalys health.
/// </summary>
[DataField("weakeningParticleType")]
[DataField]
public AnomalousParticleType WeakeningParticleType;
#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
/// directly or by hitting the anomaly.
/// </summary>
[DataField("anomalyContactDamage", required: true)]
[DataField(required: true)]
public DamageSpecifier AnomalyContactDamage = default!;
/// <summary>
/// The sound effect played when a player
/// burns themselves on an anomaly via contact.
/// </summary>
[DataField("anomalyContactDamageSound")]
[DataField]
public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
#region Floating Animation
@@ -226,23 +227,6 @@ public sealed partial class AnomalyComponent : Component
#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>
/// Event raised at regular intervals on an anomaly to do whatever its effect is.
/// </summary>

View File

@@ -1,5 +1,4 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Anomaly.Components;
@@ -7,31 +6,27 @@ namespace Content.Shared.Anomaly.Components;
/// <summary>
/// Tracks anomalies going supercritical
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(SharedAnomalySystem))]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAnomalySystem))]
public sealed partial class AnomalySupercriticalComponent : Component
{
/// <summary>
/// The time when the supercritical animation ends and it does whatever effect.
/// </summary>
[DataField("endTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan EndTime;
/// <summary>
/// The length of the animation before it goes supercritical.
/// </summary>
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan SupercriticalDuration = TimeSpan.FromSeconds(10);
/// <summary>
/// The maximum size the anomaly scales to while going supercritical
/// </summary>
[DataField("maxScaleAmount")]
[DataField]
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.Popups;
using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Random;
using Robust.Shared.Timing;
@@ -30,10 +29,6 @@ public abstract class SharedAnomalySystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<AnomalyComponent, ComponentGetState>(OnAnomalyGetState);
SubscribeLocalEvent<AnomalyComponent, ComponentHandleState>(OnAnomalyHandleState);
SubscribeLocalEvent<AnomalySupercriticalComponent, ComponentGetState>(OnSupercriticalGetState);
SubscribeLocalEvent<AnomalySupercriticalComponent, ComponentHandleState>(OnSupercriticalHandleState);
SubscribeLocalEvent<AnomalyComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<AnomalyComponent, AttackedEvent>(OnAttacked);
@@ -44,43 +39,6 @@ public abstract class SharedAnomalySystem : EntitySystem
_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)
{
DoAnomalyBurnDamage(uid, args.User, component);

View File

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

View File

@@ -4,18 +4,17 @@ using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Body.Components;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedBodySystem))]
public sealed partial class BodyComponent : Component
{
/// <summary>
/// Relevant template to spawn for this body.
/// </summary>
[DataField]
[DataField, AutoNetworkedField]
public ProtoId<BodyPrototype>? Prototype;
/// <summary>
@@ -29,35 +28,17 @@ public sealed partial class BodyComponent : Component
[ViewVariables]
public string RootPartSlot => RootContainer.ID;
[DataField] public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib");
[DataField, AutoNetworkedField]
public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib");
/// <summary>
/// The amount of legs required to move at full speed.
/// If 0, then legs do not impact speed.
/// </summary>
[DataField] public int RequiredLegs;
[DataField, AutoNetworkedField]
public int RequiredLegs;
[ViewVariables]
[DataField]
[DataField, AutoNetworkedField]
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.DragDrop;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using MapInitEvent = Robust.Shared.GameObjects.MapInitEvent;
namespace Content.Shared.Body.Systems;
@@ -30,8 +28,6 @@ public partial class SharedBodySystem
SubscribeLocalEvent<BodyComponent, ComponentInit>(OnBodyInit);
SubscribeLocalEvent<BodyComponent, MapInitEvent>(OnBodyMapInit);
SubscribeLocalEvent<BodyComponent, CanDragEvent>(OnBodyCanDrag);
SubscribeLocalEvent<BodyComponent, ComponentGetState>(OnBodyGetState);
SubscribeLocalEvent<BodyComponent, ComponentHandleState>(OnBodyHandleState);
}
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)
{
// Setup the initial container.

View File

@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Buckle.Components;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedBuckleSystem))]
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
/// across a table two tiles away" problem.
/// </summary>
[DataField("range")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
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.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public bool Buckled;
[ViewVariables]
[AutoNetworkedField]
public EntityUid? LastEntityBuckledTo;
/// <summary>
/// Whether or not collisions should be possible with the entity we are strapped to
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("dontCollide")]
[DataField, AutoNetworkedField]
public bool DontCollide;
/// <summary>
/// Whether or not we should be allowed to pull the entity we are strapped to
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("pullStrap")]
[DataField]
public bool PullStrap;
/// <summary>
/// The amount of time that must pass for this entity to
/// be able to unbuckle after recently buckling.
/// </summary>
[DataField("delay")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan UnbuckleDelay = TimeSpan.FromSeconds(0.25f);
public TimeSpan Delay = TimeSpan.FromSeconds(0.25f);
/// <summary>
/// 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.
/// </summary>
[ViewVariables]
[AutoNetworkedField]
public EntityUid? BuckledTo;
/// <summary>
/// The amount of space that this entity occupies in a
/// <see cref="StrapComponent"/>.
/// </summary>
[DataField("size")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public int Size = 100;
/// <summary>
/// Used for client rendering
/// </summary>
[ViewVariables]
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;
[ViewVariables] public int? OriginalDrawDepth;
}
[ByRefEvent]

View File

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

View File

@@ -12,14 +12,12 @@ using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Popups;
using Content.Shared.Pulling.Components;
using Content.Shared.Pulling.Events;
using Content.Shared.Standing;
using Content.Shared.Storage.Components;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
using Content.Shared.Vehicle.Components;
using Content.Shared.Verbs;
using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Utility;
@@ -32,7 +30,6 @@ public abstract partial class SharedBuckleSystem
{
SubscribeLocalEvent<BuckleComponent, ComponentStartup>(OnBuckleComponentStartup);
SubscribeLocalEvent<BuckleComponent, ComponentShutdown>(OnBuckleComponentShutdown);
SubscribeLocalEvent<BuckleComponent, ComponentGetState>(OnBuckleComponentGetState);
SubscribeLocalEvent<BuckleComponent, MoveEvent>(OnBuckleMove);
SubscribeLocalEvent<BuckleComponent, InteractHandEvent>(OnBuckleInteractHand);
SubscribeLocalEvent<BuckleComponent, GetVerbsEvent<InteractionVerb>>(AddUnbuckleVerb);
@@ -58,11 +55,6 @@ public abstract partial class SharedBuckleSystem
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)
{
if (component.BuckledTo is not {} strapUid)
@@ -434,7 +426,7 @@ public abstract partial class SharedBuckleSystem
if (attemptEvent.Cancelled)
return false;
if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.UnbuckleDelay)
if (_gameTiming.CurTime < buckleComp.BuckleTime + buckleComp.Delay)
return false;
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.Verbs;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
namespace Content.Shared.Buckle;
@@ -19,9 +18,6 @@ public abstract partial class SharedBuckleSystem
SubscribeLocalEvent<StrapComponent, ComponentShutdown>(OnStrapShutdown);
SubscribeLocalEvent<StrapComponent, ComponentRemove>((_, c, _) => StrapRemoveAll(c));
SubscribeLocalEvent<StrapComponent, ComponentGetState>(OnStrapGetState);
SubscribeLocalEvent<StrapComponent, ComponentHandleState>(OnStrapHandleState);
SubscribeLocalEvent<StrapComponent, EntInsertedIntoContainerMessage>(OnStrapEntModifiedFromContainer);
SubscribeLocalEvent<StrapComponent, EntRemovedFromContainerMessage>(OnStrapEntModifiedFromContainer);
SubscribeLocalEvent<StrapComponent, GetVerbsEvent<InteractionVerb>>(AddStrapVerbs);
@@ -50,24 +46,6 @@ public abstract partial class SharedBuckleSystem
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)
{
if (_gameTiming.ApplyingState)

View File

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

View File

@@ -1,65 +1,43 @@
using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Cabinet;
/// <summary>
/// Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets.
/// </summary>
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ItemCabinetComponent : Component
{
/// <summary>
/// Sound to be played when the cabinet door is opened.
/// </summary>
[DataField("doorSound"), ViewVariables(VVAccess.ReadWrite)]
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier? DoorSound;
/// <summary>
/// The <see cref="ItemSlot"/> that stores the actual item. The entity whitelist, sounds, and other
/// behaviours are specified by this <see cref="ItemSlot"/> definition.
/// </summary>
[DataField("cabinetSlot"), ViewVariables]
[DataField, ViewVariables]
public ItemSlot CabinetSlot = new();
/// <summary>
/// Whether the cabinet is currently open or not.
/// </summary>
[DataField("opened")]
[DataField, AutoNetworkedField]
public bool Opened;
/// <summary>
/// The state for when the cabinet is open
/// </summary>
[DataField("openState"), ViewVariables(VVAccess.ReadWrite)]
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
public string? OpenState;
/// <summary>
/// The state for when the cabinet is closed
/// </summary>
[DataField("closedState"), ViewVariables(VVAccess.ReadWrite)]
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)]
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 Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -19,9 +18,6 @@ public abstract class SharedItemCabinetSystem : EntitySystem
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<ItemCabinetComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<ItemCabinetComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove);
SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup);
@@ -35,24 +31,6 @@ public abstract class SharedItemCabinetSystem : EntitySystem
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)
{
_itemSlots.AddItemSlot(uid, "ItemCabinet", cabinet.CabinetSlot);

View File

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

View File

@@ -1,7 +1,5 @@
using Content.Shared.Containers.ItemSlots;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Network;
namespace Content.Shared.CartridgeLoader;
@@ -24,10 +22,6 @@ public abstract class SharedCartridgeLoaderSystem : EntitySystem
SubscribeLocalEvent<CartridgeLoaderComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
SubscribeLocalEvent<CartridgeLoaderComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
SubscribeLocalEvent<CartridgeComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<CartridgeComponent, ComponentHandleState>(OnHandleState);
}
private void OnComponentInit(EntityUid uid, CartridgeLoaderComponent loader, ComponentInit args)
@@ -55,22 +49,6 @@ public abstract class SharedCartridgeLoaderSystem : EntitySystem
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)
{
_appearanceSystem.SetData(uid, CartridgeLoaderVisuals.CartridgeInserted, loader.CartridgeSlot.HasItem);

View File

@@ -1,39 +1,22 @@
using Robust.Shared.Serialization;
using Robust.Shared.GameStates;
namespace Content.Shared.Chemistry.Components
{
//TODO: refactor movement modifier component because this is a pretty poor solution
[RegisterComponent]
[NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MovespeedModifierMetabolismComponent : Component
{
[ViewVariables]
[AutoNetworkedField, ViewVariables]
public float WalkSpeedModifier { get; set; }
[ViewVariables]
[AutoNetworkedField, ViewVariables]
public float SprintSpeedModifier { get; set; }
/// <summary>
/// When the current modifier is expected to end.
/// </summary>
[ViewVariables]
[AutoNetworkedField, ViewVariables]
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 Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using static Content.Shared.Chemistry.Components.MovespeedModifierMetabolismComponent;
using Robust.Shared.Timing;
namespace Content.Shared.Chemistry
{
@@ -21,30 +18,10 @@ namespace Content.Shared.Chemistry
UpdatesOutsidePrediction = true;
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentHandleState>(OnMovespeedHandleState);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<MovespeedModifierMetabolismComponent, ComponentStartup>(AddComponent);
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)
{
args.ModifySpeed(component.WalkSpeedModifier, component.SprintSpeedModifier);

View File

@@ -1,21 +1,20 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Climbing;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ClimbingComponent : Component
{
/// <summary>
/// Whether the owner is climbing on a climbable entity.
/// </summary>
[ViewVariables]
[ViewVariables, AutoNetworkedField]
public bool IsClimbing { get; set; }
/// <summary>
/// Whether the owner is being moved onto the climbed entity.
/// </summary>
[ViewVariables]
[ViewVariables, AutoNetworkedField]
public bool OwnerIsTransitioning { get; set; }
/// <summary>
@@ -25,17 +24,4 @@ public sealed partial class ClimbingComponent : Component
[ViewVariables]
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.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Clothing.Components;
/// <summary>
/// Allow players to change clothing sprite to any other clothing prototype.
/// </summary>
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedChameleonClothingSystem))]
public sealed partial class ChameleonClothingComponent : Component
{
@@ -18,15 +17,15 @@ public sealed partial class ChameleonClothingComponent : Component
/// Filter possible chameleon options by their slot flag.
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
[DataField("slot", required: true)]
[DataField(required: true)]
public SlotFlags Slot;
/// <summary>
/// EntityPrototype id that chameleon item is trying to mimic.
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
[DataField("default", required: true, customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? SelectedId;
[DataField(required: true), AutoNetworkedField]
public EntProtoId? Default;
/// <summary>
/// Current user that wears chameleon clothing.
@@ -35,12 +34,6 @@ public sealed partial class ChameleonClothingComponent : Component
public EntityUid? User;
}
[Serializable, NetSerializable]
public sealed class ChameleonClothingComponentState : ComponentState
{
public string? SelectedId;
}
[Serializable, NetSerializable]
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.
protected void UpdateVisuals(EntityUid uid, ChameleonClothingComponent component)
{
if (string.IsNullOrEmpty(component.SelectedId) ||
!_proto.TryIndex(component.SelectedId, out EntityPrototype? proto))
if (string.IsNullOrEmpty(component.Default) ||
!_proto.TryIndex(component.Default, out EntityPrototype? proto))
return;
// world sprite icon

View File

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

View File

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

View File

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

View File

@@ -16,11 +16,9 @@ using Content.Shared.Throwing;
using Content.Shared.Weapons.Melee.Events;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
namespace Content.Shared.Damage.Systems;
@@ -52,8 +50,7 @@ public sealed partial class StaminaSystem : EntitySystem
SubscribeLocalEvent<StaminaComponent, EntityUnpausedEvent>(OnStamUnpaused);
SubscribeLocalEvent<StaminaComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<StaminaComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<StaminaComponent, ComponentGetState>(OnStamGetState);
SubscribeLocalEvent<StaminaComponent, ComponentHandleState>(OnStamHandleState);
SubscribeLocalEvent<StaminaComponent, AfterAutoHandleStateEvent>(OnStamHandleState);
SubscribeLocalEvent<StaminaComponent, DisarmedEvent>(OnDisarmed);
SubscribeLocalEvent<StaminaComponent, RejuvenateEvent>(OnRejuvenate);
@@ -67,31 +64,8 @@ public sealed partial class StaminaSystem : EntitySystem
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)
EnterStamCrit(uid, component);
else
@@ -283,7 +257,7 @@ public sealed partial class StaminaSystem : EntitySystem
// Reset the decay cooldown upon taking damage.
if (oldDamage < component.StaminaDamage)
{
var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.DecayCooldown);
var nextUpdate = _timing.CurTime + TimeSpan.FromSeconds(component.Cooldown);
if (component.NextUpdate < nextUpdate)
component.NextUpdate = nextUpdate;
@@ -419,18 +393,6 @@ public sealed partial class StaminaSystem : EntitySystem
Dirty(component);
_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>

View File

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

View File

@@ -2,72 +2,57 @@ using Content.Shared.DeviceLinking;
using Content.Shared.DeviceNetwork.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.DeviceNetwork.Components;
[RegisterComponent]
[NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedNetworkConfiguratorSystem))]
public sealed partial class NetworkConfiguratorComponent : Component
{
/// <summary>
/// Determines whether the configurator is in linking mode or list mode
/// </summary>
[DataField("linkModeActive")]
[DataField, AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public bool LinkModeActive = true;
/// <summary>
/// The entity containing a <see cref="DeviceListComponent"/> this configurator is currently interacting with
/// </summary>
[DataField("activeDeviceList")]
public EntityUid? ActiveDeviceList = null;
[DataField, AutoNetworkedField]
public EntityUid? ActiveDeviceList;
/// <summary>
/// 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.
/// </summary>
[DataField("activeDeviceLink")]
public EntityUid? ActiveDeviceLink = null;
[DataField]
public EntityUid? ActiveDeviceLink;
/// <summary>
/// The target device this configurator is currently linking with the <see cref="ActiveDeviceLink"/>
/// </summary>
[DataField("deviceLinkTarget")]
public EntityUid? DeviceLinkTarget = null;
[DataField]
public EntityUid? DeviceLinkTarget;
/// <summary>
/// The list of devices stored in the configurator
/// </summary>
[DataField("devices")]
[DataField]
public Dictionary<string, EntityUid> Devices = new();
[DataField("useDelay")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan UseDelay = TimeSpan.FromSeconds(0.5);
[DataField("lastUseAttempt", customTypeSerializer:typeof(TimeOffsetSerializer))]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan LastUseAttempt;
[DataField("soundNoAccess")]
[DataField]
public SoundSpecifier SoundNoAccess = new SoundPathSpecifier("/Audio/Machines/custom_deny.ogg");
[DataField("soundSwitchMode")]
[DataField]
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 Content.Shared.DeviceNetwork.Components;
using Robust.Shared.GameStates;
namespace Content.Shared.DeviceNetwork.Systems;
public abstract class SharedDeviceListSystem : EntitySystem
{
public override void Initialize()
{
SubscribeLocalEvent<DeviceListComponent, ComponentGetState>(GetDeviceListState);
SubscribeLocalEvent<DeviceListComponent, ComponentHandleState>(HandleDeviceListState);
}
/// <summary>
/// Updates the device list stored on this entity.
/// </summary>
@@ -57,23 +50,6 @@ public abstract class SharedDeviceListSystem : EntitySystem
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

View File

@@ -1,37 +1,10 @@
using Content.Shared.Actions;
using Content.Shared.DeviceNetwork.Components;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.DeviceNetwork.Systems;
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

View File

@@ -1,7 +1,6 @@
using Content.Shared.DeviceLinking;
using Content.Shared.Doors.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Doors.Components;
@@ -9,16 +8,17 @@ namespace Content.Shared.Doors.Components;
/// <summary>
/// Companion component to DoorComponent that handles airlock-specific behavior -- wires, requiring power to operate, bolts, and allowing automatic closing.
/// </summary>
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedAirlockSystem), Friend = AccessPermissions.ReadWriteExecute, Other = AccessPermissions.Read)]
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)]
[DataField("safety")]
[DataField, AutoNetworkedField]
public bool Safety = true;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("emergencyAccess")]
[DataField]
public bool EmergencyAccess = false;
/// <summary>
@@ -26,20 +26,20 @@ public sealed partial class AirlockComponent : Component
/// 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.)
/// </summary>
[DataField("poweredPryModifier")]
[DataField]
public float PoweredPryModifier = 9f;
/// <summary>
/// Whether the maintenance panel should be visible even if the airlock is opened.
/// </summary>
[DataField("openPanelVisible")]
[DataField]
public bool OpenPanelVisible = false;
/// <summary>
/// Whether the airlock should stay open if the airlock was clicked.
/// If the airlock was bumped into it will still auto close.
/// </summary>
[DataField("keepOpenIfClicked")]
[DataField]
public bool KeepOpenIfClicked = false;
/// <summary>
@@ -51,7 +51,7 @@ public sealed partial class AirlockComponent : Component
/// <summary>
/// Delay until an open door automatically closes.
/// </summary>
[DataField("autoCloseDelay")]
[DataField]
public TimeSpan AutoCloseDelay = TimeSpan.FromSeconds(5f);
/// <summary>
@@ -64,7 +64,7 @@ public sealed partial class AirlockComponent : Component
/// <summary>
/// The receiver port for turning off automatic closing.
/// </summary>
[DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string AutoClosePort = "AutoClose";
#region Graphics
@@ -72,79 +72,68 @@ public sealed partial class AirlockComponent : Component
/// <summary>
/// Whether the door lights should be visible.
/// </summary>
[DataField("openUnlitVisible")]
[DataField]
public bool OpenUnlitVisible = false;
/// <summary>
/// Whether the door should display emergency access lights.
/// </summary>
[DataField("emergencyAccessLayer")]
[DataField]
public bool EmergencyAccessLayer = true;
/// <summary>
/// Whether or not to animate the panel when the door opens or closes.
/// </summary>
[DataField("animatePanel")]
[DataField]
public bool AnimatePanel = true;
/// <summary>
/// The sprite state used to animate the airlock frame when the airlock opens.
/// </summary>
[DataField("openingSpriteState")]
[DataField]
public string OpeningSpriteState = "opening_unlit";
/// <summary>
/// The sprite state used to animate the airlock panel when the airlock opens.
/// </summary>
[DataField("openingPanelSpriteState")]
[DataField]
public string OpeningPanelSpriteState = "panel_opening";
/// <summary>
/// The sprite state used to animate the airlock frame when the airlock closes.
/// </summary>
[DataField("closingSpriteState")]
[DataField]
public string ClosingSpriteState = "closing_unlit";
/// <summary>
/// The sprite state used to animate the airlock panel when the airlock closes.
/// </summary>
[DataField("closingPanelSpriteState")]
[DataField]
public string ClosingPanelSpriteState = "panel_closing";
/// <summary>
/// The sprite state used for the open airlock lights.
/// </summary>
[DataField("openSpriteState")]
[DataField]
public string OpenSpriteState = "open_unlit";
/// <summary>
/// The sprite state used for the closed airlock lights.
/// </summary>
[DataField("closedSpriteState")]
[DataField]
public string ClosedSpriteState = "closed_unlit";
/// <summary>
/// The sprite state used for the 'access denied' lights animation.
/// </summary>
[DataField("denySpriteState")]
[DataField]
public string DenySpriteState = "deny_unlit";
/// <summary>
/// How long the animation played when the airlock denies access is in seconds.
/// </summary>
[DataField("denyAnimationTime")]
[DataField]
public float DenyAnimationTime = 0.3f;
#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.Doors.Systems;
using Content.Shared.Tools;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Timing;
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
namespace Content.Shared.Doors.Components;
[NetworkedComponent]
[RegisterComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class DoorComponent : Component
{
/// <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.
/// </remarks>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("state")]
[DataField, AutoNetworkedField]
[Access(typeof(SharedDoorSystem))]
public DoorState State = DoorState.Closed;
@@ -35,46 +33,47 @@ public sealed partial class DoorComponent : Component
/// <summary>
/// Closing time until impassable. Total time is this plus <see cref="CloseTimeTwo"/>.
/// </summary>
[DataField("closeTimeOne")]
[DataField]
public TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.4f);
/// <summary>
/// Closing time until fully closed. Total time is this plus <see cref="CloseTimeOne"/>.
/// </summary>
[DataField("closeTimeTwo")]
[DataField]
public TimeSpan CloseTimeTwo = TimeSpan.FromSeconds(0.2f);
/// <summary>
/// Opening time until passable. Total time is this plus <see cref="OpenTimeTwo"/>.
/// </summary>
[DataField("openTimeOne")]
[DataField]
public TimeSpan OpenTimeOne = TimeSpan.FromSeconds(0.4f);
/// <summary>
/// Opening time until fully open. Total time is this plus <see cref="OpenTimeOne"/>.
/// </summary>
[DataField("openTimeTwo")]
[DataField]
public TimeSpan OpenTimeTwo = TimeSpan.FromSeconds(0.2f);
/// <summary>
/// Interval between deny sounds & visuals;
/// </summary>
[DataField("denyDuration")]
[DataField]
public TimeSpan DenyDuration = TimeSpan.FromSeconds(0.45f);
[DataField("emagDuration")]
[DataField]
public TimeSpan EmagDuration = TimeSpan.FromSeconds(0.8f);
/// <summary>
/// When the door is active, this is the time when the state will next update.
/// </summary>
[AutoNetworkedField]
public TimeSpan? NextStateChange;
/// <summary>
/// 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.
/// </summary>
[DataField("partial")]
[DataField, AutoNetworkedField]
public bool Partial;
#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
/// again. Total stun time is actually given by this plus <see cref="OpenTimeOne"/>.
/// </summary>
[DataField("doorStunTime")]
[DataField]
public TimeSpan DoorStunTime = TimeSpan.FromSeconds(2f);
[DataField("crushDamage")]
[DataField]
public DamageSpecifier? CrushDamage;
/// <summary>
/// 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.
/// </summary>
[DataField("canCrush")]
[DataField]
public bool CanCrush = true;
/// <summary>
/// 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.
/// </summary>
[DataField("performCollisionCheck")]
[DataField]
public bool PerformCollisionCheck = true;
/// <summary>
/// List of EntityUids of entities we're currently crushing. Cleared in OnPartialOpen().
/// </summary>
[DataField("currentlyCrushing")]
[DataField, AutoNetworkedField]
public HashSet<EntityUid> CurrentlyCrushing = new();
#endregion
@@ -152,7 +151,7 @@ public sealed partial class DoorComponent : Component
/// <summary>
/// The sprite state used for the door when it's open.
/// </summary>
[DataField("openSpriteState")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public string OpenSpriteState = "open";
@@ -165,7 +164,7 @@ public sealed partial class DoorComponent : Component
/// <summary>
/// The sprite state used for the door when it's closed.
/// </summary>
[DataField("closedSpriteState")]
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public string ClosedSpriteState = "closed";
@@ -178,37 +177,37 @@ public sealed partial class DoorComponent : Component
/// <summary>
/// The sprite state used for the door when it's opening.
/// </summary>
[DataField("openingSpriteState")]
[DataField]
public string OpeningSpriteState = "opening";
/// <summary>
/// The sprite state used for the door when it's closing.
/// </summary>
[DataField("closingSpriteState")]
[DataField]
public string ClosingSpriteState = "closing";
/// <summary>
/// The sprite state used for the door when it's being emagged.
/// </summary>
[DataField("emaggingSpriteState")]
[DataField]
public string EmaggingSpriteState = "emagging";
/// <summary>
/// The sprite state used for the door when it's open.
/// </summary>
[DataField("openingAnimationTime")]
[DataField]
public float OpeningAnimationTime = 0.8f;
/// <summary>
/// The sprite state used for the door when it's open.
/// </summary>
[DataField("closingAnimationTime")]
[DataField]
public float ClosingAnimationTime = 0.8f;
/// <summary>
/// The sprite state used for the door when it's open.
/// </summary>
[DataField("emaggingAnimationTime")]
[DataField]
public float EmaggingAnimationTime = 1.5f;
/// <summary>
@@ -237,7 +236,7 @@ public sealed partial class DoorComponent : Component
/// <summary>
/// Time until next state change. Because apparently <see cref="IGameTiming.CurTime"/> might not get saved/restored.
/// </summary>
[DataField("SecondsUntilStateChange")]
[DataField]
private float? SecondsUntilStateChange
{
[UsedImplicitly]
@@ -262,47 +261,47 @@ public sealed partial class DoorComponent : Component
}
#endregion
[DataField("canPry"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool CanPry = true;
[DataField("pryingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
public string PryingQuality = "Prying";
[DataField]
public ProtoId<ToolQualityPrototype> PryingQuality = "Prying";
/// <summary>
/// Default time that the door should take to pry open.
/// </summary>
[DataField("pryTime"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float PryTime = 1.5f;
[DataField("changeAirtight")]
[DataField]
public bool ChangeAirtight = true;
/// <summary>
/// Whether the door blocks light.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("occludes")]
[DataField]
public bool Occludes = true;
/// <summary>
/// Whether the door will open when it is bumped into.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("bumpOpen")]
[DataField]
public bool BumpOpen = true;
/// <summary>
/// Whether the door will open when it is activated or clicked.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("clickOpen")]
[DataField]
public bool ClickOpen = true;
[DataField("openDrawDepth", customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int OpenDrawDepth = (int)DrawDepth.DrawDepth.Doors;
[DataField(customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int OpenDrawDepth = (int) DrawDepth.DrawDepth.Doors;
[DataField("closedDrawDepth", customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int ClosedDrawDepth = (int)DrawDepth.DrawDepth.Doors;
[DataField(customTypeSerializer: typeof(ConstantSerializer<DrawDepthTag>))]
public int ClosedDrawDepth = (int) DrawDepth.DrawDepth.Doors;
}
[Serializable, NetSerializable]
@@ -335,20 +334,3 @@ public enum DoorVisualLayers : byte
BaseBolted,
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.Popups;
using Robust.Shared.GameStates;
namespace Content.Shared.Doors.Systems;
@@ -14,32 +13,15 @@ public abstract class SharedAirlockSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<AirlockComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<AirlockComponent, ComponentHandleState>(OnHandleState);
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)
{
if (!airlock.Safety)
args.PerformCollisionCheck = false;
}
public void UpdateEmergencyLightStatus(EntityUid uid, AirlockComponent component)
{
Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess);

View File

@@ -10,7 +10,6 @@ using Content.Shared.Physics;
using Content.Shared.Stunnable;
using Content.Shared.Tag;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
@@ -55,8 +54,7 @@ public abstract partial class SharedDoorSystem : EntitySystem
SubscribeLocalEvent<DoorComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<DoorComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<DoorComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<DoorComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate);
@@ -102,29 +100,14 @@ public abstract partial class SharedDoorSystem : EntitySystem
}
#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));
}
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)
if (door.NextStateChange == null)
_activeDoors.Remove(door);
else
_activeDoors.Add(door);
RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State), false);
RaiseLocalEvent(uid, new DoorStateChangedEvent(door.State));
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
}

View File

@@ -1,29 +1,17 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Electrocution
{
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedElectrocutionSystem))]
[RegisterComponent, NetworkedComponent]
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>
/// Siemens coefficient. Zero means completely insulated.
/// </summary>
[DataField("coefficient")]
public float SiemensCoefficient { 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;
}
[DataField, AutoNetworkedField]
public float Coefficient { get; set; } = 0f;
}
}

View File

@@ -1,6 +1,5 @@
using Content.Shared.Inventory;
using Content.Shared.StatusEffect;
using Robust.Shared.GameStates;
namespace Content.Shared.Electrocution
{
@@ -13,8 +12,6 @@ namespace Content.Shared.Electrocution
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).
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)
@@ -22,7 +19,7 @@ namespace Content.Shared.Electrocution
if (!Resolve(uid, ref insulated))
return;
insulated.SiemensCoefficient = siemensCoefficient;
insulated.Coefficient = siemensCoefficient;
Dirty(insulated);
}
@@ -45,21 +42,7 @@ namespace Content.Shared.Electrocution
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,17 +1,12 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Emoting;
namespace Content.Shared.Emoting
public sealed class EmoteSystem : EntitySystem
{
public sealed class EmoteSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<EmoteAttemptEvent>(OnEmoteAttempt);
SubscribeLocalEvent<EmotingComponent, ComponentGetState>(OnEmotingGetState);
SubscribeLocalEvent<EmotingComponent, ComponentHandleState>(OnEmotingHandleState);
}
public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null)
@@ -27,34 +22,9 @@ namespace Content.Shared.Emoting
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)
{
if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled)
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;
namespace Content.Shared.Emoting
namespace Content.Shared.Emoting;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class EmotingComponent : Component
{
[RegisterComponent, NetworkedComponent]
public sealed partial class EmotingComponent : Component
{
[DataField("enabled"), Access(typeof(EmoteSystem),
Friend = AccessPermissions.ReadWrite,
Other = AccessPermissions.Read)] public bool Enabled = true;
}
[DataField, AutoNetworkedField]
[Access(typeof(EmoteSystem), Friend = AccessPermissions.ReadWrite, Other = AccessPermissions.Read)]
public bool Enabled = true;
}

View File

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

View File

@@ -8,14 +8,12 @@ using Content.Shared.Physics.Pull;
using Content.Shared.Tag;
using Content.Shared.Verbs;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Events;
using Robust.Shared.Network;
using Robust.Shared.Utility;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared.Follower;
@@ -38,25 +36,6 @@ public sealed class FollowerSystem : EntitySystem
SubscribeLocalEvent<FollowerComponent, GotEquippedHandEvent>(OnGotEquippedHand);
SubscribeLocalEvent<FollowedComponent, EntityTerminatingEvent>(OnFollowedTerminating);
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)
@@ -242,12 +221,6 @@ public sealed class FollowerSystem : EntitySystem
StopFollowingEntity(player, uid, followed);
}
}
[Serializable, NetSerializable]
private sealed class FollowedComponentState : ComponentState
{
public HashSet<NetEntity> Following = new();
}
}
public abstract class FollowEvent : EntityEventArgs

View File

@@ -1,10 +1,9 @@
using System.Numerics;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Gravity;
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedFloatingVisualizerSystem))]
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.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("animationTime")]
[DataField, AutoNetworkedField]
public float AnimationTime = 2f;
/// <summary>
/// How far it goes in any direction.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("offset")]
[DataField, AutoNetworkedField]
public Vector2 Offset = new(0, 0.2f);
[ViewVariables(VVAccess.ReadWrite)]
[AutoNetworkedField]
public bool CanFloat = false;
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>
/// Indicates this entity is shaking due to gravity changes.
/// </summary>
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class GravityShakeComponent : Component
{
[ViewVariables(VVAccess.ReadWrite), DataField("shakeTimes")]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public int ShakeTimes;
[DataField("nextShake", customTypeSerializer:typeof(TimeOffsetSerializer))]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
public TimeSpan NextShake;
}

View File

@@ -1,5 +1,4 @@
using System.Numerics;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
namespace Content.Shared.Gravity;
@@ -18,8 +17,6 @@ public abstract class SharedFloatingVisualizerSystem : EntitySystem
SubscribeLocalEvent<FloatingVisualsComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<GravityChangedEvent>(OnGravityChanged);
SubscribeLocalEvent<FloatingVisualsComponent, EntParentChangedMessage>(OnEntParentChanged);
SubscribeLocalEvent<FloatingVisualsComponent, ComponentGetState>(OnComponentGetState);
SubscribeLocalEvent<FloatingVisualsComponent, ComponentHandleState>(OnComponentHandleState);
}
/// <summary>
@@ -71,19 +68,4 @@ public abstract class SharedFloatingVisualizerSystem : EntitySystem
if (CanFloat(uid, component, transform))
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;
public abstract partial class SharedGravitySystem
@@ -11,8 +8,6 @@ public abstract partial class SharedGravitySystem
private void InitializeShake()
{
SubscribeLocalEvent<GravityShakeComponent, EntityUnpausedEvent>(OnShakeUnpaused);
SubscribeLocalEvent<GravityShakeComponent, ComponentGetState>(OnShakeGetState);
SubscribeLocalEvent<GravityShakeComponent, ComponentHandleState>(OnShakeHandleState);
}
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) {}
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.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid;
[NetworkedComponent, RegisterComponent]
[NetworkedComponent, RegisterComponent, AutoGenerateComponentState(true)]
public sealed partial class HumanoidAppearanceComponent : Component
{
[DataField("markingSet")]
public MarkingSet ClientOldMarkings = new();
[DataField]
public MarkingSet MarkingSet = new();
[DataField("baseLayers")]
[DataField]
public Dictionary<HumanoidVisualLayers, HumanoidSpeciesSpriteLayer> BaseLayers = new();
[DataField("permanentlyHidden")]
[DataField, AutoNetworkedField(true)]
public HashSet<HumanoidVisualLayers> PermanentlyHidden = new();
// Couldn't these be somewhere else?
[DataField("gender")]
[ViewVariables] public Gender Gender = default!;
[DataField, AutoNetworkedField]
public Gender Gender;
[DataField("age")]
[ViewVariables] public int Age = 18;
[DataField, AutoNetworkedField]
public int Age = 18;
/// <summary>
/// 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
/// all layer settings.
/// </summary>
[DataField("customBaseLayers")]
[DataField, AutoNetworkedField(true)]
public Dictionary<HumanoidVisualLayers, CustomBaseLayerInfo> CustomBaseLayers = new();
/// <summary>
/// Current species. Dictates things like base body sprites,
/// base humanoid to spawn, etc.
/// </summary>
[DataField("species", customTypeSerializer: typeof(PrototypeIdSerializer<SpeciesPrototype>), required: true)]
public string Species { get; set; } = default!;
[DataField(required: true), AutoNetworkedField]
public ProtoId<SpeciesPrototype> Species { get; set; }
/// <summary>
/// The initial profile and base layers to apply to this humanoid.
/// </summary>
[DataField("initial", customTypeSerializer: typeof(PrototypeIdSerializer<HumanoidProfilePrototype>))]
public string? Initial { get; private set; }
[DataField]
public ProtoId<HumanoidProfilePrototype>? Initial { get; private set; }
/// <summary>
/// Skin color of this humanoid.
/// </summary>
[DataField("skinColor")]
[DataField, AutoNetworkedField]
public Color SkinColor { get; set; } = Color.FromHex("#C0967F");
/// <summary>
/// Visual layers currently hidden. This will affect the base sprite
/// on this humanoid layer, and any markings that sit above it.
/// </summary>
[DataField("hiddenLayers")]
[DataField, AutoNetworkedField(true)]
public HashSet<HumanoidVisualLayers> HiddenLayers = new();
[DataField("sex")]
[DataField, AutoNetworkedField]
public Sex Sex = Sex.Male;
[DataField("eyeColor")]
[DataField, AutoNetworkedField]
public Color EyeColor = Color.Brown;
/// <summary>
@@ -84,65 +84,26 @@ public sealed partial class HumanoidAppearanceComponent : Component
public Color? CachedFacialHairColor;
}
[DataDefinition]
[Serializable, NetSerializable]
public sealed partial class HumanoidAppearanceState : ComponentState
public readonly partial struct CustomBaseLayerInfo
{
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]
[Serializable, NetSerializable]
public readonly partial struct CustomBaseLayerInfo
{
public CustomBaseLayerInfo(string? id, Color? color = null)
{
DebugTools.Assert(id == null || IoCManager.Resolve<IPrototypeManager>().HasIndex<HumanoidSpeciesSpriteLayer>(id));
ID = id;
Id = id;
Color = color;
}
/// <summary>
/// ID of this custom base layer. Must be a <see cref="HumanoidSpeciesSpriteLayer"/>.
/// </summary>
[DataField("id", customTypeSerializer: typeof(PrototypeIdSerializer<HumanoidSpeciesSpriteLayer>))]
public string? ID { init; get; }
[DataField]
public ProtoId<HumanoidSpeciesSpriteLayer>? Id { get; init; }
/// <summary>
/// Color of this custom base layer. Null implies skin colour if the corresponding <see cref="HumanoidSpeciesSpriteLayer"/> is set to match skin.
/// </summary>
[DataField("color")]
public Color? Color { init; get; }
}
[DataField]
public Color? Color { get; init; }
}

View File

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

View File

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

View File

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

View File

@@ -1,10 +1,7 @@
using System.Threading;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using Content.Shared.Containers.ItemSlots;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Implants.Components;
/// <summary>
@@ -12,7 +9,7 @@ namespace Content.Shared.Implants.Components;
/// Some can be single use (implant only) or some can draw out an implant
/// </summary>
//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 const string ImplanterSlotId = "implanter_slot";
@@ -21,15 +18,14 @@ public sealed partial class ImplanterComponent : Component
/// <summary>
/// Used for implanters that start with specific implants
/// </summary>
[ViewVariables]
[DataField("implant", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? Implant;
[DataField]
public EntProtoId? Implant;
/// <summary>
/// The time it takes to implant someone else
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("implantTime")]
[DataField]
public float ImplantTime = 5f;
//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
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("drawTime")]
[DataField]
public float DrawTime = 60f;
/// <summary>
/// Good for single-use injectors
/// </summary>
[ViewVariables]
[DataField("implantOnly")]
public bool ImplantOnly = false;
[DataField, AutoNetworkedField]
public bool ImplantOnly;
/// <summary>
/// The current mode of the implanter
/// Mode is changed automatically depending if it implants or draws
/// </summary>
[ViewVariables]
[DataField("currentMode")]
[DataField, AutoNetworkedField]
public ImplanterToggleMode CurrentMode;
/// <summary>
/// The name and description of the implant to show on the implanter
/// </summary>
[ViewVariables]
[DataField("implantData")]
[DataField]
public (string, string) ImplantData;
/// <summary>
/// The <see cref="ItemSlot"/> for this implanter
/// </summary>
[ViewVariables]
[DataField("implanterSlot", required:true)]
[DataField(required: true)]
public ItemSlot ImplanterSlot = new();
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]
public enum ImplanterToggleMode : byte
{

View File

@@ -1,5 +1,4 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
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.
/// </summary>
[RegisterComponent, NetworkedComponent]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedInteractionSystem))]
public sealed partial class InteractionRelayComponent : Component
{
/// <summary>
/// The entity the interactions are being relayed to.
/// </summary>
[ViewVariables]
[ViewVariables, AutoNetworkedField]
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 Robust.Shared.GameStates;
namespace Content.Shared.Interaction;
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)
{
if (!Resolve(uid, ref component))
return;
component.RelayEntity = relayEntity;
Dirty(component);
Dirty(uid, component);
}
}

View File

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

View File

@@ -1,33 +1,20 @@
using System.Numerics;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Jittering
namespace Content.Shared.Jittering;
[Access(typeof(SharedJitteringSystem))]
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class JitteringComponent : Component
{
[Access(typeof(SharedJitteringSystem))]
[RegisterComponent, NetworkedComponent]
public sealed partial class JitteringComponent : Component
{
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public float Amplitude { get; set; }
[AutoNetworkedField]
[ViewVariables(VVAccess.ReadWrite)]
public float Frequency { get; set; }
[ViewVariables(VVAccess.ReadWrite)]
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.StatusEffect;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
namespace Content.Shared.Jittering
@@ -21,25 +20,9 @@ namespace Content.Shared.Jittering
public override void Initialize()
{
SubscribeLocalEvent<JitteringComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<JitteringComponent, ComponentHandleState>(OnHandleState);
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)
{
EntityManager.RemoveComponentDeferred<JitteringComponent>(uid);

View File

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

View File

@@ -1,4 +1,5 @@
using Content.Shared.Research.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Lathe;
@@ -6,13 +7,13 @@ namespace Content.Shared.Lathe;
[Serializable, NetSerializable]
public sealed class LatheUpdateState : BoundUserInterfaceState
{
public List<string> Recipes;
public List<ProtoId<LatheRecipePrototype>> Recipes;
public List<LatheRecipePrototype> Queue;
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;
Queue = queue;

View File

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

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