Glass tables break when climbed on (#6246)

This commit is contained in:
mirrorcult
2022-01-22 05:52:35 -07:00
committed by GitHub
parent 1819069427
commit 1880db9c75
6 changed files with 138 additions and 7 deletions

View File

@@ -32,6 +32,7 @@ namespace Content.Client.Entry
"PoweredLight",
"Smes",
"LightBulb",
"GlassTable",
"Healing",
"Material",
"RandomAppearance",

View File

@@ -1,14 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.Climbing.Components;
using Content.Server.Popups;
using Content.Server.Stunnable;
using Content.Shared.ActionBlocker;
using Content.Shared.Climbing;
using Content.Shared.Damage;
using Content.Shared.GameTicking;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player;
namespace Content.Server.Climbing
{
@@ -18,6 +23,9 @@ namespace Content.Server.Climbing
private readonly HashSet<ClimbingComponent> _activeClimbers = new();
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
public override void Initialize()
{
@@ -25,6 +33,7 @@ namespace Content.Server.Climbing
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<ClimbableComponent, GetAlternativeVerbsEvent>(AddClimbVerb);
SubscribeLocalEvent<GlassTableComponent, ClimbedOnEvent>(OnGlassClimbed);
}
public void ForciblySetClimbing(EntityUid uid, ClimbingComponent? component = null)
@@ -47,12 +56,24 @@ namespace Content.Server.Climbing
// Add a climb verb
Verb verb = new();
verb.Act = () => component.TryClimb(args.User);
verb.Act = () => component.TryClimb(args.User, args.Target);
verb.Text = Loc.GetString("comp-climbable-verb-climb");
// TODO VERBS ICON add a climbing icon?
args.Verbs.Add(verb);
}
private void OnGlassClimbed(EntityUid uid, GlassTableComponent component, ClimbedOnEvent args)
{
_damageableSystem.TryChangeDamage(args.Climber, component.ClimberDamage);
_damageableSystem.TryChangeDamage(uid, component.TableDamage);
_stunSystem.TryParalyze(args.Climber, TimeSpan.FromSeconds(component.StunTime), true);
// Not shown to the user, since they already get a 'you climb on the glass table' popup
_popupSystem.PopupEntity(Loc.GetString("glass-table-shattered-others",
("table", uid), ("climber", args.Climber)), args.Climber,
Filter.Pvs(uid).RemoveWhereAttachedEntity(puid => puid == args.Climber));
}
public void AddActiveClimber(ClimbingComponent climbingComponent)
{
_activeClimbers.Add(climbingComponent);

View File

@@ -139,17 +139,17 @@ namespace Content.Server.Climbing.Components
{
if (eventArgs.User == eventArgs.Dragged)
{
TryClimb(eventArgs.User);
TryClimb(eventArgs.User, eventArgs.Target);
}
else
{
TryMoveEntity(eventArgs.User, eventArgs.Dragged);
TryMoveEntity(eventArgs.User, eventArgs.Dragged, eventArgs.Target);
}
return true;
}
private async void TryMoveEntity(EntityUid user, EntityUid entityToMove)
private async void TryMoveEntity(EntityUid user, EntityUid entityToMove, EntityUid climbable)
{
var doAfterEventArgs = new DoAfterEventArgs(user, _climbDelay, default, entityToMove)
{
@@ -184,6 +184,9 @@ namespace Content.Server.Climbing.Components
// we may potentially need additional logic since we're forcing a player onto a climbable
// there's also the cases where the user might collide with the person they are forcing onto the climbable that i haven't accounted for
_entities.EventBus.RaiseLocalEvent(entityToMove, new StartClimbEvent(climbable), false);
_entities.EventBus.RaiseLocalEvent(climbable, new ClimbedOnEvent(entityToMove), false);
var othersMessage = Loc.GetString("comp-climbable-user-climbs-force-other",
("user", user), ("moved-user", entityToMove), ("climbable", Owner));
user.PopupMessageOtherClients(othersMessage);
@@ -193,7 +196,7 @@ namespace Content.Server.Climbing.Components
}
}
public async void TryClimb(EntityUid user)
public async void TryClimb(EntityUid user, EntityUid climbable)
{
if (!_entities.TryGetComponent(user, out ClimbingComponent? climbingComponent) || climbingComponent.IsClimbing)
return;
@@ -216,6 +219,9 @@ namespace Content.Server.Climbing.Components
var direction = (_entities.GetComponent<TransformComponent>(Owner).WorldPosition - userPos).Normalized;
var endPoint = _entities.GetComponent<TransformComponent>(Owner).WorldPosition;
_entities.EventBus.RaiseLocalEvent(user, new StartClimbEvent(climbable), false);
_entities.EventBus.RaiseLocalEvent(climbable, new ClimbedOnEvent(user), false);
var climbMode = _entities.GetComponent<ClimbingComponent>(user);
climbMode.IsClimbing = true;
@@ -239,3 +245,29 @@ namespace Content.Server.Climbing.Components
}
}
}
/// <summary>
/// Raised on an entity when it is climbed on.
/// </summary>
public class ClimbedOnEvent : EntityEventArgs
{
public EntityUid Climber;
public ClimbedOnEvent(EntityUid climber)
{
Climber = climber;
}
}
/// <summary>
/// Raised on an entity when it successfully climbs on something.
/// </summary>
public class StartClimbEvent : EntityEventArgs
{
public EntityUid Climbable;
public StartClimbEvent(EntityUid climbable)
{
Climbable = climbable;
}
}

View File

@@ -0,0 +1,33 @@
using Content.Shared.Damage;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Climbing.Components;
/// <summary>
/// Glass tables shatter and stun you when climbed on.
/// This is a really entity-specific behavior, so opted to make it
/// not very generalized with regards to naming.
/// </summary>
[RegisterComponent, Friend(typeof(ClimbSystem))]
[ComponentProtoName("GlassTable")]
public class GlassTableComponent : Component
{
/// <summary>
/// How much damage should be given to the climber?
/// </summary>
[DataField("climberDamage")]
public DamageSpecifier ClimberDamage = default!;
/// <summary>
/// How much damage should be given to the table when climbed on?
/// </summary>
[DataField("tableDamage")]
public DamageSpecifier TableDamage = default!;
/// <summary>
/// How long should someone who climbs on this table be stunned for?
/// </summary>
public float StunTime = 5.0f;
}

View File

@@ -0,0 +1,4 @@
### Tables which take damage when a user is dragged onto them
## Showed to users other than the climber
glass-table-shattered-others = { CAPITALIZE(THE($table)) } cracks under the weight of { THE($climber) }!

View File

@@ -1,6 +1,7 @@
- type: entity
id: TableFrame
parent: TableBase
# BaseStructure and not BaseTable, since these shouldn't be climbable/placeable.
parent: BaseStructure
name: table frame
description: Pieces of metal that make the frame of a table.
components:
@@ -8,9 +9,21 @@
sprite: Structures/Furniture/Tables/frame.rsi
- type: Icon
sprite: Structures/Furniture/Tables/frame.rsi
- type: Fixtures
fixtures:
- shape:
!type:PhysShapeAabb
bounds: "-0.45,-0.45,0.45,0.45"
mass: 50
mask:
- Impassable
- VaultImpassable
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
- type: IconSmooth
key: state
base: state_
- type: Destructible
thresholds:
- trigger:
@@ -104,6 +117,13 @@
sprite: Structures/Furniture/Tables/glass.rsi
- type: Icon
sprite: Structures/Furniture/Tables/glass.rsi
- type: GlassTable
climberDamage:
types:
Slash: 15
tableDamage:
types:
Blunt: 25
- type: Destructible
thresholds:
- trigger:
@@ -118,6 +138,8 @@
ShardGlass:
min: 1
max: 1
- !type:ChangeConstructionNodeBehavior
node: TableFrame
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Construction
@@ -134,6 +156,13 @@
sprite: Structures/Furniture/Tables/r_glass.rsi
- type: Icon
sprite: Structures/Furniture/Tables/r_glass.rsi
- type: GlassTable
climberDamage:
types:
Slash: 25
tableDamage:
types:
Blunt: 40
- type: Destructible
thresholds:
- trigger:
@@ -143,6 +172,8 @@
- !type:PlaySoundBehavior
sound:
path: /Audio/Effects/glass_break2.ogg
- !type:ChangeConstructionNodeBehavior
node: TableFrame
- !type:SpawnEntitiesBehavior
spawn:
ShardGlass:
@@ -167,15 +198,24 @@
sprite: Structures/Furniture/Tables/plasma.rsi
- type: Icon
sprite: Structures/Furniture/Tables/plasma.rsi
- type: GlassTable
climberDamage:
types:
Slash: 30
tableDamage:
types:
Blunt: 100
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 20
damage: 50
behaviors:
- !type:PlaySoundBehavior
sound:
path: /Audio/Effects/glass_break2.ogg
- !type:ChangeConstructionNodeBehavior
node: TableFrame
- !type:SpawnEntitiesBehavior
spawn:
ShardGlassPlasma: