using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Client.Guidebook.Richtext; using Content.Client.Message; using Content.Client.UserInterface.ControlExtensions; using Content.Shared.Chemistry.Reagent; using Content.Shared.Kitchen; using JetBrains.Annotations; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Client.UserInterface; using Robust.Shared.Prototypes; using Robust.Shared.Utility; using Robust.Client.GameObjects; namespace Content.Client.Guidebook.Controls; /// /// Control for embedding a microwave recipe into a guidebook. /// [UsedImplicitly, GenerateTypedNameReferences] public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag, ISearchableControl, IPrototypeRepresentationControl { [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly ILogManager _logManager = default!; private readonly SpriteSystem _sprite = default!; // Frontier private readonly ISawmill _sawmill = default!; public IPrototype? RepresentedPrototype { get; private set; } public GuideMicrowaveEmbed() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); MouseFilter = MouseFilterMode.Stop; _sawmill = _logManager.GetSawmill("guidebook.microwave"); _sprite = IoCManager.Resolve().GetEntitySystem(); // Frontier } public GuideMicrowaveEmbed(string recipe) : this() { GenerateControl(_prototype.Index(recipe)); } public GuideMicrowaveEmbed(FoodRecipePrototype recipe) : this() { GenerateControl(recipe); } public bool CheckMatchesSearch(string query) { return this.ChildrenContainText(query); } public void SetHiddenState(bool state, string query) { Visible = CheckMatchesSearch(query) ? state : !state; } public bool TryParseTag(Dictionary args, [NotNullWhen(true)] out Control? control) { control = null; if (!args.TryGetValue("Recipe", out var id)) { _sawmill.Error("Recipe embed tag is missing recipe prototype argument"); return false; } if (!_prototype.TryIndex(id, out var recipe)) { _sawmill.Error($"Specified recipe prototype \"{id}\" is not a valid recipe prototype"); return false; } GenerateControl(recipe); control = this; return true; } private void GenerateHeader(FoodRecipePrototype recipe) { var entity = _prototype.Index(recipe.Result); RepresentedPrototype = entity; IconContainer.AddChild(new GuideEntityEmbed(recipe.Result, false, false)); ResultName.SetMarkup(entity.Name); ResultDescription.SetMarkup(entity.Description); } private void GenerateSolidIngredients(FoodRecipePrototype recipe) { foreach (var (product, amount) in recipe.IngredientsSolids.OrderByDescending(p => p.Value)) { var ingredient = _prototype.Index(product); IngredientsGrid.AddChild(new GuideEntityEmbed(product, false, false)); // solid name var solidNameMsg = new FormattedMessage(); solidNameMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-solid-name-display", ("ingredient", ingredient.Name))); solidNameMsg.Pop(); var solidNameLabel = new GuidebookRichPrototypeLink(); solidNameLabel.SetMessage(solidNameMsg); solidNameLabel.LinkedPrototype = ingredient; IngredientsGrid.AddChild(solidNameLabel); // solid quantity var solidQuantityMsg = new FormattedMessage(); solidQuantityMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-solid-quantity-display", ("amount", amount))); solidQuantityMsg.Pop(); var solidQuantityLabel = new RichTextLabel(); solidQuantityLabel.SetMessage(solidQuantityMsg); IngredientsGrid.AddChild(solidQuantityLabel); } } private void GenerateLiquidIngredients(FoodRecipePrototype recipe) { foreach (var (product, amount) in recipe.IngredientsReagents.OrderByDescending(p => p.Value)) { var reagent = _prototype.Index(product); // liquid color var liquidColorMsg = new FormattedMessage(); liquidColorMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-reagent-color-display", ("color", reagent.SubstanceColor))); liquidColorMsg.Pop(); var liquidColorLabel = new GuidebookRichPrototypeLink(); liquidColorLabel.SetMessage(liquidColorMsg); liquidColorLabel.HorizontalAlignment = Control.HAlignment.Center; liquidColorLabel.LinkedPrototype = reagent; IngredientsGrid.AddChild(liquidColorLabel); // liquid name var liquidNameMsg = new FormattedMessage(); liquidNameMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-reagent-name-display", ("reagent", reagent.LocalizedName))); liquidNameMsg.Pop(); var liquidNameLabel = new RichTextLabel(); liquidNameLabel.SetMessage(liquidNameMsg); IngredientsGrid.AddChild(liquidNameLabel); // liquid quantity var liquidQuantityMsg = new FormattedMessage(); liquidQuantityMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-reagent-quantity-display", ("amount", amount))); liquidQuantityMsg.Pop(); var liquidQuantityLabel = new RichTextLabel(); liquidQuantityLabel.SetMessage(liquidQuantityMsg); IngredientsGrid.AddChild(liquidQuantityLabel); } } private void GenerateIngredients(FoodRecipePrototype recipe) { GenerateLiquidIngredients(recipe); GenerateSolidIngredients(recipe); } private void GenerateCookTime(FoodRecipePrototype recipe) { // Frontier: multiple processing methods per recipe List processingTypes = new(); var recipeType = (MicrowaveRecipeType)recipe.RecipeType; if (recipeType.HasFlag(MicrowaveRecipeType.Microwave)) { if (recipe.SecretRecipe) AppendMachineTexture("/Textures/Structures/Machines/microwave_syndie.rsi", "mw"); else AppendMachineTexture("/Textures/Structures/Machines/microwave.rsi", "mw"); processingTypes.Add(Loc.GetString("guidebook-food-processing-type-microwave")); } if (recipeType.HasFlag(MicrowaveRecipeType.Oven)) { if (recipe.SecretRecipe) AppendMachineTexture("/Textures/_NF/Structures/Machines/oven_syndie.rsi", "composite_off"); else AppendMachineTexture("/Textures/_NF/Structures/Machines/oven.rsi", "composite_off"); processingTypes.Add(Loc.GetString("guidebook-food-processing-type-oven")); } if (recipeType.HasFlag(MicrowaveRecipeType.Assembler)) { AppendMachineTexture("/Textures/_NF/Structures/Machines/assembler.rsi", "assembler"); processingTypes.Add(Loc.GetString("guidebook-food-processing-type-assembler")); } if (recipeType.HasFlag(MicrowaveRecipeType.MedicalAssembler)) { AppendMachineTexture("/Textures/_NF/Structures/Machines/medical_assembler.rsi", "mediwave-base"); processingTypes.Add(Loc.GetString("guidebook-food-processing-type-medical-assembler")); } var processingTypeString = string.Join('/', processingTypes); var msg = new FormattedMessage(); msg.AddMarkupOrThrow(Loc.GetString("guidebook-food-processing-cooking", ("processingTypes", processingTypeString), ("time", recipe.CookTime))); msg.Pop(); // End Frontier: multiple processing methods per recipe CookTimeLabel.SetMessage(msg); } // Frontier: convenience function to add a machine to the recipe private void AppendMachineTexture(string path, string state) { var machineTexture = new TextureRect(); machineTexture.Texture = _sprite.Frame0(new SpriteSpecifier.Rsi(new ResPath(path), state)); Machines.AddChild(machineTexture); } // End Frontier private void GenerateControl(FoodRecipePrototype recipe) { GenerateHeader(recipe); GenerateIngredients(recipe); GenerateCookTime(recipe); } }