From 3c13f9d43d38f7b49e074823e4af19338195e092 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Mon, 28 Aug 2023 14:27:36 +0300 Subject: [PATCH 01/49] Add instrument type and recipe prototypes --- .../SupaKitchen/CookingRecipePrototype.cs | 54 +++++++++++++++++++ .../SupaKitchen/InstrumentTypePrototype.cs | 16 ++++++ 2 files changed, 70 insertions(+) create mode 100644 Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs create mode 100644 Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs diff --git a/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs b/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs new file mode 100644 index 00000000000000..e308977c42f638 --- /dev/null +++ b/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs @@ -0,0 +1,54 @@ +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; + +namespace Content.Shared.SS220.SupaKitchen; + +[Prototype("cookingRecipe")] +public sealed class CookingRecipePrototype : IPrototype +{ + [ViewVariables] + [IdDataField] + public string ID { get; } = default!; + + [DataField("name")] + private string _name = string.Empty; + + [DataField("reagents", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + private readonly Dictionary _ingsReagents = new(); + + [DataField("solids", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + private readonly Dictionary _ingsSolids = new(); + + [DataField("result", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string Result { get; } = string.Empty; + + [DataField("instrumentType", customTypeSerializer: typeof(PrototypeIdSerializer))] + public string InstrumentType { get; } = string.Empty; + + [DataField("time")] + public uint CookTime { get; } = 5; + + public string Name => Loc.GetString(_name); + + public IReadOnlyDictionary IngredientsReagents => _ingsReagents; + public IReadOnlyDictionary IngredientsSolids => _ingsSolids; + + /// + /// Count the number of ingredients in a recipe for sorting the recipe list. + /// This makes sure that where ingredient lists overlap, the more complex + /// recipe is picked first. + /// + public FixedPoint2 IngredientCount() + { + FixedPoint2 n = 0; + n += _ingsReagents.Count; // number of distinct reagents + foreach (FixedPoint2 i in _ingsSolids.Values) // sum the number of solid ingredients + { + n += i; + } + return n; + } +} diff --git a/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs new file mode 100644 index 00000000000000..8fd61465fb98d0 --- /dev/null +++ b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs @@ -0,0 +1,16 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.SS220.SupaKitchen; + +[Prototype("instrumentType")] +public sealed class InstrumentTypePrototype : IPrototype +{ + [ViewVariables] + [IdDataField] + public string ID { get; } = default!; + + [DataField("name")] + private string _name = string.Empty; + + public string Name => Loc.GetString(_name); +} From a3bfad748a75d2d78fec1fd2855e14337a5e1f35 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Mon, 28 Aug 2023 14:57:18 +0300 Subject: [PATCH 02/49] Added test recipe --- .../Prototypes/SS220/SupaKitchen/Recipes/testrecipe.yml | 9 +++++++++ .../Prototypes/SS220/SupaKitchen/instrumentTypes.yml | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 Resources/Prototypes/SS220/SupaKitchen/Recipes/testrecipe.yml create mode 100644 Resources/Prototypes/SS220/SupaKitchen/instrumentTypes.yml diff --git a/Resources/Prototypes/SS220/SupaKitchen/Recipes/testrecipe.yml b/Resources/Prototypes/SS220/SupaKitchen/Recipes/testrecipe.yml new file mode 100644 index 00000000000000..11dbff230bde66 --- /dev/null +++ b/Resources/Prototypes/SS220/SupaKitchen/Recipes/testrecipe.yml @@ -0,0 +1,9 @@ +- type: cookingRecipe + id: RecipeBun + name: bun recipe + result: FoodBreadBun + instrumentType: microwave + time: 5 + solids: + FoodDough: 1 + FoodApple: 1 \ No newline at end of file diff --git a/Resources/Prototypes/SS220/SupaKitchen/instrumentTypes.yml b/Resources/Prototypes/SS220/SupaKitchen/instrumentTypes.yml new file mode 100644 index 00000000000000..6c84a8e072eeef --- /dev/null +++ b/Resources/Prototypes/SS220/SupaKitchen/instrumentTypes.yml @@ -0,0 +1,3 @@ +- type: instrumentType + id: microwave + name: microwaving \ No newline at end of file From 1a76c0496ed96adb1c2136d683223f3aee46b0b9 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Mon, 28 Aug 2023 17:16:48 +0300 Subject: [PATCH 03/49] Cooking machine implementation start --- .../SupaKitchen/CookingInstrumentSystem.cs | 141 ++++++++++++++++++ .../SupaKitchen/CookingMachineComponent.cs | 14 ++ .../SS220/SupaKitchen/CookingMachineSystem.cs | 24 +++ .../SupaKitchen/CookingInstrumentComponent.cs | 14 ++ .../SupaKitchen/CookingRecipePrototype.cs | 1 + .../SupaKitchen/InstrumentTypePrototype.cs | 1 + .../Structures/Machines/microwave.yml | 23 ++- 7 files changed, 210 insertions(+), 8 deletions(-) create mode 100644 Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs create mode 100644 Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs create mode 100644 Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs create mode 100644 Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs diff --git a/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs b/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs new file mode 100644 index 00000000000000..0252c63eaada18 --- /dev/null +++ b/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs @@ -0,0 +1,141 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Server.Chemistry.Components.SolutionManager; +using Content.Server.Chemistry.EntitySystems; +using Content.Shared.FixedPoint; +using Content.Shared.SS220.SupaKitchen; +using Robust.Server.Containers; +using Robust.Shared.Containers; + +namespace Content.Server.SS220.SupaKitchen; +public sealed class CookingInstrumentSystem : EntitySystem +{ + [Dependency] private readonly ContainerSystem _container = default!; + [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + } + + private void OnInit(EntityUid uid, CookingInstrumentComponent component, ComponentInit ags) + { + component.Storage = _container.EnsureContainer(uid, "cooking_instrument_entity_container"); + } + + public static (CookingRecipePrototype, int) CanSatisfyRecipe( + CookingInstrumentComponent component, + CookingRecipePrototype recipe, + Dictionary solids, + Dictionary reagents, + uint cookingTimer + ) + { + var portions = 0; + + if ( + cookingTimer % recipe.CookTime != 0 + && !component.IgnoreTime + ) + { + //can't be a multiple of this recipe + return (recipe, 0); + } + + foreach (var solid in recipe.IngredientsSolids) + { + if (!solids.ContainsKey(solid.Key)) + return (recipe, 0); + + if (solids[solid.Key] < solid.Value) + return (recipe, 0); + + portions = portions == 0 + ? solids[solid.Key] / solid.Value.Int() + : Math.Min(portions, solids[solid.Key] / solid.Value.Int()); + } + + foreach (var reagent in recipe.IngredientsReagents) + { + if (!reagents.ContainsKey(reagent.Key)) + return (recipe, 0); + + if (reagents[reagent.Key] < reagent.Value) + return (recipe, 0); + + portions = portions == 0 + ? reagents[reagent.Key].Int() / reagent.Value.Int() + : Math.Min(portions, reagents[reagent.Key].Int() / reagent.Value.Int()); + } + + //cook only as many of those portions as time allows + if (!component.IgnoreTime) + portions = (int) Math.Min(portions, cookingTimer / recipe.CookTime); + + + return (recipe, portions); + } + + private void SubtractContents(CookingInstrumentComponent component, Container container, CookingRecipePrototype recipe) + { + var totalReagentsToRemove = new Dictionary(recipe.IngredientsReagents); + + // this is spaghetti ngl + foreach (var item in container.ContainedEntities) + { + if (!TryComp(item, out var solMan)) + continue; + + // go over every solution + foreach (var (_, solution) in solMan.Solutions) + { + foreach (var (reagent, _) in recipe.IngredientsReagents) + { + // removed everything + if (!totalReagentsToRemove.ContainsKey(reagent)) + continue; + + if (!solution.ContainsReagent(reagent)) + continue; + + var quant = solution.GetReagentQuantity(reagent); + + if (quant >= totalReagentsToRemove[reagent]) + { + quant = totalReagentsToRemove[reagent]; + totalReagentsToRemove.Remove(reagent); + } + else + { + totalReagentsToRemove[reagent] -= quant; + } + + _solutionContainer.TryRemoveReagent(item, solution, reagent, quant); + } + } + } + + foreach (var recipeSolid in recipe.IngredientsSolids) + { + for (var i = 0; i < recipeSolid.Value; i++) + { + foreach (var item in container.ContainedEntities) + { + var metaData = MetaData(item); + if (metaData.EntityPrototype == null) + { + continue; + } + + if (metaData.EntityPrototype.ID == recipeSolid.Key) + { + component.Storage.Remove(item); + EntityManager.DeleteEntity(item); + break; + } + } + } + } + } +} diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs new file mode 100644 index 00000000000000..9f1f005f436cdd --- /dev/null +++ b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs @@ -0,0 +1,14 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Robust.Shared.Containers; + +namespace Content.Server.SS220.SupaKitchen; +public sealed partial class CookingMachineComponent : Component +{ + [ViewVariables] + public uint CookingTimer = 0; + + [DataField("maxCookingTimer"), ViewVariables(VVAccess.ReadWrite)] + public uint MaxCookingTimer = 30; + + public Container Storage = default!; +} diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs new file mode 100644 index 00000000000000..317c4b2fd2e605 --- /dev/null +++ b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs @@ -0,0 +1,24 @@ +using Robust.Server.Containers; +using Robust.Shared.Containers; + +namespace Content.Server.SS220.SupaKitchen; +public sealed class CookingMachineSystem : EntitySystem +{ + [Dependency] private readonly ContainerSystem _container = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + } + + private void OnInit(EntityUid uid, CookingMachineComponent component, ComponentInit ags) + { + component.Storage = _container.EnsureContainer(uid, "cooking_instrument_entity_container"); + } + + public static bool HasContents(CookingMachineComponent component) + { + return component.Storage.ContainedEntities.Any(); + } +} diff --git a/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs b/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs new file mode 100644 index 00000000000000..314d5c9ab0dd0b --- /dev/null +++ b/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs @@ -0,0 +1,14 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.SS220.SupaKitchen; +public sealed partial class CookingInstrumentComponent : Component +{ + [DataField("instrumentType", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + [ViewVariables] + public string? InstrumentType; + + [ViewVariables] + [DataField("ignoreTime")] + public bool IgnoreTime = false; +} diff --git a/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs b/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs index e308977c42f638..6e583209c16370 100644 --- a/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs +++ b/Content.Shared/SS220/SupaKitchen/CookingRecipePrototype.cs @@ -1,3 +1,4 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt using Content.Shared.Chemistry.Reagent; using Content.Shared.FixedPoint; using Robust.Shared.Prototypes; diff --git a/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs index 8fd61465fb98d0..1caab1c25d4418 100644 --- a/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs +++ b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs @@ -1,3 +1,4 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt using Robust.Shared.Prototypes; namespace Content.Shared.SS220.SupaKitchen; diff --git a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml index 37b5e50d31dcdb..770bb4cf609673 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml @@ -4,8 +4,13 @@ name: microwave description: It's magic. components: - - type: Microwave - capacity: 10 +# - type: Microwave #SS220 remove default microwave +# capacity: 10 + #SS220 supa kitchen begin + - type: CookingInstrument + instrumentType: microwave + - type: CookingMachine + #SS220 supa kitchen end - type: Appearance - type: GenericVisualizer visuals: @@ -32,8 +37,6 @@ enum.MicrowaveVisualizerLayers.BaseUnlit: True: { visible: true } False: { visible: false } - - type: ActivatableUI - key: enum.MicrowaveUiKey.Key - type: DeviceLinkSink ports: - On @@ -42,10 +45,14 @@ receiveFrequencyId: BasicDevice - type: WirelessNetworkConnection range: 200 - - type: UserInterface - interfaces: - - key: enum.MicrowaveUiKey.Key - type: MicrowaveBoundUserInterface +#SS220 remove default microwave begin +# - type: ActivatableUI +# key: enum.MicrowaveUiKey.Key +# - type: UserInterface +# interfaces: +# - key: enum.MicrowaveUiKey.Key +# type: MicrowaveBoundUserInterface +#SS220 remove default microwave end - type: Physics - type: Fixtures fixtures: From 43001e80a8a02eb7a7d40a7315ce4f0d4828b085 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Mon, 28 Aug 2023 20:36:58 +0300 Subject: [PATCH 04/49] Kitchen development --- .../SupaKitchen/CookingMachineComponent.cs | 3 + .../SS220/SupaKitchen/CookingMachineSystem.cs | 70 ++++++++++++++++++- .../SS220/SupaKitchen/CookingMachineShared.cs | 17 +++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs index 9f1f005f436cdd..ed2fd09ccafcee 100644 --- a/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs +++ b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs @@ -10,5 +10,8 @@ public sealed partial class CookingMachineComponent : Component [DataField("maxCookingTimer"), ViewVariables(VVAccess.ReadWrite)] public uint MaxCookingTimer = 30; + [DataField("broken"), ViewVariables(VVAccess.ReadOnly)] + public bool Broken = false; + public Container Storage = default!; } diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs index 317c4b2fd2e605..704f484d332c69 100644 --- a/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs +++ b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs @@ -1,24 +1,92 @@ +using Content.Server.Hands.Systems; +using Content.Server.Power.Components; +using Content.Shared.Construction.EntitySystems; +using Content.Shared.Destructible; +using Content.Shared.Interaction; +using Content.Shared.Item; +using Content.Shared.Popups; +using Content.Shared.Power; +using Content.Shared.SS220.SupaKitchen; using Robust.Server.Containers; using Robust.Shared.Containers; +using System.Linq; namespace Content.Server.SS220.SupaKitchen; public sealed class CookingMachineSystem : EntitySystem { [Dependency] private readonly ContainerSystem _container = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly HandsSystem _handsSystem = default!; + [Dependency] private readonly SharedContainerSystem _sharedContainer = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnInteractUsing, after: new[] { typeof(AnchorableSystem) }); + SubscribeLocalEvent(OnPowerChanged); + SubscribeLocalEvent(OnBreak); } private void OnInit(EntityUid uid, CookingMachineComponent component, ComponentInit ags) { - component.Storage = _container.EnsureContainer(uid, "cooking_instrument_entity_container"); + component.Storage = _container.EnsureContainer(uid, "cooking_machine_entity_container"); + } + + private void OnPowerChanged(EntityUid uid, CookingMachineComponent component, ref PowerChangedEvent args) + { + if (!args.Powered) + { + SetAppearance(uid, CookingMachineVisualState.Idle, component); + _sharedContainer.EmptyContainer(component.Storage); + } + //UpdateUserInterfaceState(uid, component); + } + + private void OnInteractUsing(EntityUid uid, CookingMachineComponent component, InteractUsingEvent args) + { + if (args.Handled) + return; + if (!(TryComp(uid, out var apc) && apc.Powered)) + { + _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-no-power"), uid, args.User); + return; + } + + if (component.Broken) + { + _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-broken"), uid, args.User); + return; + } + + if (!HasComp(args.Used)) + { + _popupSystem.PopupEntity(Loc.GetString("microwave-component-interact-using-transfer-fail"), uid, args.User); + return; + } + + args.Handled = true; + _handsSystem.TryDropIntoContainer(args.User, args.Used, component.Storage); + //UpdateUserInterfaceState(uid, component); + } + + private void OnBreak(EntityUid uid, CookingMachineComponent component, BreakageEventArgs args) + { + component.Broken = true; + SetAppearance(uid, CookingMachineVisualState.Broken, component); + _sharedContainer.EmptyContainer(component.Storage); + //UpdateUserInterfaceState(uid, component); } public static bool HasContents(CookingMachineComponent component) { return component.Storage.ContainedEntities.Any(); } + + public void SetAppearance(EntityUid uid, CookingMachineVisualState state, CookingMachineComponent component) + { + var display = component.Broken ? CookingMachineVisualState.Broken : state; + _appearance.SetData(uid, PowerDeviceVisuals.VisualState, display); + } } diff --git a/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs b/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs new file mode 100644 index 00000000000000..3765e5ea938d1f --- /dev/null +++ b/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs @@ -0,0 +1,17 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.SS220.SupaKitchen; + +[Serializable, NetSerializable] +public enum CookingMachineVisualState +{ + Idle, + Cooking, + Broken +} + +[Serializable, NetSerializable] +public enum CookingMachineUiKey +{ + Key +} From fdc13935a558f588104f4148435f09085912f5f8 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Tue, 29 Aug 2023 11:25:05 +0300 Subject: [PATCH 05/49] kitchen dev --- .../SupaKitchen/CookingInstrumentSystem.cs | 9 +------- .../SupaKitchen/CookingMachineComponent.cs | 12 +++++++++- .../SS220/SupaKitchen/CookingMachineSystem.cs | 22 ++++++++++++++++--- .../SupaKitchen/CookingInstrumentComponent.cs | 2 +- .../SS220/SupaKitchen/CookingMachineShared.cs | 17 ++++++++++++++ .../SupaKitchen/InstrumentTypePrototype.cs | 4 ++-- 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs b/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs index 0252c63eaada18..766bf0e2ff2a86 100644 --- a/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs +++ b/Content.Server/SS220/SupaKitchen/CookingInstrumentSystem.cs @@ -15,13 +15,6 @@ public sealed class CookingInstrumentSystem : EntitySystem public override void Initialize() { base.Initialize(); - - SubscribeLocalEvent(OnInit); - } - - private void OnInit(EntityUid uid, CookingInstrumentComponent component, ComponentInit ags) - { - component.Storage = _container.EnsureContainer(uid, "cooking_instrument_entity_container"); } public static (CookingRecipePrototype, int) CanSatisfyRecipe( @@ -130,7 +123,7 @@ private void SubtractContents(CookingInstrumentComponent component, Container co if (metaData.EntityPrototype.ID == recipeSolid.Key) { - component.Storage.Remove(item); + container.Remove(item); EntityManager.DeleteEntity(item); break; } diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs index ed2fd09ccafcee..b1f155ff7e0ee9 100644 --- a/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs +++ b/Content.Server/SS220/SupaKitchen/CookingMachineComponent.cs @@ -1,4 +1,5 @@ // © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Shared.SS220.SupaKitchen; using Robust.Shared.Containers; namespace Content.Server.SS220.SupaKitchen; @@ -10,8 +11,17 @@ public sealed partial class CookingMachineComponent : Component [DataField("maxCookingTimer"), ViewVariables(VVAccess.ReadWrite)] public uint MaxCookingTimer = 30; - [DataField("broken"), ViewVariables(VVAccess.ReadOnly)] + [ViewVariables(VVAccess.ReadWrite)] + public float CookTimeRemaining; + + [ViewVariables] + public (CookingRecipePrototype?, int) CurrentlyCookingRecipe; + + [DataField("broken"), ViewVariables] public bool Broken = false; + [DataField("active"), ViewVariables] + public bool Active = false; + public Container Storage = default!; } diff --git a/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs index 704f484d332c69..b9b111e9c1e0f7 100644 --- a/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs +++ b/Content.Server/SS220/SupaKitchen/CookingMachineSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Power; using Content.Shared.SS220.SupaKitchen; using Robust.Server.Containers; +using Robust.Server.GameObjects; using Robust.Shared.Containers; using System.Linq; @@ -19,6 +20,8 @@ public sealed class CookingMachineSystem : EntitySystem [Dependency] private readonly HandsSystem _handsSystem = default!; [Dependency] private readonly SharedContainerSystem _sharedContainer = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly UserInterfaceSystem _userInterface = default!; + public override void Initialize() { base.Initialize(); @@ -41,7 +44,7 @@ private void OnPowerChanged(EntityUid uid, CookingMachineComponent component, re SetAppearance(uid, CookingMachineVisualState.Idle, component); _sharedContainer.EmptyContainer(component.Storage); } - //UpdateUserInterfaceState(uid, component); + UpdateUserInterfaceState(uid, component); } private void OnInteractUsing(EntityUid uid, CookingMachineComponent component, InteractUsingEvent args) @@ -68,7 +71,7 @@ private void OnInteractUsing(EntityUid uid, CookingMachineComponent component, I args.Handled = true; _handsSystem.TryDropIntoContainer(args.User, args.Used, component.Storage); - //UpdateUserInterfaceState(uid, component); + UpdateUserInterfaceState(uid, component); } private void OnBreak(EntityUid uid, CookingMachineComponent component, BreakageEventArgs args) @@ -76,7 +79,7 @@ private void OnBreak(EntityUid uid, CookingMachineComponent component, BreakageE component.Broken = true; SetAppearance(uid, CookingMachineVisualState.Broken, component); _sharedContainer.EmptyContainer(component.Storage); - //UpdateUserInterfaceState(uid, component); + UpdateUserInterfaceState(uid, component); } public static bool HasContents(CookingMachineComponent component) @@ -89,4 +92,17 @@ public void SetAppearance(EntityUid uid, CookingMachineVisualState state, Cookin var display = component.Broken ? CookingMachineVisualState.Broken : state; _appearance.SetData(uid, PowerDeviceVisuals.VisualState, display); } + + public void UpdateUserInterfaceState(EntityUid uid, CookingMachineComponent component) + { + var ui = _userInterface.GetUiOrNull(uid, CookingMachineUiKey.Key); + if (ui == null) + return; + + UserInterfaceSystem.SetUiState(ui, new CookingMachineUpdateUserInterfaceState( + component.Storage.ContainedEntities.ToArray(), + component.Active, + component.CookingTimer + )); + } } diff --git a/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs b/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs index 314d5c9ab0dd0b..f3d6ef315e5764 100644 --- a/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs +++ b/Content.Shared/SS220/SupaKitchen/CookingInstrumentComponent.cs @@ -4,7 +4,7 @@ namespace Content.Shared.SS220.SupaKitchen; public sealed partial class CookingInstrumentComponent : Component { - [DataField("instrumentType", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] + [DataField("instrumentType", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))] [ViewVariables] public string? InstrumentType; diff --git a/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs b/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs index 3765e5ea938d1f..0beb0da8860c64 100644 --- a/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs +++ b/Content.Shared/SS220/SupaKitchen/CookingMachineShared.cs @@ -2,6 +2,23 @@ namespace Content.Shared.SS220.SupaKitchen; +[NetSerializable, Serializable] +public sealed class CookingMachineUpdateUserInterfaceState : BoundUserInterfaceState +{ + public EntityUid[] ContainedSolids; + public bool IsMachineBusy; + public uint CurrentCookTime; + + public CookingMachineUpdateUserInterfaceState(EntityUid[] containedSolids, + bool isMachineBusy, uint currentCookTime) + { + ContainedSolids = containedSolids; + IsMachineBusy = isMachineBusy; + CurrentCookTime = currentCookTime; + } + +} + [Serializable, NetSerializable] public enum CookingMachineVisualState { diff --git a/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs index 1caab1c25d4418..c3c8914e6c0f7d 100644 --- a/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs +++ b/Content.Shared/SS220/SupaKitchen/InstrumentTypePrototype.cs @@ -3,8 +3,8 @@ namespace Content.Shared.SS220.SupaKitchen; -[Prototype("instrumentType")] -public sealed class InstrumentTypePrototype : IPrototype +[Prototype("cookingInstrumentType")] +public sealed class CookingInstrumentTypePrototype : IPrototype { [ViewVariables] [IdDataField] From 2fd35834c31500d892080899fabff576aa8e9062 Mon Sep 17 00:00:00 2001 From: Artur Zhidkov Date: Tue, 29 Aug 2023 15:34:11 +0300 Subject: [PATCH 06/49] kitchen dev 2 --- .../CookingMachineBoundUserInterface.cs | 119 ++++++++++++++++++ .../SupaKitchen/CookingMachineWindow.xaml | 73 +++++++++++ .../SupaKitchen/CookingMachineWindow.xaml.cs | 51 ++++++++ .../SupaKitchen/CookingMachineComponent.cs | 29 ++++- .../SS220/SupaKitchen/CookingMachineSystem.cs | 45 +++++++ .../SS220/SupaKitchen/CookingMachineShared.cs | 48 ++++++- .../SupaKitchen/CookingRecipePrototype.cs | 2 +- .../Structures/Machines/microwave.yml | 6 + 8 files changed, 368 insertions(+), 5 deletions(-) create mode 100644 Content.Client/SS220/SupaKitchen/CookingMachineBoundUserInterface.cs create mode 100644 Content.Client/SS220/SupaKitchen/CookingMachineWindow.xaml create mode 100644 Content.Client/SS220/SupaKitchen/CookingMachineWindow.xaml.cs diff --git a/Content.Client/SS220/SupaKitchen/CookingMachineBoundUserInterface.cs b/Content.Client/SS220/SupaKitchen/CookingMachineBoundUserInterface.cs new file mode 100644 index 00000000000000..ea143fe4c77e6f --- /dev/null +++ b/Content.Client/SS220/SupaKitchen/CookingMachineBoundUserInterface.cs @@ -0,0 +1,119 @@ +using Content.Shared.Chemistry.Components; +using Content.Shared.SS220.SupaKitchen; +using JetBrains.Annotations; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; + +namespace Content.Client.SS220.SupaKitchen.UI +{ + [UsedImplicitly] + public sealed class CookingMachineBoundUserInterface : BoundUserInterface + { + [ViewVariables] + private CookingMachineWindow? _menu; + + [ViewVariables] + private readonly Dictionary _solids = new(); + + [ViewVariables] + private readonly Dictionary _reagents = new(); + + public CookingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + _menu = new CookingMachineWindow(this); + _menu.OpenCentered(); + _menu.OnClose += Close; + _menu.StartButton.OnPressed += _ => SendMessage(new CookingMachineStartCookMessage()); + _menu.EjectButton.OnPressed += _ => SendMessage(new CookingMachineEjectMessage()); + _menu.IngredientsList.OnItemSelected += args => + { + SendMessage(new CookingMachineEjectSolidIndexedMessage(_solids[args.ItemIndex])); + }; + + _menu.OnCookTimeSelected += (args, buttonIndex) => + { + var actualButton = (CookingMachineWindow.MicrowaveCookTimeButton) args.Button; + SendMessage(new CookingMachineSelectCookTimeMessage(buttonIndex, actualButton.CookTime)); + }; + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (!disposing) + { + return; + } + + _solids.Clear(); + _menu?.Dispose(); + } + + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + if (state is not CookingMachineUpdateUserInterfaceState cState) + { + return; + } + + _menu?.ToggleBusyDisableOverlayPanel(cState.IsMachineBusy); + RefreshContentsDisplay(cState.ContainedSolids); + + if (_menu == null) return; + + var currentlySelectedTimeButton = (Button) _menu.CookTimeButtonVbox.GetChild(cState.ActiveButtonIndex); + currentlySelectedTimeButton.Pressed = true; + var cookTime = cState.ActiveButtonIndex == 0 + ? Loc.GetString("microwave-menu-instant-button") + : cState.CurrentCookTime.ToString(); + _menu.CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", + ("time", cookTime)); + } + + private void RefreshContentsDisplay(EntityUid[] containedSolids) + { + _reagents.Clear(); + + if (_menu == null) return; + + _solids.Clear(); + _menu.IngredientsList.Clear(); + foreach (var entity in containedSolids) + { + if (EntMan.Deleted(entity)) + { + return; + } + + // TODO just use sprite view + + Texture? texture; + if (EntMan.TryGetComponent(entity, out var iconComponent)) + { + texture = EntMan.System().GetIcon(iconComponent); + } + else if (EntMan.TryGetComponent(entity, out var spriteComponent)) + { + texture = spriteComponent.Icon?.Default; + } + else + { + continue; + } + + var solidItem = _menu.IngredientsList.AddItem(EntMan.GetComponent(entity).EntityName, texture); + var solidIndex = _menu.IngredientsList.IndexOf(solidItem); + _solids.Add(solidIndex, entity); + } + } + } +} diff --git a/Content.Client/SS220/SupaKitchen/CookingMachineWindow.xaml b/Content.Client/SS220/SupaKitchen/CookingMachineWindow.xaml new file mode 100644 index 00000000000000..c0418088da211f --- /dev/null +++ b/Content.Client/SS220/SupaKitchen/CookingMachineWindow.xaml @@ -0,0 +1,73 @@ + + + + + + + +