ItemToggle + slots stuff (#31312)

* ItemToggle + slots stuff

- Add component for itemslot locks to match LockComponent (surprised this didn't exist).
- Add thing for pointlight to match itemtoggle. In future should be used for PDAs and stuff but need to fix some other stuff first.

* Also this

* grill
This commit is contained in:
metalgearsloth
2024-08-25 22:30:28 +10:00
committed by GitHub
parent a89d4c750b
commit c0a07614c0
10 changed files with 163 additions and 17 deletions

View File

@@ -0,0 +1,13 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Containers.ItemSlots;
/// <summary>
/// Updates the relevant ItemSlots locks based on <see cref="LockComponent"/>
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class ItemSlotsLockComponent : Component
{
[DataField(required: true)]
public List<string> Slots = new();
}

View File

@@ -0,0 +1,36 @@
using Content.Shared.Lock;
namespace Content.Shared.Containers.ItemSlots;
public sealed partial class ItemSlotsSystem
{
private void InitializeLock()
{
SubscribeLocalEvent<ItemSlotsLockComponent, MapInitEvent>(OnLockMapInit);
SubscribeLocalEvent<ItemSlotsLockComponent, LockToggledEvent>(OnLockToggled);
}
private void OnLockMapInit(Entity<ItemSlotsLockComponent> ent, ref MapInitEvent args)
{
if (!TryComp(ent.Owner, out LockComponent? lockComp))
return;
UpdateLocks(ent, lockComp.Locked);
}
private void OnLockToggled(Entity<ItemSlotsLockComponent> ent, ref LockToggledEvent args)
{
UpdateLocks(ent, args.Locked);
}
private void UpdateLocks(Entity<ItemSlotsLockComponent> ent, bool value)
{
foreach (var slot in ent.Comp.Slots)
{
if (!TryGetSlot(ent.Owner, slot, out var itemSlot))
continue;
SetLock(ent.Owner, itemSlot, value);
}
}
}

View File

@@ -24,7 +24,7 @@ namespace Content.Shared.Containers.ItemSlots
/// Note when using popups on entities with many slots with InsertOnInteract, EjectOnInteract or EjectOnUse: /// Note when using popups on entities with many slots with InsertOnInteract, EjectOnInteract or EjectOnUse:
/// A single use will try to insert to/eject from every slot and generate a popup for each that fails. /// A single use will try to insert to/eject from every slot and generate a popup for each that fails.
/// </remarks> /// </remarks>
public sealed class ItemSlotsSystem : EntitySystem public sealed partial class ItemSlotsSystem : EntitySystem
{ {
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
@@ -38,6 +38,8 @@ namespace Content.Shared.Containers.ItemSlots
{ {
base.Initialize(); base.Initialize();
InitializeLock();
SubscribeLocalEvent<ItemSlotsComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<ItemSlotsComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ItemSlotsComponent, ComponentInit>(Oninitialize); SubscribeLocalEvent<ItemSlotsComponent, ComponentInit>(Oninitialize);

View File

@@ -19,6 +19,12 @@ public sealed partial class ItemToggleComponent : Component
[DataField, AutoNetworkedField] [DataField, AutoNetworkedField]
public bool Activated = false; public bool Activated = false;
/// <summary>
/// Can the entity be activated in the world.
/// </summary>
[DataField]
public bool OnActivate = true;
/// <summary> /// <summary>
/// If this is set to false then the item can't be toggled by pressing Z. /// If this is set to false then the item can't be toggled by pressing Z.
/// Use another system to do it then. /// Use another system to do it then.
@@ -52,12 +58,6 @@ public sealed partial class ItemToggleComponent : Component
/// </summary> /// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public SoundSpecifier? SoundFailToActivate; public SoundSpecifier? SoundFailToActivate;
/// <summary>
/// Whether or not to toggle the entity's lights on or off.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool ToggleLight = true;
} }
/// <summary> /// <summary>

View File

@@ -1,8 +1,10 @@
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events; using Content.Shared.Interaction.Events;
using Content.Shared.Item.ItemToggle.Components; using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Temperature; using Content.Shared.Temperature;
using Content.Shared.Toggleable; using Content.Shared.Toggleable;
using Content.Shared.Verbs;
using Content.Shared.Wieldable; using Content.Shared.Wieldable;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
@@ -20,7 +22,6 @@ public sealed class ItemToggleSystem : EntitySystem
[Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPointLightSystem _light = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedPopupSystem _popup = default!;
private EntityQuery<ItemToggleComponent> _query; private EntityQuery<ItemToggleComponent> _query;
@@ -36,6 +37,8 @@ public sealed class ItemToggleSystem : EntitySystem
SubscribeLocalEvent<ItemToggleComponent, ItemUnwieldedEvent>(TurnOffOnUnwielded); SubscribeLocalEvent<ItemToggleComponent, ItemUnwieldedEvent>(TurnOffOnUnwielded);
SubscribeLocalEvent<ItemToggleComponent, ItemWieldedEvent>(TurnOnOnWielded); SubscribeLocalEvent<ItemToggleComponent, ItemWieldedEvent>(TurnOnOnWielded);
SubscribeLocalEvent<ItemToggleComponent, UseInHandEvent>(OnUseInHand); SubscribeLocalEvent<ItemToggleComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<ItemToggleComponent, GetVerbsEvent<ActivationVerb>>(OnActivateVerb);
SubscribeLocalEvent<ItemToggleComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<ItemToggleHotComponent, IsHotEvent>(OnIsHotEvent); SubscribeLocalEvent<ItemToggleHotComponent, IsHotEvent>(OnIsHotEvent);
@@ -66,6 +69,32 @@ public sealed class ItemToggleSystem : EntitySystem
Toggle((ent, ent.Comp), args.User, predicted: ent.Comp.Predictable); Toggle((ent, ent.Comp), args.User, predicted: ent.Comp.Predictable);
} }
private void OnActivateVerb(Entity<ItemToggleComponent> ent, ref GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
var user = args.User;
args.Verbs.Add(new ActivationVerb()
{
Text = !ent.Comp.Activated ? Loc.GetString("item-toggle-activate") : Loc.GetString("item-toggle-deactivate"),
Act = () =>
{
Toggle((ent.Owner, ent.Comp), user, predicted: ent.Comp.Predictable);
}
});
}
private void OnActivate(Entity<ItemToggleComponent> ent, ref ActivateInWorldEvent args)
{
if (args.Handled || !ent.Comp.OnActivate)
return;
args.Handled = true;
Toggle((ent.Owner, ent.Comp), args.User, predicted: ent.Comp.Predictable);
}
/// <summary> /// <summary>
/// Used when an item is attempted to be toggled. /// Used when an item is attempted to be toggled.
/// Sets its state to the opposite of what it is. /// Sets its state to the opposite of what it is.
@@ -203,16 +232,7 @@ public sealed class ItemToggleSystem : EntitySystem
if (TryComp(ent, out AppearanceComponent? appearance)) if (TryComp(ent, out AppearanceComponent? appearance))
{ {
_appearance.SetData(ent, ToggleVisuals.Toggled, ent.Comp.Activated, appearance); _appearance.SetData(ent, ToggleVisuals.Toggled, ent.Comp.Activated, appearance);
if (ent.Comp.ToggleLight)
_appearance.SetData(ent, ToggleableLightVisuals.Enabled, ent.Comp.Activated, appearance);
} }
if (!ent.Comp.ToggleLight)
return;
if (_light.TryGetLight(ent, out var light))
_light.SetEnabled(ent, ent.Comp.Activated, light);
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,12 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Light.Components;
/// <summary>
/// Toggles point light on an entity whenever ItemToggle hits.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class ItemTogglePointLightComponent : Component
{
}

View File

@@ -0,0 +1,29 @@
using Content.Shared.Item.ItemToggle.Components;
using Content.Shared.Toggleable;
using ItemTogglePointLightComponent = Content.Shared.Light.Components.ItemTogglePointLightComponent;
namespace Content.Shared.Light.EntitySystems;
/// <summary>
/// Handles ItemToggle for PointLight
/// </summary>
public sealed class ItemTogglePointLightSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedPointLightSystem _light = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ItemTogglePointLightComponent, ItemToggledEvent>(OnLightToggled);
}
private void OnLightToggled(Entity<ItemTogglePointLightComponent> ent, ref ItemToggledEvent args)
{
if (!_light.TryGetLight(ent.Owner, out var light))
return;
_appearance.SetData(ent, ToggleableLightVisuals.Enabled, args.Activated);
_light.SetEnabled(ent.Owner, args.Activated, comp: light);
}
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Power.Components;
[RegisterComponent, NetworkedComponent]
public sealed partial class ItemSlotRequiresPowerComponent : Component
{
}

View File

@@ -0,0 +1,23 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Power.Components;
namespace Content.Shared.Power.EntitySystems;
public sealed class ItemSlotRequiresPowerSystem : EntitySystem
{
[Dependency] private readonly SharedPowerReceiverSystem _receiver = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ItemSlotRequiresPowerComponent, ItemSlotInsertAttemptEvent>(OnInsertAttempt);
}
private void OnInsertAttempt(Entity<ItemSlotRequiresPowerComponent> ent, ref ItemSlotInsertAttemptEvent args)
{
if (!_receiver.IsPowered(ent.Owner))
{
args.Cancelled = true;
}
}
}

View File

@@ -0,0 +1,2 @@
item-toggle-activate = Activate
item-toggle-deactivate = Deactivate