mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
* 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>
285 lines
11 KiB
C#
285 lines
11 KiB
C#
using System.Linq;
|
|
using Content.Shared.Kitchen.Components;
|
|
using Content.Shared.Random.Helpers;
|
|
|
|
namespace Content.Shared.Kitchen.EntitySystems;
|
|
|
|
public abstract partial class MicrowaveSystem
|
|
{
|
|
/// <summary>
|
|
/// Adds temperature to every item in the microwave based on the time it took to microwave.
|
|
/// </summary>
|
|
/// <param name="ent">The microwave entity.</param>
|
|
/// <param name="time">The heating time that has elapsed, in seconds.</param>
|
|
private void AddTemperature(Entity<MicrowaveComponent> ent, float time)
|
|
{
|
|
var component = ent.Comp;
|
|
var heatToAdd = time * component.DeltaHeat;
|
|
var objHeatToAdd = heatToAdd * component.ObjectHeatMultiplier;
|
|
|
|
// TODO: Divide heat amongst contents?
|
|
foreach (var entity in GetMicrowaveContents(ent.AsNullable()))
|
|
{
|
|
_temperature.ChangeHeat(entity, objHeatToAdd);
|
|
|
|
foreach (var (_, soln) in Solution.EnumerateSolutions(entity))
|
|
{
|
|
var solution = soln.Comp.Solution;
|
|
if (solution.Temperature > component.TemperatureUpperThreshold)
|
|
continue;
|
|
|
|
Solution.AddThermalEnergy(soln, heatToAdd);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to roll random "malfunction" events on a malfunctioning microwave.
|
|
/// </summary>
|
|
protected virtual void RollMalfunction(Entity<MicrowaveComponent> ent)
|
|
{
|
|
if (SharedRandomExtensions.PredictedProb(Timing, ent.Comp.ExplosionChance, GetNetEntity(ent)))
|
|
Explode(ent.AsNullable());
|
|
}
|
|
|
|
public virtual void Explode(Entity<MicrowaveComponent?> ent)
|
|
{
|
|
if (!MicrowaveQuery.Resolve(ent.Owner, ref ent.Comp))
|
|
return;
|
|
|
|
ent.Comp.Broken = true;
|
|
DirtyField(ent.AsNullable(), nameof(ent.Comp.Broken));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start up the microwave. This processes each item in the microwave to experience microwave "on-cooking"
|
|
/// effects, attempts to retrieve a microwave recipe with its valid ingredients, and activates the
|
|
/// microwave visually.
|
|
/// </summary>
|
|
public void StartCooking(Entity<MicrowaveComponent> microwave, EntityUid? user)
|
|
{
|
|
if (!HasContents(microwave.AsNullable())
|
|
|| IsActiveMicrowave(microwave.AsNullable())
|
|
|| !_power.IsPowered(microwave.Owner))
|
|
return;
|
|
|
|
var contents = GetMicrowaveContents(microwave.AsNullable());
|
|
var malfunctioning = false;
|
|
var shouldContinue = TryStartMicrowavingContents(microwave,
|
|
contents,
|
|
user,
|
|
ref malfunctioning,
|
|
out var ingredientContents);
|
|
|
|
if (!shouldContinue)
|
|
return;
|
|
|
|
var ingredients = GetTotalIngredients(ingredientContents);
|
|
var cookTime = microwave.Comp.CurrentCookTimerTime;
|
|
var recipe = GetRecipe(microwave, ingredients, cookTime);
|
|
|
|
ActivateMicrowave(microwave, recipe, malfunctioning, user);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts up the microwave cooking operation, setting the starting time and recipe of the microwave.
|
|
/// </summary>
|
|
/// <param name="microwave">The microwave entity.</param>
|
|
/// <param name="recipe">The recipe and portion count associated with this operaton.</param>
|
|
/// <param name="malfunctioning">Whether or not this microwave is malfunctioning.</param>
|
|
/// <param name="user">The entity that is activating the microwave.</param>
|
|
private void ActivateMicrowave(Entity<MicrowaveComponent> microwave,
|
|
PortionedRecipe? recipe,
|
|
bool malfunctioning,
|
|
EntityUid? user)
|
|
{
|
|
var uid = microwave.Owner;
|
|
var component = microwave.Comp;
|
|
var curTime = Timing.CurTime;
|
|
var cookTime = component.CurrentCookTimerTime * component.CookTimeMultiplier;
|
|
|
|
Audio.PlayPredicted(component.BeginCookingSound, uid, user);
|
|
|
|
var activeComp = new ActiveMicrowaveComponent
|
|
{
|
|
PortionedRecipe = recipe,
|
|
TotalTime = component.CurrentCookTimerTime,
|
|
CookTimeEnd = curTime + TimeSpan.FromSeconds(cookTime),
|
|
Malfunctioning = malfunctioning,
|
|
NextMalfunction = malfunctioning
|
|
? curTime + component.MalfunctionInterval
|
|
: TimeSpan.Zero,
|
|
};
|
|
|
|
AddComp(uid, activeComp);
|
|
UpdateUI(microwave.AsNullable());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Iterates over the contents of a microwave and performs some on-microwaved effects.
|
|
/// Plastic items will melt and turn into burned messes.
|
|
/// Metal items will cause the microwave to malfunction.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This also raises a BeingMicrowavedEvent on each item in the microwave. The result of
|
|
/// this event may cause us to exit early and proceed with cooking - for example, an
|
|
/// entity that causes the microwave to explode when microwaved.
|
|
///
|
|
/// If cooking is not cancelled, the items inside will gain `ActiveMicrowaveComponent.`.
|
|
/// </remarks>
|
|
/// <param name="microwave">The microwave entity.</param>
|
|
/// <param name="contents">The contents of the microwave.</param>
|
|
/// <param name="user">The entity that is activating the microwave.</param>
|
|
/// <param name="malfunctioning">Whether or not the microwave is malfunctioning.</param>
|
|
/// <param name="ingredientContents">A list of entities usable as ingredients.</param>
|
|
/// <returns>Wheteher or not we can proceed to use the microwave.</returns>
|
|
private bool TryStartMicrowavingContents(Entity<MicrowaveComponent> microwave,
|
|
IReadOnlyList<EntityUid> contents,
|
|
EntityUid? user,
|
|
ref bool malfunctioning,
|
|
out List<EntityUid> ingredientContents)
|
|
{
|
|
ingredientContents = contents.ToList();
|
|
foreach (var item in contents)
|
|
{
|
|
MicrowaveItem(microwave,
|
|
item,
|
|
user,
|
|
ref malfunctioning,
|
|
out var shouldExit,
|
|
out var shouldRemoveFromIngredients);
|
|
|
|
if (shouldExit)
|
|
return false;
|
|
|
|
if (shouldRemoveFromIngredients)
|
|
ingredientContents.Remove(item);
|
|
}
|
|
|
|
foreach (var item in ingredientContents)
|
|
{
|
|
BeginActivelyMicrowaving(item, microwave.Owner);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processes a single entity in the microwave. This modifies / results in three
|
|
/// different parameters related to the operation: if the microwave should malfunction,
|
|
/// if the microwave should stop, and if the entity is still usable as an ingredient.
|
|
/// </summary>
|
|
/// <param name="microwave">The microwave entity.</param>
|
|
/// <param name="item">The entity being microwaved.</param>
|
|
/// <param name="user">The entity activating the microwave.</param>
|
|
/// <param name="malfunctioning">Whether or not this microwave is malfunctioning.</param>
|
|
/// <param name="shouldStopMicrowave">Whether or not this microwave should stop.</param>
|
|
/// <param name="shouldRemoveFromIngredients">Whether or not this entity remains a valid ingredient.</param>
|
|
private void MicrowaveItem(Entity<MicrowaveComponent> microwave,
|
|
EntityUid item,
|
|
EntityUid? user,
|
|
ref bool malfunctioning,
|
|
out bool shouldStopMicrowave,
|
|
out bool shouldRemoveFromIngredients)
|
|
{
|
|
shouldStopMicrowave = false;
|
|
shouldRemoveFromIngredients = false;
|
|
|
|
// Special item-in-microwave interactions. Certain "being microwaved' interactions
|
|
// may cancel out any actual cooking, so this may early exit.
|
|
var beingMicrowaved = new BeingMicrowavedEvent(microwave.Owner, user);
|
|
RaiseLocalEvent(item, beingMicrowaved);
|
|
|
|
if (beingMicrowaved.Handled)
|
|
{
|
|
UpdateUI(microwave.AsNullable());
|
|
shouldStopMicrowave = true;
|
|
return;
|
|
}
|
|
|
|
if (_whitelist.IsWhitelistPass(microwave.Comp.MalfunctionWhenCookedWhitelist, item))
|
|
malfunctioning = true;
|
|
|
|
if (_whitelist.IsWhitelistPass(microwave.Comp.BurnWhenCookedWhitelist, item))
|
|
{
|
|
shouldRemoveFromIngredients = true;
|
|
CreateBurnedMess(microwave, item);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Turns a single entity in the microwave into a failed "burned mess" recipe.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This happens to entities that pass <see cref="MicrowaveComponent.BurnWhenCookedWhitelist"/>
|
|
/// when microwaved.
|
|
/// </remarks>
|
|
/// <param name="microwave">The microwave entity.</param>
|
|
/// <param name="item">The entity to burn.</param>
|
|
private void CreateBurnedMess(Entity<MicrowaveComponent> microwave, EntityUid item)
|
|
{
|
|
var entProto = microwave.Comp.FailureResult;
|
|
var coords = Transform(microwave).Coordinates;
|
|
var junk = PredictedSpawnAtPosition(entProto, coords);
|
|
Container.Insert(junk, microwave.Comp.Storage);
|
|
|
|
PredictedDel(item);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Completes a recipe in a microwave, removing its relevant ingredient contents
|
|
/// from the microwave and producing finished dish entities in their place.
|
|
/// </summary>
|
|
/// <param name="microwave">The microwave entity.</param>
|
|
/// <param name="portionedRecipe">The recipe we are using.</param>
|
|
private void SpawnFinishedRecipe(Entity<MicrowaveComponent> microwave, PortionedRecipe portionedRecipe)
|
|
{
|
|
SubtractContents(microwave, portionedRecipe);
|
|
|
|
var coords = Transform(microwave).Coordinates;
|
|
for (var i = 0; i < portionedRecipe.Count; i++)
|
|
{
|
|
if (!ProtoMan.Resolve(portionedRecipe.Recipe, out var recipe))
|
|
continue;
|
|
|
|
PredictedSpawnAtPosition(recipe.Result, coords);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finishes a cooking operation in the microwave, resulting in a finished food recipe,
|
|
/// the ejection of all remaining ingredients, and a sound cue.
|
|
/// </summary>
|
|
/// <param name="ent">The micorawve entity.</param>
|
|
private void CompleteCooking(Entity<ActiveMicrowaveComponent, MicrowaveComponent> ent)
|
|
{
|
|
var active = ent.Comp1;
|
|
var microwave = ent.Comp2;
|
|
var microwaveEnt = (ent.Owner, microwave);
|
|
|
|
// Spawn a finished recipe, if there is one.
|
|
if (active.PortionedRecipe != null)
|
|
SpawnFinishedRecipe(microwaveEnt, active.PortionedRecipe.Value);
|
|
|
|
// TODO: Audio prediction sucks. Predict this properly when audio prediction is less broken
|
|
// https://github.com/space-wizards/RobustToolbox/issues/6436
|
|
if (_net.IsServer)
|
|
Audio.PlayPvs(microwave.FoodDoneSound, ent); // beep... beep... beep
|
|
|
|
// Clean up the microwave.
|
|
Container.EmptyContainer(microwave.Storage);
|
|
StopCooking(microwaveEnt);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes components from a microwave and its contents related to active microwave use.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// When the ActiveMicrowaveComponent is removed, it will trigger <see cref="OnCookEnd"/> on shutdown.
|
|
/// </remarks>
|
|
/// <param name="ent">The microwave entity.</param>
|
|
private void StopCooking(Entity<MicrowaveComponent> ent)
|
|
{
|
|
RemComp<ActiveMicrowaveComponent>(ent);
|
|
}
|
|
}
|