mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-20 15:16:43 +01:00
Reverts Citadel-Station-13/Citadel-Station-13-RP#6764 It literally does not work as advertised. It doesn't work at all. There's only one output side, it always puts into the output side. It can take from the output side, and then it puts it back into the output side. This is a non-functioning PR. Test your PRs properly.
344 lines
12 KiB
Plaintext
344 lines
12 KiB
Plaintext
GLOBAL_LIST_EMPTY(all_turbines)
|
|
|
|
/obj/machinery/power/generator
|
|
name = "thermoelectric generator"
|
|
desc = "It's a high efficiency thermoelectric generator."
|
|
icon_state = "teg-unassembled"
|
|
density = 1
|
|
anchored = 0
|
|
|
|
use_power = USE_POWER_IDLE
|
|
idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things.
|
|
|
|
var/max_power = 500000
|
|
var/thermal_efficiency = 0.65
|
|
|
|
var/obj/machinery/atmospherics/component/binary/circulator/circ1
|
|
var/obj/machinery/atmospherics/component/binary/circulator/circ2
|
|
|
|
var/last_circ1_gen = 0
|
|
var/last_circ2_gen = 0
|
|
var/last_thermal_gen = 0
|
|
var/stored_energy = 0
|
|
var/lastgen1 = 0
|
|
var/lastgen2 = 0
|
|
var/effective_gen = 0
|
|
var/lastgenlev = 0
|
|
var/datum/looping_sound/generator/soundloop
|
|
|
|
/obj/machinery/power/generator/Initialize(mapload)
|
|
soundloop = new(list(src), FALSE)
|
|
desc = initial(desc) + " Rated for [round(max_power/1000)] kW."
|
|
GLOB.all_turbines += src
|
|
..() //Not returned, because...
|
|
return INITIALIZE_HINT_LATELOAD
|
|
|
|
/obj/machinery/power/generator/LateInitialize()
|
|
reconnect()
|
|
|
|
/obj/machinery/power/generator/Destroy()
|
|
QDEL_NULL(soundloop)
|
|
GLOB.all_turbines -= src
|
|
return ..()
|
|
|
|
//generators connect in dir and global.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
|
|
/obj/machinery/power/generator/proc/reconnect()
|
|
circ1 = null
|
|
circ2 = null
|
|
if(src.loc && anchored)
|
|
if(src.dir & (EAST|WEST))
|
|
circ1 = locate(/obj/machinery/atmospherics/component/binary/circulator) in get_step(src,WEST)
|
|
circ2 = locate(/obj/machinery/atmospherics/component/binary/circulator) in get_step(src,EAST)
|
|
|
|
if(circ1 && circ2)
|
|
if(circ1.dir != NORTH || circ2.dir != SOUTH)
|
|
circ1 = null
|
|
circ2 = null
|
|
|
|
else if(src.dir & (NORTH|SOUTH))
|
|
circ1 = locate(/obj/machinery/atmospherics/component/binary/circulator) in get_step(src,NORTH)
|
|
circ2 = locate(/obj/machinery/atmospherics/component/binary/circulator) in get_step(src,SOUTH)
|
|
|
|
if(circ1 && circ2 && (circ1.dir != EAST || circ2.dir != WEST))
|
|
circ1 = null
|
|
circ2 = null
|
|
|
|
/obj/machinery/power/generator/proc/updateicon()
|
|
icon_state = anchored ? "teg-assembled" : "teg-unassembled"
|
|
cut_overlays()
|
|
if (circ1)
|
|
circ1.temperature_overlay = null
|
|
if (circ2)
|
|
circ2.temperature_overlay = null
|
|
if (machine_stat & (NOPOWER|BROKEN))
|
|
return 1
|
|
else
|
|
if (lastgenlev != 0)
|
|
add_overlay("teg-op[lastgenlev]")
|
|
if (circ1 && circ2)
|
|
var/extreme = (lastgenlev > 9) ? "ex" : ""
|
|
if (circ1.last_temperature < circ2.last_temperature)
|
|
circ1.temperature_overlay = "circ-[extreme]cold"
|
|
circ2.temperature_overlay = "circ-[extreme]hot"
|
|
else
|
|
circ1.temperature_overlay = "circ-[extreme]hot"
|
|
circ2.temperature_overlay = "circ-[extreme]cold"
|
|
return 1
|
|
|
|
/obj/machinery/power/generator/process(delta_time)
|
|
if(!circ1 || !circ2 || !anchored || machine_stat & (BROKEN|NOPOWER))
|
|
stored_energy = 0
|
|
return
|
|
|
|
updateDialog()
|
|
|
|
var/datum/gas_mixture/air1 = circ1.return_transfer_air()
|
|
var/datum/gas_mixture/air2 = circ2.return_transfer_air()
|
|
|
|
lastgen2 = lastgen1
|
|
lastgen1 = 0
|
|
last_thermal_gen = 0
|
|
last_circ1_gen = 0
|
|
last_circ2_gen = 0
|
|
|
|
if(air1 && air2)
|
|
var/air1_heat_capacity = air1.heat_capacity()
|
|
var/air2_heat_capacity = air2.heat_capacity()
|
|
var/delta_temperature = abs(air2.temperature - air1.temperature)
|
|
|
|
if(delta_temperature > 0 && air1_heat_capacity > 0 && air2_heat_capacity > 0)
|
|
var/energy_transfer = delta_temperature*air2_heat_capacity*air1_heat_capacity/(air2_heat_capacity+air1_heat_capacity)
|
|
var/heat = energy_transfer*(1-thermal_efficiency)
|
|
last_thermal_gen = energy_transfer*thermal_efficiency
|
|
|
|
if(air2.temperature > air1.temperature)
|
|
air2.temperature = air2.temperature - energy_transfer/air2_heat_capacity
|
|
air1.temperature = air1.temperature + heat/air1_heat_capacity
|
|
else
|
|
air2.temperature = air2.temperature + heat/air2_heat_capacity
|
|
air1.temperature = air1.temperature - energy_transfer/air1_heat_capacity
|
|
|
|
//Transfer the air
|
|
if (air1)
|
|
circ1.air2.merge(air1)
|
|
if (air2)
|
|
circ2.air2.merge(air2)
|
|
|
|
//Update the gas networks
|
|
if(circ1.network2)
|
|
circ1.network2.update = 1
|
|
if(circ2.network2)
|
|
circ2.network2.update = 1
|
|
|
|
//Exceeding maximum power leads to some power loss
|
|
if(effective_gen > max_power && prob(5))
|
|
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
stored_energy *= 0.5
|
|
|
|
//Power
|
|
last_circ1_gen = circ1.return_stored_energy()
|
|
last_circ2_gen = circ2.return_stored_energy()
|
|
stored_energy += last_thermal_gen + last_circ1_gen + last_circ2_gen
|
|
lastgen1 = stored_energy*0.4 //smoothened power generation to prevent slingshotting as pressure is equalized, then restored by pumps
|
|
stored_energy -= lastgen1
|
|
effective_gen = (lastgen1 + lastgen2) / 2
|
|
|
|
// Sounds.
|
|
if(effective_gen > (max_power * 0.05)) // More than 5% and sounds start.
|
|
soundloop.start()
|
|
soundloop.opacity_check = 1
|
|
soundloop.volume = LERP(1, 40, effective_gen / max_power)
|
|
else
|
|
soundloop.stop()
|
|
|
|
// update icon overlays and power usage only if displayed level has changed
|
|
var/genlev = max(0, min( round(11*effective_gen / max_power), 11))
|
|
if(effective_gen > 100 && genlev == 0)
|
|
genlev = 1
|
|
if(genlev != lastgenlev)
|
|
lastgenlev = genlev
|
|
updateicon()
|
|
add_avail(effective_gen * 0.001)
|
|
|
|
/obj/machinery/power/generator/attack_ai(mob/user)
|
|
attack_hand(user)
|
|
|
|
/obj/machinery/power/generator/attackby(obj/item/W as obj, mob/user as mob)
|
|
if(W.is_wrench())
|
|
playsound(src, W.tool_sound, 75, 1)
|
|
anchored = !anchored
|
|
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.")
|
|
update_use_power(anchored ? USE_POWER_IDLE : USE_POWER_ACTIVE)
|
|
if(anchored) // Powernet connection stuff.
|
|
connect_to_network()
|
|
else
|
|
disconnect_from_network()
|
|
reconnect()
|
|
lastgenlev = 0
|
|
effective_gen = 0
|
|
updateicon()
|
|
else
|
|
..()
|
|
|
|
/obj/machinery/power/generator/attack_hand(mob/user, datum/event_args/actor/clickchain/e_args)
|
|
add_fingerprint(user)
|
|
if(machine_stat & (BROKEN|NOPOWER) || !anchored)
|
|
return
|
|
if(!circ1 || !circ2) //Just incase the middle part of the TEG was not wrenched last.
|
|
reconnect()
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/power/generator/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "TEGenerator", name)
|
|
ui.open()
|
|
|
|
/obj/machinery/power/generator/ui_data(mob/user, datum/tgui/ui)
|
|
// this is the data which will be sent to the ui
|
|
var/vertical = 0
|
|
if (dir == NORTH || dir == SOUTH)
|
|
vertical = 1
|
|
|
|
var/list/data = list()
|
|
data["totalOutput"] = effective_gen
|
|
data["maxTotalOutput"] = max_power
|
|
data["thermalOutput"] = last_thermal_gen
|
|
|
|
data["primary"] = list()
|
|
if(circ1)
|
|
//The one on the left (or top)
|
|
data["primary"]["dir"] = vertical ? "top" : "left"
|
|
data["primary"]["output"] = last_circ1_gen
|
|
data["primary"]["flowCapacity"] = circ1.volume_capacity_used*100
|
|
data["primary"]["inletPressure"] = circ1.air1.return_pressure()
|
|
data["primary"]["inletTemperature"] = circ1.air1.temperature
|
|
data["primary"]["outletPressure"] = circ1.air2.return_pressure()
|
|
data["primary"]["outletTemperature"] = circ1.air2.temperature
|
|
|
|
data["secondary"] = list()
|
|
if(circ2)
|
|
//Now for the one on the right (or bottom)
|
|
data["secondary"]["dir"] = vertical ? "bottom" : "right"
|
|
data["secondary"]["output"] = last_circ2_gen
|
|
data["secondary"]["flowCapacity"] = circ2.volume_capacity_used*100
|
|
data["secondary"]["inletPressure"] = circ2.air1.return_pressure()
|
|
data["secondary"]["inletTemperature"] = circ2.air1.temperature
|
|
data["secondary"]["outletPressure"] = circ2.air2.return_pressure()
|
|
data["secondary"]["outletTemperature"] = circ2.air2.temperature
|
|
|
|
return data
|
|
/*
|
|
/obj/machinery/power/generator/nano_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
|
|
|
|
var/data[0]
|
|
data["totalOutput"] = effective_gen/1000
|
|
data["maxTotalOutput"] = max_power/1000
|
|
data["thermalOutput"] = last_thermal_gen/1000
|
|
data["circConnected"] = 0
|
|
|
|
if(circ1)
|
|
//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
|
|
data["primaryInletPressure"] = circ1.air1.return_pressure()
|
|
data["primaryInletTemperature"] = circ1.air1.temperature
|
|
data["primaryOutletPressure"] = circ1.air2.return_pressure()
|
|
data["primaryOutletTemperature"] = circ1.air2.temperature
|
|
|
|
if(circ2)
|
|
//Now for 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
|
|
data["secondaryInletPressure"] = circ2.air1.return_pressure()
|
|
data["secondaryInletTemperature"] = circ2.air1.temperature
|
|
data["secondaryOutletPressure"] = circ2.air2.return_pressure()
|
|
data["secondaryOutletTemperature"] = circ2.air2.temperature
|
|
|
|
if(circ1 && circ2)
|
|
data["circConnected"] = 1
|
|
else
|
|
data["circConnected"] = 0
|
|
|
|
|
|
// 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)
|
|
*/
|
|
/obj/machinery/power/generator/power_change()
|
|
..()
|
|
updateicon()
|
|
|
|
|
|
/obj/machinery/power/generator/verb/rotate_clockwise()
|
|
set category = VERB_CATEGORY_OBJECT
|
|
set name = "Rotate Generator Clockwise"
|
|
set src in view(1)
|
|
|
|
if (usr.stat || usr.restrained() || anchored)
|
|
return
|
|
|
|
src.setDir(turn(src.dir, 270))
|
|
|
|
/obj/machinery/power/generator/verb/rotate_counterclockwise()
|
|
set category = VERB_CATEGORY_OBJECT
|
|
set name = "Rotate Generator Counterclockwise"
|
|
set src in view(1)
|
|
|
|
if (usr.stat || usr.restrained() || anchored)
|
|
return
|
|
|
|
src.setDir(turn(src.dir, 90))
|
|
|
|
/obj/machinery/power/generator/power_spike()
|
|
// if(!effective_gen >= max_power / 2 && powernet) // Don't make a spike if we're not making a whole lot of power.
|
|
// return
|
|
|
|
var/list/powernet_union = powernet.nodes
|
|
for(var/obj/machinery/power/terminal/T in powernet.nodes)
|
|
if(T.master && istype(T.master, /obj/machinery/power/smes))
|
|
var/obj/machinery/power/smes/S = T.master
|
|
powernet_union |= S.powernet.nodes
|
|
|
|
var/found_grid_checker = FALSE
|
|
for(var/obj/machinery/power/grid_checker/G in powernet_union)
|
|
G.power_failure(prob(30)) // If we found a grid checker, then all is well.
|
|
found_grid_checker = TRUE
|
|
if(!found_grid_checker) // Otherwise lets break some stuff.
|
|
spawn(1)
|
|
command_announcement.Announce("Dangerous power spike detected in the power network. Please check machinery \
|
|
for electrical damage.",
|
|
"Critical Power Overload")
|
|
var/i = 0
|
|
var/limit = rand(30, 50)
|
|
for(var/obj/machinery/power/P in powernet_union)
|
|
P.overload(src)
|
|
i++
|
|
if(i % 5)
|
|
sleep(1)
|
|
if(i >= limit)
|
|
break
|