Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Languages #13

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
AwareFoxy marked this conversation as resolved.
Show resolved Hide resolved
AwareFoxy marked this conversation as resolved.
Show resolved Hide resolved
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>
AwareFoxy marked this conversation as resolved.
Show resolved Hide resolved
AwareFoxy marked this conversation as resolved.
Show resolved Hide resolved
</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;
}
}
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