CatStation/Content.Client/Guidebook/Controls/GuideMicrowaveEmbed.xaml.cs
portfiend b9b794deef
Microwave Refactor and Prediction (#43129)
* adjust fields of meal recipe prototype

* document microwave recipe datafields

* use file scoped namespace for microwave recipes

* more of this

* localize every microwave recipe

* make microwave system shared

* refactor recipe reagent contents

* refactor recipe solids + add material ingredient datafield

* im making this a bit less silly

* awa

* move this shit out

* move this shit out also

* refactor Wzhzhzh

* im gonna shorten this parameter by 1 actually

* move this into recipes

* make processcontents a little better(?)

* clean imports

* rename a struct

* use cooking ingredients struct

* comment

* use whitelist for this

* unused dependency

* rearranged the parameters of get recipe portions

* rearrange some stuff

* clean up more imports

* move container related functions into separate file

* move this function out of ProcessContents

* prevent microwaves from having items inserted while active

* use IsPowered in microwave system

* use byref syntax and Entity<>

* moving the override up
sorry i like it being up here

* refactor microwave updating

* clean up recipe finish logic

* im renaming this function actually

* move some functions around

* move more stuff around

* some comments

* fix compiler error

* fix the yml of all microwave recipes

* use materials instead of solids for this stuff

* oops

* fix this

* turn microwave sparks into datafield

* move activelymicrowaved events into separate folder

* make UpdateUserInterfaceState use entity only

* rearrange some functions

* move UI functions out

* comment microwave UI stuff

* more comments

* comment recipe functions

* refactor GetTotalIngredients to use an operator

* give CookingIngredients addition methods

* comment the rest of CookingIngredients

* make subtraction functions clearer?

* remove redundant comment

* handle zero/negative ingredient cases

* simplify subtract contents logic

* fix these comments

* typo

* add microwave recipe test

* move active microwave methods

* comment active microwave methods

* comment cooking methods

* comment microwave methods

* change setappearance to use entity<>

* add some public api decorators

* comment all of MicrowaveComponent

* use file-scoped namespace for MicrowaveComponent

* comment

* fix baguette sword

* maybe...?

* oh oops

* document the rest of the owl

* kill the massive YML breaking change

* fix protoman dependency

* move shared microwave stuff to SharedMicrowaveSystem

* fix usings

* move microwave components to shared

* fix up microwave datafields

* move APIs to shared

* move activemicrowave methods to shared

* initialize on shared

* move ui functions to shared

* add actor here

* stuff

* predict microwave update loop

* make clientside microwave system

* adjust the update loop for microwaves

* clean up

* add field deltas to microwaves

* dirty fields instead of whole component

* move this to the partial

* move GetRecipesForMicrowave to shared

* comments

* predict microwave BUI

* oops

* refactor microwave bui update

* move UI messages to shared

* move messages to UI file

* move init to shared

* move container methosd to shared

* oops my using

* move cooking functions into partial

* move cooking methods to shared

* move microwave recipe methods to shared

* move the rest of the microwave events to shared

* update imports

* remove custom type serializer

* better (?) microwave UI prediction

* fix list notations

* OK IT WAS THE DATAFIELDS

* add IOC inject

* dont use IOC for htis

* sealed

* prediction fixes pt1

* make microwave cooking updates more consistent

* datafield tweaks

* test for multiple portions in microwave recipes

* test for multiple recipe portions

* better(?) prediction for malfunctions

* remove redundant comment

* prevent solution reactions in microwave

* cleanup some microwave stuff

* eh i think this should be container actually

* this can be API i think

* reduce system redundancy

* this has to be public

* use resolve pattern for explode

* use GetMicrowaveContents in microwave system

* this can be an API too

* add conversion script for unlocalized recipes

* use EnsureComp instead of AddComp

* suffering

* fix recipe prediction

* fix the audio

* reduce redundant networking

* i think this should be autopaused?

* nevermind we use dynamic portions in the test

* oops i wrote the test wrong

* make lemoon cake take 2 lemoons again
sorry test fail

* rename "materials" to "stacks"
realized theyre different

* add stack guidebook quantities

* Kill audio

* fix lemoon cake recipe for real?

* mark PortionedRecipe as a datadefinition

* fix the microwave timer

* review

* cleanup

* Update SharedMicrowaveSystem.Recipes.cs

* update

* add audio params

* review: inject microwavesystem

* review: named variable

* review: move dependencies

* review: use gametest for recipe test

* review: make access attributes standalone

* rename prototypes and datafields

* review: rename this var

* review: move this function down

* review: remove these scripts

* actually this should stay

* refactor cook time buttons

* review: use a color name for this

* fix timer reset

* Dirty

* review: make ActivelyMicrowavedComponent networked

* review: slarti comments part 1

* review: remove serializable attribute from CookingIngredients

* rename file

* review: more microwave audio boilerplate. yippee!

* review: use resolve pattern for TryGetStackId
i dont like the way this makes the rest of the code look but we ball maybe. i dont know what else to do here

* review: move ui update to constructor

* review: kill LastCookUpdated

* actually i do this instead

* fixed up the PR

* cleanup

* ///

* Update microwave.yml

---------

Co-authored-by: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com>
Co-authored-by: Pok245 <113675512+Pok27@users.noreply.github.com>
2026-10-04 23:38:48 +00:00

225 lines
7.6 KiB
C#

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;
namespace Content.Client.Guidebook.Controls;
/// <summary>
/// Control for embedding a microwave recipe into a guidebook.
/// </summary>
[UsedImplicitly, GenerateTypedNameReferences]
public sealed partial class GuideMicrowaveEmbed : PanelContainer, IDocumentTag, ISearchableControl, IPrototypeRepresentationControl
{
[Dependency] private IPrototypeManager _prototype = default!;
[Dependency] private ILogManager _logManager = default!;
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");
}
public GuideMicrowaveEmbed(string recipe) : this()
{
GenerateControl(_prototype.Index<MicrowaveMealRecipePrototype>(recipe));
}
public GuideMicrowaveEmbed(MicrowaveMealRecipePrototype 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<string, string> 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<MicrowaveMealRecipePrototype>(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(MicrowaveMealRecipePrototype recipe)
{
var entity = _prototype.Index<EntityPrototype>(recipe.Result);
RepresentedPrototype = entity;
IconContainer.AddChild(new GuideEntityEmbed(recipe.Result, false, false));
ResultName.SetMarkup(entity.Name);
ResultDescription.SetMarkup(entity.Description);
}
private void GenerateSolidIngredients(MicrowaveMealRecipePrototype recipe)
{
foreach (var (product, amount) in recipe.Ingredients.Solids.OrderByDescending(p => p.Value))
{
var ingredient = _prototype.Index<EntityPrototype>(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(MicrowaveMealRecipePrototype recipe)
{
foreach (var (product, amount) in recipe.Ingredients.Reagents.OrderByDescending(p => p.Value))
{
var reagent = _prototype.Index<ReagentPrototype>(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 GenerateStackIngredients(MicrowaveMealRecipePrototype recipe)
{
foreach (var (product, amount) in recipe.Ingredients.Stacks.OrderByDescending(p => p.Value))
{
var stack = _prototype.Index(product);
// stack icon
IngredientsGrid.AddChild(new GuideEntityEmbed(stack.Spawn, false, false));
// stack name
var stackName = Loc.GetString(stack.Name);
var stackNameMsg = new FormattedMessage();
stackNameMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-stack-name-display", ("stack", stackName)));
stackNameMsg.Pop();
var stackNameLabel = new RichTextLabel();
stackNameLabel.SetMessage(stackNameMsg);
IngredientsGrid.AddChild(stackNameLabel);
// stack quantity
var stackQuantityMsg = new FormattedMessage();
stackQuantityMsg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-stack-quantity-display", ("amount", amount)));
stackQuantityMsg.Pop();
var stackQuantityLabel = new RichTextLabel();
stackQuantityLabel.SetMessage(stackQuantityMsg);
IngredientsGrid.AddChild(stackQuantityLabel);
}
}
private void GenerateIngredients(MicrowaveMealRecipePrototype recipe)
{
GenerateLiquidIngredients(recipe);
GenerateStackIngredients(recipe);
GenerateSolidIngredients(recipe);
}
private void GenerateCookTime(MicrowaveMealRecipePrototype recipe)
{
var msg = new FormattedMessage();
msg.AddMarkupOrThrow(Loc.GetString("guidebook-microwave-cook-time", ("time", recipe.Time)));
msg.Pop();
CookTimeLabel.SetMessage(msg);
}
private void GenerateControl(MicrowaveMealRecipePrototype recipe)
{
GenerateHeader(recipe);
GenerateIngredients(recipe);
GenerateCookTime(recipe);
}
}