mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-29 23:57:29 +00:00
Fix Nyano systems for solution refactor
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
|
||||
namespace Content.Client.Kitchen.Components
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
|
||||
namespace Content.Client.Kitchen.Components
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Shared.Nyanotrasen.Kitchen.UI;
|
||||
using Robust.Client.GameObjects;
|
||||
using Content.Shared.Kitchen.UI;
|
||||
|
||||
namespace Content.Client.Nyanotrasen.Kitchen.UI
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Content.Shared.Nyanotrasen.Kitchen.UI;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Content.Shared.Kitchen.UI;
|
||||
|
||||
namespace Content.Client.Nyanotrasen.Kitchen.UI
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Client.Kitchen.Components;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
|
||||
namespace Content.Client.Kitchen.Visualizers
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Client.Chemistry.Visualizers;
|
||||
using Content.Client.Kitchen.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
|
||||
namespace Content.Client.Kitchen.Visualizers
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#nullable enable annotations
|
||||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Kitchen.EntitySystems;
|
||||
using Content.Server.Nyanotrasen.Kitchen.Components;
|
||||
using Content.Server.Nyanotrasen.Kitchen.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Reflection;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Medical;
|
||||
using Content.Server.Nutrition.EntitySystems;
|
||||
using Content.Server.Nutrition.Components;
|
||||
@@ -162,13 +163,13 @@ public sealed partial class FelinidSystem : EntitySystem
|
||||
var hairball = EntityManager.SpawnEntity(component.HairballPrototype, Transform(uid).Coordinates);
|
||||
var hairballComp = Comp<HairballComponent>(hairball);
|
||||
|
||||
if (TryComp<BloodstreamComponent>(uid, out var bloodstream))
|
||||
if (TryComp<BloodstreamComponent>(uid, out var bloodstream) && bloodstream.ChemicalSolution.HasValue)
|
||||
{
|
||||
var temp = bloodstream.ChemicalSolution.SplitSolution(20);
|
||||
var temp = _solutionSystem.SplitSolution(bloodstream.ChemicalSolution.Value, 20);
|
||||
|
||||
if (_solutionSystem.TryGetSolution(hairball, hairballComp.SolutionName, out var hairballSolution))
|
||||
{
|
||||
_solutionSystem.TryAddSolution(hairball, hairballSolution, temp);
|
||||
_solutionSystem.TryAddSolution(hairballSolution.Value, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -4,6 +4,7 @@ using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
using Content.Shared.Chemistry.Components;
|
||||
|
||||
namespace Content.Server.Chemistry.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class SolutionRegenerationSwitcherComponent : Component
|
||||
{
|
||||
[DataField("options", required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<Solution> Options = default!;
|
||||
|
||||
[DataField("currentIndex"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int CurrentIndex = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Should the already generated solution be kept when switching?
|
||||
/// </summary>
|
||||
[DataField("keepSolution"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool KeepSolution = false;
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Verbs;
|
||||
|
||||
namespace Content.Server.Chemistry.EntitySystems
|
||||
{
|
||||
public sealed class SolutionRegenerationSwitcherSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly SolutionContainerSystem _solutionSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popups = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_sawmill = Logger.GetSawmill("chemistry");
|
||||
|
||||
SubscribeLocalEvent<SolutionRegenerationSwitcherComponent, GetVerbsEvent<AlternativeVerb>>(AddSwitchVerb);
|
||||
}
|
||||
|
||||
private void AddSwitchVerb(EntityUid uid, SolutionRegenerationSwitcherComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
|
||||
if (component.Options.Count <= 1)
|
||||
return;
|
||||
|
||||
AlternativeVerb verb = new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
SwitchReagent(uid, component, args.User);
|
||||
},
|
||||
Text = Loc.GetString("autoreagent-switch"),
|
||||
Priority = 2
|
||||
};
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void SwitchReagent(EntityUid uid, SolutionRegenerationSwitcherComponent component, EntityUid user)
|
||||
{
|
||||
if (!TryComp<SolutionRegenerationComponent>(uid, out var solutionRegenerationComponent))
|
||||
{
|
||||
_sawmill.Warning($"{ToPrettyString(uid)} has no SolutionRegenerationComponent.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (component.CurrentIndex + 1 == component.Options.Count)
|
||||
component.CurrentIndex = 0;
|
||||
else
|
||||
component.CurrentIndex++;
|
||||
|
||||
if (!_solutionSystem.TryGetSolution(uid, solutionRegenerationComponent.Solution, out var solution))
|
||||
{
|
||||
_sawmill.Error($"Can't get SolutionRegeneration.Solution for {ToPrettyString(uid)}");
|
||||
return;
|
||||
}
|
||||
|
||||
var newSolution = component.Options[component.CurrentIndex];
|
||||
var primaryId = newSolution.GetPrimaryReagentId();
|
||||
if (primaryId == null)
|
||||
{
|
||||
_sawmill.Error($"Can't get PrimaryReagentId for {ToPrettyString(uid)} on index {component.CurrentIndex}.");
|
||||
return;
|
||||
}
|
||||
ReagentPrototype? proto;
|
||||
|
||||
//Only reagents with spritePath property can change appearance of transformable containers!
|
||||
if (!string.IsNullOrWhiteSpace(primaryId?.Prototype))
|
||||
{
|
||||
if (!_prototypeManager.TryIndex(primaryId.Value.Prototype, out proto))
|
||||
{
|
||||
_sawmill.Error($"Can't get get reagent prototype {primaryId} for {ToPrettyString(uid)}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else return;
|
||||
|
||||
// Empty out the current solution.
|
||||
if (!component.KeepSolution)
|
||||
solution.RemoveAllSolution();
|
||||
|
||||
// Replace the generating solution with the newly selected solution.
|
||||
var generated = solutionRegenerationComponent.Generated;
|
||||
generated.RemoveAllSolution();
|
||||
_solutionSystem.TryAddSolution(uid, generated, newSolution);
|
||||
|
||||
_popups.PopupEntity(Loc.GetString("autoregen-switched", ("reagent", proto.LocalizedName)), user, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
|
||||
namespace Content.Server.Kitchen.Components
|
||||
{
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Construction.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Nutrition;
|
||||
using Content.Shared.Nyanotrasen.Kitchen;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
|
||||
using Content.Server.Kitchen.EntitySystems;
|
||||
using Content.Server.Nutrition;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Construction.Prototypes;
|
||||
using Content.Shared.Kitchen.Components;
|
||||
using Content.Shared.Nutrition;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Kitchen.Components
|
||||
namespace Content.Server.Nyanotrasen.Kitchen.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[Access(typeof(DeepFryerSystem))]
|
||||
[Access(typeof(SharedDeepfryerSystem))]
|
||||
// This line appears to be depracted: [ComponentReference(typeof(SharedDeepFryerComponent))]
|
||||
public sealed partial class DeepFryerComponent : SharedDeepFryerComponent
|
||||
{
|
||||
@@ -86,7 +85,7 @@ namespace Content.Server.Kitchen.Components
|
||||
|
||||
/// <summary>
|
||||
/// What reagents are added to tasty deep-fried food?
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("goodReagents")]
|
||||
@@ -94,7 +93,7 @@ namespace Content.Server.Kitchen.Components
|
||||
|
||||
/// <summary>
|
||||
/// What reagents are added to terrible deep-fried food?
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("badReagents")]
|
||||
@@ -102,7 +101,7 @@ namespace Content.Server.Kitchen.Components
|
||||
|
||||
/// <summary>
|
||||
/// What reagents replace every 1 unit of oil spent on frying?
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// JJ Comment: I removed Solution from this. Unsure if I need to replace it with something.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("wasteReagents")]
|
||||
@@ -158,7 +157,7 @@ namespace Content.Server.Kitchen.Components
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("solutionSizeCoefficient")]
|
||||
public FixedPoint2 SolutionSizeCoefficient { get; set; } = 0.5f;
|
||||
public FixedPoint2 SolutionSizeCoefficient { get; set; } = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// What's the maximum amount of solution that should ever be imparted?
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
using System.Text;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Server.Nyanotrasen.Kitchen.Components;
|
||||
using Content.Server.Paper;
|
||||
using Content.Shared.Atmos.Rotting;
|
||||
using Content.Shared.Buckle.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.NPC;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Nyanotrasen.Kitchen.EntitySystems;
|
||||
|
||||
public sealed partial class DeepFryerSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Make an item look deep-fried.
|
||||
/// </summary>
|
||||
private void MakeCrispy(EntityUid item)
|
||||
{
|
||||
EnsureComp<AppearanceComponent>(item);
|
||||
EnsureComp<DeepFriedComponent>(item);
|
||||
|
||||
_appearanceSystem.SetData(item, DeepFriedVisuals.Fried, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Turn a dead mob into food.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is meant to be an irreversible process, similar to gibbing.
|
||||
/// </remarks>
|
||||
public bool TryMakeMobIntoFood(EntityUid mob, MobStateComponent mobStateComponent, bool force = false)
|
||||
{
|
||||
// Don't do anything to mobs until they're dead.
|
||||
if (force || _mobStateSystem.IsDead(mob, mobStateComponent))
|
||||
{
|
||||
RemComp<ActiveNPCComponent>(mob);
|
||||
RemComp<AtmosExposedComponent>(mob);
|
||||
RemComp<BarotraumaComponent>(mob);
|
||||
RemComp<BuckleComponent>(mob);
|
||||
RemComp<GhostTakeoverAvailableComponent>(mob);
|
||||
RemComp<InternalsComponent>(mob);
|
||||
RemComp<PerishableComponent>(mob);
|
||||
RemComp<RespiratorComponent>(mob);
|
||||
RemComp<RottingComponent>(mob);
|
||||
|
||||
// Ensure it's Food here, so it passes the whitelist.
|
||||
var mobFoodComponent = EnsureComp<FoodComponent>(mob);
|
||||
_solutionContainerSystem.EnsureSolution(mob, mobFoodComponent.Solution, out var alreadyHadFood);
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(mob, mobFoodComponent.Solution, out var mobFoodSolution))
|
||||
return false;
|
||||
|
||||
// This line here is mainly for mice, because they have a food
|
||||
// component that mirrors how much blood they have, which is
|
||||
// used for the reagent grinder.
|
||||
if (alreadyHadFood)
|
||||
_solutionContainerSystem.RemoveAllSolution(mobFoodSolution.Value);
|
||||
|
||||
if (TryComp<BloodstreamComponent>(mob, out var bloodstreamComponent) && bloodstreamComponent.ChemicalSolution != null)
|
||||
{
|
||||
// Fry off any blood into protein.
|
||||
var bloodSolution = bloodstreamComponent.BloodSolution;
|
||||
var solPresent = bloodSolution!.Value.Comp.Solution.Volume;
|
||||
_solutionContainerSystem.RemoveReagent(bloodSolution.Value, "Blood", FixedPoint2.MaxValue);
|
||||
var bloodRemoved = solPresent - bloodSolution.Value.Comp.Solution.Volume;
|
||||
|
||||
var proteinQuantity = bloodRemoved * BloodToProteinRatio;
|
||||
mobFoodSolution.Value.Comp.Solution.MaxVolume += proteinQuantity;
|
||||
_solutionContainerSystem.TryAddReagent(mobFoodSolution.Value, "Protein", proteinQuantity);
|
||||
|
||||
// This is a heuristic. If you had blood, you might just taste meaty.
|
||||
if (bloodRemoved > FixedPoint2.Zero)
|
||||
EnsureComp<FlavorProfileComponent>(mob).Flavors.Add(MobFlavorMeat);
|
||||
|
||||
// Bring in whatever chemicals they had in them too.
|
||||
mobFoodSolution.Value.Comp.Solution.MaxVolume +=
|
||||
bloodstreamComponent.ChemicalSolution.Value.Comp.Solution.Volume;
|
||||
_solutionContainerSystem.AddSolution(mobFoodSolution.Value,
|
||||
bloodstreamComponent.ChemicalSolution.Value.Comp.Solution);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make an item actually edible.
|
||||
/// </summary>
|
||||
private void MakeEdible(EntityUid uid, DeepFryerComponent component, EntityUid item, FixedPoint2 solutionQuantity)
|
||||
{
|
||||
if (!TryComp<DeepFriedComponent>(item, out var deepFriedComponent))
|
||||
{
|
||||
_sawmill.Error($"{ToPrettyString(item)} is missing the DeepFriedComponent before being made Edible.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove any components that wouldn't make sense anymore.
|
||||
RemComp<ButcherableComponent>(item);
|
||||
|
||||
if (TryComp<PaperComponent>(item, out var paperComponent))
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
for (var i = 0; i < paperComponent.Content.Length; ++i)
|
||||
{
|
||||
var uchar = paperComponent.Content.Substring(i, 1);
|
||||
|
||||
if (uchar == "\n" || _random.Prob(0.4f))
|
||||
stringBuilder.Append(uchar);
|
||||
else
|
||||
stringBuilder.Append("x");
|
||||
}
|
||||
|
||||
paperComponent.Content = stringBuilder.ToString();
|
||||
}
|
||||
|
||||
var foodComponent = EnsureComp<FoodComponent>(item);
|
||||
var extraSolution = new Solution();
|
||||
if (TryComp(item, out FlavorProfileComponent? flavorProfileComponent))
|
||||
{
|
||||
HashSet<string> goodFlavors = new(flavorProfileComponent.Flavors);
|
||||
goodFlavors.IntersectWith(component.GoodFlavors);
|
||||
|
||||
HashSet<string> badFlavors = new(flavorProfileComponent.Flavors);
|
||||
badFlavors.IntersectWith(component.BadFlavors);
|
||||
|
||||
deepFriedComponent.PriceCoefficient = Math.Max(0.01f,
|
||||
1.0f
|
||||
+ goodFlavors.Count * component.GoodFlavorPriceBonus
|
||||
- badFlavors.Count * component.BadFlavorPriceMalus);
|
||||
|
||||
if (goodFlavors.Count > 0)
|
||||
{
|
||||
foreach (var reagent in component.GoodReagents)
|
||||
{
|
||||
extraSolution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * goodFlavors.Count);
|
||||
|
||||
// Mask the taste of "medicine."
|
||||
flavorProfileComponent.IgnoreReagents.Add(reagent.Reagent.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (badFlavors.Count > 0)
|
||||
{
|
||||
foreach (var reagent in component.BadReagents)
|
||||
{
|
||||
extraSolution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * badFlavors.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flavorProfileComponent = EnsureComp<FlavorProfileComponent>(item);
|
||||
// TODO: Default flavor?
|
||||
}
|
||||
|
||||
// Make sure there's enough room for the fryer solution.
|
||||
var foodSolution = _solutionContainerSystem.EnsureSolution(item, foodComponent.Solution);
|
||||
if (!_solutionContainerSystem.TryGetSolution(item, foodSolution.Name, out var foodContainer))
|
||||
return;
|
||||
|
||||
// The solution quantity is used to give the fried food an extra
|
||||
// buffer too, to support injectables or condiments.
|
||||
foodSolution.MaxVolume = 2 * solutionQuantity + foodSolution.Volume + extraSolution.Volume;
|
||||
_solutionContainerSystem.AddSolution(foodContainer.Value,
|
||||
component.Solution.SplitSolution(solutionQuantity));
|
||||
_solutionContainerSystem.AddSolution(foodContainer.Value, extraSolution);
|
||||
_solutionContainerSystem.UpdateChemicals(foodContainer.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Nyanotrasen.Kitchen.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Nyanotrasen.Kitchen.UI;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Tools.Components;
|
||||
|
||||
namespace Content.Server.Nyanotrasen.Kitchen.EntitySystems;
|
||||
|
||||
public sealed partial class DeepFryerSystem
|
||||
{
|
||||
public bool CanInsertItem(EntityUid uid, DeepFryerComponent component, EntityUid item)
|
||||
{
|
||||
// Keep this consistent with the checks in TryInsertItem.
|
||||
return HasComp<ItemComponent>(item) &&
|
||||
!HasComp<StorageComponent>(item) &&
|
||||
component.Storage.ContainedEntities.Count < component.StorageMaxEntities;
|
||||
}
|
||||
|
||||
private bool TryInsertItem(EntityUid uid, DeepFryerComponent component, EntityUid user, EntityUid item)
|
||||
{
|
||||
if (!HasComp<ItemComponent>(item))
|
||||
{
|
||||
_popupSystem.PopupEntity(
|
||||
Loc.GetString("deep-fryer-interact-using-not-item"),
|
||||
uid,
|
||||
user);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HasComp<StorageComponent>(item))
|
||||
{
|
||||
_popupSystem.PopupEntity(
|
||||
Loc.GetString("deep-fryer-storage-no-fit",
|
||||
("item", item)),
|
||||
uid,
|
||||
user);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (component.Storage.ContainedEntities.Count >= component.StorageMaxEntities)
|
||||
{
|
||||
_popupSystem.PopupEntity(
|
||||
Loc.GetString("deep-fryer-storage-full"),
|
||||
uid,
|
||||
user);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_handsSystem.TryDropIntoContainer(user, item, component.Storage))
|
||||
return false;
|
||||
|
||||
AfterInsert(uid, component, item);
|
||||
|
||||
_adminLogManager.Add(LogType.Action, LogImpact.Low,
|
||||
$"{ToPrettyString(user)} put {ToPrettyString(item)} inside {ToPrettyString(uid)}.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, DeepFryerComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
// By default, allow entities with SolutionTransfer or Tool
|
||||
// components to perform their usual actions. Inserting them (if
|
||||
// the chef really wants to) will be supported through the UI.
|
||||
if (HasComp<SolutionTransferComponent>(args.Used) ||
|
||||
HasComp<ToolComponent>(args.Used))
|
||||
return;
|
||||
|
||||
if (TryInsertItem(uid, component, args.User, args.Used))
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnInsertItem(EntityUid uid, DeepFryerComponent component, DeepFryerInsertItemMessage args)
|
||||
{
|
||||
var user = args.Session.AttachedEntity;
|
||||
|
||||
if (user == null ||
|
||||
!TryComp<HandsComponent>(user, out var handsComponent) ||
|
||||
handsComponent.ActiveHandEntity == null)
|
||||
return;
|
||||
|
||||
if (handsComponent.ActiveHandEntity != null)
|
||||
TryInsertItem(uid, component, user.Value, handsComponent.ActiveHandEntity.Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Kitchen.Components;
|
||||
using Content.Server.Nyanotrasen.Kitchen.Components;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.Nyanotrasen.Kitchen.EntitySystems;
|
||||
|
||||
public sealed partial class DeepFryerSystem
|
||||
{
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var component in EntityManager.EntityQuery<DeepFryerComponent>())
|
||||
{
|
||||
var uid = component.Owner;
|
||||
|
||||
if (_gameTimingSystem.CurTime < component.NextFryTime ||
|
||||
!_powerReceiverSystem.IsPowered(uid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateNextFryTime(uid, component);
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(uid, component.Solution.Name, out var solution))
|
||||
continue;
|
||||
|
||||
// Heat the vat solution and contained entities.
|
||||
_solutionContainerSystem.SetTemperature(solution.Value, component.PoweredTemperature);
|
||||
|
||||
foreach (var item in component.Storage.ContainedEntities)
|
||||
CookItem(uid, component, item);
|
||||
|
||||
// Do something bad if there's enough heat but not enough oil.
|
||||
var oilVolume = GetOilVolume(uid, component);
|
||||
|
||||
if (oilVolume < component.SafeOilVolume)
|
||||
{
|
||||
foreach (var item in component.Storage.ContainedEntities.ToArray())
|
||||
BurnItem(uid, component, item);
|
||||
|
||||
if (oilVolume > FixedPoint2.Zero)
|
||||
{
|
||||
//JJ Comment - this code block makes the Linter fail, and doesn't seem to be necessary with the changes I made.
|
||||
foreach (var reagent in component.Solution.Contents.ToArray())
|
||||
{
|
||||
_prototypeManager.TryIndex<ReagentPrototype>(reagent.Reagent.ToString(), out var proto);
|
||||
|
||||
foreach (var effect in component.UnsafeOilVolumeEffects)
|
||||
{
|
||||
effect.Effect(new ReagentEffectArgs(uid,
|
||||
null,
|
||||
component.Solution,
|
||||
proto!,
|
||||
reagent.Quantity,
|
||||
EntityManager,
|
||||
null,
|
||||
1f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
component.Solution.RemoveAllSolution();
|
||||
|
||||
_popupSystem.PopupEntity(
|
||||
Loc.GetString("deep-fryer-oil-volume-low",
|
||||
("deepFryer", uid)),
|
||||
uid,
|
||||
PopupType.SmallCaution);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// We only alert the chef that there's a problem with oil purity
|
||||
// if there's anything to cook beyond this point.
|
||||
if (!component.Storage.ContainedEntities.Any())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (GetOilPurity(uid, component) < component.FryingOilThreshold)
|
||||
{
|
||||
_popupSystem.PopupEntity(
|
||||
Loc.GetString("deep-fryer-oil-purity-low",
|
||||
("deepFryer", uid)),
|
||||
uid,
|
||||
Filter.Pvs(uid, PvsWarningRange),
|
||||
true);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var item in component.Storage.ContainedEntities.ToArray())
|
||||
DeepFry(uid, component, item);
|
||||
|
||||
// After the round of frying, replace the spent oil with a
|
||||
// waste product.
|
||||
if (component.WasteToAdd > FixedPoint2.Zero)
|
||||
{
|
||||
foreach (var reagent in component.WasteReagents)
|
||||
component.Solution.AddReagent(reagent.Reagent.ToString(), reagent.Quantity * component.WasteToAdd);
|
||||
|
||||
component.WasteToAdd = FixedPoint2.Zero;
|
||||
|
||||
_solutionContainerSystem.UpdateChemicals(solution.Value, true);
|
||||
}
|
||||
|
||||
UpdateUserInterface(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAmbientSound(EntityUid uid, DeepFryerComponent component)
|
||||
{
|
||||
_ambientSoundSystem.SetAmbience(uid, HasBubblingOil(uid, component));
|
||||
}
|
||||
|
||||
private void UpdateNextFryTime(EntityUid uid, DeepFryerComponent component)
|
||||
{
|
||||
component.NextFryTime = _gameTimingSystem.CurTime + component.FryInterval;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,7 @@ using Content.Server.Access.Systems;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Server.Damage.Components;
|
||||
using Content.Server.Destructible;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Linq;
|
||||
using Content.Server.Botany;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.Psionics;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
@@ -175,7 +176,7 @@ public sealed class OracleSystem : EntitySystem
|
||||
|
||||
sol.AddReagent(reagent, amount);
|
||||
|
||||
_solutionSystem.TryMixAndOverflow(uid, fountainSol, sol, fountainSol.MaxVolume, out var overflowing);
|
||||
_solutionSystem.TryMixAndOverflow(fountainSol.Value, sol, fountainSol.Value.Comp.Solution.MaxVolume, out var overflowing);
|
||||
|
||||
if (overflowing != null && overflowing.Volume > 0)
|
||||
_puddleSystem.TrySpillAt(uid, overflowing, out var _);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Kitchen
|
||||
namespace Content.Shared.Nyanotrasen.Kitchen
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class ClearSlagDoAfterEvent : DoAfterEvent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Kitchen.Components
|
||||
namespace Content.Shared.Nyanotrasen.Kitchen.Components
|
||||
{
|
||||
[NetworkedComponent]
|
||||
public abstract partial class SharedDeepFriedComponent : Component
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Kitchen.Components
|
||||
namespace Content.Shared.Nyanotrasen.Kitchen.Components
|
||||
{
|
||||
public abstract partial class SharedDeepFryerComponent : Component { }
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace Content.Shared.Nyanotrasen.Kitchen;
|
||||
|
||||
public abstract class SharedDeepfryerSystem : EntitySystem
|
||||
{
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Kitchen.UI
|
||||
namespace Content.Shared.Nyanotrasen.Kitchen.UI
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DeepFryerBoundUserInterfaceState : BoundUserInterfaceState
|
||||
|
||||
Reference in New Issue
Block a user