mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-29 07:59:01 +01:00
Update TEG NanoUI to TGUI, rename TEG to Stirling engine (#21933)
As title. TEGs are basically just thermopiles IRL; a Stirling engine more accurately reflects its functionality. <img width="551" height="303" alt="image" src="https://github.com/user-attachments/assets/eb0f0c73-c1cc-4a04-85bc-13a413d8ac48" /> --------- Signed-off-by: Batrachophreno <Batrochophreno@gmail.com> Co-authored-by: Cody Brittain <1779662+Generalcamo@users.noreply.github.com>
This commit is contained in:
co-authored by
Cody Brittain
parent
04d2cdd020
commit
eb6c7ff844
@@ -21,6 +21,8 @@
|
||||
var/volume_capacity_used = 0
|
||||
var/stored_energy = 0
|
||||
var/temperature_overlay
|
||||
/// When passing its status to the main Stirling generator, this informs labeling on the TGUI.
|
||||
var/is_hot_loop = FALSE
|
||||
|
||||
density = TRUE
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/machinery/power/generator
|
||||
name = "thermoelectric generator"
|
||||
desc = "It's a high efficiency thermoelectric generator."
|
||||
name = "\improper Stirling engine"
|
||||
desc = "It's a high efficiency Stirling engine. This model produces electricity from the temperature and differential between two gas loops."
|
||||
icon_state = "teg-unassembled"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
@@ -44,11 +44,13 @@
|
||||
circ2 = null
|
||||
return ..()
|
||||
|
||||
//generators connect in dir and reverse_dir(dir) directions
|
||||
//mnemonic to determine circulator/generator directions: the cirulators orbit clockwise around the generator
|
||||
//so a circulator to the NORTH of the generator connects first to the EAST, then to the WEST
|
||||
//and a circulator to the WEST of the generator connects first to the NORTH, then to the SOUTH
|
||||
//note that the circulator's outlet dir is it's always facing dir, and it's inlet is always the reverse
|
||||
/**
|
||||
* Circulators connect in dir and reverse_dir(dir) directions
|
||||
* A mnemonic to determine circulator/generator directions: the cirulators orbit clockwise around the generator.
|
||||
* So a circulator to the NORTH of the generator connects first to the EAST, then to the WEST,
|
||||
* and a circulator to the WEST of the generator connects first to the NORTH, then to the SOUTH.
|
||||
* Note that the circulator's outlet dir is it's always facing dir, and it's inlet is always the reverse
|
||||
*/
|
||||
/obj/machinery/power/generator/proc/reconnect()
|
||||
if(circ1)
|
||||
circ1.temperature_overlay = null
|
||||
@@ -78,11 +80,11 @@
|
||||
/obj/machinery/power/generator/update_icon()
|
||||
icon_state = anchored ? "teg-assembled" : "teg-unassembled"
|
||||
ClearOverlays()
|
||||
if (circ1)
|
||||
if(circ1)
|
||||
circ1.temperature_overlay = null
|
||||
if (circ2)
|
||||
if(circ2)
|
||||
circ2.temperature_overlay = null
|
||||
if (stat & (NOPOWER|BROKEN))
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return TRUE
|
||||
else
|
||||
if (lastgenlev != 0)
|
||||
@@ -91,10 +93,14 @@
|
||||
var/extreme = (lastgenlev > 9) ? "ex" : ""
|
||||
if (circ1.last_temperature < circ2.last_temperature)
|
||||
circ1.temperature_overlay = "circ-[extreme]cold"
|
||||
circ1.is_hot_loop = FALSE
|
||||
circ2.temperature_overlay = "circ-[extreme]hot"
|
||||
circ2.is_hot_loop = TRUE
|
||||
else
|
||||
circ1.temperature_overlay = "circ-[extreme]hot"
|
||||
circ1.is_hot_loop = TRUE
|
||||
circ2.temperature_overlay = "circ-[extreme]cold"
|
||||
circ2.is_hot_loop = FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/generator/process()
|
||||
@@ -102,8 +108,6 @@
|
||||
stored_energy = 0
|
||||
return
|
||||
|
||||
updateDialog()
|
||||
|
||||
var/datum/gas_mixture/air1 = circ1.return_transfer_air()
|
||||
var/datum/gas_mixture/air2 = circ2.return_transfer_air()
|
||||
|
||||
@@ -174,6 +178,7 @@
|
||||
if(attacking_item.tool_behaviour == TOOL_WRENCH)
|
||||
attacking_item.play_tool_sound(get_turf(src), 75)
|
||||
anchored = !anchored
|
||||
balloon_alert(user, "[anchored ? "secure" : "unsecure"]")
|
||||
user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the bolts holding [src.name] to the floor.", \
|
||||
"You [anchored ? "secure" : "unsecure"] the bolts holding [src] to the floor.", \
|
||||
"You hear a ratchet")
|
||||
@@ -193,20 +198,27 @@
|
||||
reconnect()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/power/generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
// this is the data which will be sent to the ui
|
||||
var/vertical = 0
|
||||
if (dir == NORTH || dir == SOUTH)
|
||||
vertical = 1
|
||||
/obj/machinery/power/generator/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
// Interface ID should match your tgui route registration/name.
|
||||
ui = new(user, src, "StirlingEngine", "Stirling Engine")
|
||||
ui.open()
|
||||
|
||||
var/data[0]
|
||||
data["totalOutput"] = effective_gen/1000
|
||||
data["maxTotalOutput"] = max_power/1000
|
||||
data["thermalOutput"] = last_thermal_gen/1000
|
||||
data["circConnected"] = 0
|
||||
/obj/machinery/power/generator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/vertical = FALSE
|
||||
if(dir == NORTH || dir == SOUTH)
|
||||
vertical = TRUE
|
||||
|
||||
data["totalOutput"] = effective_gen / 1000
|
||||
data["maxTotalOutput"] = max_power / 1000
|
||||
data["thermalOutput"] = last_thermal_gen / 1000
|
||||
data["circConnected"] = FALSE
|
||||
|
||||
if(circ1)
|
||||
//The one on the left (or top)
|
||||
// The one on the left (or top)
|
||||
data["primaryDir"] = vertical ? "top" : "left"
|
||||
data["primaryOutput"] = last_circ1_gen/1000
|
||||
data["primaryFlowCapacity"] = circ1.volume_capacity_used*100
|
||||
@@ -214,9 +226,10 @@
|
||||
data["primaryInletTemperature"] = circ1.air1.temperature
|
||||
data["primaryOutletPressure"] = XGM_PRESSURE(circ1.air2)
|
||||
data["primaryOutletTemperature"] = circ1.air2.temperature
|
||||
data["primaryIsHot"] = circ1.is_hot_loop
|
||||
|
||||
if(circ2)
|
||||
//Now for the one on the right (or bottom)
|
||||
// The one on the right (or bottom)
|
||||
data["secondaryDir"] = vertical ? "bottom" : "right"
|
||||
data["secondaryOutput"] = last_circ2_gen/1000
|
||||
data["secondaryFlowCapacity"] = circ2.volume_capacity_used*100
|
||||
@@ -224,25 +237,11 @@
|
||||
data["secondaryInletTemperature"] = circ2.air1.temperature
|
||||
data["secondaryOutletPressure"] = XGM_PRESSURE(circ2.air2)
|
||||
data["secondaryOutletTemperature"] = circ2.air2.temperature
|
||||
data["secondaryIsHot"] = circ2.is_hot_loop
|
||||
|
||||
if(circ1 && circ2)
|
||||
data["circConnected"] = 1
|
||||
else
|
||||
data["circConnected"] = 0
|
||||
data["circConnected"] = (circ1 && circ2) ? TRUE : FALSE
|
||||
|
||||
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "generator.tmpl", "Thermoelectric Generator", 450, 500)
|
||||
// when the ui is first opened this is the data it will use
|
||||
ui.set_initial_data(data)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/generator/power_change()
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Your name.
|
||||
author: Batrachophrenoboocosmomachia
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
|
||||
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- spellcheck: "Renames TEGs to Stirling engines to more accurately reflect their functionality."
|
||||
- refactor: "Refactor of interface for TEG/Stirling Engines to use TGUI instead of NanoUI."
|
||||
@@ -1,19 +0,0 @@
|
||||
<!--
|
||||
Title: Jukebox UI
|
||||
Used In File(s): \code\game\machinery\jukebox.dm
|
||||
-->
|
||||
|
||||
<H3><span class="white">Current track:</span> <span class="average">{{:data.current_track}}</span></H3>
|
||||
<div>
|
||||
{{:helper.link('Play' , 'play', {'play' : 1}, data.playing == 1 ? 'disabled' : null, null)}}
|
||||
{{:helper.link('Stop' , 'stop', {'stop' : 1}, data.playing == 0 ? 'disabled' : null, null)}}
|
||||
</div>
|
||||
|
||||
<H3><span class="white">Available tracks:</span></H3>
|
||||
<div class="itemContent">
|
||||
{{for data.tracks}}
|
||||
<div class="item">
|
||||
{{:helper.link( value.track, 'gear', {'change_track' : 1, 'title' : value.track}, value.track == data.current_track ? 'disabled' : null, null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
@@ -1,24 +0,0 @@
|
||||
The current alert level is:
|
||||
{{if data.alertLevel == 'green'}}
|
||||
<span class='good'>Green</span>
|
||||
{{/if}}
|
||||
{{if data.alertLevel == 'blue'}}
|
||||
<span style='color: rgb(13, 186, 212);font-weight: bold;'>Blue</span>
|
||||
{{/if}}
|
||||
{{if data.alertLevel == 'red'}}
|
||||
<span class='bad'>Red</span>
|
||||
{{/if}}
|
||||
{{if data.alertLevel == 'delta'}}
|
||||
<span class='bad'>DELTA</span>
|
||||
{{/if}}
|
||||
<hr/>
|
||||
<h3>State</h3>
|
||||
{{:helper.link('No Party :(', '', {'state': 'inactive'}, data.active ? null : 'selected')}}
|
||||
{{:helper.link('PARTY!!!', '', {'state': 'active'}, data.active ? 'selected' : null)}}
|
||||
<h3>Timed Lockdown</h3>
|
||||
{{:helper.link('Set', '', {'tmr' : 'set'})}}
|
||||
{{if data.timing}}
|
||||
{{:helper.link('Stop', '', {'tmr' : 'stop'})}}
|
||||
{{/if}}
|
||||
{{if !(data.timing)}}{{:helper.link('Start', '', {'tmr' : 'start'})}}{{/if}}<br/>
|
||||
{{if data.time}}Time Left: {{:data.time}} seconds.{{/if}}
|
||||
@@ -1,36 +0,0 @@
|
||||
<div class="item" style="padding-top: 10px">
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Chamber Pressure:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80) || (data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95) || (data.chamber_pressure > 110) ? 'average' : 'good')}}
|
||||
<div class="statusValue">
|
||||
{{:data.chamber_pressure}} kPa
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" style="padding-top: 10px">
|
||||
<div class="item">
|
||||
<div class="itemContent" style="width: 100%">
|
||||
{{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}}
|
||||
{{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="padding-top: 2px; width: 100%">
|
||||
{{if data.interior_status.state == "open"}}
|
||||
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, 'redButton')}}
|
||||
{{else}}
|
||||
{{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? 'yellowButton' : null)}}
|
||||
{{/if}}
|
||||
{{if data.exterior_status.state == "open"}}
|
||||
{{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, 'redButton')}}
|
||||
{{else}}
|
||||
{{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? 'yellowButton' : null)}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" style="padding-top: 10px; width: 100%">
|
||||
{{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redButton' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,187 @@
|
||||
import {
|
||||
Box,
|
||||
LabeledList,
|
||||
NoticeBox,
|
||||
ProgressBar,
|
||||
Section,
|
||||
Stack,
|
||||
} from '../components';
|
||||
import { useBackend } from '../backend';
|
||||
import { round } from 'common/math';
|
||||
import { Window } from '../layouts';
|
||||
import { BooleanLike } from '../../common/react';
|
||||
|
||||
type Data = {
|
||||
totalOutput: number;
|
||||
maxTotalOutput: number;
|
||||
thermalOutput: number;
|
||||
circConnected: BooleanLike;
|
||||
isHot: BooleanLike;
|
||||
|
||||
primaryDir?: string;
|
||||
primaryOutput?: number;
|
||||
primaryFlowCapacity?: number;
|
||||
primaryInletPressure?: number;
|
||||
primaryInletTemperature?: number;
|
||||
primaryOutletPressure?: number;
|
||||
primaryOutletTemperature?: number;
|
||||
primaryIsHot?: BooleanLike;
|
||||
|
||||
secondaryDir?: string;
|
||||
secondaryOutput?: number;
|
||||
secondaryFlowCapacity?: number;
|
||||
secondaryInletPressure?: number;
|
||||
secondaryInletTemperature?: number;
|
||||
secondaryOutletPressure?: number;
|
||||
secondaryOutletTemperature?: number;
|
||||
secondaryIsHot?: BooleanLike;
|
||||
};
|
||||
|
||||
// Round numbers to one decimal place
|
||||
const f1 = (n?: number) => round(n ?? 0, 0.1);
|
||||
|
||||
export const StirlingEngine = (props, context) => {
|
||||
const { data } = useBackend<Data>(context);
|
||||
const {
|
||||
totalOutput,
|
||||
maxTotalOutput,
|
||||
thermalOutput,
|
||||
circConnected,
|
||||
|
||||
primaryDir,
|
||||
primaryOutput,
|
||||
primaryFlowCapacity,
|
||||
primaryInletPressure,
|
||||
primaryInletTemperature,
|
||||
primaryOutletPressure,
|
||||
primaryOutletTemperature,
|
||||
primaryIsHot,
|
||||
|
||||
secondaryDir,
|
||||
secondaryOutput,
|
||||
secondaryFlowCapacity,
|
||||
secondaryInletPressure,
|
||||
secondaryInletTemperature,
|
||||
secondaryOutletPressure,
|
||||
secondaryOutletTemperature,
|
||||
secondaryIsHot,
|
||||
} = data;
|
||||
|
||||
const bothConnected = !!circConnected;
|
||||
const maxValue = Math.max(maxTotalOutput || 0, 0.001);
|
||||
|
||||
return (
|
||||
<Window width={550} height={300}>
|
||||
<Window.Content scrollable>
|
||||
<Section>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Total Output">
|
||||
<ProgressBar
|
||||
value={totalOutput || 0}
|
||||
minValue={0}
|
||||
maxValue={maxValue}
|
||||
/>
|
||||
<Box mt={0.5}>{f1(totalOutput)} kW</Box>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Thermal Output">
|
||||
{f1(thermalOutput)} kWth
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
|
||||
{bothConnected ? (
|
||||
<Stack>
|
||||
<Stack.Item grow basis={0}>
|
||||
<CirculatorBlock
|
||||
title="Primary Circulator"
|
||||
dir={primaryDir}
|
||||
output={primaryOutput}
|
||||
flowCapacity={primaryFlowCapacity}
|
||||
inletPressure={primaryInletPressure}
|
||||
inletTemperature={primaryInletTemperature}
|
||||
outletPressure={primaryOutletPressure}
|
||||
outletTemperature={primaryOutletTemperature}
|
||||
isHot={primaryIsHot}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow basis={0}>
|
||||
<CirculatorBlock
|
||||
title="Secondary Circulator"
|
||||
dir={secondaryDir}
|
||||
output={secondaryOutput}
|
||||
flowCapacity={secondaryFlowCapacity}
|
||||
inletPressure={secondaryInletPressure}
|
||||
inletTemperature={secondaryInletTemperature}
|
||||
outletPressure={secondaryOutletPressure}
|
||||
outletTemperature={secondaryOutletTemperature}
|
||||
isHot={secondaryIsHot}
|
||||
/>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
) : (
|
||||
<NoticeBox danger>
|
||||
ERROR: Both circulators must be connected!
|
||||
</NoticeBox>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const CirculatorBlock = (props: {
|
||||
title: string;
|
||||
dir?: string;
|
||||
output?: number;
|
||||
flowCapacity?: number;
|
||||
inletPressure?: number;
|
||||
inletTemperature?: number;
|
||||
outletPressure?: number;
|
||||
outletTemperature?: number;
|
||||
isHot?: BooleanLike;
|
||||
}) => {
|
||||
const {
|
||||
title,
|
||||
dir,
|
||||
output,
|
||||
flowCapacity,
|
||||
inletPressure,
|
||||
inletTemperature,
|
||||
outletPressure,
|
||||
outletTemperature,
|
||||
isHot,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Section
|
||||
title={`${title} (${dir ?? '-'})`}
|
||||
fill
|
||||
backgroundColor={
|
||||
isHot ? 'rgba(255, 25, 25, 0.1)' : 'rgba(25, 25, 255, 0.1)'
|
||||
}
|
||||
textColor={isHot ? 'rgb(255, 225, 200)' : 'rgb(200, 225, 255)'}
|
||||
>
|
||||
<Box>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Turbine Output">
|
||||
{f1(output)} kWth
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Flow Capacity">
|
||||
{f1(flowCapacity)} %
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Inlet Pressure">
|
||||
{f1(inletPressure)} kPa
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Inlet Temperature">
|
||||
{f1(inletTemperature)} K
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Outlet Pressure">
|
||||
{f1(outletPressure)} kPa
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Outlet Temperature">
|
||||
{f1(outletTemperature)} K
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Box>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user