Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

ЛАЙ ДАУН ЧАСТЬ 3 #337

Merged
merged 12 commits into from
Jun 24, 2024
1 change: 1 addition & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.Arcade1);
human.AddFunction(ContentKeyFunctions.Arcade2);
human.AddFunction(ContentKeyFunctions.Arcade3);
human.AddFunction(ContentKeyFunctions.LieDownStandUp);

// actions should be common (for ghosts, mobs, etc)
common.AddFunction(ContentKeyFunctions.OpenActionsMenu);
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/Movement/Systems/WaddleAnimationSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Numerics;
using System.Numerics;
using Content.Client.Buckle;
using Content.Client.Gravity;
using Content.Shared.ActionBlocker;
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 @@ -181,6 +181,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.Drop);
AddButton(ContentKeyFunctions.ExamineEntity);
AddButton(ContentKeyFunctions.SwapHands);
AddButton(ContentKeyFunctions.LieDownStandUp);
AddButton(ContentKeyFunctions.MoveStoredItem);
AddButton(ContentKeyFunctions.RotateStoredItem);
AddButton(ContentKeyFunctions.SaveItemLocation);
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 @@ -56,6 +56,7 @@ public static class ContentKeyFunctions
public static readonly BoundKeyFunction ZoomOut = "ZoomOut";
public static readonly BoundKeyFunction ZoomIn = "ZoomIn";
public static readonly BoundKeyFunction ResetZoom = "ResetZoom";
public static readonly BoundKeyFunction LieDownStandUp = "LieDownStandUp";

public static readonly BoundKeyFunction ArcadeUp = "ArcadeUp";
public static readonly BoundKeyFunction ArcadeDown = "ArcadeDown";
Expand Down
25 changes: 25 additions & 0 deletions Content.Shared/LieDown/LyingDownComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Shared.Actions;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Shared.LieDown;

/// <summary>
/// Makes the target to lie down.
/// </summary>
[Access(typeof(SharedLieDownSystem))]
[RegisterComponent, NetworkedComponent()]
public sealed partial class LyingDownComponent : Component
{
/// <summary>
/// The action to lie down or stand up.
/// </summary>
[DataField]
public EntProtoId? MakeToStandUpAction = "action-name-make-standup";
}

[Serializable, NetSerializable]
public sealed class ChangeStandingStateEvent : EntityEventArgs {}
189 changes: 189 additions & 0 deletions Content.Shared/LieDown/SharedLieDownSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using Content.Shared.Actions;
using Content.Shared.Buckle;
using Content.Shared.Buckle.Components;
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Input;
using Content.Shared.Interaction;
using Content.Shared.Movement.Systems;
using Content.Shared.Standing;
using Content.Shared.Verbs;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
using Content.Shared.Carrying;

namespace Content.Shared.LieDown;

public class SharedLieDownSystem : EntitySystem
{
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movement = default!;
[Dependency] private readonly StandingStateSystem _standing = default!;
[Dependency] private readonly SharedBuckleSystem _buckle = default!;

public override void Initialize()
{
SubscribeLocalEvent<LyingDownComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<LyingDownComponent, GetVerbsEvent<AlternativeVerb>>(AddStandUpVerb);
SubscribeLocalEvent<LyingDownComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<LyingDownComponent, RefreshMovementSpeedModifiersEvent>(OnRefresh);

SubscribeLocalEvent<LyingDownComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<LyingDownComponent, ComponentShutdown>(OnComponentShutdown);
SubscribeLocalEvent<LyingDownComponent, BuckleChangeEvent>(OnBuckleChange);
SubscribeLocalEvent<LyingDownComponent, CarryDoAfterEvent>(OnDoAfter);


// Bind keybinds to lie down action
SubscribeNetworkEvent<ChangeStandingStateEvent>(OnChangeAction);
CommandBinds.Builder
.Bind(ContentKeyFunctions.LieDownStandUp, InputCmdHandler.FromDelegate(ChangeLyingState))
.Register<SharedLieDownSystem>();
}

private void OnDoAfter(EntityUid uid, LyingDownComponent component, CarryDoAfterEvent args) {
_standing.Stand(uid);
RemCompDeferred<LyingDownComponent>(uid);
}

private void OnBuckleChange(EntityUid uid, LyingDownComponent component, ref BuckleChangeEvent args) {
if (args.Buckling) {
RemCompDeferred<LyingDownComponent>(uid);
}
}

private void OnComponentShutdown(EntityUid uid, LyingDownComponent component, ComponentShutdown args)
{
SwitchActions(uid);
_movement.RefreshMovementSpeedModifiers(uid);
}

private void OnComponentStartup(EntityUid uid, LyingDownComponent component, ComponentStartup args)
{
SwitchActions(uid);
_movement.RefreshMovementSpeedModifiers(uid);
}

/// <summary>
/// Send an update event when player pressed keybind.
/// </summary>
private void ChangeLyingState(ICommonSession? session)
{
RaiseNetworkEvent(new ChangeStandingStateEvent());
}

/// <summary>
/// Process player event, that pressed keybind.
/// </summary>
private void OnChangeAction(ChangeStandingStateEvent msg, EntitySessionEventArgs args)
{
if (!args.SenderSession.AttachedEntity.HasValue)
return;

var uid = args.SenderSession.AttachedEntity.Value;
if (_standing.IsDown(uid))
{
TryStandUp(uid);
}
else
{
TryLieDown(uid);
}
}

/// <summary>
/// Update movement speed according to the lying state.
/// </summary>
private void OnRefresh(EntityUid uid, LyingDownComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (_standing.IsDown(uid))
{
args.ModifySpeed(0f, 0f);
}
else
{
args.ModifySpeed(1f, 1f);
}
}

/// <summary>
/// Change available to player actions.
/// </summary>
private void SwitchActions(EntityUid uid)
{
var standingComponent = Comp<StandingStateComponent>(uid);
if (_standing.IsDown(uid))
{
_actions.AddAction(uid, ref standingComponent.StandUpActionEntity, standingComponent.StandUpAction);
_actions.RemoveAction(uid, standingComponent.LieDownActionEntity);
}
else
{
_actions.AddAction(uid, ref standingComponent.LieDownActionEntity, standingComponent.LieDownAction);
_actions.RemoveAction(uid, standingComponent.StandUpActionEntity);
}
}

/// <summary>
/// When interacting with a lying down person, add ability to make him stand up.
/// </summary>
private void OnInteractHand(EntityUid uid, LyingDownComponent component, InteractHandEvent args)
{
TryStandUp(args.Target);
}

/// <summary>
/// Add a verb to player menu to make him stand up.
/// </summary>
private void AddStandUpVerb(EntityUid uid, LyingDownComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess)
return;

if (args.Target == args.User)
return;

if (!_standing.IsDown(uid))
return;

AlternativeVerb verb = new()
{
Act = () =>
{
TryStandUp(uid);
},
Text = Loc.GetString(component.MakeToStandUpAction!),
Priority = 2
};

args.Verbs.Add(verb);
}

/// <summary>
/// If somebody examined a lying down person, add description.
/// </summary>
private void OnExamined(EntityUid uid, LyingDownComponent component, ExaminedEvent args)
{
if (args.IsInDetailsRange && _standing.IsDown(uid))
{
args.PushMarkup(Loc.GetString("lying-down-examined", ("target", Identity.Entity(uid, EntityManager))));
}
}

public void TryStandUp(EntityUid uid)
{
if (!_standing.IsDown(uid) || !_standing.Stand(uid))
return;

RemCompDeferred<LyingDownComponent>(uid);
}

public void TryLieDown(EntityUid uid)
{
if (_standing.IsDown(uid) || !_standing.Down(uid, false, false))
return;

EnsureComp<LyingDownComponent>(uid);
}
}

62 changes: 43 additions & 19 deletions Content.Shared/Standing/StandingStateComponent.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,48 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Content.Shared.Actions;
using Robust.Shared.Prototypes;

namespace Content.Shared.Standing
namespace Content.Shared.Standing;


[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(StandingStateSystem))]
public sealed partial class StandingStateComponent : Component
{
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(StandingStateSystem))]
public sealed partial class StandingStateComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall");

[DataField, AutoNetworkedField]
public bool Standing { get; set; } = true;

/// <summary>
/// List of fixtures that had their collision mask changed when the entity was downed.
/// Required for re-adding the collision mask.
/// </summary>
[DataField, AutoNetworkedField]
public List<string> ChangedFixtures = new();
}
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall");

[DataField, AutoNetworkedField]
public bool Standing = true;

/// <summary>
/// List of fixtures that had their collision mask changed when the entity was downed.
/// Required for re-adding the collision mask.
/// </summary>
[DataField, AutoNetworkedField]
public List<string> ChangedFixtures = new();

[DataField]
public EntProtoId LieDownAction = "ActionLieDown";

[DataField, AutoNetworkedField]
public EntityUid? LieDownActionEntity;

[DataField("stand-up-action")]
public EntProtoId StandUpAction = "ActionStandUp";

[DataField, AutoNetworkedField]
public EntityUid? StandUpActionEntity;

[DataField]
public TimeSpan Delay = TimeSpan.FromSeconds(2);

[DataField]
public TimeSpan LastUsage = TimeSpan.FromSeconds(2);
}

public sealed partial class LieDownActionEvent : InstantActionEvent {}
public sealed partial class StandUpActionEvent : InstantActionEvent {}

Loading
Loading