diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index bb4d5ac97c..6bef0499fd 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -913,3 +913,13 @@
req_components = list(
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/matter_bin = 2)
+
+/obj/item/circuitboard/machine/generator
+ name = "Thermo-Electric Generator (Machine Board)"
+ build_path = /obj/machinery/power/generator
+ req_components = list()
+
+/obj/item/circuitboard/machine/circulator
+ name = "Circulator/Heat Exchanger (Machine Board)"
+ build_path = /obj/machinery/atmospherics/components/binary/circulator
+ req_components = list()
\ No newline at end of file
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
index e8007a6608..cf1d0e1866 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm
@@ -1,23 +1,41 @@
//node2, air2, network2 correspond to input
//node1, air1, network1 correspond to output
-
+#define CIRCULATOR_COLD 0
+#define CIRCULATOR_HOT 1
/obj/machinery/atmospherics/components/binary/circulator
name = "circulator/heat exchanger"
desc = "A gas circulator pump and heat exchanger."
- icon_state = "circ1-off"
+ icon_state = "circ-off"
- var/side = CIRC_LEFT
- var/status = 0
+ var/active = FALSE
var/last_pressure_delta = 0
- pipe_flags = PIPING_ONE_PER_TURF
+ pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
density = TRUE
- var/global/const/CIRC_LEFT = 1
- var/global/const/CIRC_RIGHT = 2
+ var/flipped = 0
+ var/mode = CIRCULATOR_HOT
+ var/obj/machinery/power/generator/generator
+
+//default cold circ for mappers
+/obj/machinery/atmospherics/components/binary/circulator/cold
+ mode = CIRCULATOR_COLD
+
+/obj/machinery/atmospherics/components/binary/circulator/Initialize(mapload)
+ .=..()
+ component_parts = list(new /obj/item/circuitboard/machine/circulator)
+
+/obj/machinery/atmospherics/components/binary/circulator/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
+
+/obj/machinery/atmospherics/components/binary/circulator/Destroy()
+ if(generator)
+ disconnectFromGenerator()
+ return ..()
/obj/machinery/atmospherics/components/binary/circulator/proc/return_transfer_air()
@@ -56,11 +74,115 @@
/obj/machinery/atmospherics/components/binary/circulator/update_icon()
if(!is_operational())
- icon_state = "circ[side]-p"
+ icon_state = "circ-p-[flipped]"
else if(last_pressure_delta > 0)
if(last_pressure_delta > ONE_ATMOSPHERE)
- icon_state = "circ[side]-run"
+ icon_state = "circ-run-[flipped]"
else
- icon_state = "circ[side]-slow"
+ icon_state = "circ-slow-[flipped]"
else
- icon_state = "circ[side]-off"
+ icon_state = "circ-off-[flipped]"
+
+/obj/machinery/atmospherics/components/binary/circulator/wrench_act(mob/living/user, obj/item/I)
+ if(!panel_open)
+ return
+ anchored = !anchored
+ I.play_tool_sound(src)
+ if(generator)
+ disconnectFromGenerator()
+ to_chat(user, "You [anchored?"secure":"unsecure"] [src].")
+
+
+ var/obj/machinery/atmospherics/node1 = nodes[1]
+ var/obj/machinery/atmospherics/node2 = nodes[2]
+
+ if(node1)
+ node1.disconnect(src)
+ nodes[1] = null
+ nullifyPipenet(parents[1])
+ if(node2)
+ node2.disconnect(src)
+ nodes[2] = null
+ nullifyPipenet(parents[2])
+
+ if(anchored)
+ SetInitDirections()
+ atmosinit()
+ node1 = nodes[1]
+ if(node1)
+ node1.atmosinit()
+ node1.addMember(src)
+ node2 = nodes[2]
+ if(node2)
+ node2.atmosinit()
+ node2.addMember(src)
+ build_network()
+
+ return TRUE
+
+/obj/machinery/atmospherics/components/binary/circulator/SetInitDirections()
+ switch(dir)
+ if(NORTH, SOUTH)
+ initialize_directions = EAST|WEST
+ if(EAST, WEST)
+ initialize_directions = NORTH|SOUTH
+
+/obj/machinery/atmospherics/components/binary/circulator/getNodeConnects()
+ if(flipped)
+ return list(turn(dir, 270), turn(dir, 90))
+ return list(turn(dir, 90), turn(dir, 270))
+
+/obj/machinery/atmospherics/components/binary/circulator/can_be_node(obj/machinery/atmospherics/target)
+ if(anchored)
+ return ..(target)
+ return FALSE
+
+/obj/machinery/atmospherics/components/binary/circulator/multitool_act(mob/living/user, obj/item/I)
+ if(generator)
+ disconnectFromGenerator()
+ mode = !mode
+ to_chat(user, "You set [src] to [mode?"cold":"hot"] mode.")
+ return TRUE
+
+/obj/machinery/atmospherics/components/binary/circulator/screwdriver_act(mob/user, obj/item/I)
+ panel_open = !panel_open
+ I.play_tool_sound(src)
+ to_chat(user, "You [panel_open?"open":"close"] the panel on [src].")
+ return TRUE
+
+/obj/machinery/atmospherics/components/binary/circulator/crowbar_act(mob/user, obj/item/I)
+ default_deconstruction_crowbar(I)
+ return TRUE
+
+/obj/machinery/atmospherics/components/binary/circulator/on_deconstruction()
+ if(generator)
+ disconnectFromGenerator()
+
+/obj/machinery/atmospherics/components/binary/circulator/proc/disconnectFromGenerator()
+ if(mode)
+ generator.cold_circ = null
+ else
+ generator.hot_circ = null
+ generator.update_icon()
+ generator = null
+
+/obj/machinery/atmospherics/components/binary/circulator/setPipingLayer(new_layer)
+ ..()
+ pixel_x = 0
+ pixel_y = 0
+
+/obj/machinery/atmospherics/components/binary/circulator/verb/circulator_flip()
+ set name = "Flip"
+ set category = "Object"
+ set src in oview(1)
+
+ if(!ishuman(usr))
+ return
+
+ if(anchored)
+ to_chat(usr, "[src] is anchored!")
+ return
+
+ flipped = !flipped
+ to_chat(usr, "You flip [src].")
+ update_icon()
\ No newline at end of file
diff --git a/code/modules/atmospherics/machinery/components/components_base.dm b/code/modules/atmospherics/machinery/components/components_base.dm
index c333651f5a..e31d96a0c2 100644
--- a/code/modules/atmospherics/machinery/components/components_base.dm
+++ b/code/modules/atmospherics/machinery/components/components_base.dm
@@ -73,6 +73,9 @@ Pipenet stuff; housekeeping
P.build_pipeline(src)
/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
+ if(!reference)
+ CRASH("nullifyPipenet(null) called by [type] on [COORD(src)]")
+ return
var/i = parents.Find(reference)
reference.other_airs -= airs[i]
reference.other_atmosmch -= src
diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm
index fb9482841c..bc034ec506 100644
--- a/code/modules/atmospherics/machinery/datum_pipeline.dm
+++ b/code/modules/atmospherics/machinery/datum_pipeline.dm
@@ -129,6 +129,9 @@
/obj/machinery/atmospherics/components/addMember(obj/machinery/atmospherics/A)
var/datum/pipeline/P = returnPipenet(A)
+ if(!P)
+ CRASH("null.addMember() called by [type] on [COORD(src)]")
+ return
P.addMember(A, src)
diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm
index eb6e82a242..04645b2267 100644
--- a/code/modules/power/generator.dm
+++ b/code/modules/power/generator.dm
@@ -8,10 +8,6 @@
var/obj/machinery/atmospherics/components/binary/circulator/cold_circ
var/obj/machinery/atmospherics/components/binary/circulator/hot_circ
- //note: these currently only support EAST and WEST
- var/cold_dir = WEST
- var/hot_dir = EAST
-
var/lastgen = 0
var/lastgenlev = -1
var/lastcirc = "00"
@@ -19,34 +15,18 @@
/obj/machinery/power/generator/Initialize(mapload)
. = ..()
- var/obj/machinery/atmospherics/components/binary/circulator/circpath = /obj/machinery/atmospherics/components/binary/circulator
- cold_circ = locate(circpath) in get_step(src, cold_dir)
- hot_circ = locate(circpath) in get_step(src, hot_dir)
+ find_circs()
connect_to_network()
SSair.atmos_machinery += src
-
- if(cold_circ)
- switch(cold_dir)
- if(EAST)
- cold_circ.side = circpath.CIRC_RIGHT
- if(WEST)
- cold_circ.side = circpath.CIRC_LEFT
- cold_circ.update_icon()
-
- if(hot_circ)
- switch(hot_dir)
- if(EAST)
- hot_circ.side = circpath.CIRC_RIGHT
- if(WEST)
- hot_circ.side = circpath.CIRC_LEFT
- hot_circ.update_icon()
-
- if(!cold_circ || !hot_circ)
- stat |= BROKEN
-
update_icon()
+ component_parts = list(new /obj/item/circuitboard/machine/generator)
+
+/obj/machinery/power/generator/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS )
/obj/machinery/power/generator/Destroy()
+ kill_circs()
SSair.atmos_machinery -= src
return ..()
@@ -61,7 +41,8 @@
if(L != 0)
add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
- add_overlay("teg-oc[lastcirc]")
+ if(hot_circ && cold_circ)
+ add_overlay("teg-oc[lastcirc]")
#define GENRATE 800 // generator output coefficient from Q
@@ -122,7 +103,7 @@
lastgen -= power_output
..()
-/obj/machinery/power/generator/proc/get_menu(include_link = 1)
+/obj/machinery/power/generator/proc/get_menu(include_link = TRUE)
var/t = ""
if(!powernet)
t += "Unable to connect to the power network!"
@@ -147,8 +128,12 @@
t += "Pressure Inlet: [round(hot_circ_air2.return_pressure(), 0.1)] kPa / Outlet: [round(hot_circ_air1.return_pressure(), 0.1)] kPa
"
t += ""
+ else if(!hot_circ && cold_circ)
+ t += "Unable to locate hot circulator!"
+ else if(hot_circ && !cold_circ)
+ t += "Unable to locate cold circulator!"
else
- t += "Unable to locate all parts!"
+ t += "Unable to locate any parts!"
if(include_link)
t += "
Close"
@@ -167,10 +152,81 @@
if( href_list["close"] )
usr << browse(null, "window=teg")
usr.unset_machine()
- return 0
- return 1
+ return FALSE
+ return TRUE
/obj/machinery/power/generator/power_change()
..()
update_icon()
+
+/obj/machinery/power/generator/proc/find_circs()
+ kill_circs()
+ var/list/circs = list()
+ var/obj/machinery/atmospherics/components/binary/circulator/C
+ var/circpath = /obj/machinery/atmospherics/components/binary/circulator
+ if(dir == NORTH || dir == SOUTH)
+ C = locate(circpath) in get_step(src, EAST)
+ if(C && C.dir == WEST)
+ circs += C
+
+ C = locate(circpath) in get_step(src, WEST)
+ if(C && C.dir == EAST)
+ circs += C
+
+ else
+ C = locate(circpath) in get_step(src, NORTH)
+ if(C && C.dir == SOUTH)
+ circs += C
+
+ C = locate(circpath) in get_step(src, SOUTH)
+ if(C && C.dir == NORTH)
+ circs += C
+
+ if(circs.len)
+ for(C in circs)
+ if(C.mode == CIRCULATOR_COLD && !cold_circ)
+ cold_circ = C
+ C.generator = src
+ else if(C.mode == CIRCULATOR_HOT && !hot_circ)
+ hot_circ = C
+ C.generator = src
+
+/obj/machinery/power/generator/wrench_act(mob/living/user, obj/item/I)
+ if(!panel_open)
+ return
+ anchored = !anchored
+ I.play_tool_sound(src)
+ if(!anchored)
+ kill_circs()
+ connect_to_network()
+ to_chat(user, "You [anchored?"secure":"unsecure"] [src].")
+ return TRUE
+
+/obj/machinery/power/generator/multitool_act(mob/living/user, obj/item/I)
+ if(!anchored)
+ return
+ find_circs()
+ to_chat(user, "You update [src]'s circulator links.")
+ return TRUE
+
+/obj/machinery/power/generator/screwdriver_act(mob/user, obj/item/I)
+ panel_open = !panel_open
+ I.play_tool_sound(src)
+ to_chat(user, "You [panel_open?"open":"close"] the panel on [src].")
+ return TRUE
+
+/obj/machinery/power/generator/crowbar_act(mob/user, obj/item/I)
+ default_deconstruction_crowbar(I)
+ return TRUE
+
+/obj/machinery/power/generator/on_deconstruction()
+ kill_circs()
+
+/obj/machinery/power/generator/proc/kill_circs()
+ if(hot_circ)
+ hot_circ.generator = null
+ hot_circ = null
+ if(cold_circ)
+ cold_circ.generator = null
+ cold_circ = null
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index 618f955450..d07a922fc7 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -10,6 +10,22 @@
category = list ("Engineering Machinery")
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+/datum/design/board/circulator
+ name = "Machine Design (Circulator Board)"
+ desc = "The circuit board for a circulator."
+ id = "circulator"
+ build_path = /obj/machinery/atmospherics/components/binary/circulator
+ category = list ("Engineering Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+
+/datum/design/board/teg
+ name = "Machine Design (TEG Board)"
+ desc = "The circuit board for a TEG."
+ id = "teg"
+ build_path = /obj/machinery/power/generator
+ category = list ("Engineering Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+
/datum/design/board/announcement_system
name = "Machine Design (Automated Announcement System Board)"
desc = "The circuit board for an automated announcement system."
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 0472bb9e7a..015f0dafb6 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -130,7 +130,7 @@
display_name = "Advanced Power Manipulation"
description = "How to get more zap."
prereq_ids = list("engineering")
- design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor")
+ design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor", "circulator", "teg")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
diff --git a/icons/obj/atmospherics/components/binary_devices.dmi b/icons/obj/atmospherics/components/binary_devices.dmi
index 9331613af3..9c6a1b6a1f 100644
Binary files a/icons/obj/atmospherics/components/binary_devices.dmi and b/icons/obj/atmospherics/components/binary_devices.dmi differ
diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi
index cd76709b00..dc6d4547b4 100644
Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ