mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-17 13:37:47 +03:00
# Description This significantly improves the quality of the language system by fixing the mistakes I've made almost a year ago while developing it. Mainly, this throws away the old half-broken way of networking in favor of the component state system provided by RT. Language speaker comp is now shared with SendOnlyToOwner = true, and its state is handled manually. In addition to that, this brings the following changes: - UniversalLanguageSpeaker and LanguageKnowledge are now server-side - DetermineLanguagesEvent and LanguagesUpdateEvent are now shared (so that future systems can be built in shared, if needed) - Everything now uses the ProtoId<LanguagePrototype> type instead of raw strings (god, I hated those so much) - The server-side language system now accepts Entity<T?> arguments instead of EntityUid + T - UniversalLanguageSpeaker is now based on DetermineEntityLanguagesEvent and gets an Enabled field, which allows to turn it off. This may have some use in the future. - Some minor cleanup <!-- TODO MEDIA <details><summary><h1>Media</h1></summary> <p>  </p> </details> --> # Changelog No cl --------- Co-authored-by: VMSolidus <evilexecutive@gmail.com>
62 lines
2.0 KiB
C#
62 lines
2.0 KiB
C#
using Content.Shared.Language;
|
|
using Content.Shared.Language.Components;
|
|
using Content.Shared.Language.Events;
|
|
using Content.Shared.Language.Systems;
|
|
using Robust.Client.Player;
|
|
using Robust.Shared.GameStates;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Client.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();
|
|
}
|
|
}
|