diff --git a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs index 99ea516f74..67a04d9601 100644 --- a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.Storage; using Content.Shared.Verbs; using Content.Shared.Destructible; using Content.Shared.DoAfter; +using Content.Shared.Hands.Components; using Content.Shared.Kitchen; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; @@ -72,12 +73,17 @@ public sealed class SharpSystem : EntitySystem if (!sharp.Butchering.Add(target)) return false; + // if the user isn't the entity with the sharp component, + // they will need to be holding something with their hands, so we set needHand to true + // so that the doafter can be interrupted if they drop the item in their hands + var needHand = user != knife; + var doAfter = new DoAfterArgs(EntityManager, user, sharp.ButcherDelayModifier * butcher.ButcherDelay, new SharpDoAfterEvent(), knife, target: target, used: knife) { BreakOnDamage = true, BreakOnMove = true, - NeedHand = true, + NeedHand = needHand, }; _doAfterSystem.TryStartDoAfter(doAfter); return true; @@ -136,13 +142,20 @@ public sealed class SharpSystem : EntitySystem private void OnGetInteractionVerbs(EntityUid uid, ButcherableComponent component, GetVerbsEvent args) { - if (component.Type != ButcheringType.Knife || args.Hands == null || !args.CanAccess || !args.CanInteract) + if (component.Type != ButcheringType.Knife || !args.CanAccess || !args.CanInteract) return; - bool disabled = false; + // if the user has no hands, don't show them the verb if they have no SharpComponent either + if (!TryComp(args.User, out var userSharpComp) && args.Hands == null) + return; + + var disabled = false; string? message = null; - if (!HasComp(args.Using)) + // if the user has hands + // and the item they're holding doesn't have the SharpComponent + // disable the verb + if (!TryComp(args.Using, out var usingSharpComp) && args.Hands != null) { disabled = true; message = Loc.GetString("butcherable-need-knife", @@ -150,9 +163,9 @@ public sealed class SharpSystem : EntitySystem } else if (_containerSystem.IsEntityInContainer(uid)) { + disabled = true; message = Loc.GetString("butcherable-not-in-container", ("target", uid)); - disabled = true; } else if (TryComp(uid, out var state) && !_mobStateSystem.IsDead(uid, state)) { @@ -160,12 +173,20 @@ public sealed class SharpSystem : EntitySystem message = Loc.GetString("butcherable-mob-isnt-dead"); } + // set the object doing the butchering to the item in the user's hands or to the user themselves + // if either has the SharpComponent + EntityUid sharpObject = default; + if (usingSharpComp != null) + sharpObject = args.Using!.Value; + else if (userSharpComp != null) + sharpObject = args.User; + InteractionVerb verb = new() { Act = () => { if (!disabled) - TryStartButcherDoafter(args.Using!.Value, args.Target, args.User); + TryStartButcherDoafter(sharpObject, args.Target, args.User); }, Message = message, Disabled = disabled, diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index f62d8011d9..19bf16a94c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -121,6 +121,7 @@ - type: Grammar attributes: gender: male + - type: Sharp - type: entity id: MobRatKingBuff