From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sun, 5 Jan 2025 19:06:10 +0000 (+0000) Subject: wielding refactor/fixes (#32188) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=0aebc76feb86095514fbc572879691cf3d892e50;p=space-station-14.git wielding refactor/fixes (#32188) * refactor wieldable events * fix inconsitency with wielding and use updated events * wieldable cosmetic refactoring * Update Content.Shared/Wieldable/Events.cs Co-authored-by: Centronias * real Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> --------- Co-authored-by: deltanedas <@deltanedas:kde.org> Co-authored-by: Centronias Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> --- diff --git a/Content.Shared/Wieldable/BeforeUnwieldEvent.cs b/Content.Shared/Wieldable/BeforeUnwieldEvent.cs deleted file mode 100644 index 4328ba50c4..0000000000 --- a/Content.Shared/Wieldable/BeforeUnwieldEvent.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Content.Shared.Wieldable; - -public sealed class BeforeUnwieldEvent : CancellableEntityEventArgs -{ -} \ No newline at end of file diff --git a/Content.Shared/Wieldable/BeforeWieldEvent.cs b/Content.Shared/Wieldable/BeforeWieldEvent.cs deleted file mode 100644 index 744a009f9c..0000000000 --- a/Content.Shared/Wieldable/BeforeWieldEvent.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Content.Shared.Wieldable; - -public sealed class BeforeWieldEvent : CancellableEntityEventArgs -{ -} \ No newline at end of file diff --git a/Content.Shared/Wieldable/Events.cs b/Content.Shared/Wieldable/Events.cs new file mode 100644 index 0000000000..fe7e084c02 --- /dev/null +++ b/Content.Shared/Wieldable/Events.cs @@ -0,0 +1,43 @@ +namespace Content.Shared.Wieldable; + +/// +/// Raised directed on an item when it is wielded. +/// +[ByRefEvent] +public readonly record struct ItemWieldedEvent(EntityUid User); + +/// +/// Raised directed on an item that has been unwielded. +/// Force is whether the item is being forced to be unwielded, or if the player chose to unwield it themselves. +/// +[ByRefEvent] +public readonly record struct ItemUnwieldedEvent(EntityUid User, bool Force); + +/// +/// Raised directed on an item before a user tries to wield it. +/// If this event is cancelled wielding will not happen. +/// +[ByRefEvent] +public record struct WieldAttemptEvent(EntityUid User, bool Cancelled = false) +{ + public void Cancel() + { + Cancelled = true; + } +} + +/// +/// Raised directed on an item before a user tries to stop wielding it willingly. +/// If this event is cancelled unwielding will not happen. +/// +/// +/// This event is not raised if the user is forced to unwield the item. +/// +[ByRefEvent] +public record struct UnwieldAttemptEvent(EntityUid User, bool Cancelled = false) +{ + public void Cancel() + { + Cancelled = true; + } +} diff --git a/Content.Shared/Wieldable/ItemUnwieldedEvent.cs b/Content.Shared/Wieldable/ItemUnwieldedEvent.cs deleted file mode 100644 index f980d45802..0000000000 --- a/Content.Shared/Wieldable/ItemUnwieldedEvent.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Content.Shared.Wieldable; - -#region Events - -/// -/// Raised on the item that has been unwielded. -/// -public sealed class ItemUnwieldedEvent : EntityEventArgs -{ - public EntityUid? User; - /// - /// Whether the item is being forced to be unwielded, or if the player chose to unwield it themselves. - /// - public bool Force; - - public ItemUnwieldedEvent(EntityUid? user = null, bool force=false) - { - User = user; - Force = force; - } -} - -#endregion diff --git a/Content.Shared/Wieldable/ItemWieldedEvent.cs b/Content.Shared/Wieldable/ItemWieldedEvent.cs deleted file mode 100644 index 15e204728a..0000000000 --- a/Content.Shared/Wieldable/ItemWieldedEvent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Shared.Wieldable; - -/// -/// Raised directed on an entity when it is wielded. -/// -[ByRefEvent] -public readonly record struct ItemWieldedEvent; diff --git a/Content.Shared/Wieldable/WieldableDoAfterEvent.cs b/Content.Shared/Wieldable/WieldableDoAfterEvent.cs deleted file mode 100644 index 8431de9b26..0000000000 --- a/Content.Shared/Wieldable/WieldableDoAfterEvent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.DoAfter; -using Robust.Shared.Serialization; - -namespace Content.Shared.Wieldable; - -[Serializable, NetSerializable] -public sealed partial class WieldableDoAfterEvent : SimpleDoAfterEvent -{ -} diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index 0a193576bf..200a50d28f 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -25,16 +25,16 @@ namespace Content.Shared.Wieldable; public sealed class WieldableSystem : EntitySystem { - [Dependency] private readonly SharedVirtualItemSystem _virtualItemSystem = default!; - [Dependency] private readonly SharedHandsSystem _handsSystem = default!; - [Dependency] private readonly SharedItemSystem _itemSystem = default!; - [Dependency] private readonly SharedPopupSystem _popupSystem = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly UseDelaySystem _delay = default!; - [Dependency] private readonly SharedGunSystem _gun = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly INetManager _netManager = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedGunSystem _gun = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly SharedItemSystem _item = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedVirtualItemSystem _virtualItem = default!; + [Dependency] private readonly UseDelaySystem _delay = default!; public override void Initialize() { @@ -82,7 +82,7 @@ public sealed class WieldableSystem : EntitySystem { component.LastPopup = time; var message = Loc.GetString("wieldable-component-requires", ("item", uid)); - _popupSystem.PopupClient(message, args.Used, args.User); + _popup.PopupClient(message, args.Used, args.User); } } } @@ -99,8 +99,7 @@ public sealed class WieldableSystem : EntitySystem private void OnDeselectWieldable(EntityUid uid, WieldableComponent component, HandDeselectedEvent args) { - if (!component.Wielded || - _handsSystem.EnumerateHands(args.User).Count() > 2) + if (_hands.EnumerateHands(args.User).Count() > 2) return; TryUnwield(uid, component, args.User); @@ -138,7 +137,7 @@ public sealed class WieldableSystem : EntitySystem if (args.Hands == null || !args.CanAccess || !args.CanInteract) return; - if (!_handsSystem.IsHolding(args.User, uid, out _, args.Hands)) + if (!_hands.IsHolding(args.User, uid, out _, args.Hands)) return; // TODO VERB TOOLTIPS Make CanWield or some other function return string, set as verb tooltip and disable @@ -170,28 +169,28 @@ public sealed class WieldableSystem : EntitySystem public bool CanWield(EntityUid uid, WieldableComponent component, EntityUid user, bool quiet = false) { // Do they have enough hands free? - if (!EntityManager.TryGetComponent(user, out var hands)) + if (!TryComp(user, out var hands)) { if (!quiet) - _popupSystem.PopupClient(Loc.GetString("wieldable-component-no-hands"), user, user); + _popup.PopupClient(Loc.GetString("wieldable-component-no-hands"), user, user); return false; } // Is it.. actually in one of their hands? - if (!_handsSystem.IsHolding(user, uid, out _, hands)) + if (!_hands.IsHolding(user, uid, out _, hands)) { if (!quiet) - _popupSystem.PopupClient(Loc.GetString("wieldable-component-not-in-hands", ("item", uid)), user, user); + _popup.PopupClient(Loc.GetString("wieldable-component-not-in-hands", ("item", uid)), user, user); return false; } - if (_handsSystem.CountFreeableHands((user, hands)) < component.FreeHandsRequired) + if (_hands.CountFreeableHands((user, hands)) < component.FreeHandsRequired) { if (!quiet) { var message = Loc.GetString("wieldable-component-not-enough-free-hands", ("number", component.FreeHandsRequired), ("item", uid)); - _popupSystem.PopupClient(message, user, user); + _popup.PopupClient(message, user, user); } return false; } @@ -209,22 +208,26 @@ public sealed class WieldableSystem : EntitySystem if (!CanWield(used, component, user)) return false; - var ev = new BeforeWieldEvent(); - RaiseLocalEvent(used, ev); + if (TryComp(used, out UseDelayComponent? useDelay) + && !_delay.TryResetDelay((used, useDelay), true)) + return false; + + var attemptEv = new WieldAttemptEvent(user); + RaiseLocalEvent(used, ref attemptEv); - if (ev.Cancelled) + if (attemptEv.Cancelled) return false; if (TryComp(used, out var item)) { component.OldInhandPrefix = item.HeldPrefix; - _itemSystem.SetHeldPrefix(used, component.WieldedInhandPrefix, component: item); + _item.SetHeldPrefix(used, component.WieldedInhandPrefix, component: item); } - component.Wielded = true; + SetWielded((used, component), true); if (component.WieldSound != null) - _audioSystem.PlayPredicted(component.WieldSound, used, user); + _audio.PlayPredicted(component.WieldSound, used, user); //This section handles spawning the virtual item(s) to occupy the required additional hand(s). //Since the client can't currently predict entity spawning, only do this if this is running serverside. @@ -234,7 +237,7 @@ public sealed class WieldableSystem : EntitySystem var virtuals = new List(); for (var i = 0; i < component.FreeHandsRequired; i++) { - if (_virtualItemSystem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true)) + if (_virtualItem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true)) { virtuals.Add(virtualItem.Value); continue; @@ -249,78 +252,79 @@ public sealed class WieldableSystem : EntitySystem } } - if (TryComp(used, out UseDelayComponent? useDelay) - && !_delay.TryResetDelay((used, useDelay), true)) - return false; - var selfMessage = Loc.GetString("wieldable-component-successful-wield", ("item", used)); var othersMessage = Loc.GetString("wieldable-component-successful-wield-other", ("user", Identity.Entity(user, EntityManager)), ("item", used)); - _popupSystem.PopupPredicted(selfMessage, othersMessage, user, user); + _popup.PopupPredicted(selfMessage, othersMessage, user, user); - var targEv = new ItemWieldedEvent(); - RaiseLocalEvent(used, ref targEv); + var ev = new ItemWieldedEvent(user); + RaiseLocalEvent(used, ref ev); - Dirty(used, component); return true; } /// - /// Attempts to unwield an item, with no DoAfter. + /// Attempts to unwield an item, with no use delay. /// /// True if the attempt wasn't blocked. - public bool TryUnwield(EntityUid used, WieldableComponent component, EntityUid user) + public bool TryUnwield(EntityUid used, WieldableComponent component, EntityUid user, bool force = false) { - var ev = new BeforeUnwieldEvent(); - RaiseLocalEvent(used, ev); + if (!component.Wielded) + return false; // already unwielded - if (ev.Cancelled) - return false; + if (!force) + { + var attemptEv = new UnwieldAttemptEvent(user); + RaiseLocalEvent(used, ref attemptEv); + + if (attemptEv.Cancelled) + return false; + } - component.Wielded = false; - var targEv = new ItemUnwieldedEvent(user); + SetWielded((used, component), false); - RaiseLocalEvent(used, targEv); + var ev = new ItemUnwieldedEvent(user, force); + RaiseLocalEvent(used, ref ev); return true; } + /// + /// Sets wielded without doing any checks. + /// + private void SetWielded(Entity ent, bool wielded) + { + ent.Comp.Wielded = wielded; + Dirty(ent); + _appearance.SetData(ent, WieldableVisuals.Wielded, wielded); + } + private void OnItemUnwielded(EntityUid uid, WieldableComponent component, ItemUnwieldedEvent args) { - if (args.User == null) - return; + _item.SetHeldPrefix(uid, component.OldInhandPrefix); - if (TryComp(uid, out var item)) - { - _itemSystem.SetHeldPrefix(uid, component.OldInhandPrefix, component: item); - } + var user = args.User; + _virtualItem.DeleteInHandsMatching(user, uid); if (!args.Force) // don't play sound/popup if this was a forced unwield { if (component.UnwieldSound != null) - _audioSystem.PlayPredicted(component.UnwieldSound, uid, args.User); + _audio.PlayPredicted(component.UnwieldSound, uid, user); var selfMessage = Loc.GetString("wieldable-component-failed-wield", ("item", uid)); - var othersMessage = Loc.GetString("wieldable-component-failed-wield-other", ("user", Identity.Entity(args.User.Value, EntityManager)), ("item", uid)); - _popupSystem.PopupPredicted(selfMessage, othersMessage, args.User.Value, args.User.Value); + var othersMessage = Loc.GetString("wieldable-component-failed-wield-other", ("user", Identity.Entity(args.User, EntityManager)), ("item", uid)); + _popup.PopupPredicted(selfMessage, othersMessage, user, user); } - - _appearance.SetData(uid, WieldableVisuals.Wielded, false); - - Dirty(uid, component); - _virtualItemSystem.DeleteInHandsMatching(args.User.Value, uid); } private void OnItemLeaveHand(EntityUid uid, WieldableComponent component, GotUnequippedHandEvent args) { - if (!component.Wielded || uid != args.Unequipped) - return; - - RaiseLocalEvent(uid, new ItemUnwieldedEvent(args.User, force: true), true); + if (uid == args.Unequipped) + TryUnwield(uid, component, args.User, force: true); } private void OnVirtualItemDeleted(EntityUid uid, WieldableComponent component, VirtualItemDeletedEvent args) { - if (args.BlockingEntity == uid && component.Wielded) - TryUnwield(args.BlockingEntity, component, args.User); + if (args.BlockingEntity == uid) + TryUnwield(uid, component, args.User, force: true); } private void OnGetMeleeDamage(EntityUid uid, IncreaseDamageOnWieldComponent component, ref GetMeleeDamageEvent args)