Add support for printing reagents in lathes (#30476)
* Add support for reagents in lathes * missing locale
This commit is contained in:
@@ -100,11 +100,9 @@
|
|||||||
Margin="5 0 0 0"
|
Margin="5 0 0 0"
|
||||||
Text="{Loc 'lathe-menu-fabricating-message'}">
|
Text="{Loc 'lathe-menu-fabricating-message'}">
|
||||||
</Label>
|
</Label>
|
||||||
<EntityPrototypeView
|
<BoxContainer Name="FabricatingDisplayContainer"
|
||||||
Name="FabricatingEntityProto"
|
HorizontalAlignment="Left"
|
||||||
HorizontalAlignment="Left"
|
Margin="100 0 0 0"/>
|
||||||
Margin="100 0 0 0"
|
|
||||||
/>
|
|
||||||
<Label
|
<Label
|
||||||
Name="NameLabel"
|
Name="NameLabel"
|
||||||
RectClipContent="True"
|
RectClipContent="True"
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
using System.Buffers;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Content.Client.Materials;
|
using Content.Client.Materials;
|
||||||
using Content.Shared.Lathe;
|
using Content.Shared.Lathe;
|
||||||
using Content.Shared.Lathe.Prototypes;
|
using Content.Shared.Lathe.Prototypes;
|
||||||
using Content.Shared.Materials;
|
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Client.ResourceManagement;
|
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.Lathe.UI;
|
namespace Content.Client.Lathe.UI;
|
||||||
@@ -92,7 +89,7 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
|
|
||||||
if (SearchBar.Text.Trim().Length != 0)
|
if (SearchBar.Text.Trim().Length != 0)
|
||||||
{
|
{
|
||||||
if (proto.Name.ToLowerInvariant().Contains(SearchBar.Text.Trim().ToLowerInvariant()))
|
if (_lathe.GetRecipeName(recipe).ToLowerInvariant().Contains(SearchBar.Text.Trim().ToLowerInvariant()))
|
||||||
recipesToShow.Add(proto);
|
recipesToShow.Add(proto);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -104,19 +101,15 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
if (!int.TryParse(AmountLineEdit.Text, out var quantity) || quantity <= 0)
|
if (!int.TryParse(AmountLineEdit.Text, out var quantity) || quantity <= 0)
|
||||||
quantity = 1;
|
quantity = 1;
|
||||||
|
|
||||||
var sortedRecipesToShow = recipesToShow.OrderBy(p => p.Name);
|
var sortedRecipesToShow = recipesToShow.OrderBy(_lathe.GetRecipeName);
|
||||||
RecipeList.Children.Clear();
|
RecipeList.Children.Clear();
|
||||||
_entityManager.TryGetComponent(Entity, out LatheComponent? lathe);
|
_entityManager.TryGetComponent(Entity, out LatheComponent? lathe);
|
||||||
|
|
||||||
foreach (var prototype in sortedRecipesToShow)
|
foreach (var prototype in sortedRecipesToShow)
|
||||||
{
|
{
|
||||||
EntityPrototype? recipeProto = null;
|
|
||||||
if (_prototypeManager.TryIndex(prototype.Result, out EntityPrototype? entityProto))
|
|
||||||
recipeProto = entityProto;
|
|
||||||
|
|
||||||
var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe);
|
var canProduce = _lathe.CanProduce(Entity, prototype, quantity, component: lathe);
|
||||||
|
|
||||||
var control = new RecipeControl(prototype, () => GenerateTooltipText(prototype), canProduce, recipeProto);
|
var control = new RecipeControl(_lathe, prototype, () => GenerateTooltipText(prototype), canProduce, GetRecipeDisplayControl(prototype));
|
||||||
control.OnButtonPressed += s =>
|
control.OnButtonPressed += s =>
|
||||||
{
|
{
|
||||||
if (!int.TryParse(AmountLineEdit.Text, out var amount) || amount <= 0)
|
if (!int.TryParse(AmountLineEdit.Text, out var amount) || amount <= 0)
|
||||||
@@ -132,9 +125,9 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
var multiplier = _entityManager.GetComponent<LatheComponent>(Entity).MaterialUseMultiplier;
|
var multiplier = _entityManager.GetComponent<LatheComponent>(Entity).MaterialUseMultiplier;
|
||||||
|
|
||||||
foreach (var (id, amount) in prototype.RequiredMaterials)
|
foreach (var (id, amount) in prototype.Materials)
|
||||||
{
|
{
|
||||||
if (!_prototypeManager.TryIndex<MaterialPrototype>(id, out var proto))
|
if (!_prototypeManager.TryIndex(id, out var proto))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier);
|
var adjustedAmount = SharedLatheSystem.AdjustMaterial(amount, prototype.ApplyMaterialDiscount, multiplier);
|
||||||
@@ -163,8 +156,9 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
sb.AppendLine(tooltipText);
|
sb.AppendLine(tooltipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(prototype.Description))
|
var desc = _lathe.GetRecipeDescription(prototype);
|
||||||
sb.AppendLine(Loc.GetString("lathe-menu-description-display", ("description", prototype.Description)));
|
if (!string.IsNullOrWhiteSpace(desc))
|
||||||
|
sb.AppendLine(Loc.GetString("lathe-menu-description-display", ("description", desc)));
|
||||||
|
|
||||||
// Remove last newline
|
// Remove last newline
|
||||||
if (sb.Length > 0)
|
if (sb.Length > 0)
|
||||||
@@ -222,13 +216,10 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
var queuedRecipeBox = new BoxContainer();
|
var queuedRecipeBox = new BoxContainer();
|
||||||
queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
queuedRecipeBox.Orientation = BoxContainer.LayoutOrientation.Horizontal;
|
||||||
|
|
||||||
var queuedRecipeProto = new EntityPrototypeView();
|
queuedRecipeBox.AddChild(GetRecipeDisplayControl(recipe));
|
||||||
queuedRecipeBox.AddChild(queuedRecipeProto);
|
|
||||||
if (_prototypeManager.TryIndex(recipe.Result, out EntityPrototype? entityProto) && entityProto != null)
|
|
||||||
queuedRecipeProto.SetPrototype(entityProto);
|
|
||||||
|
|
||||||
var queuedRecipeLabel = new Label();
|
var queuedRecipeLabel = new Label();
|
||||||
queuedRecipeLabel.Text = $"{idx}. {recipe.Name}";
|
queuedRecipeLabel.Text = $"{idx}. {_lathe.GetRecipeName(recipe)}";
|
||||||
queuedRecipeBox.AddChild(queuedRecipeLabel);
|
queuedRecipeBox.AddChild(queuedRecipeLabel);
|
||||||
QueueList.AddChild(queuedRecipeBox);
|
QueueList.AddChild(queuedRecipeBox);
|
||||||
idx++;
|
idx++;
|
||||||
@@ -241,10 +232,29 @@ public sealed partial class LatheMenu : DefaultWindow
|
|||||||
if (recipe == null)
|
if (recipe == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_prototypeManager.TryIndex(recipe.Result, out EntityPrototype? entityProto) && entityProto != null)
|
FabricatingDisplayContainer.Children.Clear();
|
||||||
FabricatingEntityProto.SetPrototype(entityProto);
|
FabricatingDisplayContainer.AddChild(GetRecipeDisplayControl(recipe));
|
||||||
|
|
||||||
NameLabel.Text = $"{recipe.Name}";
|
NameLabel.Text = _lathe.GetRecipeName(recipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Control GetRecipeDisplayControl(LatheRecipePrototype recipe)
|
||||||
|
{
|
||||||
|
if (recipe.Icon != null)
|
||||||
|
{
|
||||||
|
var textRect = new TextureRect();
|
||||||
|
textRect.Texture = _spriteSystem.Frame0(recipe.Icon);
|
||||||
|
return textRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipe.Result is { } result)
|
||||||
|
{
|
||||||
|
var entProtoView = new EntityPrototypeView();
|
||||||
|
entProtoView.SetPrototype(result);
|
||||||
|
return entProtoView;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Control();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnItemSelected(OptionButton.ItemSelectedEventArgs obj)
|
private void OnItemSelected(OptionButton.ItemSelectedEventArgs obj)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
Margin="0"
|
Margin="0"
|
||||||
StyleClasses="ButtonSquare">
|
StyleClasses="ButtonSquare">
|
||||||
<BoxContainer Orientation="Horizontal">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<EntityPrototypeView
|
<BoxContainer
|
||||||
Name="RecipePrototype"
|
Name="RecipeDisplayContainer"
|
||||||
Margin="0 0 4 0"
|
Margin="0 0 4 0"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Shared.Prototypes;
|
|
||||||
|
|
||||||
namespace Content.Client.Lathe.UI;
|
namespace Content.Client.Lathe.UI;
|
||||||
|
|
||||||
@@ -14,13 +11,12 @@ public sealed partial class RecipeControl : Control
|
|||||||
public Action<string>? OnButtonPressed;
|
public Action<string>? OnButtonPressed;
|
||||||
public Func<string> TooltipTextSupplier;
|
public Func<string> TooltipTextSupplier;
|
||||||
|
|
||||||
public RecipeControl(LatheRecipePrototype recipe, Func<string> tooltipTextSupplier, bool canProduce, EntityPrototype? entityPrototype = null)
|
public RecipeControl(LatheSystem latheSystem, LatheRecipePrototype recipe, Func<string> tooltipTextSupplier, bool canProduce, Control displayControl)
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
RecipeName.Text = recipe.Name;
|
RecipeName.Text = latheSystem.GetRecipeName(recipe);
|
||||||
if (entityPrototype != null)
|
RecipeDisplayContainer.AddChild(displayControl);
|
||||||
RecipePrototype.SetPrototype(entityPrototype);
|
|
||||||
Button.Disabled = !canProduce;
|
Button.Disabled = !canProduce;
|
||||||
TooltipTextSupplier = tooltipTextSupplier;
|
TooltipTextSupplier = tooltipTextSupplier;
|
||||||
Button.TooltipSupplier = SupplyTooltip;
|
Button.TooltipSupplier = SupplyTooltip;
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ public sealed class MaterialArbitrageTest
|
|||||||
{
|
{
|
||||||
foreach (var recipe in recipes)
|
foreach (var recipe in recipes)
|
||||||
{
|
{
|
||||||
foreach (var (matId, amount) in recipe.RequiredMaterials)
|
foreach (var (matId, amount) in recipe.Materials)
|
||||||
{
|
{
|
||||||
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
||||||
if (spawnedMats.TryGetValue(matId, out var numSpawned))
|
if (spawnedMats.TryGetValue(matId, out var numSpawned))
|
||||||
@@ -273,7 +273,7 @@ public sealed class MaterialArbitrageTest
|
|||||||
{
|
{
|
||||||
foreach (var recipe in recipes)
|
foreach (var recipe in recipes)
|
||||||
{
|
{
|
||||||
foreach (var (matId, amount) in recipe.RequiredMaterials)
|
foreach (var (matId, amount) in recipe.Materials)
|
||||||
{
|
{
|
||||||
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
||||||
if (deconstructedMats.TryGetValue(matId, out var numSpawned))
|
if (deconstructedMats.TryGetValue(matId, out var numSpawned))
|
||||||
@@ -328,7 +328,7 @@ public sealed class MaterialArbitrageTest
|
|||||||
{
|
{
|
||||||
foreach (var recipe in recipes)
|
foreach (var recipe in recipes)
|
||||||
{
|
{
|
||||||
foreach (var (matId, amount) in recipe.RequiredMaterials)
|
foreach (var (matId, amount) in recipe.Materials)
|
||||||
{
|
{
|
||||||
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
var actualAmount = SharedLatheSystem.AdjustMaterial(amount, recipe.ApplyMaterialDiscount, multiplier);
|
||||||
if (compositionComponent.MaterialComposition.TryGetValue(matId, out var numSpawned))
|
if (compositionComponent.MaterialComposition.TryGetValue(matId, out var numSpawned))
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using Robust.Shared.Map.Components;
|
|||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Shared.Research.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems;
|
namespace Content.Server.Cargo.Systems;
|
||||||
|
|
||||||
@@ -158,6 +159,26 @@ public sealed class PricingSystem : EntitySystem
|
|||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double GetLatheRecipePrice(LatheRecipePrototype recipe)
|
||||||
|
{
|
||||||
|
var price = 0.0;
|
||||||
|
|
||||||
|
if (recipe.Result is { } result)
|
||||||
|
{
|
||||||
|
price += GetEstimatedPrice(_prototypeManager.Index(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipe.ResultReagents is { } resultReagents)
|
||||||
|
{
|
||||||
|
foreach (var (reagent, amount) in resultReagents)
|
||||||
|
{
|
||||||
|
price += (_prototypeManager.Index(reagent).PricePerUnit * amount).Double();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a rough price for an entityprototype. Does not consider contained entities.
|
/// Get a rough price for an entityprototype. Does not consider contained entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Atmos;
|
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
|
using Content.Server.Fluids.EntitySystems;
|
||||||
using Content.Server.Lathe.Components;
|
using Content.Server.Lathe.Components;
|
||||||
using Content.Server.Materials;
|
using Content.Server.Materials;
|
||||||
|
using Content.Server.Popups;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.Stack;
|
using Content.Server.Stack;
|
||||||
using Content.Shared.Atmos;
|
using Content.Shared.Atmos;
|
||||||
|
using Content.Shared.Chemistry.Components;
|
||||||
|
using Content.Shared.Chemistry.EntitySystems;
|
||||||
|
using Content.Shared.Chemistry.Reagent;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Emag.Components;
|
using Content.Shared.Emag.Components;
|
||||||
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Lathe;
|
using Content.Shared.Lathe;
|
||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
using Content.Shared.ReagentSpeed;
|
using Content.Shared.ReagentSpeed;
|
||||||
using Content.Shared.Research.Components;
|
using Content.Shared.Research.Components;
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Server.Containers;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
@@ -34,9 +40,13 @@ namespace Content.Server.Lathe
|
|||||||
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphere = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly ContainerSystem _container = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _uiSys = default!;
|
[Dependency] private readonly UserInterfaceSystem _uiSys = default!;
|
||||||
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
|
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
|
||||||
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly PuddleSystem _puddle = default!;
|
||||||
[Dependency] private readonly ReagentSpeedSystem _reagentSpeed = default!;
|
[Dependency] private readonly ReagentSpeedSystem _reagentSpeed = default!;
|
||||||
|
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
|
||||||
[Dependency] private readonly StackSystem _stack = default!;
|
[Dependency] private readonly StackSystem _stack = default!;
|
||||||
[Dependency] private readonly TransformSystem _transform = default!;
|
[Dependency] private readonly TransformSystem _transform = default!;
|
||||||
|
|
||||||
@@ -63,7 +73,6 @@ namespace Content.Server.Lathe
|
|||||||
SubscribeLocalEvent<EmagLatheRecipesComponent, LatheGetRecipesEvent>(GetEmagLatheRecipes);
|
SubscribeLocalEvent<EmagLatheRecipesComponent, LatheGetRecipesEvent>(GetEmagLatheRecipes);
|
||||||
SubscribeLocalEvent<LatheHeatProducingComponent, LatheStartPrintingEvent>(OnHeatStartPrinting);
|
SubscribeLocalEvent<LatheHeatProducingComponent, LatheStartPrintingEvent>(OnHeatStartPrinting);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
var query = EntityQueryEnumerator<LatheProducingComponent, LatheComponent>();
|
var query = EntityQueryEnumerator<LatheProducingComponent, LatheComponent>();
|
||||||
@@ -119,7 +128,7 @@ namespace Content.Server.Lathe
|
|||||||
{
|
{
|
||||||
if (!_proto.TryIndex(id, out var proto))
|
if (!_proto.TryIndex(id, out var proto))
|
||||||
continue;
|
continue;
|
||||||
foreach (var (mat, _) in proto.RequiredMaterials)
|
foreach (var (mat, _) in proto.Materials)
|
||||||
{
|
{
|
||||||
if (!materialWhitelist.Contains(mat))
|
if (!materialWhitelist.Contains(mat))
|
||||||
{
|
{
|
||||||
@@ -165,7 +174,7 @@ namespace Content.Server.Lathe
|
|||||||
if (!CanProduce(uid, recipe, 1, component))
|
if (!CanProduce(uid, recipe, 1, component))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var (mat, amount) in recipe.RequiredMaterials)
|
foreach (var (mat, amount) in recipe.Materials)
|
||||||
{
|
{
|
||||||
var adjustedAmount = recipe.ApplyMaterialDiscount
|
var adjustedAmount = recipe.ApplyMaterialDiscount
|
||||||
? (int) (-amount * component.MaterialUseMultiplier)
|
? (int) (-amount * component.MaterialUseMultiplier)
|
||||||
@@ -211,8 +220,31 @@ namespace Content.Server.Lathe
|
|||||||
|
|
||||||
if (comp.CurrentRecipe != null)
|
if (comp.CurrentRecipe != null)
|
||||||
{
|
{
|
||||||
var result = Spawn(comp.CurrentRecipe.Result, Transform(uid).Coordinates);
|
if (comp.CurrentRecipe.Result is { } resultProto)
|
||||||
_stack.TryMergeToContacts(result);
|
{
|
||||||
|
var result = Spawn(resultProto, Transform(uid).Coordinates);
|
||||||
|
_stack.TryMergeToContacts(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp.CurrentRecipe.ResultReagents is { } resultReagents &&
|
||||||
|
comp.ReagentOutputSlotId is { } slotId)
|
||||||
|
{
|
||||||
|
var toAdd = new Solution(
|
||||||
|
resultReagents.Select(p => new ReagentQuantity(p.Key.Id, p.Value, null)));
|
||||||
|
|
||||||
|
// dispense it in the container if we have it and dump it if we don't
|
||||||
|
if (_container.TryGetContainer(uid, slotId, out var container) &&
|
||||||
|
container.ContainedEntities.Count == 1 &&
|
||||||
|
_solution.TryGetFitsInDispenser(container.ContainedEntities.First(), out var solution, out _))
|
||||||
|
{
|
||||||
|
_solution.AddSolution(solution.Value, toAdd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_popup.PopupEntity(Loc.GetString("lathe-reagent-dispense-no-container", ("name", uid)), uid);
|
||||||
|
_puddle.TrySpillAt(uid, toAdd, out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
comp.CurrentRecipe = null;
|
comp.CurrentRecipe = null;
|
||||||
@@ -327,6 +359,7 @@ namespace Content.Server.Lathe
|
|||||||
{
|
{
|
||||||
return GetAvailableRecipes(uid, component).Contains(recipe.ID);
|
return GetAvailableRecipes(uid, component).Contains(recipe.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region UI Messages
|
#region UI Messages
|
||||||
|
|
||||||
private void OnLatheQueueRecipeMessage(EntityUid uid, LatheComponent component, LatheQueueRecipeMessage args)
|
private void OnLatheQueueRecipeMessage(EntityUid uid, LatheComponent component, LatheQueueRecipeMessage args)
|
||||||
@@ -343,8 +376,9 @@ namespace Content.Server.Lathe
|
|||||||
}
|
}
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
_adminLogger.Add(LogType.Action, LogImpact.Low,
|
_adminLogger.Add(LogType.Action,
|
||||||
$"{ToPrettyString(args.Actor):player} queued {count} {recipe.Name} at {ToPrettyString(uid):lathe}");
|
LogImpact.Low,
|
||||||
|
$"{ToPrettyString(args.Actor):player} queued {count} {GetRecipeName(recipe)} at {ToPrettyString(uid):lathe}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TryStartProducing(uid, component);
|
TryStartProducing(uid, component);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using Content.Server.Item;
|
|||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
using Content.Shared.Materials;
|
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using Content.Shared.UserInterface;
|
using Content.Shared.UserInterface;
|
||||||
using Content.Shared.Weapons.Melee;
|
using Content.Shared.Weapons.Melee;
|
||||||
@@ -224,13 +223,13 @@ public sealed class StatValuesCommand : IConsoleCommand
|
|||||||
{
|
{
|
||||||
var cost = 0.0;
|
var cost = 0.0;
|
||||||
|
|
||||||
foreach (var (material, count) in proto.RequiredMaterials)
|
foreach (var (material, count) in proto.Materials)
|
||||||
{
|
{
|
||||||
var materialPrice = _proto.Index<MaterialPrototype>(material).Price;
|
var materialPrice = _proto.Index(material).Price;
|
||||||
cost += materialPrice * count;
|
cost += materialPrice * count;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sell = priceSystem.GetEstimatedPrice(_proto.Index<EntityPrototype>(proto.Result));
|
var sell = priceSystem.GetLatheRecipePrice(proto);
|
||||||
|
|
||||||
values.Add(new[]
|
values.Add(new[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ namespace Content.Shared.Construction
|
|||||||
{
|
{
|
||||||
var partRecipe = recipes[0];
|
var partRecipe = recipes[0];
|
||||||
if (recipes.Count > 1)
|
if (recipes.Count > 1)
|
||||||
partRecipe = recipes.MinBy(p => p.RequiredMaterials.Values.Sum());
|
partRecipe = recipes.MinBy(p => p.Materials.Values.Sum());
|
||||||
|
|
||||||
foreach (var (mat, matAmount) in partRecipe!.RequiredMaterials)
|
foreach (var (mat, matAmount) in partRecipe!.Materials)
|
||||||
{
|
{
|
||||||
materials.TryAdd(mat, 0);
|
materials.TryAdd(mat, 0);
|
||||||
materials[mat] += matAmount * amount * coefficient;
|
materials[mat] += matAmount * amount * coefficient;
|
||||||
@@ -101,9 +101,9 @@ namespace Content.Shared.Construction
|
|||||||
{
|
{
|
||||||
var partRecipe = recipes[0];
|
var partRecipe = recipes[0];
|
||||||
if (recipes.Count > 1)
|
if (recipes.Count > 1)
|
||||||
partRecipe = recipes.MinBy(p => p.RequiredMaterials.Values.Sum());
|
partRecipe = recipes.MinBy(p => p.Materials.Values.Sum());
|
||||||
|
|
||||||
foreach (var (mat, matAmount) in partRecipe!.RequiredMaterials)
|
foreach (var (mat, matAmount) in partRecipe!.Materials)
|
||||||
{
|
{
|
||||||
materials.TryAdd(mat, 0);
|
materials.TryAdd(mat, 0);
|
||||||
materials[mat] += matAmount * amount * coefficient;
|
materials[mat] += matAmount * amount * coefficient;
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ namespace Content.Shared.Lathe
|
|||||||
[DataField]
|
[DataField]
|
||||||
public SoundSpecifier? ProducingSound;
|
public SoundSpecifier? ProducingSound;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public string? ReagentOutputSlotId;
|
||||||
|
|
||||||
#region Visualizer info
|
#region Visualizer info
|
||||||
[DataField]
|
[DataField]
|
||||||
public string? IdleState;
|
public string? IdleState;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
using Content.Shared.Emag.Systems;
|
using Content.Shared.Emag.Systems;
|
||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Localizations;
|
||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -23,10 +26,21 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<EmagLatheRecipesComponent, GotEmaggedEvent>(OnEmagged);
|
SubscribeLocalEvent<EmagLatheRecipesComponent, GotEmaggedEvent>(OnEmagged);
|
||||||
|
SubscribeLocalEvent<LatheComponent, ExaminedEvent>(OnExamined);
|
||||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
||||||
|
|
||||||
BuildInverseRecipeDictionary();
|
BuildInverseRecipeDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnExamined(Entity<LatheComponent> ent, ref ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (!args.IsInDetailsRange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ent.Comp.ReagentOutputSlotId != null)
|
||||||
|
args.PushMarkup(Loc.GetString("lathe-menu-reagent-slot-examine"));
|
||||||
|
}
|
||||||
|
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null)
|
public bool CanProduce(EntityUid uid, string recipe, int amount = 1, LatheComponent? component = null)
|
||||||
{
|
{
|
||||||
@@ -40,7 +54,7 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
if (!HasRecipe(uid, recipe, component))
|
if (!HasRecipe(uid, recipe, component))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var (material, needed) in recipe.RequiredMaterials)
|
foreach (var (material, needed) in recipe.Materials)
|
||||||
{
|
{
|
||||||
var adjustedAmount = AdjustMaterial(needed, recipe.ApplyMaterialDiscount, component.MaterialUseMultiplier);
|
var adjustedAmount = AdjustMaterial(needed, recipe.ApplyMaterialDiscount, component.MaterialUseMultiplier);
|
||||||
|
|
||||||
@@ -72,6 +86,9 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
_inverseRecipeDictionary.Clear();
|
_inverseRecipeDictionary.Clear();
|
||||||
foreach (var latheRecipe in _proto.EnumeratePrototypes<LatheRecipePrototype>())
|
foreach (var latheRecipe in _proto.EnumeratePrototypes<LatheRecipePrototype>())
|
||||||
{
|
{
|
||||||
|
if (latheRecipe.Result == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
_inverseRecipeDictionary.GetOrNew(latheRecipe.Result).Add(latheRecipe);
|
_inverseRecipeDictionary.GetOrNew(latheRecipe.Result).Add(latheRecipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,4 +100,55 @@ public abstract class SharedLatheSystem : EntitySystem
|
|||||||
recipes.AddRange(r);
|
recipes.AddRange(r);
|
||||||
return recipes.Count != 0;
|
return recipes.Count != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetRecipeName(ProtoId<LatheRecipePrototype> proto)
|
||||||
|
{
|
||||||
|
return GetRecipeName(_proto.Index(proto));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetRecipeName(LatheRecipePrototype proto)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(proto.Name))
|
||||||
|
return Loc.GetString(proto.Name);
|
||||||
|
|
||||||
|
if (proto.Result is { } result)
|
||||||
|
{
|
||||||
|
return _proto.Index(result).Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proto.ResultReagents is { } resultReagents)
|
||||||
|
{
|
||||||
|
return ContentLocalizationManager.FormatList(resultReagents
|
||||||
|
.Select(p => Loc.GetString("lathe-menu-result-reagent-display", ("reagent", _proto.Index(p.Key).LocalizedName), ("amount", p.Value)))
|
||||||
|
.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
[PublicAPI]
|
||||||
|
public string GetRecipeDescription(ProtoId<LatheRecipePrototype> proto)
|
||||||
|
{
|
||||||
|
return GetRecipeDescription(_proto.Index(proto));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetRecipeDescription(LatheRecipePrototype proto)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(proto.Description))
|
||||||
|
return Loc.GetString(proto.Description);
|
||||||
|
|
||||||
|
if (proto.Result is { } result)
|
||||||
|
{
|
||||||
|
return _proto.Index(result).Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proto.ResultReagents is { } resultReagents)
|
||||||
|
{
|
||||||
|
// We only use the first one for the description since these descriptions don't combine very well.
|
||||||
|
var reagent = resultReagents.First().Key;
|
||||||
|
return _proto.Index(reagent).LocalizedDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,101 +1,58 @@
|
|||||||
|
using Content.Shared.Chemistry.Reagent;
|
||||||
|
using Content.Shared.FixedPoint;
|
||||||
using Content.Shared.Lathe.Prototypes;
|
using Content.Shared.Lathe.Prototypes;
|
||||||
using Content.Shared.Materials;
|
using Content.Shared.Materials;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Research.Prototypes
|
namespace Content.Shared.Research.Prototypes
|
||||||
{
|
{
|
||||||
[NetSerializable, Serializable, Prototype("latheRecipe")]
|
[NetSerializable, Serializable, Prototype]
|
||||||
public sealed partial class LatheRecipePrototype : IPrototype
|
public sealed partial class LatheRecipePrototype : IPrototype
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
public string ID { get; private set; } = default!;
|
public string ID { get; private set; } = default!;
|
||||||
|
|
||||||
[DataField("name")]
|
|
||||||
private string _name = string.Empty;
|
|
||||||
|
|
||||||
[DataField("description")]
|
|
||||||
private string _description = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The prototype name of the resulting entity when the recipe is printed.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("result", required: true, customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
|
|
||||||
public string Result = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An entity whose sprite is displayed in the ui in place of the actual recipe result.
|
|
||||||
/// </summary>
|
|
||||||
[DataField("icon")]
|
|
||||||
public SpriteSpecifier? Icon;
|
|
||||||
|
|
||||||
[DataField("completetime")]
|
|
||||||
private TimeSpan _completeTime = TimeSpan.FromSeconds(5);
|
|
||||||
|
|
||||||
[DataField("materials", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, MaterialPrototype>))]
|
|
||||||
private Dictionary<string, int> _requiredMaterials = new();
|
|
||||||
|
|
||||||
//todo make these function calls because we're eating tons of resolves here.
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name displayed in the lathe GUI.
|
/// Name displayed in the lathe GUI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[DataField]
|
||||||
public string Name
|
public LocId? Name;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_name.Trim().Length != 0)
|
|
||||||
return _name;
|
|
||||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
|
||||||
protoMan.TryIndex(Result, out EntityPrototype? prototype);
|
|
||||||
if (prototype?.Name != null)
|
|
||||||
_name = prototype.Name;
|
|
||||||
return _name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Short description displayed in the lathe GUI.
|
/// Short description displayed in the lathe GUI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[DataField]
|
||||||
public string Description
|
public LocId? Description;
|
||||||
{
|
|
||||||
get
|
/// <summary>
|
||||||
{
|
/// The prototype name of the resulting entity when the recipe is printed.
|
||||||
if (_description.Trim().Length != 0)
|
/// </summary>
|
||||||
return _description;
|
[DataField]
|
||||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
public EntProtoId? Result;
|
||||||
protoMan.TryIndex(Result, out EntityPrototype? prototype);
|
|
||||||
if (prototype?.Description != null)
|
[DataField]
|
||||||
_description = prototype.Description;
|
public Dictionary<ProtoId<ReagentPrototype>, FixedPoint2>? ResultReagents;
|
||||||
return _description;
|
|
||||||
}
|
/// <summary>
|
||||||
}
|
/// An entity whose sprite is displayed in the ui in place of the actual recipe result.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SpriteSpecifier? Icon;
|
||||||
|
|
||||||
|
[DataField("completetime")]
|
||||||
|
public TimeSpan CompleteTime = TimeSpan.FromSeconds(5);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The materials required to produce this recipe.
|
/// The materials required to produce this recipe.
|
||||||
/// Takes a material ID as string.
|
/// Takes a material ID as string.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[DataField]
|
||||||
public Dictionary<string, int> RequiredMaterials
|
public Dictionary<ProtoId<MaterialPrototype>, int> Materials = new();
|
||||||
{
|
|
||||||
get => _requiredMaterials;
|
|
||||||
private set => _requiredMaterials = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[DataField]
|
||||||
/// <summary>
|
|
||||||
/// How many milliseconds it'll take for the lathe to finish this recipe.
|
|
||||||
/// Might lower depending on the lathe's upgrade level.
|
|
||||||
/// </summary>
|
|
||||||
[ViewVariables]
|
|
||||||
public TimeSpan CompleteTime => _completeTime;
|
|
||||||
|
|
||||||
[DataField("applyMaterialDiscount")]
|
|
||||||
public bool ApplyMaterialDiscount = true;
|
public bool ApplyMaterialDiscount = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Shared.Lathe;
|
||||||
using Content.Shared.Research.Components;
|
using Content.Shared.Research.Components;
|
||||||
using Content.Shared.Research.Prototypes;
|
using Content.Shared.Research.Prototypes;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
@@ -12,6 +13,7 @@ public abstract class SharedResearchSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
|
[Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly SharedLatheSystem _lathe = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -185,7 +187,7 @@ public abstract class SharedResearchSystem : EntitySystem
|
|||||||
var recipeProto = PrototypeManager.Index(recipe);
|
var recipeProto = PrototypeManager.Index(recipe);
|
||||||
description.PushNewline();
|
description.PushNewline();
|
||||||
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry",
|
description.AddMarkup(Loc.GetString("research-console-unlocks-list-entry",
|
||||||
("name",recipeProto.Name)));
|
("name", _lathe.GetRecipeName(recipeProto))));
|
||||||
}
|
}
|
||||||
foreach (var generic in technology.GenericUnlocks)
|
foreach (var generic in technology.GenericUnlocks)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Lathe;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Random.Helpers;
|
using Content.Shared.Random.Helpers;
|
||||||
using Content.Shared.Research.Components;
|
using Content.Shared.Research.Components;
|
||||||
@@ -19,6 +20,7 @@ public sealed class TechnologyDiskSystem : EntitySystem
|
|||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
[Dependency] private readonly SharedResearchSystem _research = default!;
|
[Dependency] private readonly SharedResearchSystem _research = default!;
|
||||||
|
[Dependency] private readonly SharedLatheSystem _lathe = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -83,8 +85,7 @@ public sealed class TechnologyDiskSystem : EntitySystem
|
|||||||
if (ent.Comp.Recipes != null && ent.Comp.Recipes.Count > 0)
|
if (ent.Comp.Recipes != null && ent.Comp.Recipes.Count > 0)
|
||||||
{
|
{
|
||||||
var prototype = _protoMan.Index(ent.Comp.Recipes[0]);
|
var prototype = _protoMan.Index(ent.Comp.Recipes[0]);
|
||||||
var resultPrototype = _protoMan.Index<EntityPrototype>(prototype.Result);
|
message = Loc.GetString("tech-disk-examine", ("result", _lathe.GetRecipeName(prototype)));
|
||||||
message = Loc.GetString("tech-disk-examine", ("result", resultPrototype.Name));
|
|
||||||
|
|
||||||
if (ent.Comp.Recipes.Count > 1) //idk how to do this well. sue me.
|
if (ent.Comp.Recipes.Count > 1) //idk how to do this well. sue me.
|
||||||
message += " " + Loc.GetString("tech-disk-examine-more");
|
message += " " + Loc.GetString("tech-disk-examine-more");
|
||||||
|
|||||||
8
Resources/Locale/en-US/lathe/recipes.ftl
Normal file
8
Resources/Locale/en-US/lathe/recipes.ftl
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
lathe-recipe-Medkit-name = first aid kit (empty)
|
||||||
|
lathe-recipe-MedkitBurn-name = burn treatment kit (empty)
|
||||||
|
lathe-recipe-MedkitToxin-name = toxin treatment kit (empty)
|
||||||
|
lathe-recipe-MedkitO2-name = oxygen deprivation treatment kit (empty)
|
||||||
|
lathe-recipe-MedkitBrute-name = brute trauma treatment kit (empty)
|
||||||
|
lathe-recipe-MedkitAdvanced-name = advanced first aid kit (empty)
|
||||||
|
lathe-recipe-MedkitRadiation-name = radiation treatment kit (empty)
|
||||||
|
lathe-recipe-MedkitCombat-name = combat medical kit (empty)
|
||||||
@@ -6,6 +6,9 @@ lathe-menu-search-designs = Search designs
|
|||||||
lathe-menu-category-all = All
|
lathe-menu-category-all = All
|
||||||
lathe-menu-search-filter = Filter:
|
lathe-menu-search-filter = Filter:
|
||||||
lathe-menu-amount = Amount:
|
lathe-menu-amount = Amount:
|
||||||
|
lathe-menu-reagent-slot-examine = It has a slot for a beaker on the side.
|
||||||
|
lathe-reagent-dispense-no-container = Liquid pours out of {THE($name)} onto the floor!
|
||||||
|
lathe-menu-result-reagent-display = {$reagent} ({$amount}u)
|
||||||
lathe-menu-material-display = {$material} ({$amount})
|
lathe-menu-material-display = {$material} ({$amount})
|
||||||
lathe-menu-tooltip-display = {$amount} of {$material}
|
lathe-menu-tooltip-display = {$amount} of {$material}
|
||||||
lathe-menu-description-display = [italic]{$description}[/italic]
|
lathe-menu-description-display = [italic]{$description}[/italic]
|
||||||
|
|||||||
@@ -134,7 +134,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: Medkit
|
id: Medkit
|
||||||
result: Medkit
|
result: Medkit
|
||||||
name: first aid kit (empty)
|
name: lathe-recipe-Medkit-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitBurn
|
id: MedkitBurn
|
||||||
result: MedkitBurn
|
result: MedkitBurn
|
||||||
name: burn treatment kit (empty)
|
name: lathe-recipe-MedkitBurn-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitToxin
|
id: MedkitToxin
|
||||||
result: MedkitToxin
|
result: MedkitToxin
|
||||||
name: toxin treatment kit (empty)
|
name: lathe-recipe-MedkitToxin-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitO2
|
id: MedkitO2
|
||||||
result: MedkitO2
|
result: MedkitO2
|
||||||
name: oxygen deprivation treatment kit (empty)
|
name: lathe-recipe-MedkitO2-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitBrute
|
id: MedkitBrute
|
||||||
result: MedkitBrute
|
result: MedkitBrute
|
||||||
name: brute trauma treatment kit (empty)
|
name: lathe-recipe-MedkitBrute-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitAdvanced
|
id: MedkitAdvanced
|
||||||
result: MedkitAdvanced
|
result: MedkitAdvanced
|
||||||
name: advanced first aid kit (empty)
|
name: lathe-recipe-MedkitAdvanced-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitRadiation
|
id: MedkitRadiation
|
||||||
result: MedkitRadiation
|
result: MedkitRadiation
|
||||||
name: radiation treatment kit (empty)
|
name: lathe-recipe-MedkitRadiation-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: MedkitCombat
|
id: MedkitCombat
|
||||||
result: MedkitCombat
|
result: MedkitCombat
|
||||||
name: combat medical kit (empty)
|
name: lathe-recipe-MedkitCombat-name
|
||||||
completetime: 2
|
completetime: 2
|
||||||
materials:
|
materials:
|
||||||
Plastic: 300
|
Plastic: 300
|
||||||
|
|||||||
Reference in New Issue
Block a user