diff --git a/baystation12.dme b/baystation12.dme index 93cd06177e0..e3a4437f1a6 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1388,6 +1388,7 @@ #include "code\modules\modular_computers\file_system\computer_file.dm" #include "code\modules\modular_computers\file_system\data.dm" #include "code\modules\modular_computers\file_system\program.dm" +#include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\engineering.dm" #include "code\modules\modular_computers\hardware\card_slot.dm" #include "code\modules\modular_computers\hardware\hard_drive.dm" diff --git a/code/modules/modular_computers/computers/item/modular_computer.dm b/code/modules/modular_computers/computers/item/modular_computer.dm index a57c2e4e7ca..b4429a00d8d 100644 --- a/code/modules/modular_computers/computers/item/modular_computer.dm +++ b/code/modules/modular_computers/computers/item/modular_computer.dm @@ -10,7 +10,7 @@ var/open = 1 // Whether the computer is active/opened/it's screen is on. var/datum/computer_file/program/active_program = null // A currently active program running on the computer. var/hardware_flag = 0 // A flag that describes this device type - + var/last_power_usage = 0 // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..) // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently // If you create a program which is limited to Laptops and Consoles you don't have to add it's icon_state overlay for Tablets too, for example. @@ -148,6 +148,7 @@ // Process currently calls handle_power(), may be expanded in future if more things are added. /obj/item/modular_computer/process() if(!enabled) // The computer is turned off + last_power_usage = 0 return 0 if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) // Active program requires NTNet to run but we've just lost connection. Crash. @@ -188,6 +189,8 @@ data["PC_ntneticon"] = "sig_low.gif" if(2) data["PC_ntneticon"] = "sig_high.gif" + if(3) + data["PC_ntneticon"] = "sig_lan.gif" data["PC_stationtime"] = worldtime2text() data["PC_hasheader"] = 1 @@ -197,6 +200,9 @@ // Installs programs necessary for computer function. // TODO: Implement program for downloading of other programs, and replace hardcoded program addition here /obj/item/modular_computer/proc/install_default_programs() + hard_drive.store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar + + //TODO: Remove once downloading is implemented hard_drive.store_file(new/datum/computer_file/program/alarm_monitor(src)) hard_drive.store_file(new/datum/computer_file/program/power_monitor(src)) hard_drive.store_file(new/datum/computer_file/program/atmos_control(src)) @@ -227,6 +233,16 @@ if( href_list["PC_exit"] ) kill_program() return + if( href_list["PC_enable_component"] ) + var/datum/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"]) + if(H && istype(H) && !H.enabled) + H.enabled = 1 + return + if( href_list["PC_disable_component"] ) + var/datum/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"]) + if(H && istype(H) && H.enabled) + H.enabled = 0 + return if( href_list["PC_shutdown"] ) kill_program(1) visible_message("\The [src] shuts down.") @@ -278,6 +294,7 @@ if(battery) battery.use(power_usage * CELLRATE) + last_power_usage = power_usage /obj/item/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it. @@ -295,4 +312,16 @@ user << "You insert \the [I] into \the [src]." return - ..() \ No newline at end of file + ..() + +// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null +/obj/item/modular_computer/proc/find_hardware_by_name(var/name) + if(hard_drive && (hard_drive.name == name)) + return hard_drive + if(network_card && (network_card.name == name)) + return network_card + if(nano_printer && (nano_printer.name == name)) + return nano_printer + if(card_slot && (card_slot.name == name)) + return card_slot + return null \ No newline at end of file diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 4a12383eb29..0c3435e42e7 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -10,6 +10,7 @@ var/battery_powered = 0 // Whether computer should be battery powered. It is set automatically use_power = 0 var/hardware_flag = 0 // A flag that describes this device type + var/last_power_usage = 0 // Power usage during last tick // Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..) // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently @@ -76,9 +77,16 @@ card_slot.stored_card = null user << "You remove the card from \the [src]" +/obj/machinery/modular_computer/New() + ..() + install_default_programs() + // Installs programs necessary for computer function. // TODO: Implement program for downloading of other programs, and replace hardcoded program addition here /obj/machinery/modular_computer/proc/install_default_programs() + hard_drive.store_file(new/datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar + + //TODO: Remove once downloading is implemented hard_drive.store_file(new/datum/computer_file/program/alarm_monitor(src)) hard_drive.store_file(new/datum/computer_file/program/power_monitor(src)) hard_drive.store_file(new/datum/computer_file/program/atmos_control(src)) @@ -143,6 +151,7 @@ /obj/machinery/modular_computer/process() if(!enabled) // The computer is turned off use_power = 0 + last_power_usage = 0 return 0 if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) // Active program requires NTNet to run but we've just lost connection. Crash. @@ -185,6 +194,8 @@ data["PC_ntneticon"] = "sig_low.gif" if(2) data["PC_ntneticon"] = "sig_high.gif" + if(3) + data["PC_ntneticon"] = "sig_lan.gif" if(tesla_link && tesla_link.enabled && powered()) data["PC_apclinkicon"] = "charging.gif" @@ -212,6 +223,20 @@ else return 0 +// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null +/obj/machinery/modular_computer/proc/find_hardware_by_name(var/name) + if(hard_drive && (hard_drive.name == name)) + return hard_drive + if(network_card && (network_card.name == name)) + return network_card + if(tesla_link && (tesla_link.name == name)) + return tesla_link + if(nano_printer && (nano_printer.name == name)) + return nano_printer + if(card_slot && (card_slot.name == name)) + return card_slot + return null + // Handles user's GUI input /obj/machinery/modular_computer/Topic(href, href_list) if(..()) @@ -219,6 +244,16 @@ if( href_list["PC_exit"] ) kill_program() return + if( href_list["PC_enable_component"] ) + var/datum/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"]) + if(H && istype(H) && !H.enabled) + H.enabled = 1 + return + if( href_list["PC_disable_component"] ) + var/datum/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"]) + if(H && istype(H) && H.enabled) + H.enabled = 0 + return if( href_list["PC_shutdown"] ) kill_program(1) visible_message("\The [src] shuts down.") @@ -291,6 +326,7 @@ use_power = 0 if (battery) battery.use(power_usage * CELLRATE) + last_power_usage = power_usage // Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us. /obj/machinery/modular_computer/power_change() diff --git a/code/modules/modular_computers/computers/machinery/modular_console.dm b/code/modules/modular_computers/computers/machinery/modular_console.dm index 71f21ce51e9..2f24b3b0b51 100644 --- a/code/modules/modular_computers/computers/machinery/modular_console.dm +++ b/code/modules/modular_computers/computers/machinery/modular_console.dm @@ -8,14 +8,16 @@ icon_state_unpowered = "console" screen_icon_state_menu = "menu" keyboard_icon_state_menu = "kb_menu" + hardware_flag = PROGRAM_CONSOLE anchored = 1 density = 1 /obj/machinery/modular_computer/console/New() - ..() battery = null network_card = new/datum/computer_hardware/network_card/wired(src) tesla_link = new/datum/computer_hardware/tesla_link(src) tesla_link.enabled = 1 + tesla_link.critical = 1 // Consoles don't usually come with cells, and this prevents people from disabling their only power source, as they wouldn't be able to enable it again. hard_drive = new/datum/computer_hardware/hard_drive/super(src) // Consoles generally have better HDDs due to lower space limitations - install_default_programs() // Consoles come with set of department-specific programs when constructed. \ No newline at end of file + ..() + update_icon() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/machinery/modular_laptop.dm b/code/modules/modular_computers/computers/machinery/modular_laptop.dm index e193b976b60..bfe9dcb43d8 100644 --- a/code/modules/modular_computers/computers/machinery/modular_laptop.dm +++ b/code/modules/modular_computers/computers/machinery/modular_laptop.dm @@ -52,7 +52,7 @@ name = "laptop computer" desc = "A portable computer" var/obj/item/laptop/portable = null // Portable version of this computer, dropped on alt-click to allow transport. Used by laptops. - battery_powered = 1 // Laptops have integrated battery + hardware_flag = PROGRAM_LAPTOP icon_state_unpowered = "laptop-open" // Icon state when the computer is turned off icon = 'icons/obj/modular_laptop.dmi' icon_state = "laptop-open" diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 653d6dfdce6..f837301c68c 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -101,8 +101,8 @@ if(ui) ui.close() return 0 - if(NM) - NM.ui_interact(user, ui_key, ui, force_open) + if(istype(NM)) + NM.ui_interact(user, ui_key, null, force_open) return 0 return 1 diff --git a/code/modules/modular_computers/file_system/programs/configurator.dm b/code/modules/modular_computers/file_system/programs/configurator.dm new file mode 100644 index 00000000000..7d2698023ca --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/configurator.dm @@ -0,0 +1,82 @@ +// This is special hardware configuration program. +// It is to be used only with modular computers. +// It allows you to toggle components of your device. + +/datum/computer_file/program/computerconfig + filename = "compconfig" + filedesc = "Computer Configuration Tool" + program_icon_state = "generic" + unsendable = 1 + undeletable = 1 + size = 2 + nanomodule_path = /datum/nano_module/computer_configurator/ + +/datum/nano_module/computer_configurator + name = "NTOS Computer Configuration Tool" + var/obj/machinery/modular_computer/stationary = null + var/obj/item/modular_computer/movable = null + +/datum/nano_module/computer_configurator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + if(program) + stationary = program.computer + movable = program.computer + + if(!istype(stationary)) + stationary = null + if(!istype(movable)) + movable = null + + // No computer connection, we can't get data from that. + if(!movable && !stationary) + return 0 + + var/list/data = list() + + if(program) + data = program.get_header_data() + + var/list/hardware = list() + if(stationary) + hardware.Add(stationary.network_card) + hardware.Add(stationary.hard_drive) + hardware.Add(stationary.tesla_link) + hardware.Add(stationary.card_slot) + hardware.Add(stationary.nano_printer) + data["disk_size"] = stationary.hard_drive.max_capacity + data["disk_used"] = stationary.hard_drive.used_capacity + data["power_usage"] = stationary.last_power_usage + data["battery_exists"] = stationary.battery ? 1 : 0 + if(stationary.battery) + data["battery_rating"] = stationary.battery.maxcharge + data["battery_percent"] = round(stationary.battery.percent()) + else if(movable) + hardware.Add(movable.network_card) + hardware.Add(movable.hard_drive) + hardware.Add(movable.card_slot) + hardware.Add(movable.nano_printer) + data["disk_size"] = movable.hard_drive.max_capacity + data["disk_used"] = movable.hard_drive.used_capacity + data["power_usage"] = movable.last_power_usage + data["battery_exists"] = movable.battery ? 1 : 0 + if(movable.battery) + data["battery_rating"] = movable.battery.maxcharge + data["battery_percent"] = round(movable.battery.percent()) + + var/list/all_entries[0] + for(var/datum/computer_hardware/H in hardware) + all_entries.Add(list(list( + "name" = H.name, + "desc" = H.desc, + "enabled" = H.enabled, + "critical" = H.critical, + "powerusage" = H.power_usage + ))) + + data["hardware"] = all_entries + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "laptop_configuration.tmpl", "NTOS Configuration Utility", 575, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/engineering.dm b/code/modules/modular_computers/file_system/programs/engineering.dm index 562bd0a2251..234d6518ddb 100644 --- a/code/modules/modular_computers/file_system/programs/engineering.dm +++ b/code/modules/modular_computers/file_system/programs/engineering.dm @@ -27,7 +27,7 @@ required_access = access_atmospherics requires_ntnet = 1 requires_ntnet_feature = NTNET_SYSTEMCONTROL - usage_flags = PROGRAM_LAPTOP & PROGRAM_CONSOLE + usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE size = 17 /datum/computer_file/program/rcon_console @@ -39,7 +39,7 @@ required_access = access_engine requires_ntnet = 1 requires_ntnet_feature = NTNET_SYSTEMCONTROL - usage_flags = PROGRAM_LAPTOP & PROGRAM_CONSOLE + usage_flags = PROGRAM_LAPTOP | PROGRAM_CONSOLE size = 25 /datum/computer_file/program/suit_sensors diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 4c61718fffc..ea201f43494 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -392,6 +392,11 @@ nanoui is used to open and update nano browser uis if(!user.client) return + // An attempted fix to UIs sometimes locking up spamming runtime errors due to src_object being null for whatever reason. + // This hard-deletes the UI, preventing the device that uses the UI from being locked up permanently. + if(!src_object) + del(src) + var/window_size = "" if (width && height) window_size = "size=[width]x[height];" diff --git a/nano/images/status_icons/sig_lan.gif b/nano/images/status_icons/sig_lan.gif new file mode 100644 index 00000000000..07ba929f7f3 Binary files /dev/null and b/nano/images/status_icons/sig_lan.gif differ diff --git a/nano/templates/laptop_configuration.tmpl b/nano/templates/laptop_configuration.tmpl new file mode 100644 index 00000000000..69af3bd6c0f --- /dev/null +++ b/nano/templates/laptop_configuration.tmpl @@ -0,0 +1,70 @@ +Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device.
+

Power Supply

+
+ Battery Status: +
+{{if data.battery_exists}} +
+ Active +
+
+ Battery Rating: +
+
+ {{:data.battery_rating}} +
+
+ Battery Charge: +
+
+ {{:helper.displayBar(data.battery_percent, 0, 100, (data.battery_percent <= 25) ? 'bad' : (data.battery_percent <= 50) ? 'average' : 'good')}} + {{:data.battery_percent}} % +
+{{else}} +
+ Not Available +
+{{/if}} +
+ Power Usage: +
+
+ {{:data.power_usage}}W +
+

File System

+
+ Used Capacity: +
+
+ {{:helper.displayBar(data.disk_used, 0, data.disk_size, 'good')}} + {{:data.disk_used}}GQ / {{:data.disk_size}}GQ +
+

Computer Components

+{{for data.hardware}} +

{{:value.name}}

+ {{:value.desc}}
+
+ State: +
+
+ {{:value.enabled ? "Enabled" : "Disabled"}} +
+
+ Power Usage: +
+
+ {{:value.powerusage}}W +
+ {{if !value.critical}} +
+ Toggle Component: +
+
+ {{:helper.link("ON", null, {'PC_enable_component' : value.name}, value.enabled ? 'disabled' : null)}} + {{:helper.link("OFF", null, {'PC_disable_component' : value.name}, value.enabled ? null : 'disabled')}} +
+ {{/if}} +

+{{/for}} +

+NTOS v2.0.4b Copyright NanoTrasen 2557 - 2559 \ No newline at end of file diff --git a/nano/templates/laptop_mainscreen.tmpl b/nano/templates/laptop_mainscreen.tmpl index bc05416e830..649d1d3b93a 100644 --- a/nano/templates/laptop_mainscreen.tmpl +++ b/nano/templates/laptop_mainscreen.tmpl @@ -1,6 +1,6 @@ No program loaded. Please select program from list below. {{for data.programs}} -
{{:helper.link(value.desc, 'icon-power', {'PC_runprogram' : value.name})}} +
{{:helper.link(value.desc, null, {'PC_runprogram' : value.name})}} {{/for}}
\ No newline at end of file diff --git a/nano/templates/layout_default.tmpl b/nano/templates/layout_default.tmpl index c7f2bbc01a4..a5fd6f5804b 100644 --- a/nano/templates/layout_default.tmpl +++ b/nano/templates/layout_default.tmpl @@ -22,9 +22,9 @@
-
{{:helper.link('Shutdown', 'icon-power', {'PC_shutdown' : 1})}} + {{:helper.link('Shutdown', null, {'PC_shutdown' : 1})}} {{if data.PC_showexitprogram}} - {{:helper.link('Exit Program', 'icon-close', {'PC_exit' : 1})}} + {{:helper.link('Exit Program', null, {'PC_exit' : 1})}} {{/if}}