diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 5b38b592ac6..809567a0a75 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -81,4 +81,15 @@ #define TARGET_DEPT_SEC 2 #define TARGET_DEPT_MED 3 #define TARGET_DEPT_SCI 4 -#define TARGET_DEPT_ENG 5 \ No newline at end of file +#define TARGET_DEPT_ENG 5 + +// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! +// These are warning defines, they should trigger before the state, not after. +#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. +#define SUPERMATTER_INACTIVE 0 // No or minimal energy +#define SUPERMATTER_NORMAL 1 // Normal operation +#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE +#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged +#define SUPERMATTER_DANGER 4 // Integrity < 75% +#define SUPERMATTER_EMERGENCY 5 // Integrity < 50% +#define SUPERMATTER_DELAMINATING 6 // Pretty obvious, Integrity < 25% diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index d3dd6a5438b..471c1334bf8 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -246,6 +246,13 @@ proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE) "sig_low.gif" = 'icons/program_icons/sig_low.gif', "sig_lan.gif" = 'icons/program_icons/sig_lan.gif', "sig_none.gif" = 'icons/program_icons/sig_none.gif', + "smmon_0.gif" = 'icons/program_icons/smmon_0.gif', + "smmon_1.gif" = 'icons/program_icons/smmon_1.gif', + "smmon_2.gif" = 'icons/program_icons/smmon_2.gif', + "smmon_3.gif" = 'icons/program_icons/smmon_3.gif', + "smmon_4.gif" = 'icons/program_icons/smmon_4.gif', + "smmon_5.gif" = 'icons/program_icons/smmon_5.gif', + "smmon_6.gif" = 'icons/program_icons/smmon_6.gif', ) /datum/asset/nanoui diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 6e0be3b385f..5dd324945fa 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -36,6 +36,7 @@ var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] hard_drive.store_file(new/datum/computer_file/program/power_monitor()) hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) + hard_drive.store_file(new/datum/computer_file/program/supermatter_monitor()) // ===== RESEARCH CONSOLE ===== /obj/machinery/modular_computer/console/preset/research diff --git a/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm new file mode 100644 index 00000000000..db9081f6ad1 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/engineering/sm_monitor.dm @@ -0,0 +1,139 @@ +/datum/computer_file/program/supermatter_monitor + filename = "smmonitor" + filedesc = "Supermatter Monitoring" + ui_header = "smmon_0.gif" + program_icon_state = "smmon_0" + extended_desc = "This program connects to specially calibrated supermatter sensors to provide information on the status of supermatter-based engines." + requires_ntnet = TRUE + transfer_access = access_construction + network_destination = "supermatter monitoring system" + size = 5 + var/last_status = SUPERMATTER_INACTIVE + var/list/supermatters + var/obj/machinery/power/supermatter_shard/active // Currently selected supermatter crystal. + + +/datum/computer_file/program/supermatter_monitor/process_tick() + ..() + var/new_status = get_status() + if(last_status != new_status) + last_status = new_status + if(last_status == SUPERMATTER_ERROR) + last_status = SUPERMATTER_INACTIVE + ui_header = "smmon_[last_status].gif" + program_icon_state = "smmon_[last_status]" + if(istype(computer)) + computer.update_icon() + +/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) + . = ..(user) + refresh() + +/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) + active = null + supermatters = null + ..() + +// Refreshes list of active supermatter crystals +/datum/computer_file/program/supermatter_monitor/proc/refresh() + supermatters = list() + var/turf/T = get_turf(nano_host()) + if(!T) + return + for(var/obj/machinery/power/supermatter_shard/S in SSair.atmos_machinery) + // Delaminating, not within coverage, not on a tile. + if(!(is_station_level(S.z) || is_mining_level(S.z) || atoms_share_level(S, T) || !istype(S.loc, /turf/simulated/))) + continue + supermatters.Add(S) + + if(!(active in supermatters)) + active = null + +/datum/computer_file/program/supermatter_monitor/proc/get_status() + . = SUPERMATTER_INACTIVE + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + . = max(., S.get_status()) + +/datum/computer_file/program/supermatter_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + var/datum/asset/assets = get_asset_datum(/datum/asset/simple/headers) + assets.send(user) + ui = new(user, src, ui_key, "supermatter_monitor.tmpl", "Supermatter Monitoring", 600, 400) + ui.set_auto_update(TRUE) + ui.set_layout_key("program") + ui.open() + +/datum/computer_file/program/supermatter_monitor/ui_data() + var/list/data = get_header_data() + + if(istype(active)) + var/turf/T = get_turf(active) + if(!T) + active = null + refresh() + return + var/datum/gas_mixture/air = T.return_air() + if(!air) + active = null + return + + data["active"] = TRUE + data["SM_integrity"] = active.get_integrity() + data["SM_power"] = active.power + data["SM_ambienttemp"] = air.temperature + data["SM_ambientpressure"] = air.return_pressure() + //data["SM_EPR"] = round((air.total_moles / air.group_multiplier) / 23.1, 0.01) + var/other_moles = 0.0 + for(var/datum/gas/G in air.trace_gases) + other_moles+=G.moles + var/TM = air.total_moles() + if(TM) + data["SM_gas_O2"] = round(100*air.oxygen/TM,0.01) + data["SM_gas_CO2"] = round(100*air.carbon_dioxide/TM,0.01) + data["SM_gas_N2"] = round(100*air.nitrogen/TM,0.01) + data["SM_gas_PL"] = round(100*air.toxins/TM,0.01) + if(other_moles) + data["SM_gas_OTHER"] = round(100*other_moles/TM,0.01) + else + data["SM_gas_OTHER"] = 0 + else + data["SM_gas_O2"] = 0 + data["SM_gas_CO2"] = 0 + data["SM_gas_N2"] = 0 + data["SM_gas_PH"] = 0 + data["SM_gas_OTHER"] = 0 + else + var/list/SMS = list() + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + var/area/A = get_area(S) + if(!A) + continue + + SMS.Add(list(list( + "area_name" = A.name, + "integrity" = S.get_integrity(), + "uid" = S.uid + ))) + + data["active"] = FALSE + data["supermatters"] = SMS + + return data + + +/datum/computer_file/program/supermatter_monitor/Topic(href, href_list) + if(..()) + return TRUE + if(href_list["clear"]) + active = null + return TRUE + if(href_list["refresh"]) + refresh() + return TRUE + if(href_list["set"]) + var/newuid = text2num(href_list["set"]) + for(var/obj/machinery/power/supermatter_shard/S in supermatters) + if(S.uid == newuid) + active = S + return TRUE diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 43d418aadf7..fd031f987c6 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -1,21 +1,33 @@ -//Ported from /vg/station13, which was in turn forked from baystation12; -//Please do not bother them with bugs from this port, however, as it has been modified quite a bit. -//Modifications include removing the world-ending full supermatter variation, and leaving only the shard. +#define NITROGEN_RETARDATION_FACTOR 0.15 //Higher == N2 slows reaction more +#define THERMAL_RELEASE_MODIFIER 10000 //Higher == more heat released during reaction +#define PLASMA_RELEASE_MODIFIER 1500 //Higher == less phor.. plasma released by reaction +#define OXYGEN_RELEASE_MODIFIER 15000 //Higher == less oxygen released at high temperature/power +#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power -#define NITROGEN_RETARDATION_FACTOR 2 //Higher == N2 slows reaction more -#define THERMAL_RELEASE_MODIFIER 5 //Higher == less heat released during reaction -#define PLASMA_RELEASE_MODIFIER 750 //Higher == less plasma released by reaction -#define OXYGEN_RELEASE_MODIFIER 325 //Higher == less oxygen released at high temperature/power -#define REACTION_POWER_MODIFIER 0.55 //Higher == more overall power +/* + How to tweak the SM + POWER_FACTOR directly controls how much power the SM puts out at a given level of excitation (power var). Making this lower means you have to work the SM harder to get the same amount of power. + CRITICAL_TEMPERATURE The temperature at which the SM starts taking damage. + CHARGING_FACTOR Controls how much emitter shots excite the SM. + DAMAGE_RATE_LIMIT Controls the maximum rate at which the SM will take damage due to high temperatures. +*/ + +//Controls how much power is produced by each collector in range - this is the main parameter for tweaking SM balance, as it basically controls how the power variable relates to the rest of the game. +#define POWER_FACTOR 1.0 +#define DECAY_FACTOR 700 //Affects how fast the supermatter power decays +#define CRITICAL_TEMPERATURE 5000 //K +#define CHARGING_FACTOR 0.05 +#define DAMAGE_RATE_LIMIT 4.5 //damage rate cap at power = 300, scales linearly with power -//These would be what you would get at point blank, decreases with distance +// Base variants are applied to everyone on the same Z level +// Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels) #define DETONATION_RADS 200 #define DETONATION_HALLUCINATION 600 -#define WARNING_DELAY 30 //seconds between warnings. +#define WARNING_DELAY 20 //seconds between warnings. /obj/machinery/power/supermatter_shard name = "supermatter shard" desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. You get headaches just from looking at it." @@ -35,15 +47,16 @@ var/safe_alert = "Crystalline hyperstructure returning to safe operating levels." var/warning_point = 50 var/warning_alert = "Danger! Crystal hyperstructure instability!" - var/emergency_point = 500 + var/emergency_point = 400 var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT." - var/explosion_point = 900 + var/explosion_point = 600 var/emergency_issued = 0 var/explosion_power = 8 var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning + var/last_zap = 0 // Time in 1/10th of seconds since the last tesla zap var/power = 0 var/oxygen = 0 // Moving this up here for easier debugging. @@ -51,38 +64,90 @@ //Temporary values so that we can optimize this //How much the bullets damage should be multiplied by when it is added to the internal variables var/config_bullet_energy = 2 - //How much of the power is left after processing is finished? -// var/config_power_reduction_per_tick = 0.5 //How much hallucination should it produce per unit of power? var/config_hallucination_power = 0.1 + var/debug = 0 + + var/disable_adminwarn = FALSE + + var/aw_normal = FALSE + var/aw_notify = FALSE + var/aw_warning = FALSE + var/aw_danger = FALSE + var/aw_emerg = FALSE + var/aw_delam = FALSE + var/obj/item/radio/radio //for logging var/has_been_powered = 0 var/has_reached_emergency = 0 +/obj/machinery/power/supermatter_shard/crystal + name = "supermatter crystal" + desc = "A strangely translucent and iridescent crystal." + base_icon_state = "darkmatter" + icon_state = "darkmatter" + anchored = TRUE + warning_point = 200 + emergency_point = 2000 + explosion_point = 3600 + gasefficency = 0.25 + explosion_power = 24 + + /obj/machinery/power/supermatter_shard/New() . = ..() poi_list |= src + //Added to the atmos_machine process as the SM is highly coupled with the atmospherics system. + //Having the SM run at a different rate then atmospherics causes odd behavior. + SSair.atmos_machinery += src radio = new(src) radio.listening = 0 investigate_log("has been created.", "supermatter") +/obj/machinery/power/supermatter_shard/proc/handle_admin_warnings() + if(disable_adminwarn) + return + + // Generic checks, similar to checks done by supermatter monitor program. + aw_normal = status_adminwarn_check(SUPERMATTER_NORMAL, aw_normal, "INFO: Supermatter crystal has been energised.(JMP).", FALSE) + aw_notify = status_adminwarn_check(SUPERMATTER_NOTIFY, aw_notify, "INFO: Supermatter crystal is approaching unsafe operating temperature.(JMP).", FALSE) + aw_warning = status_adminwarn_check(SUPERMATTER_WARNING, aw_warning, "WARN: Supermatter crystal is taking integrity damage!(JMP).", FALSE) + aw_danger = status_adminwarn_check(SUPERMATTER_DANGER, aw_danger, "WARN: Supermatter integrity is below 75%!(JMP).", TRUE) + aw_emerg = status_adminwarn_check(SUPERMATTER_EMERGENCY, aw_emerg, "CRIT: Supermatter integrity is below 50%!(JMP).", FALSE) + aw_delam = status_adminwarn_check(SUPERMATTER_DELAMINATING, aw_delam, "CRIT: Supermatter is delaminating!(JMP).", TRUE) + +/obj/machinery/power/supermatter_shard/proc/status_adminwarn_check(var/min_status, var/current_state, var/message, var/send_to_irc = FALSE) + var/status = get_status() + if(status >= min_status) + if(!current_state) + log_and_message_admins(message) + if(send_to_irc) + send2adminirc(message) + return TRUE + else + return FALSE + + /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") + if(damage > emergency_point) + emergency_lighting(0) QDEL_NULL(radio) poi_list.Remove(src) + SSair.atmos_machinery -= src return ..() /obj/machinery/power/supermatter_shard/proc/explode() investigate_log("has exploded.", "supermatter") - explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) + explosion(get_turf(src), explosion_power, explosion_power * 1.2, explosion_power * 1.5, explosion_power * 2, 1, 1) qdel(src) return -/obj/machinery/power/supermatter_shard/process() +/obj/machinery/power/supermatter_shard/process_atmos() var/turf/L = loc if(isnull(L)) // We have a null turf...something is wrong, stop processing this entity. @@ -91,11 +156,10 @@ if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now. return //Yeah just stop. - if(istype(L, /turf/space)) // Stop processing this stuff if we've been ejected. - return - if(damage > warning_point) // while the core is still damaged and it's still worth noting its status if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY) + alarm() + emergency_lighting(1) var/stability = num2text(round((damage / explosion_point) * 100)) if(damage > emergency_point) @@ -112,6 +176,7 @@ else // Phew, we're safe radio.autosay("[safe_alert]", src.name) + emergency_lighting(0) lastwarning = world.timeofday if(damage > explosion_point) @@ -128,6 +193,11 @@ mob.apply_effect(rads, IRRADIATE) explode() + emergency_lighting(0) + + if(damage > warning_point && world.timeofday > last_zap) + last_zap = world.timeofday + rand(80,200) + supermatter_zap() //Ok, get the air from the turf var/datum/gas_mixture/env = L.return_air() @@ -135,52 +205,57 @@ //Remove gas from surrounding area var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles()) - if(!removed || !removed.total_moles()) - damage += max((power-1600)/10, 0) - power = min(power, 1600) - return 1 + //ensure that damage doesn't increase too quickly due to super high temperatures resulting from no coolant, for example. We dont want the SM exploding before anyone can react. + //We want the cap to scale linearly with power (and explosion_point). Let's aim for a cap of 5 at power = 300 (based on testing, equals roughly 5% per SM alert announcement). + var/damage_inc_limit = (power/300)*(explosion_point/1000)*DAMAGE_RATE_LIMIT + + if(!env || !removed || !removed.total_moles()) + damage += max((power - 15*POWER_FACTOR)/10, 0) + else + damage_archived = damage + + damage = max(0, damage + between(-DAMAGE_RATE_LIMIT, (removed.temperature - CRITICAL_TEMPERATURE) / 150, damage_inc_limit)) - damage_archived = damage - damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 ) - //Ok, 100% oxygen atmosphere = best reaction //Maxes out at 100% oxygen pressure - oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0) - - var/temp_factor = 50 + oxygen = Clamp((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / removed.total_moles(), 0, 1) + var/temp_factor + var/equilibrium_power if(oxygen > 0.8) - // with a perfect gas mix, make the power less based on heat + //If chain reacting at oxygen > 0.8, we want the power at 800 K to stabilize at a power level of 400 + equilibrium_power = 400 icon_state = "[base_icon_state]_glow" else - // in normal mode, base the produced energy around the heat - temp_factor = 30 + //Otherwise, we want the power at 800 K to stabilize at a power level of 250 + equilibrium_power = 250 icon_state = base_icon_state - power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload - - //We've generated power, now let's transfer it to the collectors for storing/usage - transfer_energy() + temp_factor = ((equilibrium_power / DECAY_FACTOR) ** 3) / 800 + power = max((removed.temperature * temp_factor) * oxygen + power, 0) var/device_energy = power * REACTION_POWER_MODIFIER - //To figure out how much temperature to add each tick, consider that at one atmosphere's worth - //of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature - //that the device energy is around 2140. At that stage, we don't want too much heat to be put out - //Since the core is effectively "cold" + var/heat_capacity = removed.heat_capacity() - //Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock - //is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall. - removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER) - - removed.temperature = max(0, min(removed.temperature, 2500)) - - //Calculate how much gas to release removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0) removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0) + var/thermal_power = THERMAL_RELEASE_MODIFIER * device_energy + if(debug) + var/heat_capacity_new = removed.heat_capacity() + visible_message("[src]: Releasing [round(thermal_power)] W.") + visible_message("[src]: Releasing additional [round((heat_capacity_new - heat_capacity)*removed.temperature)] W with exhaust gasses.") + + removed.temperature += (device_energy) + + removed.temperature = max(0, min(removed.temperature, 10000)) + env.merge(removed) + air_update_turf() + transfer_energy() + for(var/mob/living/carbon/human/l in view(src, min(7, round(sqrt(power/6))))) // If they can see it without mesons on. Bad on them. if(l.glasses && istype(l.glasses, /obj/item/clothing/glasses/meson)) @@ -196,7 +271,8 @@ var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src),1) ) l.apply_effect(rads, IRRADIATE) - power -= (power/500)**3 + power -= (power/DECAY_FACTOR)**3 + handle_admin_warnings() return 1 @@ -217,12 +293,13 @@ has_been_powered = 1 else damage += Proj.damage * config_bullet_energy + supermatter_zap() return 0 /obj/machinery/power/supermatter_shard/singularity_act() var/gain = 100 investigate_log("Supermatter shard consumed by singularity.","singulo") - message_admins("Singularity has consumed a supermatter shard and can now become stage six.") + message_admins("Singularity has consumed a supermatter shard and can now become stage six.(JMP).") visible_message("[src] is consumed by the singularity!") for(var/mob/M in mob_list) M << 'sound/effects/supermatter.ogg' //everyone gunna know bout this @@ -306,7 +383,6 @@ user.apply_effect(150, IRRADIATE) - /obj/machinery/power/supermatter_shard/Bumped(atom/AM as mob|obj) if(istype(AM, /mob/living)) AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [AM.p_their(TRUE)] body starts to glow and catch flame before flashing into ash.",\ @@ -335,6 +411,8 @@ qdel(AM) power += 200 + supermatter_zap() + //Some poor sod got eaten, go ahead and irradiate people nearby. for(var/mob/living/L in range(10)) @@ -346,3 +424,53 @@ "The unearthly ringing subsides and you notice you have new radiation burns.", 2) else L.show_message("You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.", 2) + +#define CRITICAL_TEMPERATURE 10000 + +/obj/machinery/power/supermatter_shard/proc/get_status() + var/turf/T = get_turf(src) + if(!T) + return SUPERMATTER_ERROR + var/datum/gas_mixture/air = T.return_air() + if(!air) + return SUPERMATTER_ERROR + + if(get_integrity() < 25) + return SUPERMATTER_DELAMINATING + + if(get_integrity() < 50) + return SUPERMATTER_EMERGENCY + + if(get_integrity() < 75) + return SUPERMATTER_DANGER + + if((get_integrity() < 100) || (air.temperature > CRITICAL_TEMPERATURE)) + return SUPERMATTER_WARNING + + if(air.temperature > (CRITICAL_TEMPERATURE * 0.8)) + return SUPERMATTER_NOTIFY + + if(power > 5) + return SUPERMATTER_NORMAL + return SUPERMATTER_INACTIVE + +/obj/machinery/power/supermatter_shard/proc/alarm() + switch(get_status()) + if(SUPERMATTER_DELAMINATING) + playsound(src, 'sound/misc/bloblarm.ogg', 100) + if(SUPERMATTER_EMERGENCY) + playsound(src, 'sound/machines/engine_alert1.ogg', 100) + if(SUPERMATTER_DANGER) + playsound(src, 'sound/machines/engine_alert2.ogg', 100) + if(SUPERMATTER_WARNING) + playsound(src, 'sound/machines/terminal_alert.ogg', 75) + +/obj/machinery/power/supermatter_shard/proc/emergency_lighting(active) + if(active) + post_status("alert", "radiation") + else + post_status("shuttle") + +/obj/machinery/power/supermatter_shard/proc/supermatter_zap() + playsound(src.loc, 'sound/magic/LightningShock.ogg', 100, 1, extrarange = 5) + tesla_zap(src, 10, max(1000,power * damage / explosion_point)) diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi index 85d6026617f..fba8ad59431 100644 Binary files a/icons/obj/modular_console.dmi and b/icons/obj/modular_console.dmi differ diff --git a/icons/obj/modular_laptop.dmi b/icons/obj/modular_laptop.dmi index 2daeee0c7a4..d04e68c2041 100644 Binary files a/icons/obj/modular_laptop.dmi and b/icons/obj/modular_laptop.dmi differ diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi index 2438f375f65..a6e3223a8d0 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/program_icons/smmon_0.gif b/icons/program_icons/smmon_0.gif new file mode 100644 index 00000000000..7b716c4e1c5 Binary files /dev/null and b/icons/program_icons/smmon_0.gif differ diff --git a/icons/program_icons/smmon_1.gif b/icons/program_icons/smmon_1.gif new file mode 100644 index 00000000000..bbe319b820f Binary files /dev/null and b/icons/program_icons/smmon_1.gif differ diff --git a/icons/program_icons/smmon_2.gif b/icons/program_icons/smmon_2.gif new file mode 100644 index 00000000000..9c58edd340e Binary files /dev/null and b/icons/program_icons/smmon_2.gif differ diff --git a/icons/program_icons/smmon_3.gif b/icons/program_icons/smmon_3.gif new file mode 100644 index 00000000000..dc7c8734eed Binary files /dev/null and b/icons/program_icons/smmon_3.gif differ diff --git a/icons/program_icons/smmon_4.gif b/icons/program_icons/smmon_4.gif new file mode 100644 index 00000000000..8a75e6e1184 Binary files /dev/null and b/icons/program_icons/smmon_4.gif differ diff --git a/icons/program_icons/smmon_5.gif b/icons/program_icons/smmon_5.gif new file mode 100644 index 00000000000..59356beda0a Binary files /dev/null and b/icons/program_icons/smmon_5.gif differ diff --git a/icons/program_icons/smmon_6.gif b/icons/program_icons/smmon_6.gif new file mode 100644 index 00000000000..aea2f87921d Binary files /dev/null and b/icons/program_icons/smmon_6.gif differ diff --git a/nano/templates/supermatter_monitor.tmpl b/nano/templates/supermatter_monitor.tmpl new file mode 100644 index 00000000000..3bc87984d79 --- /dev/null +++ b/nano/templates/supermatter_monitor.tmpl @@ -0,0 +1,111 @@ +{{if data.active}} + {{:helper.link('Back to Menu', null, {'clear' : 1})}}
+
+
+ Core Integrity: +
+
+ {{:helper.displayBar(data.SM_integrity, 0, 100, (data.SM_integrity == 100) ? 'good' : (data.SM_integrity >= 50) ? 'average' : 'bad')}} {{:data.SM_integrity}}% +
+
+ Relative EER: +
+
+ {{if data.SM_power > 300}} + {{:data.SM_power}} MeV/cm3 + {{else data.SM_power > 150}} + {{:data.SM_power}} MeV/cm3 + {{else}} + {{:data.SM_power}} MeV/cm3 + {{/if}} +
+
+ Temperature: +
+
+ {{if data.SM_ambienttemp > 5000}} + {{:data.SM_ambienttemp}} K + {{else data.SM_ambienttemp > 4000}} + {{:data.SM_ambienttemp}} K + {{else}} + {{:data.SM_ambienttemp}} K + {{/if}} +
+
+ Pressure: +
+
+ {{if data.SM_ambientpressure > 10000}} + {{:data.SM_ambientpressure}} kPa + {{else data.SM_ambientpressure > 5000}} + {{:data.SM_ambientpressure}} kPa + {{else}} + {{:data.SM_ambientpressure}} kPa + {{/if}} +
+
+

+
+ Gas Composition: +
+
+
+
+ O2: +
+
+ {{:data.SM_gas_O2}} % +
+
+ CO2: +
+
+ {{:data.SM_gas_CO2}} % +
+
+ N2: +
+
+ {{:data.SM_gas_N2}} % +
+
+ PL: +
+
+ {{:data.SM_gas_PL}} % +
+
+ OTHER: +
+
+ {{:data.SM_gas_OTHER}} % +
+
+
+ +{{else}} + {{:helper.link('Refresh', null, {'refresh' : 1})}}
+ {{for data.supermatters}} +
+
+ Area: +
+
+ {{:value.area_name}} +
+
+ Integrity: +
+
+ {{:value.integrity}} % +
+
+ Options: +
+
+ {{:helper.link('View Details', null, {'set' : value.uid})}} +
+
+ {{/for}} +{{/if}} diff --git a/paradise.dme b/paradise.dme index 8fee7485f98..85bf34aeeac 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1854,6 +1854,7 @@ #include "code\modules\modular_computers\file_system\programs\command\comms.dm" #include "code\modules\modular_computers\file_system\programs\engineering\alarm.dm" #include "code\modules\modular_computers\file_system\programs\engineering\power_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\engineering\sm_monitor.dm" #include "code\modules\modular_computers\file_system\programs\generic\configurator.dm" #include "code\modules\modular_computers\file_system\programs\generic\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\generic\ntdownloader.dm" diff --git a/sound/machines/engine_alert2.ogg b/sound/machines/engine_alert2.ogg new file mode 100644 index 00000000000..83f693617a7 Binary files /dev/null and b/sound/machines/engine_alert2.ogg differ