Rejigging Item slots (#4933)
* itemslot overhaul * remove "shared" prefix * handle component shutdown * comments, cleanup, tests * comments and minor tweak * rename ItemSlotManagerState * fix swapping * fix merge * Add ItemSlot verb text override * fix merge (IEntity -> entityUid) * Fix merge (LabelSystem) * Fix merge (nuke disk) * fix test
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
@@ -21,10 +22,11 @@ namespace Content.Server.Cabinet
|
||||
public SoundSpecifier DoorSound { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The slot name, used to get the actual item slot from the ItemSlotsComponent.
|
||||
/// 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")]
|
||||
public string CabinetSlot = "cabinetSlot";
|
||||
public ItemSlot CabinetSlot = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the cabinet is currently open or not.
|
||||
|
||||
@@ -4,54 +4,63 @@ using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Player;
|
||||
using System;
|
||||
|
||||
namespace Content.Server.Cabinet
|
||||
{
|
||||
public class ItemCabinetSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedItemSlotsSystem _itemSlotsSystem = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ItemCabinetComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, InteractHandEvent>(OnInteractHand);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ComponentRemove>(OnComponentRemove);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(OnComponentStartup);
|
||||
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ActivateInWorldEvent>(OnActivateInWorld);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(InitializeAppearance);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, GetActivationVerbsEvent>(AddToggleOpenVerb);
|
||||
|
||||
SubscribeLocalEvent<ItemCabinetComponent, EntInsertedIntoContainerMessage>(OnContainerModified);
|
||||
SubscribeLocalEvent<ItemCabinetComponent, EntRemovedFromContainerMessage>(OnContainerModified);
|
||||
}
|
||||
|
||||
private void InitializeAppearance(EntityUid uid, ItemCabinetComponent component, ComponentStartup args)
|
||||
private void OnComponentInit(EntityUid uid, ItemCabinetComponent cabinet, ComponentInit args)
|
||||
{
|
||||
UpdateAppearance(uid, component);
|
||||
_itemSlotsSystem.AddItemSlot(uid, cabinet.Name, cabinet.CabinetSlot);
|
||||
}
|
||||
private void OnComponentRemove(EntityUid uid, ItemCabinetComponent cabinet, ComponentRemove args)
|
||||
{
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, cabinet.CabinetSlot);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(EntityUid uid, ItemCabinetComponent cabinet, ComponentStartup args)
|
||||
{
|
||||
UpdateAppearance(uid, cabinet);
|
||||
_itemSlotsSystem.SetLock(uid, cabinet.CabinetSlot.ID, !cabinet.Opened);
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid,
|
||||
ItemCabinetComponent? cabinet = null,
|
||||
SharedItemSlotsComponent? itemSlots = null,
|
||||
SharedAppearanceComponent? appearance = null)
|
||||
{
|
||||
if (!Resolve(uid, ref cabinet, ref itemSlots, ref appearance, false))
|
||||
if (!Resolve(uid, ref cabinet, ref appearance, false))
|
||||
return;
|
||||
|
||||
appearance.SetData(ItemCabinetVisuals.IsOpen, cabinet.Opened);
|
||||
|
||||
if (!itemSlots.Slots.TryGetValue(cabinet.CabinetSlot, out var slot))
|
||||
return;
|
||||
|
||||
appearance.SetData(ItemCabinetVisuals.ContainsItem, slot.HasEntity);
|
||||
appearance.SetData(ItemCabinetVisuals.ContainsItem, cabinet.CabinetSlot.HasItem);
|
||||
}
|
||||
|
||||
private void OnItemSlotChanged(EntityUid uid, ItemCabinetComponent cabinet, ItemSlotChangedEvent args)
|
||||
private void OnContainerModified(EntityUid uid, ItemCabinetComponent cabinet, ContainerModifiedMessage args)
|
||||
{
|
||||
UpdateAppearance(uid, cabinet, args.SlotsComponent);
|
||||
if (args.Container.ID == cabinet.CabinetSlot.ID)
|
||||
UpdateAppearance(uid, cabinet);
|
||||
}
|
||||
|
||||
private void AddToggleOpenVerb(EntityUid uid, ItemCabinetComponent cabinet, GetActivationVerbsEvent args)
|
||||
@@ -75,44 +84,6 @@ namespace Content.Server.Cabinet
|
||||
args.Verbs.Add(toggleVerb);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try insert an item if the cabinet is opened. Otherwise, just try open it.
|
||||
/// </summary>
|
||||
private void OnInteractUsing(EntityUid uid, ItemCabinetComponent comp, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!comp.Opened)
|
||||
ToggleItemCabinet(uid, comp);
|
||||
else
|
||||
_itemSlotsSystem.TryInsertContent(uid, args.Used, args.User);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the cabinet is opened and has an entity, try and take it. Otherwise toggle the cabinet open/closed;
|
||||
/// </summary>
|
||||
private void OnInteractHand(EntityUid uid, ItemCabinetComponent comp, InteractHandEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent itemSlots))
|
||||
return;
|
||||
|
||||
if (!itemSlots.Slots.TryGetValue(comp.CabinetSlot, out var slot))
|
||||
return;
|
||||
|
||||
if (comp.Opened && slot.HasEntity)
|
||||
_itemSlotsSystem.TryEjectContent(uid, comp.CabinetSlot, args.User);
|
||||
else
|
||||
ToggleItemCabinet(uid, comp);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnActivateInWorld(EntityUid uid, ItemCabinetComponent comp, ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
@@ -132,6 +103,7 @@ namespace Content.Server.Cabinet
|
||||
|
||||
cabinet.Opened = !cabinet.Opened;
|
||||
SoundSystem.Play(Filter.Pvs(uid), cabinet.DoorSound.GetSound(), uid, AudioHelpers.WithVariation(0.15f));
|
||||
_itemSlotsSystem.SetLock(uid, cabinet.CabinetSlot.ID, !cabinet.Opened);
|
||||
|
||||
UpdateAppearance(uid, cabinet);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Content.Server.Cargo.Components
|
||||
{
|
||||
|
||||
//This entire class is a PLACEHOLDER for the cargo shuttle.
|
||||
//welp only need auto-docking now.
|
||||
|
||||
[RegisterComponent]
|
||||
public class CargoTelepadComponent : Component
|
||||
@@ -136,10 +137,9 @@ namespace Content.Server.Cargo.Components
|
||||
("approver", data.Approver)));
|
||||
|
||||
// attempt to attach the label
|
||||
if (_entityManager.TryGetComponent(product.Uid, out PaperLabelComponent label) &&
|
||||
_entityManager.TryGetComponent(product.Uid, out SharedItemSlotsComponent slots))
|
||||
if (_entityManager.TryGetComponent(product.Uid, out PaperLabelComponent label))
|
||||
{
|
||||
EntitySystem.Get<SharedItemSlotsSystem>().TryInsertContent(slots, printed, label.LabelSlot);
|
||||
EntitySystem.Get<ItemSlotsSystem>().TryInsert(OwnerUid, label.LabelSlot, printed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
@@ -12,6 +13,6 @@ namespace Content.Server.Labels.Components
|
||||
public override string Name => "PaperLabel";
|
||||
|
||||
[DataField("labelSlot")]
|
||||
public string LabelSlot = "labelSlot";
|
||||
public ItemSlot LabelSlot = new();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Labels;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Utility;
|
||||
using System;
|
||||
|
||||
namespace Content.Server.Labels
|
||||
{
|
||||
@@ -18,26 +18,35 @@ namespace Content.Server.Labels
|
||||
[UsedImplicitly]
|
||||
public class LabelSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedItemSlotsSystem _itemSlotsSystem = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LabelComponent, ExaminedEvent>(OnExamine);
|
||||
SubscribeLocalEvent<PaperLabelComponent, ComponentInit>(InitializePaperLabel);
|
||||
SubscribeLocalEvent<PaperLabelComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
|
||||
SubscribeLocalEvent<PaperLabelComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<PaperLabelComponent, ComponentRemove>(OnComponentRemove);
|
||||
SubscribeLocalEvent<PaperLabelComponent, EntInsertedIntoContainerMessage>(OnContainerModified);
|
||||
SubscribeLocalEvent<PaperLabelComponent, EntRemovedFromContainerMessage>(OnContainerModified);
|
||||
SubscribeLocalEvent<PaperLabelComponent, ExaminedEvent>(OnExamined);
|
||||
}
|
||||
|
||||
private void InitializePaperLabel(EntityUid uid, PaperLabelComponent component, ComponentInit args)
|
||||
private void OnComponentInit(EntityUid uid, PaperLabelComponent component, ComponentInit args)
|
||||
{
|
||||
_itemSlotsSystem.AddItemSlot(uid, component.Name, component.LabelSlot);
|
||||
|
||||
if (!EntityManager.TryGetComponent(uid, out SharedAppearanceComponent appearance))
|
||||
return;
|
||||
|
||||
appearance.SetData(PaperLabelVisuals.HasLabel, false);
|
||||
}
|
||||
|
||||
private void OnComponentRemove(EntityUid uid, PaperLabelComponent component, ComponentRemove args)
|
||||
{
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, component.LabelSlot);
|
||||
}
|
||||
|
||||
private void OnExamine(EntityUid uid, LabelComponent? label, ExaminedEvent args)
|
||||
{
|
||||
if (!Resolve(uid, ref label))
|
||||
@@ -53,12 +62,7 @@ namespace Content.Server.Labels
|
||||
|
||||
private void OnExamined(EntityUid uid, PaperLabelComponent comp, ExaminedEvent args)
|
||||
{
|
||||
if (!EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent slots))
|
||||
return;
|
||||
|
||||
var label = _itemSlotsSystem.PeekItemInSlot(slots, comp.LabelSlot);
|
||||
|
||||
if (label == null)
|
||||
if (comp.LabelSlot.Item == null)
|
||||
return;
|
||||
|
||||
if (!args.IsInDetailsRange)
|
||||
@@ -67,8 +71,8 @@ namespace Content.Server.Labels
|
||||
return;
|
||||
}
|
||||
|
||||
if (!EntityManager.TryGetComponent(label.Uid, out PaperComponent paper))
|
||||
// should never happen
|
||||
if (!EntityManager.TryGetComponent(comp.LabelSlot.Item.Uid, out PaperComponent paper))
|
||||
// Assuming yaml has the correct entity whitelist, this should not happen.
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(paper.Content))
|
||||
@@ -83,15 +87,15 @@ namespace Content.Server.Labels
|
||||
}
|
||||
|
||||
|
||||
private void OnItemSlotChanged(EntityUid uid, PaperLabelComponent component, ItemSlotChangedEvent args)
|
||||
private void OnContainerModified(EntityUid uid, PaperLabelComponent label, ContainerModifiedMessage args)
|
||||
{
|
||||
if (args.SlotName != component.LabelSlot)
|
||||
if (args.Container.ID != label.LabelSlot.ID)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent(uid, out SharedAppearanceComponent appearance))
|
||||
return;
|
||||
|
||||
appearance.SetData(PaperLabelVisuals.HasLabel, args.ContainedItem != null);
|
||||
appearance.SetData(PaperLabelVisuals.HasLabel, label.LabelSlot.HasItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,12 @@ namespace Content.Server.Nuke
|
||||
public int Timer = 180;
|
||||
|
||||
/// <summary>
|
||||
/// Slot name for to store nuclear disk inside bomb.
|
||||
/// See <see cref="SharedItemSlotsComponent"/> for mor info.
|
||||
/// The <see cref="ItemSlot"/> that stores the nuclear disk. The entity whitelist, sounds, and some other
|
||||
/// behaviours are specified by this <see cref="ItemSlot"/> definition. Make sure the whitelist, is correct
|
||||
/// otherwise a blank bit of paper will work as a "disk".
|
||||
/// </summary>
|
||||
[DataField("slot")]
|
||||
public string DiskSlotName = "DiskSlot";
|
||||
[DataField("diskSlot")]
|
||||
public ItemSlot DiskSlot = new();
|
||||
|
||||
/// <summary>
|
||||
/// Annihilation radius in which all human players will be gibed
|
||||
@@ -71,13 +72,6 @@ namespace Content.Server.Nuke
|
||||
[ViewVariables]
|
||||
public float RemainingTime;
|
||||
|
||||
/// <summary>
|
||||
/// Does bomb contains valid entity inside <see cref="DiskSlotName"/>?
|
||||
/// If it is, user can anchor bomb or enter nuclear code to arm it.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public bool DiskInserted = false;
|
||||
|
||||
/// <summary>
|
||||
/// Curent nuclear code buffer. Entered manually by players.
|
||||
/// If valid it will allow arm/disarm bomb.
|
||||
|
||||
@@ -19,6 +19,7 @@ using Content.Server.Coordinates.Helpers;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Sound;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Nuke
|
||||
{
|
||||
@@ -26,7 +27,7 @@ namespace Content.Server.Nuke
|
||||
{
|
||||
[Dependency] private readonly NukeCodeSystem _codes = default!;
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
[Dependency] private readonly SharedItemSlotsSystem _itemSlots = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlots = default!;
|
||||
[Dependency] private readonly PopupSystem _popups = default!;
|
||||
[Dependency] private readonly IEntityLookup _lookup = default!;
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
@@ -39,7 +40,8 @@ namespace Content.Server.Nuke
|
||||
SubscribeLocalEvent<NukeComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<NukeComponent, ComponentRemove>(OnRemove);
|
||||
SubscribeLocalEvent<NukeComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<NukeComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
|
||||
SubscribeLocalEvent<NukeComponent, EntInsertedIntoContainerMessage>(OnItemSlotChanged);
|
||||
SubscribeLocalEvent<NukeComponent, EntRemovedFromContainerMessage>(OnItemSlotChanged);
|
||||
|
||||
// anchoring logic
|
||||
SubscribeLocalEvent<NukeComponent, AnchorAttemptEvent>(OnAnchorAttempt);
|
||||
@@ -59,6 +61,7 @@ namespace Content.Server.Nuke
|
||||
private void OnInit(EntityUid uid, NukeComponent component, ComponentInit args)
|
||||
{
|
||||
component.RemainingTime = component.Timer;
|
||||
_itemSlots.AddItemSlot(uid, component.Name, component.DiskSlot);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
@@ -93,14 +96,14 @@ namespace Content.Server.Nuke
|
||||
private void OnRemove(EntityUid uid, NukeComponent component, ComponentRemove args)
|
||||
{
|
||||
_tickingBombs.Remove(uid);
|
||||
_itemSlots.RemoveItemSlot(uid, component.DiskSlot);
|
||||
}
|
||||
|
||||
private void OnItemSlotChanged(EntityUid uid, NukeComponent component, ItemSlotChangedEvent args)
|
||||
private void OnItemSlotChanged(EntityUid uid, NukeComponent component, ContainerModifiedMessage args)
|
||||
{
|
||||
if (args.SlotName != component.DiskSlotName)
|
||||
if (args.Container.ID != component.DiskSlot.ID)
|
||||
return;
|
||||
|
||||
component.DiskInserted = args.ContainedItem != null;
|
||||
UpdateStatus(uid, component);
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
@@ -137,7 +140,7 @@ namespace Content.Server.Nuke
|
||||
private void CheckAnchorAttempt(EntityUid uid, NukeComponent component, BaseAnchoredAttemptEvent args)
|
||||
{
|
||||
// cancel any anchor attempt without nuke disk
|
||||
if (!component.DiskInserted)
|
||||
if (!component.DiskSlot.HasItem)
|
||||
{
|
||||
var msg = Loc.GetString("nuke-component-cant-anchor");
|
||||
_popups.PopupEntity(msg, uid, Filter.Entities(args.User));
|
||||
@@ -160,15 +163,15 @@ namespace Content.Server.Nuke
|
||||
#region UI Events
|
||||
private void OnEjectButtonPressed(EntityUid uid, NukeComponent component, NukeEjectMessage args)
|
||||
{
|
||||
if (!component.DiskInserted)
|
||||
if (!component.DiskSlot.HasItem)
|
||||
return;
|
||||
|
||||
_itemSlots.TryEjectContent(uid, component.DiskSlotName, args.Session.AttachedEntity);
|
||||
_itemSlots.TryEjectToHands(uid, component.DiskSlot, args.Session.AttachedEntityUid);
|
||||
}
|
||||
|
||||
private async void OnAnchorButtonPressed(EntityUid uid, NukeComponent component, NukeAnchorMessage args)
|
||||
{
|
||||
if (!component.DiskInserted)
|
||||
if (!component.DiskSlot.HasItem)
|
||||
return;
|
||||
|
||||
if (!EntityManager.TryGetComponent(uid, out TransformComponent? transform))
|
||||
@@ -218,7 +221,7 @@ namespace Content.Server.Nuke
|
||||
|
||||
private void OnArmButtonPressed(EntityUid uid, NukeComponent component, NukeArmedMessage args)
|
||||
{
|
||||
if (!component.DiskInserted)
|
||||
if (!component.DiskSlot.HasItem)
|
||||
return;
|
||||
|
||||
if (component.Status == NukeStatus.AWAIT_ARM)
|
||||
@@ -240,12 +243,12 @@ namespace Content.Server.Nuke
|
||||
switch (component.Status)
|
||||
{
|
||||
case NukeStatus.AWAIT_DISK:
|
||||
if (component.DiskInserted)
|
||||
if (component.DiskSlot.HasItem)
|
||||
component.Status = NukeStatus.AWAIT_CODE;
|
||||
break;
|
||||
case NukeStatus.AWAIT_CODE:
|
||||
{
|
||||
if (!component.DiskInserted)
|
||||
if (!component.DiskSlot.HasItem)
|
||||
{
|
||||
component.Status = NukeStatus.AWAIT_DISK;
|
||||
component.EnteredCode = "";
|
||||
@@ -299,7 +302,7 @@ namespace Content.Server.Nuke
|
||||
if (EntityManager.TryGetComponent(uid, out TransformComponent transform))
|
||||
anchored = transform.Anchored;
|
||||
|
||||
var allowArm = component.DiskInserted &&
|
||||
var allowArm = component.DiskSlot.HasItem &&
|
||||
(component.Status == NukeStatus.AWAIT_ARM ||
|
||||
component.Status == NukeStatus.ARMED);
|
||||
|
||||
@@ -307,7 +310,7 @@ namespace Content.Server.Nuke
|
||||
{
|
||||
Status = component.Status,
|
||||
RemainingTime = (int) component.RemainingTime,
|
||||
DiskInserted = component.DiskInserted,
|
||||
DiskInserted = component.DiskSlot.HasItem,
|
||||
IsAnchored = anchored,
|
||||
AllowArm = allowArm,
|
||||
EnteredCodeLength = component.EnteredCode.Length,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.Access.Components;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.PDA
|
||||
@@ -12,16 +15,19 @@ namespace Content.Server.PDA
|
||||
{
|
||||
public override string Name => "PDA";
|
||||
|
||||
[DataField("idSlot")]
|
||||
public string IdSlot = "pdaIdSlot";
|
||||
[DataField("idSlot")]
|
||||
public ItemSlot IdSlot = new();
|
||||
|
||||
[DataField("penSlot")]
|
||||
public string PenSlot = "pdaPenSlot";
|
||||
public ItemSlot PenSlot = new();
|
||||
|
||||
[ViewVariables] [DataField("idCard")] public string? StartingIdCard;
|
||||
// Really this should just be using ItemSlot.StartingItem. However, seeing as we have so many different starting
|
||||
// PDA's and no nice way to inherit the other fields from the ItemSlot data definition, this makes the yaml much
|
||||
// nicer to read.
|
||||
[DataField("idCard", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string? IdCard;
|
||||
|
||||
[ViewVariables] public IdCardComponent? ContainedID;
|
||||
[ViewVariables] public bool PenInserted;
|
||||
[ViewVariables] public bool FlashlightOn;
|
||||
|
||||
[ViewVariables] public string? OwnerName;
|
||||
|
||||
@@ -9,6 +9,7 @@ using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.PDA;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
@@ -16,7 +17,7 @@ namespace Content.Server.PDA
|
||||
{
|
||||
public class PDASystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedItemSlotsSystem _slotsSystem = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!;
|
||||
[Dependency] private readonly UplinkSystem _uplinkSystem = default!;
|
||||
[Dependency] private readonly UnpoweredFlashlightSystem _unpoweredFlashlight = default!;
|
||||
|
||||
@@ -25,10 +26,12 @@ namespace Content.Server.PDA
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PDAComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<PDAComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<PDAComponent, ComponentRemove>(OnComponentRemove);
|
||||
|
||||
SubscribeLocalEvent<PDAComponent, ActivateInWorldEvent>(OnActivateInWorld);
|
||||
SubscribeLocalEvent<PDAComponent, UseInHandEvent>(OnUse);
|
||||
SubscribeLocalEvent<PDAComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
|
||||
SubscribeLocalEvent<PDAComponent, EntInsertedIntoContainerMessage>(OnItemInserted);
|
||||
SubscribeLocalEvent<PDAComponent, EntRemovedFromContainerMessage>(OnItemRemoved);
|
||||
SubscribeLocalEvent<PDAComponent, LightToggleEvent>(OnLightToggle);
|
||||
|
||||
SubscribeLocalEvent<PDAComponent, UplinkInitEvent>(OnUplinkInit);
|
||||
@@ -41,19 +44,16 @@ namespace Content.Server.PDA
|
||||
if (ui != null)
|
||||
ui.OnReceiveMessage += (msg) => OnUIMessage(pda, msg);
|
||||
|
||||
UpdatePDAAppearance(pda);
|
||||
if (pda.IdCard != null)
|
||||
pda.IdSlot.StartingItem = pda.IdCard;
|
||||
_itemSlotsSystem.AddItemSlot(uid, $"{pda.Name}-id", pda.IdSlot);
|
||||
_itemSlotsSystem.AddItemSlot(uid, $"{pda.Name}-pen", pda.PenSlot);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, PDAComponent pda, MapInitEvent args)
|
||||
private void OnComponentRemove(EntityUid uid, PDAComponent pda, ComponentRemove args)
|
||||
{
|
||||
// try to place ID inside item slot
|
||||
if (!string.IsNullOrEmpty(pda.StartingIdCard))
|
||||
{
|
||||
// if pda prototype doesn't have slots, ID will drop down on ground
|
||||
var idCard = EntityManager.SpawnEntity(pda.StartingIdCard, pda.Owner.Transform.Coordinates);
|
||||
if (EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent? itemSlots))
|
||||
_slotsSystem.TryInsertContent(itemSlots, idCard, pda.IdSlot);
|
||||
}
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, pda.IdSlot);
|
||||
_itemSlotsSystem.RemoveItemSlot(uid, pda.PenSlot);
|
||||
}
|
||||
|
||||
private void OnUse(EntityUid uid, PDAComponent pda, UseInHandEvent args)
|
||||
@@ -70,22 +70,19 @@ namespace Content.Server.PDA
|
||||
args.Handled = OpenUI(pda, args.User);
|
||||
}
|
||||
|
||||
private void OnItemSlotChanged(EntityUid uid, PDAComponent pda, ItemSlotChangedEvent args)
|
||||
private void OnItemInserted(EntityUid uid, PDAComponent pda, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
// check if ID slot changed
|
||||
if (args.SlotName == pda.IdSlot)
|
||||
{
|
||||
var item = args.ContainedItem;
|
||||
if (item == null || !EntityManager.TryGetComponent(item.Value, out IdCardComponent ? idCard))
|
||||
pda.ContainedID = null;
|
||||
else
|
||||
pda.ContainedID = idCard;
|
||||
}
|
||||
else if (args.SlotName == pda.PenSlot)
|
||||
{
|
||||
var item = args.ContainedItem;
|
||||
pda.PenInserted = item != null;
|
||||
}
|
||||
if (args.Container.ID == pda.IdSlot.ID)
|
||||
pda.ContainedID = args.Entity.GetComponentOrNull<IdCardComponent>();
|
||||
|
||||
UpdatePDAAppearance(pda);
|
||||
UpdatePDAUserInterface(pda);
|
||||
}
|
||||
|
||||
private void OnItemRemoved(EntityUid uid, PDAComponent pda, EntRemovedFromContainerMessage args)
|
||||
{
|
||||
if (args.Container.ID == pda.IdSlot.ID)
|
||||
pda.ContainedID = null;
|
||||
|
||||
UpdatePDAAppearance(pda);
|
||||
UpdatePDAUserInterface(pda);
|
||||
@@ -142,11 +139,15 @@ namespace Content.Server.PDA
|
||||
var hasUplink = pda.Owner.HasComponent<UplinkComponent>();
|
||||
|
||||
var ui = pda.Owner.GetUIOrNull(PDAUiKey.Key);
|
||||
ui?.SetState(new PDAUpdateState(pda.FlashlightOn, pda.PenInserted, ownerInfo, hasUplink));
|
||||
ui?.SetState(new PDAUpdateState(pda.FlashlightOn, pda.PenSlot.HasItem, ownerInfo, hasUplink));
|
||||
}
|
||||
|
||||
private void OnUIMessage(PDAComponent pda, ServerBoundUserInterfaceMessage msg)
|
||||
{
|
||||
// cast EntityUid? to EntityUid
|
||||
if (msg.Session.AttachedEntityUid is not EntityUid playerUid)
|
||||
return;
|
||||
|
||||
switch (msg.Message)
|
||||
{
|
||||
case PDARequestUpdateInterfaceMessage _:
|
||||
@@ -161,12 +162,12 @@ namespace Content.Server.PDA
|
||||
|
||||
case PDAEjectIDMessage _:
|
||||
{
|
||||
_slotsSystem.TryEjectContent(pda.Owner.Uid, pda.IdSlot, msg.Session.AttachedEntity);
|
||||
_itemSlotsSystem.TryEjectToHands(pda.Owner.Uid, pda.IdSlot, playerUid);
|
||||
break;
|
||||
}
|
||||
case PDAEjectPenMessage _:
|
||||
{
|
||||
_slotsSystem.TryEjectContent(pda.Owner.Uid, pda.PenSlot, msg.Session.AttachedEntity);
|
||||
_itemSlotsSystem.TryEjectToHands(pda.Owner.Uid, pda.PenSlot, playerUid);
|
||||
break;
|
||||
}
|
||||
case PDAShowUplinkMessage _:
|
||||
|
||||
@@ -136,10 +136,10 @@ namespace Content.Server.Sandbox
|
||||
if (pda.ContainedID == null)
|
||||
{
|
||||
var newID = CreateFreshId();
|
||||
if (pda.Owner.TryGetComponent(out SharedItemSlotsComponent? itemSlots))
|
||||
if (pda.Owner.TryGetComponent(out ItemSlotsComponent? itemSlots))
|
||||
{
|
||||
_entityManager.EntitySysManager.GetEntitySystem<SharedItemSlotsSystem>().
|
||||
TryInsertContent(itemSlots, newID, pda.IdSlot);
|
||||
_entityManager.EntitySysManager.GetEntitySystem<ItemSlotsSystem>().
|
||||
TryInsert(wornItem.Owner.Uid, pda.IdSlot, newID);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user