diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs index 7a8a9938545..afe9ed60656 100644 --- a/Content.Client/Input/ContentContexts.cs +++ b/Content.Client/Input/ContentContexts.cs @@ -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); diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index a575f1ba51c..1ecf44235d1 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -181,6 +181,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action +/// Makes the target to lie down. +/// +[Access(typeof(SharedLieDownSystem))] +[RegisterComponent, NetworkedComponent()] +public sealed partial class LyingDownComponent : Component +{ + /// + /// The action to lie down or stand up. + /// + [DataField("make-to-stand-up-action", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string? MakeToStandUpAction = "action-name-make-standup"; +} + +[Serializable, NetSerializable] +public sealed class ChangeStandingStateEvent : EntityEventArgs {} diff --git a/Content.Shared/LieDown/SharedLieDownSystem.cs b/Content.Shared/LieDown/SharedLieDownSystem.cs new file mode 100644 index 00000000000..3e60286fbe4 --- /dev/null +++ b/Content.Shared/LieDown/SharedLieDownSystem.cs @@ -0,0 +1,167 @@ +using Content.Shared.Actions; +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.IoC; +using Robust.Shared.Player; + +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!; + + public override void Initialize() + { + SubscribeLocalEvent(OnInteractHand); + SubscribeLocalEvent>(AddStandUpVerb); + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent(OnRefresh); + + SubscribeLocalEvent(OnComponentStartup); + SubscribeLocalEvent(OnComponentShutdown); + + // Bind keybinds to lie down action + SubscribeNetworkEvent(OnChangeAction); + CommandBinds.Builder + .Bind(ContentKeyFunctions.LieDownStandUp, InputCmdHandler.FromDelegate(ChangeLyingState)) + .Register(); + } + + 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); + } + + /// + /// Send an update event when player pressed keybind. + /// + private void ChangeLyingState(ICommonSession? session) + { + RaiseNetworkEvent(new ChangeStandingStateEvent()); + } + + /// + /// Process player event, that pressed keybind. + /// + 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); + } + } + + /// + /// Update movement speed according to the lying state. + /// + private void OnRefresh(EntityUid uid, LyingDownComponent component, RefreshMovementSpeedModifiersEvent args) + { + if (_standing.IsDown(uid)) + { + args.ModifySpeed(0.4f, 0.4f); + } + else + { + args.ModifySpeed(1f, 1f); + } + } + + /// + /// Change available to player actions. + /// + private void SwitchActions(EntityUid uid) + { + var standingComponent = Comp(uid); + _actions.AddAction(uid, ref standingComponent.ToggleActionEntity, standingComponent.ToggleAction); + } + + /// + /// When interacting with a lying down person, add ability to make him stand up. + /// + private void OnInteractHand(EntityUid uid, LyingDownComponent component, InteractHandEvent args) + { + TryStandUp(args.Target); + } + + /// + /// Add a verb to player menu to make him stand up. + /// + private void AddStandUpVerb(EntityUid uid, LyingDownComponent component, GetVerbsEvent 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); + } + + /// + /// If somebody examined a lying down person, add description. + /// + 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; + + Logger.Debug("{uid} tried to stand up", uid); + + RemCompDeferred(uid); + } + + public void TryLieDown(EntityUid uid) + { + if (_standing.IsDown(uid) || !_standing.Down(uid, false, false)) + return; + + Logger.Debug("{uid} tried to lie down", uid); + + EnsureComp(uid); + } + } +} diff --git a/Content.Shared/Standing/StandingStateComponent.cs b/Content.Shared/Standing/StandingStateComponent.cs index 5d7bb0a59fd..cd43405f25b 100644 --- a/Content.Shared/Standing/StandingStateComponent.cs +++ b/Content.Shared/Standing/StandingStateComponent.cs @@ -1,9 +1,12 @@ +using Content.Shared.Actions; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Standing { - [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] + [RegisterComponent, NetworkedComponent(), AutoGenerateComponentState] [Access(typeof(StandingStateSystem))] public sealed partial class StandingStateComponent : Component { @@ -20,5 +23,18 @@ public sealed partial class StandingStateComponent : Component /// [DataField, AutoNetworkedField] public List ChangedFixtures = new(); + + [DataField] + public EntProtoId ToggleAction = "ActionToggleLieDown"; + + [DataField, AutoNetworkedField] + public EntityUid? ToggleActionEntity; + + + [DataField("IsDown"), AutoNetworkedField] + public bool IsDown = false; } + + public sealed partial class LieDownActionEvent : InstantActionEvent {} + public sealed partial class StandUpActionEvent : InstantActionEvent {} } diff --git a/Content.Shared/Standing/StandingStateSystem.cs b/Content.Shared/Standing/StandingStateSystem.cs index ed586e970dc..eca7afb04b7 100644 --- a/Content.Shared/Standing/StandingStateSystem.cs +++ b/Content.Shared/Standing/StandingStateSystem.cs @@ -1,4 +1,7 @@ +using Content.Shared.Actions; using Content.Shared.Hands.Components; +using Content.Shared.LieDown; +using Content.Shared.Movement.Systems; using Content.Shared.Physics; using Content.Shared.Rotation; using Robust.Shared.Audio; @@ -13,18 +16,54 @@ public sealed class StandingStateSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedLieDownSystem _lieDown = 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; + public override void Initialize() + { + SubscribeLocalEvent(OnComponentInit); + + SubscribeLocalEvent(OnLieDownAction); + SubscribeLocalEvent(OnStandUpAction); + } public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null) { if (!Resolve(uid, ref standingState, false)) return false; + if (HasComp(uid)) + RemComp(uid); + return !standingState.Standing; } + /// + /// When component is added to player, add an action. + /// + private void OnComponentInit(EntityUid uid, StandingStateComponent component, ComponentStartup args) + { + _actions.AddAction(uid, ref component.ToggleActionEntity, component.ToggleAction); + } + + /// + /// Event that being risen on lie down attempt. + /// + private void OnLieDownAction(EntityUid uid, StandingStateComponent component, LieDownActionEvent args) + { + _lieDown.TryLieDown(uid); + } + + /// + /// Event that being risen on stand up attempt. + /// + private void OnStandUpAction(EntityUid uid, StandingStateComponent component, StandUpActionEvent args) + { + _lieDown.TryStandUp(uid); + } + public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true, StandingStateComponent? standingState = null, AppearanceComponent? appearance = null, diff --git a/Resources/Locale/en-US/actions/actions/lie-down.ftl b/Resources/Locale/en-US/actions/actions/lie-down.ftl new file mode 100644 index 00000000000..2160f49afc2 --- /dev/null +++ b/Resources/Locale/en-US/actions/actions/lie-down.ftl @@ -0,0 +1,5 @@ +action-name-liedown = Lie down +action-name-standup = Stand up +action-name-make-standup = Make to stand up +lying-down-examined = [color=lightblue]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} is lying down.[/color] +ui-options-function-lie-down-stand-up = Lie on the ground diff --git a/Resources/Locale/ru-RU/actions/actions/lie-down.ftl b/Resources/Locale/ru-RU/actions/actions/lie-down.ftl new file mode 100644 index 00000000000..2160f49afc2 --- /dev/null +++ b/Resources/Locale/ru-RU/actions/actions/lie-down.ftl @@ -0,0 +1,5 @@ +action-name-liedown = Lie down +action-name-standup = Stand up +action-name-make-standup = Make to stand up +lying-down-examined = [color=lightblue]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} is lying down.[/color] +ui-options-function-lie-down-stand-up = Lie on the ground diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 347964a6a0c..5ddee672191 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -174,6 +174,22 @@ - type: SleepEmitSound - type: SSDIndicator - type: StandingState + lie-down-action: + type: instantAction + id: LieDown + icon: Interface/Actions/lie-down-state.png + name: action-name-liedown + itemIconStyle: NoItem + event: !type:LieDownActionEvent + checkCanInteract: true + stand-up-action: + type: instantAction + id: StandUp + icon: Interface/Actions/stand-up-state.png + name: action-name-standup + itemIconStyle: NoItem + event: !type:StandUpActionEvent + checkCanInteract: true - type: Fingerprint - type: Dna - type: MindContainer @@ -216,7 +232,7 @@ - type: MobPrice price: 1500 # Kidnapping a living person and selling them for cred is a good move. deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less. - - type: CanEscapeInventory # Carrying system from nyanotrasen. + - type: CanEscapeInventory # Carrying system from nyanotrasen. - type: Tag tags: - CanPilot diff --git a/Resources/Textures/Interface/Actions/lie-down-state.png b/Resources/Textures/Interface/Actions/lie-down-state.png new file mode 100644 index 00000000000..436ff4ee198 Binary files /dev/null and b/Resources/Textures/Interface/Actions/lie-down-state.png differ diff --git a/Resources/Textures/Interface/Actions/stand-up-state.png b/Resources/Textures/Interface/Actions/stand-up-state.png new file mode 100644 index 00000000000..4318582ff4a Binary files /dev/null and b/Resources/Textures/Interface/Actions/stand-up-state.png differ diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml index c11f59d17c9..6ea39da20c2 100644 --- a/Resources/keybinds.yml +++ b/Resources/keybinds.yml @@ -1,4 +1,4 @@ -version: 1 # Not used right now, whatever. +version: 1 # Not used right now, whatever. binds: - function: UIClick type: State @@ -120,6 +120,10 @@ binds: type: State mod1: Shift key: Num9 +- function: LieDownStandUp + type: State + key: Z + mod1: Shift - function: FocusOOCWindow type: State key: LBracket diff --git a/Resources/keybinds.yml.orig b/Resources/keybinds.yml.orig new file mode 100644 index 00000000000..a00a5bf4a66 --- /dev/null +++ b/Resources/keybinds.yml.orig @@ -0,0 +1,589 @@ +version: 1 # Not used right now, whatever. +binds: +- function: UIClick + type: State + key: MouseLeft + canFocus: true +- function: UIRightClick + type: State + key: MouseRight + canFocus: true + priority: 10 +- function: CloseModals + type: State + key: Escape + priority: 10 +- function: Use + type: State + key: MouseLeft + canFocus: true +- function: UseSecondary + type: State + key: MouseRight + canFocus: true + priority: -1 # UIRightClick & EditorCancelPlace should fire first. +- function: ShowDebugMonitors + type: Toggle + key: F3 +- function: HideUI + type: Toggle + mod1: Shift + key: F4 +- function: MoveUp + type: State + key: W +- function: MoveLeft + type: State + key: A +- function: MoveRight + type: State + key: D +- function: MoveDown + type: State + key: S +- function: Walk + type: State + key: Shift +# Shuttle +- function: ShuttleStrafeUp + type: State + key: W +- function: ShuttleStrafeLeft + type: State + key: A +- function: ShuttleStrafeRight + type: State + key: D +- function: ShuttleStrafeDown + type: State + key: S +- function: ShuttleRotateLeft + type: State + key: Q +- function: ShuttleRotateRight + type: State + key: E +- function: ShuttleBrake + type: State + key: Space +# Camera +- function: CameraRotateLeft + type: State + key: NumpadNum7 +- function: CameraRotateRight + type: State + key: NumpadNum9 +- function: CameraReset + type: State + key: NumpadNum8 +- function: ZoomOut + type: State + key: NumpadNum4 +- function: ZoomIn + type: State + key: NumpadNum6 +- function: ResetZoom + type: State + key: NumpadNum5 +# Misc +- function: ShowEscapeMenu + type: State + key: F10 +- function: ToggleFullscreen + type: State + key: F11 +- function: CycleChatChannelForward + type: State + key: Tab + priority: 1 # Before tab complete +- function: CycleChatChannelBackward + type: State + key: Tab + mod1: Control +- function: FocusChatInputWindow + type: State + key: T +- function: FocusLocalChatWindow + type: State + key: Period +- function: FocusEmote + type: State + mod1: Shift + key: Apostrophe +- function: FocusWhisperChatWindow + type: State + key: Comma +- function: FocusRadioWindow + type: State + key: SemiColon +- function: FocusLOOCWindow + type: State + mod1: Shift + key: Num9 +- function: FocusOOCWindow + type: State + key: LBracket +- function: FocusAdminChatWindow + type: State + key: RBracket +- function: FocusDeadChatWindow + type: State + key: Backslash +- function: FocusConsoleChatWindow + type: State + key: Slash +- function: EditorLinePlace + type: State + key: MouseLeft + canFocus: true + mod1: Shift +- function: EditorGridPlace + type: State + key: MouseLeft + canFocus: true + mod1: Control +- function: EditorPlaceObject + type: State + key: MouseLeft + canFocus: true +- function: EditorCancelPlace + type: State + key: MouseRight + canFocus: true +- function: EditorRotateObject + type: State + key: MouseMiddle +- function: EditorFlipObject + type: State + key: MouseMiddle + mod1: Control +- function: EditorCopyObject + type: State + key: P +- function: SwapHands + type: State + key: X +- function: MoveStoredItem + type: State + key: MouseLeft + canFocus: true + priority: 10 +- function: RotateStoredItem + type: State + key: MouseRight +- function: SaveItemLocation + type: State + key: MouseMiddle +- function: Drop + type: State + key: Q +- function: ActivateItemInHand + type: State + key: Z +- function: AltActivateItemInHand + type: State + key: Z + mod1: Alt +- function: OpenCharacterMenu + type: State + key: C +- function: OpenEmotesMenu + type: State + key: Y +- function: TextCursorSelect + # TextCursorSelect HAS to be above ExamineEntity + # So that LineEdit receives it correctly. + # TODO: Make it so that UI keybinds are somehow prioritized so this ordering stuff isn't necessary. + type: State + key: MouseLeft + mod1: Shift + canFocus: true +- function: ExamineEntity + type: State + key: MouseLeft + canFocus: true + mod1: Shift +- function: ActivateItemInWorld + type: State + key: E +- function: AltActivateItemInWorld + type: State + key: MouseLeft + canFocus: true + mod1: Alt +- function: AltActivateItemInWorld # secondary binding + type: State + key: E + mod1: Alt +- function: ThrowItemInHand + type: State + key: Q + mod1: Control +- function: TryPullObject + type: State + canFocus: true + key: MouseLeft + mod1: Control +- function: MovePulledObject + type: State + key: MouseRight + mod1: Control +- function: ReleasePulledObject + type: State + key: H +- function: OpenCraftingMenu + type: State + key: G +- function: OpenGuidebook + type: State + key: NumpadNum0 +- function: OpenAHelp + type: State + key: F1 +- function: OpenInventoryMenu + type: State + key: I +- function: SmartEquipBackpack + type: State + key: B + mod1: Shift +- function: SmartEquipBelt + type: State + key: E + mod1: Shift +- function: OpenBackpack + type: State + key: V +- function: OpenBelt + type: State + key: V + mod1: Shift +- function: ShowDebugConsole + type: State + key: Tilde +- function: InspectEntity + type: State + key: v + mod1: Alt +- function: MouseMiddle + type: State + key: MouseMiddle + canFocus: true +- function: TextCursorLeft + type: State + key: Left + canRepeat: true +- function: TextCursorRight + type: State + key: Right + canRepeat: true +- function: TextCursorUp + type: State + key: Up + canRepeat: true + priority: 2 +- function: TextCursorDown + type: State + key: Down + canRepeat: true + priority: 2 +- function: TextCursorWordLeft + type: State + key: Left + mod1: Control + canRepeat: true + allowSubCombs: true +- function: TextCursorWordRight + type: State + key: Right + mod1: Control + canRepeat: true + allowSubCombs: true +- function: TextCursorBegin + type: State + key: Home +- function: TextCursorEnd + type: State + key: End + canRepeat: true +- function: TextCursorSelectLeft + type: State + key: Left + mod1: Shift + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectRight + type: State + key: Right + mod1: Shift + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectUp + type: State + key: Up + mod1: Shift + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectDown + type: State + key: Down + mod1: Shift + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectWordLeft + type: State + key: Left + mod1: Shift + mod2: Control + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectWordRight + type: State + key: Right + mod1: Shift + mod2: Control + canRepeat: true + allowSubCombs: true +- function: TextCursorSelectBegin + type: State + mod1: Shift + key: Home + allowSubCombs: true +- function: TextCursorSelectEnd + type: State + mod1: Shift + key: End + canRepeat: true + allowSubCombs: true +- function: TextBackspace + type: State + key: BackSpace + canRepeat: true +- function: TextDelete + type: State + key: Delete + canRepeat: true +- function: TextWordBackspace + type: State + key: BackSpace + mod1: Control + canRepeat: true + allowSubCombs: true +- function: TextWordDelete + type: State + key: Delete + mod1: Control + canRepeat: true + allowSubCombs: true +- function: TextNewline + type: State + key: Return + canRepeat: true +- function: TextNewline + type: State + key: NumpadEnter + canRepeat: true +- function: TextSubmit + type: State + key: Return +- function: TextSubmit + type: State + key: NumpadEnter +- function: MultilineTextSubmit + type: State + key: Return + mod1: Control +- function: MultilineTextSubmit + type: State + key: NumpadEnter + mod1: Control +- function: TextSelectAll + type: State + key: A + mod1: Control + allowSubCombs: true +- function: TextCopy + type: State + key: C + mod1: Control + allowSubCombs: true +- function: TextCut + type: State + key: X + mod1: Control + allowSubCombs: true +- function: TextPaste + type: State + key: V + mod1: Control + allowSubCombs: true +- function: TextHistoryPrev + type: State + key: Up +- function: TextHistoryNext + type: State + key: Down +- function: TextCompleteNext + type: State + key: Down + priority: 1 + canRepeat: true +- function: TextCompletePrev + type: State + key: Up + priority: 1 + canRepeat: true +- function: TextReleaseFocus + type: State + key: Escape + priority: 15 +- function: TextScrollToBottom + type: State + key: PageDown +- function: TextTabComplete + type: State + key: Tab +- function: OpenEntitySpawnWindow + type: State + key: F5 +- function: OpenTileSpawnWindow + type: State + key: F6 +- function: OpenAdminMenu + type: State + key: F7 +- function: OpenDecalSpawnWindow + type: State + key: F8 +- function: OpenScoreboardWindow + type: State + key: F9 +- function: OpenSandboxWindow + type: State + key: B +- function: TakeScreenshot + type: State + key: F2 +- function: TakeScreenshotNoUI + type: State + key: F2 + mod1: Shift +- function: GuiTabNavigateNext + type: State + key: Tab +- function: GuiTabNavigatePrev + type: State + key: Tab + mod1: Shift +- function: EscapeContext + type: State + key: Escape +- function: WindowCloseAll + type: State + key: Escape + mod1: Shift +- function: Point + type: State + key: MouseMiddle + mod1: Shift +- function: ArcadeUp + type: State + key: Up +- function: ArcadeDown + type: State + key: Down +- function: ArcadeLeft + type: State + key: Left +- function: ArcadeRight + type: State + key: Right +- function: Arcade1 + type: State + key: Space +- function: Arcade2 + type: State + key: C +- function: Arcade3 + type: State + key: Z +- function: OpenAbilitiesMenu + type: State + key: K +- function: Hotbar0 + type: State + key: Num0 +- function: Hotbar1 + type: State + key: Num1 +- function: Hotbar2 + type: State + key: Num2 +- function: Hotbar3 + type: State + key: Num3 +- function: Hotbar4 + type: State + key: Num4 +- function: Hotbar5 + type: State + key: Num5 +- function: Hotbar6 + type: State + key: Num6 +- function: Hotbar7 + type: State + key: Num7 +- function: Hotbar8 + type: State + key: Num8 +- function: Hotbar9 + type: State + key: Num9 +<<<<<<< HEAD +======= +- function: Loadout0 + type: State + key: Num0 + mod1: Shift +- function: Loadout1 + type: State + key: Num1 + mod1: Shift +- function: Loadout2 + type: State + key: Num2 + mod1: Shift +- function: Loadout3 + type: State + key: Num3 + mod1: Shift +- function: Loadout4 + type: State + key: Num4 + mod1: Shift +- function: Loadout5 + type: State + key: Num5 + mod1: Shift +- function: Loadout6 + type: State + key: Num6 + mod1: Shift +- function: Loadout7 + type: State + key: Num7 + mod1: Shift +- function: Loadout8 + type: State + key: Num8 + mod1: Shift +- function: Loadout9 + type: State + key: Num9 + mod1: Shift +- function: LieDownStandUp + type: State + key: Z + mod1: Shift +>>>>>>> Moved stuff to standing system for ease of use. Fixed some edge cases with KnockedDownComponent.