Separated Bonk functionality and component from ClimbSystem and ClimbComponent (#13635)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls a probability chance for a "bad action" if the target entity is clumsy.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity that the clumsy check is happening for.</param>
|
||||
/// <param name="chance">
|
||||
/// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
|
||||
/// </param>
|
||||
/// <returns>True if a "bad action" happened, false if the normal action should happen.</returns>
|
||||
public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
|
||||
{
|
||||
return Resolve(entity, ref component, false) && RollClumsy(component, chance);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
63
Content.Shared/Climbing/BonkSystem.cs
Normal file
63
Content.Shared/Climbing/BonkSystem.cs
Normal file
@@ -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<BonkableComponent, DragDropEvent>(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);
|
||||
}
|
||||
}
|
||||
40
Content.Shared/Climbing/BonkableComponent.cs
Normal file
40
Content.Shared/Climbing/BonkableComponent.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Climbing;
|
||||
|
||||
/// <summary>
|
||||
/// Makes entity do damage and stun entities with ClumsyComponent
|
||||
/// upon DragDrop or Climb interactions.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(BonkSystem))]
|
||||
public sealed class BonkableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Chance of bonk triggering if the user is clumsy.
|
||||
/// </summary>
|
||||
[DataField("bonkClumsyChance")]
|
||||
public float BonkClumsyChance = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when bonking.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkSound")]
|
||||
public SoundSpecifier? BonkSound;
|
||||
|
||||
/// <summary>
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkTime")]
|
||||
public float BonkTime = 2;
|
||||
|
||||
/// <summary>
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkDamage")]
|
||||
public DamageSpecifier? BonkDamage;
|
||||
}
|
||||
@@ -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
|
||||
/// </summary>
|
||||
[DataField("delay")]
|
||||
public float ClimbDelay = 0.8f;
|
||||
|
||||
/// <summary>
|
||||
/// If set, people can bonk on this if <see cref="CCVars.GameTableBonk"/> is set or if they are clumsy.
|
||||
/// </summary>
|
||||
[DataField("bonk")] public bool Bonk = false;
|
||||
|
||||
/// <summary>
|
||||
/// Chance of bonk triggering if the user is clumsy.
|
||||
/// </summary>
|
||||
[DataField("bonkClumsyChance")]
|
||||
public float BonkClumsyChance = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when bonking.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkSound")]
|
||||
public SoundSpecifier? BonkSound;
|
||||
|
||||
/// <summary>
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkTime")]
|
||||
public float BonkTime = 2;
|
||||
|
||||
/// <summary>
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkDamage")]
|
||||
public DamageSpecifier? BonkDamage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server.Interaction.Components
|
||||
namespace Content.Shared.Interaction.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple clumsy tag-component.
|
||||
26
Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs
Normal file
26
Content.Shared/Interaction/SharedInteractionSystem.Clumsy.cs
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls a probability chance for a "bad action" if the target entity is clumsy.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity that the clumsy check is happening for.</param>
|
||||
/// <param name="chance">
|
||||
/// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
|
||||
/// </param>
|
||||
/// <returns>True if a "bad action" happened, false if the normal action should happen.</returns>
|
||||
public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
|
||||
{
|
||||
return Resolve(entity, ref component, false) && RollClumsy(component, chance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 }
|
||||
@@ -28,7 +28,7 @@
|
||||
key: state
|
||||
base: state_
|
||||
- type: Climbable
|
||||
bonk: true
|
||||
- type: Bonkable
|
||||
bonkDamage:
|
||||
types:
|
||||
Blunt: 4
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user