From 38a8a22e5acaa8b90948025dc56e32e794fe940e Mon Sep 17 00:00:00 2001 From: Rane <60792108+Elijahrane@users.noreply.github.com> Date: Wed, 27 Jul 2022 19:28:23 -0400 Subject: [PATCH] Throwing event improvements (#10055) --- Content.Server/Hands/Systems/HandsSystem.cs | 20 ++++++++++++++----- .../ActionBlocker/ActionBlockerSystem.cs | 4 ++-- Content.Shared/Throwing/BeforeThrowEvent.cs | 18 +++++++++++++++++ Content.Shared/Throwing/ThrowAttemptEvent.cs | 5 ++++- 4 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 Content.Shared/Throwing/BeforeThrowEvent.cs diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index 5f8ee7dd42..ae73a9ebc6 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -190,7 +190,7 @@ namespace Content.Server.Hands.Systems player.IsInContainer() || !TryComp(player, out SharedHandsComponent? hands) || hands.ActiveHandEntity is not EntityUid throwEnt || - !_actionBlockerSystem.CanThrow(player)) + !_actionBlockerSystem.CanThrow(player, throwEnt)) return false; if (EntityManager.TryGetComponent(throwEnt, out StackComponent? stack) && stack.Count > 1 && stack.ThrowIndividually) @@ -202,8 +202,6 @@ namespace Content.Server.Hands.Systems throwEnt = splitStack.Value; } - else if (!TryDrop(player, throwEnt, handsComp: hands)) - return false; var direction = coords.ToMapPos(EntityManager) - Transform(player).WorldPosition; if (direction == Vector2.Zero) @@ -212,11 +210,23 @@ namespace Content.Server.Hands.Systems direction = direction.Normalized * Math.Min(direction.Length, hands.ThrowRange); var throwStrength = hands.ThrowForceMultiplier; - _throwingSystem.TryThrow(throwEnt, direction, throwStrength, player); + + // Let other systems change the thrown entity (useful for virtual items) + // or the throw strength. + var ev = new BeforeThrowEvent(throwEnt, direction, throwStrength, player); + RaiseLocalEvent(player, ev, false); + + if (ev.Handled) + return true; + + // This can grief the above event so we raise it afterwards + if (!TryDrop(player, throwEnt, handsComp: hands)) + return false; + + _throwingSystem.TryThrow(ev.ItemUid, ev.Direction, ev.ThrowStrength, ev.PlayerUid); return true; } - private void HandleSmartEquipBackpack(ICommonSession? session) { HandleSmartEquip(session, "back"); diff --git a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs index f2e47ad8eb..3c0161f2f5 100644 --- a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs +++ b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs @@ -97,9 +97,9 @@ namespace Content.Shared.ActionBlocker return !ev.Cancelled; } - public bool CanThrow(EntityUid user) + public bool CanThrow(EntityUid user, EntityUid itemUid) { - var ev = new ThrowAttemptEvent(user); + var ev = new ThrowAttemptEvent(user, itemUid); RaiseLocalEvent(user, ev, true); return !ev.Cancelled; diff --git a/Content.Shared/Throwing/BeforeThrowEvent.cs b/Content.Shared/Throwing/BeforeThrowEvent.cs new file mode 100644 index 0000000000..349a18c56d --- /dev/null +++ b/Content.Shared/Throwing/BeforeThrowEvent.cs @@ -0,0 +1,18 @@ +namespace Content.Shared.Throwing +{ + public sealed class BeforeThrowEvent : HandledEntityEventArgs + { + public BeforeThrowEvent(EntityUid itemUid, Vector2 direction, float throwStrength, EntityUid playerUid) + { + ItemUid = itemUid; + Direction = direction; + ThrowStrength = throwStrength; + PlayerUid = playerUid; + } + + public EntityUid ItemUid { get; set; } + public Vector2 Direction { get; } + public float ThrowStrength { get; set;} + public EntityUid PlayerUid { get; } + } +} diff --git a/Content.Shared/Throwing/ThrowAttemptEvent.cs b/Content.Shared/Throwing/ThrowAttemptEvent.cs index 23ef048b0a..bf8cad6c74 100644 --- a/Content.Shared/Throwing/ThrowAttemptEvent.cs +++ b/Content.Shared/Throwing/ThrowAttemptEvent.cs @@ -2,12 +2,15 @@ { public sealed class ThrowAttemptEvent : CancellableEntityEventArgs { - public ThrowAttemptEvent(EntityUid uid) + public ThrowAttemptEvent(EntityUid uid, EntityUid itemUid) { Uid = uid; + ItemUid = itemUid; } public EntityUid Uid { get; } + + public EntityUid ItemUid { get; } } ///