Configuration Utility + Fixes

- Adds a computer configuration utility program, that is pre-installed on each computer. This program shows detailed component information and offers component toggling possibility.
- Bandaid fix for NanoUI runtimes which seem to be caused by nanoUIs sometimes being somehow opened on null object. Such UI is force-deleted if this happens.
- Programs now have properly defined usage_flags (Note to self: AND is not OR!)
- Minor visual adjustment to buttons in UIs.
This commit is contained in:
Atlantis
2015-08-25 05:26:27 +02:00
parent e6cbd7866d
commit 01c5de790f
13 changed files with 237 additions and 12 deletions
@@ -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
..()
..()
// 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
@@ -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()
@@ -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.
..()
update_icon()
@@ -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"
@@ -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
@@ -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)
@@ -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