Skip to content

Commit

Permalink
Merge remote-tracking branch 'next-origin/master' into FootprintsRework
Browse files Browse the repository at this point in the history
  • Loading branch information
FireNameFN committed Jan 14, 2025
2 parents a38ed3b + 79fe82a commit aaad687
Show file tree
Hide file tree
Showing 286 changed files with 342,369 additions and 228,275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public DefaultGameScreen()
Chat.OnResized += ChatOnResized;
Chat.OnChatResizeFinish += ChatOnResizeFinish;
MainViewport.OnResized += ResizeActionContainer;
MainViewport.OnResized += ResizeAlertsContainer;
MainViewport.OnResized += ResizeAlertsContainer; // Corvax-Next-Surgery
Inventory.OnResized += ResizeActionContainer;
}

Expand All @@ -37,11 +37,13 @@ private void ResizeActionContainer()
Actions.ActionsContainer.MaxGridHeight = MainViewport.Size.Y - indent;
}

// Corvax-Next-Surgery-Start
private void ResizeAlertsContainer()
{
float indent = Chat.Size.Y + Targeting.Size.Y + 120;
Alerts.AlertContainer.MaxGridHeight = Math.Max(MainViewport.Size.Y - indent, 1);
}
// Corvax-Next-Surgery-End

private void ChatOnResizeFinish(Vector2 _)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
xmlns:partStatus="clr-namespace:Content.Client._CorvaxNext.UserInterface.Systems.PartStatus.Widgets"
MinSize="64 64">
<GridContainer Columns="1" HorizontalAlignment="Right" VerticalAlignment="Top">
<PanelContainer >
<GridContainer Name="AlertContainer" Columns="1" HorizontalAlignment="Right" VerticalAlignment="Center" Access="Public" />
<PanelContainer>
<GridContainer Name="AlertContainer" Columns="1" HorizontalAlignment="Right" VerticalAlignment="Center" Access="Public" /> <!-- Corvax-Next-Surgery -->
</PanelContainer>
<partStatus:PartStatusControl Name="PartStatus" Access="Protected"/>
</GridContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public sealed partial class AlertsUI : UIWidget
public AlertsUI()
{
RobustXamlLoader.Load(this);
LayoutContainer.SetGrowHorizontal(this, LayoutContainer.GrowDirection.Begin);
LayoutContainer.SetGrowHorizontal(this, LayoutContainer.GrowDirection.Begin); // Corvax-Next-Surgery
}

public void SyncControls(AlertsSystem alertsSystem,
Expand Down
34 changes: 34 additions & 0 deletions Content.Client/_CorvaxNext/CrewMedal/CrewMedalSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Content.Client._CorvaxNext.CrewMedal.UI;
using Content.Shared._CorvaxNext.CrewMedal;

namespace Content.Client._CorvaxNext.CrewMedal;

/// <summary>
/// Handles the client-side logic for the Crew Medal system.
/// </summary>
public sealed class CrewMedalSystem : SharedCrewMedalSystem
{
[Dependency] private readonly SharedUserInterfaceSystem _userInterfaceSystem = default!;

public override void Initialize()
{
base.Initialize();
// Subscribes to the event triggered after the state is automatically handled.
SubscribeLocalEvent<CrewMedalComponent, AfterAutoHandleStateEvent>(OnCrewMedalAfterState);
}

/// <summary>
/// When an updated state is received on the client, refresh the UI to display the latest data.
/// </summary>
private void OnCrewMedalAfterState(Entity<CrewMedalComponent> entity, ref AfterAutoHandleStateEvent args)
{
// Checks if the Crew Medal UI is open for the given entity and reloads it with updated data.
if (_userInterfaceSystem.TryGetOpenUi<CrewMedalBoundUserInterface>(
entity.Owner,
CrewMedalUiKey.Key,
out var medalUi))
{
medalUi.Reload();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Content.Shared._CorvaxNext.CrewMedal;
using Robust.Client.UserInterface;

namespace Content.Client._CorvaxNext.CrewMedal.UI;

/// <summary>
/// A wrapper class for the Crew Medal user interface.
/// Initializes the <see cref="CrewMedalWindow"/> and updates it when new data is received from the server.
/// </summary>
public sealed class CrewMedalBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IEntityManager _entityManager = default!;

/// <summary>
/// The main interface window.
/// </summary>
[ViewVariables]
private CrewMedalWindow? _window;

public CrewMedalBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}

protected override void Open()
{
base.Open();

_window = this.CreateWindow<CrewMedalWindow>();
_window.OnReasonChanged += HandleReasonChanged;

Reload();
}

/// <summary>
/// Called when the reason is changed in the <see cref="CrewMedalWindow"/>.
/// Sends a message to the server with the new reason if it differs from the current one.
/// </summary>
private void HandleReasonChanged(string newReason)
{
if (!_entityManager.TryGetComponent<CrewMedalComponent>(Owner, out var component))
return;

if (!component.Reason.Equals(newReason))
{
SendPredictedMessage(new CrewMedalReasonChangedMessage(newReason));
}
}

/// <summary>
/// Updates the data in the window to reflect the current state of the <see cref="CrewMedalComponent"/>.
/// </summary>
public void Reload()
{
if (_window is null)
return;

if (!_entityManager.TryGetComponent<CrewMedalComponent>(Owner, out var component))
return;

_window.SetCurrentReason(component.Reason);
_window.SetAwarded(component.Awarded);
_window.SetMaxCharacters(component.MaxCharacters);
}
}
13 changes: 13 additions & 0 deletions Content.Client/_CorvaxNext/CrewMedal/UI/CrewMedalWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Loc 'crew-medal-ui-header'}">
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
<Label Text="{Loc 'crew-medal-ui-reason'}" />
<BoxContainer Orientation="Horizontal">
<LineEdit Name="ReasonLineEdit" HorizontalExpand="True" />
<Button Name="SaveButton" Text="{Loc 'crew-medal-ui-save'}" />
</BoxContainer>
<Label Name="CharacterLabel" Text="" />
<Label Text="{Loc 'crew-medal-ui-info'}" />
</BoxContainer>
</DefaultWindow>
88 changes: 88 additions & 0 deletions Content.Client/_CorvaxNext/CrewMedal/UI/CrewMedalWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._CorvaxNext.CrewMedal.UI;

[GenerateTypedNameReferences]
public sealed partial class CrewMedalWindow : DefaultWindow
{
/// <summary>
/// Event triggered when the "Save" button is pressed,
/// provided the user has changed the reason text.
/// </summary>
public event Action<string>? OnReasonChanged;

private bool _isFocused;
private string _reason = string.Empty;
private bool _awarded;
private int _maxCharacters = 50;

public CrewMedalWindow()
{
RobustXamlLoader.Load(this);

ReasonLineEdit.OnTextChanged += _ =>
{
// Check character limit and award status
SaveButton.Disabled = _awarded || ReasonLineEdit.Text.Length > _maxCharacters;
CharacterLabel.Text = Loc.GetString(
"crew-medal-ui-character-limit",
("number", ReasonLineEdit.Text.Length),
("max", _maxCharacters));
};

ReasonLineEdit.OnFocusEnter += _ => _isFocused = true;
ReasonLineEdit.OnFocusExit += _ => _isFocused = false;

SaveButton.OnPressed += _ =>
{
OnReasonChanged?.Invoke(ReasonLineEdit.Text);
SaveButton.Disabled = true;
};

// Initialize the character counter display
CharacterLabel.Text = Loc.GetString(
"crew-medal-ui-character-limit",
("number", ReasonLineEdit.Text.Length),
("max", _maxCharacters));
}

/// <summary>
/// Sets the current reason and synchronizes it with the input field
/// if the user is not currently editing the field.
/// </summary>
public void SetCurrentReason(string reason)
{
if (_reason == reason)
return;

_reason = reason;

// Synchronize text if the input field is not focused
if (!_isFocused)
ReasonLineEdit.Text = _reason;
}

/// <summary>
/// Updates the "is medal awarded" status
/// and disables editing if the medal is already awarded.
/// </summary>
public void SetAwarded(bool awarded)
{
_awarded = awarded;
ReasonLineEdit.Editable = !_awarded;
SaveButton.Disabled = _awarded;
}

/// <summary>
/// Updates the maximum character limit for the reason.
/// If the current text exceeds the limit, it will be truncated.
/// </summary>
public void SetMaxCharacters(int number)
{
_maxCharacters = number;
if (ReasonLineEdit.Text.Length > _maxCharacters)
ReasonLineEdit.Text = ReasonLineEdit.Text[.._maxCharacters];
}
}
124 changes: 124 additions & 0 deletions Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using Robust.Client.Animations;
using Robust.Shared.Animations;
using Robust.Shared.GameStates;
using Robust.Client.GameObjects;
using Content.Shared.Emoting;
using Content.Shared._CorvaxNext.Emoting;
using System.Numerics;
using Robust.Shared.Prototypes;
using Content.Shared.Chat.Prototypes;

namespace Content.Client._CorvaxNext.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<AnimatedEmotesComponent, ComponentHandleState>(OnHandleState);

SubscribeLocalEvent<AnimatedEmotesComponent, AnimationFlipEmoteEvent>(OnFlip);
SubscribeLocalEvent<AnimatedEmotesComponent, AnimationSpinEmoteEvent>(OnSpin);
SubscribeLocalEvent<AnimatedEmotesComponent, AnimationJumpEmoteEvent>(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<EmotePrototype>(state.Emote, out var emote))
return;

if (emote.Event != null)
RaiseLocalEvent(uid, emote.Event);
}

private void OnFlip(Entity<AnimatedEmotesComponent> 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<AnimatedEmotesComponent> 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<AnimatedEmotesComponent> 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);
}
}
Loading

0 comments on commit aaad687

Please sign in to comment.