diff --git a/code/modules/alarm/alarm_handler.dm b/code/modules/alarm/alarm_handler.dm index d7a7cdf713..22b069093a 100644 --- a/code/modules/alarm/alarm_handler.dm +++ b/code/modules/alarm/alarm_handler.dm @@ -50,6 +50,11 @@ /datum/alarm_handler/proc/major_alarms() return visible_alarms() +/datum/alarm_handler/proc/has_major_alarms() + if(alarms && alarms.len) + return 1 + return 0 + /datum/alarm_handler/proc/minor_alarms() return visible_alarms() diff --git a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm index 1a4922b5ec..2af92c74e5 100644 --- a/code/modules/modular_computers/NTNet/NTNRC/conversation.dm +++ b/code/modules/modular_computers/NTNet/NTNRC/conversation.dm @@ -1,4 +1,7 @@ +var/global/ntnrc_uid = 0 + /datum/ntnet_conversation/ + var/id = null var/title = "Untitled Conversation" var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator, var/list/messages = list() @@ -6,6 +9,8 @@ var/password /datum/ntnet_conversation/New() + id = ntnrc_uid + ntnrc_uid++ if(ntnet_global) ntnet_global.chat_channels.Add(src) ..() diff --git a/code/modules/modular_computers/computers/item/console_presets.dm b/code/modules/modular_computers/computers/item/console_presets.dm index 450c9e6383..4c7eb7b0d1 100644 --- a/code/modules/modular_computers/computers/item/console_presets.dm +++ b/code/modules/modular_computers/computers/item/console_presets.dm @@ -8,6 +8,7 @@ . = ..() if(!cpu) return + cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(cpu) if(_has_id_slot) cpu.card_slot = new/obj/item/weapon/computer_hardware/card_slot(cpu) if(_has_printer) diff --git a/code/modules/modular_computers/computers/item/modular_computer.dm b/code/modules/modular_computers/computers/item/modular_computer.dm index 35ea31a45b..e243d041c7 100644 --- a/code/modules/modular_computers/computers/item/modular_computer.dm +++ b/code/modules/modular_computers/computers/item/modular_computer.dm @@ -28,6 +28,7 @@ // Important hardware (must be installed for computer to work) + var/obj/item/weapon/computer_hardware/processor_unit/processor_unit // CPU. Without it the computer won't run. Better CPUs can run more programs at once. var/obj/item/weapon/computer_hardware/network_card/network_card // Network Card component of this computer. Allows connection to NTNet var/obj/item/weapon/computer_hardware/hard_drive/hard_drive // Hard Drive component of this computer. Stores programs and files. var/obj/item/weapon/computer_hardware/battery_module/battery_module // An internal power source for this computer. Can be recharged. @@ -36,6 +37,8 @@ var/obj/item/weapon/computer_hardware/nano_printer/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs. var/obj/item/weapon/computer_hardware/hard_drive/portable/portable_drive // Portable data storage + var/list/idle_threads = list() // Idle programs on background. They still receive process calls but can't be interacted with. + // Eject ID card from computer, if it has ID slot with card inside. /obj/item/modular_computer/verb/eject_id() @@ -69,6 +72,14 @@ card_slot.stored_card = null user << "You remove the card from \the [src]" +/obj/item/modular_computer/attack_ghost(var/mob/observer/dead/user) + if(enabled) + ui_interact(user) + else if(check_rights(R_ADMIN, 0, user)) + var/response = alert(user, "This computer is turned off. Would you like to turn it on?", "Admin Override", "Yes", "No") + if(response == "Yes") + turn_on(user) + /obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user) if(computer_emagged) user << "\The [src] was already emagged." @@ -151,13 +162,24 @@ /obj/item/modular_computer/attack_self(mob/user) if(enabled) ui_interact(user) - else if((battery_module && battery_module.battery.charge) || check_power_override()) // Battery-run and charged or non-battery but powered by APC. - user << "You press the power button and start up \the [src]" + else + turn_on(user) + +/obj/item/modular_computer/proc/turn_on(var/mob/user) + var/issynth = issilicon(user) // Robots and AIs get different activation messages. + if(processor_unit && ((battery_module && battery_module.battery.charge) || check_power_override())) // Battery-run and charged or non-battery but powered by APC. + if(issynth) + user << "You send an activation signal to \the [src], turning it on" + else + user << "You press the power button and start up \the [src]" enabled = 1 update_icon() ui_interact(user) else // Unpowered - user << "You press the power button but \the [src] does not respond." + if(issynth) + user << "You send an activation signal to \the [src] but it does not respond" + else + user << "You press the power button but \the [src] does not respond" // Process currently calls handle_power(), may be expanded in future if more things are added. /obj/item/modular_computer/process() @@ -169,11 +191,22 @@ kill_program(1) visible_message("\The [src]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.") + for(var/datum/computer_file/program/P in idle_threads) + if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) + P.kill_program(1) + idle_threads.Remove(P) + visible_message("\The [src] screen displays an \"Process [P.filename].[P.filetype] (PID [rand(100,999)]) terminated - Network Error\" error") + if(active_program) active_program.process_tick() active_program.ntnet_status = get_ntnet_status() active_program.computer_emagged = computer_emagged + for(var/datum/computer_file/program/P in idle_threads) + P.process_tick() + P.ntnet_status = get_ntnet_status() + P.computer_emagged = computer_emagged + handle_power() // Handles all computer power interaction // Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_" @@ -211,6 +244,17 @@ if(3) data["PC_ntneticon"] = "sig_lan.gif" + if(idle_threads.len) + var/list/program_headers = list() + for(var/datum/computer_file/program/P in idle_threads) + if(!P.ui_header) + continue + program_headers.Add(list(list( + "icon" = P.ui_header + ))) + + data["PC_programheaders"] = program_headers + data["PC_stationtime"] = stationtime2text() data["PC_hasheader"] = 1 data["PC_showexitprogram"] = active_program ? 1 : 0 // Hides "Exit Program" button on mainscreen @@ -238,9 +282,13 @@ return 0 return ntnet_global.add_log(text, network_card) -/obj/item/modular_computer/proc/shutdown_computer() +/obj/item/modular_computer/proc/shutdown_computer(var/loud = 1) kill_program(1) - visible_message("\The [src] shuts down.") + for(var/datum/computer_file/program/P in idle_threads) + P.kill_program(1) + idle_threads.Remove(P) + if(loud) + visible_message("\The [src] shuts down.") enabled = 0 update_icon() return @@ -265,6 +313,23 @@ if( href_list["PC_shutdown"] ) shutdown_computer() return + if( href_list["PC_minimize"] ) + var/mob/user = usr + if(!active_program || !processor_unit) + return + + if(idle_threads.len >= processor_unit.max_idle_programs) + user << "\The [src] displays a \"Maximal CPU load reached. Unable to minimize another program.\" error" + return + + idle_threads.Add(active_program) + active_program.running = 0 // Should close any existing UIs + SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program) + active_program = null + update_icon() + if(user && istype(user)) + ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. + if( href_list["PC_runprogram"] ) var/prog = href_list["PC_runprogram"] var/datum/computer_file/program/P = null @@ -280,6 +345,14 @@ if(!P.is_supported_by_hardware(hardware_flag, 1, user)) return + // The program is already running. Resume it. + if(P in idle_threads) + P.running = 1 + active_program = P + idle_threads.Remove(P) + update_icon() + return + if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet. user << "\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning." return @@ -292,9 +365,7 @@ /obj/item/modular_computer/proc/power_failure() if(enabled) // Shut down the computer visible_message("\The [src]'s screen flickers \"BATTERY CRITICAL\" warning as it shuts down unexpectedly.") - kill_program(1) - enabled = 0 - update_icon() + shutdown_computer(0) // Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged /obj/item/modular_computer/proc/handle_power() @@ -303,11 +374,9 @@ return 0 var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage - if(network_card && network_card.enabled) - power_usage += network_card.power_usage - - if(hard_drive && hard_drive.enabled) - power_usage += hard_drive.power_usage + for(var/obj/item/weapon/computer_hardware/H in get_all_components()) + if(H.enabled) + power_usage += H.power_usage if(battery_module) battery_module.battery.use(power_usage * CELLRATE) @@ -421,6 +490,12 @@ return found = 1 battery_module = H + else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit)) + if(processor_unit) + user << "This computer's processor slot is already occupied by \the [processor_unit]." + return + found = 1 + processor_unit = H if(found) user << "You install \the [H] into \the [src]" H.holder2 = src @@ -448,11 +523,15 @@ if(battery_module == H) battery_module = null found = 1 + if(processor_unit == H) + processor_unit = null + found = 1 + critical = 1 if(found) user << "You remove \the [H] from \the [src]." H.forceMove(get_turf(src)) H.holder2 = null - if(critical) + if(critical && enabled) user << "\The [src]'s screen freezes for few seconds and then displays an \"HARDWARE ERROR: Critical component disconnected. Please verify component connection and reboot the device. If the problem persists contact technical support for assistance.\" warning." kill_program(1) enabled = 0 @@ -473,6 +552,8 @@ return card_slot if(battery_module && (battery_module.name == name)) return battery_module + if(processor_unit && (processor_unit.name == name)) + return processor_unit return null // Returns list of all components @@ -490,4 +571,6 @@ all_components.Add(card_slot) if(battery_module) all_components.Add(battery_module) + if(processor_unit) + all_components.Add(processor_unit) return all_components \ No newline at end of file diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index c840f2717c..9dc87d3517 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -78,9 +78,7 @@ /obj/item/modular_computer/processor/shutdown_computer() if(!machinery_computer) return - kill_program(1) - visible_message("\The [machinery_computer] shuts down.") - enabled = 0 + ..() machinery_computer.update_icon() return diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 8771e15627..c3877cde06 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -27,6 +27,10 @@ var/obj/item/modular_computer/processor/cpu = null // CPU that handles most logic while this type only handles power and other specific things. +/obj/machinery/modular_computer/attack_ghost(var/mob/observer/dead/user) + if(cpu) + cpu.attack_ghost(user) + /obj/machinery/modular_computer/emag_act(var/remaining_charges, var/mob/user) return //cpu ? cpu.emag_act(remaining_charges, user) : NO_EMAG_ACT @@ -77,8 +81,7 @@ if(cpu && cpu.enabled) // Shut down the computer visible_message("\The [src]'s screen flickers [cpu.battery_module ? "\"BATTERY CRITICAL\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.") if(cpu) - cpu.kill_program(1) - cpu.enabled = 0 + cpu.shutdown_computer(0) battery_powered = 0 update_icon() stat |= NOPOWER diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index f75e8271b5..b6e63700f3 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -18,6 +18,8 @@ var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable. var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable. var/computer_emagged = 0 // Set to 1 if computer that's running us was emagged. Computer updates this every Process() tick + var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images! + /datum/computer_file/program/New(var/obj/item/modular_computer/comp = null) ..() @@ -35,6 +37,11 @@ temp.usage_flags = usage_flags return temp +// Relays icon update to the computer. +/datum/computer_file/program/proc/update_computer_icon() + if(computer) + computer.update_icon() + // Attempts to create a log in global ntnet datum. Returns 1 on success, 0 on fail. /datum/computer_file/program/proc/generate_network_log(var/text) if(computer) diff --git a/code/modules/modular_computers/file_system/programs/_engineering.dm b/code/modules/modular_computers/file_system/programs/_engineering.dm index d2a7521b43..83d1797af7 100644 --- a/code/modules/modular_computers/file_system/programs/_engineering.dm +++ b/code/modules/modular_computers/file_system/programs/_engineering.dm @@ -15,18 +15,37 @@ filename = "alarmmonitor" filedesc = "Alarm Monitoring" nanomodule_path = /datum/nano_module/alarm_monitor/engineering - program_icon_state = "alarm_monitor" + ui_header = "alarm_green.gif" + program_icon_state = "alert-green" extended_desc = "This program provides visual interface for station's alarm system." requires_ntnet = 1 network_destination = "alarm monitoring network" size = 5 + var/has_alert = 0 + +/datum/computer_file/program/alarm_monitor/process_tick() + ..() + var/datum/nano_module/alarm_monitor/NMA = NM + if(istype(NMA) && NMA.has_major_alarms()) + if(!has_alert) + program_icon_state = "alert-red" + ui_header = "alarm_red.gif" + update_computer_icon() + has_alert = 1 + else + if(has_alert) + program_icon_state = "alert-green" + ui_header = "alarm_green.gif" + update_computer_icon() + has_alert = 0 + return 1 /datum/computer_file/program/atmos_control filename = "atmoscontrol" filedesc = "Atmosphere Control" nanomodule_path = /datum/nano_module/atmos_control program_icon_state = "atmos_control" - extended_desc = "This program allows remote control of air alarms around the station" + extended_desc = "This program allows remote control of air alarms around the station. This program can not be run on tablet computers." required_access = access_atmospherics requires_ntnet = 1 network_destination = "atmospheric control system" @@ -39,7 +58,7 @@ filedesc = "RCON Remote Control" nanomodule_path = /datum/nano_module/rcon program_icon_state = "generic" - extended_desc = "This program allows remote control of power distribution systems around the station." + extended_desc = "This program allows remote control of power distribution systems around the station. This program can not be run on tablet computers." required_access = access_engine requires_ntnet = 1 network_destination = "RCON remote control system" diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index d148036ee5..c9c601a66d 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -10,6 +10,7 @@ requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD available_on_ntnet = 0 nanomodule_path = /datum/nano_module/computer_ntnetdownload/ + ui_header = "downloader_finished.gif" var/datum/computer_file/program/downloaded_file = null var/hacked_download = 0 var/download_completion = 0 //GQ of downloaded data. @@ -32,6 +33,8 @@ if(!computer || !computer.hard_drive || !computer.hard_drive.try_store_file(PRG)) return 0 + ui_header = "downloader_running.gif" + if(PRG in ntnet_global.available_station_software) generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.") hacked_download = 0 @@ -50,6 +53,7 @@ generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].") downloaded_file = null download_completion = 0 + ui_header = "downloader_finished.gif" /datum/computer_file/program/ntnetdownload/proc/complete_file_download() if(!downloaded_file) @@ -60,6 +64,7 @@ downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance." downloaded_file = null download_completion = 0 + ui_header = "downloader_finished.gif" /datum/computer_file/program/ntnetdownload/process_tick() if(!downloaded_file) diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index 3e38c9abeb..0fa9c7a96b 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -7,8 +7,10 @@ requires_ntnet = 1 requires_ntnet_feature = NTNET_COMMUNICATION network_destination = "NTNRC server" + ui_header = "ntnrc_idle.gif" available_on_ntnet = 1 nanomodule_path = /datum/nano_module/computer_chatclient/ + var/last_message = null // Used to generate the toolbar icon var/username var/datum/ntnet_conversation/channel = null var/operator_mode = 0 // Channel operator mode @@ -30,7 +32,7 @@ if(href_list["PRG_joinchannel"]) var/datum/ntnet_conversation/C for(var/datum/ntnet_conversation/chan in ntnet_global.chat_channels) - if(chan.title == href_list["PRG_joinchannel"]) + if(chan.id == text2num(href_list["PRG_joinchannel"])) C = chan break @@ -143,6 +145,20 @@ ..(href, href_list) +/datum/computer_file/program/chatclient/process_tick() + ..() + if(running) + ui_header = "ntnrc_idle.gif" + if(channel) + // Remember the last message. If there is no message in the channel remember null. + last_message = channel.messages.len ? channel.messages[channel.messages.len - 1] : null + else + last_message = null + return 1 + if(channel && channel.messages && channel.messages.len) + ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif" + else + ui_header = "ntnrc_idle.gif" /datum/computer_file/program/chatclient/kill_program(var/forced = 0) if(channel) @@ -188,7 +204,8 @@ for(var/datum/ntnet_conversation/conv in ntnet_global.chat_channels) if(conv && conv.title) all_channels.Add(list(list( - "chan" = conv.title + "chan" = conv.title, + "id" = conv.id ))) data["all_channels"] = all_channels diff --git a/code/modules/modular_computers/hardware/processor_unit.dm b/code/modules/modular_computers/hardware/processor_unit.dm new file mode 100644 index 0000000000..c258a3e5aa --- /dev/null +++ b/code/modules/modular_computers/hardware/processor_unit.dm @@ -0,0 +1,36 @@ +// CPU that allows the computer to run programs. +// Better CPUs are obtainable via research and can run more programs on background. + +/obj/item/weapon/computer_hardware/processor_unit + name = "standard processor" + desc = "A standard CPU used in most computers. It can run up to three programs simultaneously." + icon_state = "cpu_normal" + hardware_size = 2 + power_usage = 50 + critical = 1 + + var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description. + +/obj/item/weapon/computer_hardware/processor_unit/small + name = "standard microprocessor" + desc = "A standard miniaturised CPU used in portable devices. It can run up to two programs simultaneously." + icon_state = "cpu_small" + hardware_size = 1 + power_usage = 25 + max_idle_programs = 1 + +/obj/item/weapon/computer_hardware/processor_unit/photonic + name = "photonic processor" + desc = "An advanced experimental CPU that uses photonic core instead of regular circuitry. It can run up to five programs simultaneously, but uses a lot of power." + icon_state = "cpu_normal_photonic" + hardware_size = 2 + power_usage = 250 + max_idle_programs = 4 + +/obj/item/weapon/computer_hardware/processor_unit/photonic/small + name = "photonic microprocessor" + desc = "An advanced miniaturised CPU for use in portable devices. It uses photonic core instead of regular circuitry. It can run up to three programs simultaneously." + icon_state = "cpu_small_photonic" + hardware_size = 1 + power_usage = 75 + max_idle_programs = 2 \ No newline at end of file diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index fb4358d32d..4ce6e94e17 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -19,6 +19,7 @@ var/total_price = 0 // Price of currently vended device. // Device loadout + var/dev_cpu = 1 // 1: Default, 2: Upgraded var/dev_battery = 1 // 1: Default, 2: Upgraded, 3: Advanced var/dev_disk = 1 // 1: Default, 2: Upgraded, 3: Advanced var/dev_netcard = 0 // 0: None, 1: Basic, 2: Long-Range @@ -36,6 +37,7 @@ if(fabricated_tablet) qdel(fabricated_tablet) fabricated_tablet = null + dev_cpu = 1 dev_battery = 1 dev_disk = 1 dev_netcard = 0 @@ -50,17 +52,25 @@ if(fabricate) fabricated_laptop = new(src) total_price = 99 + switch(dev_cpu) + if(1) + if(fabricate) + fabricated_laptop.cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_laptop.cpu) + if(2) + if(fabricate) + fabricated_laptop.cpu.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit(fabricated_laptop.cpu) + total_price += 299 switch(dev_battery) if(1) // Basic(750C) if(fabricate) - fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_tablet) + fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module(fabricated_laptop.cpu) if(2) // Upgraded(1100C) if(fabricate) - fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(fabricated_tablet) + fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/advanced(fabricated_laptop.cpu) total_price += 199 if(3) // Advanced(1500C) if(fabricate) - fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(fabricated_tablet) + fabricated_laptop.cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(fabricated_laptop.cpu) total_price += 499 switch(dev_disk) if(1) // Basic(128GQ) @@ -100,6 +110,7 @@ else if(devtype == 2) // Tablet, more expensive, not everyone could probably afford this. if(fabricate) fabricated_tablet = new(src) + fabricated_tablet.processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(fabricated_tablet) total_price = 199 switch(dev_battery) if(1) // Basic(300C) @@ -169,6 +180,10 @@ state = 2 // Wait for ID swipe for payment processing fabricate_and_recalc_price(0) return 1 + if(href_list["hw_cpu"]) + dev_cpu = text2num(href_list["hw_cpu"]) + fabricate_and_recalc_price(0) + return 1 if(href_list["hw_battery"]) dev_battery = text2num(href_list["hw_battery"]) fabricate_and_recalc_price(0) @@ -213,6 +228,7 @@ data["hw_tesla"] = dev_tesla data["hw_nanoprint"] = dev_nanoprint data["hw_card"] = dev_card + data["hw_cpu"] = dev_cpu data["totalprice"] = "[total_price]$" ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) diff --git a/code/modules/nano/modules/alarm_monitor.dm b/code/modules/nano/modules/alarm_monitor.dm index 1a230dc908..7ca7a3a26b 100644 --- a/code/modules/nano/modules/alarm_monitor.dm +++ b/code/modules/nano/modules/alarm_monitor.dm @@ -37,6 +37,14 @@ return all_alarms +// Modified version of above proc that uses slightly less resources, returns 1 if there is a major alarm, 0 otherwise. +/datum/nano_module/alarm_monitor/proc/has_major_alarms() + for(var/datum/alarm_handler/AH in alarm_handlers) + if(AH.has_major_alarms()) + return 1 + + return 0 + /datum/nano_module/alarm_monitor/proc/minor_alarms() var/list/all_alarms = new() for(var/datum/alarm_handler/AH in alarm_handlers) diff --git a/code/modules/research/designs/modular_computer.dm b/code/modules/research/designs/modular_computer.dm index 618b0f801e..253087cb1e 100644 --- a/code/modules/research/designs/modular_computer.dm +++ b/code/modules/research/designs/modular_computer.dm @@ -200,3 +200,43 @@ materials = list(DEFAULT_WALL_MATERIAL = 4000) build_path = /obj/item/weapon/computer_hardware/battery_module/micro sort_string = "VBAAU" + +/datum/design/item/modularcomponent/cpu/ + name = "computer processor unit" + id = "cpu_normal" + req_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 8000) + chemicals = list("sacid" = 20) + build_path = /obj/item/weapon/computer_hardware/processor_unit + sort_string = "VBAAV" + +/datum/design/item/modularcomponent/cpu/small + name = "computer microprocessor unit" + id = "cpu_small" + req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 4000) + chemicals = list("sacid" = 20) + build_path = /obj/item/weapon/computer_hardware/processor_unit/small + sort_string = "VBAAW" + +/datum/design/item/modularcomponent/cpu/photonic + name = "computer photonic processor unit" + id = "pcpu_normal" + req_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 4) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 32000, glass = 8000) + chemicals = list("sacid" = 40) + build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic + sort_string = "VBAAX" + +/datum/design/item/modularcomponent/cpu/photonic/small + name = "computer photonic microprocessor unit" + id = "pcpu_small" + req_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) + build_type = IMPRINTER + materials = list(DEFAULT_WALL_MATERIAL = 16000, glass = 4000) + chemicals = list("sacid" = 20) + build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic/small + sort_string = "VBAAY" diff --git a/icons/obj/modular_components.dmi b/icons/obj/modular_components.dmi index e2aca17340..3594a12c17 100644 Binary files a/icons/obj/modular_components.dmi and b/icons/obj/modular_components.dmi differ diff --git a/icons/obj/modular_console.dmi b/icons/obj/modular_console.dmi index 7cadca6509..3b852ddb57 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 583def71e5..8ee252055c 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 fb0e1fd9c9..1872315f49 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/nano/images/status_icons/alarm_green.gif b/nano/images/status_icons/alarm_green.gif new file mode 100644 index 0000000000..7c2570c8ce Binary files /dev/null and b/nano/images/status_icons/alarm_green.gif differ diff --git a/nano/images/status_icons/alarm_red.gif b/nano/images/status_icons/alarm_red.gif new file mode 100644 index 0000000000..327d58e4db Binary files /dev/null and b/nano/images/status_icons/alarm_red.gif differ diff --git a/nano/images/status_icons/downloader_finished.gif b/nano/images/status_icons/downloader_finished.gif new file mode 100644 index 0000000000..f01b7c42af Binary files /dev/null and b/nano/images/status_icons/downloader_finished.gif differ diff --git a/nano/images/status_icons/downloader_running.gif b/nano/images/status_icons/downloader_running.gif new file mode 100644 index 0000000000..68fb977c86 Binary files /dev/null and b/nano/images/status_icons/downloader_running.gif differ diff --git a/nano/images/status_icons/ntnrc_idle.gif b/nano/images/status_icons/ntnrc_idle.gif new file mode 100644 index 0000000000..d47c01d580 Binary files /dev/null and b/nano/images/status_icons/ntnrc_idle.gif differ diff --git a/nano/images/status_icons/ntnrc_new.gif b/nano/images/status_icons/ntnrc_new.gif new file mode 100644 index 0000000000..af72a8b332 Binary files /dev/null and b/nano/images/status_icons/ntnrc_new.gif differ diff --git a/nano/templates/computer_fabricator.tmpl b/nano/templates/computer_fabricator.tmpl index 73de4cbd5a..2df5c3af2a 100644 --- a/nano/templates/computer_fabricator.tmpl +++ b/nano/templates/computer_fabricator.tmpl @@ -29,6 +29,10 @@
| {{:helper.link(value.chan, null, {'PRG_joinchannel' : value.chan})}} + |
| {{:helper.link(value.chan, null, {'PRG_joinchannel' : value.id})}} {{/for}} |