forked from space-syndicate/space-station-14
-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'next-origin/master' into FootprintsRework
- Loading branch information
Showing
286 changed files
with
342,369 additions
and
228,275 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
Content.Client/_CorvaxNext/CrewMedal/UI/CrewMedalBoundUserInterface.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
13
Content.Client/_CorvaxNext/CrewMedal/UI/CrewMedalWindow.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
88
Content.Client/_CorvaxNext/CrewMedal/UI/CrewMedalWindow.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
124
Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.