Skip to content

Commit

Permalink
Merge Upstream 13.10.2024 (Grimbly-Station#108)
Browse files Browse the repository at this point in the history
<!--
This is a semi-strict format, you can add/remove sections as needed but
the order/format should be kept the same
Remove these comments before submitting
-->

# Description

<!--
Explain this PR in as much detail as applicable

Some example prompts to consider:
How might this affect the game? The codebase?
What might be some alternatives to this?
How/Who does this benefit/hurt [the game/codebase]?
-->

Merges the most recent EE upstream, now with 100% more bugfixing!

---

# TODO

<!--
A list of everything you have to do before this PR is "complete"
You probably won't have to complete everything before merging but it's
good to leave future references
-->

- [ ] Task
- [x] Completed Task

---

<!--
This is default collapsed, readers click to expand it and see all your
media
The PR media section can get very large at times, so this is a good way
to keep it clean
The title is written using HTML tags
The title must be within the <summary> tags or you won't see it
-->

<details><summary><h1>Media</h1></summary>
<p>

![Example Media Embed](https://example.com/thisimageisntreal.png)

</p>
</details>

---

# Changelog

<!--
You can add an author after the `:cl:` to change the name that appears
in the changelog (ex: `:cl: Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->
  • Loading branch information
SsalamethVersaach authored Oct 13, 2024
2 parents 1d3fe8a + 8dce104 commit b4b4729
Show file tree
Hide file tree
Showing 561 changed files with 313,973 additions and 2,372 deletions.
6 changes: 6 additions & 0 deletions Content.Client/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,11 @@ public void ToggleGhostVisibility()
{
GhostVisibility = !GhostVisibility;
}

public void ReturnToRound()
{
var msg = new GhostReturnToRoundRequest();
RaiseNetworkEvent(msg);
}
}
}
56 changes: 28 additions & 28 deletions Content.Client/Language/LanguageMenuWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
using Content.Client.Language.Systems;
using Content.Shared.Language;
using Content.Shared.Language.Components;
using Content.Shared.Language.Events;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;

namespace Content.Client.Language;

[GenerateTypedNameReferences]
public sealed partial class LanguageMenuWindow : DefaultWindow, IEntityEventSubscriber
public sealed partial class LanguageMenuWindow : DefaultWindow
{
private readonly LanguageSystem _clientLanguageSystem;
private readonly List<EntryState> _entries = new();


public LanguageMenuWindow()
{
RobustXamlLoader.Load(this);
_clientLanguageSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<LanguageSystem>();

_clientLanguageSystem.OnLanguagesChanged += OnUpdateState;
_clientLanguageSystem.OnLanguagesChanged += UpdateState;
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_clientLanguageSystem.OnLanguagesChanged -= OnUpdateState;

if (disposing)
_clientLanguageSystem.OnLanguagesChanged -= UpdateState;
}

protected override void Opened()
{
// Refresh the window when it gets opened.
// This actually causes two refreshes: one immediately, and one after the server sends a state message.
UpdateState(_clientLanguageSystem.CurrentLanguage, _clientLanguageSystem.SpokenLanguages);
_clientLanguageSystem.RequestStateUpdate();
UpdateState();
}


private void OnUpdateState(object? sender, LanguagesUpdatedMessage args)
private void UpdateState()
{
UpdateState(args.CurrentLanguage, args.Spoken);
var languageSpeaker = _clientLanguageSystem.GetLocalSpeaker();
if (languageSpeaker == null)
return;

UpdateState(languageSpeaker.CurrentLanguage, languageSpeaker.SpokenLanguages);
}

public void UpdateState(string currentLanguage, List<string> spokenLanguages)
public void UpdateState(ProtoId<LanguagePrototype> currentLanguage, List<ProtoId<LanguagePrototype>> spokenLanguages)
{
var langName = Loc.GetString($"language-{currentLanguage}-name");
CurrentLanguageLabel.Text = Loc.GetString("language-menu-current-language", ("language", langName));
Expand All @@ -58,15 +61,15 @@ public void UpdateState(string currentLanguage, List<string> spokenLanguages)
// Disable the button for the currently chosen language
foreach (var entry in _entries)
{
if (entry.button != null)
entry.button.Disabled = entry.language == currentLanguage;
if (entry.Button != null)
entry.Button.Disabled = entry.Language == currentLanguage;
}
}

private void AddLanguageEntry(string language)
private void AddLanguageEntry(ProtoId<LanguagePrototype> language)
{
var proto = _clientLanguageSystem.GetLanguagePrototype(language);
var state = new EntryState { language = language };
var state = new EntryState { Language = language };

var container = new BoxContainer { Orientation = BoxContainer.LayoutOrientation.Vertical };

Expand All @@ -87,7 +90,7 @@ private void AddLanguageEntry(string language)

var button = new Button { Text = "Choose" };
button.OnPressed += _ => OnLanguageChosen(language);
state.button = button;
state.Button = button;

header.AddChild(name);
header.AddChild(button);
Expand Down Expand Up @@ -125,21 +128,18 @@ private void AddLanguageEntry(string language)
_entries.Add(state);
}


private void OnLanguageChosen(string id)
private void OnLanguageChosen(ProtoId<LanguagePrototype> id)
{
var proto = _clientLanguageSystem.GetLanguagePrototype(id);
if (proto == null)
return;
_clientLanguageSystem.RequestSetLanguage(id);

_clientLanguageSystem.RequestSetLanguage(proto);
UpdateState(id, _clientLanguageSystem.SpokenLanguages);
// Predict the change
if (_clientLanguageSystem.GetLocalSpeaker()?.SpokenLanguages is {} languages)
UpdateState(id, languages);
}


private struct EntryState
{
public string language;
public Button? button;
public ProtoId<LanguagePrototype> Language;
public Button? Button;
}
}
78 changes: 29 additions & 49 deletions Content.Client/Language/Systems/LanguageSystem.cs
Original file line number Diff line number Diff line change
@@ -1,81 +1,61 @@
using Content.Shared.Language;
using Content.Shared.Language.Components;
using Content.Shared.Language.Events;
using Content.Shared.Language.Systems;
using Robust.Client;
using Robust.Client.Player;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;

namespace Content.Client.Language.Systems;

/// <summary>
/// Client-side language system.
/// </summary>
/// <remarks>
/// Unlike the server, the client is not aware of other entities' languages; it's only notified about the entity that it posesses.
/// Due to that, this system stores such information in a static manner.
/// </remarks>
public sealed class LanguageSystem : SharedLanguageSystem
{
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;

/// <summary>
/// The current language of the entity currently possessed by the player.
/// Invoked when the languages of the local player entity change, for use in UI.
/// </summary>
public string CurrentLanguage { get; private set; } = default!;
/// <summary>
/// The list of languages the currently possessed entity can speak.
/// </summary>
public List<string> SpokenLanguages { get; private set; } = new();
/// <summary>
/// The list of languages the currently possessed entity can understand.
/// </summary>
public List<string> UnderstoodLanguages { get; private set; } = new();

public event EventHandler<LanguagesUpdatedMessage>? OnLanguagesChanged;
public event Action? OnLanguagesChanged;

public override void Initialize()
{
base.Initialize();

SubscribeNetworkEvent<LanguagesUpdatedMessage>(OnLanguagesUpdated);
_client.RunLevelChanged += OnRunLevelChanged;
_playerManager.LocalPlayerAttached += NotifyUpdate;
SubscribeLocalEvent<LanguageSpeakerComponent, ComponentHandleState>(OnHandleState);
}

private void OnLanguagesUpdated(LanguagesUpdatedMessage message)
private void OnHandleState(Entity<LanguageSpeakerComponent> ent, ref ComponentHandleState args)
{
// TODO this entire thing is horrible. If someone is willing to refactor this, LanguageSpeakerComponent should become shared with SendOnlyToOwner = true
// That way, this system will be able to use the existing networking infrastructure instead of relying on this makeshift... whatever this is.
CurrentLanguage = message.CurrentLanguage;
SpokenLanguages = message.Spoken;
UnderstoodLanguages = message.Understood;
if (args.Current is not LanguageSpeakerComponent.State state)
return;

OnLanguagesChanged?.Invoke(this, message);
}
ent.Comp.CurrentLanguage = state.CurrentLanguage;
ent.Comp.SpokenLanguages = state.SpokenLanguages;
ent.Comp.UnderstoodLanguages = state.UnderstoodLanguages;

private void OnRunLevelChanged(object? sender, RunLevelChangedEventArgs args)
{
// Request an update when entering a game
if (args.NewLevel == ClientRunLevel.InGame)
RequestStateUpdate();
if (ent.Owner == _playerManager.LocalEntity)
NotifyUpdate(ent);
}

/// <summary>
/// Sends a network request to the server to update this system's state.
/// The server may ignore the said request if the player is not possessing an entity.
/// Returns the LanguageSpeakerComponent of the local player entity.
/// Will return null if the player does not have an entity, or if the client has not yet received the component state.
/// </summary>
public void RequestStateUpdate()
public LanguageSpeakerComponent? GetLocalSpeaker()
{
RaiseNetworkEvent(new RequestLanguagesMessage());
return CompOrNull<LanguageSpeakerComponent>(_playerManager.LocalEntity);
}

public void RequestSetLanguage(LanguagePrototype language)
public void RequestSetLanguage(ProtoId<LanguagePrototype> language)
{
if (language.ID == CurrentLanguage)
if (GetLocalSpeaker()?.CurrentLanguage?.Equals(language) == true)
return;

RaiseNetworkEvent(new LanguagesSetMessage(language.ID));
RaiseNetworkEvent(new LanguagesSetMessage(language));
}

// May cause some minor desync...
// So to reduce the probability of desync, we replicate the change locally too
if (SpokenLanguages.Contains(language.ID))
CurrentLanguage = language.ID;
private void NotifyUpdate(EntityUid localPlayer)
{
RaiseLocalEvent(localPlayer, new LanguagesUpdateEvent(), broadcast: true);
OnLanguagesChanged?.Invoke();
}
}
2 changes: 1 addition & 1 deletion Content.Client/Lobby/UI/LobbyGui.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Stretch="KeepAspectCovered" />
<BoxContainer Name="MainContainer" VerticalExpand="True" HorizontalExpand="True" Orientation="Horizontal"
Margin="10 10 10 10" SeparationOverride="2">
<SplitContainer State="Auto" HorizontalExpand="True">
<SplitContainer State="Auto" ResizeMode="NotResizable" HorizontalExpand="True">
<!-- LHS Controls -->
<BoxContainer Name="LeftSide" Orientation="Vertical" SeparationOverride="4" HorizontalExpand="True">
<Control Name="DefaultState" VerticalExpand="True">
Expand Down
24 changes: 10 additions & 14 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
ToolTip="{Loc 'humanoid-profile-editor-guidebook-button-tooltip'}"/>
<OptionButton Name="CSpeciesButton" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Species -->
<BoxContainer Name="CCustomSpecieName" HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-customspeciename-label'}" />
<Control HorizontalExpand="True"/>
<LineEdit Name="CCustomSpecieNameEdit" MinSize="270 0" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Age -->
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-age-label'}" />
Expand Down Expand Up @@ -91,18 +97,6 @@
<Control HorizontalExpand="True"/>
<Button Name="ShowLoadouts" Pressed="True" ToggleMode="True" Text="{Loc 'Show'}" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Clothing -->
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-clothing-label'}" />
<Control HorizontalExpand="True"/>
<OptionButton Name="CClothingButton" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Backpack -->
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-backpack-label'}" />
<Control HorizontalExpand="True"/>
<OptionButton Name="CBackpackButton" HorizontalAlignment="Right" />
</BoxContainer>
<!-- Spawn Priority -->
<BoxContainer HorizontalExpand="True">
<Label Text="{Loc 'humanoid-profile-editor-spawn-priority-label'}" />
Expand Down Expand Up @@ -211,8 +205,10 @@
<ui:NeoTabContainer Name="CLoadoutsTabs" VerticalExpand="True" SeparatorMargin="0" />
</BoxContainer>
<BoxContainer Name="CMarkingsTab" HorizontalExpand="True" Orientation="Vertical" Margin="10">
<!-- Markings -->
<humanoid:MarkingPicker Name="CMarkings" IgnoreCategories="Hair,FacialHair" />
<ScrollContainer HorizontalExpand="True" HScrollEnabled="True" VerticalExpand="True" VScrollEnabled="True">
<!-- Markings -->
<humanoid:MarkingPicker Name="CMarkings" IgnoreCategories="Hair,FacialHair" />
</ScrollContainer>
</BoxContainer>
</ui:NeoTabContainer>
</BoxContainer>
Expand Down
Loading

0 comments on commit b4b4729

Please sign in to comment.