SharedMagicMirrorSystem.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. using Content.Shared.DoAfter;
  2. using Content.Shared.Humanoid;
  3. using Content.Shared.Humanoid.Markings;
  4. using Content.Shared.Interaction;
  5. using Content.Shared.UserInterface;
  6. using Robust.Shared.Serialization;
  7. namespace Content.Shared.MagicMirror;
  8. public abstract class SharedMagicMirrorSystem : EntitySystem
  9. {
  10. [Dependency] private readonly SharedInteractionSystem _interaction = default!;
  11. [Dependency] protected readonly SharedUserInterfaceSystem UISystem = default!;
  12. public override void Initialize()
  13. {
  14. base.Initialize();
  15. SubscribeLocalEvent<MagicMirrorComponent, AfterInteractEvent>(OnMagicMirrorInteract);
  16. SubscribeLocalEvent<MagicMirrorComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
  17. SubscribeLocalEvent<MagicMirrorComponent, ActivatableUIOpenAttemptEvent>(OnAttemptOpenUI);
  18. SubscribeLocalEvent<MagicMirrorComponent, BoundUserInterfaceCheckRangeEvent>(OnMirrorRangeCheck);
  19. }
  20. private void OnMagicMirrorInteract(Entity<MagicMirrorComponent> mirror, ref AfterInteractEvent args)
  21. {
  22. if (!args.CanReach || args.Target == null)
  23. return;
  24. UpdateInterface(mirror, args.Target.Value, mirror);
  25. UISystem.TryOpenUi(mirror.Owner, MagicMirrorUiKey.Key, args.User);
  26. }
  27. private void OnMirrorRangeCheck(EntityUid uid, MagicMirrorComponent component, ref BoundUserInterfaceCheckRangeEvent args)
  28. {
  29. if (args.Result == BoundUserInterfaceRangeResult.Fail)
  30. return;
  31. if (component.Target == null || !Exists(component.Target))
  32. {
  33. component.Target = null;
  34. args.Result = BoundUserInterfaceRangeResult.Fail;
  35. return;
  36. }
  37. if (!_interaction.InRangeUnobstructed(component.Target.Value, uid))
  38. args.Result = BoundUserInterfaceRangeResult.Fail;
  39. }
  40. private void OnAttemptOpenUI(EntityUid uid, MagicMirrorComponent component, ref ActivatableUIOpenAttemptEvent args)
  41. {
  42. var user = component.Target ?? args.User;
  43. if (!HasComp<HumanoidAppearanceComponent>(user))
  44. args.Cancel();
  45. }
  46. private void OnBeforeUIOpen(Entity<MagicMirrorComponent> ent, ref BeforeActivatableUIOpenEvent args)
  47. {
  48. UpdateInterface(ent, args.User, ent);
  49. }
  50. protected void UpdateInterface(EntityUid mirrorUid, EntityUid targetUid, MagicMirrorComponent component)
  51. {
  52. if (!TryComp<HumanoidAppearanceComponent>(targetUid, out var humanoid))
  53. return;
  54. component.Target ??= targetUid;
  55. var hair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.Hair, out var hairMarkings)
  56. ? new List<Marking>(hairMarkings)
  57. : new();
  58. var facialHair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.FacialHair, out var facialHairMarkings)
  59. ? new List<Marking>(facialHairMarkings)
  60. : new();
  61. var state = new MagicMirrorUiState(
  62. humanoid.Species,
  63. hair,
  64. humanoid.MarkingSet.PointsLeft(MarkingCategories.Hair) + hair.Count,
  65. facialHair,
  66. humanoid.MarkingSet.PointsLeft(MarkingCategories.FacialHair) + facialHair.Count);
  67. // TODO: Component states
  68. component.Target = targetUid;
  69. UISystem.SetUiState(mirrorUid, MagicMirrorUiKey.Key, state);
  70. Dirty(mirrorUid, component);
  71. }
  72. }
  73. [Serializable, NetSerializable]
  74. public enum MagicMirrorUiKey : byte
  75. {
  76. Key
  77. }
  78. [Serializable, NetSerializable]
  79. public enum MagicMirrorCategory : byte
  80. {
  81. Hair,
  82. FacialHair
  83. }
  84. [Serializable, NetSerializable]
  85. public sealed class MagicMirrorSelectMessage : BoundUserInterfaceMessage
  86. {
  87. public MagicMirrorSelectMessage(MagicMirrorCategory category, string marking, int slot)
  88. {
  89. Category = category;
  90. Marking = marking;
  91. Slot = slot;
  92. }
  93. public MagicMirrorCategory Category { get; }
  94. public string Marking { get; }
  95. public int Slot { get; }
  96. }
  97. [Serializable, NetSerializable]
  98. public sealed class MagicMirrorChangeColorMessage : BoundUserInterfaceMessage
  99. {
  100. public MagicMirrorChangeColorMessage(MagicMirrorCategory category, List<Color> colors, int slot)
  101. {
  102. Category = category;
  103. Colors = colors;
  104. Slot = slot;
  105. }
  106. public MagicMirrorCategory Category { get; }
  107. public List<Color> Colors { get; }
  108. public int Slot { get; }
  109. }
  110. [Serializable, NetSerializable]
  111. public sealed class MagicMirrorRemoveSlotMessage : BoundUserInterfaceMessage
  112. {
  113. public MagicMirrorRemoveSlotMessage(MagicMirrorCategory category, int slot)
  114. {
  115. Category = category;
  116. Slot = slot;
  117. }
  118. public MagicMirrorCategory Category { get; }
  119. public int Slot { get; }
  120. }
  121. [Serializable, NetSerializable]
  122. public sealed class MagicMirrorSelectSlotMessage : BoundUserInterfaceMessage
  123. {
  124. public MagicMirrorSelectSlotMessage(MagicMirrorCategory category, int slot)
  125. {
  126. Category = category;
  127. Slot = slot;
  128. }
  129. public MagicMirrorCategory Category { get; }
  130. public int Slot { get; }
  131. }
  132. [Serializable, NetSerializable]
  133. public sealed class MagicMirrorAddSlotMessage : BoundUserInterfaceMessage
  134. {
  135. public MagicMirrorAddSlotMessage(MagicMirrorCategory category)
  136. {
  137. Category = category;
  138. }
  139. public MagicMirrorCategory Category { get; }
  140. }
  141. [Serializable, NetSerializable]
  142. public sealed class MagicMirrorUiState : BoundUserInterfaceState
  143. {
  144. public MagicMirrorUiState(string species, List<Marking> hair, int hairSlotTotal, List<Marking> facialHair, int facialHairSlotTotal)
  145. {
  146. Species = species;
  147. Hair = hair;
  148. HairSlotTotal = hairSlotTotal;
  149. FacialHair = facialHair;
  150. FacialHairSlotTotal = facialHairSlotTotal;
  151. }
  152. public NetEntity Target;
  153. public string Species;
  154. public List<Marking> Hair;
  155. public int HairSlotTotal;
  156. public List<Marking> FacialHair;
  157. public int FacialHairSlotTotal;
  158. }
  159. [Serializable, NetSerializable]
  160. public sealed partial class MagicMirrorRemoveSlotDoAfterEvent : DoAfterEvent
  161. {
  162. public override DoAfterEvent Clone() => this;
  163. public MagicMirrorCategory Category;
  164. public int Slot;
  165. }
  166. [Serializable, NetSerializable]
  167. public sealed partial class MagicMirrorAddSlotDoAfterEvent : DoAfterEvent
  168. {
  169. public override DoAfterEvent Clone() => this;
  170. public MagicMirrorCategory Category;
  171. }
  172. [Serializable, NetSerializable]
  173. public sealed partial class MagicMirrorSelectDoAfterEvent : DoAfterEvent
  174. {
  175. public MagicMirrorCategory Category;
  176. public int Slot;
  177. public string Marking = string.Empty;
  178. public override DoAfterEvent Clone() => this;
  179. }
  180. [Serializable, NetSerializable]
  181. public sealed partial class MagicMirrorChangeColorDoAfterEvent : DoAfterEvent
  182. {
  183. public override DoAfterEvent Clone() => this;
  184. public MagicMirrorCategory Category;
  185. public int Slot;
  186. public List<Color> Colors = new List<Color>();
  187. }