diff --git a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs index eaca65a2a1..ea3e3bcf73 100644 --- a/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Client/Weapons/Melee/MeleeWeaponSystem.cs @@ -5,6 +5,7 @@ using Content.Client.Weapons.Melee.Components; using Content.Shared.MobState.Components; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; +using Content.Shared.StatusEffect; using Robust.Client.Animations; using Robust.Client.GameObjects; using Robust.Client.Graphics; @@ -218,9 +219,13 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem return false; } - // If target doesn't have hands then we can't disarm so will let the player know it's pointless. + // They need to either have hands... if (!HasComp(ev.Target!.Value)) { + // or just be able to be shoved over. + if (TryComp(ev.Target!.Value, out var status) && status.AllowedEffects.Contains("KnockedDown")) + return true; + if (Timing.IsFirstTimePredicted && HasComp(ev.Target.Value)) PopupSystem.PopupEntity(Loc.GetString("disarm-action-disarmable", ("targetName", ev.Target.Value)), ev.Target.Value, Filter.Local()); diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index 71c4dea9ab..8c11eb4862 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -94,15 +94,6 @@ namespace Content.Server.Hands.Systems if (!_handsSystem.TryDrop(uid, component.ActiveHand!, null, checkActionBlocker: false)) return; - var targEnt = Identity.Entity(args.Target, EntityManager); - var msgOther = Loc.GetString("hands-component-disarm-success-others-message", - ("disarmer", Identity.Entity(args.Source, EntityManager)), ("disarmed", targEnt)); - var msgUser = Loc.GetString("hands-component-disarm-success-message", ("disarmed", targEnt)); - - var filter = Filter.Pvs(args.Source).RemoveWhereAttachedEntity(e => e == args.Source); - _popupSystem.PopupEntity(msgOther, args.Source, filter); - _popupSystem.PopupEntity(msgUser, args.Source, Filter.Entities(args.Source)); - args.Handled = true; // no shove/stun. } diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 6d210e93f6..0ee6f36560 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -25,6 +25,7 @@ using Content.Shared.Physics; using Content.Shared.Verbs; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; +using Content.Shared.StatusEffect; using Robust.Server.Player; using Robust.Shared.Audio; using Robust.Shared.Map; @@ -328,8 +329,8 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem if (!TryComp(ev.Target.Value, out var targetHandsComponent)) { - // Client will have already predicted this. - return false; + if (!TryComp(ev.Target!.Value, out var status) || !status.AllowedEffects.Contains("KnockedDown")) + return false; } if (!InRange(user, ev.Target.Value, component.Range, session)) @@ -339,7 +340,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem EntityUid? inTargetHand = null; - if (targetHandsComponent.ActiveHand is { IsEmpty: false }) + if (targetHandsComponent?.ActiveHand is { IsEmpty: false }) { inTargetHand = targetHandsComponent.ActiveHand.HeldEntity!.Value; } @@ -368,13 +369,17 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem } var filterOther = Filter.Pvs(user, entityManager: EntityManager).RemoveWhereAttachedEntity(e => e == user); + var msgPrefix = "disarm-action-"; + + if (inTargetHand == null) + msgPrefix = "disarm-action-shove-"; var msgOther = Loc.GetString( - "disarm-action-popup-message-other-clients", + msgPrefix + "popup-message-other-clients", ("performerName", Identity.Entity(user, EntityManager)), ("targetName", Identity.Entity(target, EntityManager))); - var msgUser = Loc.GetString("disarm-action-popup-message-cursor", ("targetName", Identity.Entity(target, EntityManager))); + var msgUser = Loc.GetString(msgPrefix + "popup-message-cursor", ("targetName", Identity.Entity(target, EntityManager))); PopupSystem.PopupEntity(msgOther, user, filterOther); PopupSystem.PopupEntity(msgUser, target, Filter.Entities(user)); diff --git a/Resources/Locale/en-US/actions/actions/disarm-action.ftl b/Resources/Locale/en-US/actions/actions/disarm-action.ftl index ed60ff86fb..1465d7a8b1 100644 --- a/Resources/Locale/en-US/actions/actions/disarm-action.ftl +++ b/Resources/Locale/en-US/actions/actions/disarm-action.ftl @@ -1,6 +1,8 @@ disarm-action-disarmable = {THE($targetName)} is not disarmable! disarm-action-popup-message-other-clients = {CAPITALIZE(THE($performerName))} disarmed {THE($targetName)}! disarm-action-popup-message-cursor = Disarmed {THE($targetName)}! +disarm-action-shove-popup-message-other-clients = {CAPITALIZE(THE($performerName))} shoves {THE($targetName)}! +disarm-action-shove-popup-message-cursor = You shove {THE($targetName)}! action-name-disarm = [color=red]Disarm[/color] action-description-disarm = Attempt to [color=red]disarm[/color] someone. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index e6257afee8..45bd509fa2 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -98,6 +98,8 @@ 0: Alive 5: Critical 10: Dead + - type: Stamina + excess: 10 - type: Appearance - type: DamageStateVisuals rotate: true diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml index ce451d48ff..535f49dbb5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml @@ -32,6 +32,8 @@ thresholds: 0: Alive 150: Dead + - type: Stamina + excess: 150 - type: Appearance - type: DamageStateVisuals states: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 6944972b4d..d8c7bb85c9 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -40,6 +40,8 @@ 0: Alive 50: Critical 100: Dead + - type: Stamina + excess: 100 - type: MovementAlwaysTouching - type: Appearance - type: DamageStateVisuals diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 174522f3ad..d24e4f8207 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -197,6 +197,8 @@ 0: Alive 40: Critical 60: Dead + - type: Stamina + excess: 60 - type: MeleeWeapon hidden: true angle: 0 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 09982d608b..abbd3e25de 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -76,6 +76,8 @@ thresholds: 0: Alive 120: Dead + - type: Stamina + excess: 120 - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml index e2ab7a4389..e13e013040 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml @@ -94,6 +94,7 @@ 0: Alive 50: Critical 100: Dead + - type: Stamina - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml index 8124ddec4c..4c9aaa7ae3 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml @@ -34,6 +34,8 @@ thresholds: 0: Alive 15: Dead + - type: Stamina + excess: 15 - type: MovementAlwaysTouching - type: Appearance - type: DamageStateVisuals diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 0946d11c6e..cb9b40d9db 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -57,6 +57,8 @@ thresholds: 0: Alive 200: Dead + - type: Stamina + excess: 200 - type: Bloodstream bloodReagent: FluorosulfuricAcid bloodlossDamage: @@ -130,6 +132,8 @@ thresholds: 0: Alive 300: Dead + - type: Stamina + excess: 300 - type: SlowOnDamage speedModifierThresholds: 250: 0.7 @@ -160,6 +164,8 @@ thresholds: 0: Alive 200: Dead + - type: Stamina + excess: 200 - type: MovementSpeedModifier baseWalkSpeed : 3.0 baseSprintSpeed : 5.5 @@ -193,6 +199,8 @@ thresholds: 0: Alive 1500: Dead + - type: Stamina + excess: 1500 - type: MovementSpeedModifier baseWalkSpeed : 2.8 baseSprintSpeed : 3.8 @@ -231,6 +239,8 @@ thresholds: 0: Alive 550: Dead + - type: Stamina + excess: 550 - type: MovementSpeedModifier baseWalkSpeed : 2.3 baseSprintSpeed : 4.2 @@ -269,6 +279,8 @@ thresholds: 0: Alive 250: Dead + - type: Stamina + excess: 250 - type: MovementSpeedModifier baseWalkSpeed : 2.7 baseSprintSpeed : 6.0 @@ -317,6 +329,8 @@ thresholds: 0: Alive 300: Dead + - type: Stamina + excess: 300 - type: SlowOnDamage speedModifierThresholds: 250: 0.4