EmotesMenu.xaml.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System.Numerics;
  2. using Content.Client.UserInterface.Controls;
  3. using Content.Shared.Chat.Prototypes;
  4. using Content.Shared.Speech;
  5. using Content.Shared.Whitelist;
  6. using Robust.Client.AutoGenerated;
  7. using Robust.Client.GameObjects;
  8. using Robust.Client.UserInterface.Controls;
  9. using Robust.Client.UserInterface.XAML;
  10. using Robust.Shared.Player;
  11. using Robust.Shared.Prototypes;
  12. namespace Content.Client.Chat.UI;
  13. [GenerateTypedNameReferences]
  14. public sealed partial class EmotesMenu : RadialMenu
  15. {
  16. [Dependency] private readonly EntityManager _entManager = default!;
  17. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  18. [Dependency] private readonly ISharedPlayerManager _playerManager = default!;
  19. public event Action<ProtoId<EmotePrototype>>? OnPlayEmote;
  20. public EmotesMenu()
  21. {
  22. IoCManager.InjectDependencies(this);
  23. RobustXamlLoader.Load(this);
  24. var spriteSystem = _entManager.System<SpriteSystem>();
  25. var whitelistSystem = _entManager.System<EntityWhitelistSystem>();
  26. var main = FindControl<RadialContainer>("Main");
  27. var emotes = _prototypeManager.EnumeratePrototypes<EmotePrototype>();
  28. foreach (var emote in emotes)
  29. {
  30. var player = _playerManager.LocalSession?.AttachedEntity;
  31. if (emote.Category == EmoteCategory.Invalid ||
  32. emote.ChatTriggers.Count == 0 ||
  33. !(player.HasValue && whitelistSystem.IsWhitelistPassOrNull(emote.Whitelist, player.Value)) ||
  34. whitelistSystem.IsBlacklistPass(emote.Blacklist, player.Value))
  35. continue;
  36. if (!emote.Available &&
  37. _entManager.TryGetComponent<SpeechComponent>(player.Value, out var speech) &&
  38. !speech.AllowedEmotes.Contains(emote.ID))
  39. continue;
  40. var parent = FindControl<RadialContainer>(emote.Category.ToString());
  41. var button = new EmoteMenuButton
  42. {
  43. SetSize = new Vector2(64f, 64f),
  44. ToolTip = Loc.GetString(emote.Name),
  45. ProtoId = emote.ID,
  46. };
  47. var tex = new TextureRect
  48. {
  49. VerticalAlignment = VAlignment.Center,
  50. HorizontalAlignment = HAlignment.Center,
  51. Texture = spriteSystem.Frame0(emote.Icon),
  52. TextureScale = new Vector2(2f, 2f),
  53. };
  54. button.AddChild(tex);
  55. parent.AddChild(button);
  56. foreach (var child in main.Children)
  57. {
  58. if (child is not RadialMenuTextureButton castChild)
  59. continue;
  60. if (castChild.TargetLayer == emote.Category.ToString())
  61. {
  62. castChild.Visible = true;
  63. break;
  64. }
  65. }
  66. }
  67. // Set up menu actions
  68. foreach (var child in Children)
  69. {
  70. if (child is not RadialContainer container)
  71. continue;
  72. AddEmoteClickAction(container);
  73. }
  74. }
  75. private void AddEmoteClickAction(RadialContainer container)
  76. {
  77. foreach (var child in container.Children)
  78. {
  79. if (child is not EmoteMenuButton castChild)
  80. continue;
  81. castChild.OnButtonUp += _ =>
  82. {
  83. OnPlayEmote?.Invoke(castChild.ProtoId);
  84. Close();
  85. };
  86. }
  87. }
  88. }
  89. public sealed class EmoteMenuButton : RadialMenuTextureButtonWithSector
  90. {
  91. public ProtoId<EmotePrototype> ProtoId { get; set; }
  92. }