Skip to content

Commit

Permalink
Feat: Togglable Under-Table Crawling (#1036)
Browse files Browse the repository at this point in the history
# Description
This reverts most code changes done by
#939 and
re-implements them in a better way:
- Players can now toggle under-furniture crawling with a keybind
(shift-R by default)
- Crawling that way is 50% slower for obvious balancing reasons
- The respective cvar for it is now true by default and prevents players
from beginning the "crawl under furniture" thing

Also cleaned up a few methods I was seriously pissed off by. There is
still a lot to clean up and fix, but I will leave it for a dedicated PR
in the future.

# Why (balancing)
Let me lie on the bed instead of under it!!!!!!!

<details><summary><h1>Media</h1></summary>
<p>


https://github.com/user-attachments/assets/5f04c82a-b88b-4005-8052-a1a6f011bcc9

</p>
</details>

# Changelog
:cl:
- add: You can now toggle crawling under furniture! The default keybind
is Shift-R, you can change it in settings.
  • Loading branch information
Mnemotechnician authored Oct 13, 2024
1 parent 74fa664 commit aa799f5
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 69 deletions.
1 change: 1 addition & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.OpenBelt);
human.AddFunction(ContentKeyFunctions.OfferItem);
human.AddFunction(ContentKeyFunctions.ToggleStanding);
human.AddFunction(ContentKeyFunctions.ToggleCrawlingUnder);
human.AddFunction(ContentKeyFunctions.MouseMiddle);
human.AddFunction(ContentKeyFunctions.ArcadeUp);
human.AddFunction(ContentKeyFunctions.ArcadeDown);
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void HandleHoldLookUp(BaseButton.ButtonToggledEventArgs args)
_cfg.SetCVar(CCVars.HoldLookUp, args.Pressed);
_cfg.SaveToFile();
}

private void HandleDefaultWalk(BaseButton.ButtonToggledEventArgs args)
{
_cfg.SetCVar(CCVars.DefaultWalk, args.Pressed);
Expand Down Expand Up @@ -205,6 +205,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.OfferItem);
AddButton(ContentKeyFunctions.SaveItemLocation);
AddButton(ContentKeyFunctions.ToggleStanding);
AddButton(ContentKeyFunctions.ToggleCrawlingUnder);
AddButton(ContentKeyFunctions.LookUp);
AddCheckBox("ui-options-function-auto-get-up", _cfg.GetCVar(CCVars.AutoGetUp), HandleToggleAutoGetUp);
AddCheckBox("ui-options-function-hold-look-up", _cfg.GetCVar(CCVars.HoldLookUp), HandleHoldLookUp);
Expand Down
43 changes: 19 additions & 24 deletions Content.Client/Standing/LayingDownSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using Content.Shared.Standing;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;

namespace Content.Client.Standing;

Expand All @@ -21,12 +21,27 @@ public override void Initialize()
base.Initialize();

SubscribeLocalEvent<LayingDownComponent, MoveEvent>(OnMovementInput);
SubscribeNetworkEvent<DrawDownedEvent>(OnDowned);
SubscribeNetworkEvent<DrawStoodEvent>(OnStood);

SubscribeNetworkEvent<CheckAutoGetUpEvent>(OnCheckAutoGetUp);
}

public override void Update(float frameTime)
{
// Update draw depth of laying down entities as necessary
var query = EntityQueryEnumerator<LayingDownComponent, StandingStateComponent, SpriteComponent>();
while (query.MoveNext(out var uid, out var layingDown, out var standing, out var sprite))
{
// Do not modify the entities draw depth if it's modified externally
if (sprite.DrawDepth != layingDown.NormalDrawDepth && sprite.DrawDepth != layingDown.CrawlingUnderDrawDepth)
continue;

sprite.DrawDepth = standing.CurrentState is StandingState.Lying && layingDown.IsCrawlingUnder
? layingDown.CrawlingUnderDrawDepth
: layingDown.NormalDrawDepth;
}

query.Dispose();
}

private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveEvent args)
{
if (!_timing.IsFirstTimePredicted
Expand All @@ -51,26 +66,6 @@ private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveE
sprite.Rotation = Angle.FromDegrees(90);
}

private void OnDowned(DrawDownedEvent args)
{
var uid = GetEntity(args.Uid);
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !TryComp<LayingDownComponent>(uid, out var component))
return;

sprite.DrawDepth = component.CrawlingDrawDepth;
}

private void OnStood(DrawStoodEvent args)
{
var uid = GetEntity(args.Uid);
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !TryComp<LayingDownComponent>(uid, out var component))
return;

sprite.DrawDepth = component.NormalDrawDepth;
}

private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args)
{
if (!_timing.IsFirstTimePredicted)
Expand Down
5 changes: 5 additions & 0 deletions Content.Server/Standing/LayingDownSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using Content.Shared.Standing;
using Content.Shared.CCVar;
using Content.Shared.Input;
using Content.Shared.Movement.Systems;
using Content.Shared.Popups;
using Robust.Shared.Configuration;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;

namespace Content.Server.Standing;

Expand Down
2 changes: 1 addition & 1 deletion Content.Server/Traits/Assorted/LayingDownModifierSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ private void OnStartup(EntityUid uid, LayingDownModifierComponent component, Com
return;

layingDown.StandingUpTime *= component.LayingDownCooldownMultiplier;
layingDown.SpeedModify *= component.DownedSpeedMultiplierMultiplier;
layingDown.LyingSpeedModifier *= component.DownedSpeedMultiplierMultiplier;
}
}
5 changes: 2 additions & 3 deletions Content.Shared/CCVar/CCVars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2487,11 +2487,10 @@ public static readonly CVarDef<float>
CVarDef.Create("rest.hold_look_up", false, CVar.CLIENT | CVar.ARCHIVE);

/// <summary>
/// When true, entities that fall to the ground will be able to crawl under tables and
/// plastic flaps, allowing them to take cover from gunshots.
/// When true, players can choose to crawl under tables while laying down, using the designated keybind.
/// </summary>
public static readonly CVarDef<bool> CrawlUnderTables =
CVarDef.Create("rest.crawlundertables", false, CVar.REPLICATED);
CVarDef.Create("rest.crawlundertables", true, CVar.SERVER | CVar.ARCHIVE);

#endregion

Expand Down
1 change: 1 addition & 0 deletions Content.Shared/Input/ContentKeyFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static class ContentKeyFunctions
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
public static readonly BoundKeyFunction OfferItem = "OfferItem";
public static readonly BoundKeyFunction ToggleStanding = "ToggleStanding";
public static readonly BoundKeyFunction ToggleCrawlingUnder = "ToggleCrawlingUnder";
public static readonly BoundKeyFunction LookUp = "LookUp";

public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
Expand Down
26 changes: 9 additions & 17 deletions Content.Shared/Standing/LayingDownComponent.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Content.Shared.DrawDepth;

namespace Content.Shared.Standing;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class LayingDownComponent : Component
{
[DataField, AutoNetworkedField]
public float StandingUpTime { get; set; } = 1f;
public TimeSpan StandingUpTime = TimeSpan.FromSeconds(1);

[DataField, AutoNetworkedField]
public float SpeedModify { get; set; } = 0.4f;
public float LyingSpeedModifier = 0.35f,
CrawlingUnderSpeedModifier = 0.5f;

[DataField, AutoNetworkedField]
public bool AutoGetUp;

/// <summary>
/// If true, the entity is choosing to crawl under furniture. This is purely visual and has no effect on physics.
/// </summary>
[DataField, AutoNetworkedField]
public int NormalDrawDepth = (int) DrawDepth.DrawDepth.Mobs;
public bool IsCrawlingUnder = false;

[DataField, AutoNetworkedField]
public int CrawlingDrawDepth = (int) DrawDepth.DrawDepth.SmallMobs;
public int NormalDrawDepth = (int) DrawDepth.DrawDepth.Mobs,
CrawlingUnderDrawDepth = (int) DrawDepth.DrawDepth.SmallMobs;
}

[Serializable, NetSerializable]
Expand All @@ -31,15 +35,3 @@ public sealed class CheckAutoGetUpEvent(NetEntity user) : CancellableEntityEvent
{
public NetEntity User = user;
}

[Serializable, NetSerializable]
public sealed class DrawDownedEvent(NetEntity uid) : EntityEventArgs
{
public NetEntity Uid = uid;
}

[Serializable, NetSerializable]
public sealed class DrawStoodEvent(NetEntity uid) : EntityEventArgs
{
public NetEntity Uid = uid;
}
50 changes: 40 additions & 10 deletions Content.Shared/Standing/SharedLayingDownSystem.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using Content.Shared.ActionBlocker;
using Content.Shared.CCVar;
using Content.Shared.DoAfter;
using Content.Shared.Gravity;
using Content.Shared.Input;
using Content.Shared.Mobs.Systems;
using Content.Shared.Movement.Systems;
using Content.Shared.Standing;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Robust.Shared.Configuration;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
using Robust.Shared.Serialization;
Expand All @@ -17,11 +20,16 @@ public abstract class SharedLayingDownSystem : EntitySystem
[Dependency] private readonly StandingStateSystem _standing = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedGravitySystem _gravity = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly SharedPopupSystem _popups = default!;
[Dependency] private readonly MovementSpeedModifierSystem _speed = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;

public override void Initialize()
{
CommandBinds.Builder
.Bind(ContentKeyFunctions.ToggleStanding, InputCmdHandler.FromDelegate(ToggleStanding))
.Bind(ContentKeyFunctions.ToggleCrawlingUnder, InputCmdHandler.FromDelegate(HandleCrawlUnderRequest, handle: false))
.Register<SharedLayingDownSystem>();

SubscribeNetworkEvent<ChangeLayingDownEvent>(OnChangeState);
Expand Down Expand Up @@ -49,17 +57,37 @@ private void ToggleStanding(ICommonSession? session)
RaiseNetworkEvent(new ChangeLayingDownEvent());
}

private void HandleCrawlUnderRequest(ICommonSession? session)
{
if (session == null
|| session.AttachedEntity is not {} uid
|| !TryComp<StandingStateComponent>(uid, out var standingState)
|| !TryComp<LayingDownComponent>(uid, out var layingDown)
|| !_actionBlocker.CanInteract(uid, null))
return;

var newState = !layingDown.IsCrawlingUnder;
if (standingState.CurrentState is StandingState.Standing)
newState = false; // If the entity is already standing, this function only serves a fallback method to fix its draw depth

// Do not allow to begin crawling under if it's disabled in config. We still, however, allow to stop it, as a failsafe.
if (newState && !_config.GetCVar(CCVars.CrawlUnderTables))
{
_popups.PopupEntity(Loc.GetString("crawling-under-tables-disabled-popup"), uid, session);
return;
}

layingDown.IsCrawlingUnder = newState;
_speed.RefreshMovementSpeedModifiers(uid);
Dirty(uid, layingDown);
}

private void OnChangeState(ChangeLayingDownEvent ev, EntitySessionEventArgs args)
{
if (!args.SenderSession.AttachedEntity.HasValue)
return;

var uid = args.SenderSession.AttachedEntity.Value;

// TODO: Wizard
//if (HasComp<FrozenComponent>(uid))
// return;

if (!TryComp(uid, out StandingStateComponent? standing)
|| !TryComp(uid, out LayingDownComponent? layingDown))
return;
Expand Down Expand Up @@ -89,10 +117,11 @@ private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component

private void OnRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (_standing.IsDown(uid))
args.ModifySpeed(component.SpeedModify, component.SpeedModify);
else
args.ModifySpeed(1f, 1f);
if (!_standing.IsDown(uid))
return;

var modifier = component.LyingSpeedModifier * (component.IsCrawlingUnder ? component.CrawlingUnderSpeedModifier : 1);
args.ModifySpeed(modifier, modifier);
}

private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntParentChangedMessage args)
Expand Down Expand Up @@ -125,6 +154,7 @@ public bool TryStandUp(EntityUid uid, LayingDownComponent? layingDown = null, St
return false;

standingState.CurrentState = StandingState.GettingUp;
layingDown.IsCrawlingUnder = false;
return true;
}

Expand Down
14 changes: 1 addition & 13 deletions Content.Shared/Standing/StandingStateSystem.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using Content.Shared.Buckle;
using Content.Shared.Buckle.Components;
using Content.Shared.CCVar;
using Content.Shared.Hands.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Physics;
using Content.Shared.Rotation;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization;

namespace Content.Shared.Standing;

Expand All @@ -20,7 +17,6 @@ public sealed class StandingStateSystem : EntitySystem
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
[Dependency] private readonly SharedBuckleSystem _buckle = default!;
[Dependency] private readonly IConfigurationManager _config = default!;

// If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited.
private const int StandingCollisionLayer = (int) CollisionGroup.MidImpassable;
Expand Down Expand Up @@ -69,10 +65,6 @@ public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true
Dirty(standingState);
RaiseLocalEvent(uid, new DownedEvent(), false);

// Raising this event will lower the entity's draw depth to the same as a small mob.
if (_config.GetCVar(CCVars.CrawlUnderTables) && setDrawDepth)
RaiseNetworkEvent(new DrawDownedEvent(GetNetEntity(uid)));

// Seemed like the best place to put it
_appearance.SetData(uid, RotationVisuals.RotationState, RotationState.Horizontal, appearance);

Expand Down Expand Up @@ -129,10 +121,6 @@ public bool Stand(EntityUid uid,
Dirty(uid, standingState);
RaiseLocalEvent(uid, new StoodEvent(), false);

// Raising this event will increase the entity's draw depth to a normal mob's.
if (_config.GetCVar(CCVars.CrawlUnderTables))
RaiseNetworkEvent(new DrawStoodEvent(GetNetEntity(uid)));

_appearance.SetData(uid, RotationVisuals.RotationState, RotationState.Vertical, appearance);

if (TryComp(uid, out FixturesComponent? fixtureComponent))
Expand Down Expand Up @@ -170,4 +158,4 @@ public sealed class StoodEvent : EntityEventArgs { }
/// <summary>
/// Raised when an entity is not standing
/// </summary>
public sealed class DownedEvent : EntityEventArgs { }
public sealed class DownedEvent : EntityEventArgs { }
1 change: 1 addition & 0 deletions Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ ui-options-function-rotate-stored-item = Rotate stored item
ui-options-function-offer-item = Offer something
ui-options-function-save-item-location = Save item location
ui-options-function-toggle-standing = Toggle standing
ui-options-function-toggle-crawling-under = Toggle crawling under furniture
ui-options-static-storage-ui = Lock storage window to hotbar
ui-options-function-smart-equip-backpack = Smart-equip to backpack
Expand Down
3 changes: 3 additions & 0 deletions Resources/Locale/en-US/movement/laying.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
crawling-under-tables-disabled-popup = Crawling under tables is disabled on this server.
# TODO either remove those, or make use of them
laying-comp-lay-success-self = You lay down.
laying-comp-lay-success-other = {THE($entity)} lays down.
laying-comp-lay-fail-self = You can't lay down right now.
Expand Down
4 changes: 4 additions & 0 deletions Resources/keybinds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ binds:
- function: ToggleStanding
type: State
key: R
- function: ToggleCrawlingUnder
type: State
mod1: Shift
key: R
- function: ShowDebugConsole
type: State
key: Tilde
Expand Down

0 comments on commit aa799f5

Please sign in to comment.