1
0

GuideReagentReaction.xaml.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using System.Linq;
  2. using Content.Client.Message;
  3. using Content.Client.UserInterface.ControlExtensions;
  4. using Content.Shared.Atmos.Prototypes;
  5. using Content.Shared.Chemistry.Components;
  6. using Content.Shared.Chemistry.Reaction;
  7. using Content.Shared.Chemistry.Reagent;
  8. using Content.Shared.FixedPoint;
  9. using Content.Shared.Localizations;
  10. using JetBrains.Annotations;
  11. using Robust.Client.AutoGenerated;
  12. using Robust.Client.GameObjects;
  13. using Robust.Client.UserInterface.Controls;
  14. using Robust.Client.UserInterface.XAML;
  15. using Robust.Shared.Graphics.RSI;
  16. using Robust.Shared.Prototypes;
  17. using Robust.Shared.Utility;
  18. namespace Content.Client.Guidebook.Controls;
  19. [UsedImplicitly, GenerateTypedNameReferences]
  20. public sealed partial class GuideReagentReaction : BoxContainer, ISearchableControl
  21. {
  22. [ValidatePrototypeId<MixingCategoryPrototype>]
  23. private const string DefaultMixingCategory = "DummyMix";
  24. private readonly IPrototypeManager _protoMan;
  25. public GuideReagentReaction(IPrototypeManager protoMan)
  26. {
  27. RobustXamlLoader.Load(this);
  28. _protoMan = protoMan;
  29. }
  30. public GuideReagentReaction(ReactionPrototype prototype, IPrototypeManager protoMan, IEntitySystemManager sysMan) : this(protoMan)
  31. {
  32. var reactantsLabel = ReactantsLabel;
  33. SetReagents(prototype.Reactants, ref reactantsLabel, protoMan);
  34. var productLabel = ProductsLabel;
  35. var products = new Dictionary<string, FixedPoint2>(prototype.Products);
  36. foreach (var (reagent, reactantProto) in prototype.Reactants)
  37. {
  38. if (reactantProto.Catalyst)
  39. products.Add(reagent, reactantProto.Amount);
  40. }
  41. SetReagents(products, ref productLabel, protoMan);
  42. var mixingCategories = new List<MixingCategoryPrototype>();
  43. if (prototype.MixingCategories != null)
  44. {
  45. foreach (var category in prototype.MixingCategories)
  46. {
  47. mixingCategories.Add(protoMan.Index(category));
  48. }
  49. }
  50. else
  51. {
  52. mixingCategories.Add(protoMan.Index<MixingCategoryPrototype>(DefaultMixingCategory));
  53. }
  54. SetMixingCategory(mixingCategories, prototype, sysMan);
  55. }
  56. public GuideReagentReaction(EntityPrototype prototype,
  57. Solution solution,
  58. IReadOnlyList<ProtoId<MixingCategoryPrototype>> categories,
  59. IPrototypeManager protoMan,
  60. IEntitySystemManager sysMan) : this(protoMan)
  61. {
  62. var icon = sysMan.GetEntitySystem<SpriteSystem>().GetPrototypeIcon(prototype).GetFrame(RsiDirection.South, 0);
  63. var entContainer = new BoxContainer
  64. {
  65. Orientation = LayoutOrientation.Horizontal,
  66. HorizontalExpand = true,
  67. HorizontalAlignment = HAlignment.Center,
  68. Children =
  69. {
  70. new TextureRect
  71. {
  72. Texture = icon
  73. }
  74. }
  75. };
  76. var nameLabel = new RichTextLabel();
  77. nameLabel.SetMarkup(Loc.GetString("guidebook-reagent-sources-ent-wrapper", ("name", prototype.Name)));
  78. entContainer.AddChild(nameLabel);
  79. ReactantsContainer.AddChild(entContainer);
  80. var productLabel = ProductsLabel;
  81. SetReagents(solution.Contents, ref productLabel, protoMan);
  82. SetMixingCategory(categories, null, sysMan);
  83. }
  84. public GuideReagentReaction(GasPrototype prototype,
  85. IReadOnlyList<ProtoId<MixingCategoryPrototype>> categories,
  86. IPrototypeManager protoMan,
  87. IEntitySystemManager sysMan) : this(protoMan)
  88. {
  89. ReactantsLabel.Visible = true;
  90. ReactantsLabel.SetMarkup(Loc.GetString("guidebook-reagent-sources-gas-wrapper",
  91. ("name", Loc.GetString(prototype.Name).ToLower())));
  92. if (prototype.Reagent != null)
  93. {
  94. var quantity = new Dictionary<string, FixedPoint2>
  95. {
  96. { prototype.Reagent, FixedPoint2.New(0.21f) }
  97. };
  98. var productLabel = ProductsLabel;
  99. SetReagents(quantity, ref productLabel, protoMan);
  100. }
  101. SetMixingCategory(categories, null, sysMan);
  102. }
  103. private void SetReagents(List<ReagentQuantity> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
  104. {
  105. var amounts = new Dictionary<string, FixedPoint2>();
  106. foreach (var (reagent, quantity) in reagents)
  107. {
  108. amounts.Add(reagent.Prototype, quantity);
  109. }
  110. SetReagents(amounts, ref label, protoMan);
  111. }
  112. private void SetReagents(
  113. Dictionary<string, ReactantPrototype> reactants,
  114. ref RichTextLabel label,
  115. IPrototypeManager protoMan)
  116. {
  117. var amounts = new Dictionary<string, FixedPoint2>();
  118. foreach (var (reagent, reactantPrototype) in reactants)
  119. {
  120. amounts.Add(reagent, reactantPrototype.Amount);
  121. }
  122. SetReagents(amounts, ref label, protoMan);
  123. }
  124. [PublicAPI]
  125. private void SetReagents(
  126. Dictionary<ProtoId<MixingCategoryPrototype>, ReactantPrototype> reactants,
  127. ref RichTextLabel label,
  128. IPrototypeManager protoMan)
  129. {
  130. var amounts = new Dictionary<string, FixedPoint2>();
  131. foreach (var (reagent, reactantPrototype) in reactants)
  132. {
  133. amounts.Add(reagent, reactantPrototype.Amount);
  134. }
  135. SetReagents(amounts, ref label, protoMan);
  136. }
  137. private void SetReagents(Dictionary<string, FixedPoint2> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
  138. {
  139. var msg = new FormattedMessage();
  140. var reagentCount = reagents.Count;
  141. var i = 0;
  142. foreach (var (product, amount) in reagents.OrderByDescending(p => p.Value))
  143. {
  144. msg.AddMarkupOrThrow(Loc.GetString("guidebook-reagent-recipes-reagent-display",
  145. ("reagent", protoMan.Index<ReagentPrototype>(product).LocalizedName), ("ratio", amount)));
  146. i++;
  147. if (i < reagentCount)
  148. msg.PushNewline();
  149. }
  150. msg.Pop();
  151. label.SetMessage(msg);
  152. label.Visible = true;
  153. }
  154. private void SetMixingCategory(IReadOnlyList<ProtoId<MixingCategoryPrototype>> mixingCategories, ReactionPrototype? prototype, IEntitySystemManager sysMan)
  155. {
  156. var foo = new List<MixingCategoryPrototype>();
  157. foreach (var cat in mixingCategories)
  158. {
  159. foo.Add(_protoMan.Index(cat));
  160. }
  161. SetMixingCategory(foo, prototype, sysMan);
  162. }
  163. private void SetMixingCategory(IReadOnlyList<MixingCategoryPrototype> mixingCategories, ReactionPrototype? prototype, IEntitySystemManager sysMan)
  164. {
  165. if (mixingCategories.Count == 0)
  166. return;
  167. // only use the first one for the icon.
  168. if (mixingCategories.First() is { } primaryCategory)
  169. {
  170. MixTexture.Texture = sysMan.GetEntitySystem<SpriteSystem>().Frame0(primaryCategory.Icon);
  171. }
  172. var mixingVerb = ContentLocalizationManager.FormatList(mixingCategories
  173. .Select(p => Loc.GetString(p.VerbText)).ToList());
  174. var minTemp = prototype?.MinimumTemperature ?? 0;
  175. var maxTemp = prototype?.MaximumTemperature ?? float.PositiveInfinity;
  176. var text = Loc.GetString("guidebook-reagent-recipes-mix-info",
  177. ("verb", mixingVerb),
  178. ("minTemp", minTemp),
  179. ("maxTemp", maxTemp),
  180. ("hasMax", !float.IsPositiveInfinity(maxTemp)));
  181. MixLabel.SetMarkup(text);
  182. }
  183. public bool CheckMatchesSearch(string query)
  184. {
  185. return this.ChildrenContainText(query);
  186. }
  187. public void SetHiddenState(bool state, string query)
  188. {
  189. Visible = CheckMatchesSearch(query) ? state : !state;
  190. }
  191. }