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.Components;
|
||||||
using Content.Shared.Body.Part;
|
using Content.Shared.Body.Part;
|
||||||
using Content.Shared.Buckle.Components;
|
using Content.Shared.Buckle.Components;
|
||||||
using Content.Shared.CCVar;
|
|
||||||
using Content.Shared.Climbing;
|
using Content.Shared.Climbing;
|
||||||
using Content.Shared.Climbing.Events;
|
using Content.Shared.Climbing.Events;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
@@ -46,6 +45,7 @@ public sealed class ClimbSystem : SharedClimbSystem
|
|||||||
[Dependency] private readonly StunSystem _stunSystem = default!;
|
[Dependency] private readonly StunSystem _stunSystem = default!;
|
||||||
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
|
[Dependency] private readonly BonkSystem _bonkSystem = default!;
|
||||||
|
|
||||||
private const string ClimbingFixtureName = "climb";
|
private const string ClimbingFixtureName = "climb";
|
||||||
private const int ClimbingCollisionGroup = (int) (CollisionGroup.TableLayer | CollisionGroup.LowImpassable);
|
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))
|
if (!args.CanAccess || !args.CanInteract || !_actionBlockerSystem.CanMove(args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (component.Bonk && _cfg.GetCVar(CCVars.GameTableBonk))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!TryComp(args.User, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
|
if (!TryComp(args.User, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -117,7 +114,7 @@ public sealed class ClimbSystem : SharedClimbSystem
|
|||||||
if (!TryComp(entityToMove, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
|
if (!TryComp(entityToMove, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryBonk(component, user))
|
if (_bonkSystem.TryBonk(entityToMove, climbable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_doAfterSystem.DoAfter(new DoAfterEventArgs(user, component.ClimbDelay, default, climbable, entityToMove)
|
_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)
|
private void OnClimbFinished(EntityUid uid, ClimbingComponent climbing, ClimbFinishedEvent args)
|
||||||
{
|
{
|
||||||
Climb(uid, args.User, args.Instigator, args.Climbable, climbing: climbing);
|
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.Cargo.Systems;
|
||||||
using Content.Server.Examine;
|
using Content.Server.Examine;
|
||||||
using Content.Server.Interaction;
|
using Content.Server.Interaction;
|
||||||
using Content.Server.Interaction.Components;
|
|
||||||
using Content.Server.Stunnable;
|
using Content.Server.Stunnable;
|
||||||
using Content.Server.Weapons.Melee;
|
using Content.Server.Weapons.Melee;
|
||||||
using Content.Server.Weapons.Ranged.Components;
|
using Content.Server.Weapons.Ranged.Components;
|
||||||
@@ -10,6 +9,7 @@ using Content.Shared.Damage;
|
|||||||
using Content.Shared.Damage.Systems;
|
using Content.Shared.Damage.Systems;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
|
using Content.Shared.Interaction.Components;
|
||||||
using Content.Shared.Projectiles;
|
using Content.Shared.Projectiles;
|
||||||
using Content.Shared.Weapons.Melee;
|
using Content.Shared.Weapons.Melee;
|
||||||
using Content.Shared.Weapons.Ranged;
|
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.Damage;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
@@ -19,37 +19,5 @@ namespace Content.Shared.Climbing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("delay")]
|
[DataField("delay")]
|
||||||
public float ClimbDelay = 0.8f;
|
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;
|
using Content.Shared.Damage;
|
||||||
|
|
||||||
namespace Content.Server.Interaction.Components
|
namespace Content.Shared.Interaction.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A simple clumsy tag-component.
|
/// 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.Physics.Systems;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -54,6 +55,7 @@ namespace Content.Shared.Interaction
|
|||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
||||||
[Dependency] private readonly SharedPullingSystem _pullSystem = default!;
|
[Dependency] private readonly SharedPullingSystem _pullSystem = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
|
||||||
private const CollisionGroup InRangeUnobstructedMask
|
private const CollisionGroup InRangeUnobstructedMask
|
||||||
= CollisionGroup.Impassable | CollisionGroup.InteractImpassable;
|
= 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
|
key: state
|
||||||
base: state_
|
base: state_
|
||||||
- type: Climbable
|
- type: Climbable
|
||||||
bonk: true
|
- type: Bonkable
|
||||||
bonkDamage:
|
bonkDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 4
|
Blunt: 4
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: TableFrame
|
id: TableFrame
|
||||||
# BaseStructure and not BaseTable, since these shouldn't be climbable/placeable.
|
# BaseStructure and not BaseTable, since these shouldn't be climbable/placeable.
|
||||||
parent: BaseStructure
|
parent: BaseStructure
|
||||||
@@ -219,6 +219,7 @@
|
|||||||
node: TableReinforced
|
node: TableReinforced
|
||||||
- type: Climbable
|
- type: Climbable
|
||||||
# Reinforced tables are extra tough
|
# Reinforced tables are extra tough
|
||||||
|
- type: Bonkable
|
||||||
bonkDamage:
|
bonkDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 8
|
Blunt: 8
|
||||||
|
|||||||
Reference in New Issue
Block a user