Predict EmitterSystem ExamineEvent and GetVerbsEvent (#39318)
* ididathing.exe * commit * cleanup --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,8 @@ public sealed class EmitterSystem : SharedEmitterSystem
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<EmitterComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
SubscribeLocalEvent<EmitterComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Content.Server.Projectiles;
|
|||||||
using Content.Server.Weapons.Ranged.Systems;
|
using Content.Server.Weapons.Ranged.Systems;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.DeviceLinking.Events;
|
using Content.Shared.DeviceLinking.Events;
|
||||||
using Content.Shared.Examine;
|
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Lock;
|
using Content.Shared.Lock;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
@@ -15,9 +14,7 @@ using Content.Shared.Power;
|
|||||||
using Content.Shared.Projectiles;
|
using Content.Shared.Projectiles;
|
||||||
using Content.Shared.Singularity.Components;
|
using Content.Shared.Singularity.Components;
|
||||||
using Content.Shared.Singularity.EntitySystems;
|
using Content.Shared.Singularity.EntitySystems;
|
||||||
using Content.Shared.Verbs;
|
|
||||||
using Content.Shared.Weapons.Ranged.Components;
|
using Content.Shared.Weapons.Ranged.Components;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Physics.Components;
|
using Robust.Shared.Physics.Components;
|
||||||
@@ -28,7 +25,6 @@ using Timer = Robust.Shared.Timing.Timer;
|
|||||||
|
|
||||||
namespace Content.Server.Singularity.EntitySystems
|
namespace Content.Server.Singularity.EntitySystems
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class EmitterSystem : SharedEmitterSystem
|
public sealed class EmitterSystem : SharedEmitterSystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
@@ -46,8 +42,6 @@ namespace Content.Server.Singularity.EntitySystems
|
|||||||
SubscribeLocalEvent<EmitterComponent, PowerConsumerReceivedChanged>(ReceivedChanged);
|
SubscribeLocalEvent<EmitterComponent, PowerConsumerReceivedChanged>(ReceivedChanged);
|
||||||
SubscribeLocalEvent<EmitterComponent, PowerChangedEvent>(OnApcChanged);
|
SubscribeLocalEvent<EmitterComponent, PowerChangedEvent>(OnApcChanged);
|
||||||
SubscribeLocalEvent<EmitterComponent, ActivateInWorldEvent>(OnActivate);
|
SubscribeLocalEvent<EmitterComponent, ActivateInWorldEvent>(OnActivate);
|
||||||
SubscribeLocalEvent<EmitterComponent, GetVerbsEvent<Verb>>(OnGetVerb);
|
|
||||||
SubscribeLocalEvent<EmitterComponent, ExaminedEvent>(OnExamined);
|
|
||||||
SubscribeLocalEvent<EmitterComponent, AnchorStateChangedEvent>(OnAnchorStateChanged);
|
SubscribeLocalEvent<EmitterComponent, AnchorStateChangedEvent>(OnAnchorStateChanged);
|
||||||
SubscribeLocalEvent<EmitterComponent, SignalReceivedEvent>(OnSignalReceived);
|
SubscribeLocalEvent<EmitterComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
}
|
}
|
||||||
@@ -99,47 +93,6 @@ namespace Content.Server.Singularity.EntitySystems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetVerb(EntityUid uid, EmitterComponent component, GetVerbsEvent<Verb> args)
|
|
||||||
{
|
|
||||||
if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (TryComp<LockComponent>(uid, out var lockComp) && lockComp.Locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (component.SelectableTypes.Count < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var type in component.SelectableTypes)
|
|
||||||
{
|
|
||||||
var proto = _prototype.Index<EntityPrototype>(type);
|
|
||||||
|
|
||||||
var v = new Verb
|
|
||||||
{
|
|
||||||
Priority = 1,
|
|
||||||
Category = VerbCategory.SelectType,
|
|
||||||
Text = proto.Name,
|
|
||||||
Disabled = type == component.BoltType,
|
|
||||||
Impact = LogImpact.Medium,
|
|
||||||
DoContactInteraction = true,
|
|
||||||
Act = () =>
|
|
||||||
{
|
|
||||||
component.BoltType = type;
|
|
||||||
_popup.PopupEntity(Loc.GetString("emitter-component-type-set", ("type", proto.Name)), uid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
args.Verbs.Add(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnExamined(EntityUid uid, EmitterComponent component, ExaminedEvent args)
|
|
||||||
{
|
|
||||||
if (component.SelectableTypes.Count < 2)
|
|
||||||
return;
|
|
||||||
var proto = _prototype.Index<EntityPrototype>(component.BoltType);
|
|
||||||
args.PushMarkup(Loc.GetString("emitter-component-current-type", ("type", proto.Name)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReceivedChanged(
|
private void ReceivedChanged(
|
||||||
EntityUid uid,
|
EntityUid uid,
|
||||||
EmitterComponent component,
|
EmitterComponent component,
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ using Content.Shared.DeviceLinking;
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
|
||||||
|
|
||||||
namespace Content.Shared.Singularity.Components;
|
namespace Content.Shared.Singularity.Components;
|
||||||
|
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
public sealed partial class EmitterComponent : Component
|
public sealed partial class EmitterComponent : Component
|
||||||
{
|
{
|
||||||
public CancellationTokenSource? TimerCancel;
|
public CancellationTokenSource? TimerCancel;
|
||||||
@@ -27,8 +25,8 @@ public sealed partial class EmitterComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity that is spawned when the emitter fires.
|
/// The entity that is spawned when the emitter fires.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("boltType", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
[DataField, AutoNetworkedField]
|
||||||
public string BoltType = "EmitterBolt";
|
public EntProtoId BoltType = "EmitterBolt";
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public List<EntProtoId> SelectableTypes = new();
|
public List<EntProtoId> SelectableTypes = new();
|
||||||
@@ -36,68 +34,68 @@ public sealed partial class EmitterComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current amount of power being used.
|
/// The current amount of power being used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("powerUseActive")]
|
[DataField]
|
||||||
public int PowerUseActive = 600;
|
public int PowerUseActive = 600;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of shots that are fired in a single "burst"
|
/// The amount of shots that are fired in a single "burst"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fireBurstSize")]
|
[DataField]
|
||||||
public int FireBurstSize = 3;
|
public int FireBurstSize = 3;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time between each shot during a burst.
|
/// The time between each shot during a burst.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fireInterval")]
|
[DataField]
|
||||||
public TimeSpan FireInterval = TimeSpan.FromSeconds(2);
|
public TimeSpan FireInterval = TimeSpan.FromSeconds(2);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current minimum delay between bursts.
|
/// The current minimum delay between bursts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fireBurstDelayMin")]
|
[DataField]
|
||||||
public TimeSpan FireBurstDelayMin = TimeSpan.FromSeconds(4);
|
public TimeSpan FireBurstDelayMin = TimeSpan.FromSeconds(4);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The current maximum delay between bursts.
|
/// The current maximum delay between bursts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fireBurstDelayMax")]
|
[DataField]
|
||||||
public TimeSpan FireBurstDelayMax = TimeSpan.FromSeconds(10);
|
public TimeSpan FireBurstDelayMax = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The visual state that is set when the emitter is turned on
|
/// The visual state that is set when the emitter is turned on
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("onState")]
|
[DataField]
|
||||||
public string? OnState = "beam";
|
public string? OnState = "beam";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The visual state that is set when the emitter doesn't have enough power.
|
/// The visual state that is set when the emitter doesn't have enough power.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("underpoweredState")]
|
[DataField]
|
||||||
public string? UnderpoweredState = "underpowered";
|
public string? UnderpoweredState = "underpowered";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signal port that turns on the emitter.
|
/// Signal port that turns on the emitter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
|
[DataField]
|
||||||
public string OnPort = "On";
|
public ProtoId<SinkPortPrototype> OnPort = "On";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signal port that turns off the emitter.
|
/// Signal port that turns off the emitter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
|
[DataField]
|
||||||
public string OffPort = "Off";
|
public ProtoId<SinkPortPrototype> OffPort = "Off";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Signal port that toggles the emitter on or off.
|
/// Signal port that toggles the emitter on or off.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
|
[DataField]
|
||||||
public string TogglePort = "Toggle";
|
public ProtoId<SinkPortPrototype> TogglePort = "Toggle";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Map of signal ports to entity prototype IDs of the entity that will be fired.
|
/// Map of signal ports to entity prototype IDs of the entity that will be fired.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("setTypePorts", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<string, SinkPortPrototype>))]
|
[DataField]
|
||||||
public Dictionary<string, string> SetTypePorts = new();
|
public Dictionary<ProtoId<SinkPortPrototype>, EntProtoId> SetTypePorts = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
[NetSerializable, Serializable]
|
[NetSerializable, Serializable]
|
||||||
|
|||||||
@@ -1,6 +1,66 @@
|
|||||||
namespace Content.Shared.Singularity.EntitySystems;
|
using Content.Shared.Database;
|
||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Lock;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Singularity.Components;
|
||||||
|
using Content.Shared.Verbs;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.Singularity.EntitySystems;
|
||||||
|
|
||||||
public abstract class SharedEmitterSystem : EntitySystem
|
public abstract class SharedEmitterSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<EmitterComponent, ExaminedEvent>(OnExamined);
|
||||||
|
SubscribeLocalEvent<EmitterComponent, GetVerbsEvent<Verb>>(OnGetVerb);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetVerb(Entity<EmitterComponent> ent, ref GetVerbsEvent<Verb> args)
|
||||||
|
{
|
||||||
|
if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract || args.Hands == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TryComp<LockComponent>(ent.Owner, out var lockComp) && lockComp.Locked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.SelectableTypes.Count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var type in ent.Comp.SelectableTypes)
|
||||||
|
{
|
||||||
|
var proto = _prototype.Index(type);
|
||||||
|
|
||||||
|
var v = new Verb
|
||||||
|
{
|
||||||
|
Priority = 1,
|
||||||
|
Category = VerbCategory.SelectType,
|
||||||
|
Text = proto.Name,
|
||||||
|
Disabled = type == ent.Comp.BoltType,
|
||||||
|
Impact = LogImpact.Medium,
|
||||||
|
DoContactInteraction = true,
|
||||||
|
Act = () =>
|
||||||
|
{
|
||||||
|
ent.Comp.BoltType = type;
|
||||||
|
Dirty(ent);
|
||||||
|
_popup.PopupClient(Loc.GetString("emitter-component-type-set", ("type", proto.Name)), ent.Owner);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
args.Verbs.Add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamined(Entity<EmitterComponent> ent, ref ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (ent.Comp.SelectableTypes.Count < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var proto = _prototype.Index(ent.Comp.BoltType);
|
||||||
|
args.PushMarkup(Loc.GetString("emitter-component-current-type", ("type", proto.Name)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user