Updates Part Three

This commit is contained in:
Unknown
2019-04-03 18:20:23 -04:00
parent 05e51d5a80
commit b0c818b737
19 changed files with 164 additions and 65 deletions
@@ -10,6 +10,9 @@
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
var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged
var/last_world_time = "00:00"
var/list/last_header_icons
var/computer_emagged = 0 // Whether the computer is emagged.
var/base_active_power_usage = 50 // Power usage when the computer is open (screen is active) and can be interacted with. Remember hardware can use power too.
@@ -46,7 +49,7 @@
set category = "Object"
set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
if(usr.incapacitated() || !istype(usr, /mob/living))
usr << "<span class='warning'>You can't do that.</span>"
return
@@ -70,8 +73,15 @@
card_slot.stored_card.forceMove(get_turf(src))
card_slot.stored_card = null
update_uis()
user << "You remove the card from \the [src]"
if(active_program)
active_program.event_idremoved(0)
for(var/datum/computer_file/program/P in idle_threads)
P.event_idremoved(1)
/obj/item/modular_computer/attack_ghost(var/mob/observer/dead/user)
if(enabled)
ui_interact(user)
@@ -92,7 +102,7 @@
/obj/item/modular_computer/New()
START_PROCESSING(SSobj, src)
update_icon()
..()
return ..()
/obj/item/modular_computer/Destroy()
kill_program(1)
@@ -188,26 +198,30 @@
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.
kill_program(1)
visible_message("<span class='danger'>\The [src]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
active_program.event_networkfailure(0)
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("<span class='danger'>\The [src] screen displays an \"Process [P.filename].[P.filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
P.event_networkfailure(1)
if(active_program)
active_program.process_tick()
active_program.ntnet_status = get_ntnet_status()
active_program.computer_emagged = computer_emagged
if(active_program.program_state != PROGRAM_STATE_KILLED)
active_program.process_tick()
active_program.ntnet_status = get_ntnet_status()
active_program.computer_emagged = computer_emagged
else
active_program = null
for(var/datum/computer_file/program/P in idle_threads)
P.process_tick()
P.ntnet_status = get_ntnet_status()
P.computer_emagged = computer_emagged
if(P.program_state != PROGRAM_STATE_KILLED)
P.process_tick()
P.ntnet_status = get_ntnet_status()
P.computer_emagged = computer_emagged
else
idle_threads.Remove(P)
handle_power() // Handles all computer power interaction
check_update_ui_need()
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
/obj/item/modular_computer/proc/get_header_data()
@@ -299,20 +313,20 @@
return 1
if( href_list["PC_exit"] )
kill_program()
return
return 1
if( href_list["PC_enable_component"] )
var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"])
if(H && istype(H) && !H.enabled)
H.enabled = 1
return
return 1
if( href_list["PC_disable_component"] )
var/obj/item/weapon/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"])
if(H && istype(H) && H.enabled)
H.enabled = 0
return
return 1
if( href_list["PC_shutdown"] )
shutdown_computer()
return
return 1
if( href_list["PC_minimize"] )
var/mob/user = usr
if(!active_program || !processor_unit)
@@ -323,7 +337,7 @@
return
idle_threads.Add(active_program)
active_program.running = 0 // Should close any existing UIs
active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program)
active_program = null
update_icon()
@@ -347,7 +361,7 @@
// The program is already running. Resume it.
if(P in idle_threads)
P.running = 1
P.program_state = PROGRAM_STATE_ACTIVE
active_program = P
idle_threads.Remove(P)
update_icon()
@@ -359,12 +373,16 @@
if(P.run_program(user))
active_program = P
update_icon()
return
return 1
// Used in following function to reduce copypaste
/obj/item/modular_computer/proc/power_failure()
if(enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers \"BATTERY CRITICAL\" warning as it shuts down unexpectedly.</span>")
if(active_program)
active_program.event_powerfailure(0)
for(var/datum/computer_file/program/PRG in idle_threads)
PRG.event_powerfailure(1)
shutdown_computer(0)
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
@@ -380,6 +398,7 @@
if(battery_module)
battery_module.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)
@@ -395,6 +414,7 @@
user.drop_from_inventory(I)
card_slot.stored_card = I
I.forceMove(src)
update_uis()
user << "You insert \the [I] into \the [src]."
return
if(istype(W, /obj/item/weapon/paper))
@@ -573,4 +593,46 @@
all_components.Add(battery_module)
if(processor_unit)
all_components.Add(processor_unit)
return all_components
return all_components
/obj/item/modular_computer/proc/update_uis()
if(active_program) //Should we update program ui or computer ui?
SSnanoui.update_uis(active_program)
if(active_program.NM)
SSnanoui.update_uis(active_program.NM)
else
SSnanoui.update_uis(src)
/obj/item/modular_computer/proc/check_update_ui_need()
var/ui_updated_needed = 0
if(battery_module)
var/batery_percent = battery_module.battery.percent()
if(last_battery_percent != batery_percent) //Let's update UI on percent chandge
ui_updated_needed = 1
last_battery_percent = batery_percent
if(stationtime2text() != last_world_time)
last_world_time = stationtime2text()
ui_updated_needed = 1
if(idle_threads.len)
var/list/current_header_icons = list()
for(var/datum/computer_file/program/P in idle_threads)
if(!P.ui_header)
continue
current_header_icons[P.type] = P.ui_header
if(!last_header_icons)
last_header_icons = current_header_icons
else if(!listequal(last_header_icons, current_header_icons))
last_header_icons = current_header_icons
ui_updated_needed = 1
else
for(var/x in last_header_icons|current_header_icons)
if(last_header_icons[x]!=current_header_icons[x])
last_header_icons = current_header_icons
ui_updated_needed = 1
break
if(ui_updated_needed)
update_uis()
@@ -80,6 +80,7 @@
return
..()
machinery_computer.update_icon()
machinery_computer.use_power = 0
return
// Tesla links only work on machinery types, so we'll override the default try_install_component() proc
@@ -94,6 +95,7 @@
// Consoles don't usually have internal power source, so we can't disable tesla link in them.
if(istype(machinery_computer, /obj/machinery/modular_computer/console))
L.critical = 1
L.enabled = 1
found = 1
..(user, H, found)
@@ -3,6 +3,7 @@
/obj/item/modular_computer/tablet/preset/custom_loadout/cheap/New()
. = ..()
desc = "A low-end tablet often seen among low ranked station personnel"
processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src)
battery_module = new/obj/item/weapon/computer_hardware/battery_module/nano(src)
hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/micro(src)
network_card = new/obj/item/weapon/computer_hardware/network_card(src)
@@ -10,6 +11,7 @@
// Alternative version, an average one, for higher ranked positions mostly
/obj/item/modular_computer/tablet/preset/custom_loadout/advanced/New()
. = ..()
processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src)
battery_module = new/obj/item/weapon/computer_hardware/battery_module(src)
hard_drive = new/obj/item/weapon/computer_hardware/hard_drive/small(src)
network_card = new/obj/item/weapon/computer_hardware/network_card(src)
@@ -83,8 +83,8 @@
if(cpu)
cpu.shutdown_computer(0)
battery_powered = 0
update_icon()
stat |= NOPOWER
update_icon()
// Called by cpu item's process() automatically, handles our power interaction.
/obj/machinery/modular_computer/proc/handle_power()
@@ -133,6 +133,7 @@
return
else
..()
update_icon()
/obj/machinery/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(cpu)
@@ -5,7 +5,7 @@
var/required_access = null // List of required accesses to *run* the program.
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
var/running = 0 // Set to 1 when the program is run and back to 0 when it's stopped.
var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
var/obj/item/modular_computer/computer // Device that runs this program.
var/filedesc = "Unknown Program" // User-friendly name of this program.
var/extended_desc = "N/A" // Short description of this program's function.
@@ -96,13 +96,13 @@
NM.program = src // Set the program reference to separate variable, instead.
if(requires_ntnet && network_destination)
generate_network_log("Connection opened to [network_destination].")
running = 1
program_state = PROGRAM_STATE_ACTIVE
return 1
return 0
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
/datum/computer_file/program/proc/kill_program(var/forced = 0)
running = 0
program_state = PROGRAM_STATE_KILLED
if(network_destination)
generate_network_log("Connection to [network_destination] closed.")
if(NM)
@@ -113,7 +113,7 @@
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable.
/datum/computer_file/program/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!running) // Our program was closed. Close the ui if it exists.
if(program_state != PROGRAM_STATE_ACTIVE) // Our program was closed. Close the ui if it exists.
if(ui)
ui.close()
return computer.ui_interact(user)
@@ -129,6 +129,7 @@
// Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program)
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
/datum/computer_file/program/Topic(href, href_list)
if(..())
return 1
if(computer)
computer.Topic(href, href_list)
..()
return computer.Topic(href, href_list)
@@ -0,0 +1,18 @@
// Events are sent to the program by the computer.
// Always include a parent call when overriding an event.
// Called when the ID card is removed from computer. ID is removed AFTER this proc.
/datum/computer_file/program/proc/event_idremoved(var/background)
return
// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.
/datum/computer_file/program/proc/event_powerfailure(var/background)
kill_program(1)
// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met.
/datum/computer_file/program/proc/event_networkfailure(var/background)
kill_program(1)
if(background)
computer.visible_message("<span class='danger'>\The [computer]'s screen displays an \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
else
computer.visible_message("<span class='danger'>\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
@@ -6,10 +6,28 @@
nanomodule_path = /datum/nano_module/power_monitor/
program_icon_state = "power_monitor"
extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
ui_header = "power_norm.gif"
required_access = access_engine
requires_ntnet = 1
network_destination = "power monitoring system"
size = 9
var/has_alert = 0
/datum/computer_file/program/power_monitor/process_tick()
..()
var/datum/nano_module/power_monitor/NMA = NM
if(istype(NMA) && NMA.has_alarm())
if(!has_alert)
program_icon_state = "power_monitor_warn"
ui_header = "power_warn.gif"
update_computer_icon()
has_alert = 1
else
if(has_alert)
program_icon_state = "power_monitor"
ui_header = "power_norm.gif"
update_computer_icon()
has_alert = 0
/datum/computer_file/program/alarm_monitor
filename = "alarmmonitor"
@@ -24,7 +24,7 @@
dos_speed = NTNETSPEED_ETHERNET * 10
if(target && executed)
target.dos_overload += dos_speed
if(target.is_operational())
if(!target.is_operational())
target.dos_sources.Remove(src)
target = null
error = "Connection to destination relay lost."
@@ -89,8 +89,9 @@
target = R
return
if(href_list["PRG_reset"])
target.dos_sources.Remove(src)
target = null
if(target)
target.dos_sources.Remove(src)
target = null
executed = 0
error = ""
return
@@ -88,7 +88,7 @@
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(0)
/datum/nano_module/card_mod/proc/format_jobs(list/jobs)
var/obj/item/weapon/card/id/id_card = program.computer.card_slot.stored_card
@@ -16,25 +16,17 @@
/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
if(istype(movable, /obj/item/modular_computer/processor))
var/obj/item/modular_computer/processor/P = movable
stationary = P.machinery_computer
// No computer connection, we can't get data from that.
if(!movable && !stationary)
if(!movable)
return 0
var/list/data = list()
@@ -42,27 +34,15 @@
if(program)
data = program.get_header_data()
var/list/hardware = list()
if(stationary)
if(stationary.cpu)
movable = stationary.cpu
hardware.Add(stationary.tesla_link)
else
return
var/list/hardware = movable.get_all_components()
if(movable)
hardware.Add(movable.network_card)
hardware.Add(movable.hard_drive)
hardware.Add(movable.card_slot)
hardware.Add(movable.nano_printer)
hardware.Add(movable.battery_module)
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_module ? 1 : 0
if(movable.battery_module)
data["battery_rating"] = movable.battery_module.battery.maxcharge
data["battery_percent"] = round(movable.battery_module.battery.percent())
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_module ? 1 : 0
if(movable.battery_module)
data["battery_rating"] = movable.battery_module.battery.maxcharge
data["battery_percent"] = round(movable.battery_module.battery.percent())
var/list/all_entries[0]
for(var/obj/item/weapon/computer_hardware/H in hardware)
@@ -81,4 +61,4 @@
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(0)
@@ -223,5 +223,5 @@
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(0)
@@ -147,7 +147,7 @@
/datum/computer_file/program/chatclient/process_tick()
..()
if(running)
if(program_state != PROGRAM_STATE_KILLED)
ui_header = "ntnrc_idle.gif"
if(channel)
// Remember the last message. If there is no message in the channel remember null.