+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;
{
base.Open();
- List<string> accessLevels;
+ List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<AccessOverriderComponent>(Owner, out var accessOverrider))
{
else
{
- accessLevels = new List<string>();
+ accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_accessOverriderSystem.Log.Error($"No AccessOverrider component found for {EntMan.ToPrettyString(Owner)}!");
}
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);
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;
+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;
protected override void Open()
{
base.Open();
- List<string> accessLevels;
+ List<ProtoId<AccessLevelPrototype>> accessLevels;
if (EntMan.TryGetComponent<IdCardConsoleComponent>(Owner, out var idCard))
{
}
else
{
- accessLevels = new List<string>();
+ accessLevels = new List<ProtoId<AccessLevelPrototype>>();
_idCardConsoleSystem.Log.Error($"No IdCardConsole component found for {EntMan.ToPrettyString(Owner)}!");
}
private string? _lastJobProto;
public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, IPrototypeManager prototypeManager,
- List<string> accessLevels)
+ List<ProtoId<AccessLevelPrototype>> accessLevels)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
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;
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached);
- SubscribeLocalEvent<AlertsComponent, ComponentHandleState>(ClientAlertsHandleState);
+ SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
}
protected override void LoadPrototypes()
{
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)
using Content.Shared.BarSign;
using Content.Shared.Power;
using Robust.Client.GameObjects;
-using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Client.BarSign;
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");
using Content.Shared.Buckle.Components;
using Content.Shared.Vehicle.Components;
using Robust.Client.GameObjects;
-using Robust.Shared.GameStates;
namespace Content.Client.Buckle;
{
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))
return;
// Adjust draw depth when the chair faces north so that the seat back is drawn over the player.
- // Reset the draw depth when rotated in any other direction.
- // TODO when ECSing, make this a visualizer
- // This code was written before rotatable viewports were introduced, so hard-coding Direction.North
- // and comparing it against LocalRotation now breaks this in other rotations. This is a FIXME, but
- // better to get it working for most people before we look at a more permanent solution.
+ // Reset the draw depth when rotated in any other direction.
+ // TODO when ECSing, make this a visualizer
+ // This code was written before rotatable viewports were introduced, so hard-coding Direction.North
+ // and comparing it against LocalRotation now breaks this in other rotations. This is a FIXME, but
+ // better to get it working for most people before we look at a more permanent solution.
if (component is { Buckled: true, LastEntityBuckledTo: { } } &&
Transform(component.LastEntityBuckledTo.Value).LocalRotation.GetCardinalDir() == Direction.North &&
TryComp<SpriteComponent>(component.LastEntityBuckledTo, out var buckledSprite))
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;
public override void Initialize()
{
base.Initialize();
- SubscribeLocalEvent<ChameleonClothingComponent, ComponentHandleState>(HandleState);
+ SubscribeLocalEvent<ChameleonClothingComponent, AfterAutoHandleStateEvent>(HandleState);
PrepareAllVariants();
_proto.PrototypesReloaded += OnProtoReloaded;
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);
}
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)
-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;
{
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)
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)
{
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
// 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 });
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);
-
- ApplyState(uid, humanoid, Comp<SpriteComponent>(uid), state);
+ 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;
+
+ 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);
}
}
+
+ humanoid.ClientOldMarkings = new MarkingSet(humanoid.MarkingSet);
}
- private void ClearAllMarkings(EntityUid uid, HumanoidAppearanceComponent humanoid,
- SpriteComponent sprite)
+ private void ClearAllMarkings(HumanoidAppearanceComponent humanoid, SpriteComponent sprite)
{
- foreach (var markingList in humanoid.MarkingSet.Markings.Values)
+ foreach (var markingList in humanoid.ClientOldMarkings.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)
+ humanoid.ClientOldMarkings.Clear();
+
+ foreach (var markingList in humanoid.MarkingSet.Markings.Values)
{
- RemoveMarking(uid, marking, spriteComp);
+ foreach (var marking in markingList)
+ {
+ RemoveMarking(marking, sprite);
+ }
}
}
- private void RemoveMarking(EntityUid uid, Marking marking,
- SpriteComponent spriteComp)
+ private void RemoveMarking(Marking marking, SpriteComponent spriteComp)
{
if (!_markingManager.TryGetMarking(marking, out var prototype))
{
spriteComp.RemoveLayer(index);
}
}
- private void ApplyMarking(EntityUid uid,
- MarkingPrototype markingPrototype,
+ private void ApplyMarking(MarkingPrototype markingPrototype,
IReadOnlyList<Color>? colors,
bool visible,
HumanoidAppearanceComponent humanoid,
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);
}
}
}
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
-using Robust.Client.GameObjects;
-using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
-using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Client.Humanoid;
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;
using Content.Client.Items;
using Content.Shared.Implants;
using Content.Shared.Implants.Components;
-using Robust.Shared.GameStates;
namespace Content.Client.Implants;
{
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;
}
using System.Linq;
using System.Text;
-using Content.Shared.FixedPoint;
using Content.Shared.Lathe;
using Content.Shared.Materials;
using Content.Shared.Research.Prototypes;
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.
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)
using Content.Client.Interactable;
using Content.Shared.Climbing;
using Content.Shared.DragDrop;
-using Robust.Shared.GameStates;
namespace Content.Client.Movement.Systems;
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);
using Content.Shared.Points;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
-using Robust.Shared.GameStates;
namespace Content.Client.Points;
{
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();
}
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;
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;
}
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;
.Register<TabletopSystem>();
SubscribeNetworkEvent<TabletopPlayEvent>(OnTabletopPlay);
- SubscribeLocalEvent<TabletopDraggableComponent, ComponentHandleState>(HandleComponentState);
SubscribeLocalEvent<TabletopDraggableComponent, ComponentRemove>(HandleDraggableRemoved);
SubscribeLocalEvent<TabletopDraggableComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
_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)
else if (component.UnspawnedCount > 0)
{
component.UnspawnedCount--;
- ent = Spawn(component.FillProto, coordinates);
+ ent = Spawn(component.Proto, coordinates);
EnsureShootable(ent.Value);
}
+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;
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,
using System.Linq;
using Content.Shared.BarSign;
-using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
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
_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);
}
}
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;
SubscribeLocalEvent<ClimbingComponent, ClimbDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<ClimbingComponent, EndCollideEvent>(OnClimbEndCollide);
SubscribeLocalEvent<ClimbingComponent, BuckleChangeEvent>(OnBuckleChange);
- SubscribeLocalEvent<ClimbingComponent, ComponentGetState>(OnClimbingGetState);
SubscribeLocalEvent<GlassTableComponent, ClimbedOnEvent>(OnGlassClimbed);
}
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)
using Content.Shared.Prototypes;
using Content.Shared.Verbs;
using Robust.Server.GameObjects;
-using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
{
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)
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);
}
// 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
return;
if (!IsValidTarget(proto, component.Slot))
return;
- component.SelectedId = protoId;
+ component.Default = protoId;
UpdateIdentityBlocker(uid, component, proto);
UpdateVisuals(uid, component);
using Content.Shared.Cuffs;
-using JetBrains.Annotations;
using Content.Shared.Cuffs.Components;
+using JetBrains.Annotations;
using Robust.Shared.GameStates;
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
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.
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;
[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()
return;
var siemens = TryComp<InsulatedComponent>(args.Used, out var insulation)
- ? insulation.SiemensCoefficient
+ ? insulation.Coefficient
: 1;
TryDoElectrifiedAct(uid, args.User, siemens, electrified);
using Content.Shared.Mobs.Components;
using Content.Shared.Popups;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
namespace Content.Server.Implants;
InitializeImplanted();
SubscribeLocalEvent<ImplanterComponent, AfterInteractEvent>(OnImplanterAfterInteract);
- SubscribeLocalEvent<ImplanterComponent, ComponentGetState>(OnImplanterGetState);
SubscribeLocalEvent<ImplanterComponent, ImplantEvent>(OnImplant);
SubscribeLocalEvent<ImplanterComponent, DrawEvent>(OnDraw);
}
- 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)
{
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)
{
}
[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))
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();
}
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);
using Robust.Server.GameObjects;
using Robust.Server.GameStates;
using Robust.Server.Player;
-using Robust.Shared.GameStates;
using Robust.Shared.Utility;
namespace Content.Server.Points;
base.Initialize();
SubscribeLocalEvent<PointManagerComponent, ComponentStartup>(OnStartup);
- SubscribeLocalEvent<PointManagerComponent, ComponentGetState>(OnGetState);
}
private void OnStartup(EntityUid uid, PointManagerComponent component, ComponentStartup args)
_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>
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;
SubscribeLocalEvent<GeigerComponent, GotUnequippedHandEvent>(OnUnequippedHand);
SubscribeLocalEvent<RadiationSystemUpdatedEvent>(OnUpdate);
- SubscribeLocalEvent<GeigerComponent, ComponentGetState>(OnGetState);
}
private void OnActivate(EntityUid uid, GeigerComponent component, ActivateInWorldEvent args)
}
}
- 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
{
weaponComp.HitSound = comp.OnHitOff;
if (comp.Secret)
- weaponComp.HideFromExamine = true;
+ weaponComp.Hidden = true;
}
if (comp.IsSharp)
{
weaponComp.HitSound = comp.OnHitOn;
if (comp.Secret)
- weaponComp.HideFromExamine = false;
+ weaponComp.Hidden = false;
}
if (TryComp<DisarmMalusComponent>(uid, out var malus))
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;
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;
private void OnMeleeExamineDamage(EntityUid uid, MeleeWeaponComponent component, ref DamageExamineEvent args)
{
- if (component.HideFromExamine)
+ if (component.Hidden)
return;
var damageSpec = GetDamage(uid, args.User, component);
else if (component.UnspawnedCount > 0)
{
component.UnspawnedCount--;
- ent = Spawn(component.FillProto, coordinates);
+ ent = Spawn(component.Proto, coordinates);
EnsureShootable(ent.Value);
}
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;
}
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;
//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;
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))
{
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();
}
}
- [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
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
{
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]
// 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",
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
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)
_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
{
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
{
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)
_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;
- }
- }
}
}
/// 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;
}
+++ /dev/null
-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;
- }
-}
using System.Diagnostics.CodeAnalysis;
-using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared.Alert;
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
- SubscribeLocalEvent<AlertsComponent, ComponentGetState>(ClientAlertsGetState);
SubscribeNetworkEvent<ClickAlertEvent>(HandleClickAlert);
LoadPrototypes();
alert.OnClick?.AlertClicked(player.Value);
}
-
- private static void ClientAlertsGetState(EntityUid uid, AlertsComponent component, ref ComponentGetState args)
- {
- args.State = new AlertsComponentState(component.Alerts);
- }
}
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;
///
/// 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>
/// 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>
/// <remarks>
/// Wacky-Stability scale lives on in my heart. - emo
/// </remarks>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Severity = 0f;
#region Health
/// 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>
/// <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>
/// <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
/// <remarks>
/// +/- 0.2 from perfect stability (0.5)
/// </remarks>
- [DataField("initialStabilityRange")]
+ [DataField]
public (float, float) InitialStabilityRange = (0.4f, 0.6f);
/// <summary>
/// <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
/// 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
#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>
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
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;
-}
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;
{
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);
_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);
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Prototypes;
-namespace Content.Shared.BarSign
-{
- [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;
+namespace Content.Shared.BarSign;
- public BarSignComponentState(string? current)
- {
- CurrentSign = current;
- }
- }
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+public sealed partial class BarSignComponent : Component
+{
+ [DataField, AutoNetworkedField] public ProtoId<BarSignPrototype>? Current;
}
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>
[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;
- }
-}
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;
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)
}
}
- 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.
namespace Content.Shared.Buckle.Components;
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedBuckleSystem))]
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;
/// 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.
/// 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]
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;
/// 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;
/// 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);
/// 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;
/// <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>
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;
{
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);
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)
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))
using Content.Shared.Storage;
using Content.Shared.Verbs;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
namespace Content.Shared.Buckle;
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);
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)
|| !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);
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;
- }
-}
-
using Content.Shared.Verbs;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
/// <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);
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);
/// <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
{
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;
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)
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);
-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;
- }
- }
}
}
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
{
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);
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>
[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; }
- }
}
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
{
/// 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.
public EntityUid? User;
}
-[Serializable, NetSerializable]
-public sealed class ChameleonClothingComponentState : ComponentState
-{
- public string? SelectedId;
-}
-
[Serializable, NetSerializable]
public sealed class ChameleonBoundUserInterfaceState : BoundUserInterfaceState
{
// 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
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
{
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()
/// <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.
/// <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;
}
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;
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);
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
// 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;
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>
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;
}
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;
- }
-}
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>
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
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
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;
/// <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>
/// 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>
/// <summary>
/// Delay until an open door automatically closes.
/// </summary>
- [DataField("autoCloseDelay")]
+ [DataField]
public TimeSpan AutoCloseDelay = TimeSpan.FromSeconds(5f);
/// <summary>
/// <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
/// <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;
- }
-}
-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>
/// 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;
/// <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
/// 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
/// <summary>
/// The sprite state used for the door when it's open.
/// </summary>
- [DataField("openSpriteState")]
+ [DataField]
[ViewVariables(VVAccess.ReadWrite)]
public string OpenSpriteState = "open";
/// <summary>
/// The sprite state used for the door when it's closed.
/// </summary>
- [DataField("closedSpriteState")]
+ [DataField]
[ViewVariables(VVAccess.ReadWrite)]
public string ClosedSpriteState = "closed";
/// <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>
/// <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]
}
#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]
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;
- }
-}
using Content.Shared.Doors.Components;
using Content.Shared.Popups;
-using Robust.Shared.GameStates;
namespace Content.Shared.Doors.Systems;
{
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);
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;
SubscribeLocalEvent<DoorComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<DoorComponent, ComponentRemove>(OnRemove);
- SubscribeLocalEvent<DoorComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<DoorComponent, ComponentHandleState>(OnHandleState);
+ SubscribeLocalEvent<DoorComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate);
}
#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);
}
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;
}
}
using Content.Shared.Inventory;
using Content.Shared.StatusEffect;
-using Robust.Shared.GameStates;
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)
if (!Resolve(uid, ref insulated))
return;
- insulated.SiemensCoefficient = siemensCoefficient;
+ insulated.Coefficient = siemensCoefficient;
Dirty(insulated);
}
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;
- }
-
}
}
-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()
{
- public override void Initialize()
- {
- base.Initialize();
+ base.Initialize();
- SubscribeLocalEvent<EmoteAttemptEvent>(OnEmoteAttempt);
- SubscribeLocalEvent<EmotingComponent, ComponentGetState>(OnEmotingGetState);
- SubscribeLocalEvent<EmotingComponent, ComponentHandleState>(OnEmotingHandleState);
- }
-
- public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null)
- {
- if (value && !Resolve(uid, ref component))
- return;
-
- component = EnsureComp<EmotingComponent>(uid);
-
- if (component.Enabled == value)
- return;
-
- Dirty(component);
- }
-
- private void OnEmotingHandleState(EntityUid uid, EmotingComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not EmotingComponentState state)
- return;
+ SubscribeLocalEvent<EmoteAttemptEvent>(OnEmoteAttempt);
+ }
- component.Enabled = state.Enabled;
- }
+ public void SetEmoting(EntityUid uid, bool value, EmotingComponent? component = null)
+ {
+ if (value && !Resolve(uid, ref component))
+ return;
- private void OnEmotingGetState(EntityUid uid, EmotingComponent component, ref ComponentGetState args)
- {
- args.State = new EmotingComponentState(component.Enabled);
- }
+ component = EnsureComp<EmotingComponent>(uid);
- private void OnEmoteAttempt(EmoteAttemptEvent args)
- {
- if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled)
- args.Cancel();
- }
+ if (component.Enabled == value)
+ return;
- [Serializable, NetSerializable]
- private sealed class EmotingComponentState : ComponentState
- {
- public bool Enabled { get; }
+ Dirty(component);
+ }
- public EmotingComponentState(bool enabled)
- {
- Enabled = enabled;
- }
- }
+ private void OnEmoteAttempt(EmoteAttemptEvent args)
+ {
+ if (!TryComp(args.Uid, out EmotingComponent? emote) || !emote.Enabled)
+ args.Cancel();
}
}
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;
}
/// <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();
}
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;
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)
StopFollowingEntity(player, uid, followed);
}
}
-
- [Serializable, NetSerializable]
- private sealed class FollowedComponentState : ComponentState
- {
- public HashSet<NetEntity> Following = new();
- }
}
public abstract class FollowEvent : EntityEventArgs
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
{
/// 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;
- }
+ public readonly string AnimationKey = "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;
}
using System.Numerics;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
namespace Content.Shared.Gravity;
SubscribeLocalEvent<FloatingVisualsComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<GravityChangedEvent>(OnGravityChanged);
SubscribeLocalEvent<FloatingVisualsComponent, EntParentChangedMessage>(OnEntParentChanged);
- SubscribeLocalEvent<FloatingVisualsComponent, ComponentGetState>(OnComponentGetState);
- SubscribeLocalEvent<FloatingVisualsComponent, ComponentHandleState>(OnComponentHandleState);
}
/// <summary>
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;
- }
}
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-
namespace Content.Shared.Gravity;
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)
}
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;
- }
}
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:
/// 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>
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)
+ public CustomBaseLayerInfo(string? id, Color? color = null)
{
- Markings = currentMarkings;
- PermanentlyHidden = permanentlyHidden;
- HiddenLayers = hiddenLayers;
- CustomBaseLayers = customBaseLayers;
- Sex = sex;
- Gender = gender;
- Age = age;
- Species = species;
- SkinColor = skinColor;
- EyeColor = eyeColor;
+ DebugTools.Assert(id == null || IoCManager.Resolve<IPrototypeManager>().HasIndex<HumanoidSpeciesSpriteLayer>(id));
+ Id = id;
+ Color = color;
}
- [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;
- 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; }
-
- /// <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; }
- }
+ /// <summary>
+ /// ID of this custom base layer. Must be a <see cref="HumanoidSpeciesSpriteLayer"/>.
+ /// </summary>
+ [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]
+ public Color? Color { get; init; }
}
using Content.Shared.Preferences;
using Robust.Shared.Prototypes;
-using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid.Prototypes;
+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;
{
base.Initialize();
SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentInit>(OnInit);
- SubscribeLocalEvent<HumanoidAppearanceComponent, ComponentGetState>(OnGetState);
}
private void OnInit(EntityUid uid, HumanoidAppearanceComponent humanoid, ComponentInit args)
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>
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);
using Content.Shared.Humanoid.Markings;
using Robust.Shared.Serialization;
-using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Humanoid;
-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>
/// 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";
/// <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
/// 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
{
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
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;
- }
-}
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);
}
}
-using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.ActionBlocker;
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;
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;
new PointerInputCmdHandler(HandleTryPullObject))
.Register<SharedInteractionSystem>();
- InitializeRelay();
InitializeBlocking();
}
using System.Numerics;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-namespace Content.Shared.Jittering
-{
- [Access(typeof(SharedJitteringSystem))]
- [RegisterComponent, NetworkedComponent]
- public sealed partial class JitteringComponent : Component
- {
- [ViewVariables(VVAccess.ReadWrite)]
- public float Amplitude { get; set; }
-
- [ViewVariables(VVAccess.ReadWrite)]
- public float Frequency { get; set; }
+namespace Content.Shared.Jittering;
- [ViewVariables(VVAccess.ReadWrite)]
- public Vector2 LastJitter { get; set; }
- }
+[Access(typeof(SharedJitteringSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class JitteringComponent : Component
+{
+ [AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float Amplitude { get; set; }
- [Serializable, NetSerializable]
- public sealed class JitteringComponentState : ComponentState
- {
- public float Amplitude { get; }
- public float Frequency { get; }
+ [AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float Frequency { get; set; }
- public JitteringComponentState(float amplitude, float frequency)
- {
- Amplitude = amplitude;
- Frequency = frequency;
- }
- }
+ [ViewVariables(VVAccess.ReadWrite)]
+ public Vector2 LastJitter { get; set; }
}
using Content.Shared.Rejuvenate;
using Content.Shared.StatusEffect;
-using Robust.Shared.GameStates;
using Robust.Shared.Timing;
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);
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
/// <summary>
/// Whether the lathe can eject the materials stored within it
/// </summary>
- [DataField("canEjectStoredMaterials")]
+ [DataField]
public bool CanEjectStoredMaterials = true;
#region MachineUpgrading
/// <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;
{
public readonly EntityUid Lathe;
- public List<string> Recipes = new();
+ public List<ProtoId<LatheRecipePrototype>> Recipes = new();
public LatheGetRecipesEvent(EntityUid lathe)
{
using Content.Shared.Research.Prototypes;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
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;
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;
{
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)
{
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;
- }
-}
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;
- }
-}
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;
/// 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>
/// 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>
/// <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;
/// <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
{
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.Dictionary;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Materials;
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedMaterialStorageSystem))]
-[RegisterComponent, NetworkedComponent]
public sealed partial class MaterialStorageComponent : Component
{
- [DataField("storage", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, MaterialPrototype>))]
- public Dictionary<string, int> Storage { get; set; } = new();
+ [DataField, AutoNetworkedField]
+ public Dictionary<ProtoId<MaterialPrototype>, int> Storage { get; set; } = new();
/// <summary>
/// Whether or not interacting with the materialstorage inserts the material in hand.
/// </summary>
- [DataField("insertOnInteract")]
+ [DataField]
public bool InsertOnInteract = true;
/// <summary>
/// How much material the storage can store in total.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("storageLimit")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public int? StorageLimit;
/// <summary>
/// Whitelist for specifying the kind of items that can be insert into this entity.
/// </summary>
- [DataField("whitelist")]
- public EntityWhitelist? EntityWhitelist;
+ [DataField]
+ public EntityWhitelist? Whitelist;
/// <summary>
/// Whether or not to drop contained materials when deconstructed.
/// </summary>
- [DataField("dropOnDeconstruct")]
+ [DataField]
public bool DropOnDeconstruct = true;
/// <summary>
/// Whitelist generated on runtime for what specific materials can be inserted into this entity.
/// </summary>
- [DataField("materialWhiteList", customTypeSerializer: typeof(PrototypeIdListSerializer<MaterialPrototype>))]
- public List<string>? MaterialWhiteList;
+ [DataField, AutoNetworkedField]
+ public List<ProtoId<MaterialPrototype>>? MaterialWhiteList;
/// <summary>
/// Whether or not the visualization for the insertion animation
/// should ignore the color of the material being inserted.
/// </summary>
- [DataField("ignoreColor")]
+ [DataField]
public bool IgnoreColor;
/// <summary>
/// The sound that plays when inserting an item into the storage
/// </summary>
- [DataField("insertingSound")]
+ [DataField]
public SoundSpecifier? InsertingSound;
/// <summary>
/// How long the inserting animation will play
/// </summary>
- [DataField("insertionTime")]
+ [DataField]
public TimeSpan InsertionTime = TimeSpan.FromSeconds(0.79f); // 0.01 off for animation timing
}
{
public readonly EntityUid Storage = Storage;
- public List<string> Whitelist = new();
-}
-
-[Serializable, NetSerializable]
-public sealed class MaterialStorageComponentState : ComponentState
-{
- public Dictionary<string, int> Storage;
-
- public List<string>? MaterialWhitelist;
-
- public MaterialStorageComponentState(Dictionary<string, int> storage, List<string>? materialWhitelist)
- {
- Storage = storage;
- MaterialWhitelist = materialWhitelist;
- }
+ public List<ProtoId<MaterialPrototype>> Whitelist = new();
}
using Content.Shared.Mobs.Components;
using Content.Shared.Stacks;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Physics.Events;
using Robust.Shared.Timing;
/// <inheritdoc/>
public override void Initialize()
{
- SubscribeLocalEvent<MaterialReclaimerComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<MaterialReclaimerComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<MaterialReclaimerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<MaterialReclaimerComponent, EntityUnpausedEvent>(OnUnpaused);
SubscribeLocalEvent<MaterialReclaimerComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<ActiveMaterialReclaimerComponent, EntityUnpausedEvent>(OnActiveUnpaused);
}
- private void OnGetState(EntityUid uid, MaterialReclaimerComponent component, ref ComponentGetState args)
- {
- args.State = new MaterialReclaimerComponentState(component.Powered,
- component.Enabled,
- component.MaterialProcessRate,
- component.ItemsProcessed);
- }
-
- private void OnHandleState(EntityUid uid, MaterialReclaimerComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MaterialReclaimerComponentState state)
- return;
- component.Powered = state.Powered;
- component.Enabled = state.Enabled;
- component.MaterialProcessRate = state.MaterialProcessRate;
- component.ItemsProcessed = state.ItemsProcessed;
- }
-
private void OnShutdown(EntityUid uid, MaterialReclaimerComponent component, ComponentShutdown args)
{
component.Stream?.Stop();
using Content.Shared.Interaction.Components;
using Content.Shared.Stacks;
using JetBrains.Annotations;
-using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
SubscribeLocalEvent<MaterialStorageComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<MaterialStorageComponent, InteractUsingEvent>(OnInteractUsing);
- SubscribeLocalEvent<MaterialStorageComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<MaterialStorageComponent, ComponentHandleState>(OnHandleState);
- SubscribeLocalEvent<InsertingMaterialStorageComponent, ComponentGetState>(OnGetInsertingState);
- SubscribeLocalEvent<InsertingMaterialStorageComponent, ComponentHandleState>(OnHandleInsertingState);
SubscribeLocalEvent<InsertingMaterialStorageComponent, EntityUnpausedEvent>(OnUnpaused);
}
_appearance.SetData(uid, MaterialStorageVisuals.Inserting, false);
}
- private void OnGetState(EntityUid uid, MaterialStorageComponent component, ref ComponentGetState args)
- {
- args.State = new MaterialStorageComponentState(component.Storage, component.MaterialWhiteList);
- }
-
- private void OnHandleState(EntityUid uid, MaterialStorageComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MaterialStorageComponentState state)
- return;
-
- component.Storage = new Dictionary<string, int>(state.Storage);
-
- if (state.MaterialWhitelist != null)
- component.MaterialWhiteList = new List<string>(state.MaterialWhitelist);
- }
-
- private void OnGetInsertingState(EntityUid uid, InsertingMaterialStorageComponent component, ref ComponentGetState args)
- {
- args.State = new InsertingMaterialStorageComponentState(component.EndTime, component.MaterialColor);
- }
-
- private void OnHandleInsertingState(EntityUid uid, InsertingMaterialStorageComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not InsertingMaterialStorageComponentState state)
- return;
-
- component.EndTime = state.EndTime;
- component.MaterialColor = state.MaterialColor;
- }
-
private void OnUnpaused(EntityUid uid, InsertingMaterialStorageComponent component, ref EntityUnpausedEvent args)
{
component.EndTime += args.PausedTime;
if (!Resolve(toInsert, ref material, ref composition, false))
return false;
- if (storage.EntityWhitelist?.IsValid(toInsert) == false)
+ if (storage.Whitelist?.IsValid(toInsert) == false)
return false;
if (HasComp<UnremoveableComponent>(toInsert))
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Mech.Components;
/// A large, pilotable machine that has equipment that is
/// powered via an internal battery.
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MechComponent : Component
{
/// <summary>
/// How much "health" the mech has left.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public FixedPoint2 Integrity;
/// <summary>
/// The maximum amount of damage the mech can take.
/// </summary>
- [DataField("maxIntegrity")]
+ [DataField, AutoNetworkedField]
public FixedPoint2 MaxIntegrity = 250;
/// <summary>
/// How much energy the mech has.
/// Derived from the currently inserted battery.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public FixedPoint2 Energy = 0;
/// <summary>
/// The maximum amount of energy the mech can have.
/// Derived from the currently inserted battery.
/// </summary>
- [DataField("maxEnergy")]
+ [DataField, AutoNetworkedField]
public FixedPoint2 MaxEnergy = 0;
/// <summary>
/// A multiplier used to calculate how much of the damage done to a mech
/// is transfered to the pilot
/// </summary>
- [DataField("mechToPilotDamageMultiplier")]
+ [DataField]
public float MechToPilotDamageMultiplier;
/// <summary>
/// Whether the mech has been destroyed and is no longer pilotable.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public bool Broken = false;
/// <summary>
/// The current selected equipment of the mech.
/// If null, the mech is using just its fists.
/// </summary>
- [ViewVariables]
+ [ViewVariables, AutoNetworkedField]
public EntityUid? CurrentSelectedEquipment;
/// <summary>
/// <summary>
/// A whitelist for inserting equipment items.
/// </summary>
- [DataField("equipmentWhitelist")]
+ [DataField]
public EntityWhitelist? EquipmentWhitelist;
- [DataField("pilotWhitelist")]
+ [DataField]
public EntityWhitelist? PilotWhitelist;
/// <summary>
/// <summary>
/// How long it takes to enter the mech.
/// </summary>
- [DataField("entryDelay")]
+ [DataField]
public float EntryDelay = 3;
/// <summary>
/// How long it takes to pull *another person*
/// outside of the mech. You can exit instantly yourself.
/// </summary>
- [DataField("exitDelay")]
+ [DataField]
public float ExitDelay = 3;
/// <summary>
/// How long it takes to pull out the battery.
/// </summary>
- [DataField("batteryRemovalDelay")]
+ [DataField]
public float BatteryRemovalDelay = 2;
/// <summary>
/// This needs to be redone
/// when mech internals are added
/// </remarks>
- [DataField("airtight"), ViewVariables(VVAccess.ReadWrite)]
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
public bool Airtight;
/// <summary>
/// The equipment that the mech initially has when it spawns.
/// Good for things like nukie mechs that start with guns.
/// </summary>
- [DataField("startingEquipment", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
- public List<string> StartingEquipment = new();
+ [DataField]
+ public List<EntProtoId> StartingEquipment = new();
#region Action Prototypes
- [DataField("mechCycleAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string MechCycleAction = "ActionMechCycleEquipment";
- [DataField("mechUiAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string MechUiAction = "ActionMechOpenUI";
- [DataField("mechEjectAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string MechEjectAction = "ActionMechEject";
+ [DataField]
+ public EntProtoId MechCycleAction = "ActionMechCycleEquipment";
+ [DataField]
+ public EntProtoId MechUiAction = "ActionMechOpenUI";
+ [DataField]
+ public EntProtoId MechEjectAction = "ActionMechEject";
#endregion
#region Visualizer States
- [DataField("baseState")]
+ [DataField]
public string? BaseState;
- [DataField("openState")]
+ [DataField]
public string? OpenState;
- [DataField("brokenState")]
+ [DataField]
public string? BrokenState;
#endregion
[DataField] public EntityUid? MechUiActionEntity;
[DataField] public EntityUid? MechEjectActionEntity;
}
-
-/// <summary>
-/// Contains network state for <see cref="MechComponent"/>.
-/// </summary>
-[Serializable, NetSerializable]
-public sealed class MechComponentState : ComponentState
-{
- public FixedPoint2 Integrity;
- public FixedPoint2 MaxIntegrity;
- public FixedPoint2 Energy;
- public FixedPoint2 MaxEnergy;
- public NetEntity? CurrentSelectedEquipment;
- public bool Broken;
-}
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Mech.Components;
/// <remarks>
/// Get in the robot, Shinji
/// </remarks>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MechPilotComponent : Component
{
/// <summary>
/// The mech being piloted
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public EntityUid Mech;
}
-
-[Serializable, NetSerializable]
-public sealed class MechPilotComponentState : ComponentState
-{
- public NetEntity Mech;
-}
using Content.Shared.Popups;
using Content.Shared.Weapons.Melee;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
/// <inheritdoc/>
public override void Initialize()
{
- SubscribeLocalEvent<MechComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<MechComponent, ComponentHandleState>(OnHandleState);
- SubscribeLocalEvent<MechPilotComponent, ComponentGetState>(OnPilotGetState);
- SubscribeLocalEvent<MechPilotComponent, ComponentHandleState>(OnPilotHandleState);
-
SubscribeLocalEvent<MechComponent, MechToggleEquipmentEvent>(OnToggleEquipmentAction);
SubscribeLocalEvent<MechComponent, MechEjectPilotEvent>(OnEjectPilotEvent);
SubscribeLocalEvent<MechComponent, InteractNoHandEvent>(RelayInteractionEvent);
SubscribeLocalEvent<MechPilotComponent, AttackAttemptEvent>(OnAttackAttempt);
}
- #region State Handling
-
- private void OnGetState(EntityUid uid, MechComponent component, ref ComponentGetState args)
- {
- args.State = new MechComponentState
- {
- Integrity = component.Integrity,
- MaxIntegrity = component.MaxIntegrity,
- Energy = component.Energy,
- MaxEnergy = component.MaxEnergy,
- CurrentSelectedEquipment = GetNetEntity(component.CurrentSelectedEquipment),
- Broken = component.Broken
- };
- }
-
- private void OnHandleState(EntityUid uid, MechComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MechComponentState state)
- return;
-
- component.Integrity = state.Integrity;
- component.MaxIntegrity = state.MaxIntegrity;
- component.Energy = state.Energy;
- component.MaxEnergy = state.MaxEnergy;
- component.CurrentSelectedEquipment = EnsureEntity<MechComponent>(state.CurrentSelectedEquipment, uid);
- component.Broken = state.Broken;
- }
-
- private void OnPilotGetState(EntityUid uid, MechPilotComponent component, ref ComponentGetState args)
- {
- args.State = new MechPilotComponentState
- {
- Mech = GetNetEntity(component.Mech)
- };
- }
-
- private void OnPilotHandleState(EntityUid uid, MechPilotComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MechPilotComponentState state)
- return;
-
- component.Mech = EnsureEntity<MechPilotComponent>(state.Mech, uid);
- }
-
- #endregion
-
private void OnToggleEquipmentAction(EntityUid uid, MechComponent component, MechToggleEquipmentEvent args)
{
if (args.Handled)
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
-namespace Content.Shared.Movement.Components
+namespace Content.Shared.Movement.Components;
+
+/// <summary>
+/// Changes footstep sound
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class FootstepModifierComponent : Component
{
- /// <summary>
- /// Changes footstep sound
- /// </summary>
- [RegisterComponent, NetworkedComponent]
- public sealed partial class FootstepModifierComponent : Component
- {
- [DataField("footstepSoundCollection", required: true)]
- public SoundSpecifier Sound = default!;
- }
+ [DataField(required: true), AutoNetworkedField]
+ public SoundSpecifier FootstepSoundCollection = default!;
}
namespace Content.Shared.Movement.Components
{
- [RegisterComponent]
- [NetworkedComponent]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
public sealed partial class InputMoverComponent : Component
{
// This class has to be able to handle server TPS being lower than client FPS.
public Vector2 CurTickWalkMovement;
public Vector2 CurTickSprintMovement;
+ [AutoNetworkedField]
public MoveButtons HeldMoveButtons = MoveButtons.None;
/// <summary>
/// Entity our movement is relative to.
/// </summary>
+ [AutoNetworkedField]
public EntityUid? RelativeEntity;
/// <summary>
/// Although our movement might be relative to a particular entity we may have an additional relative rotation
/// e.g. if we've snapped to a different cardinal direction
/// </summary>
- [ViewVariables]
+ [ViewVariables, AutoNetworkedField]
public Angle TargetRelativeRotation = Angle.Zero;
/// <summary>
/// The current relative rotation. This will lerp towards the <see cref="TargetRelativeRotation"/>.
/// </summary>
- [ViewVariables] public Angle RelativeRotation;
+ [ViewVariables, AutoNetworkedField]
+ public Angle RelativeRotation;
/// <summary>
/// If we traverse on / off a grid then set a timer to update our relative inputs.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("lerpTarget", customTypeSerializer: typeof(TimeOffsetSerializer))]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan LerpTarget;
public const float LerpTime = 1.0f;
public bool Sprinting => (HeldMoveButtons & MoveButtons.Walk) == 0x0;
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public bool CanMove { get; set; } = true;
}
}
/// <summary>
/// Added to someone using a jetpack for movement purposes
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class JetpackUserComponent : Component
{
+ [AutoNetworkedField]
public EntityUid Jetpack;
}
/// <summary>
/// Has additional movement data such as footsteps and weightless grab range for an entity.
/// </summary>
- [RegisterComponent]
- [NetworkedComponent()]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MobMoverComponent : Component
{
private float _stepSoundDistance;
- [DataField("grabRange")] public float GrabRange = 1.0f;
+ [DataField] public float GrabRange = 1.0f;
- [DataField("pushStrength")] public float PushStrength = 600f;
+ [DataField] public float PushStrength = 600f;
[ViewVariables(VVAccess.ReadWrite)]
public EntityCoordinates LastPosition { get; set; }
}
}
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float GrabRangeVV
{
get => GrabRange;
}
}
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float PushStrengthVV
{
get => PushStrength;
/// Applies basic movement speed and movement modifiers for an entity.
/// If this is not present on the entity then they will use defaults for movement.
/// </summary>
- [RegisterComponent]
- [NetworkedComponent, Access(typeof(MovementSpeedModifierSystem))]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+ [Access(typeof(MovementSpeedModifierSystem))]
public sealed partial class MovementSpeedModifierComponent : Component
{
// Weightless
public const float DefaultBaseWalkSpeed = 2.5f;
public const float DefaultBaseSprintSpeed = 4.5f;
- [ViewVariables]
+ [AutoNetworkedField, ViewVariables]
public float WalkSpeedModifier = 1.0f;
- [ViewVariables]
+ [AutoNetworkedField, ViewVariables]
public float SprintSpeedModifier = 1.0f;
[ViewVariables(VVAccess.ReadWrite)]
/// <summary>
/// Minimum speed a mob has to be moving before applying movement friction.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("minimumFrictionSpeed")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float MinimumFrictionSpeed = DefaultMinimumFrictionSpeed;
/// <summary>
/// The negative velocity applied for friction when weightless and providing inputs.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("weightlessFriction")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float WeightlessFriction = DefaultWeightlessFriction;
/// <summary>
/// The negative velocity applied for friction when weightless and not providing inputs.
/// This is essentially how much their speed decreases per second.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("weightlessFrictionNoInput")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float WeightlessFrictionNoInput = DefaultWeightlessFrictionNoInput;
/// <summary>
/// The movement speed modifier applied to a mob's total input velocity when weightless.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("weightlessModifier")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float WeightlessModifier = DefaultWeightlessModifier;
/// <summary>
/// The acceleration applied to mobs when moving and weightless.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("weightlessAcceleration")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float WeightlessAcceleration = DefaultWeightlessAcceleration;
/// <summary>
/// The acceleration applied to mobs when moving.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("acceleration")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float Acceleration = DefaultAcceleration;
/// <summary>
/// The negative velocity applied for friction.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("friction")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public float Friction = DefaultFriction;
/// <summary>
/// The negative velocity applied for friction.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("frictionNoInput")] public float? FrictionNoInput = null;
+ [ViewVariables(VVAccess.ReadWrite), DataField]
+ public float? FrictionNoInput;
- [ViewVariables(VVAccess.ReadWrite), DataField("baseWalkSpeed")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float BaseWalkSpeed { get; set; } = DefaultBaseWalkSpeed;
- [ViewVariables(VVAccess.ReadWrite), DataField("baseSprintSpeed")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float BaseSprintSpeed { get; set; } = DefaultBaseSprintSpeed;
[ViewVariables]
using Content.Shared.Inventory;
using Content.Shared.Movement.Components;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
using Robust.Shared.Timing;
-using Robust.Shared.Utility;
namespace Content.Shared.Movement.Systems
{
{
[Dependency] private readonly IGameTiming _timing = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<MovementSpeedModifierComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<MovementSpeedModifierComponent, ComponentHandleState>(OnHandleState);
- }
-
- private void OnGetState(EntityUid uid, MovementSpeedModifierComponent component, ref ComponentGetState args)
- {
- args.State = new MovementSpeedModifierComponentState
- {
- BaseWalkSpeed = component.BaseWalkSpeed,
- BaseSprintSpeed = component.BaseSprintSpeed,
- WalkSpeedModifier = component.WalkSpeedModifier,
- SprintSpeedModifier = component.SprintSpeedModifier,
- };
- }
-
- private void OnHandleState(EntityUid uid, MovementSpeedModifierComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MovementSpeedModifierComponentState state) return;
- component.BaseWalkSpeed = state.BaseWalkSpeed;
- component.BaseSprintSpeed = state.BaseSprintSpeed;
- component.WalkSpeedModifier = state.WalkSpeedModifier;
- component.SprintSpeedModifier = state.SprintSpeedModifier;
- }
-
public void RefreshMovementSpeedModifiers(EntityUid uid, MovementSpeedModifierComponent? move = null)
{
if (!Resolve(uid, ref move, false))
move.Acceleration = acceleration;
Dirty(move);
}
-
- [Serializable, NetSerializable]
- private sealed class MovementSpeedModifierComponentState : ComponentState
- {
- public float BaseWalkSpeed;
- public float BaseSprintSpeed;
- public float WalkSpeedModifier;
- public float SprintSpeedModifier;
- }
}
/// <summary>
using Content.Shared.Movement.Events;
using Content.Shared.Popups;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization;
SubscribeLocalEvent<JetpackUserComponent, CanWeightlessMoveEvent>(OnJetpackUserCanWeightless);
SubscribeLocalEvent<JetpackUserComponent, EntParentChangedMessage>(OnJetpackUserEntParentChanged);
- SubscribeLocalEvent<JetpackUserComponent, ComponentGetState>(OnJetpackUserGetState);
- SubscribeLocalEvent<JetpackUserComponent, ComponentHandleState>(OnJetpackUserHandleState);
SubscribeLocalEvent<GravityChangedEvent>(OnJetpackUserGravityChanged);
}
}
}
- private void OnJetpackUserHandleState(EntityUid uid, JetpackUserComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not JetpackUserComponentState state)
- return;
-
- component.Jetpack = EnsureEntity<JetpackUserComponent>(state.Jetpack, uid);
- }
-
- private void OnJetpackUserGetState(EntityUid uid, JetpackUserComponent component, ref ComponentGetState args)
- {
- args.State = new JetpackUserComponentState()
- {
- Jetpack = GetNetEntity(component.Jetpack),
- };
- }
-
private void OnJetpackDropped(EntityUid uid, JetpackComponent component, DroppedEvent args)
{
SetEnabled(uid, component, false, args.User);
{
return true;
}
-
- [Serializable, NetSerializable]
- protected sealed class JetpackUserComponentState : ComponentState
- {
- public NetEntity Jetpack;
- }
}
[Serializable, NetSerializable]
+++ /dev/null
-using Content.Shared.Movement.Components;
-using Robust.Shared.Audio;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Movement.Systems;
-
-public abstract partial class SharedMoverController
-{
- private void InitializeFootsteps()
- {
- SubscribeLocalEvent<FootstepModifierComponent, ComponentGetState>(OnFootGetState);
- SubscribeLocalEvent<FootstepModifierComponent, ComponentHandleState>(OnFootHandleState);
- }
-
- private void OnFootHandleState(EntityUid uid, FootstepModifierComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not FootstepModifierComponentState state) return;
- component.Sound = state.Sound;
- }
-
- private void OnFootGetState(EntityUid uid, FootstepModifierComponent component, ref ComponentGetState args)
- {
- args.State = new FootstepModifierComponentState()
- {
- Sound = component.Sound,
- };
- }
-
- [Serializable, NetSerializable]
- private sealed class FootstepModifierComponentState : ComponentState
- {
- public SoundSpecifier Sound = default!;
- }
-}
using Content.Shared.Input;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events;
-using Robust.Shared.GameStates;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Players;
.Register<SharedMoverController>();
SubscribeLocalEvent<InputMoverComponent, ComponentInit>(OnInputInit);
- SubscribeLocalEvent<InputMoverComponent, ComponentGetState>(OnInputGetState);
- SubscribeLocalEvent<InputMoverComponent, ComponentHandleState>(OnInputHandleState);
+ SubscribeLocalEvent<InputMoverComponent, AfterAutoHandleStateEvent>(OnInputHandleState);
SubscribeLocalEvent<InputMoverComponent, EntParentChangedMessage>(OnInputParentChange);
SubscribeLocalEvent<AutoOrientComponent, EntParentChangedMessage>(OnAutoParentChange);
Dirty(component);
}
- private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref ComponentHandleState args)
+ private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref AfterAutoHandleStateEvent args)
{
- if (args.Current is not InputMoverComponentState state)
- return;
-
- component.HeldMoveButtons = state.Buttons;
component.LastInputTick = GameTick.Zero;
component.LastInputSubTick = 0;
- component.CanMove = state.CanMove;
-
- component.RelativeRotation = state.RelativeRotation;
- component.TargetRelativeRotation = state.TargetRelativeRotation;
- component.RelativeEntity = EnsureEntity<InputMoverComponent>(state.RelativeEntity, uid);
- component.LerpTarget = state.LerpAccumulator;
- }
-
- private void OnInputGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args)
- {
- args.State = new InputMoverComponentState(
- component.HeldMoveButtons,
- component.CanMove,
- component.RelativeRotation,
- component.TargetRelativeRotation,
- GetNetEntity(component.RelativeEntity),
- component.LerpTarget);
}
private void ShutdownInput()
}
}
- [Serializable, NetSerializable]
- private sealed class InputMoverComponentState : ComponentState
- {
- public MoveButtons Buttons { get; }
- public readonly bool CanMove;
-
- /// <summary>
- /// Our current rotation for movement purposes. This is lerping towards <see cref="TargetRelativeRotation"/>
- /// </summary>
- public Angle RelativeRotation;
-
- /// <summary>
- /// Target rotation relative to the <see cref="RelativeEntity"/>. Typically 0
- /// </summary>
- public Angle TargetRelativeRotation;
- public NetEntity? RelativeEntity;
- public TimeSpan LerpAccumulator;
-
- public InputMoverComponentState(MoveButtons buttons, bool canMove, Angle relativeRotation, Angle targetRelativeRotation, NetEntity? relativeEntity, TimeSpan lerpTarget)
- {
- Buttons = buttons;
- CanMove = canMove;
- RelativeRotation = relativeRotation;
- TargetRelativeRotation = targetRelativeRotation;
- RelativeEntity = relativeEntity;
- LerpAccumulator = lerpTarget;
- }
- }
-
private sealed class ShuttleInputCmdHandler : InputCmdHandler
{
private readonly SharedMoverController _controller;
}
[Flags]
+ [Serializable, NetSerializable]
public enum MoveButtons : byte
{
None = 0,
+++ /dev/null
-using Content.Shared.Movement.Components;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Movement.Systems;
-
-public abstract partial class SharedMoverController
-{
- private void InitializeMob()
- {
- SubscribeLocalEvent<MobMoverComponent, ComponentGetState>(OnMobGetState);
- SubscribeLocalEvent<MobMoverComponent, ComponentHandleState>(OnMobHandleState);
- }
-
- private void OnMobHandleState(EntityUid uid, MobMoverComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MobMoverComponentState state) return;
- component.GrabRangeVV = state.GrabRange;
- component.PushStrengthVV = state.PushStrength;
- }
-
- private void OnMobGetState(EntityUid uid, MobMoverComponent component, ref ComponentGetState args)
- {
- args.State = new MobMoverComponentState(component.GrabRange, component.PushStrength);
- }
-
- [Serializable, NetSerializable]
- private sealed class MobMoverComponentState : ComponentState
- {
- public float GrabRange;
- public float PushStrength;
-
- public MobMoverComponentState(float grabRange, float pushStrength)
- {
- GrabRange = grabRange;
- PushStrength = pushStrength;
- }
- }
-}
+using System.Diagnostics.CodeAnalysis;
+using System.Numerics;
+using Content.Shared.Bed.Sleep;
using Content.Shared.CCVar;
using Content.Shared.Friction;
using Content.Shared.Gravity;
using Content.Shared.Inventory;
using Content.Shared.Maps;
+using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Pulling.Components;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Physics;
+using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Controllers;
+using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
-using System.Diagnostics.CodeAnalysis;
-using System.Numerics;
-using Content.Shared.Mobs.Systems;
-using Robust.Shared.Physics.Components;
-using Robust.Shared.Physics.Systems;
-using Content.Shared.Bed.Sleep;
namespace Content.Shared.Movement.Systems
{
NoRotateQuery = GetEntityQuery<NoRotateOnMoveComponent>();
CanMoveInAirQuery = GetEntityQuery<CanMoveInAirComponent>();
- InitializeFootsteps();
InitializeInput();
- InitializeMob();
InitializeRelay();
_configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true);
_configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true);
if (TryComp<FootstepModifierComponent>(uid, out var moverModifier))
{
- sound = moverModifier.Sound;
+ sound = moverModifier.FootstepSoundCollection;
return true;
}
if (_inventory.TryGetSlotEntity(uid, "shoes", out var shoes) &&
TryComp<FootstepModifierComponent>(shoes, out var modifier))
{
- sound = modifier.Sound;
+ sound = modifier.FootstepSoundCollection;
return true;
}
{
if (TryComp<FootstepModifierComponent>(xform.MapUid, out var modifier))
{
- sound = modifier.Sound;
+ sound = modifier.FootstepSoundCollection;
return true;
}
if (TryComp<FootstepModifierComponent>(maybeFootstep, out var footstep))
{
- sound = footstep.Sound;
+ sound = footstep.FootstepSoundCollection;
return true;
}
}
using Content.Shared.Conveyor;
using Content.Shared.Gravity;
using Content.Shared.Movement.Systems;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
public override void Initialize()
{
UpdatesAfter.Add(typeof(SharedMoverController));
- SubscribeLocalEvent<ConveyorComponent, ComponentGetState>(OnConveyorGetState);
- SubscribeLocalEvent<ConveyorComponent, ComponentHandleState>(OnConveyorHandleState);
SubscribeLocalEvent<ConveyorComponent, StartCollideEvent>(OnConveyorStartCollide);
SubscribeLocalEvent<ConveyorComponent, EndCollideEvent>(OnConveyorEndCollide);
base.Initialize();
}
- private void OnConveyorGetState(EntityUid uid, ConveyorComponent component, ref ComponentGetState args)
- {
- args.State = new ConveyorComponentState(component.Angle, component.Speed, component.State, component.Powered);
- }
-
- private void OnConveyorHandleState(EntityUid uid, ConveyorComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not ConveyorComponentState state)
- return;
-
- component.Powered = state.Powered;
- component.Angle = state.Angle;
- component.Speed = state.Speed;
- component.State = state.State;
- }
-
private void OnConveyorStartCollide(EntityUid uid, ConveyorComponent component, ref StartCollideEvent args)
{
var otherUid = args.OtherEntity;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Physics;
/// <summary>
/// Use this to allow a specific UID to prevent collides
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class PreventCollideComponent : Component
{
+ [AutoNetworkedField]
public EntityUid Uid;
}
-[Serializable, NetSerializable]
-public sealed class PreventCollideComponentState : ComponentState
-{
- public NetEntity Uid;
-
- public PreventCollideComponentState(NetEntity netEntity)
- {
- Uid = netEntity;
- }
-}
-using Robust.Shared.GameStates;
-using Robust.Shared.Physics.Dynamics;
-using Robust.Shared.Physics.Events;
+using Robust.Shared.Physics.Events;
namespace Content.Shared.Physics;
{
base.Initialize();
- SubscribeLocalEvent<PreventCollideComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<PreventCollideComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<PreventCollideComponent, PreventCollideEvent>(OnPreventCollide);
}
- private void OnGetState(EntityUid uid, PreventCollideComponent component, ref ComponentGetState args)
- {
- args.State = new PreventCollideComponentState(GetNetEntity(component.Uid));
- }
-
- private void OnHandleState(EntityUid uid, PreventCollideComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not PreventCollideComponentState state)
- return;
-
- component.Uid = EnsureEntity<PreventCollideComponent>(state.Uid, uid);
- }
-
private void OnPreventCollide(EntityUid uid, PreventCollideComponent component, ref PreventCollideEvent args)
{
if (component.Uid == args.OtherEntity)
/// <summary>
/// Detects items placed on it that match a whitelist.
/// </summary>
-[RegisterComponent, NetworkedComponent, Access(typeof(ItemPlacerSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(ItemPlacerSystem))]
public sealed partial class ItemPlacerComponent : Component
{
/// <summary>
/// The entities that are currently on top of the placer.
/// Guaranteed to have less than <see cref="MaxEntities"/> enitities if it is set.
/// </summary>
- [DataField("placedEntities")]
+ [DataField, AutoNetworkedField]
public HashSet<EntityUid> PlacedEntities = new();
/// <summary>
/// Whitelist for entities that can be placed.
/// </summary>
- [DataField("whitelist"), ViewVariables(VVAccess.ReadWrite)]
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
public EntityWhitelist? Whitelist;
/// <summary>
/// The max amount of entities that can be placed at the same time.
/// If 0, there is no limit.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("maxEntities")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public uint MaxEntities = 1;
}
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
-using System.Linq;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Placeable;
SubscribeLocalEvent<ItemPlacerComponent, StartCollideEvent>(OnStartCollide);
SubscribeLocalEvent<ItemPlacerComponent, EndCollideEvent>(OnEndCollide);
- SubscribeLocalEvent<ItemPlacerComponent, ComponentGetState>(OnPlacerGetState);
- SubscribeLocalEvent<ItemPlacerComponent, ComponentHandleState>(OnPlacerHandleState);
- }
-
- private void OnPlacerHandleState(EntityUid uid, ItemPlacerComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not ItemPlacerComponentState state)
- return;
-
- component.MaxEntities = state.MaxEntities;
- component.PlacedEntities.Clear();
- var ents = EnsureEntitySet<ItemPlacerComponent>(state.Entities, uid);
- component.PlacedEntities.UnionWith(ents);
- }
-
- private void OnPlacerGetState(EntityUid uid, ItemPlacerComponent component, ref ComponentGetState args)
- {
- args.State = new ItemPlacerComponentState()
- {
- MaxEntities = component.MaxEntities,
- Entities = GetNetEntitySet(component.PlacedEntities),
- };
}
private void OnStartCollide(EntityUid uid, ItemPlacerComponent comp, ref StartCollideEvent args)
_placeableSurface.SetPlaceable(uid, true);
}
-
- [Serializable, NetSerializable]
- private sealed class ItemPlacerComponentState : ComponentState
- {
- public uint MaxEntities;
- public HashSet<NetEntity> Entities = default!;
- }
}
/// <summary>
using System.Numerics;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-namespace Content.Shared.Placeable
-{
- [RegisterComponent, NetworkedComponent]
- [Access(typeof(PlaceableSurfaceSystem))]
- public sealed partial class PlaceableSurfaceComponent : Component
- {
- [DataField("isPlaceable")]
- public bool IsPlaceable { get; set; } = true;
-
- [DataField("placeCentered")]
- public bool PlaceCentered { get; set; }
+namespace Content.Shared.Placeable;
- [DataField("positionOffset")]
- public Vector2 PositionOffset { get; set; }
- }
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(PlaceableSurfaceSystem))]
+public sealed partial class PlaceableSurfaceComponent : Component
+{
+ [DataField, AutoNetworkedField]
+ public bool IsPlaceable { get; set; } = true;
- [Serializable, NetSerializable]
- public sealed class PlaceableSurfaceComponentState : ComponentState
- {
- public readonly bool IsPlaceable;
- public readonly bool PlaceCentered;
- public readonly Vector2 PositionOffset;
+ [DataField, AutoNetworkedField]
+ public bool PlaceCentered { get; set; }
- public PlaceableSurfaceComponentState(bool placeable, bool centered, Vector2 offset)
- {
- IsPlaceable = placeable;
- PlaceCentered = centered;
- PositionOffset = offset;
- }
- }
+ [DataField, AutoNetworkedField]
+ public Vector2 PositionOffset { get; set; }
}
using System.Numerics;
-using Content.Shared.Storage.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
-using Robust.Shared.GameStates;
+using Content.Shared.Storage.Components;
namespace Content.Shared.Placeable
{
base.Initialize();
SubscribeLocalEvent<PlaceableSurfaceComponent, AfterInteractUsingEvent>(OnAfterInteractUsing);
- SubscribeLocalEvent<PlaceableSurfaceComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<PlaceableSurfaceComponent, ComponentHandleState>(OnHandleState);
- }
-
- private void OnGetState(EntityUid uid, PlaceableSurfaceComponent component, ref ComponentGetState args)
- {
- args.State = new PlaceableSurfaceComponentState(component.IsPlaceable, component.PlaceCentered, component.PositionOffset);
}
public void SetPlaceable(EntityUid uid, bool isPlaceable, PlaceableSurfaceComponent? surface = null)
return;
surface.IsPlaceable = isPlaceable;
- Dirty(surface);
+ Dirty(uid, surface);
}
public void SetPlaceCentered(EntityUid uid, bool placeCentered, PlaceableSurfaceComponent? surface = null)
return;
surface.PlaceCentered = placeCentered;
- Dirty(surface);
+ Dirty(uid, surface);
}
public void SetPositionOffset(EntityUid uid, Vector2 offset, PlaceableSurfaceComponent? surface = null)
return;
surface.PositionOffset = offset;
- Dirty(surface);
+ Dirty(uid, surface);
}
private void OnAfterInteractUsing(EntityUid uid, PlaceableSurfaceComponent surface, AfterInteractUsingEvent args)
args.Handled = true;
}
-
- private void OnHandleState(EntityUid uid, PlaceableSurfaceComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not PlaceableSurfaceComponentState state)
- return;
-
- component.IsPlaceable = state.IsPlaceable;
- component.PlaceCentered = state.PlaceCentered;
- component.PositionOffset = state.PositionOffset;
- }
}
}
using Content.Shared.FixedPoint;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
-using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared.Points;
/// <summary>
/// This is a component that generically stores points for all players.
/// </summary>
-[RegisterComponent, NetworkedComponent, Access(typeof(SharedPointSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+[Access(typeof(SharedPointSystem))]
public sealed partial class PointManagerComponent : Component
{
/// <summary>
/// A dictionary of a player's netuserID to the amount of points they have.
/// </summary>
- [DataField("points")]
+ [DataField, AutoNetworkedField(true)]
public Dictionary<NetUserId, FixedPoint2> Points = new();
/// <summary>
/// A text-only version of the scoreboard used by the client.
/// </summary>
- [DataField("scoreboard")]
+ [DataField, AutoNetworkedField]
public FormattedMessage Scoreboard = new();
}
-
-[Serializable, NetSerializable]
-public sealed class PointManagerComponentState : ComponentState
-{
- public Dictionary<NetUserId, FixedPoint2> Points;
-
- public FormattedMessage Scoreboard;
-
- public PointManagerComponentState(Dictionary<NetUserId, FixedPoint2> points, FormattedMessage scoreboard)
- {
- Points = points;
- Scoreboard = scoreboard;
- }
-}
/// Geiger counter that shows current radiation level.
/// Can be added as a component to clothes.
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(SharedGeigerSystem))]
public sealed partial class GeigerComponent : Component
{
/// <summary>
/// If true it will be active only when player equipped it.
/// </summary>
- [DataField("attachedToSuit")]
+ [DataField]
public bool AttachedToSuit;
/// <summary>
/// Is geiger counter currently active?
/// If false attached entity will ignore any radiation rays.
/// </summary>
- [DataField("isEnabled")]
+ [DataField, AutoNetworkedField]
public bool IsEnabled;
/// <summary>
/// Should it shows examine message with current radiation level?
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("showExamine")]
+ [DataField]
public bool ShowExamine;
/// <summary>
/// Should it shows item control when equipped by player?
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("showControl")]
+ [DataField]
public bool ShowControl;
/// <summary>
/// Map of sounds that should be play on loop for different radiation levels.
/// </summary>
- [DataField("sounds")]
+ [DataField]
public Dictionary<GeigerDangerLevel, SoundSpecifier> Sounds = new()
{
{GeigerDangerLevel.Low, new SoundPathSpecifier("/Audio/Items/Geiger/low.ogg")},
/// <summary>
/// Current radiation level in rad per second.
/// </summary>
- [ViewVariables(VVAccess.ReadOnly)]
+ [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public float CurrentRadiation;
/// <summary>
/// Estimated radiation danger level.
/// </summary>
- [ViewVariables(VVAccess.ReadOnly)]
+ [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public GeigerDangerLevel DangerLevel = GeigerDangerLevel.None;
/// <summary>
/// Because sound is annoying, geiger counter clicks will play
/// only for player that equipped it.
/// </summary>
- [ViewVariables(VVAccess.ReadOnly)]
+ [ViewVariables(VVAccess.ReadOnly), AutoNetworkedField]
public EntityUid? User;
/// <summary>
public IPlayingAudioStream? Stream;
}
-[Serializable, NetSerializable]
-public sealed class GeigerComponentState : ComponentState
-{
- public float CurrentRadiation;
- public GeigerDangerLevel DangerLevel;
- public bool IsEnabled;
- public NetEntity? User;
-}
-
[Serializable, NetSerializable]
public enum GeigerDangerLevel : byte
{
/// <summary>
/// Handles what a grid should look like on radar.
/// </summary>
-[RegisterComponent, NetworkedComponent, Access(typeof(SharedShuttleSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedShuttleSystem))]
public sealed partial class IFFComponent : Component
{
/// <summary>
/// </summary>
public static readonly Color IFFColor = Color.Aquamarine;
- [ViewVariables(VVAccess.ReadWrite), DataField("flags")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public IFFFlags Flags = IFFFlags.None;
/// <summary>
/// Color for this to show up on IFF.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("color")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public Color Color = IFFColor;
}
namespace Content.Shared.Shuttles.Components;
-[RegisterComponent, NetworkedComponent, Access(typeof(SharedRadarConsoleSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedRadarConsoleSystem))]
public sealed partial class RadarConsoleComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
.SetRange(Owner, value, this);
}
- [DataField("maxRange")]
+ [DataField, AutoNetworkedField]
public float MaxRange = 256f;
}
using Content.Shared.Shuttles.Components;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Shuttles.Systems;
public const float DefaultMinRange = 64f;
public const float DefaultMaxRange = 256f;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<RadarConsoleComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<RadarConsoleComponent, ComponentHandleState>(OnHandleState);
- }
-
- private void OnHandleState(EntityUid uid, RadarConsoleComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not RadarConsoleComponentState state)
- return;
-
- component.MaxRange = state.Range;
- }
-
- private void OnGetState(EntityUid uid, RadarConsoleComponent component, ref ComponentGetState args)
- {
- args.State = new RadarConsoleComponentState()
- {
- Range = component.MaxRange
- };
- }
-
protected virtual void UpdateState(EntityUid uid, RadarConsoleComponent component)
{
}
Dirty(uid, component);
UpdateState(uid, component);
}
-
- [Serializable, NetSerializable]
- protected sealed class RadarConsoleComponentState : ComponentState
- {
- public float Range;
- }
}
using Content.Shared.Shuttles.Components;
using JetBrains.Annotations;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Shuttles.Systems;
* Handles the label visibility on radar controls. This can be hiding the label or applying other effects.
*/
- private void InitializeIFF()
- {
- SubscribeLocalEvent<IFFComponent, ComponentGetState>(OnIFFGetState);
- SubscribeLocalEvent<IFFComponent, ComponentHandleState>(OnIFFHandleState);
- }
-
protected virtual void UpdateIFFInterfaces(EntityUid gridUid, IFFComponent component) {}
/// <summary>
Dirty(component);
UpdateIFFInterfaces(gridUid, component);
}
-
- private void OnIFFHandleState(EntityUid uid, IFFComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not IFFComponentState state)
- return;
-
- component.Flags = state.Flags;
- component.Color = state.Color;
- }
-
- private void OnIFFGetState(EntityUid uid, IFFComponent component, ref ComponentGetState args)
- {
- args.State = new IFFComponentState()
- {
- Flags = component.Flags,
- Color = component.Color,
- };
- }
-
- [Serializable, NetSerializable]
- private sealed class IFFComponentState : ComponentState
- {
- public IFFFlags Flags;
- public Color Color;
- }
}
public abstract partial class SharedShuttleSystem : EntitySystem
{
- public override void Initialize()
- {
- base.Initialize();
- InitializeIFF();
- }
}
[Flags]
using Content.Shared.StepTrigger.Components;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Slippery
{
/// <remarks>
/// Requires <see cref="StepTriggerComponent"/>, see that component for some additional properties.
/// </remarks>
- [RegisterComponent]
- [NetworkedComponent]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SlipperyComponent : Component
{
/// <summary>
/// Path to the sound to be played when a mob slips.
/// </summary>
- [DataField("slipSound")]
+ [DataField, AutoNetworkedField]
[Access(Other = AccessPermissions.ReadWriteExecute)]
public SoundSpecifier SlipSound = new SoundPathSpecifier("/Audio/Effects/slip.ogg");
/// How many seconds the mob will be paralyzed for.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("paralyzeTime")]
+ [DataField, AutoNetworkedField]
[Access(Other = AccessPermissions.ReadWrite)]
public float ParalyzeTime = 3f;
/// The entity's speed will be multiplied by this to slip it forwards.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("launchForwardsMultiplier")]
+ [DataField, AutoNetworkedField]
[Access(Other = AccessPermissions.ReadWrite)]
public float LaunchForwardsMultiplier = 1f;
}
-
- [Serializable, NetSerializable]
- public sealed class SlipperyComponentState : ComponentState
- {
- public float ParalyzeTime { get; }
- public float LaunchForwardsMultiplier { get; }
- public string SlipSound { get; }
-
- public SlipperyComponentState(float paralyzeTime, float launchForwardsMultiplier, string slipSound)
- {
- ParalyzeTime = paralyzeTime;
- LaunchForwardsMultiplier = launchForwardsMultiplier;
- SlipSound = slipSound;
- }
- }
}
using Content.Shared.StepTrigger.Systems;
using Content.Shared.Stunnable;
using JetBrains.Annotations;
-using Robust.Shared.Audio;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
SubscribeLocalEvent<NoSlipComponent, SlipAttemptEvent>(OnNoSlipAttempt);
// as long as slip-resistant mice are never added, this should be fine (otherwise a mouse-hat will transfer it's power to the wearer).
SubscribeLocalEvent<NoSlipComponent, InventoryRelayedEvent<SlipAttemptEvent>>((e, c, ev) => OnNoSlipAttempt(e, c, ev.Args));
- SubscribeLocalEvent<SlipperyComponent, ComponentGetState>(OnSlipperyGetState);
- SubscribeLocalEvent<SlipperyComponent, ComponentHandleState>(OnSlipperyHandleState);
- }
-
- private void OnSlipperyHandleState(EntityUid uid, SlipperyComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not SlipperyComponentState state) return;
-
- component.ParalyzeTime = state.ParalyzeTime;
- component.LaunchForwardsMultiplier = state.LaunchForwardsMultiplier;
- component.SlipSound = new SoundPathSpecifier(state.SlipSound);
- }
-
- private void OnSlipperyGetState(EntityUid uid, SlipperyComponent component, ref ComponentGetState args)
- {
- args.State = new SlipperyComponentState(component.ParalyzeTime, component.LaunchForwardsMultiplier, _audio.GetSound(component.SlipSound));
}
private void HandleStepTrigger(EntityUid uid, SlipperyComponent component, ref StepTriggeredEvent args)
-using System.Collections.Specialized;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
+using Robust.Shared.Prototypes;
namespace Content.Shared.Speech
{
/// Component required for entities to be able to speak. (TODO: Entities can speak fine without this, this only forbids them speak if they have it and enabled is false.)
/// Contains the option to let entities make noise when speaking, change speech verbs, datafields for the sounds in question, and relevant AudioParams.
/// </summary>
- [RegisterComponent, NetworkedComponent]
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class SpeechComponent : Component
{
- [DataField("enabled"), Access(typeof(SpeechSystem),
- Friend = AccessPermissions.ReadWrite,
- Other = AccessPermissions.Read)]
+ [DataField, AutoNetworkedField]
+ [Access(typeof(SpeechSystem), Friend = AccessPermissions.ReadWrite, Other = AccessPermissions.Read)]
public bool Enabled = true;
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("speechSounds", customTypeSerializer:typeof(PrototypeIdSerializer<SpeechSoundsPrototype>))]
- public string? SpeechSounds;
+ [DataField]
+ public ProtoId<SpeechSoundsPrototype>? SpeechSounds;
/// <summary>
/// What speech verb prototype should be used by default for displaying this entity's messages?
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("speechVerb", customTypeSerializer:typeof(PrototypeIdSerializer<SpeechVerbPrototype>))]
- public string SpeechVerb = "Default";
+ [DataField]
+ public ProtoId<SpeechVerbPrototype> SpeechVerb = "Default";
/// <summary>
/// A mapping from chat suffixes loc strings to speech verb prototypes that should be conditionally used.
/// For things like '?' changing to 'asks' or '!!' making text bold and changing to 'yells'. Can be overridden if necessary.
/// </summary>
- [DataField("suffixSpeechVerbs", customTypeSerializer:typeof(PrototypeIdValueDictionarySerializer<string, SpeechVerbPrototype>))]
- public Dictionary<string, string> SuffixSpeechVerbs = new()
+ [DataField]
+ public Dictionary<string, ProtoId<SpeechVerbPrototype>> SuffixSpeechVerbs = new()
{
{ "chat-speech-verb-suffix-exclamation-strong", "DefaultExclamationStrong" },
{ "chat-speech-verb-suffix-exclamation", "DefaultExclamation" },
{ "chat-speech-verb-suffix-mumble", "DefaultMumble" },
};
- [DataField("audioParams")]
+ [DataField]
public AudioParams AudioParams = AudioParams.Default.WithVolume(6f).WithRolloffFactor(4.5f);
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("soundCooldownTime")]
+ [DataField]
public float SoundCooldownTime { get; set; } = 0.5f;
public TimeSpan LastTimeSoundPlayed = TimeSpan.Zero;
-using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-
namespace Content.Shared.Speech
{
public sealed class SpeechSystem : EntitySystem
base.Initialize();
SubscribeLocalEvent<SpeakAttemptEvent>(OnSpeakAttempt);
- SubscribeLocalEvent<SpeechComponent, ComponentGetState>(OnSpeechGetState);
- SubscribeLocalEvent<SpeechComponent, ComponentHandleState>(OnSpeechHandleState);
}
public void SetSpeech(EntityUid uid, bool value, SpeechComponent? component = null)
Dirty(component);
}
- private void OnSpeechHandleState(EntityUid uid, SpeechComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not SpeechComponentState state)
- return;
-
- component.Enabled = state.Enabled;
- }
-
- private void OnSpeechGetState(EntityUid uid, SpeechComponent component, ref ComponentGetState args)
- {
- args.State = new SpeechComponentState(component.Enabled);
- }
-
private void OnSpeakAttempt(SpeakAttemptEvent args)
{
if (!TryComp(args.Uid, out SpeechComponent? speech) || !speech.Enabled)
args.Cancel();
}
-
- [Serializable, NetSerializable]
- private sealed class SpeechComponentState : ComponentState
- {
- public readonly bool Enabled;
-
- public SpeechComponentState(bool enabled)
- {
- Enabled = enabled;
- }
- }
}
}
namespace Content.Shared.Standing
{
+ [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(StandingStateSystem))]
- [RegisterComponent, NetworkedComponent]
public sealed partial class StandingStateComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("downSound")]
+ [DataField]
public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall");
- [DataField("standing")]
+ [DataField, AutoNetworkedField]
public bool Standing { get; set; } = true;
/// <summary>
/// List of fixtures that had their collision mask changed when the entity was downed.
/// Required for re-adding the collision mask.
/// </summary>
- [DataField("changedFixtures")]
+ [DataField, AutoNetworkedField(true)]
public List<string> ChangedFixtures = new();
}
}
using Content.Shared.Physics;
using Content.Shared.Rotation;
using Robust.Shared.Audio;
-using Robust.Shared.GameStates;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
-using Robust.Shared.Serialization;
namespace Content.Shared.Standing
{
// If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited.
private const int StandingCollisionLayer = (int) CollisionGroup.MidImpassable;
- public override void Initialize()
- {
- SubscribeLocalEvent<StandingStateComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<StandingStateComponent, ComponentHandleState>(OnHandleState);
- }
-
- private void OnHandleState(EntityUid uid, StandingStateComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not StandingComponentState state)
- return;
-
- component.Standing = state.Standing;
- component.ChangedFixtures = new List<string>(state.ChangedFixtures);
- }
-
- private void OnGetState(EntityUid uid, StandingStateComponent component, ref ComponentGetState args)
- {
- args.State = new StandingComponentState(component.Standing, component.ChangedFixtures);
- }
-
public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null)
{
if (!Resolve(uid, ref standingState, false))
return true;
}
-
- // I'm not calling it StandingStateComponentState
- [Serializable, NetSerializable]
- private sealed class StandingComponentState : ComponentState
- {
- public bool Standing { get; }
- public List<string> ChangedFixtures { get; }
-
- public StandingComponentState(bool standing, List<string> changedFixtures)
- {
- Standing = standing;
- ChangedFixtures = changedFixtures;
- }
- }
}
public sealed class DropHandItemsEvent : EventArgs
using Content.Shared.StepTrigger.Systems;
using Content.Shared.Whitelist;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.StepTrigger.Components;
-[RegisterComponent]
-[NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
[Access(typeof(StepTriggerSystem))]
public sealed partial class StepTriggerComponent : Component
{
/// <summary>
/// List of entities that are currently colliding with the entity.
/// </summary>
- [ViewVariables]
- public readonly HashSet<EntityUid> Colliding = new();
+ [ViewVariables, AutoNetworkedField(true)]
+ public HashSet<EntityUid> Colliding = new();
/// <summary>
/// The list of entities that are standing on this entity,
/// which shouldn't be able to trigger it again until stepping off.
/// </summary>
- [ViewVariables]
- public readonly HashSet<EntityUid> CurrentlySteppedOn = new();
+ [ViewVariables, AutoNetworkedField(true)]
+ public HashSet<EntityUid> CurrentlySteppedOn = new();
/// <summary>
/// Whether or not this component will currently try to trigger for entities.
/// </summary>
- [DataField("active")]
+ [DataField, AutoNetworkedField]
public bool Active = true;
/// <summary>
/// Ratio of shape intersection for a trigger to occur.
/// </summary>
- [DataField("intersectRatio")]
+ [DataField, AutoNetworkedField]
public float IntersectRatio = 0.3f;
/// <summary>
/// Entities will only be triggered if their speed exceeds this limit.
/// </summary>
- [DataField("requiredTriggeredSpeed")]
- public float RequiredTriggerSpeed = 3.5f;
+ [DataField, AutoNetworkedField]
+ public float RequiredTriggeredSpeed = 3.5f;
/// <summary>
/// If any entities occupy the blacklist on the same tile then steptrigger won't work.
/// </summary>
- [DataField("blacklist")]
+ [DataField]
public EntityWhitelist? Blacklist;
/// <summary>
/// If this is true, steptrigger will still occur on entities that are in air / weightless. They do not
/// by default.
/// </summary>
- [DataField("ignoreWeightless")]
- public bool IgnoreWeightless = false;
+ [DataField]
+ public bool IgnoreWeightless;
}
[RegisterComponent]
{
}
-
-[Serializable, NetSerializable]
-public sealed class StepTriggerComponentState : ComponentState
-{
- public float IntersectRatio { get; }
- public float RequiredTriggerSpeed { get; }
- public readonly HashSet<NetEntity> CurrentlySteppedOn;
- public readonly HashSet<NetEntity> Colliding;
- public readonly bool Active;
-
- public StepTriggerComponentState(float intersectRatio, HashSet<NetEntity> currentlySteppedOn, HashSet<NetEntity> colliding, float requiredTriggerSpeed, bool active)
- {
- IntersectRatio = intersectRatio;
- CurrentlySteppedOn = currentlySteppedOn;
- RequiredTriggerSpeed = requiredTriggerSpeed;
- Active = active;
- Colliding = colliding;
- }
-}
-
using Content.Shared.Gravity;
using Content.Shared.StepTrigger.Components;
-using Robust.Shared.GameStates;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
public override void Initialize()
{
UpdatesOutsidePrediction = true;
- SubscribeLocalEvent<StepTriggerComponent, ComponentGetState>(TriggerGetState);
- SubscribeLocalEvent<StepTriggerComponent, ComponentHandleState>(TriggerHandleState);
+ SubscribeLocalEvent<StepTriggerComponent, AfterAutoHandleStateEvent>(TriggerHandleState);
SubscribeLocalEvent<StepTriggerComponent, StartCollideEvent>(OnStartCollide);
SubscribeLocalEvent<StepTriggerComponent, EndCollideEvent>(OnEndCollide);
// this is hard to explain
var intersect = Box2.Area(otherAabb.Intersect(ourAabb));
var ratio = Math.Max(intersect / Box2.Area(otherAabb), intersect / Box2.Area(ourAabb));
- if (otherPhysics.LinearVelocity.Length() < component.RequiredTriggerSpeed
+ if (otherPhysics.LinearVelocity.Length() < component.RequiredTriggeredSpeed
|| component.CurrentlySteppedOn.Contains(otherUid)
|| ratio < component.IntersectRatio
|| !CanTrigger(uid, otherUid, component))
}
}
-
- private void TriggerHandleState(EntityUid uid, StepTriggerComponent component, ref ComponentHandleState args)
+ private void TriggerHandleState(EntityUid uid, StepTriggerComponent component, ref AfterAutoHandleStateEvent args)
{
- if (args.Current is not StepTriggerComponentState state)
- return;
-
- component.RequiredTriggerSpeed = state.RequiredTriggerSpeed;
- component.IntersectRatio = state.IntersectRatio;
- component.Active = state.Active;
- var stepped = EnsureEntitySet<StepTriggerComponent>(state.CurrentlySteppedOn, uid);
- var colliding = EnsureEntitySet<StepTriggerComponent>(state.CurrentlySteppedOn, uid);
-
- component.CurrentlySteppedOn.Clear();
- component.CurrentlySteppedOn.UnionWith(stepped);
-
- component.Colliding.Clear();
- component.Colliding.UnionWith(colliding);
-
if (component.Colliding.Count > 0)
{
EnsureComp<StepTriggerActiveComponent>(uid);
}
}
- private void TriggerGetState(EntityUid uid, StepTriggerComponent component, ref ComponentGetState args)
- {
- args.State = new StepTriggerComponentState(
- component.IntersectRatio,
- GetNetEntitySet(component.CurrentlySteppedOn),
- GetNetEntitySet(component.Colliding),
- component.RequiredTriggerSpeed,
- component.Active);
- }
-
public void SetIntersectRatio(EntityUid uid, float ratio, StepTriggerComponent? component = null)
{
if (!Resolve(uid, ref component))
if (!Resolve(uid, ref component))
return;
- if (MathHelper.CloseToPercent(component.RequiredTriggerSpeed, speed))
+ if (MathHelper.CloseToPercent(component.RequiredTriggeredSpeed, speed))
return;
- component.RequiredTriggerSpeed = speed;
+ component.RequiredTriggeredSpeed = speed;
Dirty(uid, component);
}
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Shared.Storage.Components;
/// This is used for things like paper bins, in which
/// you can only take off of the top of the bin.
/// </summary>
-[RegisterComponent, NetworkedComponent, Access(typeof(BinSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(BinSystem))]
public sealed partial class BinComponent : Component
{
/// <summary>
/// i can handle entities being deleted and removed
/// out of order by other systems
/// </remarks>
- [DataField("items")]
+ [DataField, AutoNetworkedField]
public List<EntityUid> Items = new();
/// <summary>
/// The items that start in the bin. Sorted in order.
/// </summary>
- [DataField("initialContents", customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))]
- public List<string> InitialContents = new();
+ [DataField]
+ public List<EntProtoId> InitialContents = new();
/// <summary>
/// A whitelist governing what items can be inserted into the bin.
/// </summary>
- [DataField("whitelist")]
+ [DataField, AutoNetworkedField]
public EntityWhitelist? Whitelist;
/// <summary>
/// The maximum amount of items
/// that can be stored in the bin.
/// </summary>
- [DataField("maxItems")]
+ [DataField, AutoNetworkedField]
public int MaxItems = 20;
}
-
-[Serializable, NetSerializable]
-public sealed class BinComponentState : ComponentState
-{
- public List<NetEntity> Items;
-
- public EntityWhitelist? Whitelist;
-
- public int MaxItems;
-
- public BinComponentState(List<NetEntity> items, EntityWhitelist? whitelist, int maxItems)
- {
- Items = items;
- Whitelist = whitelist;
- MaxItems = maxItems;
- }
-}
using Content.Shared.Interaction;
using Content.Shared.Storage.Components;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Robust.Shared.Timing;
/// <inheritdoc/>
public override void Initialize()
{
- SubscribeLocalEvent<BinComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<BinComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<BinComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<BinComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<BinComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
SubscribeLocalEvent<BinComponent, AfterInteractUsingEvent>(OnAfterInteractUsing);
}
- private void OnGetState(EntityUid uid, BinComponent component, ref ComponentGetState args)
- {
- args.State = new BinComponentState(GetNetEntityList(component.Items), component.Whitelist, component.MaxItems);
- }
-
- private void OnHandleState(EntityUid uid, BinComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not BinComponentState state)
- return;
-
- component.Items = EnsureEntityList<BinComponent>(state.Items, uid);
- component.Whitelist = state.Whitelist;
- component.MaxItems = state.MaxItems;
- }
-
private void OnStartup(EntityUid uid, BinComponent component, ComponentStartup args)
{
component.ItemContainer = _container.EnsureContainer<Container>(uid, BinContainerId);
/// <summary>
/// Allows an entity to be dragged around by the mouse. The position is updated for all player while dragging.
/// </summary>
-[NetworkedComponent]
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class TabletopDraggableComponent : Component
{
// The player dragging the piece
- [ViewVariables]
+ [ViewVariables, AutoNetworkedField]
public NetUserId? DraggingPlayer;
}
using Content.Shared.Interaction;
using Content.Shared.Tabletop.Components;
using Content.Shared.Tabletop.Events;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
public override void Initialize()
{
- SubscribeLocalEvent<TabletopDraggableComponent, ComponentGetState>(GetDraggableState);
SubscribeAllEvent<TabletopDraggingPlayerChangedEvent>(OnDraggingPlayerChanged);
SubscribeAllEvent<TabletopMoveEvent>(OnTabletopMove);
}
_transforms.SetLocalPositionNoLerp(transform, msg.Coordinates.Position);
}
- private void GetDraggableState(EntityUid uid, TabletopDraggableComponent component, ref ComponentGetState args)
- {
- args.State = new TabletopDraggableComponentState(component.DraggingPlayer);
- }
-
private void OnDraggingPlayerChanged(TabletopDraggingPlayerChangedEvent msg, EntitySessionEventArgs args)
{
var dragged = GetEntity(msg.DraggedEntityUid);
/// Represents an entity which is linked to other entities (perhaps portals), and which can be walked through/
/// thrown into to teleport an entity.
/// </summary>
-[RegisterComponent, Access(typeof(LinkedEntitySystem)), NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(LinkedEntitySystem))]
public sealed partial class LinkedEntityComponent : Component
{
/// <summary>
/// The entities that this entity is linked to.
/// </summary>
- [DataField("linkedEntities")]
+ [DataField, AutoNetworkedField]
public HashSet<EntityUid> LinkedEntities = new();
/// <summary>
/// Should this entity be deleted if all of its links are removed?
/// </summary>
- [DataField("deleteOnEmptyLinks")]
- public bool DeleteOnEmptyLinks = false;
-}
-
-[Serializable, NetSerializable]
-public sealed class LinkedEntityComponentState : ComponentState
-{
- public HashSet<NetEntity> LinkedEntities;
-
- public LinkedEntityComponentState(HashSet<NetEntity> linkedEntities)
- {
- LinkedEntities = linkedEntities;
- }
+ [DataField]
+ public bool DeleteOnEmptyLinks;
}
[Serializable, NetSerializable]
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
namespace Content.Shared.Teleportation.Components;
/// Attached to an entity after portal transit to mark that they should not immediately be portaled back
/// at the end destination.
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class PortalTimeoutComponent : Component
{
/// <summary>
/// The portal that was entered. Null if coming from a hand teleporter, etc.
/// </summary>
- [ViewVariables, DataField("enteredPortal")]
- public EntityUid? EnteredPortal = null;
-}
-
-[Serializable, NetSerializable]
-public sealed class PortalTimeoutComponentState : ComponentState
-{
- public NetEntity? EnteredPortal;
-
- public PortalTimeoutComponentState(NetEntity? enteredPortal)
- {
- EnteredPortal = enteredPortal;
- }
+ [ViewVariables, DataField, AutoNetworkedField]
+ public EntityUid? EnteredPortal;
}
-using Content.Shared.Teleportation.Components;
-using Robust.Shared.GameStates;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using Content.Shared.Teleportation.Components;
namespace Content.Shared.Teleportation.Systems;
base.Initialize();
SubscribeLocalEvent<LinkedEntityComponent, ComponentShutdown>(OnLinkShutdown);
-
- SubscribeLocalEvent<LinkedEntityComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<LinkedEntityComponent, ComponentHandleState>(OnHandleState);
- }
-
- private void OnGetState(EntityUid uid, LinkedEntityComponent component, ref ComponentGetState args)
- {
- args.State = new LinkedEntityComponentState(GetNetEntitySet(component.LinkedEntities));
- }
-
- private void OnHandleState(EntityUid uid, LinkedEntityComponent component, ref ComponentHandleState args)
- {
- if (args.Current is LinkedEntityComponentState state)
- {
- component.LinkedEntities = EnsureEntitySet<LinkedEntityComponent>(state.LinkedEntities, uid);
- }
}
private void OnLinkShutdown(EntityUid uid, LinkedEntityComponent component, ComponentShutdown args)
using System.Linq;
using Content.Shared.Ghost;
-using Content.Shared.Pinpointer;
using Content.Shared.Popups;
using Content.Shared.Projectiles;
using Content.Shared.Pulling;
using Content.Shared.Pulling.Components;
using Content.Shared.Teleportation.Components;
using Content.Shared.Verbs;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Physics.Dynamics;
SubscribeLocalEvent<PortalComponent, StartCollideEvent>(OnCollide);
SubscribeLocalEvent<PortalComponent, EndCollideEvent>(OnEndCollide);
SubscribeLocalEvent<PortalComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
-
- SubscribeLocalEvent<PortalTimeoutComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<PortalTimeoutComponent, ComponentHandleState>(OnHandleState);
}
private void OnGetVerbs(EntityUid uid, PortalComponent component, GetVerbsEvent<AlternativeVerb> args)
});
}
- private void OnGetState(EntityUid uid, PortalTimeoutComponent component, ref ComponentGetState args)
- {
- args.State = new PortalTimeoutComponentState(GetNetEntity(component.EnteredPortal));
- }
-
- private void OnHandleState(EntityUid uid, PortalTimeoutComponent component, ref ComponentHandleState args)
- {
- if (args.Current is PortalTimeoutComponentState state)
- component.EnteredPortal = EnsureEntity<PortalTimeoutComponent>(state.EnteredPortal, uid);
- }
-
private bool ShouldCollide(string ourId, string otherId, Fixture our, Fixture other)
{
// most non-hard fixtures shouldn't pass through portals, but projectiles are non-hard as well
-using System.Threading;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
-namespace Content.Shared.Timing
-{
- /// <summary>
- /// Timer that creates a cooldown each time an object is activated/used
- /// </summary>
- [RegisterComponent]
- [NetworkedComponent]
- public sealed partial class UseDelayComponent : Component
- {
- public TimeSpan LastUseTime;
-
- public TimeSpan? DelayEndTime;
+namespace Content.Shared.Timing;
- [DataField("delay")]
- [ViewVariables(VVAccess.ReadWrite)]
- public TimeSpan Delay = TimeSpan.FromSeconds(1);
+/// <summary>
+/// Timer that creates a cooldown each time an object is activated/used
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+public sealed partial class UseDelayComponent : Component
+{
+ [AutoNetworkedField]
+ public TimeSpan LastUseTime;
- /// <summary>
- /// Stores remaining delay pausing (and eventually, serialization).
- /// </summary>
- [DataField("remainingDelay")]
- public TimeSpan? RemainingDelay;
+ [AutoNetworkedField]
+ public TimeSpan? DelayEndTime;
- public bool ActiveDelay => DelayEndTime != null;
- }
+ [DataField, AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public TimeSpan Delay = TimeSpan.FromSeconds(1);
- [Serializable, NetSerializable]
- public sealed class UseDelayComponentState : ComponentState
- {
- public readonly TimeSpan LastUseTime;
- public readonly TimeSpan Delay;
- public readonly TimeSpan? DelayEndTime;
+ /// <summary>
+ /// Stores remaining delay pausing (and eventually, serialization).
+ /// </summary>
+ [DataField]
+ public TimeSpan? RemainingDelay;
- public UseDelayComponentState(TimeSpan lastUseTime, TimeSpan delay, TimeSpan? delayEndTime)
- {
- LastUseTime = lastUseTime;
- Delay = delay;
- DelayEndTime = delayEndTime;
- }
- }
+ public bool ActiveDelay => DelayEndTime != null;
}
-using System.Threading;
using Content.Shared.Cooldown;
-using Robust.Shared.GameStates;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
{
base.Initialize();
- SubscribeLocalEvent<UseDelayComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<UseDelayComponent, ComponentHandleState>(OnHandleState);
+ SubscribeLocalEvent<UseDelayComponent, AfterAutoHandleStateEvent>(OnHandleState);
SubscribeLocalEvent<UseDelayComponent, EntityPausedEvent>(OnPaused);
SubscribeLocalEvent<UseDelayComponent, EntityUnpausedEvent>(OnUnpaused);
_activeDelays.Add(component);
}
- private void OnHandleState(EntityUid uid, UseDelayComponent component, ref ComponentHandleState args)
+ private void OnHandleState(EntityUid uid, UseDelayComponent component, ref AfterAutoHandleStateEvent args)
{
- if (args.Current is not UseDelayComponentState state)
- return;
-
- component.LastUseTime = state.LastUseTime;
- component.Delay = state.Delay;
- component.DelayEndTime = state.DelayEndTime;
-
if (component.DelayEndTime == null)
_activeDelays.Remove(component);
else
_activeDelays.Add(component);
}
- private void OnGetState(EntityUid uid, UseDelayComponent component, ref ComponentGetState args)
- {
- args.State = new UseDelayComponentState(component.LastUseTime, component.Delay, component.DelayEndTime);
- }
-
public override void Update(float frameTime)
{
base.Update(frameTime);
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
-using Robust.Shared.Serialization;
using Robust.Shared.Utility;
-namespace Content.Shared.Tools.Components
+namespace Content.Shared.Tools.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+public sealed partial class MultipleToolComponent : Component
{
- [RegisterComponent, NetworkedComponent]
- public sealed partial class MultipleToolComponent : Component
+ [DataDefinition]
+ public sealed partial class ToolEntry
{
- [DataDefinition]
- public sealed partial class ToolEntry
- {
- [DataField("behavior", required: true)]
- public PrototypeFlags<ToolQualityPrototype> Behavior = new();
-
- [DataField("useSound")]
- public SoundSpecifier? Sound;
+ [DataField(required: true)]
+ public PrototypeFlags<ToolQualityPrototype> Behavior = new();
- [DataField("changeSound")]
- public SoundSpecifier? ChangeSound;
+ [DataField]
+ public SoundSpecifier? UseSound;
- [DataField("sprite")]
- public SpriteSpecifier? Sprite;
- }
+ [DataField]
+ public SoundSpecifier? ChangeSound;
- [DataField("entries", required: true)]
- public ToolEntry[] Entries { get; private set; } = Array.Empty<ToolEntry>();
+ [DataField]
+ public SpriteSpecifier? Sprite;
+ }
- [ViewVariables]
- public uint CurrentEntry = 0;
+ [DataField(required: true)]
+ public ToolEntry[] Entries { get; private set; } = Array.Empty<ToolEntry>();
- [ViewVariables]
- public string CurrentQualityName = string.Empty;
+ [ViewVariables]
+ [AutoNetworkedField]
+ public uint CurrentEntry = 0;
- [ViewVariables(VVAccess.ReadWrite)]
- public bool UiUpdateNeeded;
+ [ViewVariables]
+ public string CurrentQualityName = string.Empty;
- [DataField("statusShowBehavior")]
- public bool StatusShowBehavior = true;
- }
+ [ViewVariables(VVAccess.ReadWrite)]
+ public bool UiUpdateNeeded;
- [NetSerializable, Serializable]
- public sealed class MultipleToolComponentState : ComponentState
- {
- public readonly uint Selected;
-
- public MultipleToolComponentState(uint selected)
- {
- Selected = selected;
- }
- }
+ [DataField]
+ public bool StatusShowBehavior = true;
}
using System.Linq;
using Content.Shared.Interaction;
using Content.Shared.Tools.Components;
-using Robust.Shared.GameStates;
using Content.Shared.Prying.Components;
namespace Content.Shared.Tools;
{
SubscribeLocalEvent<MultipleToolComponent, ComponentStartup>(OnMultipleToolStartup);
SubscribeLocalEvent<MultipleToolComponent, ActivateInWorldEvent>(OnMultipleToolActivated);
- SubscribeLocalEvent<MultipleToolComponent, ComponentGetState>(OnMultipleToolGetState);
- SubscribeLocalEvent<MultipleToolComponent, ComponentHandleState>(OnMultipleToolHandleState);
+ SubscribeLocalEvent<MultipleToolComponent, AfterAutoHandleStateEvent>(OnMultipleToolHandleState);
}
- private void OnMultipleToolHandleState(EntityUid uid, MultipleToolComponent component, ref ComponentHandleState args)
+ private void OnMultipleToolHandleState(EntityUid uid, MultipleToolComponent component, ref AfterAutoHandleStateEvent args)
{
- if (args.Current is not MultipleToolComponentState state)
- return;
-
- component.CurrentEntry = state.Selected;
SetMultipleTool(uid, component);
}
args.Handled = CycleMultipleTool(uid, multiple, args.User);
}
- private void OnMultipleToolGetState(EntityUid uid, MultipleToolComponent multiple, ref ComponentGetState args)
- {
- args.State = new MultipleToolComponentState(multiple.CurrentEntry);
- }
-
public bool CycleMultipleTool(EntityUid uid, MultipleToolComponent? multiple = null, EntityUid? user = null)
{
if (!Resolve(uid, ref multiple))
}
var current = multiple.Entries[multiple.CurrentEntry];
- tool.UseSound = current.Sound;
+ tool.UseSound = current.UseSound;
tool.Qualities = current.Behavior;
// TODO: Replace this with a better solution later
// This code should be purged anyway but with that being said this doesn't handle components being changed.
if (TryComp<StrapComponent>(uid, out var strap))
{
- component.BaseBuckleOffset = strap.BuckleOffset;
- strap.BuckleOffsetUnclamped = Vector2.Zero;
+ component.BaseBuckleOffset = strap.BuckleOffsetClamped;
+ strap.BuckleOffset = Vector2.Zero;
}
_modifier.RefreshMovementSpeedModifiers(uid);
return;
// TODO: Strap should handle this but buckle E/C moment.
- var oldOffset = strap.BuckleOffsetUnclamped;
+ var oldOffset = strap.BuckleOffset;
- strap.BuckleOffsetUnclamped = xform.LocalRotation.Degrees switch
+ strap.BuckleOffset = xform.LocalRotation.Degrees switch
{
< 45f => new(0, component.SouthOverride),
<= 135f => component.BaseBuckleOffset,
_ => new(0, component.SouthOverride)
};
- if (!oldOffset.Equals(strap.BuckleOffsetUnclamped))
+ if (!oldOffset.Equals(strap.BuckleOffset))
Dirty(strap);
foreach (var buckledEntity in strap.BuckledEntities)
{
var buckleXform = Transform(buckledEntity);
- _transform.SetLocalPositionNoLerp(buckleXform, strap.BuckleOffset);
+ _transform.SetLocalPositionNoLerp(buckleXform, strap.BuckleOffsetClamped);
}
}
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.Weapons.Melee;
/// <summary>
/// When given to a mob lets them do unarmed attacks, or when given to an item lets someone wield it to do attacks.
/// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class MeleeWeaponComponent : Component
{
// TODO: This is becoming bloated as shit.
/// <summary>
/// Does this entity do a disarm on alt attack.
/// </summary>
- [DataField("altDisarm"), ViewVariables(VVAccess.ReadWrite)]
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
public bool AltDisarm = true;
/// <summary>
/// Should the melee weapon's damage stats be examinable.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField("hidden")]
- public bool HideFromExamine;
+ [DataField]
+ public bool Hidden;
/// <summary>
/// Next time this component is allowed to light attack. Heavy attacks are wound up and never have a cooldown.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("nextAttack", customTypeSerializer:typeof(TimeOffsetSerializer))]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadWrite)]
public TimeSpan NextAttack;
/// <summary>
/// Starts attack cooldown when equipped if true.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("resetOnHandSelected")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public bool ResetOnHandSelected = true;
/*
/// <summary>
/// How many times we can attack per second.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("attackRate")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float AttackRate = 1f;
/// <summary>
/// Are we currently holding down the mouse for an attack.
/// Used so we can't just hold the mouse button and attack constantly.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public bool Attacking = false;
/// <summary>
/// Base damage for this weapon. Can be modified via heavy damage or other means.
/// </summary>
- [DataField("damage", required:true)]
+ [DataField(required:true)]
[ViewVariables(VVAccess.ReadWrite)]
public DamageSpecifier Damage = default!;
- [DataField("bluntStaminaDamageFactor")] [ViewVariables(VVAccess.ReadWrite)]
+ [DataField]
+ [ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 BluntStaminaDamageFactor = FixedPoint2.New(0.5f);
/// <summary>
/// Multiplies damage by this amount for single-target attacks.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("clickDamageModifier")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public FixedPoint2 ClickDamageModifier = FixedPoint2.New(1);
// TODO: Temporarily 1.5 until interactionoutline is adjusted to use melee, then probably drop to 1.2
/// <summary>
/// Nearest edge range to hit an entity.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("range")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float Range = 1.5f;
/// <summary>
/// Total width of the angle for wide attacks.
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("angle")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public Angle Angle = Angle.FromDegrees(60);
- [ViewVariables(VVAccess.ReadWrite), DataField("animation", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string ClickAnimation = "WeaponArcPunch";
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ public EntProtoId Animation = "WeaponArcPunch";
- [ViewVariables(VVAccess.ReadWrite), DataField("wideAnimation", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string WideAnimation = "WeaponArcSlash";
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
+ public EntProtoId WideAnimation = "WeaponArcSlash";
// Sounds
{
public EntityUid? Weapon;
}
-
-[Serializable, NetSerializable]
-public sealed class MeleeWeaponComponentState : ComponentState
-{
- // None of the other data matters for client as they're not predicted.
-
- public float AttackRate;
- public bool Attacking;
- public TimeSpan NextAttack;
-
- public string ClickAnimation;
- public string WideAnimation;
- public float Range;
-
- public MeleeWeaponComponentState(float attackRate, bool attacking, TimeSpan nextAttack, string clickAnimation, string wideAnimation, float range)
- {
- AttackRate = attackRate;
- Attacking = attacking;
- NextAttack = nextAttack;
- ClickAnimation = clickAnimation;
- WideAnimation = wideAnimation;
- Range = range;
- }
-}
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
base.Initialize();
SubscribeLocalEvent<MeleeWeaponComponent, EntityUnpausedEvent>(OnMeleeUnpaused);
- SubscribeLocalEvent<MeleeWeaponComponent, ComponentGetState>(OnGetState);
- SubscribeLocalEvent<MeleeWeaponComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<MeleeWeaponComponent, HandSelectedEvent>(OnMeleeSelected);
SubscribeLocalEvent<MeleeWeaponComponent, ShotAttemptedEvent>(OnMeleeShotAttempted);
SubscribeLocalEvent<MeleeWeaponComponent, GunShotEvent>(OnMeleeShot);
AttemptAttack(args.SenderSession.AttachedEntity.Value, weaponUid, weapon, msg, args.SenderSession);
}
- private void OnGetState(EntityUid uid, MeleeWeaponComponent component, ref ComponentGetState args)
- {
- args.State = new MeleeWeaponComponentState(component.AttackRate, component.Attacking, component.NextAttack, component.ClickAnimation, component.WideAnimation, component.Range);
- }
-
- private void OnHandleState(EntityUid uid, MeleeWeaponComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not MeleeWeaponComponentState state)
- return;
-
- component.Attacking = state.Attacking;
- component.AttackRate = state.AttackRate;
- component.NextAttack = state.NextAttack;
-
- component.ClickAnimation = state.ClickAnimation;
- component.WideAnimation = state.WideAnimation;
- component.Range = state.Range;
- }
-
/// <summary>
/// Gets the total damage a weapon does, including modifiers like wielding and enablind/disabling
/// </summary>
{
case LightAttackEvent light:
DoLightAttack(user, light, weaponUid, weapon, session);
- animation = weapon.ClickAnimation;
+ animation = weapon.Animation;
break;
case DisarmAttackEvent disarm:
if (!DoDisarm(user, disarm, weaponUid, weapon, session))
return false;
- animation = weapon.ClickAnimation;
+ animation = weapon.Animation;
break;
case HeavyAttackEvent heavy:
if (!DoHeavyAttack(user, heavy, weaponUid, weapon, session))
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Weapons.Ranged.Components;
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class BallisticAmmoProviderComponent : Component
{
- [ViewVariables(VVAccess.ReadWrite), DataField("soundRack")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public SoundSpecifier? SoundRack = new SoundPathSpecifier("/Audio/Weapons/Guns/Cock/smg_cock.ogg");
- [ViewVariables(VVAccess.ReadWrite), DataField("soundInsert")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public SoundSpecifier? SoundInsert = new SoundPathSpecifier("/Audio/Weapons/Guns/MagIn/bullet_insert.ogg");
- [ViewVariables(VVAccess.ReadWrite), DataField("proto", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
- public string? FillProto;
+ [ViewVariables(VVAccess.ReadWrite), DataField]
+ public EntProtoId? Proto;
- [ViewVariables(VVAccess.ReadWrite), DataField("capacity")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public int Capacity = 30;
public int Count => UnspawnedCount + Container.ContainedEntities.Count;
- [ViewVariables(VVAccess.ReadWrite), DataField("unspawnedCount")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public int UnspawnedCount;
- [ViewVariables(VVAccess.ReadWrite), DataField("whitelist")]
+ [ViewVariables(VVAccess.ReadWrite), DataField]
public EntityWhitelist? Whitelist;
public Container Container = default!;
// TODO: Make this use stacks when the typeserializer is done.
- [DataField("entities")]
+ [DataField, AutoNetworkedField]
public List<EntityUid> Entities = new();
/// <summary>
/// <remarks>
/// Set to false for entities like turrets to avoid users being able to cycle them.
/// </remarks>
- [ViewVariables(VVAccess.ReadWrite), DataField("cycleable")]
+ [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool Cycleable = true;
/// <summary>
/// Is it okay for this entity to directly transfer its valid ammunition into another provider?
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), DataField("mayTransfer")]
- public bool MayTransfer = false;
+ [ViewVariables(VVAccess.ReadWrite), DataField]
+ public bool MayTransfer;
/// <summary>
/// DoAfter delay for filling a bullet into another ballistic ammo provider.
/// </summary>
- [DataField("fillDelay")]
+ [DataField]
public TimeSpan FillDelay = TimeSpan.FromSeconds(0.5);
}
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Containers;
-using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
SubscribeLocalEvent<BallisticAmmoProviderComponent, AfterInteractEvent>(OnBallisticAfterInteract);
SubscribeLocalEvent<BallisticAmmoProviderComponent, AmmoFillDoAfterEvent>(OnBallisticAmmoFillDoAfter);
SubscribeLocalEvent<BallisticAmmoProviderComponent, UseInHandEvent>(OnBallisticUse);
-
- SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentGetState>(OnBallisticGetState);
- SubscribeLocalEvent<BallisticAmmoProviderComponent, ComponentHandleState>(OnBallisticHandleState);
- }
-
- private void OnBallisticGetState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentGetState args)
- {
- args.State = new BallisticAmmoProviderComponentState()
- {
- UnspawnedCount = component.UnspawnedCount,
- Cycleable = component.Cycleable,
- Entities = GetNetEntityList(component.Entities),
- };
- }
-
- private void OnBallisticHandleState(EntityUid uid, BallisticAmmoProviderComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not BallisticAmmoProviderComponentState state)
- return;
-
- component.UnspawnedCount = state.UnspawnedCount;
- component.Cycleable = state.Cycleable;
- component.Entities = EnsureEntityList<BallisticAmmoProviderComponent>(state.Entities, uid);
}
private void OnBallisticUse(EntityUid uid, BallisticAmmoProviderComponent component, UseInHandEvent args)
{
// TODO this should be part of the prototype, not set on map init.
// Alternatively, just track spawned count, instead of unspawned count.
- if (component.FillProto != null)
+ if (component.Proto != null)
{
component.UnspawnedCount = Math.Max(0, component.Capacity - component.Container.ContainedEntities.Count);
UpdateBallisticAppearance(uid, component);
else if (component.UnspawnedCount > 0)
{
component.UnspawnedCount--;
- entity = Spawn(component.FillProto, args.Coordinates);
+ entity = Spawn(component.Proto, args.Coordinates);
args.Ammo.Add((entity, EnsureShootable(entity)));
}
}
Appearance.SetData(uid, AmmoVisuals.AmmoCount, GetBallisticShots(component), appearance);
Appearance.SetData(uid, AmmoVisuals.AmmoMax, component.Capacity, appearance);
}
-
- [Serializable, NetSerializable]
- private sealed class BallisticAmmoProviderComponentState : ComponentState
- {
- public int UnspawnedCount;
- public List<NetEntity> Entities = new();
- public bool Cycleable = true;
- }
}
/// <summary>
using Content.Shared.Chat.Prototypes;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
-using Content.Shared.Roles;
using Content.Shared.Humanoid;
+using Content.Shared.Roles;
using Content.Shared.StatusIcon;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-using static Content.Shared.Humanoid.HumanoidAppearanceState;
namespace Content.Shared.Zombies;
var getty = new ComponentGetState();
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
- var alertState = (AlertsComponentState) getty.State!;
+ var alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
Assert.NotNull(alertState);
Assert.That(alertState.Alerts.Count, Is.EqualTo(1));
Assert.That(alertState.Alerts.ContainsKey(lowpressure.AlertKey));
// Lazy
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
- alertState = (AlertsComponentState) getty.State!;
+ alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
Assert.That(alertState.Alerts.Count, Is.EqualTo(1));
Assert.That(alertState.Alerts.ContainsKey(highpressure.AlertKey));
EntitySystem.Get<AlertsSystem>().ClearAlertCategory(alertsComponent.Owner, AlertCategory.Pressure);
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
- alertState = (AlertsComponentState) getty.State!;
+ alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
Assert.That(alertState.Alerts.Count, Is.EqualTo(0));
}
}