// TURBINE v2 AKA rev4407 Engine reborn! // How to use it? - Mappers // // This is a very good power generating mechanism. All you need is a blast furnace with soaring flames and output. // Not everything is included yet so the turbine can run out of fuel quiet quickly. The best thing about the turbine is that even // though something is on fire that passes through it, it won't be on fire as it passes out of it. So the exhaust fumes can still // containt unreacted fuel - plasma and oxygen that needs to be filtered out and re-routed back. This of course requires smart piping // For a computer to work with the turbine the compressor requires a comp_id matching with the turbine computer's id. This will be // subjected to a change in the near future mind you. Right now this method of generating power is a good backup but don't expect it // become a main power source unless some work is done. Have fun. At 50k RPM it generates 60k power. So more than one turbine is needed! // // - Numbers // // Example setup S - sparker // B - Blast doors into space for venting // *BBB****BBB* C - Compressor // S CT * T - Turbine // * ^ * * V * D - Doors with firedoor // **|***D**|** ^ - Fuel feed (Not vent, but a gas outlet) // | | V - Suction vent (Like the ones in atmos // /obj/machinery/compressor name = "compressor" desc = "The compressor stage of a gas turbine generator." icon = 'icons/obj/pipes.dmi' icon_state = "compressor" anchored = TRUE density = TRUE circuit = /obj/item/weapon/circuitboard/machine/power_compressor var/obj/machinery/power/turbine/turbine var/datum/gas_mixture/gas_contained var/turf/simulated/inturf var/starter = 0 var/rpm = 0 var/rpmtarget = 0 var/capacity = 1e6 var/comp_id = 0 var/efficiency /obj/machinery/power/turbine name = "gas turbine generator" desc = "A gas turbine used for backup power generation." icon = 'icons/obj/pipes.dmi' icon_state = "turbine" anchored = TRUE density = TRUE circuit = /obj/item/weapon/circuitboard/machine/power_turbine var/obj/machinery/compressor/compressor var/turf/simulated/outturf var/lastgen var/productivity = 1 /obj/machinery/computer/turbine_computer name = "gas turbine control computer" desc = "A computer to remotely control a gas turbine." icon_keyboard = "tech_key" icon_screen = "turbinecomp" circuit = /obj/item/weapon/circuitboard/turbine_control var/obj/machinery/compressor/compressor var/list/obj/machinery/door/blast/doors var/id = 0 var/door_status = 0 /obj/item/weapon/circuitboard/machine/power_compressor name = T_BOARD("power compressor") build_path = /obj/machinery/compressor board_type = new /datum/frame/frame_types/machine origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 2) req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/manipulator = 6) /obj/item/weapon/circuitboard/machine/power_turbine name = T_BOARD("power turbine") build_path = /obj/machinery/power/turbine board_type = new /datum/frame/frame_types/machine origin_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 4) req_components = list(/obj/item/stack/cable_coil = 5, /obj/item/weapon/stock_parts/capacitor = 6) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compressor // the inlet stage of the gas turbine electricity generator ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define COMPFRICTION 5e5 #define COMPSTARTERLOAD 2800 /obj/machinery/compressor/initialize() . = ..() default_apply_parts() gas_contained = new() inturf = get_step(src, dir) locate_machinery() if(!turbine) stat |= BROKEN // When anchored, don't let air past us. /obj/machinery/compressor/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0) if(!height || air_group) return !anchored return !density /obj/machinery/compressor/proc/locate_machinery() if(turbine) return turbine = locate() in get_step(src, get_dir(inturf, src)) if(turbine) turbine.locate_machinery() /obj/machinery/compressor/RefreshParts() var/E = 0 for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) E += M.rating efficiency = E / 6 /obj/machinery/compressor/attackby(obj/item/W, mob/user) src.add_fingerprint(user) if(default_deconstruction_screwdriver(user, W)) return if(default_part_replacement(user, W)) return if(default_unfasten_wrench(user, W)) return if(default_deconstruction_crowbar(user, W)) return if(ismultitool(W)) var/new_ident = input("Enter a new ident tag.", name, comp_id) as null|text if(new_ident && user.Adjacent(src)) comp_id = new_ident return return ..() /obj/machinery/compressor/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/wrench/W, var/time = 20) if((. = ..())) turbine = null if(anchored) inturf = get_step(src, dir) locate_machinery() if(turbine) to_chat(user, "Turbine connected.") stat &= ~BROKEN else to_chat(user, "Turbine not connected.") stat |= BROKEN /obj/machinery/compressor/process() if(!turbine) stat = BROKEN if(stat & BROKEN || panel_open) return if(!starter) return overlays.Cut() rpm = 0.9* rpm + 0.1 * rpmtarget var/datum/gas_mixture/environment = inturf.return_air() // It's a simplified version taking only 1/10 of the moles from the turf nearby. It should be later changed into a better version var/transfer_moles = environment.total_moles / 10 var/datum/gas_mixture/removed = inturf.remove_air(transfer_moles) gas_contained.merge(removed) // RPM function to include compression friction - be advised that too low/high of a compfriction value can make things screwy rpm = max(0, rpm - (rpm*rpm)/(COMPFRICTION*efficiency)) if(starter && !(stat & NOPOWER)) use_power(2800) if(rpm<1000) rpmtarget = 1000 else if(rpm<1000) rpmtarget = 0 if(rpm>50000) overlays += image('icons/obj/pipes.dmi', "comp-o4", FLY_LAYER) else if(rpm>10000) overlays += image('icons/obj/pipes.dmi', "comp-o3", FLY_LAYER) else if(rpm>2000) overlays += image('icons/obj/pipes.dmi', "comp-o2", FLY_LAYER) else if(rpm>500) overlays += image('icons/obj/pipes.dmi', "comp-o1", FLY_LAYER) //TODO: DEFERRED ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Turbine ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from // rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is. #define TURBPRES 9000000 #define TURBGENQ 100000 #define TURBGENG 0.8 /obj/machinery/power/turbine/initialize() . = ..() default_apply_parts() // The outlet is pointed at the direction of the turbine component outturf = get_step(src, dir) locate_machinery() if(!compressor) stat |= BROKEN /obj/machinery/power/turbine/RefreshParts() var/P = 0 for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) P += C.rating productivity = P / 6 /obj/machinery/power/turbine/proc/locate_machinery() if(compressor) return compressor = locate() in get_step(src, get_dir(outturf, src)) if(compressor) compressor.locate_machinery() /obj/machinery/power/turbine/attackby(obj/item/W, mob/user) src.add_fingerprint(user) if(default_deconstruction_screwdriver(user, W)) return if(default_part_replacement(user, W)) return if(default_unfasten_wrench(user, W)) return if(default_deconstruction_crowbar(user, W)) return return ..() /obj/machinery/power/turbine/default_unfasten_wrench(var/mob/user, var/obj/item/weapon/wrench/W, var/time = 20) if((. = ..())) compressor = null if(anchored) outturf = get_step(src, dir) locate_machinery() if(compressor) to_chat(user, "Compressor connected.") stat &= ~BROKEN else to_chat(user, "Compressor not connected.") stat |= BROKEN /obj/machinery/power/turbine/process() if(!compressor) stat = BROKEN if((stat & BROKEN) || panel_open) return if(!compressor.starter) return overlays.Cut() // This is the power generation function. If anything is needed it's good to plot it in EXCEL before modifying // the TURBGENQ and TURBGENG values lastgen = ((compressor.rpm / TURBGENQ)**TURBGENG) * TURBGENQ * productivity add_avail(lastgen) // Weird function but it works. Should be something else... var/newrpm = ((compressor.gas_contained.temperature) * compressor.gas_contained.total_moles)/4 newrpm = max(0, newrpm) if(!compressor.starter || newrpm > 1000) compressor.rpmtarget = newrpm if(compressor.gas_contained.total_moles>0) var/oamount = min(compressor.gas_contained.total_moles, (compressor.rpm+100)/35000*compressor.capacity) var/datum/gas_mixture/removed = compressor.gas_contained.remove(oamount) outturf.assume_air(removed) // If it works, put an overlay that it works! if(lastgen > 100) overlays += image('icons/obj/pipes.dmi', "turb-o", FLY_LAYER) updateDialog() /obj/machinery/power/turbine/attack_hand(var/mob/user as mob) if((. = ..())) return src.interact(user) /obj/machinery/power/turbine/interact(mob/user) if(!Adjacent(user) || (stat & (NOPOWER|BROKEN)) && !issilicon(user)) user.unset_machine(src) user << browse(null, "window=turbine") return user.set_machine(src) var/t = "Gas Turbine Generator
"
	t += "Generated power : [DisplayPower(lastgen)]

" t += "Turbine: [round(compressor.rpm)] RPM
" t += "Starter: [ compressor.starter ? "Off On" : "Off On"]" t += "

Close" t += "
" var/datum/browser/popup = new(user, "turbine", name, 700, 500, src) popup.set_content(t) popup.open() return /obj/machinery/power/turbine/Topic(href, href_list) if(..()) return if(href_list["close"]) usr << browse(null, "window=turbine") usr.unset_machine(src) return else if(href_list["str"]) if(compressor) compressor.starter = !compressor.starter updateDialog() ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Turbine Computer ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /obj/machinery/computer/turbine_computer/initialize() . = ..() return INITIALIZE_HINT_LATELOAD /obj/machinery/computer/turbine_computer/LateInitialize() locate_machinery() /obj/machinery/computer/turbine_computer/proc/locate_machinery() if(!id) return for(var/obj/machinery/compressor/C in machines) if(C.comp_id == id) compressor = C LAZYINITLIST(doors) for(var/obj/machinery/door/blast/P in machines) if(P.id == id) doors += P /obj/machinery/computer/turbine_computer/attackby(obj/item/W, mob/user) if(ismultitool(W)) var/new_ident = input("Enter a new ident tag.", name, id) as null|text if(new_ident && user.Adjacent(src)) id = new_ident return /obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob) if((. = ..())) return src.interact(user) /obj/machinery/computer/turbine_computer/interact(mob/user) return ui_interact(user) /obj/machinery/computer/turbine_computer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) var/list/data = list() data["connected"] = (compressor && compressor.turbine) ? TRUE : FALSE data["compressor_broke"] = (!compressor || (compressor.stat & BROKEN)) ? TRUE : FALSE data["turbine_broke"] = (!compressor || !compressor.turbine || (compressor.turbine.stat & BROKEN)) ? TRUE : FALSE data["broken"] = (data["compressor_broke"] || data["turbine_broke"]) data["door_status"] = door_status ? TRUE : FALSE if(compressor && compressor.turbine) data["online"] = compressor.starter data["power"] = DisplayPower(compressor.turbine.lastgen) data["rpm"] = compressor.rpm data["temp"] = compressor.gas_contained.temperature // update the ui if it exists, returns null if no ui is passed/found ui = nanomanager.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, "turbine_computer.tmpl", name, 520, 440) // 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(TRUE) /obj/machinery/computer/turbine_computer/Topic(href, href_list) if(..()) return if(href_list["power-on"]) if(compressor && compressor.turbine) compressor.starter = TRUE . = TRUE else if(href_list["power-off"]) if(compressor && compressor.turbine) compressor.starter = FALSE . = TRUE else if(href_list["reconnect"]) locate_machinery() . = TRUE else if(href_list["doors"]) door_status = !door_status for(var/obj/machinery/door/blast/D in src.doors) if (door_status) spawn(0) D.close() else spawn(0)D.open() . = TRUE #undef COMPFRICTION #undef COMPSTARTERLOAD #undef TURBPRES #undef TURBGENQ #undef TURBGENG