Add reagent sources to the guidebook (#22627)
* source in my guidebook * finish it! * sir yes sir oorah * network that bitch, baby
This commit is contained in:
@@ -17,12 +17,25 @@
|
||||
<GridContainer Name="RecipesDescriptionContainer"
|
||||
Margin="10 0 10 0"
|
||||
Columns="1"
|
||||
HSeparationOverride="5"
|
||||
HSeparationOverride="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalExpand="True"/>
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="SourcesContainer" HorizontalExpand="True">
|
||||
<Collapsible Orientation="Vertical" HorizontalExpand="True">
|
||||
<CollapsibleHeading Title="{Loc 'guidebook-reagent-sources-header'}"/>
|
||||
<CollapsibleBody>
|
||||
<GridContainer Name="SourcesDescriptionContainer"
|
||||
Margin="10 0 10 0"
|
||||
Columns="1"
|
||||
HSeparationOverride="5"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalExpand="True"/>
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="EffectsContainer" HorizontalExpand="True">
|
||||
<Collapsible Orientation="Vertical">
|
||||
<CollapsibleHeading Title="{Loc 'guidebook-reagent-effects-header'}"/>
|
||||
|
||||
@@ -6,10 +6,8 @@ using Content.Client.Message;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Localizations;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
@@ -99,7 +97,7 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
|
||||
#region Recipe
|
||||
var reactions = _prototype.EnumeratePrototypes<ReactionPrototype>()
|
||||
.Where(p => p.Products.ContainsKey(reagent.ID))
|
||||
.Where(p => !p.Source && p.Products.ContainsKey(reagent.ID))
|
||||
.OrderBy(p => p.Priority)
|
||||
.ThenBy(p => p.Products.Count)
|
||||
.ToList();
|
||||
@@ -108,8 +106,7 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
{
|
||||
foreach (var reactionPrototype in reactions)
|
||||
{
|
||||
var ctrl = GetRecipeGuide(reactionPrototype);
|
||||
RecipesDescriptionContainer.AddChild(ctrl);
|
||||
RecipesDescriptionContainer.AddChild(new GuideReagentReaction(reactionPrototype, _prototype, _systemManager));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -159,6 +156,8 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
}
|
||||
#endregion
|
||||
|
||||
GenerateSources(reagent);
|
||||
|
||||
FormattedMessage description = new();
|
||||
description.AddText(reagent.LocalizedDescription);
|
||||
description.PushNewline();
|
||||
@@ -167,64 +166,45 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
ReagentDescription.SetMessage(description);
|
||||
}
|
||||
|
||||
private GuideReagentReaction GetRecipeGuide(ReactionPrototype reactionPrototype)
|
||||
private void GenerateSources(ReagentPrototype reagent)
|
||||
{
|
||||
var control = new GuideReagentReaction();
|
||||
|
||||
var reactantMsg = new FormattedMessage();
|
||||
var reactantsCount = reactionPrototype.Reactants.Count;
|
||||
var i = 0;
|
||||
foreach (var (product, reactant) in reactionPrototype.Reactants)
|
||||
var sources = _chemistryGuideData.GetReagentSources(reagent.ID);
|
||||
if (sources.Count == 0)
|
||||
{
|
||||
reactantMsg.AddMarkup(Loc.GetString("guidebook-reagent-recipes-reagent-display",
|
||||
("reagent", _prototype.Index<ReagentPrototype>(product).LocalizedName), ("ratio", reactant.Amount)));
|
||||
i++;
|
||||
if (i < reactantsCount)
|
||||
reactantMsg.PushNewline();
|
||||
SourcesContainer.Visible = false;
|
||||
return;
|
||||
}
|
||||
reactantMsg.Pop();
|
||||
control.ReactantsLabel.SetMessage(reactantMsg);
|
||||
SourcesContainer.Visible = true;
|
||||
|
||||
var productMsg = new FormattedMessage();
|
||||
var productCount = reactionPrototype.Products.Count;
|
||||
var u = 0;
|
||||
foreach (var (product, ratio) in reactionPrototype.Products)
|
||||
var orderedSources = sources
|
||||
.OrderBy(o => o.OutputCount)
|
||||
.ThenBy(o => o.IdentifierString);
|
||||
foreach (var source in orderedSources)
|
||||
{
|
||||
productMsg.AddMarkup(Loc.GetString("guidebook-reagent-recipes-reagent-display",
|
||||
("reagent", _prototype.Index<ReagentPrototype>(product).LocalizedName), ("ratio", ratio)));
|
||||
u++;
|
||||
if (u < productCount)
|
||||
productMsg.PushNewline();
|
||||
}
|
||||
productMsg.Pop();
|
||||
control.ProductsLabel.SetMessage(productMsg);
|
||||
|
||||
var mixingCategories = new List<MixingCategoryPrototype>();
|
||||
if (reactionPrototype.MixingCategories != null)
|
||||
{
|
||||
foreach (var category in reactionPrototype.MixingCategories)
|
||||
if (source is ReagentEntitySourceData entitySourceData)
|
||||
{
|
||||
mixingCategories.Add(_prototype.Index(category));
|
||||
SourcesDescriptionContainer.AddChild(new GuideReagentReaction(
|
||||
entitySourceData.SourceEntProto,
|
||||
entitySourceData.Solution,
|
||||
entitySourceData.MixingType,
|
||||
_prototype,
|
||||
_systemManager));
|
||||
}
|
||||
else if (source is ReagentReactionSourceData reactionSourceData)
|
||||
{
|
||||
SourcesDescriptionContainer.AddChild(new GuideReagentReaction(
|
||||
reactionSourceData.ReactionPrototype,
|
||||
_prototype,
|
||||
_systemManager));
|
||||
}
|
||||
else if (source is ReagentGasSourceData gasSourceData)
|
||||
{
|
||||
SourcesDescriptionContainer.AddChild(new GuideReagentReaction(
|
||||
gasSourceData.GasPrototype,
|
||||
gasSourceData.MixingType,
|
||||
_prototype,
|
||||
_systemManager));
|
||||
}
|
||||
}
|
||||
|
||||
// only use the first one for the icon.
|
||||
if (mixingCategories.FirstOrDefault() is { } primaryCategory)
|
||||
{
|
||||
control.MixTexture.Texture = _systemManager.GetEntitySystem<SpriteSystem>().Frame0(primaryCategory.Icon);
|
||||
}
|
||||
|
||||
var mixingVerb = mixingCategories.Count == 0
|
||||
? Loc.GetString("guidebook-reagent-recipes-mix")
|
||||
: ContentLocalizationManager.FormatList(mixingCategories.Select(p => Loc.GetString(p.VerbText)).ToList());
|
||||
|
||||
var text = Loc.GetString("guidebook-reagent-recipes-mix-info",
|
||||
("verb", mixingVerb),
|
||||
("minTemp", reactionPrototype.MinimumTemperature),
|
||||
("maxTemp", reactionPrototype.MaximumTemperature),
|
||||
("hasMax", !float.IsPositiveInfinity(reactionPrototype.MaximumTemperature)));
|
||||
|
||||
control.MixLabel.SetMarkup(text);
|
||||
return control;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<BoxContainer xmlns="https://spacestation14.io"
|
||||
Orientation="Horizontal"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Center">
|
||||
HorizontalExpand="True"
|
||||
Margin="0 0 0 5">
|
||||
<BoxContainer Name="ReactantsContainer" Orientation="Vertical" HorizontalExpand="True" VerticalAlignment="Center">
|
||||
<RichTextLabel Name="ReactantsLabel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Access="Public"/>
|
||||
Access="Public"
|
||||
Visible="False"/>
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextureRect TexturePath="/Textures/Interface/Misc/beakerlarge.png"
|
||||
@@ -22,6 +24,7 @@
|
||||
<RichTextLabel Name="ProductsLabel"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Access="Public"/>
|
||||
Access="Public"
|
||||
Visible="False"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -1,13 +1,206 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Message;
|
||||
using Content.Client.UserInterface.ControlExtensions;
|
||||
using Content.Shared.Atmos.Prototypes;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Localizations;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Graphics.RSI;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Guidebook.Controls;
|
||||
|
||||
[UsedImplicitly, GenerateTypedNameReferences]
|
||||
public sealed partial class GuideReagentReaction : BoxContainer, ISearchableControl
|
||||
{
|
||||
[ValidatePrototypeId<MixingCategoryPrototype>]
|
||||
private const string DefaultMixingCategory = "DummyMix";
|
||||
|
||||
private readonly IPrototypeManager _protoMan;
|
||||
|
||||
public GuideReagentReaction(IPrototypeManager protoMan)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_protoMan = protoMan;
|
||||
}
|
||||
|
||||
public GuideReagentReaction(ReactionPrototype prototype, IPrototypeManager protoMan, IEntitySystemManager sysMan) : this(protoMan)
|
||||
{
|
||||
var reactantsLabel = ReactantsLabel;
|
||||
SetReagents(prototype.Reactants, ref reactantsLabel, protoMan);
|
||||
var productLabel = ProductsLabel;
|
||||
var products = new Dictionary<string, FixedPoint2>(prototype.Products);
|
||||
foreach (var (reagent, reactantProto) in prototype.Reactants)
|
||||
{
|
||||
if (reactantProto.Catalyst)
|
||||
products.Add(reagent, reactantProto.Amount);
|
||||
}
|
||||
SetReagents(products, ref productLabel, protoMan);
|
||||
|
||||
var mixingCategories = new List<MixingCategoryPrototype>();
|
||||
if (prototype.MixingCategories != null)
|
||||
{
|
||||
foreach (var category in prototype.MixingCategories)
|
||||
{
|
||||
mixingCategories.Add(protoMan.Index(category));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mixingCategories.Add(protoMan.Index<MixingCategoryPrototype>(DefaultMixingCategory));
|
||||
}
|
||||
SetMixingCategory(mixingCategories, prototype, sysMan);
|
||||
}
|
||||
|
||||
public GuideReagentReaction(EntityPrototype prototype,
|
||||
Solution solution,
|
||||
IReadOnlyList<ProtoId<MixingCategoryPrototype>> categories,
|
||||
IPrototypeManager protoMan,
|
||||
IEntitySystemManager sysMan) : this(protoMan)
|
||||
{
|
||||
var icon = sysMan.GetEntitySystem<SpriteSystem>().GetPrototypeIcon(prototype).GetFrame(RsiDirection.South, 0);
|
||||
var entContainer = new BoxContainer
|
||||
{
|
||||
Orientation = LayoutOrientation.Horizontal,
|
||||
HorizontalExpand = true,
|
||||
HorizontalAlignment = HAlignment.Center,
|
||||
Children =
|
||||
{
|
||||
new TextureRect
|
||||
{
|
||||
Texture = icon
|
||||
}
|
||||
}
|
||||
};
|
||||
var nameLabel = new RichTextLabel();
|
||||
nameLabel.SetMarkup(Loc.GetString("guidebook-reagent-sources-ent-wrapper", ("name", prototype.Name)));
|
||||
entContainer.AddChild(nameLabel);
|
||||
ReactantsContainer.AddChild(entContainer);
|
||||
|
||||
var productLabel = ProductsLabel;
|
||||
SetReagents(solution.Contents, ref productLabel, protoMan);
|
||||
SetMixingCategory(categories, null, sysMan);
|
||||
}
|
||||
|
||||
public GuideReagentReaction(GasPrototype prototype,
|
||||
IReadOnlyList<ProtoId<MixingCategoryPrototype>> categories,
|
||||
IPrototypeManager protoMan,
|
||||
IEntitySystemManager sysMan) : this(protoMan)
|
||||
{
|
||||
ReactantsLabel.Visible = true;
|
||||
ReactantsLabel.SetMarkup(Loc.GetString("guidebook-reagent-sources-gas-wrapper",
|
||||
("name", Loc.GetString(prototype.Name).ToLower())));
|
||||
|
||||
if (prototype.Reagent != null)
|
||||
{
|
||||
var quantity = new Dictionary<string, FixedPoint2>
|
||||
{
|
||||
{ prototype.Reagent, FixedPoint2.New(0.21f) }
|
||||
};
|
||||
var productLabel = ProductsLabel;
|
||||
SetReagents(quantity, ref productLabel, protoMan);
|
||||
}
|
||||
SetMixingCategory(categories, null, sysMan);
|
||||
}
|
||||
|
||||
private void SetReagents(List<ReagentQuantity> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, quantity) in reagents)
|
||||
{
|
||||
amounts.Add(reagent.Prototype, quantity);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
}
|
||||
|
||||
private void SetReagents(
|
||||
Dictionary<string, ReactantPrototype> reactants,
|
||||
ref RichTextLabel label,
|
||||
IPrototypeManager protoMan)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, reactantPrototype) in reactants)
|
||||
{
|
||||
amounts.Add(reagent, reactantPrototype.Amount);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
private void SetReagents(
|
||||
Dictionary<ProtoId<MixingCategoryPrototype>, ReactantPrototype> reactants,
|
||||
ref RichTextLabel label,
|
||||
IPrototypeManager protoMan)
|
||||
{
|
||||
var amounts = new Dictionary<string, FixedPoint2>();
|
||||
foreach (var (reagent, reactantPrototype) in reactants)
|
||||
{
|
||||
amounts.Add(reagent, reactantPrototype.Amount);
|
||||
}
|
||||
SetReagents(amounts, ref label, protoMan);
|
||||
}
|
||||
|
||||
private void SetReagents(Dictionary<string, FixedPoint2> reagents, ref RichTextLabel label, IPrototypeManager protoMan)
|
||||
{
|
||||
var msg = new FormattedMessage();
|
||||
var reagentCount = reagents.Count;
|
||||
var i = 0;
|
||||
foreach (var (product, amount) in reagents.OrderByDescending(p => p.Value))
|
||||
{
|
||||
msg.AddMarkup(Loc.GetString("guidebook-reagent-recipes-reagent-display",
|
||||
("reagent", protoMan.Index<ReagentPrototype>(product).LocalizedName), ("ratio", amount)));
|
||||
i++;
|
||||
if (i < reagentCount)
|
||||
msg.PushNewline();
|
||||
}
|
||||
msg.Pop();
|
||||
label.SetMessage(msg);
|
||||
label.Visible = true;
|
||||
}
|
||||
|
||||
private void SetMixingCategory(IReadOnlyList<ProtoId<MixingCategoryPrototype>> mixingCategories, ReactionPrototype? prototype, IEntitySystemManager sysMan)
|
||||
{
|
||||
var foo = new List<MixingCategoryPrototype>();
|
||||
foreach (var cat in mixingCategories)
|
||||
{
|
||||
foo.Add(_protoMan.Index(cat));
|
||||
}
|
||||
SetMixingCategory(foo, prototype, sysMan);
|
||||
}
|
||||
|
||||
private void SetMixingCategory(IReadOnlyList<MixingCategoryPrototype> mixingCategories, ReactionPrototype? prototype, IEntitySystemManager sysMan)
|
||||
{
|
||||
if (mixingCategories.Count == 0)
|
||||
return;
|
||||
|
||||
// only use the first one for the icon.
|
||||
if (mixingCategories.First() is { } primaryCategory)
|
||||
{
|
||||
MixTexture.Texture = sysMan.GetEntitySystem<SpriteSystem>().Frame0(primaryCategory.Icon);
|
||||
}
|
||||
|
||||
var mixingVerb = ContentLocalizationManager.FormatList(mixingCategories
|
||||
.Select(p => Loc.GetString(p.VerbText)).ToList());
|
||||
|
||||
var minTemp = prototype?.MinimumTemperature ?? 0;
|
||||
var maxTemp = prototype?.MaximumTemperature ?? float.PositiveInfinity;
|
||||
var text = Loc.GetString("guidebook-reagent-recipes-mix-info",
|
||||
("verb", mixingVerb),
|
||||
("minTemp", minTemp),
|
||||
("maxTemp", maxTemp),
|
||||
("hasMax", !float.IsPositiveInfinity(maxTemp)));
|
||||
|
||||
MixLabel.SetMarkup(text);
|
||||
}
|
||||
|
||||
public bool CheckMatchesSearch(string query)
|
||||
{
|
||||
return this.ChildrenContainText(query);
|
||||
|
||||
Reference in New Issue
Block a user