From eae58211e193bda899bafafadb55d6d5486ab43f Mon Sep 17 00:00:00 2001
From: Ilya Chvilyov <90278813+Telyonok@users.noreply.github.com>
Date: Wed, 1 Feb 2023 00:33:00 +0300
Subject: [PATCH] Separated Bonk functionality and component from ClimbSystem
and ClimbComponent (#13635)
---
Content.Server/Climbing/ClimbSystem.cs | 30 +--------
.../Interaction/InteractionSystem.Clumsy.cs | 25 --------
.../Weapons/Ranged/Systems/GunSystem.cs | 2 +-
Content.Shared/Climbing/BonkSystem.cs | 63 +++++++++++++++++++
Content.Shared/Climbing/BonkableComponent.cs | 40 ++++++++++++
Content.Shared/Climbing/ClimbableComponent.cs | 34 +---------
.../Interaction/Components/ClumsyComponent.cs | 2 +-
.../SharedInteractionSystem.Clumsy.cs | 26 ++++++++
.../Interaction/SharedInteractionSystem.cs | 2 +
.../bonk/components/bonkable-component.ftl | 2 +
.../Furniture/Tables/base_structuretables.yml | 2 +-
.../Structures/Furniture/Tables/tables.yml | 3 +-
12 files changed, 141 insertions(+), 90 deletions(-)
delete mode 100644 Content.Server/Interaction/InteractionSystem.Clumsy.cs
create mode 100644 Content.Shared/Climbing/BonkSystem.cs
create mode 100644 Content.Shared/Climbing/BonkableComponent.cs
rename {Content.Server => Content.Shared}/Interaction/Components/ClumsyComponent.cs (87%)
create mode 100644 Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs
create mode 100644 Resources/Locale/en-US/bonk/components/bonkable-component.ftl
diff --git a/Content.Server/Climbing/ClimbSystem.cs b/Content.Server/Climbing/ClimbSystem.cs
index f06bcf8210..f0c953c99a 100644
--- a/Content.Server/Climbing/ClimbSystem.cs
+++ b/Content.Server/Climbing/ClimbSystem.cs
@@ -8,7 +8,6 @@ using Content.Shared.ActionBlocker;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Buckle.Components;
-using Content.Shared.CCVar;
using Content.Shared.Climbing;
using Content.Shared.Climbing.Events;
using Content.Shared.Damage;
@@ -46,6 +45,7 @@ public sealed class ClimbSystem : SharedClimbSystem
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
+ [Dependency] private readonly BonkSystem _bonkSystem = default!;
private const string ClimbingFixtureName = "climb";
private const int ClimbingCollisionGroup = (int) (CollisionGroup.TableLayer | CollisionGroup.LowImpassable);
@@ -92,9 +92,6 @@ public sealed class ClimbSystem : SharedClimbSystem
if (!args.CanAccess || !args.CanInteract || !_actionBlockerSystem.CanMove(args.User))
return;
- if (component.Bonk && _cfg.GetCVar(CCVars.GameTableBonk))
- return;
-
if (!TryComp(args.User, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
return;
@@ -117,7 +114,7 @@ public sealed class ClimbSystem : SharedClimbSystem
if (!TryComp(entityToMove, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
return;
- if (TryBonk(component, user))
+ if (_bonkSystem.TryBonk(entityToMove, climbable))
return;
_doAfterSystem.DoAfter(new DoAfterEventArgs(user, component.ClimbDelay, default, climbable, entityToMove)
@@ -130,29 +127,6 @@ public sealed class ClimbSystem : SharedClimbSystem
});
}
- private bool TryBonk(ClimbableComponent component, EntityUid user)
- {
- if (!component.Bonk)
- return false;
-
- if (!_cfg.GetCVar(CCVars.GameTableBonk))
- {
- // Not set to always bonk, try clumsy roll.
- if (!_interactionSystem.TryRollClumsy(user, component.BonkClumsyChance))
- return false;
- }
-
- // BONK!
-
- _audioSystem.PlayPvs(component.BonkSound, component.Owner);
- _stunSystem.TryParalyze(user, TimeSpan.FromSeconds(component.BonkTime), true);
-
- if (component.BonkDamage is { } bonkDmg)
- _damageableSystem.TryChangeDamage(user, bonkDmg, true, origin: user);
-
- return true;
- }
-
private void OnClimbFinished(EntityUid uid, ClimbingComponent climbing, ClimbFinishedEvent args)
{
Climb(uid, args.User, args.Instigator, args.Climbable, climbing: climbing);
diff --git a/Content.Server/Interaction/InteractionSystem.Clumsy.cs b/Content.Server/Interaction/InteractionSystem.Clumsy.cs
deleted file mode 100644
index 2ecfc83c7f..0000000000
--- a/Content.Server/Interaction/InteractionSystem.Clumsy.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Content.Server.Interaction.Components;
-using Robust.Shared.Random;
-
-namespace Content.Server.Interaction;
-
-public sealed partial class InteractionSystem
-{
- public bool RollClumsy(ClumsyComponent component, float chance)
- {
- return component.Running && _random.Prob(chance);
- }
-
- ///
- /// Rolls a probability chance for a "bad action" if the target entity is clumsy.
- ///
- /// The entity that the clumsy check is happening for.
- ///
- /// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
- ///
- /// True if a "bad action" happened, false if the normal action should happen.
- public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
- {
- return Resolve(entity, ref component, false) && RollClumsy(component, chance);
- }
-}
diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
index c6d1cc41cb..3443534a5e 100644
--- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
+++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs
@@ -2,7 +2,6 @@ using System.Linq;
using Content.Server.Cargo.Systems;
using Content.Server.Examine;
using Content.Server.Interaction;
-using Content.Server.Interaction.Components;
using Content.Server.Stunnable;
using Content.Server.Weapons.Melee;
using Content.Server.Weapons.Ranged.Components;
@@ -10,6 +9,7 @@ using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
+using Content.Shared.Interaction.Components;
using Content.Shared.Projectiles;
using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Ranged;
diff --git a/Content.Shared/Climbing/BonkSystem.cs b/Content.Shared/Climbing/BonkSystem.cs
new file mode 100644
index 0000000000..9774f59751
--- /dev/null
+++ b/Content.Shared/Climbing/BonkSystem.cs
@@ -0,0 +1,63 @@
+using Content.Shared.Interaction;
+using Content.Shared.Stunnable;
+using Content.Shared.CCVar;
+using Content.Shared.Damage;
+using Content.Shared.DragDrop;
+using Robust.Shared.Configuration;
+using Content.Shared.Popups;
+using Content.Shared.IdentityManagement;
+using Robust.Shared.Player;
+
+namespace Content.Shared.Climbing;
+
+public sealed class BonkSystem : EntitySystem
+{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+ [Dependency] private readonly DamageableSystem _damageableSystem = default!;
+ [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+ [Dependency] private readonly SharedStunSystem _stunSystem = default!;
+ [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
+ [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnDragDrop);
+ }
+
+ public bool TryBonk(EntityUid user, EntityUid bonkableUid, BonkableComponent? bonkableComponent = null)
+ {
+ if (Resolve(bonkableUid, ref bonkableComponent))
+ {
+ if (!_cfg.GetCVar(CCVars.GameTableBonk))
+ {
+ // Not set to always bonk, try clumsy roll.
+ if (!_interactionSystem.TryRollClumsy(user, bonkableComponent.BonkClumsyChance))
+ return false;
+ }
+
+ // BONK!
+ var userName = Identity.Entity(user, EntityManager);
+ var bonkableName = Identity.Entity(bonkableUid, EntityManager);
+
+ _popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, Filter.PvsExcept(user), true);
+
+ _popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName)), user, user);
+
+ _audioSystem.PlayPvs(bonkableComponent.BonkSound, bonkableComponent.Owner);
+ _stunSystem.TryParalyze(user, TimeSpan.FromSeconds(bonkableComponent.BonkTime), true);
+
+ if (bonkableComponent.BonkDamage is { } bonkDmg)
+ _damageableSystem.TryChangeDamage(user, bonkDmg, true, origin: user);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private void OnDragDrop(EntityUid user, BonkableComponent bonkableComponent, DragDropEvent args)
+ {
+ TryBonk(args.Dragged, args.Target);
+ }
+}
diff --git a/Content.Shared/Climbing/BonkableComponent.cs b/Content.Shared/Climbing/BonkableComponent.cs
new file mode 100644
index 0000000000..63f4f8c739
--- /dev/null
+++ b/Content.Shared/Climbing/BonkableComponent.cs
@@ -0,0 +1,40 @@
+using Content.Shared.Damage;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Climbing;
+
+///
+/// Makes entity do damage and stun entities with ClumsyComponent
+/// upon DragDrop or Climb interactions.
+///
+[RegisterComponent, NetworkedComponent, Access(typeof(BonkSystem))]
+public sealed class BonkableComponent : Component
+{
+ ///
+ /// Chance of bonk triggering if the user is clumsy.
+ ///
+ [DataField("bonkClumsyChance")]
+ public float BonkClumsyChance = 0.75f;
+
+ ///
+ /// Sound to play when bonking.
+ ///
+ ///
+ [DataField("bonkSound")]
+ public SoundSpecifier? BonkSound;
+
+ ///
+ /// How long to stun players on bonk, in seconds.
+ ///
+ ///
+ [DataField("bonkTime")]
+ public float BonkTime = 2;
+
+ ///
+ /// How much damage to apply on bonk.
+ ///
+ ///
+ [DataField("bonkDamage")]
+ public DamageSpecifier? BonkDamage;
+}
diff --git a/Content.Shared/Climbing/ClimbableComponent.cs b/Content.Shared/Climbing/ClimbableComponent.cs
index a185da1905..f4859467b9 100644
--- a/Content.Shared/Climbing/ClimbableComponent.cs
+++ b/Content.Shared/Climbing/ClimbableComponent.cs
@@ -1,4 +1,4 @@
-using Content.Shared.CCVar;
+using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.Interaction;
using Robust.Shared.Audio;
@@ -19,37 +19,5 @@ namespace Content.Shared.Climbing
///
[DataField("delay")]
public float ClimbDelay = 0.8f;
-
- ///
- /// If set, people can bonk on this if is set or if they are clumsy.
- ///
- [DataField("bonk")] public bool Bonk = false;
-
- ///
- /// Chance of bonk triggering if the user is clumsy.
- ///
- [DataField("bonkClumsyChance")]
- public float BonkClumsyChance = 0.75f;
-
- ///
- /// Sound to play when bonking.
- ///
- ///
- [DataField("bonkSound")]
- public SoundSpecifier? BonkSound;
-
- ///
- /// How long to stun players on bonk, in seconds.
- ///
- ///
- [DataField("bonkTime")]
- public float BonkTime = 2;
-
- ///
- /// How much damage to apply on bonk.
- ///
- ///
- [DataField("bonkDamage")]
- public DamageSpecifier? BonkDamage;
}
}
diff --git a/Content.Server/Interaction/Components/ClumsyComponent.cs b/Content.Shared/Interaction/Components/ClumsyComponent.cs
similarity index 87%
rename from Content.Server/Interaction/Components/ClumsyComponent.cs
rename to Content.Shared/Interaction/Components/ClumsyComponent.cs
index 9b5b2f1ef1..6938187f46 100644
--- a/Content.Server/Interaction/Components/ClumsyComponent.cs
+++ b/Content.Shared/Interaction/Components/ClumsyComponent.cs
@@ -1,6 +1,6 @@
using Content.Shared.Damage;
-namespace Content.Server.Interaction.Components
+namespace Content.Shared.Interaction.Components
{
///
/// A simple clumsy tag-component.
diff --git a/Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs b/Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs
new file mode 100644
index 0000000000..9e45847e07
--- /dev/null
+++ b/Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs
@@ -0,0 +1,26 @@
+using Content.Shared.Interaction.Components;
+using Robust.Shared.Random;
+
+namespace Content.Shared.Interaction
+{
+ public partial class SharedInteractionSystem
+ {
+ public bool RollClumsy(ClumsyComponent component, float chance)
+ {
+ return component.Running && _random.Prob(chance);
+ }
+
+ ///
+ /// Rolls a probability chance for a "bad action" if the target entity is clumsy.
+ ///
+ /// The entity that the clumsy check is happening for.
+ ///
+ /// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
+ ///
+ /// True if a "bad action" happened, false if the normal action should happen.
+ public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
+ {
+ return Resolve(entity, ref component, false) && RollClumsy(component, chance);
+ }
+ }
+}
diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs
index f0a16c3563..64f0a947db 100644
--- a/Content.Shared/Interaction/SharedInteractionSystem.cs
+++ b/Content.Shared/Interaction/SharedInteractionSystem.cs
@@ -29,6 +29,7 @@ using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using Robust.Shared.Players;
+using Robust.Shared.Random;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
@@ -54,6 +55,7 @@ namespace Content.Shared.Interaction
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly SharedPullingSystem _pullSystem = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
private const CollisionGroup InRangeUnobstructedMask
= CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
diff --git a/Resources/Locale/en-US/bonk/components/bonkable-component.ftl b/Resources/Locale/en-US/bonk/components/bonkable-component.ftl
new file mode 100644
index 0000000000..fce10284ca
--- /dev/null
+++ b/Resources/Locale/en-US/bonk/components/bonkable-component.ftl
@@ -0,0 +1,2 @@
+bonkable-success-message-others = { CAPITALIZE(THE($user)) } bonks { POSS-ADJ($user) } head against { $bonkable }
+bonkable-success-message-user = You bonk your head against { $bonkable }
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml
index 43577a2dbd..0970d04bcc 100644
--- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml
+++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml
@@ -28,7 +28,7 @@
key: state
base: state_
- type: Climbable
- bonk: true
+ - type: Bonkable
bonkDamage:
types:
Blunt: 4
diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml
index 63c24e6e04..8c937d42d0 100644
--- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml
+++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml
@@ -1,4 +1,4 @@
-- type: entity
+- type: entity
id: TableFrame
# BaseStructure and not BaseTable, since these shouldn't be climbable/placeable.
parent: BaseStructure
@@ -219,6 +219,7 @@
node: TableReinforced
- type: Climbable
# Reinforced tables are extra tough
+ - type: Bonkable
bonkDamage:
types:
Blunt: 8