Skip to content

Commit

Permalink
Merge pull request #254 from Evgencheg/upstream
Browse files Browse the repository at this point in the history
Upstream
  • Loading branch information
Evgencheg authored Oct 9, 2024
2 parents 7067a3b + 7eb999c commit ec2afb0
Show file tree
Hide file tree
Showing 155 changed files with 136,594 additions and 602 deletions.
3 changes: 2 additions & 1 deletion Content.Client/Corvax/TTS/TTSSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Content.Shared.Administration;
using Content.Shared.Ghost;
using System.Linq;
using Content.Shared.Language.Components;
using JetBrains.Annotations;


Expand Down Expand Up @@ -96,7 +97,7 @@ private void OnPlayTTS(PlayTTSEvent ev)
{
var isadmin = _adminMgr.HasFlag(AdminFlags.Admin) && _entities.TryGetComponent<GhostComponent>(player, out var ghostcomp);

if ((_language.UnderstoodLanguages.Contains(ev.LanguageProtoId) || isadmin) && ev.LanguageProtoId != "Sign")
if (((_entities.TryGetComponent<LanguageSpeakerComponent>(player, out var langcomp) && langcomp.UnderstoodLanguages.Contains(ev.LanguageProtoId)) || isadmin) && ev.LanguageProtoId != "Sign")
_contentRoot.AddOrUpdateFile(filePath, ev.Data);
else
return; //временно отключена озвучка языков
Expand Down
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 = "Выбрать" };
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();
}
}
6 changes: 6 additions & 0 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,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
30 changes: 30 additions & 0 deletions Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public sealed partial class HumanoidProfileEditor : BoxContainer

private LineEdit _ageEdit => CAgeEdit;
private LineEdit _nameEdit => CNameEdit;

private BoxContainer _ccustomspecienamecontainerEdit => CCustomSpecieName;
private LineEdit _customspecienameEdit => CCustomSpecieNameEdit;
private TextEdit? _flavorTextEdit;
private Button _nameRandomButton => CNameRandomize;
private Button _randomizeEverythingButton => CRandomizeEverything;
Expand Down Expand Up @@ -141,6 +144,12 @@ public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IProt

#endregion Name

#region Custom Specie Name

_customspecienameEdit.OnTextChanged += args => { SetCustomSpecieName(args.Text); };

#endregion CustomSpecieName

#region Appearance

CAppearance.Orphan();
Expand Down Expand Up @@ -208,6 +217,7 @@ public HumanoidProfileEditor(IClientPreferencesManager preferencesManager, IProt
SetSpecies(_speciesList[args.Id].ID);
UpdateHairPickers();
OnSkinColorOnValueChanged();
UpdateCustomSpecieNameEdit();
};

#endregion Species
Expand Down Expand Up @@ -1041,6 +1051,12 @@ private void SetName(string newName)
IsDirty = true;
}

private void SetCustomSpecieName(string customname)
{
Profile = Profile?.WithCustomSpeciesName(customname);
IsDirty = true;
}

private void SetSpawnPriority(SpawnPriorityPreference newSpawnPriority)
{
Profile = Profile?.WithSpawnPriorityPreference(newSpawnPriority);
Expand Down Expand Up @@ -1087,6 +1103,19 @@ private void UpdateNameEdit()
_nameEdit.Text = Profile?.Name ?? "";
}

private void UpdateCustomSpecieNameEdit()
{
if (Profile == null)
return;

_customspecienameEdit.Text = Profile.Customspeciename ?? "";

if (!_prototypeManager.TryIndex<SpeciesPrototype>(Profile.Species, out var speciesProto))
return;

_ccustomspecienamecontainerEdit.Visible = speciesProto.CustomName;
}

private void UpdateFlavorTextEdit()
{
if(_flavorTextEdit != null)
Expand Down Expand Up @@ -1371,6 +1400,7 @@ public void UpdateControls()
return;

UpdateNameEdit();
UpdateCustomSpecieNameEdit();
UpdateFlavorTextEdit();
UpdateSexControls();
UpdateGenderControls();
Expand Down
19 changes: 8 additions & 11 deletions Content.Client/Standing/LayingDownSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public override void Initialize()

SubscribeLocalEvent<LayingDownComponent, MoveEvent>(OnMovementInput);
SubscribeNetworkEvent<DrawDownedEvent>(OnDowned);
SubscribeLocalEvent<LayingDownComponent, StoodEvent>(OnStood);
SubscribeNetworkEvent<DrawStoodEvent>(OnStood);

SubscribeNetworkEvent<CheckAutoGetUpEvent>(OnCheckAutoGetUp);
}
Expand Down Expand Up @@ -54,24 +54,21 @@ private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveE
private void OnDowned(DrawDownedEvent args)
{
var uid = GetEntity(args.Uid);

if (!TryComp<SpriteComponent>(uid, out var sprite)
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !TryComp<LayingDownComponent>(uid, out var component))
return;

if (!component.OriginalDrawDepth.HasValue)
component.OriginalDrawDepth = sprite.DrawDepth;

sprite.DrawDepth = (int) DrawDepth.SmallMobs;
sprite.DrawDepth = component.CrawlingDrawDepth;
}

private void OnStood(EntityUid uid, LayingDownComponent component, StoodEvent args)
private void OnStood(DrawStoodEvent args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !component.OriginalDrawDepth.HasValue)
var uid = GetEntity(args.Uid);
if (!TryComp<SpriteComponent>(uid, out var sprite)
|| !TryComp<LayingDownComponent>(uid, out var component))
return;

sprite.DrawDepth = component.OriginalDrawDepth.Value;
sprite.DrawDepth = component.NormalDrawDepth;
}

private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args)
Expand Down
3 changes: 2 additions & 1 deletion Content.IntegrationTests/Tests/PostMapInitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public sealed class PostMapInitTest
"LPPAsterisk", //LPP
"LPPNormandy", //LPP
"LPPPebble", //LPP
"LPPSubmarine" //LPP
"LPPSubmarine", //LPP
"Gax"
};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ private static HumanoidCharacterProfile CharlieCharlieson()
"The biggest boy around.",
"Human",
"Eugene", // LPP-TTS
"",
1,
1,
21,
Expand Down
Loading

0 comments on commit ec2afb0

Please sign in to comment.