Disarm 1984 (#8872)

This commit is contained in:
Rane
2022-06-17 01:37:07 -04:00
committed by GitHub
parent 01189a5590
commit b44ec9554a
10 changed files with 96 additions and 6 deletions

View File

@@ -1,16 +1,20 @@
using Content.Server.Actions.Events; using Content.Server.Actions.Events;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.CombatMode.Disarm;
using Content.Server.Hands.Components; using Content.Server.Hands.Components;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Weapon.Melee; using Content.Server.Weapon.Melee;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
using Content.Shared.Damage;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Stunnable;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Physics;
namespace Content.Server.CombatMode namespace Content.Server.CombatMode
{ {
@@ -38,9 +42,17 @@ namespace Content.Server.CombatMode
if (!_actionBlockerSystem.CanAttack(args.Performer)) if (!_actionBlockerSystem.CanAttack(args.Performer))
return; return;
if (TryComp<HandsComponent>(args.Performer, out var hands)
&& hands.ActiveHand != null
&& !hands.ActiveHand.IsEmpty)
{
_popupSystem.PopupEntity(Loc.GetString("disarm-action-free-hand"), args.Performer, Filter.Entities(args.Performer));
return;
}
EntityUid? inTargetHand = null; EntityUid? inTargetHand = null;
if (EntityManager.TryGetComponent<HandsComponent>(args.Target, out HandsComponent? targetHandsComponent) if (TryComp<HandsComponent>(args.Target, out HandsComponent? targetHandsComponent)
&& targetHandsComponent.ActiveHand != null && targetHandsComponent.ActiveHand != null
&& !targetHandsComponent.ActiveHand.IsEmpty) && !targetHandsComponent.ActiveHand.IsEmpty)
{ {
@@ -64,8 +76,8 @@ namespace Content.Server.CombatMode
var filterOther = filterAll.RemoveWhereAttachedEntity(e => e == args.Performer); var filterOther = filterAll.RemoveWhereAttachedEntity(e => e == args.Performer);
args.Handled = true; args.Handled = true;
var chance = CalculateDisarmChance(args.Performer, args.Target, inTargetHand, component);
if (_random.Prob(component.DisarmFailChance)) if (_random.Prob(chance))
{ {
SoundSystem.Play(component.DisarmFailSound.GetSound(), Filter.Pvs(args.Performer), args.Performer, AudioHelpers.WithVariation(0.025f)); SoundSystem.Play(component.DisarmFailSound.GetSound(), Filter.Pvs(args.Performer), args.Performer, AudioHelpers.WithVariation(0.025f));
@@ -89,8 +101,40 @@ namespace Content.Server.CombatMode
SoundSystem.Play(component.DisarmSuccessSound.GetSound(), filterAll, args.Performer, AudioHelpers.WithVariation(0.025f)); SoundSystem.Play(component.DisarmSuccessSound.GetSound(), filterAll, args.Performer, AudioHelpers.WithVariation(0.025f));
_adminLogger.Add(LogType.DisarmedAction, $"{ToPrettyString(args.Performer):user} used disarm on {ToPrettyString(args.Target):target}"); _adminLogger.Add(LogType.DisarmedAction, $"{ToPrettyString(args.Performer):user} used disarm on {ToPrettyString(args.Target):target}");
var eventArgs = new DisarmedEvent() { Target = args.Target, Source = args.Performer, PushProbability = component.DisarmPushChance }; var eventArgs = new DisarmedEvent() { Target = args.Target, Source = args.Performer, PushProbability = chance };
RaiseLocalEvent(args.Target, eventArgs); RaiseLocalEvent(args.Target, eventArgs);
} }
private float CalculateDisarmChance(EntityUid disarmer, EntityUid disarmed, EntityUid? inTargetHand, SharedCombatModeComponent disarmerComp)
{
float healthMod = 0;
if (TryComp<DamageableComponent>(disarmer, out var disarmerDamage) && TryComp<DamageableComponent>(disarmed, out var disarmedDamage))
{
// I wanted this to consider their mob state thresholds too but I'm not touching that shitcode after having a go at this.
healthMod = (((float) disarmedDamage.TotalDamage - (float) disarmerDamage.TotalDamage) / 200); // Ex. You have 0 damage, they have 90, you get a 45% chance increase
}
float massMod = 0;
if (TryComp<PhysicsComponent>(disarmer, out var disarmerPhysics) && TryComp<PhysicsComponent>(disarmed, out var disarmedPhysics))
{
if (disarmerPhysics.FixturesMass != 0) // yeah this will never happen but let's not kill the server if it does
massMod = (((disarmedPhysics.FixturesMass / disarmerPhysics.FixturesMass - 1 ) / 2)); // Ex, you weigh 120, they weigh 70, you get a 29% bonus
}
float chance = (disarmerComp.BaseDisarmFailChance - healthMod - massMod);
if (HasComp<SlowedDownComponent>(disarmer)) // might need to revisit this part after stamina damage, right now this is basically "pre-stun"
chance += 0.35f;
if (HasComp<SlowedDownComponent>(disarmed))
chance -= 0.35f;
if (inTargetHand != null && TryComp<DisarmMalusComponent>(inTargetHand, out var malus))
{
chance += malus.Malus;
}
return Math.Clamp(chance, 0f, 1f);
}
} }
} }

View File

@@ -0,0 +1,16 @@
namespace Content.Server.CombatMode.Disarm
{
/// <summary>
/// Applies a malus to disarm attempts against this item.
/// </summary>
[RegisterComponent]
public sealed class DisarmMalusComponent : Component
{
/// <summary>
/// So, disarm chances are a % chance represented as a value between 0 and 1.
/// This default would be a 30% penalty to that.
/// </summary>
[DataField("malus")]
public float Malus = 0.3f;
}
}

View File

@@ -36,5 +36,8 @@ namespace Content.Server.Weapon.Melee.EnergySword
[DataField("litDamageBonus", required: true)] [DataField("litDamageBonus", required: true)]
public DamageSpecifier LitDamageBonus = default!; public DamageSpecifier LitDamageBonus = default!;
[DataField("litDisarmMalus", required: true)]
public float litDisarmMalus = 0.6f;
} }
} }

View File

@@ -5,6 +5,7 @@ using Content.Shared.Light;
using Content.Shared.Light.Component; using Content.Shared.Light.Component;
using Content.Shared.Toggleable; using Content.Shared.Toggleable;
using Content.Shared.Tools.Components; using Content.Shared.Tools.Components;
using Content.Server.CombatMode.Disarm;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random; using Robust.Shared.Random;
@@ -68,6 +69,11 @@ namespace Content.Server.Weapon.Melee.EnergySword
item.Size = 5; item.Size = 5;
} }
if (TryComp<DisarmMalusComponent>(comp.Owner, out var malus))
{
malus.Malus -= comp.litDisarmMalus;
}
SoundSystem.Play(comp.DeActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner); SoundSystem.Play(comp.DeActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner);
comp.Activated = false; comp.Activated = false;
@@ -85,6 +91,11 @@ namespace Content.Server.Weapon.Melee.EnergySword
SoundSystem.Play(comp.ActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner); SoundSystem.Play(comp.ActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner);
if (TryComp<DisarmMalusComponent>(comp.Owner, out var malus))
{
malus.Malus += comp.litDisarmMalus;
}
comp.Activated = true; comp.Activated = true;
} }

View File

@@ -15,10 +15,10 @@ namespace Content.Shared.CombatMode
private TargetingZone _activeZone; private TargetingZone _activeZone;
[DataField("disarmFailChance")] [DataField("disarmFailChance")]
public readonly float DisarmFailChance = 0.4f; public readonly float BaseDisarmFailChance = 0.4f;
[DataField("pushChance")] [DataField("pushChance")]
public readonly float DisarmPushChance = 0.4f; public readonly float BasePushFailChance = 0.4f;
[DataField("disarmFailSound")] [DataField("disarmFailSound")]
public readonly SoundSpecifier DisarmFailSound = new SoundPathSpecifier("/Audio/Weapons/punchmiss.ogg"); public readonly SoundSpecifier DisarmFailSound = new SoundPathSpecifier("/Audio/Weapons/punchmiss.ogg");

View File

@@ -1,3 +1,5 @@
disarm-action-free-hand = You need to use a free hand to disarm!
disarm-action-popup-message-other-clients = {$performerName} fails to disarm {$targetName}! disarm-action-popup-message-other-clients = {$performerName} fails to disarm {$targetName}!
disarm-action-popup-message-cursor = You fail to disarm {$targetName}! disarm-action-popup-message-cursor = You fail to disarm {$targetName}!

View File

@@ -10,6 +10,7 @@
Slash: 12.5 Slash: 12.5
Heat: 12.5 Heat: 12.5
Blunt: -7 Blunt: -7
litDisarmMalus: 0.6
- type: Sharp - type: Sharp
- type: Sprite - type: Sprite
sprite: Objects/Weapons/Melee/e_sword.rsi sprite: Objects/Weapons/Melee/e_sword.rsi
@@ -47,6 +48,8 @@
right: right:
- state: inhand-right-blade - state: inhand-right-blade
shader: unshaded shader: unshaded
- type: DisarmMalus
malus: 0
- type: entity - type: entity
name: pen name: pen
@@ -61,6 +64,7 @@
Slash: 7.5 Slash: 7.5
Heat: 7.5 Heat: 7.5
Blunt: -1 Blunt: -1
litDisarmMalus: 0.4
- type: Sprite - type: Sprite
sprite: Objects/Weapons/Melee/e_dagger.rsi sprite: Objects/Weapons/Melee/e_dagger.rsi
layers: layers:
@@ -98,3 +102,5 @@
- type: Tag - type: Tag
tags: tags:
- Write - Write
- type: DisarmMalus
malus: 0

View File

@@ -89,6 +89,8 @@
size: 10 size: 10
sprite: Objects/Weapons/Melee/combat_knife.rsi sprite: Objects/Weapons/Melee/combat_knife.rsi
prefix: inhand prefix: inhand
- type: DisarmMalus
malus: 0.225
- type: entity - type: entity
name: survival knife name: survival knife

View File

@@ -18,6 +18,7 @@
- type: Tag - type: Tag
tags: tags:
- CaptainSabre - CaptainSabre
- type: DisarmMalus
- type: entity - type: entity
name: katana name: katana
@@ -39,6 +40,7 @@
- type: Item - type: Item
size: 15 size: 15
sprite: Objects/Weapons/Melee/katana.rsi sprite: Objects/Weapons/Melee/katana.rsi
- type: DisarmMalus
- type: entity - type: entity
name: machete name: machete
@@ -60,6 +62,7 @@
- type: Item - type: Item
size: 15 size: 15
sprite: Objects/Weapons/Melee/machete.rsi sprite: Objects/Weapons/Melee/machete.rsi
- type: DisarmMalus
- type: entity - type: entity
name: claymore name: claymore
@@ -80,3 +83,4 @@
sprite: Objects/Weapons/Melee/claymore.rsi sprite: Objects/Weapons/Melee/claymore.rsi
Slots: Slots:
- back - back
- type: DisarmMalus

View File

@@ -27,6 +27,8 @@
size: 20 size: 20
Slots: Slots:
- Belt - Belt
- type: DisarmMalus
malus: 0.225
- type: entity - type: entity
name: flash name: flash