Skip to content

Commit

Permalink
Languages
Browse files Browse the repository at this point in the history
  • Loading branch information
AwareFoxy committed Oct 29, 2024
1 parent 2293b77 commit 4ad302d
Show file tree
Hide file tree
Showing 114 changed files with 4,178 additions and 203 deletions.
1 change: 1 addition & 0 deletions Content.Client/Input/ContentContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public static void SetupContexts(IInputContextContainer contexts)
human.AddFunction(ContentKeyFunctions.MovePulledObject);
human.AddFunction(ContentKeyFunctions.ReleasePulledObject);
human.AddFunction(ContentKeyFunctions.OpenCraftingMenu);
human.AddFunction(ContentKeyFunctions.OpenLanguageMenu); // Corvax-Languages
human.AddFunction(ContentKeyFunctions.OpenInventoryMenu);
human.AddFunction(ContentKeyFunctions.SmartEquipBackpack);
human.AddFunction(ContentKeyFunctions.SmartEquipBelt);
Expand Down
1 change: 1 addition & 0 deletions Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action<BaseButton.Butto
AddButton(ContentKeyFunctions.CycleChatChannelBackward);
AddButton(ContentKeyFunctions.OpenCharacterMenu);
AddButton(ContentKeyFunctions.OpenCraftingMenu);
AddButton(ContentKeyFunctions.OpenLanguageMenu); // Corvax-Languages
AddButton(ContentKeyFunctions.OpenGuidebook);
AddButton(ContentKeyFunctions.OpenInventoryMenu);
AddButton(ContentKeyFunctions.OpenAHelp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Content.Client.UserInterface.Systems.MenuBar.Widgets;
using Content.Client.UserInterface.Systems.Sandbox;
using Robust.Client.UserInterface.Controllers;
using Content.Client._EinsteinEngine.UserInterface.Systems.Language; // Corvax-Languages

namespace Content.Client.UserInterface.Systems.MenuBar;

Expand All @@ -24,6 +25,7 @@ public sealed class GameTopMenuBarUIController : UIController
[Dependency] private readonly SandboxUIController _sandbox = default!;
[Dependency] private readonly GuidebookUIController _guidebook = default!;
[Dependency] private readonly EmotesUIController _emotes = default!;
[Dependency] private readonly LanguageMenuUIController _language = default!; // Corvax-Languages

private GameTopMenuBar? GameTopMenuBar => UIManager.GetActiveUIWidgetOrNull<GameTopMenuBar>();

Expand All @@ -47,6 +49,7 @@ public void UnloadButtons()
_action.UnloadButton();
_sandbox.UnloadButton();
_emotes.UnloadButton();
_language.UnloadButton(); // Corvax-Languages
}

public void LoadButtons()
Expand All @@ -60,5 +63,6 @@ public void LoadButtons()
_action.LoadButton();
_sandbox.LoadButton();
_emotes.LoadButton();
_language.LoadButton(); // Corvax-Languages
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<!-- Corvax-Languages-Start -->
<ui:MenuButton
Name="LanguageButton"
Access="Internal"
Icon="{xe:Tex '/Textures/_EinsteinEngine/Interface/language.png'}"
BoundKey = "{x:Static is:ContentKeyFunctions.OpenLanguageMenu}"
ToolTip="Open the Language Menu"
MinSize="42 64"
HorizontalExpand="True"
AppendStyleClass="{x:Static style:StyleBase.ButtonSquare}"
/>
<!-- Corvax-Languages-End -->
<ui:MenuButton
Name="AdminButton"
Access="Internal"
Expand Down
18 changes: 18 additions & 0 deletions Content.Client/_EinsteinEngine/Language/LanguageMenuWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
Title="{Loc language-menu-window-title}"
SetSize="300 300">
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
<PanelContainer Name="CurrentLanguageContainer" Access="Public" StyleClasses="PdaBorderRect">
<Label Name="CurrentLanguageLabel" Access="Public" Text="Current Language:" HorizontalExpand="True"></Label>
</PanelContainer>

<ui:HLine></ui:HLine>

<ScrollContainer HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="False" VScrollEnabled="True" MinHeight="50">
<BoxContainer Name="OptionsList" Access="Public" HorizontalExpand="True" SeparationOverride="2" Orientation="Vertical">
<!-- The rest here is generated programmatically -->
</BoxContainer>
</ScrollContainer>
</BoxContainer>
</DefaultWindow>
143 changes: 143 additions & 0 deletions Content.Client/_EinsteinEngine/Language/LanguageMenuWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using Content.Client._EinsteinEngine.Language.Systems;
using Content.Shared._EinsteinEngine.Language;
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._EinsteinEngine.Language;

[GenerateTypedNameReferences]
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 += UpdateState;
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

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

protected override void Opened()
{
UpdateState();
}

private void UpdateState()
{
var languageSpeaker = _clientLanguageSystem.GetLocalSpeaker();
if (languageSpeaker == null)
return;

UpdateState(languageSpeaker.CurrentLanguage, languageSpeaker.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));

OptionsList.RemoveAllChildren();
_entries.Clear();

foreach (var language in spokenLanguages)
{
AddLanguageEntry(language);
}

// Disable the button for the currently chosen language
foreach (var entry in _entries)
{
if (entry.Button != null)
entry.Button.Disabled = entry.Language == currentLanguage;
}
}

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

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

#region Header
var header = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Horizontal,
HorizontalExpand = true,
SeparationOverride = 2
};

var name = new Label
{
Text = proto?.Name ?? Loc.GetString("generic-error"),
MinWidth = 50,
HorizontalExpand = true
};

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

header.AddChild(name);
header.AddChild(button);

container.AddChild(header);
#endregion

#region Collapsible description
var body = new CollapsibleBody
{
HorizontalExpand = true,
Margin = new Thickness(4f, 4f)
};

var description = new RichTextLabel { HorizontalExpand = true };
description.SetMessage(proto?.Description ?? Loc.GetString("generic-error"));
body.AddChild(description);

var collapser = new Collapsible(Loc.GetString("language-menu-description-header"), body)
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
HorizontalExpand = true
};

container.AddChild(collapser);
#endregion

// Before adding, wrap the new container in a PanelContainer to give it a distinct look
var wrapper = new PanelContainer();
wrapper.StyleClasses.Add("PdaBorderRect");

wrapper.AddChild(container);
OptionsList.AddChild(wrapper);

_entries.Add(state);
}

private void OnLanguageChosen(ProtoId<LanguagePrototype> id)
{
_clientLanguageSystem.RequestSetLanguage(id);

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

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

namespace Content.Client._EinsteinEngine.Language.Systems;

public sealed class LanguageSystem : SharedLanguageSystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;

/// <summary>
/// Invoked when the languages of the local player entity change, for use in UI.
/// </summary>
public event Action? OnLanguagesChanged;

public override void Initialize()
{
_playerManager.LocalPlayerAttached += NotifyUpdate;
SubscribeLocalEvent<LanguageSpeakerComponent, ComponentHandleState>(OnHandleState);
}

private void OnHandleState(Entity<LanguageSpeakerComponent> ent, ref ComponentHandleState args)
{
if (args.Current is not LanguageSpeakerComponent.State state)
return;

ent.Comp.CurrentLanguage = state.CurrentLanguage;
ent.Comp.SpokenLanguages = state.SpokenLanguages;
ent.Comp.UnderstoodLanguages = state.UnderstoodLanguages;

if (ent.Owner == _playerManager.LocalEntity)
NotifyUpdate(ent);
}

/// <summary>
/// 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 LanguageSpeakerComponent? GetLocalSpeaker()
{
return CompOrNull<LanguageSpeakerComponent>(_playerManager.LocalEntity);
}

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

RaiseNetworkEvent(new LanguagesSetMessage(language));
}

private void NotifyUpdate(EntityUid localPlayer)
{
RaiseLocalEvent(localPlayer, new LanguagesUpdateEvent(), broadcast: true);
OnLanguagesChanged?.Invoke();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Content.Client._EinsteinEngine.Language;
using Content.Client.Gameplay;
using Content.Client.UserInterface.Controls;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Input.Binding;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BaseButton;

namespace Content.Client._EinsteinEngine.UserInterface.Systems.Language;

[UsedImplicitly]
public sealed class LanguageMenuUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>
{
public LanguageMenuWindow? LanguageWindow;
private MenuButton? LanguageButton => UIManager.GetActiveUIWidgetOrNull<Client.UserInterface.Systems.MenuBar.Widgets.GameTopMenuBar>()?.LanguageButton;

public void OnStateEntered(GameplayState state)
{
DebugTools.Assert(LanguageWindow == null);

LanguageWindow = UIManager.CreateWindow<LanguageMenuWindow>();
LayoutContainer.SetAnchorPreset(LanguageWindow, LayoutContainer.LayoutPreset.CenterTop);

LanguageWindow.OnClose += () =>
{
if (LanguageButton != null)
LanguageButton.Pressed = false;
};
LanguageWindow.OnOpen += () =>
{
if (LanguageButton != null)
LanguageButton.Pressed = true;
};

CommandBinds.Builder.Bind(ContentKeyFunctions.OpenLanguageMenu,
InputCmdHandler.FromDelegate(_ => ToggleWindow())).Register<LanguageMenuUIController>();
}

public void OnStateExited(GameplayState state)
{
if (LanguageWindow != null)
{
LanguageWindow.Dispose();
LanguageWindow = null;
}

CommandBinds.Unregister<LanguageMenuUIController>();
}

public void UnloadButton()
{
if (LanguageButton == null)
return;

LanguageButton.OnPressed -= LanguageButtonPressed;
}

public void LoadButton()
{
if (LanguageButton == null)
return;

LanguageButton.OnPressed += LanguageButtonPressed;
}

private void LanguageButtonPressed(ButtonEventArgs args)
{
ToggleWindow();
}

private void ToggleWindow()
{
if (LanguageWindow == null)
return;

if (LanguageButton != null)
LanguageButton.SetClickPressed(!LanguageWindow.IsOpen);

if (LanguageWindow.IsOpen)
LanguageWindow.Close();
else
LanguageWindow.Open();
}
}
3 changes: 2 additions & 1 deletion Content.Server/Administration/Commands/DSay.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Content.Server.Chat.Systems;
using Content.Shared.Administration;
using Content.Shared.Chat; // Corvax-Languages
using Robust.Shared.Console;

namespace Content.Server.Administration.Commands
Expand Down Expand Up @@ -34,7 +35,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
return;

var chat = _e.System<ChatSystem>();
chat.TrySendInGameOOCMessage(entity, message, InGameOOCChatType.Dead, false, shell, player);
chat.TrySendInGameOOCMessage(entity, message, SharedChatSystem.InGameOOCChatType.Dead, false, shell, player); // Corvax-Languages
}
}
}
Loading

0 comments on commit 4ad302d

Please sign in to comment.