Skip to content

Commit

Permalink
Lay Down via Keybind (#530)
Browse files Browse the repository at this point in the history
# Description
Adds a way to lay down/crawl using a keybind (R by default) similarly to
ss13. It has the same effects as falling down after slipping or buckling
to a bed, except you don't drop items while doing so and can (very
slowly) move around. This opens new gameplay and roleplay possibilities.

You can only toggle standing/laying once in 2.5 seconds (this cooldown
is to prevent pro gamers from spamming it). It shows a small popup to
everyone. If the attempt fails for whatever reason - being buckled,
sleeping, stunned, or anything else - another popup is shown that's only
visible to you.

It's been tested and made sure that the system works correctly with
buckling, sleeping, being stunned, and shocked.

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

18 mb recording won't fit on github:


https://cdn.discordapp.com/attachments/1255902264309321851/1260354667578261504/weeee-2024-07-10_00.57.23.mp4?ex=668f0441&is=668db2c1&hm=d338a3499bf47780a66b7ba96d5e8830d8cb4167064423b8983b2d0144b7aa88&

</p>
</details>

---

# Changelog

:cl:
- add: You can now lie down and stand up at will! The default keybind
for it is "R", but it can be changed in settings.

---------

Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com>
Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com>
  • Loading branch information
Mnemotechnician and DEATHB4DEFEAT authored Jul 18, 2024
1 parent 3bc5052 commit a2c1687
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 0 deletions.
1 change: 1 addition & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.OpenBackpack);
human.AddFunction(ContentKeyFunctions.OpenBelt);
human.AddFunction(ContentKeyFunctions.OfferItem);
human.AddFunction(ContentKeyFunctions.ToggleStanding);
human.AddFunction(ContentKeyFunctions.MouseMiddle);
human.AddFunction(ContentKeyFunctions.ArcadeUp);
human.AddFunction(ContentKeyFunctions.ArcadeDown);
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddButton(ContentKeyFunctions.OfferItem);
AddButton(ContentKeyFunctions.ToggleStanding);

AddHeader("ui-options-header-interaction-adv");
AddButton(ContentKeyFunctions.SmartEquipBackpack);
Expand Down
1 change: 1 addition & 0 deletions Content.Server/NPC/Systems/NPCCombatSystem.Ranged.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ private void UpdateRanged(float frameTime)
return;
}

_gun.SetTarget(gun, comp.Target);
_gun.AttemptShoot(uid, gunUid, gun, targetCordinates);
}
}
Expand Down
14 changes: 14 additions & 0 deletions Content.Server/Standing/LayingDownComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Content.Server.Standing;

[RegisterComponent]
public sealed partial class LayingDownComponent : Component
{
[DataField]
public float DownedSpeedMultiplier = 0.15f;

[DataField]
public TimeSpan Cooldown = TimeSpan.FromSeconds(2.5f);

[DataField]
public TimeSpan NextToggleAttempt = TimeSpan.Zero;
}
101 changes: 101 additions & 0 deletions Content.Server/Standing/LayingDownSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Input;
using Content.Shared.Movement.Systems;
using Content.Shared.Popups;
using Content.Shared.Standing;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
using Robust.Shared.Timing;

namespace Content.Server.Standing;

/// <remarks>Unfortunately cannot be shared because some standing conditions are server-side only</remarks>
public sealed class LayingDownSystem : EntitySystem
{
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
[Dependency] private readonly SharedPopupSystem _popups = default!;
[Dependency] private readonly Shared.Standing.StandingStateSystem _standing = default!; // WHY IS THERE TWO DIFFERENT STANDING SYSTEMS?!
[Dependency] private readonly IGameTiming _timing = default!;


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

SubscribeLocalEvent<LayingDownComponent, StoodEvent>(DoRefreshMovementSpeed);
SubscribeLocalEvent<LayingDownComponent, DownedEvent>(DoRefreshMovementSpeed);
SubscribeLocalEvent<LayingDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovementSpeed);
SubscribeLocalEvent<LayingDownComponent, EntParentChangedMessage>(OnParentChanged);
}

public override void Shutdown()
{
base.Shutdown();

CommandBinds.Unregister<LayingDownSystem>();
}

private void DoRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, object args)
{
_movement.RefreshMovementSpeedModifiers(uid);
}

private void OnRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (TryComp<StandingStateComponent>(uid, out var standingState) && standingState.Standing)
return;

args.ModifySpeed(component.DownedSpeedMultiplier, component.DownedSpeedMultiplier);
}

private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntParentChangedMessage args)
{
// If the entity is not on a grid, try to make it stand up to avoid issues
if (!TryComp<StandingStateComponent>(uid, out var standingState)
|| standingState.Standing
|| Transform(uid).GridUid != null)
return;

_standing.Stand(uid, standingState);
}

private void ToggleStanding(ICommonSession? session)
{
if (session is not { AttachedEntity: { Valid: true } uid } playerSession
|| !Exists(uid)
|| !TryComp<StandingStateComponent>(uid, out var standingState)
|| !TryComp<LayingDownComponent>(uid, out var layingDown))
return;

// If successful, show popup to self and others. Otherwise, only to self.
if (ToggleStandingImpl(uid, standingState, layingDown, out var popupBranch))
{
_popups.PopupEntity(Loc.GetString($"laying-comp-{popupBranch}-other", ("entity", uid)), uid, Filter.PvsExcept(uid), true);
layingDown.NextToggleAttempt = _timing.CurTime + layingDown.Cooldown;
}

_popups.PopupEntity(Loc.GetString($"laying-comp-{popupBranch}-self", ("entity", uid)), uid, uid);
}

private bool ToggleStandingImpl(EntityUid uid, StandingStateComponent standingState, LayingDownComponent layingDown, out string popupBranch)
{
var success = layingDown.NextToggleAttempt <= _timing.CurTime;

if (_standing.IsDown(uid, standingState))
{
success = success && _standing.Stand(uid, standingState, force: false);
popupBranch = success ? "stand-success" : "stand-fail";
}
else
{
success = success && Transform(uid).GridUid != null; // Do not allow laying down when not on a surface.
success = success && _standing.Down(uid, standingState: standingState, playSound: true, dropHeldItems: false);
popupBranch = success ? "lay-success" : "lay-fail";
}

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

public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown";
Expand Down
8 changes: 8 additions & 0 deletions Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,14 @@ private void StopShooting(EntityUid uid, GunComponent gun)
Dirty(uid, gun);
}

/// <summary>
/// Sets the targeted entity of the gun. Should be called before attempting to shoot to avoid shooting over the target.
/// </summary>
public void SetTarget(GunComponent gun, EntityUid target)
{
gun.Target = target;
}

/// <summary>
/// Attempts to shoot at the target coordinates. Resets the shot counter after every shot.
/// </summary>
Expand Down
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 @@ -138,6 +138,7 @@ ui-options-function-swap-hands = Swap hands
ui-options-function-move-stored-item = Move stored item
ui-options-function-rotate-stored-item = Rotate stored item
ui-options-function-offer-item = Offer something
ui-options-function-toggle-standing = Toggle standing
ui-options-static-storage-ui = Lock storage window to hotbar
ui-options-function-smart-equip-backpack = Smart-equip to backpack
Expand Down
7 changes: 7 additions & 0 deletions Resources/Locale/en-US/movement/laying.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
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.
laying-comp-stand-success-self = You stand up.
laying-comp-stand-success-other = {THE($entity)} stands up.
laying-comp-stand-fail-self = You can't stand up right now.
1 change: 1 addition & 0 deletions Resources/Prototypes/Entities/Mobs/Species/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
- type: FireVisuals
alternateState: Standing
- type: OfferItem
- type: LayingDown

- type: entity
save: false
Expand Down
3 changes: 3 additions & 0 deletions Resources/keybinds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ binds:
- function: OfferItem
type: State
key: F
- function: ToggleStanding
type: State
key: R
- function: ShowDebugConsole
type: State
key: Tilde
Expand Down

0 comments on commit a2c1687

Please sign in to comment.