diff --git a/Content.Client/Emoting/AnimatedEmotesSystem.cs b/Content.Client/Emoting/AnimatedEmotesSystem.cs new file mode 100644 index 00000000000..40766b4e13e --- /dev/null +++ b/Content.Client/Emoting/AnimatedEmotesSystem.cs @@ -0,0 +1,121 @@ +using Robust.Client.Animations; +using Robust.Shared.Animations; +using Robust.Shared.GameStates; +using Robust.Client.GameObjects; +using Content.Shared.Emoting; +using System.Numerics; +using Robust.Shared.Prototypes; +using Content.Shared.Chat.Prototypes; + +namespace Content.Client.Emoting; + +public sealed partial class AnimatedEmotesSystem : SharedAnimatedEmotesSystem +{ + [Dependency] private readonly AnimationPlayerSystem _anim = default!; + [Dependency] private readonly IPrototypeManager _prot = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnHandleState); + + SubscribeLocalEvent(OnFlip); + SubscribeLocalEvent(OnSpin); + SubscribeLocalEvent(OnJump); + } + + public void PlayEmote(EntityUid uid, Animation anim, string animationKey = "emoteAnimKeyId") + { + if (_anim.HasRunningAnimation(uid, animationKey)) + return; + + _anim.Play(uid, anim, animationKey); + } + + private void OnHandleState(EntityUid uid, AnimatedEmotesComponent component, ref ComponentHandleState args) + { + if (args.Current is not AnimatedEmotesComponentState state + || !_prot.TryIndex(state.Emote, out var emote)) + return; + + if (emote.Event != null) + RaiseLocalEvent(uid, emote.Event); + } + + private void OnFlip(Entity ent, ref AnimationFlipEmoteEvent args) + { + var a = new Animation + { + Length = TimeSpan.FromMilliseconds(500), + AnimationTracks = + { + new AnimationTrackComponentProperty + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Rotation), + InterpolationMode = AnimationInterpolationMode.Linear, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(Angle.Zero, 0f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.25f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(360), 0.25f), + } + } + } + }; + PlayEmote(ent, a); + } + private void OnSpin(Entity ent, ref AnimationSpinEmoteEvent args) + { + var a = new Animation + { + Length = TimeSpan.FromMilliseconds(600), + AnimationTracks = + { + new AnimationTrackComponentProperty + { + ComponentType = typeof(TransformComponent), + Property = nameof(TransformComponent.LocalRotation), + InterpolationMode = AnimationInterpolationMode.Linear, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), 0f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(90), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(270), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.Zero, 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(90), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(270), 0.075f), + new AnimationTrackProperty.KeyFrame(Angle.Zero, 0.075f), + } + } + } + }; + PlayEmote(ent, a, "emoteAnimSpin"); + } + private void OnJump(Entity ent, ref AnimationJumpEmoteEvent args) + { + var a = new Animation + { + Length = TimeSpan.FromMilliseconds(250), + AnimationTracks = + { + new AnimationTrackComponentProperty + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Offset), + InterpolationMode = AnimationInterpolationMode.Cubic, + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(Vector2.Zero, 0f), + new AnimationTrackProperty.KeyFrame(new Vector2(0, .35f), 0.125f), + new AnimationTrackProperty.KeyFrame(Vector2.Zero, 0.125f), + } + } + } + }; + PlayEmote(ent, a); + } +} diff --git a/Content.Client/Jittering/JitteringSystem.cs b/Content.Client/Jittering/JitteringSystem.cs index 185bd490d3b..aafaf318bb9 100644 --- a/Content.Client/Jittering/JitteringSystem.cs +++ b/Content.Client/Jittering/JitteringSystem.cs @@ -45,7 +45,7 @@ private void OnShutdown(EntityUid uid, JitteringComponent jittering, ComponentSh private void OnAnimationCompleted(EntityUid uid, JitteringComponent jittering, AnimationCompletedEvent args) { - if(args.Key != _jitterAnimationKey) + if (args.Key != _jitterAnimationKey || jittering.LifeStage >= ComponentLifeStage.Stopping) return; if (TryComp(uid, out AnimationPlayerComponent? animationPlayer) diff --git a/Content.Client/ListViewSelector/ListViewSelectorBUI.cs b/Content.Client/ListViewSelector/ListViewSelectorBUI.cs index f02bab512e8..dd1f2299427 100644 --- a/Content.Client/ListViewSelector/ListViewSelectorBUI.cs +++ b/Content.Client/ListViewSelector/ListViewSelectorBUI.cs @@ -84,7 +84,7 @@ private void PopulateWindow(List items) { var itemName = item.Name; var itemDesc = item.Description; - if (_prototypeManager.TryIndex(item.Id, out var itemPrototype)) + if (_prototypeManager.TryIndex(item.Id, out var itemPrototype, false)) { itemName = itemPrototype.Name; itemDesc = itemPrototype.Description; diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs index f23fd6b4a0d..ce14882d167 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs @@ -95,7 +95,8 @@ public HumanoidProfileEditor( IPlayerManager playerManager, IPrototypeManager prototypeManager, JobRequirementsManager requirements, - MarkingManager markings) + MarkingManager markings + ) { RobustXamlLoader.Load(this); _cfgManager = cfgManager; @@ -114,7 +115,8 @@ public HumanoidProfileEditor( SaveButton.OnPressed += args => { Save?.Invoke(); }; ResetButton.OnPressed += args => { - SetProfile((HumanoidCharacterProfile?) _preferencesManager.Preferences?.SelectedCharacter, + SetProfile( + (HumanoidCharacterProfile?) _preferencesManager.Preferences?.SelectedCharacter, _preferencesManager.Preferences?.SelectedCharacterIndex); }; @@ -193,12 +195,11 @@ public HumanoidProfileEditor( #endregion Species - #region Height + #region Height and Width var prototype = _species.Find(x => x.ID == Profile?.Species) ?? _species.First(); UpdateHeightWidthSliders(); - UpdateDimensions(SliderUpdate.Both); HeightSlider.OnValueChanged += _ => UpdateDimensions(SliderUpdate.Height); WidthSlider.OnValueChanged += _ => UpdateDimensions(SliderUpdate.Width); @@ -492,7 +493,7 @@ public void RefreshFlavorText() if (_flavorText != null) return; - _flavorText = new FlavorText.FlavorText(); + _flavorText = new(); _flavorText.OnFlavorTextChanged += OnFlavorTextChange; _flavorTextEdit = _flavorText.CFlavorTextInput; CTabContainer.AddTab(_flavorText, Loc.GetString("humanoid-profile-editor-flavortext-tab")); @@ -763,11 +764,11 @@ public void RefreshJobs() foreach (var job in jobs) { var jobContainer = new BoxContainer { Orientation = LayoutOrientation.Horizontal, }; - var selector = new RequirementsSelector { Margin = new Thickness(3f, 3f, 3f, 0f) }; + var selector = new RequirementsSelector { Margin = new(3f, 3f, 3f, 0f) }; var icon = new TextureRect { - TextureScale = new Vector2(2, 2), + TextureScale = new(2, 2), VerticalAlignment = VAlignment.Center }; var jobIcon = _prototypeManager.Index(job.Icon); @@ -1349,21 +1350,26 @@ private void UpdateSpawnPriorityControls() private void UpdateHeightWidthSliders() { + if (Profile is null) + return; + var species = _species.Find(x => x.ID == Profile?.Species) ?? _species.First(); HeightSlider.MinValue = species.MinHeight; HeightSlider.MaxValue = species.MaxHeight; - HeightSlider.Value = Profile?.Height ?? species.DefaultHeight; + HeightSlider.SetValueWithoutEvent(Profile?.Height ?? species.DefaultHeight); WidthSlider.MinValue = species.MinWidth; WidthSlider.MaxValue = species.MaxWidth; - WidthSlider.Value = Profile?.Width ?? species.DefaultWidth; + WidthSlider.SetValueWithoutEvent(Profile?.Width ?? species.DefaultWidth); var height = MathF.Round(species.AverageHeight * HeightSlider.Value); HeightLabel.Text = Loc.GetString("humanoid-profile-editor-height-label", ("height", (int) height)); var width = MathF.Round(species.AverageWidth * WidthSlider.Value); WidthLabel.Text = Loc.GetString("humanoid-profile-editor-width-label", ("width", (int) width)); + + UpdateDimensions(SliderUpdate.Both); } private enum SliderUpdate @@ -1375,9 +1381,10 @@ private enum SliderUpdate private void UpdateDimensions(SliderUpdate updateType) { - var species = _species.Find(x => x.ID == Profile?.Species) ?? _species.First(); + if (Profile == null) + return; - if (Profile == null) return; + var species = _species.Find(x => x.ID == Profile?.Species) ?? _species.First(); var heightValue = Math.Clamp(HeightSlider.Value, species.MinHeight, species.MaxHeight); var widthValue = Math.Clamp(WidthSlider.Value, species.MinWidth, species.MaxWidth); @@ -1386,13 +1393,12 @@ private void UpdateDimensions(SliderUpdate updateType) if (updateType == SliderUpdate.Height || updateType == SliderUpdate.Both) if (ratio < 1 / sizeRatio || ratio > sizeRatio) - widthValue = heightValue / (ratio < 1 / sizeRatio ? (1 / sizeRatio) : sizeRatio); + widthValue = heightValue * (ratio < 1 / sizeRatio ? (1 / sizeRatio) : sizeRatio); if (updateType == SliderUpdate.Width || updateType == SliderUpdate.Both) if (ratio < 1 / sizeRatio || ratio > sizeRatio) heightValue = widthValue * (ratio < 1 / sizeRatio ? (1 / sizeRatio) : sizeRatio); - heightValue = Math.Clamp(heightValue, species.MinHeight, species.MaxHeight); widthValue = Math.Clamp(widthValue, species.MinWidth, species.MaxWidth); diff --git a/Content.Client/MainMenu/MainMenu.cs b/Content.Client/MainMenu/MainMenu.cs index 43c5bfe5674..58d94adf225 100644 --- a/Content.Client/MainMenu/MainMenu.cs +++ b/Content.Client/MainMenu/MainMenu.cs @@ -7,6 +7,7 @@ using Robust.Client.UserInterface.Controls; using Robust.Shared; using Robust.Shared.Configuration; +using Robust.Shared.Console; using Robust.Shared.Network; using Robust.Shared.Utility; using UsernameHelpers = Robust.Shared.AuthLib.UsernameHelpers; @@ -25,9 +26,11 @@ public sealed class MainScreen : Robust.Client.State.State [Dependency] private readonly IGameController _controllerProxy = default!; [Dependency] private readonly IResourceCache _resourceCache = default!; [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; + [Dependency] private readonly IConsoleHost _console = default!; private MainMenuControl _mainMenuControl = default!; private bool _isConnecting; + private bool _shouldGoLobby; // ReSharper disable once InconsistentNaming private static readonly Regex IPv6Regex = new(@"\[(.*:.*:.*)](?::(\d+))?"); @@ -38,15 +41,27 @@ protected override void Startup() _mainMenuControl = new MainMenuControl(_resourceCache, _configurationManager); _userInterfaceManager.StateRoot.AddChild(_mainMenuControl); + _client.PlayerJoinedGame += OnPlayerJoinedGame; + _mainMenuControl.QuitButton.OnPressed += QuitButtonPressed; _mainMenuControl.OptionsButton.OnPressed += OptionsButtonPressed; _mainMenuControl.DirectConnectButton.OnPressed += DirectConnectButtonPressed; + _mainMenuControl.GoToLobbyButton.OnPressed += GoToLobbyButtonPressed; _mainMenuControl.AddressBox.OnTextEntered += AddressBoxEntered; _mainMenuControl.ChangelogButton.OnPressed += ChangelogButtonPressed; _client.RunLevelChanged += RunLevelChanged; } + private void OnPlayerJoinedGame(object? sender, PlayerEventArgs e) + { + if (_shouldGoLobby) + { + _console.ExecuteCommand("golobby"); + _shouldGoLobby = false; + } + } + /// protected override void Shutdown() { @@ -77,12 +92,18 @@ private void DirectConnectButtonPressed(BaseButton.ButtonEventArgs args) TryConnect(input.Text); } + private void GoToLobbyButtonPressed(BaseButton.ButtonEventArgs obj) + { + var input = _mainMenuControl.AddressBox; + TryConnect(input.Text); + + _shouldGoLobby = true; + } + private void AddressBoxEntered(LineEdit.LineEditEventArgs args) { if (_isConnecting) - { return; - } TryConnect(args.Text); } @@ -185,6 +206,7 @@ private void _setConnectingState(bool state) { _isConnecting = state; _mainMenuControl.DirectConnectButton.Disabled = state; + _mainMenuControl.GoToLobbyButton.Disabled = state; } } } diff --git a/Content.Client/MainMenu/UI/MainMenuControl.xaml b/Content.Client/MainMenu/UI/MainMenuControl.xaml index d6c3f4b9415..e0242300fc2 100644 --- a/Content.Client/MainMenu/UI/MainMenuControl.xaml +++ b/Content.Client/MainMenu/UI/MainMenuControl.xaml @@ -30,6 +30,11 @@ Text="{Loc 'main-menu-direct-connect-button'}" TextAlign="Center" StyleIdentifier="mainMenu"/> +