-using Content.Shared.Chemistry;
+using System.Linq;
+using Content.Shared.Atmos.Prototypes;
+using Content.Shared.Body.Part;
+using Content.Shared.Chemistry;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Chemistry.Components.SolutionManager;
+using Content.Shared.Chemistry.Reaction;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Kitchen.Components;
+using Content.Shared.Prototypes;
+using Robust.Shared.Prototypes;
namespace Content.Client.Chemistry.EntitySystems;
/// <inheritdoc/>
public sealed class ChemistryGuideDataSystem : SharedChemistryGuideDataSystem
{
+ [ValidatePrototypeId<MixingCategoryPrototype>]
+ private const string DefaultMixingCategory = "DummyMix";
+ [ValidatePrototypeId<MixingCategoryPrototype>]
+ private const string DefaultGrindCategory = "DummyGrind";
+ [ValidatePrototypeId<MixingCategoryPrototype>]
+ private const string DefaultJuiceCategory = "DummyJuice";
+ [ValidatePrototypeId<MixingCategoryPrototype>]
+ private const string DefaultCondenseCategory = "DummyCondense";
+
+ private readonly Dictionary<string, List<ReagentSourceData>> _reagentSources = new();
+
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<ReagentGuideRegistryChangedEvent>(OnReceiveRegistryUpdate);
+ SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
+ OnPrototypesReloaded(null);
}
private void OnReceiveRegistryUpdate(ReagentGuideRegistryChangedEvent message)
Registry[key] = val;
}
}
+
+ private void OnPrototypesReloaded(PrototypesReloadedEventArgs? ev)
+ {
+ // this doesn't check what prototypes are being reloaded because, to be frank, we use a lot of them.
+ _reagentSources.Clear();
+ foreach (var reagent in PrototypeManager.EnumeratePrototypes<ReagentPrototype>())
+ {
+ _reagentSources.Add(reagent.ID, new());
+ }
+
+ foreach (var reaction in PrototypeManager.EnumeratePrototypes<ReactionPrototype>())
+ {
+ if (!reaction.Source)
+ continue;
+
+ var data = new ReagentReactionSourceData(
+ reaction.MixingCategories ?? new () { DefaultMixingCategory },
+ reaction);
+ foreach (var product in reaction.Products.Keys)
+ {
+ _reagentSources[product].Add(data);
+ }
+ }
+
+ foreach (var gas in PrototypeManager.EnumeratePrototypes<GasPrototype>())
+ {
+ if (gas.Reagent == null)
+ continue;
+
+ var data = new ReagentGasSourceData(
+ new () { DefaultCondenseCategory },
+ gas);
+ _reagentSources[gas.Reagent].Add(data);
+ }
+
+ // store the names of the entities used so we don't get repeats in the guide.
+ var usedNames = new List<string>();
+ foreach (var entProto in PrototypeManager.EnumeratePrototypes<EntityPrototype>())
+ {
+ if (entProto.Abstract || usedNames.Contains(entProto.Name))
+ continue;
+
+ if (!entProto.TryGetComponent<ExtractableComponent>(out var extractableComponent))
+ continue;
+
+ //these bloat the hell out of blood/fat
+ if (entProto.HasComponent<BodyPartComponent>())
+ continue;
+
+ //these feel obvious...
+ if (entProto.HasComponent<PillComponent>())
+ continue;
+
+ if (extractableComponent.JuiceSolution is { } juiceSolution)
+ {
+ var data = new ReagentEntitySourceData(
+ new() { DefaultJuiceCategory },
+ entProto,
+ juiceSolution);
+ foreach (var (id, _) in juiceSolution.Contents)
+ {
+ _reagentSources[id.Prototype].Add(data);
+ }
+
+ usedNames.Add(entProto.Name);
+ }
+
+ if (extractableComponent.GrindableSolution is { } grindableSolutionId &&
+ entProto.TryGetComponent<SolutionContainerManagerComponent>(out var manager) &&
+ manager.Solutions.TryGetValue(grindableSolutionId, out var grindableSolution))
+ {
+ var data = new ReagentEntitySourceData(
+ new() { DefaultGrindCategory },
+ entProto,
+ grindableSolution);
+ foreach (var (id, _) in grindableSolution.Contents)
+ {
+ _reagentSources[id.Prototype].Add(data);
+ }
+ usedNames.Add(entProto.Name);
+ }
+ }
+ }
+
+ public List<ReagentSourceData> GetReagentSources(string id)
+ {
+ return _reagentSources.GetValueOrDefault(id) ?? new List<ReagentSourceData>();
+ }
}
+
+/// <summary>
+/// A generic class meant to hold information about a reagent source.
+/// </summary>
+public abstract class ReagentSourceData
+{
+ /// <summary>
+ /// The mixing type that applies to this source.
+ /// </summary>
+ public readonly IReadOnlyList<ProtoId<MixingCategoryPrototype>> MixingType;
+
+ /// <summary>
+ /// The number of distinct outputs. Used for primary ordering.
+ /// </summary>
+ public abstract int OutputCount { get; }
+
+ /// <summary>
+ /// A text string corresponding to this source. Typically a name. Used for secondary ordering.
+ /// </summary>
+ public abstract string IdentifierString { get; }
+
+ protected ReagentSourceData(List<ProtoId<MixingCategoryPrototype>> mixingType)
+ {
+ MixingType = mixingType;
+ }
+}
+
+/// <summary>
+/// Used to store a reagent source that's an entity with a corresponding solution.
+/// </summary>
+public sealed class ReagentEntitySourceData : ReagentSourceData
+{
+ public readonly EntityPrototype SourceEntProto;
+
+ public readonly Solution Solution;
+
+ public override int OutputCount => Solution.Contents.Count;
+
+ public override string IdentifierString => SourceEntProto.Name;
+
+ public ReagentEntitySourceData(List<ProtoId<MixingCategoryPrototype>> mixingType, EntityPrototype sourceEntProto, Solution solution)
+ : base(mixingType)
+ {
+ SourceEntProto = sourceEntProto;
+ Solution = solution;
+ }
+}
+
+/// <summary>
+/// Used to store a reagent source that comes from a reaction between multiple reagents.
+/// </summary>
+public sealed class ReagentReactionSourceData : ReagentSourceData
+{
+ public readonly ReactionPrototype ReactionPrototype;
+
+ public override int OutputCount => ReactionPrototype.Products.Count + ReactionPrototype.Reactants.Count(r => r.Value.Catalyst);
+
+ public override string IdentifierString => ReactionPrototype.ID;
+
+ public ReagentReactionSourceData(List<ProtoId<MixingCategoryPrototype>> mixingType, ReactionPrototype reactionPrototype)
+ : base(mixingType)
+ {
+ ReactionPrototype = reactionPrototype;
+ }
+}
+
+/// <summary>
+/// Used to store a reagent source that comes from gas condensation.
+/// </summary>
+public sealed class ReagentGasSourceData : ReagentSourceData
+{
+ public readonly GasPrototype GasPrototype;
+
+ public override int OutputCount => 1;
+
+ public override string IdentifierString => Loc.GetString(GasPrototype.Name);
+
+ public ReagentGasSourceData(List<ProtoId<MixingCategoryPrototype>> mixingType, GasPrototype gasPrototype)
+ : base(mixingType)
+ {
+ GasPrototype = gasPrototype;
+ }
+}
+
<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'}"/>
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;
#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();
{
foreach (var reactionPrototype in reactions)
{
- var ctrl = GetRecipeGuide(reactionPrototype);
- RecipesDescriptionContainer.AddChild(ctrl);
+ RecipesDescriptionContainer.AddChild(new GuideReagentReaction(reactionPrototype, _prototype, _systemManager));
}
}
else
}
#endregion
+ GenerateSources(reagent);
+
FormattedMessage description = new();
description.AddText(reagent.LocalizedDescription);
description.PushNewline();
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)
- {
- reactantMsg.AddMarkup(Loc.GetString("guidebook-reagent-recipes-reagent-display",
- ("reagent", _prototype.Index<ReagentPrototype>(product).LocalizedName), ("ratio", reactant.Amount)));
- i++;
- if (i < reactantsCount)
- reactantMsg.PushNewline();
- }
- reactantMsg.Pop();
- control.ReactantsLabel.SetMessage(reactantMsg);
-
- var productMsg = new FormattedMessage();
- var productCount = reactionPrototype.Products.Count;
- var u = 0;
- foreach (var (product, ratio) in reactionPrototype.Products)
+ var sources = _chemistryGuideData.GetReagentSources(reagent.ID);
+ if (sources.Count == 0)
{
- productMsg.AddMarkup(Loc.GetString("guidebook-reagent-recipes-reagent-display",
- ("reagent", _prototype.Index<ReagentPrototype>(product).LocalizedName), ("ratio", ratio)));
- u++;
- if (u < productCount)
- productMsg.PushNewline();
+ SourcesContainer.Visible = false;
+ return;
}
- productMsg.Pop();
- control.ProductsLabel.SetMessage(productMsg);
+ SourcesContainer.Visible = true;
- var mixingCategories = new List<MixingCategoryPrototype>();
- if (reactionPrototype.MixingCategories != null)
+ var orderedSources = sources
+ .OrderBy(o => o.OutputCount)
+ .ThenBy(o => o.IdentifierString);
+ foreach (var source in orderedSources)
{
- 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;
}
}
<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"
<RichTextLabel Name="ProductsLabel"
HorizontalAlignment="Center"
VerticalAlignment="Center"
- Access="Public"/>
+ Access="Public"
+ Visible="False"/>
</BoxContainer>
</BoxContainer>
+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);
+++ /dev/null
-using Content.Server.Kitchen.EntitySystems;
-using Content.Shared.Chemistry.Components;
-
-namespace Content.Server.Kitchen.Components
-{
- /// <summary>
- /// Tag component that denotes an entity as Extractable
- /// </summary>
- [RegisterComponent]
- [Access(typeof(ReagentGrinderSystem))]
- public sealed partial class ExtractableComponent : Component
- {
- [DataField("juiceSolution")]
- public Solution? JuiceSolution;
-
- [DataField("grindableSolutionName")]
- public string? GrindableSolution;
- }
-}
using Content.Shared.FixedPoint;
using Content.Shared.Interaction;
using Content.Shared.Kitchen;
+using Content.Shared.Kitchen.Components;
using Content.Shared.Popups;
using Content.Shared.Random;
using Content.Shared.Stacks;
[DataField("priority")]
public int Priority;
+ /// <summary>
+ /// Determines whether or not this reaction creates a new chemical (false) or if it's a breakdown for existing chemicals (true)
+ /// Used in the chemistry guidebook to make divisions between recipes and reaction sources.
+ /// </summary>
+ /// <example>
+ /// Mixing together two reagents to get a third -> false
+ /// Heating a reagent to break it down into 2 different ones -> true
+ /// </example>
+ [DataField]
+ public bool Source;
+
/// <summary>
/// Comparison for creating a sorted set of reactions. Determines the order in which reactions occur.
/// </summary>
--- /dev/null
+using Content.Shared.Chemistry.Components;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Kitchen.Components;
+
+/// <summary>
+/// Tag component that denotes an entity as Extractable
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class ExtractableComponent : Component
+{
+ [DataField("juiceSolution")]
+ public Solution? JuiceSolution;
+
+ [DataField("grindableSolutionName")]
+ public string? GrindableSolution;
+};
# Types
+mixing-verb-default-mix = mix
+mixing-verb-default-grind = grind
+mixing-verb-default-juice = juice
+mixing-verb-default-condense = condense
mixing-verb-centrifuge = centrifugation
mixing-verb-electrolysis = electrolyze
mixing-verb-holy = bless
guidebook-reagent-name = [bold][color={$color}]{CAPITALIZE($name)}[/color][/bold]
guidebook-reagent-recipes-header = Recipe
guidebook-reagent-recipes-reagent-display = [bold]{$reagent}[/bold] \[{$ratio}\]
-guidebook-reagent-recipes-mix = Mix
+guidebook-reagent-sources-header = Sources
+guidebook-reagent-sources-ent-wrapper = [bold]{$name}[/bold] \[1\]
+guidebook-reagent-sources-gas-wrapper = [bold]{$name} (gas)[/bold] \[1\]
guidebook-reagent-effects-header = Effects
guidebook-reagent-effects-metabolism-group-rate = [bold]{$group}[/bold] [color=gray]({$rate} units per second)[/color]
guidebook-reagent-physical-description = [italic]Seems to be {$description}.[/italic]
guidebook-reagent-recipes-mix-info = {$minTemp ->
[0] {$hasMax ->
- [true] {$verb} below {$maxTemp}K
- *[false] {$verb}
+ [true] {CAPITALIZE($verb)} below {$maxTemp}K
+ *[false] {CAPITALIZE($verb)}
}
- *[other] {$verb} {$hasMax ->
+ *[other] {CAPITALIZE($verb)} {$hasMax ->
[true] between {$minTemp}K and {$maxTemp}K
*[false] above {$minTemp}K
}
+# Default Mixing
+# Not actually used in reactions: only meant for guidebook display purposes.
+
+- type: mixingCategory
+ id: DummyMix
+ verbText: mixing-verb-default-mix
+ icon:
+ sprite: Objects/Specific/Chemistry/beaker_large.rsi
+ state: beakerlarge
+
+- type: mixingCategory
+ id: DummyGrind
+ verbText: mixing-verb-default-grind
+ icon:
+ sprite: Structures/Machines/juicer.rsi
+ state: juicer0
+
+- type: mixingCategory
+ id: DummyJuice
+ verbText: mixing-verb-default-juice
+ icon:
+ sprite: Structures/Machines/juicer.rsi
+ state: juicer0
+
+- type: mixingCategory
+ id: DummyCondense
+ verbText: mixing-verb-default-condense
+ icon:
+ sprite: Structures/Piping/Atmospherics/condenser.rsi
+ state: display
+
+# Alternative Mixing Methods
+
- type: mixingCategory
id: Centrifuge
verbText: mixing-verb-centrifuge
- type: entity
parent: PartBase
id: PartRodMetal
- name: metal rods
+ name: metal rod
suffix: Full
components:
- type: PhysicalComposition
- type: reaction
id: BloodBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
- type: reaction
id: SlimeBloodBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
- type: reaction
id: CopperBloodBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
- type: reaction
id: ZombieBloodBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
- type: reaction
id: CelluloseBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: TableSaltBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: EthanolBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: WaterBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: BananaBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
#- type: reaction
# id: SugarBreakdown
-# minTemp: 520
- # reactants:
- # Sugar:
- # amount: 4
- # products:
- # Carbon: 1
- # Oxygen: 1
- # Hydrogen: 2
+# source: true
+# minTemp: 520
+# reactants:
+# Sugar:
+# amount: 4
+# products:
+# Carbon: 1
+# Oxygen: 1
+# Hydrogen: 2
- type: reaction
id: FiberBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
- type: reaction
id: CarbonDioxideBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: NitrousOxideBreakdown
+ source: true
requiredMixerCategories:
- Electrolysis
reactants:
- type: reaction
id: WeldingFuelBreakdown
+ source: true
requiredMixerCategories:
- Centrifuge
reactants:
"name":"pipe",
"directions":4
},
+ {
+ "name":"display"
+ },
{
"name":"fill-1"
},