Modular Cmp Updates

This commit is contained in:
Letter N
2021-02-12 18:29:00 +08:00
parent 5db87b9065
commit 5b0a1077f4
46 changed files with 1311 additions and 318 deletions

View File

@@ -99,18 +99,18 @@
falloff_exponent = 5 falloff_exponent = 5
volume = 50 volume = 50
*/ */
// /datum/looping_sound/computer /datum/looping_sound/computer
// start_sound = 'sound/machines/computer/computer_start.ogg' start_sound = 'sound/machines/computer/computer_start.ogg'
// start_length = 7.2 SECONDS start_length = 7.2 SECONDS
// start_volume = 10 start_volume = 10
// mid_sounds = list('sound/machines/computer/computer_mid1.ogg'=1, 'sound/machines/computer/computer_mid2.ogg'=1) mid_sounds = list('sound/machines/computer/computer_mid1.ogg'=1, 'sound/machines/computer/computer_mid2.ogg'=1)
// mid_length = 1.8 SECONDS mid_length = 1.8 SECONDS
// end_sound = 'sound/machines/computer/computer_end.ogg' end_sound = 'sound/machines/computer/computer_end.ogg'
// end_volume = 10 end_volume = 10
// volume = 2 volume = 2
// falloff_exponent = 5 //Ultra quiet very fast falloff_exponent = 5 //Ultra quiet very fast
// extra_range = -12 extra_range = -12
// falloff_distance = 1 //Instant falloff after initial tile falloff_distance = 1 //Instant falloff after initial tile
// /datum/looping_sound/gravgen // /datum/looping_sound/gravgen
// mid_sounds = list('sound/machines/gravgen/gravgen_mid1.ogg'=1,'sound/machines/gravgen/gravgen_mid2.ogg'=1,'sound/machines/gravgen/gravgen_mid3.ogg'=1,'sound/machines/gravgen/gravgen_mid4.ogg'=1,) // mid_sounds = list('sound/machines/gravgen/gravgen_mid1.ogg'=1,'sound/machines/gravgen/gravgen_mid2.ogg'=1,'sound/machines/gravgen/gravgen_mid3.ogg'=1,'sound/machines/gravgen/gravgen_mid4.ogg'=1,)

View File

@@ -48,8 +48,8 @@
var/multiple_slots = istype(card_slot) && istype(card_slot2) var/multiple_slots = istype(card_slot) && istype(card_slot2)
if(card_slot) if(card_slot)
if(card_slot?.stored_card || card_slot2?.stored_card) if(card_slot?.stored_card || card_slot2?.stored_card)
var/obj/item/card/id/first_ID = card_slot.stored_card var/obj/item/card/id/first_ID = card_slot?.stored_card
var/obj/item/card/id/second_ID = card_slot2.stored_card var/obj/item/card/id/second_ID = card_slot2?.stored_card
var/multiple_cards = istype(first_ID) && istype(second_ID) var/multiple_cards = istype(first_ID) && istype(second_ID)
if(user_is_adjacent) if(user_is_adjacent)
. += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]." . += "It has [multiple_slots ? "two slots" : "a slot"] for identification cards installed[multiple_cards ? " which contain [first_ID] and [second_ID]" : ", one of which contains [first_ID ? first_ID : second_ID]"]."

View File

@@ -20,6 +20,10 @@
var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged
var/last_world_time = "00:00" var/last_world_time = "00:00"
var/list/last_header_icons var/list/last_header_icons
///Looping sound for when the computer is on
var/datum/looping_sound/computer/soundloop
///Whether or not this modular computer uses the looping sound
var/looping_sound = TRUE
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. 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.
var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops) var/base_idle_power_usage = 5 // Power usage when the computer is idle and screen is off (currently only applies to laptops)
@@ -56,11 +60,14 @@
physical = src physical = src
comp_light_color = "#FFFFFF" comp_light_color = "#FFFFFF"
idle_threads = list() idle_threads = list()
if(looping_sound)
soundloop = new(list(src), enabled)
update_icon() update_icon()
/obj/item/modular_computer/Destroy() /obj/item/modular_computer/Destroy()
kill_program(forced = TRUE) kill_program(forced = TRUE)
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
QDEL_NULL(soundloop)
for(var/H in all_components) for(var/H in all_components)
var/obj/item/computer_hardware/CH = all_components[H] var/obj/item/computer_hardware/CH = all_components[H]
if(CH.holder == src) if(CH.holder == src)
@@ -103,7 +110,6 @@
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2] var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
if(!(card_slot || card_slot2)) if(!(card_slot || card_slot2))
//to_chat(user, "<span class='warning'>There isn't anywhere you can fit a card into on this computer.</span>")
return FALSE return FALSE
var/obj/item/card/inserting_id = inserting_item.RemoveID() var/obj/item/card/inserting_id = inserting_item.RemoveID()
@@ -112,7 +118,6 @@
if((card_slot?.try_insert(inserting_id)) || (card_slot2?.try_insert(inserting_id))) if((card_slot?.try_insert(inserting_id)) || (card_slot2?.try_insert(inserting_id)))
return TRUE return TRUE
//to_chat(user, "<span class='warning'>This computer doesn't have an open card slot.</span>")
return FALSE return FALSE
/obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location) /obj/item/modular_computer/MouseDrop(obj/over_object, src_location, over_location)
@@ -198,7 +203,7 @@
to_chat(user, "<span class='warning'>You send an activation signal to \the [src], but it responds with an error code. It must be damaged.</span>") to_chat(user, "<span class='warning'>You send an activation signal to \the [src], but it responds with an error code. It must be damaged.</span>")
else else
to_chat(user, "<span class='warning'>You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.</span>") to_chat(user, "<span class='warning'>You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.</span>")
return return FALSE
// If we have a recharger, enable it automatically. Lets computer without a battery work. // If we have a recharger, enable it automatically. Lets computer without a battery work.
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
@@ -210,24 +215,28 @@
to_chat(user, "<span class='notice'>You send an activation signal to \the [src], turning it on.</span>") to_chat(user, "<span class='notice'>You send an activation signal to \the [src], turning it on.</span>")
else else
to_chat(user, "<span class='notice'>You press the power button and start up \the [src].</span>") to_chat(user, "<span class='notice'>You press the power button and start up \the [src].</span>")
if(looping_sound)
soundloop.start()
enabled = 1 enabled = 1
update_icon() update_icon()
ui_interact(user) ui_interact(user)
return TRUE
else // Unpowered else // Unpowered
if(issynth) if(issynth)
to_chat(user, "<span class='warning'>You send an activation signal to \the [src] but it does not respond.</span>") to_chat(user, "<span class='warning'>You send an activation signal to \the [src] but it does not respond.</span>")
else else
to_chat(user, "<span class='warning'>You press the power button but \the [src] does not respond.</span>") to_chat(user, "<span class='warning'>You press the power button but \the [src] does not respond.</span>")
return FALSE
// Process currently calls handle_power(), may be expanded in future if more things are added. // Process currently calls handle_power(), may be expanded in future if more things are added.
/obj/item/modular_computer/process() /obj/item/modular_computer/process(delta_time)
if(!enabled) // The computer is turned off if(!enabled) // The computer is turned off
last_power_usage = 0 last_power_usage = 0
return 0 return
if(obj_integrity <= integrity_failure * max_integrity) if(obj_integrity <= integrity_failure * max_integrity)
shutdown_computer() shutdown_computer()
return 0 return
if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature))
active_program.event_networkfailure(0) // Active program requires NTNet to run but we've just lost connection. Crash. active_program.event_networkfailure(0) // Active program requires NTNet to run but we've just lost connection. Crash.
@@ -239,7 +248,7 @@
if(active_program) if(active_program)
if(active_program.program_state != PROGRAM_STATE_KILLED) if(active_program.program_state != PROGRAM_STATE_KILLED)
active_program.process_tick() active_program.process_tick(delta_time)
active_program.ntnet_status = get_ntnet_status() active_program.ntnet_status = get_ntnet_status()
else else
active_program = null active_program = null
@@ -247,14 +256,36 @@
for(var/I in idle_threads) for(var/I in idle_threads)
var/datum/computer_file/program/P = I var/datum/computer_file/program/P = I
if(P.program_state != PROGRAM_STATE_KILLED) if(P.program_state != PROGRAM_STATE_KILLED)
P.process_tick() P.process_tick(delta_time)
P.ntnet_status = get_ntnet_status() P.ntnet_status = get_ntnet_status()
else else
idle_threads.Remove(P) idle_threads.Remove(P)
handle_power() // Handles all computer power interaction handle_power(delta_time) // Handles all computer power interaction
//check_update_ui_need() //check_update_ui_need()
/**
* Displays notification text alongside a soundbeep when requested to by a program.
*
* After checking tha the requesting program is allowed to send an alert, creates
* a visible message of the requested text alongside a soundbeep. This proc adds
* text to indicate that the message is coming from this device and the program
* on it, so the supplied text should be the exact message and ending punctuation.
*
* Arguments:
* The program calling this proc.
* The message that the program wishes to display.
*/
/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
playsound(src, sound, 50, TRUE)
visible_message("<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
var/mob/living/holder = loc
if(istype(holder))
to_chat(holder, "[icon2html(src)] <span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
// Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_" // Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_"
/obj/item/modular_computer/proc/get_header_data() /obj/item/modular_computer/proc/get_header_data()
var/list/data = list() var/list/data = list()
@@ -344,13 +375,76 @@
for(var/datum/computer_file/program/P in idle_threads) for(var/datum/computer_file/program/P in idle_threads)
P.kill_program(forced = TRUE) P.kill_program(forced = TRUE)
idle_threads.Remove(P) idle_threads.Remove(P)
if(looping_sound)
soundloop.stop()
if(loud) if(loud)
physical.visible_message("<span class='notice'>\The [src] shuts down.</span>") physical.visible_message("<span class='notice'>\The [src] shuts down.</span>")
enabled = 0 enabled = 0
update_icon() update_icon()
/**
* Toggles the computer's flashlight, if it has one.
*
* Called from ui_act(), does as the name implies.
* It is seperated from ui_act() to be overwritten as needed.
*/
/obj/item/modular_computer/proc/toggle_flashlight()
if(!has_light)
return FALSE
set_light_on(!light_on)
if(light_on)
set_light(comp_light_luminosity, 1, comp_light_color)
else
set_light(0)
return TRUE
/**
* Sets the computer's light color, if it has a light.
*
* Called from ui_act(), this proc takes a color string and applies it.
* It is seperated from ui_act() to be overwritten as needed.
* Arguments:
** color is the string that holds the color value that we should use. Proc auto-fails if this is null.
*/
/obj/item/modular_computer/proc/set_flashlight_color(color)
if(!has_light || !color)
return FALSE
comp_light_color = color
set_light_color(color)
update_light()
return TRUE
/obj/item/modular_computer/screwdriver_act(mob/user, obj/item/tool)
if(!all_components.len)
to_chat(user, "<span class='warning'>This device doesn't have any components installed.</span>")
return
var/list/component_names = list()
for(var/h in all_components)
var/obj/item/computer_hardware/H = all_components[h]
component_names.Add(H.name)
var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in sortList(component_names)
if(!choice)
return
if(!Adjacent(user))
return
var/obj/item/computer_hardware/H = find_hardware_by_name(choice)
if(!H)
return
uninstall_component(H, user)
return
/obj/item/modular_computer/attackby(obj/item/W as obj, mob/user as mob) /obj/item/modular_computer/attackby(obj/item/W as obj, mob/user as mob)
// Check for ID first
if(istype(W, /obj/item/card/id) && InsertID(W))
return
// Insert items into the components // Insert items into the components
for(var/h in all_components) for(var/h in all_components)
var/obj/item/computer_hardware/H = all_components[h] var/obj/item/computer_hardware/H = all_components[h]
@@ -386,31 +480,6 @@
to_chat(user, "<span class='notice'>You repair \the [src].</span>") to_chat(user, "<span class='notice'>You repair \the [src].</span>")
return return
if(W.tool_behaviour == TOOL_SCREWDRIVER)
if(!all_components.len)
to_chat(user, "<span class='warning'>This device doesn't have any components installed.</span>")
return
var/list/component_names = list()
for(var/h in all_components)
var/obj/item/computer_hardware/H = all_components[h]
component_names.Add(H.name)
var/choice = input(user, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in sortList(component_names)
if(!choice)
return
if(!Adjacent(user))
return
var/obj/item/computer_hardware/H = find_hardware_by_name(choice)
if(!H)
return
uninstall_component(H, user)
return
..() ..()
// Used by processor to relay qdel() to machinery type. // Used by processor to relay qdel() to machinery type.

View File

@@ -5,7 +5,7 @@
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger && recharger.check_functionality()) if(recharger?.check_functionality())
if(recharger.use_power(amount)) if(recharger.use_power(amount))
return TRUE return TRUE
@@ -22,7 +22,7 @@
/obj/item/modular_computer/proc/give_power(amount) /obj/item/modular_computer/proc/give_power(amount)
var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL]
if(battery_module && battery_module.battery) if(battery_module?.battery)
return battery_module.battery.give(amount) return battery_module.battery.give(amount)
return 0 return 0
@@ -41,10 +41,10 @@
shutdown_computer(0) shutdown_computer(0)
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged // Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
/obj/item/modular_computer/proc/handle_power() /obj/item/modular_computer/proc/handle_power(delta_time)
var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE] var/obj/item/computer_hardware/recharger/recharger = all_components[MC_CHARGE]
if(recharger) if(recharger)
recharger.process() recharger.process(delta_time)
var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage

View File

@@ -7,17 +7,17 @@
if(!enabled) if(!enabled)
if(ui) if(ui)
ui.close() ui.close()
return 0 return
if(!use_power()) if(!use_power())
if(ui) if(ui)
ui.close() ui.close()
return 0 return
// Robots don't really need to see the screen, their wireless connection works as long as computer is on. // Robots don't really need to see the screen, their wireless connection works as long as computer is on.
if(!screen_on && !issilicon(user)) if(!screen_on && !issilicon(user))
if(ui) if(ui)
ui.close() ui.close()
return 0 return
// If we have an active program switch to it now. // If we have an active program switch to it now.
if(active_program) if(active_program)
@@ -37,8 +37,8 @@
if (!ui) if (!ui)
ui = new(user, src, "NtosMain") ui = new(user, src, "NtosMain")
ui.set_autoupdate(TRUE) ui.set_autoupdate(TRUE)
ui.open() if(ui.open())
ui.send_asset(get_asset_datum(/datum/asset/simple/headers)) ui.send_asset(get_asset_datum(/datum/asset/simple/headers))
/obj/item/modular_computer/ui_data(mob/user) /obj/item/modular_computer/ui_data(mob/user)
@@ -47,7 +47,9 @@
data["login"] = list() data["login"] = list()
var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD]
data["cardholder"] = FALSE
if(cardholder) if(cardholder)
data["cardholder"] = TRUE
var/obj/item/card/id/stored_card = cardholder.GetID() var/obj/item/card/id/stored_card = cardholder.GetID()
if(stored_card) if(stored_card)
var/stored_name = stored_card.registered_name var/stored_name = stored_card.registered_name
@@ -74,11 +76,11 @@
data["programs"] = list() data["programs"] = list()
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
for(var/datum/computer_file/program/P in hard_drive.stored_files) for(var/datum/computer_file/program/P in hard_drive.stored_files)
var/running = 0 var/running = FALSE
if(P in idle_threads) if(P in idle_threads)
running = 1 running = TRUE
data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running)) data["programs"] += list(list("name" = P.filename, "desc" = P.filedesc, "running" = running, "icon" = P.program_icon, "alert" = P.alert_pending))
data["has_light"] = has_light data["has_light"] = has_light
data["light_on"] = light_on data["light_on"] = light_on
@@ -88,8 +90,10 @@
// Handles user's GUI input // Handles user's GUI input
/obj/item/modular_computer/ui_act(action, params) /obj/item/modular_computer/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
switch(action) switch(action)
if("PC_exit") if("PC_exit")
@@ -144,6 +148,7 @@
if(P in idle_threads) if(P in idle_threads)
P.program_state = PROGRAM_STATE_ACTIVE P.program_state = PROGRAM_STATE_ACTIVE
active_program = P active_program = P
P.alert_pending = FALSE
idle_threads.Remove(P) idle_threads.Remove(P)
update_icon() update_icon()
return return
@@ -159,16 +164,12 @@
return return
if(P.run_program(user)) if(P.run_program(user))
active_program = P active_program = P
P.alert_pending = FALSE
update_icon() update_icon()
return 1 return 1
if("PC_toggle_light") if("PC_toggle_light")
light_on = !light_on return toggle_flashlight()
if(light_on)
set_light(comp_light_luminosity, 1, comp_light_color)
else
set_light(0)
return TRUE
if("PC_light_color") if("PC_light_color")
var/mob/user = usr var/mob/user = usr
@@ -180,10 +181,7 @@
if(color_hex2num(new_color) < 200) //Colors too dark are rejected if(color_hex2num(new_color) < 200) //Colors too dark are rejected
to_chat(user, "<span class='warning'>That color is too dark! Choose a lighter one.</span>") to_chat(user, "<span class='warning'>That color is too dark! Choose a lighter one.</span>")
new_color = null new_color = null
comp_light_color = new_color return set_flashlight_color(new_color)
light_color = new_color
update_light()
return TRUE
if("PC_Eject_Disk") if("PC_Eject_Disk")
var/param = params["name"] var/param = params["name"]

View File

@@ -17,7 +17,7 @@
// No running around with open laptops in hands. // No running around with open laptops in hands.
item_flags = SLOWS_WHILE_IN_HAND item_flags = SLOWS_WHILE_IN_HAND
screen_on = 0 // Starts closed screen_on = FALSE // Starts closed
var/start_open = TRUE // unless this var is set to 1 var/start_open = TRUE // unless this var is set to 1
var/icon_state_closed = "laptop-closed" var/icon_state_closed = "laptop-closed"
var/w_class_open = WEIGHT_CLASS_BULKY var/w_class_open = WEIGHT_CLASS_BULKY
@@ -64,17 +64,18 @@
. = ..() . = ..()
if(over_object == usr || over_object == src) if(over_object == usr || over_object == src)
try_toggle_open(usr) try_toggle_open(usr)
else if(istype(over_object, /obj/screen/inventory/hand)) return
if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object var/obj/screen/inventory/hand/H = over_object
var/mob/M = usr var/mob/M = usr
if(!M.restrained() && !M.stat) if(M.stat != CONSCIOUS || M.restrained())
if(!isturf(loc) || !Adjacent(M)) return
return if(!isturf(loc) || !Adjacent(M))
M.put_in_hand(src, H.held_index) return
M.put_in_hand(src, H.held_index)
/obj/item/modular_computer/laptop/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/modular_computer/laptop/on_attack_hand(mob/user)
. = ..()
if(screen_on && isturf(loc)) if(screen_on && isturf(loc))
return attack_self(user) return attack_self(user)

View File

@@ -43,13 +43,6 @@
/obj/item/modular_computer/processor/relay_qdel() /obj/item/modular_computer/processor/relay_qdel()
qdel(machinery_computer) qdel(machinery_computer)
// This thing is not meant to be used on it's own, get topic data from our machinery owner.
//obj/item/modular_computer/processor/canUseTopic(atom/movable/M, be_close=FALSE, no_dexterity=FALSE, no_tk=FALSE)
// if(!machinery_computer)
// return 0
// return machinery_computer.canUseTopic(user, state)
/obj/item/modular_computer/processor/shutdown_computer() /obj/item/modular_computer/processor/shutdown_computer()
if(!machinery_computer) if(!machinery_computer)
return return
@@ -59,3 +52,9 @@
/obj/item/modular_computer/processor/attack_ghost(mob/user) /obj/item/modular_computer/processor/attack_ghost(mob/user)
ui_interact(user) ui_interact(user)
/obj/item/modular_computer/processor/alert_call(datum/computer_file/program/caller, alerttext)
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext)
return
playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
machinery_computer.visible_message("<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")

View File

@@ -14,6 +14,7 @@
slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT
has_light = TRUE //LED flashlight! has_light = TRUE //LED flashlight!
comp_light_luminosity = 2.3 //Same as the PDA comp_light_luminosity = 2.3 //Same as the PDA
looping_sound = FALSE
var/has_variants = TRUE var/has_variants = TRUE
var/finish_color = null var/finish_color = null
@@ -41,6 +42,7 @@
comp_light_luminosity = 6.3 comp_light_luminosity = 6.3
has_variants = FALSE has_variants = FALSE
device_theme = "syndicate" device_theme = "syndicate"
light_color = COLOR_RED
/obj/item/modular_computer/tablet/nukeops/emag_act(mob/user) /obj/item/modular_computer/tablet/nukeops/emag_act(mob/user)
if(!enabled) if(!enabled)
@@ -48,3 +50,98 @@
return FALSE return FALSE
to_chat(user, "<span class='notice'>You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\".</span>") to_chat(user, "<span class='notice'>You swipe \the [src]. It's screen briefly shows a message reading \"MEMORY CODE INJECTION DETECTED AND SUCCESSFULLY QUARANTINED\".</span>")
return FALSE return FALSE
/// Borg Built-in tablet interface
/obj/item/modular_computer/tablet/integrated
name = "modular interface"
icon_state = "tablet-silicon"
has_light = FALSE //tablet light button actually enables/disables the borg lamp
comp_light_luminosity = 0
has_variants = FALSE
///Ref to the borg we're installed in. Set by the borg during our creation.
var/mob/living/silicon/robot/borgo
///Ref to the RoboTact app. Important enough to borgs to deserve a ref.
var/datum/computer_file/program/robotact/robotact
///IC log that borgs can view in their personal management app
var/list/borglog = list()
/obj/item/modular_computer/tablet/integrated/Initialize(mapload)
. = ..()
vis_flags |= VIS_INHERIT_ID
borgo = loc
if(!istype(borgo))
borgo = null
stack_trace("[type] initialized outside of a borg, deleting.")
return INITIALIZE_HINT_QDEL
/obj/item/modular_computer/tablet/integrated/Destroy()
borgo = null
return ..()
/obj/item/modular_computer/tablet/integrated/turn_on(mob/user)
if(borgo?.stat != DEAD)
return ..()
return FALSE
/**
* Returns a ref to the RoboTact app, creating the app if need be.
*
* The RoboTact app is important for borgs, and so should always be available.
* This proc will look for it in the tablet's robotact var, then check the
* hard drive if the robotact var is unset, and finally attempt to create a new
* copy if the hard drive does not contain the app. If the hard drive rejects
* the new copy (such as due to lack of space), the proc will crash with an error.
* RoboTact is supposed to be undeletable, so these will create runtime messages.
*/
/obj/item/modular_computer/tablet/integrated/proc/get_robotact()
if(!borgo)
return null
if(!robotact)
var/obj/item/computer_hardware/hard_drive/hard_drive = all_components[MC_HDD]
robotact = hard_drive.find_file_by_name("robotact")
if(!robotact)
stack_trace("Cyborg [borgo] ( [borgo.type] ) was somehow missing their self-manage app in their tablet. A new copy has been created.")
robotact = new(hard_drive)
if(!hard_drive.store_file(robotact))
qdel(robotact)
robotact = null
CRASH("Cyborg [borgo]'s tablet hard drive rejected recieving a new copy of the self-manage app. To fix, check the hard drive's space remaining. Please make a bug report about this.")
return robotact
//Makes the light settings reflect the borg's headlamp settings
/obj/item/modular_computer/tablet/integrated/ui_data(mob/user)
. = ..()
.["has_light"] = TRUE
.["light_on"] = borgo?.lamp_enabled
.["comp_light_color"] = borgo?.lamp_color
//Makes the flashlight button affect the borg rather than the tablet
/obj/item/modular_computer/tablet/integrated/toggle_flashlight()
if(!borgo || QDELETED(borgo))
return FALSE
borgo.toggle_headlamp()
return TRUE
//Makes the flashlight color setting affect the borg rather than the tablet
/obj/item/modular_computer/tablet/integrated/set_flashlight_color(color)
if(!borgo || QDELETED(borgo) || !color)
return FALSE
borgo.lamp_color = color
borgo.toggle_headlamp(FALSE, TRUE)
return TRUE
/obj/item/modular_computer/tablet/integrated/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg')
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
return
borgo.playsound_local(src, sound, 50, TRUE)
to_chat(borgo, "<span class='notice'>The [src] displays a [caller.filedesc] notification: [alerttext]</span>")
/obj/item/modular_computer/tablet/integrated/syndicate
icon_state = "tablet-silicon-syndicate"
device_theme = "syndicate"
/obj/item/modular_computer/tablet/integrated/syndicate/Initialize()
. = ..()
borgo.lamp_color = COLOR_RED //Syndicate likes it red

View File

@@ -29,8 +29,7 @@
install_component(new /obj/item/computer_hardware/card_slot) install_component(new /obj/item/computer_hardware/card_slot)
install_component(new /obj/item/computer_hardware/network_card) install_component(new /obj/item/computer_hardware/network_card)
install_component(new /obj/item/computer_hardware/printer/mini) install_component(new /obj/item/computer_hardware/printer/mini)
hard_drive.store_file(new /datum/computer_file/program/bounty) hard_drive.store_file(new /datum/computer_file/program/shipping)
//hard_drive.store_file(new /datum/computer_file/program/shipping)
/obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize() //This will be defunct and will be replaced when NtOS PDAs are done /obj/item/modular_computer/tablet/preset/advanced/atmos/Initialize() //This will be defunct and will be replaced when NtOS PDAs are done
. = ..() . = ..()
@@ -38,8 +37,10 @@
/obj/item/modular_computer/tablet/preset/advanced/command/Initialize() /obj/item/modular_computer/tablet/preset/advanced/command/Initialize()
. = ..() . = ..()
var/obj/item/computer_hardware/hard_drive/small/hard_drive = find_hardware_by_name("solid state drive")
install_component(new /obj/item/computer_hardware/sensorpackage) install_component(new /obj/item/computer_hardware/sensorpackage)
install_component(new /obj/item/computer_hardware/card_slot/secondary) install_component(new /obj/item/computer_hardware/card_slot/secondary)
hard_drive.store_file(new /datum/computer_file/program/budgetorders)
/// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink. /// Given by the syndicate as part of the contract uplink bundle - loads in the Contractor Uplink.
/obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize() /obj/item/modular_computer/tablet/syndicate_contract_uplink/preset/uplink/Initialize()
@@ -67,3 +68,11 @@
install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer))
install_component(new /obj/item/computer_hardware/hard_drive/small/nukeops) install_component(new /obj/item/computer_hardware/hard_drive/small/nukeops)
install_component(new /obj/item/computer_hardware/network_card) install_component(new /obj/item/computer_hardware/network_card)
//Borg Built-in tablet
/obj/item/modular_computer/tablet/integrated/Initialize()
. = ..()
install_component(new /obj/item/computer_hardware/processor_unit/small)
install_component(new /obj/item/computer_hardware/hard_drive/small/integrated)
install_component(new /obj/item/computer_hardware/recharger/cyborg)
install_component(new /obj/item/computer_hardware/network_card/integrated)

View File

@@ -48,7 +48,7 @@
cpu.attack_ghost(user) cpu.attack_ghost(user)
/obj/machinery/modular_computer/emag_act(mob/user) /obj/machinery/modular_computer/emag_act(mob/user)
. = ..() . = ..()
if(!cpu) if(!cpu)
to_chat(user, "<span class='warning'>You'd need to turn the [src] on first.</span>") to_chat(user, "<span class='warning'>You'd need to turn the [src] on first.</span>")
return FALSE return FALSE
@@ -59,7 +59,7 @@
icon_state = icon_state_powered icon_state = icon_state_powered
if(!cpu || !cpu.enabled) if(!cpu || !cpu.enabled)
if (!(stat & NOPOWER) && (cpu && cpu.use_power())) if (!(stat & NOPOWER) && (cpu?.use_power()))
add_overlay(screen_icon_screensaver) add_overlay(screen_icon_screensaver)
else else
icon_state = icon_state_unpowered icon_state = icon_state_unpowered
@@ -88,16 +88,16 @@
return ..() return ..()
// Process currently calls handle_power(), may be expanded in future if more things are added. // Process currently calls handle_power(), may be expanded in future if more things are added.
/obj/machinery/modular_computer/process() /obj/machinery/modular_computer/process(delta_time)
if(cpu) if(cpu)
// Keep names in sync. // Keep names in sync.
cpu.name = name cpu.name = name
cpu.process() cpu.process(delta_time)
// Used in following function to reduce copypaste // Used in following function to reduce copypaste
/obj/machinery/modular_computer/proc/power_failure(malfunction = 0) /obj/machinery/modular_computer/proc/power_failure(malfunction = 0)
var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL] var/obj/item/computer_hardware/battery/battery_module = cpu.all_components[MC_CELL]
if(cpu && cpu.enabled) // Shut down the computer if(cpu?.enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.</span>") visible_message("<span class='danger'>\The [src]'s screen flickers [battery_module ? "\"BATTERY [malfunction ? "MALFUNCTION" : "CRITICAL"]\"" : "\"EXTERNAL POWER LOSS\""] warning as it shuts down unexpectedly.</span>")
if(cpu) if(cpu)
cpu.shutdown_computer(0) cpu.shutdown_computer(0)
@@ -106,14 +106,18 @@
// Modular computers can have battery in them, we handle power in previous proc, so prevent this from messing it up for us. // 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() /obj/machinery/modular_computer/power_change()
if(cpu && cpu.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline. if(cpu?.use_power()) // If MC_CPU still has a power source, PC wouldn't go offline.
stat &= ~NOPOWER stat &= ~NOPOWER
update_icon() update_icon()
return return
. = ..() . = ..()
/obj/machinery/modular_computer/screwdriver_act(mob/user, obj/item/tool)
if(cpu)
return cpu.screwdriver_act(user, tool)
/obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/user) /obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/user)
if(cpu && !(flags_1 & NODECONSTRUCT_1)) if (user.a_intent == INTENT_HELP && cpu && !(flags_1 & NODECONSTRUCT_1))
return cpu.attackby(W, user) return cpu.attackby(W, user)
return ..() return ..()
@@ -125,11 +129,11 @@
cpu.ex_act(severity) cpu.ex_act(severity)
// switch(severity) // switch(severity)
// if(EXPLODE_DEVASTATE) // if(EXPLODE_DEVASTATE)
// SSexplosions.highobj += cpu // SSexplosions.high_mov_atom += cpu
// if(EXPLODE_HEAVY) // if(EXPLODE_HEAVY)
// SSexplosions.medobj += cpu // SSexplosions.med_mov_atom += cpu
// if(EXPLODE_LIGHT) // if(EXPLODE_LIGHT)
// SSexplosions.lowobj += cpu // SSexplosions.low_mov_atom += cpu
..() ..()
// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components // EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components

View File

@@ -37,7 +37,7 @@
var/obj/item/computer_hardware/network_card/wired/network_card = new() var/obj/item/computer_hardware/network_card/wired/network_card = new()
cpu.install_component(network_card) cpu.install_component(network_card)
cpu.install_component(new /obj/item/computer_hardware/recharger/APC) cpu.install_component(new /obj/item/computer_hardware/recharger/apc_recharger)
cpu.install_component(new /obj/item/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations cpu.install_component(new /obj/item/computer_hardware/hard_drive/super) // Consoles generally have better HDDs due to lower space limitations
var/area/A = get_area(src) var/area/A = get_area(src)

View File

@@ -33,6 +33,14 @@
var/tgui_id var/tgui_id
/// 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 /icons/program_icons. Be careful not to use too large images! /// 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 /icons/program_icons. Be careful not to use too large images!
var/ui_header = null var/ui_header = null
/// Font Awesome icon to use as this program's icon in the modular computer main menu. Defaults to a basic program maximize window icon if not overridden.
var/program_icon = "window-maximize-o"
/// Whether this program can send alerts while minimized or closed. Used to show a mute button per program in the file manager
var/alert_able = FALSE
/// Whether the user has muted this program's ability to send alerts.
var/alert_silenced = FALSE
/// Whether to highlight our program in the main screen. Intended for alerts, but loosely available for any need to notify of changed conditions. Think Windows task bar highlighting. Available even if alerts are muted.
var/alert_pending = FALSE
/datum/computer_file/program/New(obj/item/modular_computer/comp = null) /datum/computer_file/program/New(obj/item/modular_computer/comp = null)
..() ..()
@@ -68,8 +76,8 @@
if(!(hardware_flag & usage_flags)) if(!(hardware_flag & usage_flags))
if(loud && computer && user) if(loud && computer && user)
to_chat(user, "<span class='danger'>\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.</span>") to_chat(user, "<span class='danger'>\The [computer] flashes a \"Hardware Error - Incompatible software\" warning.</span>")
return 0 return FALSE
return 1 return TRUE
/datum/computer_file/program/proc/get_signal(specific_action = 0) /datum/computer_file/program/proc/get_signal(specific_action = 0)
if(computer) if(computer)
@@ -77,21 +85,21 @@
return 0 return 0
// Called by Process() on device that runs us, once every tick. // Called by Process() on device that runs us, once every tick.
/datum/computer_file/program/proc/process_tick() /datum/computer_file/program/proc/process_tick(delta_time)
return 1 return TRUE
/** /**
*Check if the user can run program. Only humans can operate computer. Automatically called in run_program() *Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
*ID must be inserted into a card slot to be read. If the program is not currently installed (as is the case when *ID must be inserted into a card slot to be read. If the program is not currently installed (as is the case when
*NT Software Hub is checking available software), a list can be given to be used instead. *NT Software Hub is checking available software), a list can be given to be used instead.
*Arguments: *Arguments:
*user is a ref of the mob using the device. *user is a ref of the mob using the device.
*loud is a bool deciding if this proc should use to_chats *loud is a bool deciding if this proc should use to_chats
*access_to_check is an access level that will be checked against the ID *access_to_check is an access level that will be checked against the ID
*transfer, if TRUE and access_to_check is null, will tell this proc to use the program's transfer_access in place of access_to_check *transfer, if TRUE and access_to_check is null, will tell this proc to use the program's transfer_access in place of access_to_check
*access can contain a list of access numbers to check against. If access is not empty, it will be used istead of checking any inserted ID. *access can contain a list of access numbers to check against. If access is not empty, it will be used istead of checking any inserted ID.
*/ */
/datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE, var/list/access) /datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE, list/access)
// Defaults to required_access // Defaults to required_access
if(!access_to_check) if(!access_to_check)
if(transfer && transfer_access) if(transfer && transfer_access)
@@ -147,19 +155,19 @@
ID = card_holder.GetID() ID = card_holder.GetID()
generate_network_log("Connection opened -- Program ID: [filename] User:[ID?"[ID.registered_name]":"None"]") generate_network_log("Connection opened -- Program ID: [filename] User:[ID?"[ID.registered_name]":"None"]")
program_state = PROGRAM_STATE_ACTIVE program_state = PROGRAM_STATE_ACTIVE
return 1 return TRUE
return 0 return FALSE
/** /**
* *
*Called by the device when it is emagged. *Called by the device when it is emagged.
* *
*Emagging the device allows certain programs to unlock new functions. However, the program will *Emagging the device allows certain programs to unlock new functions. However, the program will
*need to be downloaded first, and then handle the unlock on their own in their run_emag() proc. *need to be downloaded first, and then handle the unlock on their own in their run_emag() proc.
*The device will allow an emag to be run multiple times, so the user can re-emag to run the *The device will allow an emag to be run multiple times, so the user can re-emag to run the
*override again, should they download something new. The run_emag() proc should return TRUE if *override again, should they download something new. The run_emag() proc should return TRUE if
*the emagging affected anything, and FALSE if no change was made (already emagged, or has no *the emagging affected anything, and FALSE if no change was made (already emagged, or has no
*emag functions). *emag functions).
**/ **/
/datum/computer_file/program/proc/run_emag() /datum/computer_file/program/proc/run_emag()
return FALSE return FALSE
@@ -179,8 +187,8 @@
ui = SStgui.try_update_ui(user, src, ui) ui = SStgui.try_update_ui(user, src, ui)
if(!ui && tgui_id) if(!ui && tgui_id)
ui = new(user, src, tgui_id, filedesc) ui = new(user, src, tgui_id, filedesc)
ui.open() if(ui.open())
ui.send_asset(get_asset_datum(/datum/asset/simple/headers)) ui.send_asset(get_asset_datum(/datum/asset/simple/headers))
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC: // CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
// Topic calls are automagically forwarded from NanoModule this program contains. // Topic calls are automagically forwarded from NanoModule this program contains.
@@ -188,18 +196,20 @@
// Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program) // Calls beginning with "PC_" are reserved for computer handling (by whatever runs the program)
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE. // ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
/datum/computer_file/program/ui_act(action,list/params,datum/tgui/ui) /datum/computer_file/program/ui_act(action,list/params,datum/tgui/ui)
if(..()) . = ..()
return 1 if(.)
return
if(computer) if(computer)
switch(action) switch(action)
if("PC_exit") if("PC_exit")
computer.kill_program() computer.kill_program()
ui.close() ui.close()
return 1 return TRUE
if("PC_shutdown") if("PC_shutdown")
computer.shutdown_computer() computer.shutdown_computer()
ui.close() ui.close()
return 1 return TRUE
if("PC_minimize") if("PC_minimize")
var/mob/user = usr var/mob/user = usr
if(!computer.active_program || !computer.all_components[MC_CPU]) if(!computer.active_program || !computer.all_components[MC_CPU])

View File

@@ -9,6 +9,7 @@
transfer_access = ACCESS_HEADS transfer_access = ACCESS_HEADS
available_on_ntnet = TRUE available_on_ntnet = TRUE
tgui_id = "NtosAiRestorer" tgui_id = "NtosAiRestorer"
program_icon = "laptop-code"
/// Variable dictating if we are in the process of restoring the AI in the inserted intellicard /// Variable dictating if we are in the process of restoring the AI in the inserted intellicard
var/restoring = FALSE var/restoring = FALSE
@@ -19,7 +20,7 @@
if(computer) if(computer)
ai_slot = computer.all_components[MC_AI] ai_slot = computer.all_components[MC_AI]
if(computer && ai_slot && ai_slot.check_functionality()) if(computer && ai_slot?.check_functionality())
if(cardcheck == 1) if(cardcheck == 1)
return ai_slot return ai_slot
if(ai_slot.enabled && ai_slot.stored_card) if(ai_slot.enabled && ai_slot.stored_card)
@@ -31,7 +32,8 @@
return return
/datum/computer_file/program/aidiag/ui_act(action, params) /datum/computer_file/program/aidiag/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
var/mob/living/silicon/ai/A = get_ai() var/mob/living/silicon/ai/A = get_ai()
@@ -47,7 +49,7 @@
if("PRG_eject") if("PRG_eject")
if(computer.all_components[MC_AI]) if(computer.all_components[MC_AI])
var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI] var/obj/item/computer_hardware/ai_slot/ai_slot = computer.all_components[MC_AI]
if(ai_slot && ai_slot.stored_card) if(ai_slot?.stored_card)
ai_slot.try_eject(usr) ai_slot.try_eject(usr)
return TRUE return TRUE
@@ -72,10 +74,10 @@
restoring = FALSE restoring = FALSE
return return
ai_slot.locked = TRUE ai_slot.locked = TRUE
A.adjustOxyLoss(-5, 0)//, FALSE) A.adjustOxyLoss(-5, FALSE)
A.adjustFireLoss(-5, 0)//, FALSE) A.adjustFireLoss(-5, FALSE)
A.adjustToxLoss(-5, 0) A.adjustToxLoss(-5, FALSE)
A.adjustBruteLoss(-5, 0) A.adjustBruteLoss(-5, FALSE)
// Please don't forget to update health, otherwise the below if statements will probably always fail. // Please don't forget to update health, otherwise the below if statements will probably always fail.
A.updatehealth() A.updatehealth()

View File

@@ -7,6 +7,7 @@
requires_ntnet = 1 requires_ntnet = 1
size = 5 size = 5
tgui_id = "NtosStationAlertConsole" tgui_id = "NtosStationAlertConsole"
program_icon = "bell"
var/has_alert = 0 var/has_alert = 0
var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list()) var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list())

View File

@@ -9,6 +9,7 @@
unsendable = 1 unsendable = 1
undeletable = 1 undeletable = 1
tgui_id = "SyndContractor" tgui_id = "SyndContractor"
program_icon = "tasks"
var/error = "" var/error = ""
var/info_screen = TRUE var/info_screen = TRUE
var/assigned = FALSE var/assigned = FALSE
@@ -18,8 +19,9 @@
. = ..(user) . = ..(user)
/datum/computer_file/program/contract_uplink/ui_act(action, params) /datum/computer_file/program/contract_uplink/ui_act(action, params)
if(..()) . = ..()
return TRUE if(.)
return
var/mob/living/user = usr var/mob/living/user = usr
var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = computer.all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/small/syndicate/hard_drive = computer.all_components[MC_HDD]

View File

@@ -8,6 +8,7 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
available_on_syndinet = TRUE available_on_syndinet = TRUE
tgui_id = "NtosNetDos" tgui_id = "NtosNetDos"
program_icon = "satellite-dish"
var/obj/machinery/ntnet_relay/target = null var/obj/machinery/ntnet_relay/target = null
var/dos_speed = 0 var/dos_speed = 0
@@ -39,7 +40,8 @@
..() ..()
/datum/computer_file/program/ntnet_dos/ui_act(action, params) /datum/computer_file/program/ntnet_dos/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
if("PRG_target_relay") if("PRG_target_relay")

View File

@@ -8,6 +8,7 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
available_on_syndinet = TRUE available_on_syndinet = TRUE
tgui_id = "NtosRevelation" tgui_id = "NtosRevelation"
program_icon = "magnet"
var/armed = 0 var/armed = 0
/datum/computer_file/program/revelation/run_program(mob/living/user) /datum/computer_file/program/revelation/run_program(mob/living/user)
@@ -17,6 +18,12 @@
/datum/computer_file/program/revelation/proc/activate() /datum/computer_file/program/revelation/proc/activate()
if(computer) if(computer)
if(istype(computer, /obj/item/modular_computer/tablet/integrated)) //If this is a borg's integrated tablet
var/obj/item/modular_computer/tablet/integrated/modularInterface = computer
to_chat(modularInterface.borgo,"<span class='userdanger'>SYSTEM PURGE DETECTED/</span>")
addtimer(CALLBACK(modularInterface.borgo, /mob/living/silicon/robot/.proc/death), 2 SECONDS, TIMER_UNIQUE)
return
computer.visible_message("<span class='notice'>\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.</span>") computer.visible_message("<span class='notice'>\The [computer]'s screen brightly flashes and loud electrical buzzing is heard.</span>")
computer.enabled = FALSE computer.enabled = FALSE
computer.update_icon() computer.update_icon()
@@ -39,7 +46,8 @@
/datum/computer_file/program/revelation/ui_act(action, params) /datum/computer_file/program/revelation/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
if("PRG_arm") if("PRG_arm")

View File

@@ -6,6 +6,7 @@
requires_ntnet = FALSE requires_ntnet = FALSE
size = 6 size = 6
tgui_id = "NtosArcade" tgui_id = "NtosArcade"
program_icon = "gamepad"
///Returns TRUE if the game is being played. ///Returns TRUE if the game is being played.
var/game_active = TRUE var/game_active = TRUE
@@ -27,7 +28,7 @@
// user?.mind?.adjust_experience(/datum/skill/gaming, 1) // user?.mind?.adjust_experience(/datum/skill/gaming, 1)
if(boss_hp <= 0) if(boss_hp <= 0)
heads_up = "You have crushed [boss_name]! Rejoice!" heads_up = "You have crushed [boss_name]! Rejoice!"
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/win.ogg', 50)
game_active = FALSE game_active = FALSE
program_icon_state = "arcade_off" program_icon_state = "arcade_off"
if(istype(computer)) if(istype(computer))
@@ -37,7 +38,7 @@
sleep(10) sleep(10)
else if(player_hp <= 0 || player_mp <= 0) else if(player_hp <= 0 || player_mp <= 0)
heads_up = "You have been defeated... how will the station survive?" heads_up = "You have been defeated... how will the station survive?"
playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/lose.ogg', 50)
game_active = FALSE game_active = FALSE
program_icon_state = "arcade_off" program_icon_state = "arcade_off"
if(istype(computer)) if(istype(computer))
@@ -57,17 +58,17 @@
return return
if (boss_mp <= 5) if (boss_mp <= 5)
heads_up = "[boss_mpamt] magic power has been stolen from you!" heads_up = "[boss_mpamt] magic power has been stolen from you!"
playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE)
player_mp -= boss_mpamt player_mp -= boss_mpamt
boss_mp += boss_mpamt boss_mp += boss_mpamt
else if(boss_mp > 5 && boss_hp <12) else if(boss_mp > 5 && boss_hp <12)
heads_up = "[boss_name] heals for [bossheal] health!" heads_up = "[boss_name] heals for [bossheal] health!"
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE)
boss_hp += bossheal boss_hp += bossheal
boss_mp -= boss_mpamt boss_mp -= boss_mpamt
else else
heads_up = "[boss_name] attacks you for [boss_attackamt] damage!" heads_up = "[boss_name] attacks you for [boss_attackamt] damage!"
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE)
player_hp -= boss_attackamt player_hp -= boss_attackamt
pause_state = FALSE pause_state = FALSE
@@ -91,22 +92,27 @@
return data return data
/datum/computer_file/program/arcade/ui_act(action, list/params) /datum/computer_file/program/arcade/ui_act(action, list/params)
if(..()) . = ..()
return TRUE if(.)
return
var/obj/item/computer_hardware/printer/printer var/obj/item/computer_hardware/printer/printer
if(computer) if(computer)
printer = computer.all_components[MC_PRINT] printer = computer.all_components[MC_PRINT]
// var/gamerSkillLevel = usr.mind?.get_skill_level(/datum/skill/gaming) // var/gamerSkillLevel = 0
// var/gamerSkill = usr.mind?.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER) var/gamerSkill = 0
// if(usr?.mind)
// gamerSkillLevel = usr.mind.get_skill_level(/datum/skill/gaming)
// gamerSkill = usr.mind.get_skill_modifier(/datum/skill/gaming, SKILL_RANDS_MODIFIER)
switch(action) switch(action)
if("Attack") if("Attack")
var/attackamt = 0 //Spam prevention. var/attackamt = 0 //Spam prevention.
if(pause_state == FALSE) if(pause_state == FALSE)
attackamt = rand(2,6)// + rand(0, gamerSkill) attackamt = rand(2,6) + rand(0, gamerSkill)
pause_state = TRUE pause_state = TRUE
heads_up = "You attack for [attackamt] damage." heads_up = "You attack for [attackamt] damage."
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE)
boss_hp -= attackamt boss_hp -= attackamt
sleep(10) sleep(10)
game_check() game_check()
@@ -116,14 +122,14 @@
var/healamt = 0 //More Spam Prevention. var/healamt = 0 //More Spam Prevention.
var/healcost = 0 var/healcost = 0
if(pause_state == FALSE) if(pause_state == FALSE)
healamt = rand(6,8)// + rand(0, gamerSkill) healamt = rand(6,8) + rand(0, gamerSkill)
var/maxPointCost = 3 var/maxPointCost = 3
// if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN) // if(gamerSkillLevel >= SKILL_LEVEL_JOURNEYMAN)
// maxPointCost = 2 // maxPointCost = 2
healcost = rand(1, maxPointCost) healcost = rand(1, maxPointCost)
pause_state = TRUE pause_state = TRUE
heads_up = "You heal for [healamt] damage." heads_up = "You heal for [healamt] damage."
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE)
player_hp += healamt player_hp += healamt
player_mp -= healcost player_mp -= healcost
sleep(10) sleep(10)
@@ -133,10 +139,10 @@
if("Recharge_Power") if("Recharge_Power")
var/rechargeamt = 0 //As above. var/rechargeamt = 0 //As above.
if(pause_state == FALSE) if(pause_state == FALSE)
rechargeamt = rand(4,7)// + rand(0, gamerSkill) rechargeamt = rand(4,7) + rand(0, gamerSkill)
pause_state = TRUE pause_state = TRUE
heads_up = "You regain [rechargeamt] magic power." heads_up = "You regain [rechargeamt] magic power."
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3) playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE)
player_mp += rechargeamt player_mp += rechargeamt
sleep(10) sleep(10)
game_check() game_check()
@@ -153,7 +159,7 @@
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>") computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
if(ticket_count >= 1) if(ticket_count >= 1)
new /obj/item/stack/arcadeticket((get_turf(computer)), 1) new /obj/item/stack/arcadeticket((get_turf(computer)), 1)
to_chat(usr, "<span class='notice'>[computer] dispenses a ticket!</span>") to_chat(usr, "<span class='notice'>[src] dispenses a ticket!</span>")
ticket_count -= 1 ticket_count -= 1
printer.stored_paper -= 1 printer.stored_paper -= 1
else else

View File

@@ -5,6 +5,7 @@
extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device."
size = 4 size = 4
tgui_id = "NtosAtmos" tgui_id = "NtosAtmos"
program_icon = "thermometer-half"
/datum/computer_file/program/atmosscan/run_program(mob/living/user) /datum/computer_file/program/atmosscan/run_program(mob/living/user)
. = ..() . = ..()
@@ -39,5 +40,6 @@
return data return data
/datum/computer_file/program/atmosscan/ui_act(action, list/params) /datum/computer_file/program/atmosscan/ui_act(action, list/params)
if(..()) . = ..()
return TRUE if(.)
return

View File

@@ -8,6 +8,7 @@
transfer_access = ACCESS_ROBOTICS transfer_access = ACCESS_ROBOTICS
size = 5 size = 5
tgui_id = "NtosCyborgRemoteMonitor" tgui_id = "NtosCyborgRemoteMonitor"
program_icon = "project-diagram"
/datum/computer_file/program/borg_monitor/ui_data(mob/user) /datum/computer_file/program/borg_monitor/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
@@ -43,7 +44,8 @@
return data return data
/datum/computer_file/program/borg_monitor/ui_act(action, params) /datum/computer_file/program/borg_monitor/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
@@ -54,10 +56,14 @@
var/ID = checkID() var/ID = checkID()
if(!ID) if(!ID)
return return
if(R.stat == DEAD) //Dead borgs will listen to you no longer
to_chat(usr, "<span class='warn'>Error -- Could not open a connection to unit:[R]</span>")
var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message") var/message = stripped_input(usr, message = "Enter message to be sent to remote cyborg.", title = "Send Message")
if(!message) if(!message)
return return
to_chat(R, "<br><br><span class='notice'>Message from [ID] -- \"[message]\"</span><br>") to_chat(R, "<br><br><span class='notice'>Message from [ID] -- \"[message]\"</span><br>")
to_chat(usr, "Message sent to [R]: [message]")
R.logevent("Message from [ID] -- \"[message]\"")
SEND_SOUND(R, 'sound/machines/twobeep_high.ogg') SEND_SOUND(R, 'sound/machines/twobeep_high.ogg')
if(R.connected_ai) if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID] to [R] -- \"[message]\"</span><br>") to_chat(R.connected_ai, "<br><br><span class='notice'>Message from [ID] to [R] -- \"[message]\"</span><br>")

View File

@@ -44,7 +44,8 @@
return data return data
/datum/computer_file/program/bounty_board/ui_act(action, list/params) /datum/computer_file/program/bounty_board/ui_act(action, list/params)
if(..()) . = ..()
if(.)
return return
var/current_ref_num = params["request"] var/current_ref_num = params["request"]
var/current_app_num = params["applicant"] var/current_app_num = params["applicant"]

View File

@@ -0,0 +1,280 @@
/datum/computer_file/program/budgetorders
filename = "orderapp"
filedesc = "Nanotrasen Internal Requisition Network (NIRN)"
program_icon_state = "request"
extended_desc = "A request network that utilizes the Nanotrasen Ordering network to purchase supplies using a department budget account."
requires_ntnet = TRUE
transfer_access = ACCESS_HEADS
usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET
size = 20
tgui_id = "NtosCargo"
///Are you actually placing orders with it?
var/requestonly = TRUE
///Can the tablet see or buy illegal stuff?
var/contraband = FALSE
///Is it being bought from a personal account, or is it being done via a budget/cargo?
var/self_paid = FALSE
///Can this console approve purchase requests?
var/can_approve_requests = FALSE
///What do we say when the shuttle moves with living beings on it.
var/safety_warning = "For safety reasons, the automated supply shuttle \
cannot transport live organisms, human remains, classified nuclear weaponry, \
homing beacons or machinery housing any form of artificial intelligence."
///If you're being raided by pirates, what do you tell the crew?
var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
/datum/computer_file/program/budgetorders/proc/get_export_categories()
. = EXPORT_CARGO
/datum/computer_file/program/budgetorders/proc/is_visible_pack(mob/user, paccess_to_check, list/access, contraband)
if(issilicon(user)) //Borgs can't buy things.
return FALSE
if(computer.obj_flags & EMAGGED)
return TRUE
else if(contraband) //Hide contrband when non-emagged.
return FALSE
if(!paccess_to_check) // No required_access, allow it.
return TRUE
if(isAdminGhostAI(user))
return TRUE
//Aquire access from the inserted ID card.
if(!length(access))
var/obj/item/card/id/D
var/obj/item/computer_hardware/card_slot/card_slot
if(computer)
card_slot = computer.all_components[MC_CARD]
D = card_slot?.GetID()
if(!D)
return FALSE
access = D.GetAccess()
if(paccess_to_check in access)
return TRUE
return FALSE
/datum/computer_file/program/budgetorders/ui_data()
. = ..()
var/list/data = get_header_data()
data["location"] = SSshuttle.supply.getStatusText()
var/datum/bank_account/buyer = SSeconomy.get_dep_account(ACCOUNT_CAR)
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
var/obj/item/card/id/id_card = card_slot?.GetID()
if(id_card?.registered_account)
if(ACCESS_HEADS in id_card.access)
requestonly = FALSE
buyer = SSeconomy.get_dep_account(id_card.registered_account.account_job.paycheck_department)
can_approve_requests = TRUE
else
requestonly = TRUE
can_approve_requests = FALSE
else
requestonly = TRUE
if(buyer)
data["points"] = buyer.account_balance
//Otherwise static data, that is being applied in ui_data as the crates visible and buyable are not static, and are determined by inserted ID.
data["requestonly"] = requestonly
data["supplies"] = list()
for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
if(!is_visible_pack(usr, P.access_view , null, P.contraband) || P.hidden)
continue
if(!data["supplies"][P.group])
data["supplies"][P.group] = list(
"name" = P.group,
"packs" = list()
)
if((P.hidden && (P.contraband && !contraband) || (P.special && !P.special_enabled) || P.DropPodOnly))
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,
"access" = P.access
))
//Data regarding the User's capability to buy things.
data["has_id"] = id_card
data["away"] = SSshuttle.supply.getDockedId() == "supply_away"
data["self_paid"] = self_paid
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
data["loan"] = !!SSshuttle.shuttle_loan
data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched
data["can_send"] = FALSE //There is no situation where I want the app to be able to send the shuttle AWAY from the station, but conversely is fine.
data["can_approve_requests"] = can_approve_requests
data["app_cost"] = TRUE
var/message = "Remember to stamp and send back the supply manifests."
if(SSshuttle.centcom_message)
message = SSshuttle.centcom_message
if(SSshuttle.supplyBlocked)
message = blockade_warning
data["message"] = message
data["cart"] = list()
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"id" = SO.id,
"orderer" = SO.orderer,
"paid" = !isnull(SO.paying_account) //paid by requester
))
data["requests"] = list()
for(var/datum/supply_order/SO in SSshuttle.requestlist)
data["requests"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"orderer" = SO.orderer,
"reason" = SO.reason,
"id" = SO.id
))
return data
/datum/computer_file/program/budgetorders/ui_act(action, params, datum/tgui/ui)
if(..())
return
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
switch(action)
if("send")
if(!SSshuttle.supply.canMove())
computer.say(safety_warning)
return
if(SSshuttle.supplyBlocked)
computer.say(blockade_warning)
return
if(SSshuttle.supply.getDockedId() == "supply_home")
SSshuttle.supply.export_categories = get_export_categories()
SSshuttle.moveShuttle("supply", "supply_away", TRUE)
computer.say("The supply shuttle is departing.")
computer.investigate_log("[key_name(usr)] sent the supply shuttle away.", INVESTIGATE_CARGO)
else
computer.investigate_log("[key_name(usr)] called the supply shuttle.", INVESTIGATE_CARGO)
computer.say("The supply shuttle has been called and will arrive in [SSshuttle.supply.timeLeft(600)] minutes.")
SSshuttle.moveShuttle("supply", "supply_home", TRUE)
. = TRUE
if("loan")
if(!SSshuttle.shuttle_loan)
return
if(SSshuttle.supplyBlocked)
computer.say(blockade_warning)
return
else if(SSshuttle.supply.mode != SHUTTLE_IDLE)
return
else if(SSshuttle.supply.getDockedId() != "supply_away")
return
else
SSshuttle.shuttle_loan.loan_shuttle()
computer.say("The supply shuttle has been loaned to CentCom.")
computer.investigate_log("[key_name(usr)] accepted a shuttle loan event.", INVESTIGATE_CARGO)
log_game("[key_name(usr)] accepted a shuttle loan event.")
. = TRUE
if("add")
var/id = text2path(params["id"])
var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
if(!istype(pack))
return
if((pack.hidden && (pack.contraband && !contraband) || pack.DropPodOnly))
return
var/name = "*None Provided*"
var/rank = "*None Provided*"
var/ckey = usr.ckey
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
name = H.get_authentification_name()
rank = H.get_assignment(hand_first = TRUE)
else if(issilicon(usr))
name = usr.real_name
rank = "Silicon"
var/datum/bank_account/account
if(self_paid)
var/mob/living/carbon/human/H = usr
var/obj/item/card/id/id_card = H.get_idcard(TRUE)
if(!istype(id_card))
computer.say("No ID card detected.")
return
if(istype(id_card, /obj/item/card/id/departmental_budget))
computer.say("The [src] rejects [id_card].")
return
account = id_card.registered_account
if(!istype(account))
computer.say("Invalid bank account.")
return
var/reason = ""
if((requestonly && !self_paid) || !(card_slot?.GetID()))
reason = stripped_input("Reason:", name, "")
if(isnull(reason) || ..())
return
if(pack.goody && !self_paid)
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
computer.say("ERROR: Small crates may only be purchased by private accounts.")
return
if(!self_paid && ishuman(usr) && !account)
var/obj/item/card/id/id_card = card_slot?.GetID()
account = SSeconomy.get_dep_account(id_card?.registered_account?.account_job.paycheck_department)
var/turf/T = get_turf(src)
var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account)
SO.generateRequisition(T)
if((requestonly && !self_paid) || !(card_slot?.GetID()))
SSshuttle.requestlist += SO
else
SSshuttle.shoppinglist += SO
if(self_paid)
computer.say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.")
. = TRUE
if("remove")
var/id = text2num(params["id"])
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
if(SO.id == id)
SSshuttle.shoppinglist -= SO
. = TRUE
break
if("clear")
SSshuttle.shoppinglist.Cut()
. = TRUE
if("approve")
var/id = text2num(params["id"])
for(var/datum/supply_order/SO in SSshuttle.requestlist)
if(SO.id == id)
var/obj/item/card/id/id_card = card_slot?.GetID()
if(id_card && id_card?.registered_account)
SO.paying_account = SSeconomy.get_dep_account(id_card?.registered_account?.account_job.paycheck_department)
SSshuttle.requestlist -= SO
SSshuttle.shoppinglist += SO
. = TRUE
break
if("deny")
var/id = text2num(params["id"])
for(var/datum/supply_order/SO in SSshuttle.requestlist)
if(SO.id == id)
SSshuttle.requestlist -= SO
. = TRUE
break
if("denyall")
SSshuttle.requestlist.Cut()
. = TRUE
if("toggleprivate")
self_paid = !self_paid
. = TRUE
if(.)
post_signal("supply")
/datum/computer_file/program/budgetorders/proc/post_signal(command)
var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
if(!frequency)
return
var/datum/signal/status_signal = new(list("command" = command))
frequency.post_signal(src, status_signal)

View File

@@ -15,6 +15,7 @@
requires_ntnet = 0 requires_ntnet = 0
size = 8 size = 8
tgui_id = "NtosCard" tgui_id = "NtosCard"
program_icon = "id-card"
var/is_centcom = FALSE var/is_centcom = FALSE
var/minor = FALSE var/minor = FALSE
@@ -94,8 +95,9 @@
return FALSE return FALSE
/datum/computer_file/program/card_mod/ui_act(action, params) /datum/computer_file/program/card_mod/ui_act(action, params)
if(..()) . = ..()
return TRUE if(.)
return
var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/card_slot/card_slot
var/obj/item/computer_hardware/card_slot/card_slot2 var/obj/item/computer_hardware/card_slot/card_slot2
@@ -130,7 +132,7 @@
if(!authenticated) if(!authenticated)
return return
var/contents = {"<h4>Access Report</h4> var/contents = {"<h4>Access Report</h4>
<u>Prepared By:</u> [user_id_card && user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br> <u>Prepared By:</u> [user_id_card?.registered_name ? user_id_card.registered_name : "Unknown"]<br>
<u>For:</u> [target_id_card.registered_name ? target_id_card.registered_name : "Unregistered"]<br> <u>For:</u> [target_id_card.registered_name ? target_id_card.registered_name : "Unregistered"]<br>
<hr> <hr>
<u>Assignment:</u> [target_id_card.assignment]<br> <u>Assignment:</u> [target_id_card.assignment]<br>
@@ -175,7 +177,7 @@
if("PRG_edit") if("PRG_edit")
if(!computer || !authenticated || !target_id_card) if(!computer || !authenticated || !target_id_card)
return return
var/new_name = reject_bad_name(params["name"]) var/new_name = params["name"]
if(!new_name) if(!new_name)
return return
target_id_card.registered_name = new_name target_id_card.registered_name = new_name
@@ -190,7 +192,7 @@
return return
if(target == "Custom") if(target == "Custom")
var/custom_name = reject_bad_name(params["custom_name"]) var/custom_name = params["custom_name"]
if(custom_name) if(custom_name)
target_id_card.assignment = custom_name target_id_card.assignment = custom_name
target_id_card.update_label() target_id_card.update_label()
@@ -320,32 +322,31 @@
/datum/computer_file/program/card_mod/ui_data(mob/user) /datum/computer_file/program/card_mod/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
data["station_name"] = station_name()
var/obj/item/computer_hardware/card_slot/card_slot2 var/obj/item/computer_hardware/card_slot/card_slot2
var/obj/item/computer_hardware/printer/printer var/obj/item/computer_hardware/printer/printer
if(computer) if(computer)
card_slot2 = computer.all_components[MC_CARD2] card_slot2 = computer.all_components[MC_CARD2]
printer = computer.all_components[MC_PRINT] printer = computer.all_components[MC_PRINT]
data["station_name"] = station_name()
if(computer)
data["have_id_slot"] = !!(card_slot2) data["have_id_slot"] = !!(card_slot2)
data["have_printer"] = !!printer data["have_printer"] = !!(printer)
else else
data["have_id_slot"] = FALSE data["have_id_slot"] = FALSE
data["have_printer"] = FALSE data["have_printer"] = FALSE
data["authenticated"] = authenticated data["authenticated"] = authenticated
if(!card_slot2)
return data //We're just gonna error out on the js side at this point anyway
if(computer) var/obj/item/card/id/id_card = card_slot2.stored_card
var/obj/item/card/id/id_card = card_slot2.stored_card data["has_id"] = !!id_card
data["has_id"] = !!id_card data["id_name"] = id_card ? id_card.name : "-----"
data["id_name"] = id_card ? id_card.name : "-----" if(id_card)
if(id_card) data["id_rank"] = id_card.assignment ? id_card.assignment : "Unassigned"
data["id_rank"] = id_card.assignment ? id_card.assignment : "Unassigned" data["id_owner"] = id_card.registered_name ? id_card.registered_name : "-----"
data["id_owner"] = id_card.registered_name ? id_card.registered_name : "-----" data["access_on_card"] = id_card.access
data["access_on_card"] = id_card.access
return data return data

View File

@@ -5,6 +5,7 @@
extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping." extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping."
size = 6 size = 6
tgui_id = "NtosShipping" tgui_id = "NtosShipping"
program_icon = "tags"
///Account used for creating barcodes. ///Account used for creating barcodes.
var/datum/bank_account/payments_acc var/datum/bank_account/payments_acc
///The amount which the tagger will receive for the sale. ///The amount which the tagger will receive for the sale.
@@ -19,14 +20,15 @@
data["has_id_slot"] = !!card_slot data["has_id_slot"] = !!card_slot
data["has_printer"] = !!printer data["has_printer"] = !!printer
data["paperamt"] = printer ? "[printer.stored_paper] / [printer.max_paper]" : null data["paperamt"] = printer ? "[printer.stored_paper] / [printer.max_paper]" : null
data["card_owner"] = card_slot && card_slot.stored_card ? id_card.registered_name : "No Card Inserted." data["card_owner"] = card_slot?.stored_card ? id_card.registered_name : "No Card Inserted."
data["current_user"] = payments_acc ? payments_acc.account_holder : null data["current_user"] = payments_acc ? payments_acc.account_holder : null
data["barcode_split"] = percent_cut data["barcode_split"] = percent_cut
return data return data
/datum/computer_file/program/shipping/ui_act(action, list/params) /datum/computer_file/program/shipping/ui_act(action, list/params)
if(..()) . = ..()
return TRUE if(.)
return
if(!computer) if(!computer)
return return
@@ -40,7 +42,7 @@
switch(action) switch(action)
if("ejectid") if("ejectid")
if(id_card) if(id_card)
card_slot.try_eject(TRUE, usr) card_slot.try_eject(usr, TRUE)
if("selectid") if("selectid")
if(!id_card) if(!id_card)
return return

View File

@@ -13,6 +13,7 @@
available_on_ntnet = 0 available_on_ntnet = 0
requires_ntnet = 0 requires_ntnet = 0
tgui_id = "NtosConfiguration" tgui_id = "NtosConfiguration"
program_icon = "cog"
var/obj/item/modular_computer/movable = null var/obj/item/modular_computer/movable = null
@@ -34,11 +35,11 @@
data["disk_used"] = hard_drive.used_capacity data["disk_used"] = hard_drive.used_capacity
data["power_usage"] = movable.last_power_usage data["power_usage"] = movable.last_power_usage
data["battery_exists"] = battery_module ? 1 : 0 data["battery_exists"] = battery_module ? 1 : 0
if(battery_module && battery_module.battery) if(battery_module?.battery)
data["battery_rating"] = battery_module.battery.maxcharge data["battery_rating"] = battery_module.battery.maxcharge
data["battery_percent"] = round(battery_module.battery.percent()) data["battery_percent"] = round(battery_module.battery.percent())
if(battery_module && battery_module.battery) if(battery_module?.battery)
data["battery"] = list("max" = battery_module.battery.maxcharge, "charge" = round(battery_module.battery.charge)) data["battery"] = list("max" = battery_module.battery.maxcharge, "charge" = round(battery_module.battery.charge))
var/list/all_entries[0] var/list/all_entries[0]
@@ -57,7 +58,8 @@
/datum/computer_file/program/computerconfig/ui_act(action,params) /datum/computer_file/program/computerconfig/ui_act(action,params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
if("PC_toggle_component") if("PC_toggle_component")

View File

@@ -7,6 +7,7 @@
requires_ntnet = TRUE requires_ntnet = TRUE
size = 4 size = 4
tgui_id = "NtosCrewManifest" tgui_id = "NtosCrewManifest"
program_icon = "clipboard-list"
/datum/computer_file/program/crew_manifest/ui_static_data(mob/user) /datum/computer_file/program/crew_manifest/ui_static_data(mob/user)
var/list/data = list() var/list/data = list()
@@ -27,7 +28,8 @@
return data return data
/datum/computer_file/program/crew_manifest/ui_act(action, params, datum/tgui/ui) /datum/computer_file/program/crew_manifest/ui_act(action, params, datum/tgui/ui)
if(..()) . = ..()
if(.)
return return
var/obj/item/computer_hardware/printer/printer var/obj/item/computer_hardware/printer/printer

View File

@@ -8,12 +8,14 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
undeletable = TRUE undeletable = TRUE
tgui_id = "NtosFileManager" tgui_id = "NtosFileManager"
program_icon = "folder"
var/open_file var/open_file
var/error var/error
/datum/computer_file/program/filemanager/ui_act(action, params) /datum/computer_file/program/filemanager/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
var/obj/item/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/HDD = computer.all_components[MC_HDD]
@@ -65,6 +67,13 @@
var/datum/computer_file/C = F.clone(FALSE) var/datum/computer_file/C = F.clone(FALSE)
HDD.store_file(C) HDD.store_file(C)
return TRUE return TRUE
if("PRG_togglesilence")
if(!HDD)
return
var/datum/computer_file/program/binary = HDD.find_file_by_name(params["name"])
if(!binary || !istype(binary))
return
binary.alert_silenced = !binary.alert_silenced
/datum/computer_file/program/filemanager/ui_data(mob/user) /datum/computer_file/program/filemanager/ui_data(mob/user)
var/list/data = get_header_data() var/list/data = get_header_data()
@@ -78,11 +87,19 @@
else else
var/list/files = list() var/list/files = list()
for(var/datum/computer_file/F in HDD.stored_files) for(var/datum/computer_file/F in HDD.stored_files)
var/noisy = FALSE
var/silenced = FALSE
var/datum/computer_file/program/binary = F
if(istype(binary))
noisy = binary.alert_able
silenced = binary.alert_silenced
files += list(list( files += list(list(
"name" = F.filename, "name" = F.filename,
"type" = F.filetype, "type" = F.filetype,
"size" = F.size, "size" = F.size,
"undeletable" = F.undeletable "undeletable" = F.undeletable,
"alert_able" = noisy,
"alert_silenced" = silenced
)) ))
data["files"] = files data["files"] = files
if(RHDD) if(RHDD)

View File

@@ -7,6 +7,7 @@
requires_ntnet = TRUE requires_ntnet = TRUE
size = 4 size = 4
tgui_id = "NtosJobManager" tgui_id = "NtosJobManager"
program_icon = "address-book"
var/change_position_cooldown = 30 var/change_position_cooldown = 30
//Jobs you cannot open new positions for //Jobs you cannot open new positions for
@@ -49,17 +50,14 @@
return FALSE return FALSE
/datum/computer_file/program/job_management/ui_act(action, params, datum/tgui/ui) /datum/computer_file/program/job_management/ui_act(action, params, datum/tgui/ui)
if(..()) . = ..()
if(.)
return return
var/authed = FALSE var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
var/mob/user = usr var/obj/item/card/id/user_id = card_slot?.stored_card
var/obj/item/card/id/user_id = user.get_idcard()
if(user_id)
if(ACCESS_CHANGE_IDS in user_id.access)
authed = TRUE
if(!authed) if(!user_id || !(ACCESS_CHANGE_IDS in user_id.access))
return return
switch(action) switch(action)
@@ -107,10 +105,10 @@
var/list/data = get_header_data() var/list/data = get_header_data()
var/authed = FALSE var/authed = FALSE
var/obj/item/card/id/user_id = user.get_idcard(FALSE) var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
if(user_id) var/obj/item/card/id/user_id = card_slot?.stored_card
if(ACCESS_CHANGE_IDS in user_id.access) if(user_id && (ACCESS_CHANGE_IDS in user_id.access))
authed = TRUE authed = TRUE
data["authed"] = authed data["authed"] = authed

View File

@@ -11,10 +11,11 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
ui_header = "downloader_finished.gif" ui_header = "downloader_finished.gif"
tgui_id = "NtosNetDownloader" tgui_id = "NtosNetDownloader"
program_icon = "download"
var/datum/computer_file/program/downloaded_file = null var/datum/computer_file/program/downloaded_file = null
var/hacked_download = 0 var/hacked_download = FALSE
var/download_completion = 0 //GQ of downloaded data. var/download_completion = FALSE //GQ of downloaded data.
var/download_netspeed = 0 var/download_netspeed = 0
var/downloaderror = "" var/downloaderror = ""
var/obj/item/modular_computer/my_computer = null var/obj/item/modular_computer/my_computer = null
@@ -36,33 +37,33 @@
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(filename) /datum/computer_file/program/ntnetdownload/proc/begin_file_download(filename)
if(downloaded_file) if(downloaded_file)
return 0 return FALSE
var/datum/computer_file/program/PRG = SSnetworks.station_network.find_ntnet_file_by_name(filename) var/datum/computer_file/program/PRG = SSnetworks.station_network.find_ntnet_file_by_name(filename)
if(!PRG || !istype(PRG)) if(!PRG || !istype(PRG))
return 0 return FALSE
// Attempting to download antag only program, but without having emagged/syndicate computer. No. // Attempting to download antag only program, but without having emagged/syndicate computer. No.
if(PRG.available_on_syndinet && !emagged) if(PRG.available_on_syndinet && !emagged)
return 0 return FALSE
var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD] var/obj/item/computer_hardware/hard_drive/hard_drive = computer.all_components[MC_HDD]
if(!computer || !hard_drive || !hard_drive.can_store_file(PRG)) if(!computer || !hard_drive || !hard_drive.can_store_file(PRG))
return 0 return FALSE
ui_header = "downloader_running.gif" ui_header = "downloader_running.gif"
if(PRG in main_repo) if(PRG in main_repo)
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.") generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
hacked_download = 0 hacked_download = FALSE
else if(PRG in antag_repo) else if(PRG in antag_repo)
generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.") generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.")
hacked_download = 1 hacked_download = TRUE
else else
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from unspecified server.") generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from unspecified server.")
hacked_download = 0 hacked_download = FALSE
downloaded_file = PRG.clone() downloaded_file = PRG.clone()
@@ -71,7 +72,7 @@
return return
generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : "[downloaded_file.filename].[downloaded_file.filetype]"].") generate_network_log("Aborted download of file [hacked_download ? "**ENCRYPTED**" : "[downloaded_file.filename].[downloaded_file.filetype]"].")
downloaded_file = null downloaded_file = null
download_completion = 0 download_completion = FALSE
ui_header = "downloader_finished.gif" ui_header = "downloader_finished.gif"
/datum/computer_file/program/ntnetdownload/proc/complete_file_download() /datum/computer_file/program/ntnetdownload/proc/complete_file_download()
@@ -83,7 +84,7 @@
// The download failed // The download failed
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." 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 downloaded_file = null
download_completion = 0 download_completion = FALSE
ui_header = "downloader_finished.gif" ui_header = "downloader_finished.gif"
/datum/computer_file/program/ntnetdownload/process_tick() /datum/computer_file/program/ntnetdownload/process_tick()
@@ -104,21 +105,22 @@
download_completion += download_netspeed download_completion += download_netspeed
/datum/computer_file/program/ntnetdownload/ui_act(action, params) /datum/computer_file/program/ntnetdownload/ui_act(action, params)
if(..()) . = ..()
return 1 if(.)
return
switch(action) switch(action)
if("PRG_downloadfile") if("PRG_downloadfile")
if(!downloaded_file) if(!downloaded_file)
begin_file_download(params["filename"]) begin_file_download(params["filename"])
return 1 return TRUE
if("PRG_reseterror") if("PRG_reseterror")
if(downloaderror) if(downloaderror)
download_completion = 0 download_completion = FALSE
download_netspeed = 0 download_netspeed = FALSE
downloaded_file = null downloaded_file = null
downloaderror = "" downloaderror = ""
return 1 return TRUE
return 0 return FALSE
/datum/computer_file/program/ntnetdownload/ui_data(mob/user) /datum/computer_file/program/ntnetdownload/ui_data(mob/user)
my_computer = computer my_computer = computer
@@ -148,7 +150,7 @@
for(var/A in main_repo) for(var/A in main_repo)
var/datum/computer_file/program/P = A var/datum/computer_file/program/P = A
// Only those programs our user can run will show in the list // Only those programs our user can run will show in the list
if(!P.can_run(user,transfer = 1, access = access) || hard_drive.find_file_by_name(P.filename)) if(hard_drive.find_file_by_name(P.filename))
continue continue
all_entries.Add(list(list( all_entries.Add(list(list(
"filename" = P.filename, "filename" = P.filename,
@@ -156,6 +158,7 @@
"fileinfo" = P.extended_desc, "fileinfo" = P.extended_desc,
"compatibility" = check_compatibility(P), "compatibility" = check_compatibility(P),
"size" = P.size, "size" = P.size,
"access" = P.can_run(user,transfer = 1, access = access)
))) )))
data["hackedavailable"] = FALSE data["hackedavailable"] = FALSE
if(emagged) // If we are running on emagged computer we have access to some "bonus" software if(emagged) // If we are running on emagged computer we have access to some "bonus" software
@@ -169,7 +172,9 @@
"filename" = P.filename, "filename" = P.filename,
"filedesc" = P.filedesc, "filedesc" = P.filedesc,
"fileinfo" = P.extended_desc, "fileinfo" = P.extended_desc,
"compatibility" = check_compatibility(P),
"size" = P.size, "size" = P.size,
"access" = TRUE,
))) )))
data["hacked_programs"] = hacked_programs data["hacked_programs"] = hacked_programs
@@ -180,13 +185,13 @@
/datum/computer_file/program/ntnetdownload/proc/check_compatibility(datum/computer_file/program/P) /datum/computer_file/program/ntnetdownload/proc/check_compatibility(datum/computer_file/program/P)
var/hardflag = computer.hardware_flag var/hardflag = computer.hardware_flag
if(P && P.is_supported_by_hardware(hardflag,0)) if(P?.is_supported_by_hardware(hardflag,0))
return "Compatible" return "Compatible"
return "Incompatible!" return "Incompatible!"
/datum/computer_file/program/ntnetdownload/kill_program(forced) /datum/computer_file/program/ntnetdownload/kill_program(forced)
abort_file_download() abort_file_download()
return ..(forced) return ..()
//////////////////////// ////////////////////////
//Syndicate Downloader// //Syndicate Downloader//
@@ -199,7 +204,7 @@
filedesc = "Software Download Tool" filedesc = "Software Download Tool"
program_icon_state = "generic" program_icon_state = "generic"
extended_desc = "This program allows downloads of software from shared Syndicate repositories" extended_desc = "This program allows downloads of software from shared Syndicate repositories"
requires_ntnet = 0 requires_ntnet = FALSE
ui_header = "downloader_finished.gif" ui_header = "downloader_finished.gif"
tgui_id = "NtosNetDownloader" tgui_id = "NtosNetDownloader"
emagged = TRUE emagged = TRUE

View File

@@ -1,6 +1,6 @@
/datum/computer_file/program/ntnetmonitor /datum/computer_file/program/ntnetmonitor
filename = "wirecarp" filename = "wirecarp"
filedesc = "WireCarp" //wireshark. filedesc = "WireCarp"
program_icon_state = "comm_monitor" program_icon_state = "comm_monitor"
extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes" extended_desc = "This program monitors stationwide NTNet network, provides access to logging systems, and allows for configuration changes"
size = 12 size = 12
@@ -8,9 +8,11 @@
required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM. required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM.
available_on_ntnet = TRUE available_on_ntnet = TRUE
tgui_id = "NtosNetMonitor" tgui_id = "NtosNetMonitor"
program_icon = "network-wired"
/datum/computer_file/program/ntnetmonitor/ui_act(action, params) /datum/computer_file/program/ntnetmonitor/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
if("resetIDS") if("resetIDS")

View File

@@ -9,6 +9,7 @@
ui_header = "ntnrc_idle.gif" ui_header = "ntnrc_idle.gif"
available_on_ntnet = 1 available_on_ntnet = 1
tgui_id = "NtosNetChat" tgui_id = "NtosNetChat"
program_icon = "comment-alt"
var/last_message // Used to generate the toolbar icon var/last_message // Used to generate the toolbar icon
var/username var/username
var/active_channel var/active_channel
@@ -20,7 +21,8 @@
username = "DefaultUser[rand(100, 999)]" username = "DefaultUser[rand(100, 999)]"
/datum/computer_file/program/chatclient/ui_act(action, params) /datum/computer_file/program/chatclient/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel) var/datum/ntnet_conversation/channel = SSnetworks.station_network.get_chat_channel_by_id(active_channel)
@@ -182,7 +184,7 @@
var/list/all_channels = list() var/list/all_channels = list()
for(var/C in SSnetworks.station_network.chat_channels) for(var/C in SSnetworks.station_network.chat_channels)
var/datum/ntnet_conversation/conv = C var/datum/ntnet_conversation/conv = C
if(conv && conv.title) if(conv?.title)
all_channels.Add(list(list( all_channels.Add(list(list(
"chan" = conv.title, "chan" = conv.title,
"id" = conv.id "id" = conv.id

View File

@@ -11,6 +11,7 @@
requires_ntnet = 0 requires_ntnet = 0
size = 9 size = 9
tgui_id = "NtosPowerMonitor" tgui_id = "NtosPowerMonitor"
program_icon = "plug"
var/has_alert = 0 var/has_alert = 0
var/obj/structure/cable/attached_wire var/obj/structure/cable/attached_wire
@@ -49,7 +50,7 @@
local_apc = null local_apc = null
/datum/computer_file/program/power_monitor/proc/get_powernet() //keep in sync with /obj/machinery/computer/monitor's version /datum/computer_file/program/power_monitor/proc/get_powernet() //keep in sync with /obj/machinery/computer/monitor's version
if(attached_wire || (local_apc && local_apc.terminal)) if(attached_wire || (local_apc?.terminal))
return attached_wire ? attached_wire.powernet : local_apc.terminal.powernet return attached_wire ? attached_wire.powernet : local_apc.terminal.powernet
return FALSE return FALSE

View File

@@ -63,7 +63,8 @@
return data return data
/datum/computer_file/program/radar/ui_act(action, params) /datum/computer_file/program/radar/ui_act(action, params)
if(..()) . = ..()
if(.)
return return
switch(action) switch(action)
@@ -73,13 +74,13 @@
scan() scan()
/** /**
*Updates tracking information of the selected target. *Updates tracking information of the selected target.
* *
*The track() proc updates the entire set of information about the location *The track() proc updates the entire set of information about the location
*of the target, including whether the Ntos window should use a pinpointer *of the target, including whether the Ntos window should use a pinpointer
*crosshair over the up/down arrows, or none in favor of a rotating arrow *crosshair over the up/down arrows, or none in favor of a rotating arrow
*for far away targets. This information is returned in the form of a list. *for far away targets. This information is returned in the form of a list.
* *
*/ */
/datum/computer_file/program/radar/proc/track() /datum/computer_file/program/radar/proc/track()
var/atom/movable/signal = find_atom() var/atom/movable/signal = find_atom()
@@ -115,13 +116,13 @@
return trackinfo return trackinfo
/** /**
* *
*Checks the trackability of the selected target. *Checks the trackability of the selected target.
* *
*If the target is on the computer's Z level, or both are on station Z *If the target is on the computer's Z level, or both are on station Z
*levels, and the target isn't untrackable, return TRUE. *levels, and the target isn't untrackable, return TRUE.
*Arguments: *Arguments:
**arg1 is the atom being evaluated. **arg1 is the atom being evaluated.
*/ */
/datum/computer_file/program/radar/proc/trackable(atom/movable/signal) /datum/computer_file/program/radar/proc/trackable(atom/movable/signal)
if(!signal || !computer) if(!signal || !computer)
@@ -133,30 +134,30 @@
return (there.z == here.z) || (is_station_level(here.z) && is_station_level(there.z)) return (there.z == here.z) || (is_station_level(here.z) && is_station_level(there.z))
/** /**
* *
*Runs a scan of all the trackable atoms. *Runs a scan of all the trackable atoms.
* *
*Checks each entry in the GLOB of the specific trackable atoms against *Checks each entry in the GLOB of the specific trackable atoms against
*the track() proc, and fill the objects list with lists containing the *the track() proc, and fill the objects list with lists containing the
*atoms' names and REFs. The objects list is handed to the tgui screen *atoms' names and REFs. The objects list is handed to the tgui screen
*for displaying to, and being selected by, the user. A two second *for displaying to, and being selected by, the user. A two second
*sleep is used to delay the scan, both for thematical reasons as well *sleep is used to delay the scan, both for thematical reasons as well
*as to limit the load players may place on the server using these *as to limit the load players may place on the server using these
*somewhat costly loops. *somewhat costly loops.
*/ */
/datum/computer_file/program/radar/proc/scan() /datum/computer_file/program/radar/proc/scan()
return return
/** /**
* *
*Finds the atom in the appropriate list that the `selected` var indicates *Finds the atom in the appropriate list that the `selected` var indicates
* *
*The `selected` var holds a REF, which is a string. A mob REF may be *The `selected` var holds a REF, which is a string. A mob REF may be
*something like "mob_209". In order to find the actual atom, we need *something like "mob_209". In order to find the actual atom, we need
*to search the appropriate list for the REF string. This is dependant *to search the appropriate list for the REF string. This is dependant
*on the program (Lifeline uses GLOB.human_list, while Fission360 uses *on the program (Lifeline uses GLOB.human_list, while Fission360 uses
*GLOB.poi_list), but the result will be the same; evaluate the string and *GLOB.poi_list), but the result will be the same; evaluate the string and
*return an atom reference. *return an atom reference.
*/ */
/datum/computer_file/program/radar/proc/find_atom() /datum/computer_file/program/radar/proc/find_atom()
return return
@@ -212,6 +213,7 @@
requires_ntnet = TRUE requires_ntnet = TRUE
transfer_access = ACCESS_MEDICAL transfer_access = ACCESS_MEDICAL
available_on_ntnet = TRUE available_on_ntnet = TRUE
program_icon = "heartbeat"
/datum/computer_file/program/radar/lifeline/find_atom() /datum/computer_file/program/radar/lifeline/find_atom()
return locate(selected) in GLOB.human_list return locate(selected) in GLOB.human_list
@@ -228,7 +230,7 @@
var/crewmember_name = "Unknown" var/crewmember_name = "Unknown"
if(humanoid.wear_id) if(humanoid.wear_id)
var/obj/item/card/id/ID = humanoid.wear_id.GetID() var/obj/item/card/id/ID = humanoid.wear_id.GetID()
if(ID && ID.registered_name) if(ID?.registered_name)
crewmember_name = ID.registered_name crewmember_name = ID.registered_name
var/list/crewinfo = list( var/list/crewinfo = list(
ref = REF(humanoid), ref = REF(humanoid),
@@ -262,6 +264,7 @@
available_on_ntnet = FALSE available_on_ntnet = FALSE
available_on_syndinet = TRUE available_on_syndinet = TRUE
tgui_id = "NtosRadarSyndicate" tgui_id = "NtosRadarSyndicate"
program_icon = "bomb"
arrowstyle = "ntosradarpointerS.png" arrowstyle = "ntosradarpointerS.png"
pointercolor = "red" pointercolor = "red"

View File

@@ -1,13 +1,14 @@
/datum/computer_file/program/robocontrol /datum/computer_file/program/robocontrol
filename = "botkeeper" filename = "botkeeper"
filedesc = "Botkeeper" filedesc = "BotKeeper"
program_icon_state = "robot" program_icon_state = "robot"
extended_desc = "A remote controller used for giving basic commands to non-sentient robots." extended_desc = "A remote controller used for giving basic commands to non-sentient robots."
transfer_access = ACCESS_ROBOTICS transfer_access = null
requires_ntnet = TRUE requires_ntnet = TRUE
size = 12 size = 12
tgui_id = "NtosRoboControl" tgui_id = "NtosRoboControl"
program_icon = "robot"
///Number of simple robots on-station. ///Number of simple robots on-station.
var/botcount = 0 var/botcount = 0
///Used to find the location of the user for the purposes of summoning robots. ///Used to find the location of the user for the purposes of summoning robots.
@@ -36,7 +37,13 @@
for(var/B in GLOB.bots_list) for(var/B in GLOB.bots_list)
var/mob/living/simple_animal/bot/Bot = B var/mob/living/simple_animal/bot/Bot = B
if(!Bot.on || Bot.z != zlevel || Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected! if(!Bot.on || Bot.z != zlevel || Bot.remote_disabled) //Only non-emagged bots on the same Z-level are detected!
continue //Also, the PDA must have access to the bot type. continue
else if(computer) //Also, the inserted ID must have access to the bot type
var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : null
if(!id_card && !Bot.bot_core.allowed(current_user))
continue
else if(id_card && !Bot.bot_core.check_access(id_card))
continue
var/list/newbot = list("name" = Bot.name, "mode" = Bot.get_mode_ui(), "model" = Bot.model, "locat" = get_area(Bot), "bot_ref" = REF(Bot), "mule_check" = FALSE) var/list/newbot = list("name" = Bot.name, "mode" = Bot.get_mode_ui(), "model" = Bot.model, "locat" = get_area(Bot), "bot_ref" = REF(Bot), "mule_check" = FALSE)
if(Bot.bot_type == MULE_BOT) if(Bot.bot_type == MULE_BOT)
var/mob/living/simple_animal/bot/mulebot/MULE = Bot var/mob/living/simple_animal/bot/mulebot/MULE = Bot
@@ -53,8 +60,9 @@
return data return data
/datum/computer_file/program/robocontrol/ui_act(action, list/params) /datum/computer_file/program/robocontrol/ui_act(action, list/params)
if(..()) . = ..()
return TRUE if(.)
return
var/obj/item/computer_hardware/card_slot/card_slot var/obj/item/computer_hardware/card_slot/card_slot
var/obj/item/card/id/id_card var/obj/item/card/id/id_card
if(computer) if(computer)

View File

@@ -0,0 +1,147 @@
/datum/computer_file/program/robotact
filename = "robotact"
filedesc = "RoboTact"
extended_desc = "A built-in app for cyborg self-management and diagnostics."
ui_header = "robotact.gif" //DEBUG -- new icon before PR
program_icon_state = "command"
requires_ntnet = FALSE
transfer_access = null
available_on_ntnet = FALSE
unsendable = TRUE
undeletable = TRUE
usage_flags = PROGRAM_TABLET
size = 5
tgui_id = "NtosRobotact"
program_icon = "terminal"
///A typed reference to the computer, specifying the borg tablet type
var/obj/item/modular_computer/tablet/integrated/tablet
/datum/computer_file/program/robotact/Destroy()
tablet = null
return ..()
/datum/computer_file/program/robotact/run_program(mob/living/user)
if(!istype(computer, /obj/item/modular_computer/tablet/integrated))
to_chat(user, "<span class='warning'>A warning flashes across \the [computer]: Device Incompatible.</span>")
return FALSE
. = ..()
if(.)
tablet = computer
if(tablet.device_theme == "syndicate")
program_icon_state = "command-syndicate"
return TRUE
return FALSE
/datum/computer_file/program/robotact/ui_data(mob/user)
var/list/data = get_header_data()
if(!iscyborg(user))
return data
var/mob/living/silicon/robot/borgo = tablet.borgo
data["name"] = borgo.name
data["designation"] = borgo.designation //Borgo module type
data["masterAI"] = borgo.connected_ai //Master AI
var/charge = 0
var/maxcharge = 1
if(borgo.cell)
charge = borgo.cell.charge
maxcharge = borgo.cell.maxcharge
data["charge"] = charge //Current cell charge
data["maxcharge"] = maxcharge //Cell max charge
data["integrity"] = ((borgo.health + 100) / 2) //Borgo health, as percentage
data["lampIntensity"] = borgo.lamp_intensity //Borgo lamp power setting
data["sensors"] = "[borgo.sensors_on?"ACTIVE":"DISABLED"]"
data["printerPictures"] = borgo.connected_ai? borgo.connected_ai.aicamera.stored.len : borgo.aicamera.stored.len //Number of pictures taken, synced to AI if available
data["printerToner"] = borgo.toner //amount of toner
data["printerTonerMax"] = borgo.tonermax //It's a variable, might as well use it
data["thrustersInstalled"] = borgo.ionpulse //If we have a thruster uprade
data["thrustersStatus"] = "[borgo.ionpulse_on?"ACTIVE":"DISABLED"]" //Feedback for thruster status
//DEBUG -- Cover, TRUE for locked
data["cover"] = "[borgo.locked? "LOCKED":"UNLOCKED"]"
//Ability to move. FAULT if lockdown wire is cut, DISABLED if borg locked, ENABLED otherwise
data["locomotion"] = "[borgo.wires.is_cut(WIRE_LOCKDOWN)?"FAULT":"[borgo.lockcharge?"DISABLED":"ENABLED"]"]"
//Module wire. FAULT if cut, NOMINAL otherwise
data["wireModule"] = "[borgo.wires.is_cut(WIRE_RESET_MODULE)?"FAULT":"NOMINAL"]"
//DEBUG -- Camera(net) wire. FAULT if cut (or no cameranet camera), DISABLED if pulse-disabled, NOMINAL otherwise
data["wireCamera"] = "[!borgo.builtInCamera || borgo.wires.is_cut(WIRE_CAMERA)?"FAULT":"[borgo.builtInCamera.can_use()?"NOMINAL":"DISABLED"]"]"
//AI wire. FAULT if wire is cut, CONNECTED if connected to AI, READY otherwise
data["wireAI"] = "[borgo.wires.is_cut(WIRE_AI)?"FAULT":"[borgo.connected_ai?"CONNECTED":"READY"]"]"
//Law sync wire. FAULT if cut, NOMINAL otherwise
data["wireLaw"] = "[borgo.wires.is_cut(WIRE_LAWSYNC)?"FAULT":"NOMINAL"]"
return data
/datum/computer_file/program/robotact/ui_static_data(mob/user)
var/list/data = list()
if(!iscyborg(user))
return data
var/mob/living/silicon/robot/borgo = user
data["Laws"] = borgo.laws.get_law_list(TRUE, TRUE, FALSE)
data["borgLog"] = tablet.borglog
data["borgUpgrades"] = borgo.upgrades
return data
/datum/computer_file/program/robotact/ui_act(action, params)
. = ..()
if(.)
return
var/mob/living/silicon/robot/borgo = tablet.borgo
switch(action)
if("coverunlock")
if(borgo.locked)
borgo.locked = FALSE
borgo.update_icons()
if(borgo.emagged)
borgo.logevent("ChÃ¥vÃis cover lock has been [borgo.locked ? "engaged" : "released"]") //"The cover interface glitches out for a split second"
else
borgo.logevent("Chassis cover lock has been [borgo.locked ? "engaged" : "released"]")
if("lawchannel")
borgo.set_autosay()
if("lawstate")
borgo.checklaws()
if("alertPower")
if(borgo.stat == CONSCIOUS)
if(!borgo.cell || !borgo.cell.charge)
borgo.visible_message("<span class='notice'>The power warning light on <span class='name'>[borgo]</span> flashes urgently.</span>", \
"You announce you are operating in low power mode.")
playsound(borgo, 'sound/machines/buzz-two.ogg', 50, FALSE)
if("toggleSensors")
borgo.toggle_sensors()
if("viewImage")
if(borgo.connected_ai)
borgo.connected_ai.aicamera?.viewpictures(usr)
else
borgo.aicamera?.viewpictures(usr)
if("printImage")
var/obj/item/camera/siliconcam/robot_camera/borgcam = borgo.aicamera
borgcam?.borgprint(usr)
if("toggleThrusters")
borgo.toggle_ionpulse()
if("lampIntensity")
borgo.lamp_intensity = params["ref"]
borgo.toggle_headlamp(FALSE, TRUE)
/**
* Forces a full update of the UI, if currently open.
*
* Forces an update that includes refreshing ui_static_data. Called by
* law changes and borg log additions.
*/
/datum/computer_file/program/robotact/proc/force_full_update()
if(tablet)
var/datum/tgui/active_ui = SStgui.get_open_ui(tablet.borgo, src)
if(active_ui)
active_ui.send_full_update()

View File

@@ -0,0 +1,195 @@
#define DEFAULT_MAP_SIZE 15
/datum/computer_file/program/secureye
filename = "secureye"
filedesc = "SecurEye"
ui_header = "borg_mon.gif"
program_icon_state = "generic"
extended_desc = "This program allows access to standard security camera networks."
requires_ntnet = TRUE
transfer_access = ACCESS_SECURITY
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
size = 5
tgui_id = "NtosSecurEye"
program_icon = "eye"
var/list/network = list("ss13")
var/obj/machinery/camera/active_camera
/// The turf where the camera was last updated.
var/turf/last_camera_turf
var/list/concurrent_users = list()
// Stuff needed to render the map
var/map_name
var/atom/movable/screen/map_view/cam_screen
/// All the plane masters that need to be applied.
var/list/cam_plane_masters
var/atom/movable/screen/background/cam_background
/datum/computer_file/program/secureye/New()
. = ..()
// Map name has to start and end with an A-Z character,
// and definitely NOT with a square bracket or even a number.
map_name = "camera_console_[REF(src)]_map"
// Convert networks to lowercase
for(var/i in network)
network -= i
network += lowertext(i)
// Initialize map objects
cam_screen = new
cam_screen.name = "screen"
cam_screen.assigned_map = map_name
cam_screen.del_on_map_removal = FALSE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_masters = list()
for(var/plane in subtypesof(/atom/movable/screen/plane_master))
var/atom/movable/screen/instance = new plane()
instance.assigned_map = map_name
instance.del_on_map_removal = FALSE
instance.screen_loc = "[map_name]:CENTER"
cam_plane_masters += instance
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
/datum/computer_file/program/secureye/Destroy()
qdel(cam_screen)
QDEL_LIST(cam_plane_masters)
qdel(cam_background)
return ..()
/datum/computer_file/program/secureye/ui_interact(mob/user, datum/tgui/ui)
// Update UI
ui = SStgui.try_update_ui(user, src, ui)
// Update the camera, showing static if necessary and updating data if the location has moved.
update_active_camera_screen()
if(!ui)
var/user_ref = REF(user)
var/is_living = isliving(user)
// Ghosts shouldn't count towards concurrent users, which produces
// an audible terminal_on click.
if(is_living)
concurrent_users += user_ref
// Register map objects
user.client.register_map_obj(cam_screen)
for(var/plane in cam_plane_masters)
user.client.register_map_obj(plane)
user.client.register_map_obj(cam_background)
return ..()
/datum/computer_file/program/secureye/ui_data()
var/list/data = get_header_data()
data["network"] = network
data["activeCamera"] = null
if(active_camera)
data["activeCamera"] = list(
name = active_camera.c_tag,
status = active_camera.status,
)
return data
/datum/computer_file/program/secureye/ui_static_data()
var/list/data = list()
data["mapRef"] = map_name
var/list/cameras = get_available_cameras()
data["cameras"] = list()
for(var/i in cameras)
var/obj/machinery/camera/C = cameras[i]
data["cameras"] += list(list(
name = C.c_tag,
))
return data
/datum/computer_file/program/secureye/ui_act(action, params)
. = ..()
if(.)
return
if(action == "switch_camera")
var/c_tag = params["name"]
var/list/cameras = get_available_cameras()
var/obj/machinery/camera/selected_camera = cameras[c_tag]
active_camera = selected_camera
playsound(src, get_sfx("terminal_type"), 25, FALSE)
if(!selected_camera)
return TRUE
update_active_camera_screen()
return TRUE
/datum/computer_file/program/secureye/ui_close(mob/user)
. = ..()
var/user_ref = REF(user)
var/is_living = isliving(user)
// Living creature or not, we remove you anyway.
concurrent_users -= user_ref
// Unregister map objects
user.client.clear_map(map_name)
// Turn off the console
if(length(concurrent_users) == 0 && is_living)
active_camera = null
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
/datum/computer_file/program/secureye/proc/update_active_camera_screen()
// Show static if can't use the camera
if(!active_camera?.can_use())
show_camera_static()
return
var/list/visible_turfs = list()
// Is this camera located in or attached to a living thing? If so, assume the camera's loc is the living thing.
var/cam_location = isliving(active_camera.loc) ? active_camera.loc : active_camera
// If we're not forcing an update for some reason and the cameras are in the same location,
// we don't need to update anything.
// Most security cameras will end here as they're not moving.
var/newturf = get_turf(cam_location)
if(last_camera_turf == newturf)
return
// Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs.
last_camera_turf = get_turf(cam_location)
var/list/visible_things = active_camera.isXRay() ? range(active_camera.view_range, cam_location) : view(active_camera.view_range, cam_location)
for(var/turf/visible_turf in visible_things)
visible_turfs += visible_turf
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
/datum/computer_file/program/secureye/proc/show_camera_static()
cam_screen.vis_contents.Cut()
cam_background.icon_state = "scanline2"
cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE)
// Returns the list of cameras accessible from this computer
/datum/computer_file/program/secureye/proc/get_available_cameras()
var/list/L = list()
for (var/obj/machinery/camera/cam in GLOB.cameranet.cameras)
if(!is_station_level(cam.z))//Only show station cameras.
continue
L.Add(cam)
var/list/camlist = list()
for(var/obj/machinery/camera/cam in L)
if(!cam.network)
stack_trace("Camera in a cameranet has no camera network")
continue
if(!(islist(cam.network)))
stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = cam.network & network
if(tempnetwork.len)
camlist["[cam.c_tag]"] = cam
return camlist

View File

@@ -8,10 +8,16 @@
transfer_access = ACCESS_CONSTRUCTION transfer_access = ACCESS_CONSTRUCTION
size = 5 size = 5
tgui_id = "NtosSupermatterMonitor" tgui_id = "NtosSupermatterMonitor"
program_icon = "radiation"
alert_able = TRUE
var/last_status = SUPERMATTER_INACTIVE var/last_status = SUPERMATTER_INACTIVE
var/list/supermatters var/list/supermatters
var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal. var/obj/machinery/power/supermatter_crystal/active // Currently selected supermatter crystal.
/datum/computer_file/program/supermatter_monitor/Destroy()
clear_signals()
active = null
return ..()
/datum/computer_file/program/supermatter_monitor/process_tick() /datum/computer_file/program/supermatter_monitor/process_tick()
..() ..()
@@ -25,10 +31,11 @@
/datum/computer_file/program/supermatter_monitor/run_program(mob/living/user) /datum/computer_file/program/supermatter_monitor/run_program(mob/living/user)
. = ..(user) . = ..(user)
if(!(active in GLOB.machines))
active = null
refresh() refresh()
/datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE) /datum/computer_file/program/supermatter_monitor/kill_program(forced = FALSE)
active = null
supermatters = null supermatters = null
..() ..()
@@ -52,6 +59,58 @@
for(var/obj/machinery/power/supermatter_crystal/S in supermatters) for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
. = max(., S.get_status()) . = max(., S.get_status())
/**
* Sets up the signal listener for Supermatter delaminations.
*
* Unregisters any old listners for SM delams, and then registers one for the SM refered
* to in the `active` variable. This proc is also used with no active SM to simply clear
* the signal and exit.
*/
/datum/computer_file/program/supermatter_monitor/proc/set_signals()
// if(active)
// RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM, .proc/send_alert, override = TRUE)
// RegisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM, .proc/send_start_alert, override = TRUE)
/**
* Removes the signal listener for Supermatter delaminations from the selected supermatter.
*
* Pretty much does what it says.
*/
/datum/computer_file/program/supermatter_monitor/proc/clear_signals()
// if(active)
// UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_ALARM)
// UnregisterSignal(active, COMSIG_SUPERMATTER_DELAM_START_ALARM)
/**
* Sends an SM delam alert to the computer.
*
* Triggered by a signal from the selected supermatter, this proc sends a notification
* to the computer if the program is either closed or minimized. We do not send these
* notifications to the comptuer if we're the active program, because engineers fixing
* the supermatter probably don't need constant beeping to distract them.
*/
/datum/computer_file/program/supermatter_monitor/proc/send_alert()
if(!computer.get_ntnet_status())
return
if(computer.active_program != src)
computer.alert_call(src, "Crystal delamination in progress!")
alert_pending = TRUE
/**
* Sends an SM delam start alert to the computer.
*
* Triggered by a signal from the selected supermatter at the start of a delamination,
* this proc sends a notification to the computer if this program is the active one.
* We do this so that people carrying a tablet with NT CIMS open but with the NTOS window
* closed will still get one audio alert. This is not sent to computers with the program
* minimized or closed to avoid double-notifications.
*/
/datum/computer_file/program/supermatter_monitor/proc/send_start_alert()
if(!computer.get_ntnet_status())
return
if(computer.active_program == src)
computer.alert_call(src, "Crystal delamination in progress!")
/datum/computer_file/program/supermatter_monitor/ui_data() /datum/computer_file/program/supermatter_monitor/ui_data()
var/list/data = get_header_data() var/list/data = get_header_data()
@@ -107,11 +166,13 @@
return data return data
/datum/computer_file/program/supermatter_monitor/ui_act(action, params) /datum/computer_file/program/supermatter_monitor/ui_act(action, params)
if(..()) . = ..()
return TRUE if(.)
return
switch(action) switch(action)
if("PRG_clear") if("PRG_clear")
clear_signals()
active = null active = null
return TRUE return TRUE
if("PRG_refresh") if("PRG_refresh")
@@ -122,4 +183,5 @@
for(var/obj/machinery/power/supermatter_crystal/S in supermatters) for(var/obj/machinery/power/supermatter_crystal/S in supermatters)
if(S.uid == newuid) if(S.uid == newuid)
active = S active = S
set_signals()
return TRUE return TRUE

View File

@@ -24,8 +24,8 @@
/obj/item/computer_hardware/New(obj/L) /obj/item/computer_hardware/New(obj/L)
..() ..()
pixel_x = rand(-8, 8) pixel_x = base_pixel_x + rand(-8, 8)
pixel_y = rand(-8, 8) pixel_y = base_pixel_y + rand(-8, 8)
/obj/item/computer_hardware/Destroy() /obj/item/computer_hardware/Destroy()
if(holder) if(holder)
@@ -94,12 +94,20 @@
// Called when component is removed from PC. // Called when component is removed from PC.
/obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user = null) /obj/item/computer_hardware/proc/on_remove(obj/item/modular_computer/M, mob/living/user = null)
try_eject(forced = 1) try_eject(forced = TRUE)
// Called when someone tries to insert something in it - paper in printer, card in card reader, etc. // Called when someone tries to insert something in it - paper in printer, card in card reader, etc.
/obj/item/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null) /obj/item/computer_hardware/proc/try_insert(obj/item/I, mob/living/user = null)
return FALSE return FALSE
// Called when someone tries to eject something from it - card from card reader, etc. /**
/obj/item/computer_hardware/proc/try_eject(slot=0, mob/living/user = null, forced = 0) * Implement this when your hardware contains an object that the user can eject.
*
* Examples include ejecting cells from battery modules, ejecting an ID card from a card reader
* or ejecting an Intellicard from an AI card slot.
* Arguments:
* * user - The mob requesting the eject.
* * forced - Whether this action should be forced in some way.
*/
/obj/item/computer_hardware/proc/try_eject(mob/living/user = null, forced = FALSE)
return FALSE return FALSE

View File

@@ -12,7 +12,7 @@
/obj/item/computer_hardware/ai_slot/handle_atom_del(atom/A) /obj/item/computer_hardware/ai_slot/handle_atom_del(atom/A)
if(A == stored_card) if(A == stored_card)
try_eject(0, null, TRUE) try_eject(forced = TRUE)
. = ..() . = ..()
/obj/item/computer_hardware/ai_slot/examine(mob/user) /obj/item/computer_hardware/ai_slot/examine(mob/user)
@@ -39,7 +39,7 @@
return TRUE return TRUE
/obj/item/computer_hardware/ai_slot/try_eject(mob/living/user = null,forced = FALSE) /obj/item/computer_hardware/ai_slot/try_eject(mob/living/user = null, forced = FALSE)
if(!stored_card) if(!stored_card)
to_chat(user, "<span class='warning'>There is no card in \the [src].</span>") to_chat(user, "<span class='warning'>There is no card in \the [src].</span>")
return FALSE return FALSE
@@ -65,5 +65,5 @@
return return
if(I.tool_behaviour == TOOL_SCREWDRIVER) if(I.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>") to_chat(user, "<span class='notice'>You press down on the manual eject button with \the [I].</span>")
try_eject(,user,1) try_eject(user, TRUE)
return return

View File

@@ -1,5 +1,5 @@
/obj/item/computer_hardware/card_slot /obj/item/computer_hardware/card_slot
name = "identification card authentication module" // \improper breaks the find_hardware_by_name proc name = "primary RFID card module" // \improper breaks the find_hardware_by_name proc
desc = "A module allowing this computer to read or write data on ID cards. Necessary for some programs to run properly." desc = "A module allowing this computer to read or write data on ID cards. Necessary for some programs to run properly."
power_usage = 10 //W power_usage = 10 //W
icon_state = "card_mini" icon_state = "card_mini"
@@ -14,7 +14,7 @@
. = ..() . = ..()
/obj/item/computer_hardware/card_slot/Destroy() /obj/item/computer_hardware/card_slot/Destroy()
try_eject() try_eject(forced = TRUE)
return ..() return ..()
/obj/item/computer_hardware/card_slot/GetAccess() /obj/item/computer_hardware/card_slot/GetAccess()
@@ -100,14 +100,16 @@
to_chat(user, "<span class='notice'>You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].</span>") to_chat(user, "<span class='notice'>You adjust the connecter to fit into [expansion_hw ? "an expansion bay" : "the primary ID bay"].</span>")
/** /**
*Swaps the card_slot hardware between using the dedicated card slot bay on a computer, and using an expansion bay. *Swaps the card_slot hardware between using the dedicated card slot bay on a computer, and using an expansion bay.
*/ */
/obj/item/computer_hardware/card_slot/proc/swap_slot() /obj/item/computer_hardware/card_slot/proc/swap_slot()
expansion_hw = !expansion_hw expansion_hw = !expansion_hw
if(expansion_hw) if(expansion_hw)
device_type = MC_CARD2 device_type = MC_CARD2
name = "secondary RFID card module"
else else
device_type = MC_CARD device_type = MC_CARD
name = "primary RFID card module"
/obj/item/computer_hardware/card_slot/examine(mob/user) /obj/item/computer_hardware/card_slot/examine(mob/user)
. = ..() . = ..()
@@ -116,5 +118,6 @@
. += "There appears to be something loaded in the card slots." . += "There appears to be something loaded in the card slots."
/obj/item/computer_hardware/card_slot/secondary /obj/item/computer_hardware/card_slot/secondary
name = "secondary RFID card module"
device_type = MC_CARD2 device_type = MC_CARD2
expansion_hw = TRUE expansion_hw = TRUE

View File

@@ -31,43 +31,43 @@
// Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. // Use this proc to add file to the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
/obj/item/computer_hardware/hard_drive/proc/store_file(datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/store_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return FALSE
if(!can_store_file(F)) if(!can_store_file(F))
return 0 return FALSE
if(!check_functionality()) if(!check_functionality())
return 0 return FALSE
if(!stored_files) if(!stored_files)
return 0 return FALSE
// This file is already stored. Don't store it again. // This file is already stored. Don't store it again.
if(F in stored_files) if(F in stored_files)
return 0 return FALSE
F.holder = src F.holder = src
stored_files.Add(F) stored_files.Add(F)
recalculate_size() recalculate_size()
return 1 return TRUE
// Use this proc to remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks. // Use this proc to remove file from the drive. Returns 1 on success and 0 on failure. Contains necessary sanity checks.
/obj/item/computer_hardware/hard_drive/proc/remove_file(datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/remove_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return FALSE
if(!stored_files) if(!stored_files)
return 0 return FALSE
if(!check_functionality()) if(!check_functionality())
return 0 return FALSE
if(F in stored_files) if(F in stored_files)
stored_files -= F stored_files -= F
recalculate_size() recalculate_size()
return 1 return TRUE
else else
return 0 return FALSE
// Loops through all stored files and recalculates used_capacity of this drive // Loops through all stored files and recalculates used_capacity of this drive
/obj/item/computer_hardware/hard_drive/proc/recalculate_size() /obj/item/computer_hardware/hard_drive/proc/recalculate_size()
@@ -80,24 +80,24 @@
// Checks whether file can be stored on the hard drive. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file. // Checks whether file can be stored on the hard drive. We can only store unique files, so this checks whether we wouldn't get a duplicity by adding a file.
/obj/item/computer_hardware/hard_drive/proc/can_store_file(datum/computer_file/F) /obj/item/computer_hardware/hard_drive/proc/can_store_file(datum/computer_file/F)
if(!F || !istype(F)) if(!F || !istype(F))
return 0 return FALSE
if(F in stored_files) if(F in stored_files)
return 0 return FALSE
var/name = F.filename + "." + F.filetype var/name = F.filename + "." + F.filetype
for(var/datum/computer_file/file in stored_files) for(var/datum/computer_file/file in stored_files)
if((file.filename + "." + file.filetype) == name) if((file.filename + "." + file.filetype) == name)
return 0 return FALSE
// In the unlikely event someone manages to create that many files. // In the unlikely event someone manages to create that many files.
// BYOND is acting weird with numbers above 999 in loops (infinite loop prevention) // BYOND is acting weird with numbers above 999 in loops (infinite loop prevention)
if(stored_files.len >= 999) if(stored_files.len >= 999)
return 0 return FALSE
if((used_capacity + F.size) > max_capacity) if((used_capacity + F.size) > max_capacity)
return 0 return FALSE
else else
return 1 return TRUE
// Tries to find the file by filename. Returns null on failure // Tries to find the file by filename. Returns null on failure
@@ -157,7 +157,14 @@
max_capacity = 64 max_capacity = 64
icon_state = "ssd_mini" icon_state = "ssd_mini"
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
custom_price = 150 custom_price = PAYCHECK_MEDIUM * 2
// For borg integrated tablets. No downloader.
/obj/item/computer_hardware/hard_drive/small/integrated/install_default_programs()
store_file(new /datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar
store_file(new /datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation.
store_file(new /datum/computer_file/program/robotact(src))
// Syndicate variant - very slight better // Syndicate variant - very slight better
/obj/item/computer_hardware/hard_drive/small/syndicate /obj/item/computer_hardware/hard_drive/small/syndicate

View File

@@ -77,3 +77,23 @@
power_usage = 100 // Better range but higher power usage. power_usage = 100 // Better range but higher power usage.
icon_state = "net_wired" icon_state = "net_wired"
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
/obj/item/computer_hardware/network_card/integrated //Borg tablet version, only works while the borg has power and is not locked
name = "cyborg data link"
/obj/item/computer_hardware/network_card/integrated/get_signal(specific_action = 0)
var/obj/item/modular_computer/tablet/integrated/modularInterface = holder
if(!modularInterface || !istype(modularInterface))
return FALSE //wrong type of tablet
if(!modularInterface.borgo)
return FALSE //No borg found
if(modularInterface.borgo.lockcharge)
return FALSE //lockdown restricts borg networking
if(!modularInterface.borgo.cell || modularInterface.borgo.cell.charge == 0)
return FALSE //borg cell dying restricts borg networking
return ..()

View File

@@ -4,7 +4,7 @@
power_usage = 10 power_usage = 10
icon_state = "datadisk6" icon_state = "datadisk6"
w_class = WEIGHT_CLASS_TINY w_class = WEIGHT_CLASS_TINY
critical = 0 critical = FALSE
max_capacity = 16 max_capacity = 16
device_type = MC_SDD device_type = MC_SDD

View File

@@ -6,8 +6,8 @@
/obj/item/computer_hardware/recharger/proc/use_power(amount, charging=0) /obj/item/computer_hardware/recharger/proc/use_power(amount, charging=0)
if(charging) if(charging)
return 1 return TRUE
return 0 return FALSE
/obj/item/computer_hardware/recharger/process() /obj/item/computer_hardware/recharger/process()
..() ..()
@@ -23,28 +23,28 @@
holder.give_power(charge_rate * GLOB.CELLRATE) holder.give_power(charge_rate * GLOB.CELLRATE)
/obj/item/computer_hardware/recharger/APC /obj/item/computer_hardware/recharger/apc_recharger
name = "area power connector" name = "area power connector"
desc = "A device that wirelessly recharges connected device from nearby APC." desc = "A device that wirelessly recharges connected device from nearby APC."
icon_state = "charger_APC" icon_state = "charger_APC"
w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs
/obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0) /obj/item/computer_hardware/recharger/apc_recharger/use_power(amount, charging=0)
if(ismachinery(holder.physical)) if(ismachinery(holder.physical))
var/obj/machinery/M = holder.physical var/obj/machinery/M = holder.physical
if(M.powered()) if(M.powered())
M.use_power(amount) M.use_power(amount)
return 1 return TRUE
else else
var/area/A = get_area(src) var/area/A = get_area(src)
if(!istype(A)) if(!istype(A))
return 0 return FALSE
if(A.powered(EQUIP)) if(A.powered(EQUIP))
A.use_power(amount, EQUIP) A.use_power(amount, EQUIP)
return 1 return TRUE
return 0 return FALSE
/obj/item/computer_hardware/recharger/wired /obj/item/computer_hardware/recharger/wired
name = "wired power connector" name = "wired power connector"
@@ -56,27 +56,34 @@
if(ismachinery(M.physical) && M.physical.anchored) if(ismachinery(M.physical) && M.physical.anchored)
return ..() return ..()
to_chat(user, "<span class='warning'>\The [src] is incompatible with portable computers!</span>") to_chat(user, "<span class='warning'>\The [src] is incompatible with portable computers!</span>")
return 0 return FALSE
/obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0) /obj/item/computer_hardware/recharger/wired/use_power(amount, charging=0)
if(ismachinery(holder.physical) && holder.physical.anchored) if(ismachinery(holder.physical) && holder.physical.anchored)
var/obj/machinery/M = holder.physical var/obj/machinery/M = holder.physical
var/turf/T = M.loc var/turf/T = M.loc
if(!T || !istype(T)) if(!T || !istype(T))
return 0 return FALSE
var/obj/structure/cable/C = T.get_cable_node() var/obj/structure/cable/C = T.get_cable_node()
if(!C || !C.powernet) if(!C || !C.powernet)
return 0 return FALSE
var/power_in_net = C.powernet.avail-C.powernet.load var/power_in_net = C.powernet.avail-C.powernet.load
if(power_in_net && power_in_net > amount) if(power_in_net && power_in_net > amount)
C.powernet.load += amount C.powernet.load += amount
return 1 return TRUE
return FALSE
return 0 /// This recharger exists only in borg built-in tablets. I would have tied it to the borg's cell but
/// the program that displays laws should always be usable, and the exceptions were starting to pile.
/obj/item/computer_hardware/recharger/cyborg
name = "modular interface power harness"
desc = "A standard connection to power a small computer device from a cyborg's chassis."
/obj/item/computer_hardware/recharger/cyborg/use_power(amount, charging=0)
return TRUE
// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. // This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes.

View File

@@ -100,7 +100,7 @@
if(dev_apc_recharger) if(dev_apc_recharger)
total_price += 399 total_price += 399
if(fabricate) if(fabricate)
fabricated_laptop.install_component(new /obj/item/computer_hardware/recharger/APC) fabricated_laptop.install_component(new /obj/item/computer_hardware/recharger/apc_recharger)
if(dev_printer) if(dev_printer)
total_price += 99 total_price += 99
if(fabricate) if(fabricate)
@@ -169,8 +169,9 @@
/obj/machinery/lapvend/ui_act(action, params) /obj/machinery/lapvend/ui_act(action, params)
if(..()) . = ..()
return TRUE if(.)
return
switch(action) switch(action)
if("pick_device") if("pick_device")
@@ -224,7 +225,7 @@
return FALSE return FALSE
/obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui) /obj/machinery/lapvend/ui_interact(mob/user, datum/tgui/ui)
if(stat & (BROKEN | NOPOWER | MAINT)) if(machine_stat & (BROKEN | NOPOWER | MAINT))
if(ui) if(ui)
ui.close() ui.close()
return FALSE return FALSE

View File

@@ -2846,6 +2846,7 @@
#include "code\modules\modular_computers\file_system\programs\arcade.dm" #include "code\modules\modular_computers\file_system\programs\arcade.dm"
#include "code\modules\modular_computers\file_system\programs\atmosscan.dm" #include "code\modules\modular_computers\file_system\programs\atmosscan.dm"
#include "code\modules\modular_computers\file_system\programs\borg_monitor.dm" #include "code\modules\modular_computers\file_system\programs\borg_monitor.dm"
#include "code\modules\modular_computers\file_system\programs\budgetordering.dm"
#include "code\modules\modular_computers\file_system\programs\card.dm" #include "code\modules\modular_computers\file_system\programs\card.dm"
#include "code\modules\modular_computers\file_system\programs\cargobounty.dm" #include "code\modules\modular_computers\file_system\programs\cargobounty.dm"
#include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\configurator.dm"
@@ -2858,6 +2859,8 @@
#include "code\modules\modular_computers\file_system\programs\powermonitor.dm" #include "code\modules\modular_computers\file_system\programs\powermonitor.dm"
#include "code\modules\modular_computers\file_system\programs\radar.dm" #include "code\modules\modular_computers\file_system\programs\radar.dm"
#include "code\modules\modular_computers\file_system\programs\robocontrol.dm" #include "code\modules\modular_computers\file_system\programs\robocontrol.dm"
#include "code\modules\modular_computers\file_system\programs\robotact.dm"
#include "code\modules\modular_computers\file_system\programs\secureye.dm"
#include "code\modules\modular_computers\file_system\programs\sm_monitor.dm" #include "code\modules\modular_computers\file_system\programs\sm_monitor.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\contract_uplink.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\contract_uplink.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm"