diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 696af2ffe6e..fc7255140bf 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -142,6 +142,14 @@ #define REACTING 1 #define STOP_REACTIONS 2 +//Fusion +///Max amount of radiation that can be emitted per reaction cycle +#define FUSION_RAD_MAX 5000 +///Maximum instability before the reaction goes endothermic +#define FUSION_INSTABILITY_ENDOTHERMALITY 4 +///Maximum reachable fusion temperature +#define FUSION_MAXIMUM_TEMPERATURE 1e8 + // Pressure limits. /// This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) #define HAZARD_HIGH_PRESSURE 550 diff --git a/code/modules/atmospherics/machinery/components/binary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/binary_devices/thermomachine.dm index f2a4ca01855..557aa1e9dd6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/thermomachine.dm @@ -1,3 +1,5 @@ +#define THERMOMACHINE_SAFE_TEMPERATURE 500000 + /obj/machinery/atmospherics/components/binary/thermomachine icon = 'icons/obj/atmospherics/components/thermomachine.dmi' icon_state = "freezer" @@ -33,6 +35,8 @@ var/use_enviroment_heat = FALSE var/skipping_work = FALSE var/auto_thermal_regulator = FALSE + var/safeties = TRUE + var/lastwarning var/color_index = 1 /obj/machinery/atmospherics/components/binary/thermomachine/Initialize() @@ -104,6 +108,8 @@ /obj/machinery/atmospherics/components/binary/thermomachine/examine(mob/user) . = ..() + if(obj_flags & EMAGGED) + . += "Something seems wrong with [src]'s thermal safeties." . += "With the panel open:" . += "-use a wrench with left-click to rotate [src] and right-click to unanchor it." . += "-use a multitool with left-click to change the piping layer and right-click to change the piping color." @@ -156,13 +162,25 @@ var/temperature_difference = 0 var/skip_tick = TRUE if(!use_enviroment_heat && main_port.total_moles() > 0.01) - if(cooling && thermal_exchange_port.total_moles() > 0.01 && nodes[2]) + if(cooling && thermal_exchange_port.total_moles() > 0.01 && nodes[2] && (thermal_exchange_port.temperature <= THERMOMACHINE_SAFE_TEMPERATURE || !safeties)) thermal_exchange_port.temperature = max(thermal_exchange_port.temperature + heat_amount / thermal_heat_capacity + motor_heat / thermal_heat_capacity, TCMB) else if(cooling && (!thermal_exchange_port.total_moles() || !nodes[2])) skipping_work = skip_tick update_appearance() update_parents() return + if(thermal_exchange_port.temperature > THERMOMACHINE_SAFE_TEMPERATURE && safeties) + on = FALSE + visible_message("The thermal exchange port's temperature has reached critical levels, shutting down...") + update_appearance() + return + else if(thermal_exchange_port.temperature > THERMOMACHINE_SAFE_TEMPERATURE && !safeties) + if((REALTIMEOFDAY - lastwarning) / 5 >= WARNING_DELAY) + lastwarning = REALTIMEOFDAY + visible_message("The thermal exchange port's temperature has reached critical levels!") + if(check_explosion(thermal_exchange_port.temperature)) + explode() + return PROCESS_KILL //we dying anyway, so let's stop processing temperature_difference = thermal_exchange_port.temperature - main_port.temperature temperature_difference = cooling ? temperature_difference : 0 if(temperature_difference > 0) @@ -171,7 +189,7 @@ skip_tick = FALSE if(use_enviroment_heat && main_port.total_moles() > 0.01) var/enviroment_efficiency = 1 - if(cooling && enviroment.total_moles() > 0.01) + if(cooling && enviroment.total_moles() > 0.01 && (thermal_exchange_port.temperature <= THERMOMACHINE_SAFE_TEMPERATURE || !safeties)) var/enviroment_heat_capacity = enviroment.heat_capacity() if(enviroment.total_moles()) enviroment_efficiency = clamp(log(1.55, enviroment.total_moles()) * 0.15, 0.65, 1) @@ -182,6 +200,18 @@ update_appearance() update_parents() return + if(enviroment.temperature > THERMOMACHINE_SAFE_TEMPERATURE && safeties) + on = FALSE + visible_message("The enviroment's temperature has reached critical levels, shutting down...") + update_appearance() + return + else if(enviroment.temperature > THERMOMACHINE_SAFE_TEMPERATURE && !safeties) + if((REALTIMEOFDAY - lastwarning) / 5 >= WARNING_DELAY) + lastwarning = REALTIMEOFDAY + visible_message("The enviroment's temperature has reached critical levels!") + if(check_explosion(enviroment.temperature)) + explode() + return PROCESS_KILL //we dying anyway, so let's stop processing temperature_difference = enviroment.temperature - main_port.temperature temperature_difference = cooling ? temperature_difference : 0 if(temperature_difference > 0) @@ -297,6 +327,37 @@ return TRUE return FALSE +/obj/machinery/atmospherics/components/binary/thermomachine/multitool_act(mob/living/user, obj/item/multitool/multitool) + if(!istype(multitool)) + return + if(panel_open && !anchored) + piping_layer = (piping_layer >= PIPING_LAYER_MAX) ? PIPING_LAYER_MIN : (piping_layer + 1) + to_chat(user, "You change the circuitboard to layer [piping_layer].") + update_appearance() + +/obj/machinery/atmospherics/components/binary/thermomachine/emag_act(mob/user) + . = ..() + if(!(obj_flags & EMAGGED)) + if(!do_after(user, 1 SECONDS, src)) + return + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 0, src) + sparks.attach(src) + sparks.start() + obj_flags |= EMAGGED + user.visible_message("You emag [src], overwriting thermal safety restrictions.") + log_game("[key_name(user)] emagged [src] at [AREACOORD(src)], overwriting thermal safety restrictions.") + +/obj/machinery/atmospherics/components/binary/thermomachine/emp_act() + . = ..() + if(!(obj_flags & EMAGGED)) + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 0, src) + sparks.attach(src) + sparks.start() + obj_flags |= EMAGGED + safeties = FALSE + /obj/machinery/atmospherics/components/binary/thermomachine/proc/replace_tank(mob/living/user, obj/item/tank/new_tank) if(!user) return FALSE @@ -308,6 +369,23 @@ update_appearance() return TRUE +/obj/machinery/atmospherics/components/binary/thermomachine/proc/check_explosion(temperature) + if(temperature < THERMOMACHINE_SAFE_TEMPERATURE + 2000) + return FALSE + if(prob(log(6, temperature) * 10)) //75% at 500000, 100% at 1e8 + return TRUE + +/obj/machinery/atmospherics/components/binary/thermomachine/proc/explode() + explosion(loc, 0, 0, 3, 3, TRUE) + var/datum/gas_mixture/main_port = airs[1] + var/datum/gas_mixture/thermal_exchange_port = airs[2] + if(main_port) + loc.assume_air(main_port.remove_ratio(1)) + if(thermal_exchange_port) + loc.assume_air(thermal_exchange_port.remove_ratio(1)) + air_update_turf(FALSE, FALSE) + qdel(src) + /obj/machinery/atmospherics/components/binary/thermomachine/ui_status(mob/user) if(interactive) return ..() @@ -342,6 +420,9 @@ data["use_env_heat"] = use_enviroment_heat data["skipping_work"] = skipping_work data["auto_thermal_regulator"] = auto_thermal_regulator + data["safeties"] = safeties + var/hacked = (obj_flags & EMAGGED) ? TRUE : FALSE + data["hacked"] = hacked return data /obj/machinery/atmospherics/components/binary/thermomachine/ui_act(action, params) @@ -391,6 +472,10 @@ if("auto_thermal_regulator") auto_thermal_regulator = !auto_thermal_regulator . = TRUE + if("safeties") + safeties = !safeties + investigate_log("[key_name(usr)] turned off the [src] safeties", INVESTIGATE_ATMOS) + . = TRUE update_appearance() @@ -437,3 +522,5 @@ /obj/machinery/atmospherics/components/binary/thermomachine/heater/on on = TRUE icon_state = "heater_1" + +#undef THERMOMACHINE_SAFE_TEMPERATURE diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm index 0f9478ec6ce..8294546d0f1 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_defines.dm @@ -1,9 +1,3 @@ -///Max amount of radiation that can be emitted per reaction cycle -#define FUSION_RAD_MAX 5000 -///Maximum instability before the reaction goes endothermic -#define FUSION_INSTABILITY_ENDOTHERMALITY 4 -///Maximum reachable fusion temperature -#define FUSION_MAXIMUM_TEMPERATURE 1e8 ///Speed of light, in m/s #define LIGHT_SPEED 299792458 ///Calculation between the plank constant and the lambda of the lightwave diff --git a/tgui/packages/tgui/interfaces/ThermoMachine.js b/tgui/packages/tgui/interfaces/ThermoMachine.js index 7863ce888b1..49536c95511 100644 --- a/tgui/packages/tgui/interfaces/ThermoMachine.js +++ b/tgui/packages/tgui/interfaces/ThermoMachine.js @@ -48,6 +48,13 @@ export const ThermoMachine = (props, context) => { onClick={() => act('power')} /> )}> + +