From 3488e577d96322ef58a1675c062531090ef76720 Mon Sep 17 00:00:00 2001
From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Mon, 2 Oct 2023 01:17:50 +0100
Subject: [PATCH] Electric grill (#20661)
---------
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
.../Components/EntityHeaterComponent.cs | 24 ++++
.../Temperature/Systems/EntityHeaterSystem.cs | 111 ++++++++++++++++++
.../Temperature/SharedEntityHeater.cs | 21 ++++
.../en-US/temperature/entity-heater.ftl | 3 +
.../Circuitboards/Machine/production.yml | 14 +++
.../Entities/Structures/Machines/grill.yml | 35 ++++++
.../Entities/Structures/Machines/hotplate.yml | 34 +++---
.../Entities/Structures/Machines/lathe.yml | 1 +
.../Prototypes/Recipes/Lathes/electronics.yml | 8 ++
.../Prototypes/Research/civilianservices.yml | 1 +
.../Machines/electric_grill.rsi/high.png | Bin 0 -> 650 bytes
.../Machines/electric_grill.rsi/icon.png | Bin 0 -> 806 bytes
.../Machines/electric_grill.rsi/low.png | Bin 0 -> 583 bytes
.../Machines/electric_grill.rsi/medium.png | Bin 0 -> 645 bytes
.../Machines/electric_grill.rsi/meta.json | 23 ++++
15 files changed, 258 insertions(+), 17 deletions(-)
create mode 100644 Content.Server/Temperature/Components/EntityHeaterComponent.cs
create mode 100644 Content.Server/Temperature/Systems/EntityHeaterSystem.cs
create mode 100644 Content.Shared/Temperature/SharedEntityHeater.cs
create mode 100644 Resources/Locale/en-US/temperature/entity-heater.ftl
create mode 100644 Resources/Prototypes/Entities/Structures/Machines/grill.yml
create mode 100644 Resources/Textures/Structures/Machines/electric_grill.rsi/high.png
create mode 100644 Resources/Textures/Structures/Machines/electric_grill.rsi/icon.png
create mode 100644 Resources/Textures/Structures/Machines/electric_grill.rsi/low.png
create mode 100644 Resources/Textures/Structures/Machines/electric_grill.rsi/medium.png
create mode 100644 Resources/Textures/Structures/Machines/electric_grill.rsi/meta.json
diff --git a/Content.Server/Temperature/Components/EntityHeaterComponent.cs b/Content.Server/Temperature/Components/EntityHeaterComponent.cs
new file mode 100644
index 0000000000..3a162c20e3
--- /dev/null
+++ b/Content.Server/Temperature/Components/EntityHeaterComponent.cs
@@ -0,0 +1,24 @@
+using Content.Server.Temperature.Systems;
+using Content.Shared.Temperature;
+
+namespace Content.Server.Temperature.Components;
+
+///
+/// Adds thermal energy to entities with placed on it.
+///
+[RegisterComponent, Access(typeof(EntityHeaterSystem))]
+public sealed partial class EntityHeaterComponent : Component
+{
+ ///
+ /// Power used when heating at the high setting.
+ /// Low and medium are 33% and 66% respectively.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float Power = 2400f;
+
+ ///
+ /// Current setting of the heater. If it is off or unpowered it won't heat anything.
+ ///
+ [DataField]
+ public EntityHeaterSetting Setting = EntityHeaterSetting.Off;
+}
diff --git a/Content.Server/Temperature/Systems/EntityHeaterSystem.cs b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs
new file mode 100644
index 0000000000..6da774ba07
--- /dev/null
+++ b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs
@@ -0,0 +1,111 @@
+using Content.Server.Power.Components;
+using Content.Server.Temperature.Components;
+using Content.Shared.Examine;
+using Content.Shared.Placeable;
+using Content.Shared.Popups;
+using Content.Shared.Temperature;
+using Content.Shared.Verbs;
+
+namespace Content.Server.Temperature.Systems;
+
+///
+/// Handles updating and events.
+///
+public sealed class EntityHeaterSystem : EntitySystem
+{
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+ [Dependency] private readonly TemperatureSystem _temperature = default!;
+
+ private readonly int SettingCount = Enum.GetValues(typeof(EntityHeaterSetting)).Length;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnExamined);
+ SubscribeLocalEvent>(OnGetVerbs);
+ SubscribeLocalEvent(OnPowerChanged);
+ }
+
+ public override void Update(float deltaTime)
+ {
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var comp, out var placer, out var power))
+ {
+ if (!power.Powered)
+ continue;
+
+ // don't divide by total entities since its a big grill
+ // excess would just be wasted in the air but that's not worth simulating
+ // if you want a heater thermomachine just use that...
+ var energy = power.PowerReceived * deltaTime;
+ foreach (var ent in placer.PlacedEntities)
+ {
+ _temperature.ChangeHeat(ent, energy);
+ }
+ }
+ }
+
+ private void OnExamined(EntityUid uid, EntityHeaterComponent comp, ExaminedEvent args)
+ {
+ if (!args.IsInDetailsRange)
+ return;
+
+ args.PushMarkup(Loc.GetString("entity-heater-examined", ("setting", comp.Setting)));
+ }
+
+ private void OnGetVerbs(EntityUid uid, EntityHeaterComponent comp, GetVerbsEvent args)
+ {
+ if (!args.CanAccess || !args.CanInteract)
+ return;
+
+ var setting = (int) comp.Setting;
+ setting++;
+ setting %= SettingCount;
+ var nextSetting = (EntityHeaterSetting) setting;
+
+ args.Verbs.Add(new AlternativeVerb()
+ {
+ Text = Loc.GetString("entity-heater-switch-setting", ("setting", nextSetting)),
+ Act = () =>
+ {
+ ChangeSetting(uid, nextSetting, comp);
+ _popup.PopupEntity(Loc.GetString("entity-heater-switched-setting", ("setting", nextSetting)), uid, args.User);
+ }
+ });
+ }
+
+ private void OnPowerChanged(EntityUid uid, EntityHeaterComponent comp, ref PowerChangedEvent args)
+ {
+ // disable heating element glowing layer if theres no power
+ // doesn't actually turn it off since that would be annoying
+ var setting = args.Powered ? comp.Setting : EntityHeaterSetting.Off;
+ _appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
+ }
+
+ private void ChangeSetting(EntityUid uid, EntityHeaterSetting setting, EntityHeaterComponent? comp = null, ApcPowerReceiverComponent? power = null)
+ {
+ if (!Resolve(uid, ref comp, ref power))
+ return;
+
+ comp.Setting = setting;
+ power.Load = SettingPower(setting, comp.Power);
+ _appearance.SetData(uid, EntityHeaterVisuals.Setting, setting);
+ }
+
+ private float SettingPower(EntityHeaterSetting setting, float max)
+ {
+ switch (setting)
+ {
+ case EntityHeaterSetting.Low:
+ return max / 3f;
+ case EntityHeaterSetting.Medium:
+ return max * 2f / 3f;
+ case EntityHeaterSetting.High:
+ return max;
+ default:
+ return 0f;
+ }
+ }
+}
diff --git a/Content.Shared/Temperature/SharedEntityHeater.cs b/Content.Shared/Temperature/SharedEntityHeater.cs
new file mode 100644
index 0000000000..597104e1ba
--- /dev/null
+++ b/Content.Shared/Temperature/SharedEntityHeater.cs
@@ -0,0 +1,21 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Temperature;
+
+[Serializable, NetSerializable]
+public enum EntityHeaterVisuals
+{
+ Setting
+}
+
+///
+/// What heat the heater is set to, if on at all.
+///
+[Serializable, NetSerializable]
+public enum EntityHeaterSetting
+{
+ Off,
+ Low,
+ Medium,
+ High
+}
diff --git a/Resources/Locale/en-US/temperature/entity-heater.ftl b/Resources/Locale/en-US/temperature/entity-heater.ftl
new file mode 100644
index 0000000000..a809d508e7
--- /dev/null
+++ b/Resources/Locale/en-US/temperature/entity-heater.ftl
@@ -0,0 +1,3 @@
+entity-heater-examined = It is set to [color=gray]{$setting}[/color]
+entity-heater-switch-setting = Switch to {$setting}
+entity-heater-switched-setting = Switched to {$setting}
diff --git a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml
index 9ecd8c36f1..9c60e72535 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml
@@ -710,6 +710,20 @@
materialRequirements:
Glass: 1
+- type: entity
+ parent: BaseMachineCircuitboard
+ id: ElectricGrillMachineCircuitboard
+ name: electric grill machine board
+ description: A machine printed circuit board for an electric grill.
+ components:
+ - type: MachineBoard
+ prototype: KitchenElectricGrill
+ requirements:
+ Capacitor: 4
+ materialRequirements:
+ Glass: 2
+ Cable: 5
+
- type: entity
id: StasisBedMachineCircuitboard
parent: BaseMachineCircuitboard
diff --git a/Resources/Prototypes/Entities/Structures/Machines/grill.yml b/Resources/Prototypes/Entities/Structures/Machines/grill.yml
new file mode 100644
index 0000000000..dbd31b3eae
--- /dev/null
+++ b/Resources/Prototypes/Entities/Structures/Machines/grill.yml
@@ -0,0 +1,35 @@
+- type: entity
+ parent: BaseHeaterMachine
+ id: KitchenElectricGrill
+ name: electric grill
+ description: A microwave? No, a real man cooks steaks on a grill!
+ components:
+ - type: Sprite
+ # TODO: draw a sprite
+ sprite: Structures/Machines/electric_grill.rsi
+ drawdepth: SmallObjects
+ snapCardinals: true
+ layers:
+ - state: icon
+ - map: ["enum.EntityHeaterVisuals.Setting"]
+ shader: unshaded
+ visible: false
+ - type: ApcPowerReceiver
+ powerLoad: 0 # off by default
+ - type: EntityHeater
+ - type: ItemPlacer
+ maxEntities: 4 # big grill, many steaks
+ whitelist:
+ components:
+ - Temperature
+ - type: PlaceableSurface
+ - type: Machine
+ board: ElectricGrillMachineCircuitboard
+ - type: GenericVisualizer
+ visuals:
+ enum.EntityHeaterVisuals.Setting:
+ enum.EntityHeaterVisuals.Setting:
+ Off: { visible: false }
+ Low: { visible: true, state: low }
+ Medium: { visible: true, state: medium }
+ High: { visible: true, state: high }
diff --git a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml
index c5ed1de80c..3f2dc05a30 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml
@@ -1,8 +1,8 @@
+# heats an entity or solution placed on it
- type: entity
- id: ChemistryHotplate
+ abstract: true
parent: [ BaseMachinePowered, ConstructibleMachine ]
- name: hotplate
- description: "The descendent of the microwaves, our newest invention in beaker heating technology: the hotplate!"
+ id: BaseHeaterMachine
components:
- type: Transform
anchored: true
@@ -19,6 +19,20 @@
- MidImpassable
- LowImpassable
hard: false
+ - type: ApcPowerReceiver
+ powerLoad: 300
+ - type: Appearance
+ - type: ContainerContainer
+ containers:
+ machine_board: !type:Container
+ machine_parts: !type:Container
+
+- type: entity
+ parent: BaseHeaterMachine
+ id: ChemistryHotplate
+ name: hotplate
+ description: "The descendent of the microwaves, our newest invention in beaker heating technology: the hotplate!"
+ components:
- type: Sprite
sprite: Structures/Machines/hotplate.rsi
drawdepth: SmallObjects
@@ -28,15 +42,6 @@
- state: on
map: ["enum.SolutionHeaterVisuals.IsOn"]
shader: unshaded
- - type: ApcPowerReceiver
- powerLoad: 300
- - type: ItemMapper
- sprite: Structures/Machines/hotplate.rsi
- mapLayers:
- beaker:
- whitelist:
- components:
- - FitsInDispenser
- type: SolutionHeater
- type: ItemPlacer
whitelist:
@@ -47,11 +52,6 @@
positionOffset: 0, 0.25
- type: Machine
board: HotplateMachineCircuitboard
- - type: Appearance
- - type: ContainerContainer
- containers:
- machine_board: !type:Container
- machine_parts: !type:Container
- type: GenericVisualizer
visuals:
enum.SolutionHeaterVisuals.IsOn:
diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
index f0d774c1fd..45cdc33a10 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
@@ -324,6 +324,7 @@
- ReagentGrinderMachineCircuitboard
- HotplateMachineCircuitboard
- MicrowaveMachineCircuitboard
+ - ElectricGrillMachineCircuitboard
- FatExtractorMachineCircuitboard
- SheetifierMachineCircuitboard
- UniformPrinterMachineCircuitboard
diff --git a/Resources/Prototypes/Recipes/Lathes/electronics.yml b/Resources/Prototypes/Recipes/Lathes/electronics.yml
index ebb187121b..bc54c78ca1 100644
--- a/Resources/Prototypes/Recipes/Lathes/electronics.yml
+++ b/Resources/Prototypes/Recipes/Lathes/electronics.yml
@@ -517,6 +517,14 @@
Steel: 100
Glass: 900
+- type: latheRecipe
+ id: ElectricGrillMachineCircuitboard
+ result: ElectricGrillMachineCircuitboard
+ completetime: 4
+ materials:
+ Steel: 100
+ Glass: 900
+
- type: latheRecipe
id: FatExtractorMachineCircuitboard
result: FatExtractorMachineCircuitboard
diff --git a/Resources/Prototypes/Research/civilianservices.yml b/Resources/Prototypes/Research/civilianservices.yml
index b0de5d319b..9208775094 100644
--- a/Resources/Prototypes/Research/civilianservices.yml
+++ b/Resources/Prototypes/Research/civilianservices.yml
@@ -75,6 +75,7 @@
recipeUnlocks: #remove all of these once we have more kitchen equipment
- MicrowaveMachineCircuitboard
- ReagentGrinderMachineCircuitboard
+ - ElectricGrillMachineCircuitboard
- BoozeDispenserMachineCircuitboard
- SodaDispenserMachineCircuitboard
diff --git a/Resources/Textures/Structures/Machines/electric_grill.rsi/high.png b/Resources/Textures/Structures/Machines/electric_grill.rsi/high.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1fe72eb4ffd00765ca37e0c16d6e6643b90557e
GIT binary patch
literal 650
zcmV;50(Jd~P)EzLt>Nxhg23=knh3@O#hiaPGNa4ds-)-ZKyRLP?7R1D@5`n#cZ*
z0}F2Y8Hp>px)2VB=o&wdQY-P`H+yxj>lg#cl&*lKPk2^QwUV$*Lujj{n!G1Gq-5hs
z;S*t>CIbrJntGzaZzg9N{AIEhjVyxI?CHt0aiWcttdz&rCPEI|I=BY8ap6VBd#Y)i8cf4Wo7jwimcAwERWc)7-b{)t2Tx2G{s6uvXX}Fv
zktP5D010qNS#tmY3labT3lag+-G2N4006>CL_t(o!|hYS4Z|=9G*)-$0-mc~qaVNg
z=^E)=EYK|~B)dXL#$YMRhm#@`J7+F%q!hRqFgy6Z%7ee(-}v!dJoqafDC9$IKdmA>
z{H&0P0Q68yd$KBvRljk`^Jmk0VCsm_!-O+bQSy4$6sUcknA0sLZ&sj)7L?sefb~OWMBaub
k;^Z-4AP@)y0)YVG2Tm+i%`5!ly8r+H07*qoM6N<$f~ZC;x&QzG
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Structures/Machines/electric_grill.rsi/icon.png b/Resources/Textures/Structures/Machines/electric_grill.rsi/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..d085b5b4c89e1dbad364646f060e5bffb78c2d87
GIT binary patch
literal 806
zcmV+>1KIqEP)EzLt>Nxhg23=knh3@O#hiaPGNa4ds-)-ZKyRLP?7R1D@5`n#cZ*
z0}F2Y8Hp>px)2VB=o&wdQY-P`H+yxj>lg#cl&*lKPk2^QwUV$*Lujj{n!G1Gq-5hs
z;S*t>CIbrJntGzaZzg9N{AIEhjVyxI?CHt0aiWcttdz&rCPEI|I=BY8ap6VBd#Y)i8cf4Wo7jwimcAwERWc)7-b{)t2Tx2G{s6uvXX}Fv
zktP5D010qNS#tmY3labT3lag+-G2N400CY}L_t(o!((6=>3|WLqokztpB|RpyLS(6
zFAKUP8yg!{Ez8Tx1Jh<^W?(ujEDS}S1(!xsxqm49(~p=)vKXfS_=X8!deS5&xMT1}
z0Vo7OnqPfpWO(=6Q205ORR8GsTRNS@T(!bEQ3f>{Wn
z$xWyvhX8Vxf(1Fq5gEzLt>Nxhg23=knh3@O#hiaPGNa4d<1D-Zu}0Vp)rZg5K5mn%Dl0
z0}CEpOePdvU5G@&^o*ZJsg-yLn7w+}b&bJPT35g_AUvz6T3J}8A-q*qP2Lk8QgVru
z@QJWrlL3WqO+DGS~8iqe|L{1RunxUwvH
zM9wHWQ9=aqlBB{WdCCMN7iDMNeNzqJ5+(5{@>Z#$i6cu+ynazD(lsqPBYIk%JXLe=
z|M#h9W~Q6nok8e-HH^H+2Zu*6F7@t>KlWH?1^Gq~
zJ^%m!32;bRa{vGf5&!@T5&_cPe*6Fc0DwtEK~z}7V_+BsqhJ(_bihcehQ-GEHMrzr
z&t7bysRN*vH{(%KOR6In$*{Z@-M2`g(oCu&n8=AYkOd%1f%rd&CMW1&fQ1Y_%|J_G
z(NK%Vr;7v7gSdsr^g-1SU_g#@BsK#*asjeswPMQ^N002ovPDHLkV1k-j0Ez$r
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Structures/Machines/electric_grill.rsi/medium.png b/Resources/Textures/Structures/Machines/electric_grill.rsi/medium.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed5d431e8d4905d5d5072077014eae21321445e8
GIT binary patch
literal 645
zcmV;00($+4P)EzLt>Nxhg23=knh3@O#hiaPGNa4ds-)-ZKyRLP?7R1D@5`n#cZ*
z0}F2Y8Hp>px)2VB=o&wdQY-P`H+yxj>lg#cl&*lKPk2^QwUV$*Lujj{n!G1Gq-5hs
z;S*t>CIbrJntGzaZzg9N{AIEhjVyxI?CHt0aiWcttdz&rCPEI|I=BY8ap6VBd#Y)i8cf4Wo7jwimcAwERWc)7-b{)t2Tx2G{s6uvXX}Fv
zktP5D010qNS#tmY3labT3lag+-G2N4006y7L_t(o!((6=1;Z7bbd~o6VM6K{X=OQ(
z+J+|VWxo62c67B&G_<@HXdxpAgV-Q3Y$3u#!&o?rgN*`MXy^ctkG)`Qs-*#-q0?~5
z0fRe>)HJ|IhUJ-fluSo+1hV6{QxpP7mQM#_JD`C&SVAQe*%8D5vJxT4a*(A!{2xS<
zVj(pWVJ6U0STsyWz({5mM2P|