a small addition

This commit is contained in:
Geevies
2020-04-15 19:58:18 +02:00
parent 21deec90c3
commit 94579a73bf
65 changed files with 1200 additions and 1223 deletions

View File

@@ -1,6 +1,6 @@
var/global/ntnrc_uid = 0
/datum/ntnet_conversation/
var/id = null
/datum/ntnet_conversation
var/id
var/title = "Untitled Conversation"
var/datum/computer_file/program/chatclient/operator // "Administrator" of this channel. Creator starts as channel's operator,
var/list/messages = list()
@@ -18,8 +18,14 @@ var/global/ntnrc_uid = 0
operator = "NanoTrasen Information Technology Division" // assign a fake operator
..()
/datum/ntnet_conversation/proc/add_message(var/message, var/username, var/mob/user)
log_ntirc("[user.client.ckey]/([username]) : [message]",ckey=key_name(user),conversation=title)
/datum/ntnet_conversation/proc/add_message(var/message, var/username, var/mob/user, var/reply_ref)
log_ntirc("[user.client.ckey]/([username]) : [message]", ckey=key_name(user), conversation=title)
for(var/datum/computer_file/program/chatclient/C in clients)
if(C.username == username || !C.computer.screen_on)
continue
if(C.computer.active_program == C || (C in C.computer.idle_threads))
C.computer.output_message(FONT_SMALL("<b>([title]) [username]:</b> [message]"), 0)
message = "[worldtime2text()] [username]: [message]"
messages.Add(message)
@@ -45,6 +51,12 @@ var/global/ntnrc_uid = 0
if(!operator)
changeop(C)
for(var/datum/computer_file/program/chatclient/CC in clients)
if(CC == C || !CC.computer.screen_on)
continue
if(CC.computer.active_program == CC || (CC in CC.computer.idle_threads))
CC.computer.output_message(FONT_SMALL("<b>([title]) A new client ([C.username]) has entered the chat.</b>"), 0)
/datum/ntnet_conversation/proc/remove_client(var/datum/computer_file/program/chatclient/C)
if(!istype(C) || !(C in clients))
return
@@ -57,6 +69,12 @@ var/global/ntnrc_uid = 0
var/datum/computer_file/program/chatclient/newop = pick(clients)
changeop(newop)
for(var/datum/computer_file/program/chatclient/CC in clients)
if(CC == C || !CC.computer.screen_on)
continue
if(CC.computer.active_program == CC || (CC in CC.computer.idle_threads))
CC.computer.output_message(FONT_SMALL("<b>([title]) A client ([C.username]) has left the chat.</b>"), 0)
/datum/ntnet_conversation/proc/changeop(var/datum/computer_file/program/chatclient/newop)
if(istype(newop))
@@ -69,3 +87,9 @@ var/global/ntnrc_uid = 0
add_status_message("[client.username] has changed channel title from [title] to [newtitle]")
title = newtitle
for(var/datum/computer_file/program/chatclient/C in clients)
if(C == client || !C.computer.screen_on)
continue
if(C.computer.active_program == src || (C in C.computer.idle_threads))
C.computer.output_message(FONT_SMALL("([title]) A new client ([C.username]) has entered the chat."), 0)

View File

@@ -2,7 +2,7 @@ var/global/datum/ntnet/ntnet_global = new()
// This is the NTNet datum. There can be only one NTNet datum in game at once. Modular computers read data from this.
/datum/ntnet/
/datum/ntnet
var/list/relays = list()
var/list/logs = list()
var/list/available_station_software = list()
@@ -17,14 +17,14 @@ var/global/datum/ntnet/ntnet_global = new()
var/setting_maxlogcount = 100
// These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections
var/setting_softwaredownload = 1
var/setting_peertopeer = 1
var/setting_communication = 1
var/setting_systemcontrol = 1
var/setting_disabled = 0 // Setting to 1 will disable all wireless, independently on relays status.
var/setting_softwaredownload = TRUE
var/setting_peertopeer = TRUE
var/setting_communication = TRUE
var/setting_systemcontrol = TRUE
var/setting_disabled = FALSE // Setting to 1 will disable all wireless, independently on relays status.
var/intrusion_detection_enabled = 1 // Whether the IDS warning system is enabled
var/intrusion_detection_alarm = 0 // Set when there is an IDS warning due to malicious (antag) software.
var/intrusion_detection_enabled = TRUE // Whether the IDS warning system is enabled
var/intrusion_detection_alarm = FALSE // Set when there is an IDS warning due to malicious (antag) software.
// If new NTNet datum is spawned, it replaces the old one.
@@ -62,18 +62,18 @@ var/global/datum/ntnet/ntnet_global = new()
// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled.
/datum/ntnet/proc/check_function(var/specific_action = 0)
if(!relays || !relays.len) // No relays found. NTNet is down
return 0
return FALSE
var/operating = 0
var/operating = FALSE
// Check all relays. If we have at least one working relay, network is up.
for(var/obj/machinery/ntnet_relay/R in relays)
if(R.operable())
operating = 1
operating = TRUE
break
if(setting_disabled)
return 0
return FALSE
if(specific_action == NTNET_SOFTWAREDOWNLOAD)
return (operating && setting_softwaredownload)
@@ -123,7 +123,7 @@ var/global/datum/ntnet/ntnet_global = new()
// Resets the IDS alarm
/datum/ntnet/proc/resetIDS()
intrusion_detection_alarm = 0
intrusion_detection_alarm = FALSE
/datum/ntnet/proc/toggleIDS()
resetIDS()
@@ -137,7 +137,7 @@ var/global/datum/ntnet/ntnet_global = new()
// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
/datum/ntnet/proc/update_max_log_count(var/lognumber)
if(!lognumber)
return 0
return FALSE
// Trim the value if necessary
lognumber = between(MIN_NTNET_LOGS, lognumber, MAX_NTNET_LOGS)
setting_maxlogcount = lognumber

View File

@@ -7,11 +7,11 @@
idle_power_usage = 100
icon_state = "ntnet"
icon = 'icons/obj/machines/telecomms.dmi'
anchored = 1
density = 1
var/datum/ntnet/NTNet = null // This is mostly for backwards reference and to allow varedit modifications from ingame.
var/enabled = 1 // Set to 0 if the relay was turned off
var/dos_failure = 0 // Set to 1 if the relay failed due to (D)DoS attack
anchored = TRUE
density = TRUE
var/datum/ntnet/NTNet // This is mostly for backwards reference and to allow varedit modifications from ingame.
var/enabled = TRUE // Set to FALSE if the relay was turned off
var/dos_failure = FALSE // Set to TRUE if the relay failed due to (D)DoS attack
var/list/dos_sources = list() // Backwards reference for qdel() stuff
// Denial of Service attack variables
@@ -27,30 +27,24 @@
// TODO: Implement more logic here. For now it's only a placeholder.
/obj/machinery/ntnet_relay/operable()
if(!..(EMPED))
return 0
return FALSE
if(dos_failure)
return 0
return FALSE
if(!enabled)
return 0
return 1
return FALSE
return TRUE
/obj/machinery/ntnet_relay/update_icon()
icon_state = initial(icon_state)
cut_overlays()
if (panel_open)
if(panel_open)
icon_state += "_o"
if (!operable())
if(!operable())
icon_state += "_off"
else if (dos_failure)
else if(dos_failure)
add_overlay("ntnet_o_problem")
else if (!enabled)
else if(!enabled)
add_overlay("ntnet_o_error")
else
add_overlay("ntnet_o_ok")
@@ -65,12 +59,12 @@
// If DoS traffic exceeded capacity, crash.
if((dos_overload > dos_capacity) && !dos_failure)
dos_failure = 1
dos_failure = TRUE
update_icon()
ntnet_global.add_log("Quantum relay switched from normal operation mode to overload recovery mode.")
// If the DoS buffer reaches 0 again, restart.
if((dos_overload == 0) && dos_failure)
dos_failure = 0
dos_failure = FALSE
update_icon()
ntnet_global.add_log("Quantum relay switched from overload recovery mode to normal operation mode.")
..()
@@ -94,10 +88,10 @@
/obj/machinery/ntnet_relay/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["restart"])
dos_overload = 0
dos_failure = 0
dos_overload = FALSE
dos_failure = FALSE
update_icon()
ntnet_global.add_log("Quantum relay manually restarted from overload recovery mode to normal operation mode.")
else if(href_list["toggle"])
@@ -127,22 +121,22 @@
D.error = "Connection to quantum relay severed"
return ..()
/obj/machinery/ntnet_relay/attackby(var/obj/item/W as obj, var/mob/user as mob)
/obj/machinery/ntnet_relay/attackby(obj/item/W, mob/user)
if(W.isscrewdriver())
playsound(src.loc, W.usesound, 50, 1)
playsound(get_turf(src), W.usesound, 50, TRUE)
panel_open = !panel_open
to_chat(user, "You [panel_open ? "open" : "close"] the maintenance hatch")
to_chat(user, SPAN_NOTICE("You [panel_open ? "open" : "close"] the maintenance hatch."))
return
if(W.iscrowbar())
if(!panel_open)
to_chat(user, "Open the maintenance panel first.")
to_chat(user, SPAN_WARNING("Open the maintenance panel first."))
return
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
to_chat(user, "You disassemble \the [src]!")
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
to_chat(user, SPAN_NOTICE("You disassemble \the [src]!"))
for(var/atom/movable/A in component_parts)
A.forceMove(src.loc)
new/obj/machinery/constructable_frame/machine_frame(src.loc)
A.forceMove(get_turf(src))
new /obj/machinery/constructable_frame/machine_frame(get_turf(src))
qdel(src)
return
..()

View File

@@ -8,14 +8,14 @@
if(damage > broken_damage)
shutdown_computer()
return 0
return FALSE
if(active_program && active_program.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) // Active program requires NTNet to run but we've just lost connection. Crash.
active_program.event_networkfailure(0)
if(active_program?.requires_ntnet && !get_ntnet_status(active_program.requires_ntnet_feature)) // Active program requires NTNet to run but we've just lost connection. Crash.
active_program.event_networkfailure(FALSE)
for(var/datum/computer_file/program/P in idle_threads)
if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature))
P.event_networkfailure(1)
P.event_networkfailure(TRUE)
if(active_program)
if(active_program.program_state != PROGRAM_STATE_KILLED)
@@ -36,24 +36,24 @@
working = hard_drive && processor_unit && damage < broken_damage && computer_use_power()
check_update_ui_need()
if (working && enabled && world.time > ambience_last_played + 30 SECONDS && prob(3))
playsound(loc, "computerbeep", 30, 1, 10, required_preferences = SOUND_AMBIENCE)
if(working && enabled && world.time > ambience_last_played + 30 SECONDS && prob(3))
playsound(get_turf(src), "computerbeep", 30, 1, 10, required_preferences = SOUND_AMBIENCE)
ambience_last_played = world.time
/obj/item/modular_computer/proc/get_preset_programs(preset_type)
for (var/datum/modular_computer_app_presets/prs in ntnet_global.available_software_presets)
for(var/datum/modular_computer_app_presets/prs in ntnet_global.available_software_presets)
if(prs.type == preset_type)
return prs.return_install_programs()
// Used to perform preset-specific hardware changes.
/obj/item/modular_computer/proc/install_default_hardware()
return 1
return TRUE
// Used to install preset-specific programs
/obj/item/modular_computer/proc/install_default_programs()
if(enrolled)
var/programs = get_preset_programs(_app_preset_type)
for (var/datum/computer_file/program/prog in programs)
for(var/datum/computer_file/program/prog in programs)
hard_drive.store_file(prog)
/obj/item/modular_computer/Initialize()
@@ -66,7 +66,7 @@
update_icon()
/obj/item/modular_computer/Destroy()
kill_program(1)
kill_program(TRUE)
for(var/obj/item/computer_hardware/CH in src.get_all_components())
uninstall_component(null, CH)
qdel(CH)
@@ -76,12 +76,12 @@
/obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user)
if(computer_emagged)
to_chat(user, "\The [src] has already been emagged.")
to_chat(user, SPAN_WARNING("\The [src] has already been emagged."))
return NO_EMAG_ACT
else
computer_emagged = 1
to_chat(user, "You emag \the [src]. Its screen briefly displays a \"OVERRIDE ACCEPTED: New software downloads available.\" message.")
return 1
computer_emagged = TRUE
to_chat(user, SPAN_WARNING("You emag \the [src]. Its screen briefly displays, \"OVERRIDE ACCEPTED: New software downloads available.\"."))
return TRUE
/obj/item/modular_computer/update_icon()
icon_state = icon_state_unpowered
@@ -119,29 +119,29 @@
/obj/item/modular_computer/proc/turn_on(var/mob/user)
if(tesla_link)
tesla_link.enabled = 1
tesla_link.enabled = TRUE
var/issynth = issilicon(user) // Robots and AIs get different activation messages.
if(damage > broken_damage)
if(issynth)
to_chat(user, "You send an activation signal to \the [src], but it responds with an error code. It must be damaged.")
to_chat(user, SPAN_WARNING("You send an activation signal to \the [src], but it responds with an error code. It must be damaged."))
else
to_chat(user, "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.")
to_chat(user, SPAN_WARNING("You press the power button, but the computer fails to boot up, displaying a variety of errors before shutting down again."))
return
if(processor_unit && computer_use_power()) // Battery-run and charged or non-battery but powered by APC.
if(issynth)
to_chat(user, "You send an activation signal to \the [src], turning it on")
to_chat(user, SPAN_NOTICE("You send an activation signal to \the [src], turning it on."))
else
to_chat(user, "You press the power button and start up \the [src]")
to_chat(user, SPAN_NOTICE("You press the power button and start up \the [src]."))
enable_computer(user)
else // Unpowered
if(issynth)
to_chat(user, "You send an activation signal to \the [src] but it does not respond")
to_chat(user, SPAN_WARNING("You send an activation signal to \the [src], but it does not respond."))
else
to_chat(user, "You press the power button but \the [src] does not respond")
to_chat(user, SPAN_WARNING("You press the power button, but \the [src] does not respond."))
// Relays kill program request to currently active program. Use this to quit current program.
/obj/item/modular_computer/proc/kill_program(var/forced = 0)
/obj/item/modular_computer/proc/kill_program(var/forced = FALSE)
if(active_program)
active_program.kill_program(forced)
src.vueui_transfer(active_program)
@@ -160,23 +160,23 @@
/obj/item/modular_computer/proc/add_log(var/text)
if(!get_ntnet_status())
return 0
return FALSE
return ntnet_global.add_log(text, network_card)
/obj/item/modular_computer/proc/shutdown_computer(var/loud = 1)
/obj/item/modular_computer/proc/shutdown_computer(var/loud = TRUE)
SSvueui.close_uis(active_program)
kill_program(1)
kill_program(TRUE)
for(var/datum/computer_file/program/P in idle_threads)
P.kill_program(1)
P.kill_program(TRUE)
idle_threads.Remove(P)
if(loud)
visible_message("\The [src] shuts down.")
visible_message(SPAN_NOTICE("\The [src] shuts down."))
SSvueui.close_uis(src)
enabled = 0
enabled = FALSE
update_icon()
/obj/item/modular_computer/proc/enable_computer(var/mob/user = null)
enabled = 1
/obj/item/modular_computer/proc/enable_computer(var/mob/user)
enabled = TRUE
update_icon()
// Autorun feature
@@ -208,12 +208,12 @@
P = hard_drive.find_file_by_name(prog)
if(!P || !istype(P)) // Program not found or it's not executable program.
to_chat(user, "<span class='danger'>\The [src]'s screen shows \"I/O ERROR - Unable to run [prog]\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [src]'s screen displays, \"I/O ERROR - Unable to run [prog]\"."))
return
P.computer = src
if(!P.is_supported_by_hardware(hardware_flag, 1, user))
if(!P.is_supported_by_hardware(hardware_flag, TRUE, user))
return
if(P in idle_threads)
P.program_state = PROGRAM_STATE_ACTIVE
@@ -225,11 +225,11 @@
return
if(idle_threads.len >= processor_unit.max_idle_programs+1)
to_chat(user, "<span class='notice'>\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error</span>")
to_chat(user, SPAN_WARNING("\The [src] displays, \"Maximal CPU load reached. Unable to run another program.\"."))
return
if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet.
to_chat(user, "<span class='danger'>\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.</span>")
to_chat(user, FONT_SMALL(SPAN_WARNING("\The [src] displays, \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\".")))
return
if(active_program)
@@ -240,7 +240,7 @@
if(!P.vueui_transfer(src))
SSvueui.close_uis(src)
update_icon()
return 1
return TRUE
/obj/item/modular_computer/proc/update_uis()
if(active_program) //Should we update program ui or computer ui?
@@ -251,16 +251,16 @@
SSnanoui.update_uis(src)
/obj/item/modular_computer/proc/check_update_ui_need()
var/ui_update_needed = 0
var/ui_update_needed = FALSE
if(battery_module)
var/batery_percent = battery_module.battery.percent()
if(last_battery_percent != batery_percent) //Let's update UI on percent change
ui_update_needed = 1
last_battery_percent = batery_percent
var/battery_percent = battery_module.battery.percent()
if(last_battery_percent != battery_percent) //Let's update UI on percent change
ui_update_needed = TRUE
last_battery_percent = battery_percent
if(worldtime2text() != last_world_time)
last_world_time = worldtime2text()
ui_update_needed = 1
ui_update_needed = TRUE
if(idle_threads.len)
var/list/current_header_icons = list()
@@ -273,12 +273,12 @@
else if(!listequal(last_header_icons, current_header_icons))
last_header_icons = current_header_icons
ui_update_needed = 1
ui_update_needed = TRUE
else
for(var/x in last_header_icons|current_header_icons)
if(last_header_icons[x]!=current_header_icons[x])
last_header_icons = current_header_icons
ui_update_needed = 1
ui_update_needed = TRUE
break
if(ui_update_needed)
@@ -293,3 +293,12 @@
/obj/item/modular_computer/get_cell()
return battery_module ? battery_module.get_cell() : DEVICE_NO_CELL
/obj/item/modular_computer/proc/output_message(var/message, var/message_range)
message_range += message_output_range
if(message_range == 0)
var/mob/user = loc
if(istype(user))
to_chat(user, message)
return
visible_message(message, range = message_range)

View File

@@ -1,23 +1,25 @@
/obj/item/modular_computer/examine(var/mob/user)
/obj/item/modular_computer/examine(mob/user)
..()
if(Adjacent(user))
to_chat(user, FONT_SMALL(SPAN_NOTICE("It contains the following hardware:")))
for(var/CH in get_all_components())
to_chat(user, FONT_SMALL(SPAN_NOTICE(" - [capitalize_first_letters(CH)]")))
if(damage > broken_damage)
to_chat(user, "<span class='danger'>It is heavily damaged!</span>")
to_chat(user, SPAN_DANGER("It is heavily damaged!"))
else if(damage)
to_chat(user, "It is damaged.")
to_chat(user, SPAN_WARNING("It is damaged."))
/obj/item/modular_computer/proc/break_apart()
visible_message("\The [src] breaks apart!")
var/turf/newloc = get_turf(src)
new /obj/item/stack/material/steel(newloc, round(steel_sheet_cost/2))
visible_message(SPAN_WARNING("\The [src] breaks apart!"))
new /obj/item/stack/material/steel(get_turf(src), round(steel_sheet_cost/2))
for(var/obj/item/computer_hardware/H in get_all_components())
uninstall_component(null, H)
H.forceMove(newloc)
H.forceMove(get_turf(src))
if(prob(25))
H.take_damage(rand(10,30))
H.take_damage(rand(10, 30))
qdel(src)
/obj/item/modular_computer/proc/take_damage(var/amount, var/component_probability, var/damage_casing = 1, var/randomize = 1)
/obj/item/modular_computer/proc/take_damage(var/amount, var/component_probability, var/damage_casing = TRUE, var/randomize = TRUE)
if(randomize)
// 75%-125%, rand() works with integers, apparently.
amount *= (rand(75, 125) / 100.0)
@@ -42,7 +44,7 @@
// EMPs are similar to explosions, but don't cause physical damage to the casing. Instead they screw up the components
/obj/item/modular_computer/emp_act(var/severity)
take_damage(rand(100, 200) / severity, 50 / severity, 0)
take_damage(rand(100, 200) / severity, 50 / severity, FALSE)
// "Stun" weapons can cause minor damage to components (short-circuits?)
// "Burn" damage is equally strong against internal components and exterior casing

View File

@@ -1,131 +1,128 @@
// Attempts to install the hardware into appropriate slot.
/obj/item/modular_computer/proc/try_install_component(var/mob/living/user, var/obj/item/computer_hardware/H, var/found = 0)
/obj/item/modular_computer/proc/try_install_component(var/mob/living/user, var/obj/item/computer_hardware/H, var/found = FALSE)
// "USB" flash drive.
if(istype(H, /obj/item/computer_hardware/hard_drive/portable))
if(enrolled == 1 && !computer_emagged)
to_chat(user, "The client management software on this computer rejects \the [portable_drive].")
return
if(portable_drive)
to_chat(user, "This computer's portable drive slot is already occupied by \the [portable_drive].")
to_chat(user, SPAN_WARNING("\The [src]'s portable drive slot is already occupied by \the [portable_drive]."))
return
found = 1
found = TRUE
portable_drive = H
else if(istype(H, /obj/item/computer_hardware/hard_drive))
if(hard_drive)
to_chat(user, "This computer's hard drive slot is already occupied by \the [hard_drive].")
to_chat(user, SPAN_WARNING("\The [src]'s hard drive slot is already occupied by \the [hard_drive]."))
return
found = 1
found = TRUE
hard_drive = H
else if(istype(H, /obj/item/computer_hardware/network_card))
if(network_card)
to_chat(user, "This computer's network card slot is already occupied by \the [network_card].")
to_chat(user, SPAN_WARNING("\The [src]'s network card slot is already occupied by \the [network_card]."))
return
found = 1
found = TRUE
network_card = H
else if(istype(H, /obj/item/computer_hardware/nano_printer))
if(nano_printer)
to_chat(user, "This computer's nano printer slot is already occupied by \the [nano_printer].")
to_chat(user, SPAN_WARNING("\The [src]'s nano printer slot is already occupied by \the [nano_printer]."))
return
found = 1
found = TRUE
nano_printer = H
else if(istype(H, /obj/item/computer_hardware/card_slot))
if(card_slot)
to_chat(user, "This computer's card slot is already occupied by \the [card_slot].")
to_chat(user, SPAN_WARNING("\The [src]'s card slot is already occupied by \the [card_slot]."))
return
found = 1
found = TRUE
card_slot = H
else if(istype(H, /obj/item/computer_hardware/battery_module))
if(battery_module)
to_chat(user, "This computer's battery slot is already occupied by \the [battery_module].")
to_chat(user, SPAN_WARNING("\The [src]'s battery slot is already occupied by \the [battery_module]."))
return
found = 1
found = TRUE
battery_module = H
else if(istype(H, /obj/item/computer_hardware/processor_unit))
if(processor_unit)
to_chat(user, "This computer's processor slot is already occupied by \the [processor_unit].")
to_chat(user, SPAN_WARNING("\The [src]'s processor slot is already occupied by \the [processor_unit]."))
return
found = 1
found = TRUE
processor_unit = H
else if(istype(H, /obj/item/computer_hardware/ai_slot))
if(ai_slot)
to_chat(user, "This computer's intellicard slot is already occupied by \the [ai_slot].")
to_chat(user, SPAN_WARNING("\The [src]'s intellicard slot is already occupied by \the [ai_slot]."))
return
found = 1
found = TRUE
ai_slot = H
else if(istype(H, /obj/item/computer_hardware/tesla_link))
if(tesla_link)
to_chat(user, "This computer's tesla link slot is already occupied by \the [tesla_link].")
to_chat(user, SPAN_WARNING("\The [src]'s tesla link slot is already occupied by \the [tesla_link]."))
return
found = 1
found = TRUE
tesla_link = H
if(found)
to_chat(user, "You install \the [H] into \the [src]")
H.holder2 = src
user.drop_from_inventory(H,src)
to_chat(user, SPAN_NOTICE("You install \the [H] into \the [src]."))
H.parent_computer = src
user.drop_from_inventory(H, src)
update_icon()
// Uninstalls component. Found and Critical vars may be passed by parent types, if they have additional hardware.
/obj/item/modular_computer/proc/uninstall_component(var/mob/living/user, var/obj/item/computer_hardware/H, var/found = 0, var/critical = 0)
/obj/item/modular_computer/proc/uninstall_component(var/mob/living/user, var/obj/item/computer_hardware/H, var/found = FALSE, var/critical = FALSE)
if(portable_drive == H)
portable_drive = null
found = 1
found = TRUE
else if(hard_drive == H)
hard_drive = null
found = 1
critical = 1
found = TRUE
critical = TRUE
else if(network_card == H)
network_card = null
found = 1
found = TRUE
else if(nano_printer == H)
nano_printer = null
found = 1
found = TRUE
else if(card_slot == H)
card_slot = null
found = 1
found = TRUE
else if(battery_module == H)
battery_module = null
found = 1
found = TRUE
else if(processor_unit == H)
processor_unit = null
found = 1
found = TRUE
critical = 1
else if(ai_slot == H)
ai_slot = null
found = 1
found = TRUE
else if(tesla_link == H)
tesla_link = null
found = 1
found = TRUE
if(found)
if(user)
to_chat(user, "You remove \the [H] from \the [src].")
to_chat(user, SPAN_NOTICE("You remove \the [H] from \the [src]."))
H.forceMove(get_turf(src))
H.holder2 = null
H.parent_computer = null
update_icon()
if(critical && enabled)
to_chat(user, "<span class='danger'>\The [src]'s screen freezes for few seconds and then displays an \"HARDWARE ERROR: Critical component disconnected. Please verify component connection and reboot the device. If the problem persists contact technical support for assistance.\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [src]'s screen freezes for few seconds and then displays, \"HARDWARE ERROR: Critical component disconnected. Please verify component connection and reboot the device. If the problem persists contact technical support for assistance.\"."))
shutdown_computer()
// Checks all hardware pieces to determine if name matches, if yes, returns the hardware piece, otherwise returns null
/obj/item/modular_computer/proc/find_hardware_by_name(var/name)
if(portable_drive && (portable_drive.name == name))
if(portable_drive && (initial(portable_drive.name) == name))
return portable_drive
if(hard_drive && (hard_drive.name == name))
if(hard_drive && (initial(hard_drive.name) == name))
return hard_drive
if(network_card && (network_card.name == name))
if(network_card && (initial(network_card.name) == name))
return network_card
if(nano_printer && (nano_printer.name == name))
if(nano_printer && (initial(nano_printer.name) == name))
return nano_printer
if(card_slot && (card_slot.name == name))
if(card_slot && (initial(card_slot.name) == name))
return card_slot
if(battery_module && (battery_module.name == name))
if(battery_module && (initial(battery_module.name) == name))
return battery_module
if(processor_unit && (processor_unit.name == name))
if(processor_unit && (initial(processor_unit.name) == name))
return processor_unit
if(ai_slot && (ai_slot.name == name))
if(ai_slot && (initial(ai_slot.name) == name))
return ai_slot
if(tesla_link && (tesla_link.name == name))
if(tesla_link && (initial(tesla_link.name) == name))
return tesla_link
return null

View File

@@ -4,12 +4,7 @@
set category = "Object"
set src in view(1)
if(usr.incapacitated() || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "<span class='warning'>You can't reach it.</span>")
if(use_check_and_message(usr))
return
proc_eject_id(usr)
@@ -20,12 +15,7 @@
set category = "Object"
set src in view(1)
if(usr.incapacitated() || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "<span class='warning'>You can't reach it.</span>")
if(use_check_and_message(usr))
return
proc_eject_usb(usr)
@@ -35,12 +25,7 @@
set category = "Object"
set src in view(1)
if(usr.incapacitated() || !istype(usr, /mob/living))
to_chat(usr, "<span class='warning'>You can't do that.</span>")
return
if(!Adjacent(usr))
to_chat(usr, "<span class='warning'>You can't reach it.</span>")
if(use_check_and_message(usr))
return
proc_eject_ai(usr)
@@ -50,25 +35,25 @@
user = usr
if(!card_slot)
to_chat(user, "\The [src] does not have an ID card slot")
to_chat(user, SPAN_WARNING("\The [src] does not have an ID card slot."))
return
if(!card_slot.stored_card)
to_chat(user, "There is no card in \the [src]")
to_chat(user, SPAN_WARNING("There is no card in \the [src]."))
return
if(active_program)
active_program.event_idremoved(0)
active_program.event_idremoved(FALSE)
for(var/datum/computer_file/program/P in idle_threads)
P.event_idremoved(1)
P.event_idremoved(TRUE)
if(ishuman(user))
user.put_in_hands(card_slot.stored_card)
else
card_slot.stored_card.forceMove(get_turf(src))
card_slot.stored_card = null
update_uis()
to_chat(user, "You remove the card from \the [src]")
to_chat(user, SPAN_NOTICE("You remove the card from \the [src]."))
/obj/item/modular_computer/proc/proc_eject_usb(mob/user)
@@ -76,7 +61,7 @@
user = usr
if(!portable_drive)
to_chat(user, "There is no portable device connected to \the [src].")
to_chat(user, SPAN_WARNING("There is no portable drive connected to \the [src]."))
return
uninstall_component(user, portable_drive)
@@ -86,8 +71,12 @@
if(!user)
user = usr
if(!ai_slot || !ai_slot.stored_card)
to_chat(user, "There is no intellicard connected to \the [src].")
if(!ai_slot)
to_chat(user, SPAN_WARNING("\The [src] doesn't have an intellicard slot."))
return
if(!ai_slot.stored_card)
to_chat(user, SPAN_WARNING("There is no intellicard connected to \the [src]."))
return
if(ishuman(user))
@@ -123,33 +112,33 @@
else if(!enabled && screen_on)
turn_on(user)
/obj/item/modular_computer/attackby(var/obj/item/W as obj, var/mob/user as mob)
/obj/item/modular_computer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/card/tech_support))
if(!can_reset)
to_chat(user, span("notice", "You cannot reset this type of device."))
to_chat(user, SPAN_WARNING("You cannot reset this type of device."))
return
if(!enabled)
to_chat(user, span("notice", "You cannot reset the device if it isn't powered on."))
to_chat(user, SPAN_WARNING("You cannot reset the device if it isn't powered on."))
return
if(!hard_drive)
to_chat(user, span("notice", "You cannot reset a device that has no hard drive."))
to_chat(user, SPAN_WARNING("You cannot reset a device that has no hard drive."))
return
enrolled = 0
enrolled = FALSE
hard_drive.reset_drive()
visible_message("\icon[src.icon] <b>[src]</b> pings, <span class='notice'>\"Enrollment status reset! Have a NanoTrasen day.\"</span>")
if(istype(W, /obj/item/card/id)) // ID Card, try to insert it.
var/obj/item/card/id/I = W
if(!card_slot)
to_chat(user, "You try to insert \the [I] into \the [src], but it does not have an ID card slot installed.")
to_chat(user, SPAN_WARNING("You try to insert \the [I] into \the [src], but it does not have an ID card slot installed."))
return
if(card_slot.stored_card)
to_chat(user, SPAN_WARNING("You try to insert \the [I] into \the [src], but its ID card slot is occupied."))
return
if(card_slot.stored_card)
to_chat(user, "You try to insert \the [I] into \the [src], but it's ID card slot is occupied.")
return
user.drop_from_inventory(I,src)
user.drop_from_inventory(I, src)
card_slot.stored_card = I
update_uis()
to_chat(user, "You insert \the [I] into \the [src].")
to_chat(user, SPAN_NOTICE("You insert \the [I] into \the [src]."))
return
if(istype(W, /obj/item/paper))
if(!nano_printer)
@@ -164,63 +153,59 @@
if(C.hardware_size <= max_hardware_size)
try_install_component(user, C)
else
to_chat(user, "This component is too large for \the [src].")
to_chat(user, SPAN_WARNING("This component is too large for \the [src]."))
if(W.iswrench())
var/list/components = get_all_components()
if(components.len)
to_chat(user, "Remove all components from \the [src] before disassembling it.")
to_chat(user, SPAN_WARNING("You have to remove all the components from \the [src] before disassembling it."))
return
to_chat(user, span("notice", "You begin to disassemble \the [src]."))
playsound(user, W.usesound, 100, 1)
to_chat(user, SPAN_NOTICE("You begin to disassemble \the [src]."))
playsound(get_turf(src), W.usesound, 100, TRUE)
if (do_after(user, 20/W.toolspeed))
new /obj/item/stack/material/steel(get_turf(src.loc), steel_sheet_cost)
src.visible_message("\The [user] disassembles \the [src].",
"You disassemble \the [src].",
"You hear a ratchet.")
new /obj/item/stack/material/steel(get_turf(src), steel_sheet_cost)
user.visible_message(SPAN_NOTICE("\The [user] disassembles \the [src]."), SPAN_NOTICE("You disassemble \the [src]."), SPAN_NOTICE("You hear a ratcheting noise."))
qdel(src)
return
if(W.iswelder())
var/obj/item/weldingtool/WT = W
if(!WT.isOn())
to_chat(user, "\The [W] is off.")
to_chat(user, SPAN_WARNING("\The [W] is off."))
return
if(!damage)
to_chat(user, "\The [src] does not require repairs.")
to_chat(user, SPAN_WARNING("\The [src] does not require repairs."))
return
to_chat(user, "You begin repairing damage to \the [src]...")
playsound(src, 'sound/items/Welder.ogg', 100, 1)
if(WT.remove_fuel(round(damage/75)) && do_after(usr, damage/10))
to_chat(user, SPAN_NOTICE("You begin repairing the damage to \the [src]..."))
playsound(get_turf(src), 'sound/items/Welder.ogg', 100, 1)
if(WT.remove_fuel(round(damage / 75)) && do_after(user, damage / 10))
damage = 0
to_chat(user, "You repair \the [src].")
to_chat(user, SPAN_NOTICE("You fully repair \the [src]."))
update_icon()
return
if(W.isscrewdriver())
var/list/all_components = get_all_components()
if(!all_components.len)
to_chat(user, "This device doesn't have any components installed.")
to_chat(user, SPAN_WARNING("This device doesn't have any components installed."))
return
var/list/component_names = list()
for(var/obj/item/computer_hardware/H in all_components)
component_names.Add(H.name)
var/choice = input(usr, "Which component do you want to uninstall?", "Computer maintenance", null) as null|anything in component_names
var/obj/item/computer_hardware/choice = input(user, "Which component do you want to uninstall?", "Hardware Removal") as null|anything in all_components
if(!choice)
return
if(!Adjacent(usr))
return
var/obj/item/computer_hardware/H = find_hardware_by_name(choice)
var/obj/item/computer_hardware/H = find_hardware_by_name(initial(choice.name))
if(!H)
return
uninstall_component(user, H)
return
..()
/obj/item/modular_computer/MouseDrop(atom/over_object)
var/mob/M = usr
if(use_check_and_message(M))
return
if(!istype(over_object, /obj/screen) && !(over_object == src))
return attack_self(M)

View File

@@ -1,17 +1,16 @@
/obj/item/modular_computer/proc/power_failure(var/malfunction = 0)
/obj/item/modular_computer/proc/power_failure(var/malfunction = FALSE)
if(enabled) // Shut down the computer
visible_message("<span class='danger'>\The [src]'s screen flickers briefly and then goes dark.</span>")
visible_message(SPAN_WARNING("\The [src]'s screen flickers briefly and then goes dark."))
if(active_program)
active_program.event_powerfailure(0)
active_program.event_powerfailure(FALSE)
for(var/datum/computer_file/program/PRG in idle_threads)
PRG.event_powerfailure(1)
shutdown_computer(0)
PRG.event_powerfailure(TRUE)
shutdown_computer(FALSE)
power_has_failed = TRUE
update_icon()
// Tries to use power from battery. Passing 0 as parameter results in this proc returning whether battery is functional or not.
/obj/item/modular_computer/proc/battery_power(var/power_usage = 0)
// Tries to use power from battery. Passing false as parameter results in this proc returning whether battery is functional or not.
/obj/item/modular_computer/proc/battery_power(var/power_usage = FALSE)
apc_powered = FALSE
if(!battery_module || !battery_module.check_functionality() || battery_module.battery.charge <= 0)
return FALSE
@@ -51,15 +50,14 @@
// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged
/obj/item/modular_computer/proc/handle_power()
var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage
if (enabled)
if(enabled)
for(var/obj/item/computer_hardware/H in get_all_components())
if(H.enabled)
power_usage += H.power_usage
last_power_usage = power_usage
if(computer_use_power(power_usage))
if (power_has_failed)
if(power_has_failed)
power_has_failed = FALSE
update_icon()
return

View File

@@ -18,10 +18,10 @@
// We are still here, that means there is no program loaded. Load the BIOS/ROM/OS/whatever you want to call it.
// This screen simply lists available programs and user may select them.
if(!hard_drive || !hard_drive.stored_files || !hard_drive.stored_files.len)
visible_message("\The [src] beeps three times, it's screen displaying \"DISK ERROR\" warning.")
visible_message(SPAN_WARNING("\The [src] beeps three times, its screen displaying, \"DISK ERROR!\"."))
return // No HDD, No HDD files list or no stored files. Something is very broken.
if (!ui)
if(!ui)
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-system-main", 400, 500, "NTOS Main Menu")
ui.header = "modular-computer"
ui.open()
@@ -55,30 +55,30 @@
// Handles user's GUI input
/obj/item/modular_computer/Topic(href, href_list)
if(..())
return 1
if( href_list["PC_exit"] )
return TRUE
if(href_list["PC_exit"])
kill_program()
return 1
if( href_list["PC_enable_component"] )
return TRUE
if(href_list["PC_enable_component"])
var/obj/item/computer_hardware/H = find_hardware_by_name(href_list["PC_enable_component"])
if(H && istype(H) && !H.enabled)
H.enabled = 1
. = 1
if( href_list["PC_disable_component"] )
H.enabled = TRUE
. = TRUE
if(href_list["PC_disable_component"])
var/obj/item/computer_hardware/H = find_hardware_by_name(href_list["PC_disable_component"])
if(H && istype(H) && H.enabled)
H.enabled = 0
. = 1
if( href_list["PC_shutdown"] )
. = TRUE
if(href_list["PC_shutdown"])
shutdown_computer()
return 1
if( href_list["PC_minimize"] )
return TRUE
if(href_list["PC_minimize"])
var/mob/user = usr
minimize_program(user)
if( href_list["PC_killprogram"] )
if(href_list["PC_killprogram"])
var/prog = href_list["PC_killprogram"]
var/datum/computer_file/program/P = null
var/datum/computer_file/program/P
var/mob/user = usr
if(hard_drive)
P = hard_drive.find_file_by_name(prog)
@@ -86,20 +86,20 @@
if(!istype(P) || P.program_state == PROGRAM_STATE_KILLED)
return
P.kill_program(1)
P.kill_program(TRUE)
update_uis()
to_chat(user, "<span class='notice'>Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.</span>")
to_chat(user, SPAN_NOTICE("Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed."))
if( href_list["PC_runprogram"] )
if(href_list["PC_runprogram"])
. = run_program(href_list["PC_runprogram"])
ui_interact(usr)
if( href_list["PC_setautorun"] )
if(href_list["PC_setautorun"])
if(!hard_drive)
return
var/datum/computer_file/data/autorun = hard_drive.find_file_by_name("autorun")
if(!istype(autorun))
autorun = new/datum/computer_file/data()
autorun = new /datum/computer_file/data()
autorun.filename = "autorun"
hard_drive.store_file(autorun)
if(autorun.stored_data == href_list["PC_setautorun"])

View File

@@ -1,14 +1,13 @@
// This is the base type that handles everything. Subtypes can be easily created by tweaking variables in this file to your liking.
/obj/item/modular_computer
name = "Modular Computer"
desc = "A modular computer. You shouldn't see this."
var/enabled = 0 // Whether the computer is turned on.
var/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
var/working = 1 // Whether the computer is working.
var/enabled = FALSE // Whether the computer is turned on.
var/screen_on = TRUE // Whether the computer is active/opened/it's screen is on.
var/working = TRUE // Whether the computer is working.
var/can_reset = FALSE // Whether you can reset this device with the tech support card.
var/datum/computer_file/program/active_program = null // A currently active program running on the computer.
var/datum/computer_file/program/active_program // A currently active program running on the computer.
var/hardware_flag = 0 // A flag that describes this device type
var/last_power_usage = 0 // Last tick power usage of this computer
var/last_battery_percent = 0 // Used for deciding if battery percentage has chandged
@@ -18,8 +17,8 @@
var/apc_powered = FALSE // Set automatically. Whether the computer used APC power last tick.
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/enrolled = 0 // Weather the computer is enrolled in the company device management or not. 0 - unconfigured 1 - enrolled (work device) 2 - unenrolled (private device)
var/_app_preset_type = null // Used for specifying the software preset of the console
var/enrolled = FALSE // Weather the computer is enrolled in the company device management or not. 0 - unconfigured 1 - enrolled (work device) 2 - unenrolled (private device)
var/_app_preset_type // Used for specifying the software preset of the console
var/ambience_last_played // Last time sound was played
// Modular computers can run on various devices. Each DEVICE (Laptop, Console, Tablet,..)
@@ -30,13 +29,14 @@
icon_state = null // And no random pixelshifting on-creation either.
randpixel = 0
center_of_mass = null
var/icon_state_unpowered = null // Icon state when the computer is turned off
var/icon_state_unpowered // Icon state when the computer is turned off
var/icon_state_menu = "menu" // Icon state overlay when the computer is turned on, but no program is loaded that would override the screen.
var/icon_state_screensaver = null
var/icon_state_broken = null
var/icon_state_screensaver
var/icon_state_broken
var/screensaver_light_range = 0
var/screensaver_light_color = null
var/menu_light_color = null
var/screensaver_light_color
var/menu_light_color
var/message_output_range = 0 // Adds onto the output_message proc's range
var/max_hardware_size = 0 // Maximal hardware size. Currently, tablets have 1, laptops 2 and consoles 3. Limits what hardware types can be installed.
var/steel_sheet_cost = 5 // Amount of steel sheets refunded when disassembling an empty frame of this computer.
var/light_strength = 0 // Intensity of light this computer emits. Comparable to numbers light fixtures use.

View File

@@ -10,7 +10,8 @@
menu_light_color = LIGHT_COLOR_BLUE
hardware_flag = PROGRAM_CONSOLE
anchored = TRUE
density = 1
density = TRUE
message_output_range = 1
base_idle_power_usage = 100
base_active_power_usage = 500
max_hardware_size = 3

View File

@@ -2,6 +2,7 @@
anchored = TRUE
name = "laptop computer"
desc = "A portable computer."
description_info = "You can alt-click the laptop while it's set down on surface to open it up and work with it. Left clicking while it is open will allow you to operate it."
hardware_flag = PROGRAM_LAPTOP
can_reset = TRUE
icon_state_unpowered = "laptop-open"
@@ -12,19 +13,20 @@
center_of_mass = list("x"=14, "y"=10)
base_idle_power_usage = 25
base_active_power_usage = 200
message_output_range = 1
max_hardware_size = 2
light_strength = 3
max_damage = 50
broken_damage = 25
w_class = 3
var/icon_state_closed = "laptop-closed"
/obj/item/modular_computer/laptop/AltClick()
if (use_check(usr)) return
if(use_check(usr))
return
// Prevents carrying of open laptops inhand.
// While they work inhand, i feel it'd make tablets lose some of their high-mobility advantage they have over laptops now.
if(!istype(loc, /turf/))
to_chat(usr, "\The [src] has to be on a stable surface first!")
if(!isturf(loc))
to_chat(usr, SPAN_NOTICE("\The [src] has to be on a stable surface first!"))
return
anchored = !anchored
screen_on = anchored

View File

@@ -10,7 +10,6 @@
base_active_power_usage = 25
max_hardware_size = 3
max_damage = 50
w_class = 3
var/mob/living/silicon/computer_host // Thing that contains this computer. Used for silicon computers
/obj/item/modular_computer/silicon/Initialize(mapload)
@@ -43,4 +42,3 @@
/obj/item/modular_computer/silicon/Click(location, control, params)
return attack_self(usr)

View File

@@ -8,7 +8,7 @@
can_reset = TRUE
hardware_flag = PROGRAM_TABLET
max_hardware_size = 1
w_class = 2
w_class = ITEMSIZE_SMALL
light_strength = 2 // Same as PDAs
/obj/item/modular_computer/tablet/Initialize()

View File

@@ -8,16 +8,17 @@
icon_state_broken = "telescreen-broken"
hardware_flag = PROGRAM_TELESCREEN
anchored = TRUE
density = 0
density = FALSE
base_idle_power_usage = 75
base_active_power_usage = 300
message_output_range = 1
max_hardware_size = 2
steel_sheet_cost = 10
light_strength = 4
w_class = 5
w_class = ITEMSIZE_HUGE
is_holographic = TRUE
/obj/item/modular_computer/telescreen/attackby(var/obj/item/W as obj, var/mob/user as mob)
/obj/item/modular_computer/telescreen/attackby(obj/item/W, mob/user)
if(W.iscrowbar())
if(anchored)
shutdown_computer()
@@ -25,7 +26,7 @@
screen_on = FALSE
pixel_x = 0
pixel_y = 0
to_chat(user, "You unsecure \the [src].")
to_chat(user, SPAN_NOTICE("You unsecure \the [src]."))
else
var/choice = input(user, "Where do you want to place \the [src]?", "Offset selection") in list("North", "South", "West", "East", "This tile", "Cancel")
var/valid = FALSE
@@ -46,8 +47,8 @@
valid = TRUE
if(valid)
anchored = 1
anchored = TRUE
screen_on = TRUE
to_chat(user, "You secure \the [src].")
to_chat(user, SPAN_NOTICE("You secure \the [src]."))
return
..()

View File

@@ -1,138 +1,137 @@
/obj/item/modular_computer/console/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(istype(mover,/obj/item/projectile))
if (prob(80))
if(prob(80))
//Holoscreens are non solid, and the frames of the computers are thin. So projectiles will usually
//pass through
return 1
return TRUE
else if(istype(mover) && mover.checkpass(PASSTABLE))
//Animals can run under them, lots of empty space
return 1
return TRUE
return ..()
/obj/item/modular_computer/console/preset/install_default_hardware()
..()
processor_unit = new/obj/item/computer_hardware/processor_unit(src)
tesla_link = new/obj/item/computer_hardware/tesla_link(src)
hard_drive = new/obj/item/computer_hardware/hard_drive/super(src)
network_card = new/obj/item/computer_hardware/network_card/wired(src)
nano_printer = new/obj/item/computer_hardware/nano_printer(src)
processor_unit = new /obj/item/computer_hardware/processor_unit(src)
tesla_link = new /obj/item/computer_hardware/tesla_link(src)
hard_drive = new /obj/item/computer_hardware/hard_drive/super(src)
network_card = new /obj/item/computer_hardware/network_card/wired(src)
nano_printer = new /obj/item/computer_hardware/nano_printer(src)
/obj/item/modular_computer/console/preset/install_default_programs()
..()
// Engineering
/obj/item/modular_computer/console/preset/engineering/
/obj/item/modular_computer/console/preset/engineering
name = "engineering console"
_app_preset_type = /datum/modular_computer_app_presets/engineering
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/engineering/ce
name = "engineering console"
_app_preset_type = /datum/modular_computer_app_presets/engineering/ce
enrolled = 1
enrolled = TRUE
// Medical
/obj/item/modular_computer/console/preset/medical/
/obj/item/modular_computer/console/preset/medical
name = "medical console"
_app_preset_type = /datum/modular_computer_app_presets/medical
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/medical/cmo
name = "medical console"
_app_preset_type = /datum/modular_computer_app_presets/medical/cmo
enrolled = 1
enrolled = TRUE
// Research
/obj/item/modular_computer/console/preset/research/
/obj/item/modular_computer/console/preset/research
name = "research console"
_app_preset_type = /datum/modular_computer_app_presets/research
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/research/install_default_hardware()
..()
ai_slot = new/obj/item/computer_hardware/ai_slot(src)
ai_slot = new /obj/item/computer_hardware/ai_slot(src)
// Command
/obj/item/modular_computer/console/preset/command/
/obj/item/modular_computer/console/preset/command
name = "command console"
_app_preset_type = /datum/modular_computer_app_presets/command
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/command/install_default_hardware()
..()
nano_printer = new/obj/item/computer_hardware/nano_printer(src)
nano_printer = new /obj/item/computer_hardware/nano_printer(src)
nano_printer.max_paper = 25
nano_printer.stored_paper = 20
card_slot = new/obj/item/computer_hardware/card_slot(src)
card_slot = new /obj/item/computer_hardware/card_slot(src)
/obj/item/modular_computer/console/preset/command/captain
name = "captain's console"
_app_preset_type = /datum/modular_computer_app_presets/captain
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/command/hop
name = "command console"
_app_preset_type = /datum/modular_computer_app_presets/command/hop
enrolled = 1
enrolled = TRUE
// Security
/obj/item/modular_computer/console/preset/security/
/obj/item/modular_computer/console/preset/security
name = "security console"
_app_preset_type = /datum/modular_computer_app_presets/security
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/security/investigations
name = "investigations console"
_app_preset_type = /datum/modular_computer_app_presets/security/investigations
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/security/hos
name = "head of security's console"
_app_preset_type = /datum/modular_computer_app_presets/security/hos
enrolled = 1
enrolled = TRUE
// Civilian
/obj/item/modular_computer/console/preset/civilian/
/obj/item/modular_computer/console/preset/civilian
name = "civilian console"
_app_preset_type = /datum/modular_computer_app_presets/civilian
enrolled = 1
enrolled = TRUE
// Supply
/obj/item/modular_computer/console/preset/supply/
/obj/item/modular_computer/console/preset/supply
name = "supply console"
_app_preset_type = /datum/modular_computer_app_presets/supply
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/console/preset/supply/install_default_hardware()
..()
nano_printer.max_paper = 25
nano_printer.stored_paper = 20
card_slot = new/obj/item/computer_hardware/card_slot(src)
card_slot = new /obj/item/computer_hardware/card_slot(src)
// ERT
/obj/item/modular_computer/console/preset/ert/install_default_hardware()
..()
ai_slot = new/obj/item/computer_hardware/ai_slot(src)
ai_slot = new /obj/item/computer_hardware/ai_slot(src)
nano_printer.max_paper = 25
nano_printer.stored_paper = 20
card_slot = new/obj/item/computer_hardware/card_slot(src)
card_slot = new /obj/item/computer_hardware/card_slot(src)
/obj/item/modular_computer/console/preset/ert/
/obj/item/modular_computer/console/preset/ert
_app_preset_type = /datum/modular_computer_app_presets/ert
enrolled = 2
computer_emagged = TRUE
// Mercenary
/obj/item/modular_computer/console/preset/mercenary/
/obj/item/modular_computer/console/preset/mercenary
_app_preset_type = /datum/modular_computer_app_presets/merc
computer_emagged = TRUE
enrolled = 2
/obj/item/modular_computer/console/preset/mercenary/install_default_hardware()
..()
ai_slot = new/obj/item/computer_hardware/ai_slot(src)
card_slot = new/obj/item/computer_hardware/card_slot(src)
ai_slot = new /obj/item/computer_hardware/ai_slot(src)
card_slot = new /obj/item/computer_hardware/card_slot(src)
// Merchant

View File

@@ -1,6 +1,6 @@
/obj/item/modular_computer/laptop/preset
anchored = 0
screen_on = 0
anchored = FALSE
screen_on = FALSE
icon_state = "laptop-closed"
/obj/item/modular_computer/laptop/preset/install_default_hardware()
@@ -18,31 +18,31 @@
..()
// Engineering
/obj/item/modular_computer/laptop/preset/engineering/
/obj/item/modular_computer/laptop/preset/engineering
name = "engineering laptop"
desc = "A portable computer belonging to the engineering department. It appears to have been used as a door stop at one point or another."
_app_preset_type = /datum/modular_computer_app_presets/engineering
enrolled = TRUE
/obj/item/modular_computer/laptop/preset/engineering/ce/
/obj/item/modular_computer/laptop/preset/engineering/ce
name = "chief engineer's laptop"
desc = "A portable computer belonging to the chief engineer."
_app_preset_type = /datum/modular_computer_app_presets/engineering/ce
// Medical
/obj/item/modular_computer/laptop/preset/medical/
/obj/item/modular_computer/laptop/preset/medical
name = "medical laptop"
desc = "A portable computer belonging to the medical department."
_app_preset_type = /datum/modular_computer_app_presets/medical
enrolled = TRUE
/obj/item/modular_computer/laptop/preset/medical/cmo/
/obj/item/modular_computer/laptop/preset/medical/cmo
name = "chief medical officer's laptop"
desc = "A portable computer belonging to the chief medical officer."
_app_preset_type = /datum/modular_computer_app_presets/medical/cmo
// Research
/obj/item/modular_computer/laptop/preset/research/
/obj/item/modular_computer/laptop/preset/research
name = "research laptop"
desc = "A portable computer belonging to the research department."
_app_preset_type = /datum/modular_computer_app_presets/research
@@ -52,18 +52,18 @@
..()
ai_slot = new /obj/item/computer_hardware/ai_slot(src)
/obj/item/modular_computer/laptop/preset/research/rd/
/obj/item/modular_computer/laptop/preset/research/rd
name = "research director's laptop"
desc = "A portable computer belonging to the research director. The edges are stained and partially melted."
_app_preset_type = /datum/modular_computer_app_presets/research/rd
// Command
/obj/item/modular_computer/laptop/preset/command/
/obj/item/modular_computer/laptop/preset/command
name = "command laptop"
_app_preset_type = /datum/modular_computer_app_presets/command
enrolled = TRUE
/obj/item/modular_computer/laptop/preset/command/hop/
/obj/item/modular_computer/laptop/preset/command/hop
name = "head of personnel's laptop"
desc = "A portable computer beloning to the head of personnel. The fan is filled with dog hair."
_app_preset_type = /datum/modular_computer_app_presets/command/hop
@@ -72,7 +72,7 @@
..()
card_slot = new /obj/item/computer_hardware/card_slot(src)
/obj/item/modular_computer/laptop/preset/command/captain/
/obj/item/modular_computer/laptop/preset/command/captain
name = "captain's laptop"
desc = "A portable computer belonging to the captain."
_app_preset_type = /datum/modular_computer_app_presets/captain
@@ -82,31 +82,31 @@
card_slot = new /obj/item/computer_hardware/card_slot(src)
// Security
/obj/item/modular_computer/laptop/preset/security/
/obj/item/modular_computer/laptop/preset/security
name = "security laptop"
desc = "A portable computer belonging to the security department."
_app_preset_type = /datum/modular_computer_app_presets/security
enrolled = TRUE
/obj/item/modular_computer/laptop/preset/security/hos/
/obj/item/modular_computer/laptop/preset/security/hos
name = "head of security's laptop"
desc = "A portable computer belonging to the head of security. It smells faintly of gunpowder."
_app_preset_type = /datum/modular_computer_app_presets/security/hos
// Civilian
/obj/item/modular_computer/laptop/preset/civilian/
/obj/item/modular_computer/laptop/preset/civilian
_app_preset_type = /datum/modular_computer_app_presets/civilian
enrolled = TRUE
// Supply
/obj/item/modular_computer/laptop/preset/supply/
/obj/item/modular_computer/laptop/preset/supply
name = "supply laptop"
desc = "A portable computer belonging to cargo."
_app_preset_type = /datum/modular_computer_app_presets/supply
enrolled = TRUE
// Representative
/obj/item/modular_computer/laptop/preset/representative/
/obj/item/modular_computer/laptop/preset/representative
name = "representative's laptop"
desc = "A portable computer belonging to the representative's office."
_app_preset_type = /datum/modular_computer_app_presets/representative

View File

@@ -7,7 +7,6 @@
hard_drive = new /obj/item/computer_hardware/hard_drive(src)
network_card = new /obj/item/computer_hardware/network_card/advanced(src)
/obj/item/modular_computer/silicon/preset/install_default_programs()
hard_drive.store_file(new /datum/computer_file/program/filemanager())
hard_drive.store_file(new /datum/computer_file/program/ntnetdownload())

View File

@@ -1,23 +1,23 @@
/obj/item/modular_computer/tablet/preset/custom_loadout/cheap/install_default_hardware()
..()
processor_unit = new/obj/item/computer_hardware/processor_unit/small(src)
hard_drive = new/obj/item/computer_hardware/hard_drive/micro(src)
network_card = new/obj/item/computer_hardware/network_card(src)
battery_module = new/obj/item/computer_hardware/battery_module/nano(src)
processor_unit = new /obj/item/computer_hardware/processor_unit/small(src)
hard_drive = new /obj/item/computer_hardware/hard_drive/micro(src)
network_card = new /obj/item/computer_hardware/network_card(src)
battery_module = new /obj/item/computer_hardware/battery_module/nano(src)
battery_module.charge_to_full()
/obj/item/modular_computer/tablet/preset/custom_loadout/advanced/install_default_hardware()
..()
processor_unit = new/obj/item/computer_hardware/processor_unit/small(src)
hard_drive = new/obj/item/computer_hardware/hard_drive/small(src)
network_card = new/obj/item/computer_hardware/network_card(src)
nano_printer = new/obj/item/computer_hardware/nano_printer(src)
card_slot = new/obj/item/computer_hardware/card_slot(src)
battery_module = new/obj/item/computer_hardware/battery_module(src)
processor_unit = new /obj/item/computer_hardware/processor_unit/small(src)
hard_drive = new /obj/item/computer_hardware/hard_drive/small(src)
network_card = new /obj/item/computer_hardware/network_card(src)
nano_printer = new /obj/item/computer_hardware/nano_printer(src)
card_slot = new /obj/item/computer_hardware/card_slot(src)
battery_module = new /obj/item/computer_hardware/battery_module(src)
battery_module.charge_to_full()
// Cargo Delivery
/obj/item/modular_computer/tablet/preset/custom_loadout/advanced/cargo_delivery/
/obj/item/modular_computer/tablet/preset/custom_loadout/advanced/cargo_delivery
_app_preset_type = /datum/modular_computer_app_presets/cargo_delivery
enrolled = 1
enrolled = TRUE

View File

@@ -5,10 +5,10 @@
hard_drive = new/obj/item/computer_hardware/hard_drive(src)
network_card = new/obj/item/computer_hardware/network_card(src)
/obj/item/modular_computer/telescreen/preset/generic/
/obj/item/modular_computer/telescreen/preset/generic
_app_preset_type = /datum/modular_computer_app_presets/wall_generic
enrolled = 1
enrolled = TRUE
/obj/item/modular_computer/telescreen/preset/trashcompactor/
/obj/item/modular_computer/telescreen/preset/trashcompactor
_app_preset_type = /datum/modular_computer_app_presets/trashcompactor
enrolled = 1
enrolled = TRUE

View File

@@ -1,12 +1,12 @@
var/global/file_uid = 0
/datum/computer_file/
var/filename = "NewFile" // Placeholder. No spacebars
/datum/computer_file
var/filename = "NewFile" // Placehard_drive. No spacebars
var/filetype = "XXX" // File full names are [filename].[filetype] so like NewFile.XXX in this case
var/size = 1 // File size in GQ. Integers only!
var/obj/item/computer_hardware/hard_drive/holder // Holder that contains this file.
var/unsendable = 0 // Whether the file may be sent to someone via NTNet transfer or other means.
var/undeletable = 0 // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc.
var/obj/item/computer_hardware/hard_drive/hard_drive // Harddrive that contains this file.
var/unsendable = FALSE // Whether the file may be sent to someone via NTNet transfer or other means.
var/undeletable = FALSE // Whether the file may be deleted. Setting to 1 prevents deletion/renaming/etc.
var/password = "" // Placeholder for password protected files.
var/uid // UID of this file
@@ -16,18 +16,18 @@ var/global/file_uid = 0
file_uid++
/datum/computer_file/Destroy()
if(!holder)
if(!hard_drive)
return ..()
holder.remove_file(src)
// holder.holder is the computer that has drive installed. If we are Destroy()ing program that's currently running kill it.
if(holder.holder2 && holder.holder2.active_program == src)
holder.holder2.kill_program(1)
holder = null
hard_drive.remove_file(src)
// hard_drive.hard_drive is the computer that has drive installed. If we are Destroy()ing program that's currently running kill it.
if(hard_drive.parent_computer?.active_program == src)
hard_drive.parent_computer.kill_program(TRUE)
hard_drive = null
return ..()
// Returns independent copy of this file.
/datum/computer_file/proc/clone(var/rename = 0)
/datum/computer_file/proc/clone(var/rename = FALSE)
var/datum/computer_file/temp = new type
temp.unsendable = unsendable
temp.undeletable = undeletable
@@ -44,9 +44,9 @@ var/global/file_uid = 0
if(!password)
return TRUE
else
if (!input_password)
if(!input_password)
input_password = sanitize(input(user, "Please enter a password to access file '[filename]':"))
if (input_password == password)
if(input_password == password)
return TRUE
else
return FALSE

View File

@@ -4,7 +4,7 @@
var/stored_data = "" // Stored data in string format.
filetype = "DAT"
var/block_size = 1500
var/do_not_edit = 0 // Whether the user will be reminded that the file probably shouldn't be edited.
var/do_not_edit = FALSE // Whether the user will be reminded that the file probably shouldn't be edited.
/datum/computer_file/data/clone()
var/datum/computer_file/data/temp = ..()

View File

@@ -4,11 +4,11 @@
filetype = "XNML"
filename = "Unknown News Entry"
block_size = 2000 // Results in smaller files
do_not_edit = 1 // Editing the file breaks most formatting due to some HTML tags not being accepted as input from average user.
do_not_edit = TRUE // Editing the file breaks most formatting due to some HTML tags not being accepted as input from average user.
var/server_file_path // File path to HTML file that will be loaded on server start. Example: '/news_articles/space_magazine_1.html'. Use the /news_articles/ folder!
var/archived // Set to 1 for older stuff
/datum/computer_file/data/news_article/New(var/load_from_file = 0)
/datum/computer_file/data/news_article/New(var/load_from_file = FALSE)
..()
if(server_file_path && load_from_file)
stored_data = file2text(server_file_path)

View File

@@ -2,29 +2,29 @@
/datum/computer_file/program
filetype = "PRG"
filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET!
var/required_access_run = null // List of required accesses to run the program.
var/required_access_download = null // List of required accesses to download the program.
var/required_access_run // List of required accesses to run the program.
var/required_access_download // List of required accesses to download the program.
var/requires_access_to_run = PROGRAM_ACCESS_ONE // Whether the program checks for required_access when run. (1 = requires single access, 2 = requires single access from list, 3 = requires all access from list)
var/requires_access_to_download = PROGRAM_ACCESS_ONE // Whether the program checks for required_access when downloading. (1 = requires single access, 2 = requires single access from list, 3 = requires all access from list)
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
var/datum/nano_module/NM // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
var/nanomodule_path // Path to nanomodule, make sure to set this if implementing new program.
var/program_state = PROGRAM_STATE_KILLED // PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
var/obj/item/modular_computer/computer // Device that runs this program.
var/filedesc = "Unknown Program" // User-friendly name of this program.
var/extended_desc = "N/A" // Short description of this program's function.
var/program_icon_state = null // Program-specific screen icon state
var/requires_ntnet = 0 // Set to 1 for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes.
var/requires_ntnet_feature = 0 // Optional, if above is set to 1 checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION)
var/ntnet_status = 1 // NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc.
var/program_icon_state // Program-specific screen icon state
var/requires_ntnet = FALSE // Set to TRUE for program to require nonstop NTNet connection to run. If NTNet connection is lost program crashes.
var/requires_ntnet_feature = FALSE // Optional, if above is set to TRUE checks for specific function of NTNet (currently NTNET_SOFTWAREDOWNLOAD, NTNET_PEERTOPEER, NTNET_SYSTEMCONTROL and NTNET_COMMUNICATION)
var/ntnet_status = TRUE // NTNet status, updated every tick by computer running this program. Don't use this for checks if NTNet works, computers do that. Use this for calculations, etc.
var/usage_flags = PROGRAM_ALL // Bitflags (PROGRAM_CONSOLE, PROGRAM_LAPTOP, PROGRAM_TABLET combination) or PROGRAM_ALL
var/network_destination = null // Optional string that describes what NTNet server/system this program connects to. Used in default logging.
var/available_on_ntnet = 1 // Whether the program can be downloaded from NTNet. Set to 0 to disable.
var/available_on_syndinet = 0 // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
var/computer_emagged = 0 // Set to 1 if computer that's running us was emagged. Computer updates this every Process() tick
var/ui_header = null // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images!
var/network_destination // Optional string that describes what NTNet server/system this program connects to. Used in default logging.
var/available_on_ntnet = TRUE // Whether the program can be downloaded from NTNet. Set to 0 to disable.
var/available_on_syndinet = FALSE // Whether the program can be downloaded from SyndiNet (accessible via emagging the computer). Set to 1 to enable.
var/computer_emagged = FALSE // Set to TRUE if computer that's running us was emagged. Computer updates this every Process() tick
var/ui_header // Example: "something.gif" - a header image that will be rendered in computer's UI when this program is running at background. Images are taken from /nano/images/status_icons. Be careful not to use too large images!
var/color = "#FFFFFF" // The color of light the computer should emit when this program is open.
/datum/computer_file/program/New(var/obj/item/modular_computer/comp = null)
/datum/computer_file/program/New(var/obj/item/modular_computer/comp)
..()
if(comp && istype(comp))
computer = comp
@@ -57,29 +57,29 @@
/datum/computer_file/program/proc/generate_network_log(var/text)
if(computer)
return computer.add_log(text)
return 0
return FALSE
/datum/computer_file/program/proc/is_supported_by_hardware(var/hardware_flag = 0, var/loud = 0, var/mob/user = null)
/datum/computer_file/program/proc/is_supported_by_hardware(var/hardware_flag = 0, var/loud = FALSE, var/mob/user)
if(!(hardware_flag & usage_flags))
if(loud && computer && user)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.</span>")
return 0
return 1
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Hardware Error - Incompatible software\"."))
return FALSE
return TRUE
/datum/computer_file/program/proc/get_signal(var/specific_action = 0)
if(computer)
return computer.get_ntnet_status(specific_action)
return 0
return FALSE
// Called by Process() on device that runs us, once every tick.
/datum/computer_file/program/proc/process_tick()
return 1
return TRUE
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
// User has to wear their ID or have it inhand for ID Scan to work.
// Can also be called manually, with optional parameter being access_to_check to scan the user's ID
// Check type determines how the access should be checked PROGRAM_ACCESS_ONE, PROGRAM_ACCESS_LIST_ONE, PROGRAM_ACCESS_LIST_ALL
/datum/computer_file/program/proc/can_run(var/mob/user, var/loud = 0, var/access_to_check, var/check_type)
/datum/computer_file/program/proc/can_run(var/mob/user, var/loud = FALSE, var/access_to_check, var/check_type)
// Defaults to required_access_run
if(!access_to_check)
access_to_check = required_access_run
@@ -90,44 +90,43 @@
// No required_access, allow it.
if(!access_to_check || !requires_access_to_run)
return 1
return TRUE
if(!istype(user))
return 0
return FALSE
var/obj/item/card/id/I = user.GetIdCard()
if(!I)
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
return 0
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"RFID Error - Unable to scan ID.\"."))
return FALSE
if(check_type == PROGRAM_ACCESS_ONE) //Check for single access
if(access_to_check in I.access)
return 1
return TRUE
else if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
return FALSE
else if(check_type == PROGRAM_ACCESS_LIST_ONE)
for(var/check in access_to_check) //Loop through all the accesse's to check
if(check in I.access) //Success on first match
return 1
return TRUE
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
else if(check_type == PROGRAM_ACCESS_LIST_ALL)
for(var/check in access_to_check) //Loop through all the accesse's to check
if(!check in I.access) //Fail on first miss
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
return 0
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
return FALSE
else // Should never happen - So fail silently
return 0
return FALSE
// Check if the user can run program. Only humans can operate computer. Automatically called in run_program()
// User has to wear their ID or have it inhand for ID Scan to work.
// Can also be called manually, with optional parameter being access_to_check to scan the user's ID
// Check type determines how the access should be checked PROGRAM_ACCESS_ONE, PROGRAM_ACCESS_LIST_ONE, PROGRAM_ACCESS_LIST_ALL
/datum/computer_file/program/proc/can_download(var/mob/user, var/loud = 0, var/access_to_check, var/check_type)
/datum/computer_file/program/proc/can_download(var/mob/user, var/loud = FALSE, var/access_to_check, var/check_type)
// Defaults to required_access_run
if(!access_to_check)
access_to_check = required_access_download
@@ -138,36 +137,38 @@
// No required_access, allow it.
if(!access_to_check || !requires_access_to_download)
return 1
return TRUE
if(!istype(user))
return 0
return FALSE
var/obj/item/card/id/I = user.GetIdCard()
if(!I)
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
return 0
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"RFID Error - Unable to scan ID.\"."))
return FALSE
if(check_type == PROGRAM_ACCESS_ONE) //Check for single access
if(access_to_check in I.access)
return 1
return TRUE
else if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
return FALSE
else if(check_type == PROGRAM_ACCESS_LIST_ONE)
for(var/check in access_to_check) //Loop through all the accesse's to check
if(check in I.access) //Success on first match
return 1
return TRUE
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
return FALSE
else if(check_type == PROGRAM_ACCESS_LIST_ALL)
for(var/check in access_to_check) //Loop through all the accesse's to check
if(!check in I.access) //Fail on first miss
if(loud)
to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
return 0
to_chat(user, SPAN_WARNING("\The [computer] flashes, \"Access Denied.\"."))
return FALSE
else // Should never happen - So fail silently
return 0
return FALSE
// This attempts to retrieve header data for NanoUIs. If implementing completely new device of different type than existing ones
// always include the device here in this proc. This proc basically relays the request to whatever is running the program.
@@ -184,8 +185,8 @@
if(requires_ntnet && network_destination)
generate_network_log("Connection opened to [network_destination].")
program_state = PROGRAM_STATE_ACTIVE
return 1
return 0
return TRUE
return FALSE
// Use this proc to kill the program. Designed to be implemented by each program if it requires on-quit logic, such as the NTNRC client.
/datum/computer_file/program/proc/kill_program(var/forced = 0)
@@ -195,7 +196,7 @@
if(NM)
qdel(NM)
NM = null
return 1
return TRUE
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
// It returns 0 if it can't run or if NanoModule was used instead. I suggest using NanoModules where applicable.
@@ -206,8 +207,8 @@
return computer.ui_interact(user)
if(istype(NM))
NM.ui_interact(user, ui_key, null, force_open)
return 0
return 1
return FALSE
return TRUE
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
@@ -217,7 +218,7 @@
// ALWAYS INCLUDE PARENT CALL ..() OR DIE IN FIRE.
/datum/computer_file/program/Topic(href, href_list)
if(..())
return 1
return TRUE
if(computer)
return computer.Topic(href, href_list)

View File

@@ -7,12 +7,12 @@
// Called when the computer fails due to power loss. Override when program wants to specifically react to power loss.
/datum/computer_file/program/proc/event_powerfailure(var/background)
kill_program(1)
kill_program(TRUE)
// Called when the network connectivity fails. Computer does necessary checks and only calls this when requires_ntnet_feature and similar variables are not met.
/datum/computer_file/program/proc/event_networkfailure(var/background)
kill_program(1)
kill_program(TRUE)
if(background)
computer.visible_message("<span class='danger'>\The [computer]'s screen displays an \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error</span>")
computer.visible_message(FONT_SMALL(SPAN_WARNING("\The [computer]'s screen displays, \"Process [filename].[filetype] (PID [rand(100,999)]) terminated - Network Error\" error")), range = 2)
else
computer.visible_message("<span class='danger'>\The [computer]'s screen briefly freezes and then shows \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.</span>")
computer.visible_message(FONT_SMALL(SPAN_WARNING("\The [computer]'s screen briefly freezes and then shows, \"NETWORK ERROR - NTNet connection lost. Please retry. If problem persists contact your system administrator.\" error.")), range = 2)

View File

@@ -6,7 +6,7 @@
/datum/nano_module/program
available_to_ai = FALSE
var/datum/computer_file/program/program = null // Program-Based computer program that runs this nano module. Defaults to null.
var/datum/computer_file/program/program // Program-Based computer program that runs this nano module. Defaults to null.
/datum/nano_module/program/New(var/host, var/topic_manager, var/program)
..()

View File

@@ -4,14 +4,14 @@
program_icon_state = "hostile"
extended_desc = "This advanced script can perform denial of service attacks against NTNet quantum relays. The system administrator will probably notice this. Multiple devices can run this program together against the same relay for increased effect."
size = 20
requires_ntnet = 1
available_on_ntnet = 0
available_on_syndinet = 1
nanomodule_path = /datum/nano_module/program/computer_dos/
var/obj/machinery/ntnet_relay/target = null
requires_ntnet = TRUE
available_on_ntnet = FALSE
available_on_syndinet = TRUE
nanomodule_path = /datum/nano_module/program/computer_dos
var/obj/machinery/ntnet_relay/target
var/dos_speed = 0
var/error = ""
var/executed = 0
var/executed = FALSE
color = LIGHT_COLOR_RED
/datum/computer_file/program/ntnet_dos/process_tick()
@@ -34,7 +34,7 @@
if(target)
target.dos_sources.Remove(src)
target = null
executed = 0
executed = FALSE
..(forced)
@@ -53,7 +53,7 @@
if(PRG.error)
data["error"] = PRG.error
else if(PRG.target && PRG.executed)
data["target"] = 1
data["target"] = TRUE
data["speed"] = PRG.dos_speed
// This is mostly visual, generate some strings of 1s and 0s
@@ -61,9 +61,9 @@
// Combined with UI updates this adds quite nice effect to the UI
var/percentage = PRG.target.dos_overload * 100 / PRG.target.dos_capacity
var/list/strings[0]
for(var/j, j<10, j++)
for(var/j, j < 10, j++)
var/string = ""
for(var/i, i<20, i++)
for(var/i, i < 20, i++)
string = "[string][prob(percentage)]"
strings.Add(string)
data["dos_strings"] = strings
@@ -77,31 +77,31 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_dos.tmpl", "DoS Traffic Generator", 400, 250, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/computer_file/program/ntnet_dos/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["PRG_target_relay"])
for(var/obj/machinery/ntnet_relay/R in ntnet_global.relays)
if("[R.uid]" == href_list["PRG_target_relay"])
target = R
return 1
return TRUE
if(href_list["PRG_reset"])
if(target)
target.dos_sources.Remove(src)
target = null
executed = 0
executed = FALSE
error = ""
return 1
return TRUE
if(href_list["PRG_execute"])
if(target)
executed = 1
executed = TRUE
target.dos_sources.Add(src)
if(ntnet_global.intrusion_detection_enabled)
ntnet_global.add_log("IDS WARNING - Excess traffic flood targeting relay [target.uid] detected from device: [computer.network_card.get_network_tag()]")
ntnet_global.intrusion_detection_alarm = 1
return 1
ntnet_global.intrusion_detection_alarm = TRUE
return TRUE

View File

@@ -3,10 +3,10 @@
filedesc = "Camera Decryption Tool"
nanomodule_path = /datum/nano_module/camera_monitor/hacked
program_icon_state = "hostile"
extended_desc = "This very advanced piece of software uses adaptive programming and large database of cipherkeys to bypass most encryptions used on camera networks. Be warned that system administrator may notice this."
size = 73 // Very large, a price for bypassing ID checks completely.
available_on_ntnet = 0
available_on_syndinet = 1
extended_desc = "This very advanced piece of software uses adaptive programming and large database of cipherkeys to bypass most encryptions used on camera networks. Be warned that the system administrator may notice this."
size = 8
available_on_ntnet = FALSE
available_on_syndinet = TRUE
color = LIGHT_COLOR_RED
/datum/computer_file/program/camera_monitor/hacked/process_tick()
@@ -20,7 +20,7 @@
if(HNM.current_network && (HNM.current_network in current_map.station_networks) && prob(0.1))
if(ntnet_global.intrusion_detection_enabled)
ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]")
ntnet_global.intrusion_detection_alarm = 1
ntnet_global.intrusion_detection_alarm = TRUE
/datum/nano_module/camera_monitor/hacked
@@ -28,9 +28,9 @@
available_to_ai = FALSE
/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access)
return 1
return TRUE
// The hacked variant has access to all commonly used networks.
/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks)
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = TRUE)))
return networks

View File

@@ -4,14 +4,14 @@
program_icon_state = "hostile"
extended_desc = "This virus can destroy hard drive of system it is executed on. It may be obfuscated to look like another non-malicious program. Once armed, it will destroy the system upon next execution."
size = 13
requires_ntnet = 0
available_on_ntnet = 0
available_on_syndinet = 1
nanomodule_path = /datum/nano_module/program/revelation/
var/armed = 0
requires_ntnet = FALSE
available_on_ntnet = FALSE
available_on_syndinet = TRUE
nanomodule_path = /datum/nano_module/program/revelation
var/armed = FALSE
color = LIGHT_COLOR_RED
/datum/computer_file/program/revelation/run_program(var/mob/living/user)
/datum/computer_file/program/revelation/run_program(mob/living/user)
. = ..(user)
if(armed)
activate()
@@ -20,10 +20,10 @@
if(!computer)
return
computer.visible_message("<span class='notice'>\The [computer]'s screen brightly flashes and emits a loud electrical buzzing.</span>")
computer.enabled = 0
computer.visible_message(SPAN_NOTICE("\The [computer]'s screen brightly flashes and emits a loud electrical buzzing."))
computer.enabled = FALSE
computer.update_icon()
spark(computer.loc, 10, alldirs)
spark(get_turf(src), 10, alldirs)
if(computer.hard_drive)
qdel(computer.hard_drive)
@@ -36,7 +36,7 @@
/datum/computer_file/program/revelation/Topic(href, href_list)
if(..())
return 1
return TRUE
else if(href_list["PRG_arm"])
armed = !armed
else if(href_list["PRG_activate"])
@@ -47,7 +47,7 @@
if(!newname)
return
filedesc = newname
return 1
return TRUE
/datum/computer_file/program/revelation/clone()
var/datum/computer_file/program/revelation/temp = ..()
@@ -70,8 +70,7 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "revelation.tmpl", "Revelation Virus", 400, 250, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)

View File

@@ -3,18 +3,18 @@
filedesc = "Cargo Control"
extended_desc = "Application to Control Cargo Orders"
size = 12
requires_ntnet = 1
available_on_ntnet = 1
requires_ntnet = TRUE
available_on_ntnet = TRUE
required_access_download = access_hop
required_access_run = access_cargo
usage_flags = PROGRAM_CONSOLE | PROGRAM_TELESCREEN
nanomodule_path = /datum/nano_module/program/civilian/cargocontrol/
nanomodule_path = /datum/nano_module/program/civilian/cargocontrol
/datum/nano_module/program/civilian/cargocontrol/
/datum/nano_module/program/civilian/cargocontrol
name = "Cargo Control"
var/page = "overview_main" //overview_main - Main Menu, overview_submitted - Submitted Order Overview, overview_approved - Approved Order Overview, settings - Settings, details - order details, bounties - centcom bounties
var/last_user_name = "" //Name of the User that last used the computer
var/status_message = null //A status message that can be displayed
var/status_message //A status message that can be displayed
var/list/order_details = list() //Order Details for the order
var/list/shipment_details = list() //Shipment Details for a selected shipment
@@ -80,7 +80,7 @@
if(console)
data["have_printer"] = !!console.nano_printer
else
data["have_printer"] = 0
data["have_printer"] = FALSE
//Shuttle Stuff
var/datum/shuttle/autodock/ferry/supply/shuttle = SScargo.shuttle
@@ -102,19 +102,19 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "cargo_control.tmpl", name, 850, 600, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/nano_module/program/civilian/cargocontrol/Topic(href, href_list)
var/datum/shuttle/autodock/ferry/supply/shuttle = SScargo.shuttle
var/obj/item/modular_computer/console = host
if (!shuttle)
world.log << "## ERROR: Eek. The supply/shuttle datum is missing somehow."
log_debug("## ERROR: Eek. The supply/shuttle datum is missing somehow.")
return
if(..())
return 1
return TRUE
//Page switch between main, submitted, approved and settings
if(href_list["page"])
@@ -144,7 +144,7 @@
page = "bounties" //Page listing the currently available centcom bounties
else
page = "overview_main" //fall back to overview_main if a unknown page has been supplied
return 1
return TRUE
//Approve a order
if(href_list["order_approve"])
@@ -153,7 +153,7 @@
var/message = co.set_approved(last_user_name)
if(message)
status_message = message
return 1
return TRUE
//Reject a order
if(href_list["order_reject"])
@@ -162,38 +162,39 @@
var/message = co.set_rejected()
if(message)
status_message = message
return 1
return TRUE
//Send shuttle
if(href_list["shuttle_send"])
var/message = SScargo.shuttle_call(last_user_name)
if(message)
status_message = message
return 1
return TRUE
//Cancel shuttle
if(href_list["shuttle_cancel"])
var/message = SScargo.shuttle_cancel()
if(message)
status_message = message
return 1
return TRUE
//Force shuttle
if(href_list["shuttle_force"])
var/message = SScargo.shuttle_force()
if(message)
status_message = message
return 1
return TRUE
//Clear Status Message
if(href_list["clear_message"])
status_message = null
return 1
return TRUE
//Change the handling fee
if(href_list["handling_fee"])
var/handling_fee = sanitize(input(usr,"Handling Fee:","Set the new handling fee?",SScargo.get_handlingfee()) as null|text)
var/handling_fee = sanitize(input(usr, "Handling Fee:", "Set the new handling fee?", SScargo.get_handlingfee()) as null|text)
status_message = SScargo.set_handlingfee(text2num(handling_fee))
return 1
return TRUE
//Claim a bounty
if(href_list["claim_bounty"])
@@ -204,22 +205,23 @@
else
status_message = "Could not claim Bounty for [b.name]"
return
//Print functions
if(href_list["order_print"])
//Get the order
var/datum/cargo_order/co = SScargo.get_order_by_id(text2num(href_list["order_print"]))
if(co && console && console.nano_printer)
if(!console.nano_printer.print_text(co.get_report_invoice(),"Order Invoice #[co.order_id]"))
to_chat(usr,"<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
console.visible_message("<span class='notice'>\The [console] prints out paper.</span>")
console.visible_message(SPAN_NOTICE("\The [console] prints out paper."))
if(href_list["shipment_print"])
var/datum/cargo_shipment/cs = SScargo.get_shipment_by_id(text2num(href_list["shipment_print"]))
if(cs && cs.completed && console && console.nano_printer)
if(cs?.completed && console?.nano_printer)
var/obj/item/paper/P = console.nano_printer.print_text(cs.get_invoice(),"Shipment Invoice #[cs.shipment_num]")
if(!P)
to_chat(usr,"<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
//stamp the paper
@@ -230,7 +232,7 @@
P.stamped += /obj/item/stamp
P.add_overlay(stampoverlay)
P.stamps += "<HR><i>This paper has been stamped by the Shipping Server.</i>"
console.visible_message("<span class='notice'>\The [console] prints out paper.</span>")
console.visible_message(SPAN_NOTICE("\The [console] prints out paper."))
if(href_list["bounty_print"])
if(console && console.nano_printer)
var/text = "<h2>Nanotrasen Cargo Bounties</h2></br>"
@@ -241,17 +243,17 @@
text += "<ul><li>Reward: [B.reward_string()]</li>"
text += "<li>Completed: [B.completion_string()]</li></ul>"
if(!console.nano_printer.print_text(text,"paper - Bounties"))
to_chat(usr,"<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
console.visible_message("<span class='notice'>\The [console] prints out paper.</span>")
console.visible_message(SPAN_NOTICE("\The [console] prints out paper."))
/datum/nano_module/program/civilian/cargocontrol/proc/post_signal(var/command) //Old code right here - Used to send a refresh command to the status screens incargo
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
if(!frequency) return
if(!frequency)
return
var/datum/signal/status_signal = new
status_signal.source = src

View File

@@ -1,24 +1,24 @@
/datum/computer_file/program/civilian/cargodelivery
filename = "cargodelivery"
filedesc = "Cargo Delivery"
extended_desc = "Application to Control Delivery and Payment of Cargo orders"
extended_desc = "Application to Control Delivery and Payment of Cargo orders."
size = 12
requires_ntnet = 1
available_on_ntnet = 1
requires_ntnet = TRUE
available_on_ntnet = TRUE
required_access_download = access_hop
usage_flags = PROGRAM_ALL
nanomodule_path = /datum/nano_module/program/civilian/cargodelivery/
nanomodule_path = /datum/nano_module/program/civilian/cargodelivery
/datum/nano_module/program/civilian/cargodelivery/
/datum/nano_module/program/civilian/cargodelivery
name = "Cargo Delivery"
var/page = "overview_main" //overview_main - Main Menu, order_overview - Overview page for a specific order, order_payment - Payment page for a specific order
var/last_user_name = "" //Name of the User that last used the computer
var/status_message = null //A status message that can be displayed
var/status_message //A status message that can be displayed
var/list/order_details = list() //Order Details for the order
var/datum/cargo_order/co
var/mod_mode = 1 //If it can be used to pay for orders
var/mod_mode = TRUE //If it can be used to pay for orders
/datum/nano_module/program/civilian/cargodelivery/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/datum/nano_module/program/civilian/cargodelivery/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if(program && program.computer)
@@ -26,13 +26,12 @@
data["have_printer"] = !!program.computer.nano_printer
data["authenticated"] = program.can_run(user)
if(!program.computer.card_slot || !program.computer.network_card)
mod_mode = 0 //We can't pay for orders when there is no card reader and no network card
mod_mode = FALSE //We can't pay for orders when there is no card reader or no network card
if(program && program.computer && program.computer.card_slot)
var/obj/item/card/id/id_card = program.computer.card_slot.stored_card
data["has_id"] = !!id_card
data["id_account_number"] = id_card ? id_card.associated_account_number : null
//data["id_rank"] = id_card && id_card.assignment ? id_card.assignment : "Unassigned"
data["id_owner"] = id_card && id_card.registered_name ? id_card.registered_name : "-----"
data["id_name"] = id_card ? id_card.name : "-----"
last_user_name = data["id_owner"]
@@ -52,15 +51,15 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "cargo_delivery.tmpl", name, 500, 600, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/nano_module/program/civilian/cargodelivery/Topic(href, href_list)
if(..())
return 1
return TRUE
//Check if we want to deliver or pay
@@ -73,13 +72,13 @@
//Check if its already delivered
if(order_details["status"] == "delivered" && !order_details["needs_payment"])
status_message = "Unable to Deliver - Order has already been delivered and paid for."
return 1
return TRUE
if(program && program.computer && program.computer.card_slot && program.computer.network_card)
var/obj/item/card/id/id_card = program.computer.card_slot.stored_card
if(!id_card || !id_card.registered_name)
if(!id_card?.registered_name)
status_message = "Card Error: Invalid ID Card in Card Reader"
return 1
return TRUE
//Check if a payment is required
if(order_details["needs_payment"])
@@ -91,9 +90,9 @@
if(status)
status_message = status
return 1
return TRUE
playsound(program.computer, 'sound/machines/chime.ogg', 50, 1)
playsound(program.computer, 'sound/machines/chime.ogg', 50, TRUE)
//Check if we have delivered it aswell or only paid
if(order_details["status"] == "shipped")
@@ -110,7 +109,7 @@
order_details = co.get_list()
else
status_message = "Unable to process - Network Card or Cardreader Missing"
return 1
return TRUE
//But only cargo can switch between the pages
@@ -119,7 +118,7 @@
return
var/obj/item/card/id/I = user.GetIdCard()
if(!istype(I) || !I.registered_name || !(access_cargo in I.access) || issilicon(user))
to_chat(user, "Authentication error: Unable to locate ID with appropriate access to allow this operation.")
to_chat(user, SPAN_WARNING("Authentication error: Unable to locate ID with appropriate access to allow this operation."))
return
if(href_list["page"])
@@ -138,4 +137,4 @@
order_details = co.get_list()
else
page = "overview_main" //fall back to overview_main if a unknown page has been supplied
return 1
return TRUE

View File

@@ -1,25 +1,25 @@
/datum/computer_file/program/civilian/cargoorder
filename = "cargoorder"
filedesc = "Cargo Order"
extended_desc = "Application to Order Items from Cargo"
extended_desc = "Application to Order Items from Cargo."
size = 10
requires_ntnet = 1
available_on_ntnet = 1
requires_ntnet = TRUE
available_on_ntnet = TRUE
usage_flags = PROGRAM_LAPTOP | PROGRAM_TELESCREEN | PROGRAM_CONSOLE
nanomodule_path = /datum/nano_module/program/civilian/cargoorder/
nanomodule_path = /datum/nano_module/program/civilian/cargoorder
/datum/nano_module/program/civilian/cargoorder/
/datum/nano_module/program/civilian/cargoorder
name = "Cargo Order"
var/page = "main" //main - Main Menu, order - Order Page, item_details - Item Details Page, tracking - Tracking Page
var/selected_category = "" // Category that is currently selected
var/selected_item = "" // Path of the currently selected item
var/datum/cargo_order/co
var/last_user_name = "" //Name of the user that used the program
var/status_message = null //Status Message to be displayed to the user
var/status_message //Status Message to be displayed to the user
var/user_tracking_id = 0 //Tracking id of the user
var/user_tracking_code = 0 //Tracking Code of the user
/datum/nano_module/program/civilian/cargoorder/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/datum/nano_module/program/civilian/cargoorder/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE, var/datum/topic_state/state = default_state)
//Check if a cargo order exists. If not create a new one
if(!co)
var/datum/cargo_order/crord = new
@@ -51,12 +51,6 @@
//Pass a list of items in the selected category
data["category_items"] = SScargo.get_items_for_category(selected_category)
//Pass Data for Item Details Page
//else if(page == "item_details")
// var/datum/cargo_item/ci = SScargo.cargo_items[selected_item]
// if(ci)
// data["item_details"] = ci.get_list()
else if (page == "tracking")
data["tracking_id"] = user_tracking_id
data["tracking_code"] = user_tracking_code
@@ -89,28 +83,28 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "cargo_order.tmpl", name, 500, 600, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/nano_module/program/civilian/cargoorder/Topic(href, href_list)
if(..())
return 1
return TRUE
//Send the order to cargo
if(href_list["submit_order"])
if(co.items.len == 0)
return 1 //Only submit the order if there are items in it
if(!co.items.len)
return TRUE //Only submit the order if there are items in it
if(last_user_name == "Unknown")
status_message = "Unable to submit order. ID could not be located"
return 1
status_message = "Unable to submit order. ID could not be located."
return TRUE
var/reason = sanitize(input(usr,"Reason:","Why do you require this item?","") as null|text)
var/reason = sanitize(input(usr, "Reason:", "Why do you require this item?", "") as null|text)
if(!reason)
status_message = "Unable to submit order. No reason supplied."
return 1
return TRUE
co.ordered_by = last_user_name
co.reason = reason
@@ -118,7 +112,7 @@
status_message = "Order submitted successfully. Order ID: [co.order_id] Tracking code: [co.get_tracking_code()]"
//TODO: Print a list with the order data
co = null
return 1
return TRUE
//Add item to the order list
if(href_list["add_item"])
@@ -141,44 +135,44 @@
//Reset page to main page - TODO: Maybe add a way to disable jumping back to the main page - Commented out for now
//page = "main"
//selected_item = ""
return 1
return TRUE
//Remove item from the order list
if(href_list["remove_item"])
status_message = co.remove_item(text2num(href_list["remove_item"]))
return 1
return TRUE
//Clear the items in the order list
if(href_list["clear_order"])
status_message = "Order Cleared"
qdel(co)
co = new
return 1
return TRUE
//Change the selected page
if(href_list["item_details"])
page = "item_details"
selected_item = href_list["item_details"]
return 1
return TRUE
if(href_list["page"])
page = href_list["page"]
return 1
return TRUE
//Tracking Stuff
if(href_list["trackingid"])
var/trackingid = text2num(sanitize(input(usr,"Order ID:","ID of the Order that you want to track","") as null|text))
var/trackingid = text2num(sanitize(input(usr, "Order ID:", "ID of the Order that you want to track", "") as null|text))
if(trackingid)
user_tracking_id = trackingid
return 1
return TRUE
if(href_list["trackingcode"])
var/trackingcode = text2num(sanitize(input(usr,"Tracking Code:","Tracking Code of the Order that you want to track","") as null|text))
var/trackingcode = text2num(sanitize(input(usr, "Tracking Code:", "Tracking Code of the Order that you want to track", "") as null|text))
if(trackingcode)
user_tracking_code = trackingcode
return 1
return TRUE
//Change the displayed item category
if(href_list["select_category"])
selected_category = href_list["select_category"]
return 1
return TRUE
if(href_list["clear_message"])
status_message = null
return 1
return TRUE

View File

@@ -3,17 +3,17 @@
filedesc = "Crusher Control"
extended_desc = "Application to Control the Crusher"
size = 8
requires_ntnet = 0
available_on_ntnet = 0
requires_ntnet = FALSE
available_on_ntnet = FALSE
required_access_download = access_hop
required_access_run = access_janitor
usage_flags = PROGRAM_TELESCREEN
nanomodule_path = /datum/nano_module/program/crushercontrol/
nanomodule_path = /datum/nano_module/program/crushercontrol
/datum/nano_module/program/crushercontrol/
/datum/nano_module/program/crushercontrol
name = "Crusher Control"
var/message = "" // Message to return to the user
var/extending = 0 //If atleast one of the pistons is extending
var/extending = FALSE //If atleast one of the pistons is extending
var/list/pistons = list() //List of pistons linked to the program
var/list/airlocks = list() //List of airlocks linked to the program
var/list/status_airlocks = list() //Status of the airlocks
@@ -23,7 +23,7 @@
var/list/data = host.initial_data()
status_pistons = list()
extending = 0
extending = FALSE
//Cycle through the pistons and get their status
var/i = 1
@@ -32,7 +32,7 @@
var/is_blocked = pstn.is_blocked()
var/action = pstn.get_action()
if(action == "extend")
extending = 1
extending = TRUE
status_pistons.Add(list(list(
"progress"=num_progress,
"blocked"=is_blocked,
@@ -50,23 +50,23 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "crushercontrol.tmpl", name, 500, 350, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/nano_module/program/crushercontrol/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["initialize"])
pistons = list()
for(var/obj/machinery/crusher_base/pstn in orange(10,src.host))
for(var/obj/machinery/crusher_base/pstn in orange(10, src.host))
pistons += pstn
airlocks = list()
for(var/obj/machinery/door/airlock/arlk in orange(10,src.host))
if( arlk.id_tag != "crusher")
for(var/obj/machinery/door/airlock/arlk in orange(10, src.host))
if(arlk.id_tag != "crusher")
continue
airlocks += arlk
@@ -96,7 +96,7 @@
/datum/nano_module/program/crushercontrol/proc/airlock_open()
for(var/thing in airlocks)
var/obj/machinery/door/airlock/arlk = thing
if (!arlk.cur_command)
if(!arlk.cur_command)
// Not using do_command so that the command queuer works.
arlk.cur_command = "secure_open"
arlk.execute_current_command()
@@ -104,7 +104,7 @@
/datum/nano_module/program/crushercontrol/proc/airlock_close()
for(var/thing in airlocks)
var/obj/machinery/door/airlock/arlk = thing
if (!arlk.cur_command)
if(!arlk.cur_command)
arlk.cur_command = "secure_close"
arlk.execute_current_command()

View File

@@ -7,15 +7,15 @@
required_access_run = access_change_ids
required_access_download = access_change_ids
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
requires_ntnet = 0
requires_ntnet = FALSE
size = 8
color = LIGHT_COLOR_BLUE
/datum/nano_module/program/card_mod
name = "ID card modification program"
var/mod_mode = 1
var/is_centcom = 0
var/show_assignments = 0
var/mod_mode = TRUE
var/is_centcom = FALSE
var/show_assignments = FALSE
/datum/nano_module/program/card_mod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
@@ -24,12 +24,12 @@
data["station_name"] = station_name()
data["manifest"] = SSrecords.get_manifest()
data["assignments"] = show_assignments
if(program && program.computer)
if(program?.computer)
data["have_id_slot"] = !!program.computer.card_slot
data["have_printer"] = !!program.computer.nano_printer
data["authenticated"] = program.can_run(user)
if(!program.computer.card_slot)
mod_mode = 0 //We can't modify IDs when there is no card reader
mod_mode = FALSE //We can't modify IDs when there is no card reader
else
data["have_id_slot"] = 0
data["have_printer"] = 0
@@ -86,7 +86,7 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "identification_computer.tmpl", name, 600, 700, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
@@ -107,7 +107,7 @@
/datum/computer_file/program/card_mod/Topic(href, href_list)
if(..())
return 1
return TRUE
var/mob/user = usr
var/obj/item/card/id/user_id_card = user.GetIdCard()
@@ -116,16 +116,16 @@
switch(href_list["action"])
if("switchm")
if(href_list["target"] == "mod")
module.mod_mode = 1
module.mod_mode = TRUE
else if (href_list["target"] == "manifest")
module.mod_mode = 0
module.mod_mode = FALSE
if("togglea")
if(module.show_assignments)
module.show_assignments = 0
module.show_assignments = FALSE
else
module.show_assignments = 1
module.show_assignments = TRUE
if("print")
if(computer && computer.nano_printer) //This option should never be called if there is no printer
if(computer?.nano_printer) //This option should never be called if there is no printer
if(module.mod_mode)
if(can_run(user, 1))
var/contents = {"<h4>Access Report</h4>
@@ -144,20 +144,20 @@
contents += " [get_access_desc(A)]"
if(!computer.nano_printer.print_text(contents,"access report"))
to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
computer.visible_message(SPAN_NOTICE("\The [computer] prints out paper."))
else
var/contents = {"<h4>Crew Manifest</h4>
<br>
[SSrecords.get_manifest(1)]
"}
if(!computer.nano_printer.print_text(contents,text("crew manifest ([])", worldtime2text())))
to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING(">Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
computer.visible_message(SPAN_NOTICE("\The [computer] prints out paper."))
if("eject")
if(computer && computer.card_slot)
if(id_card)
@@ -210,7 +210,7 @@
jobdatum = J
break
if(!jobdatum)
to_chat(usr, "<span class='warning'>No log exists for this job: [t1]</span>")
to_chat(usr, SPAN_WARNING("No log exists for this job: [t1]"))
return
access = jobdatum.get_access(t1)
@@ -233,7 +233,7 @@
id_card.name = text("[id_card.registered_name]'s ID Card ([id_card.assignment])")
SSnanoui.update_uis(NM)
return 1
return TRUE
/datum/computer_file/program/card_mod/proc/remove_nt_access(var/obj/item/card/id/id_card)
id_card.access -= get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM)

View File

@@ -12,16 +12,16 @@
extended_desc = "Used to command and control the station. Can relay long-range communications."
required_access_run = access_heads
required_access_download = access_heads
requires_ntnet = 1
requires_ntnet = TRUE
size = 12
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP
network_destination = "station long-range communication array"
var/datum/comm_message_listener/message_core = new
var/intercept = 0
var/can_call_shuttle = 0 //If calling the shuttle should be available from this console
var/intercept = FALSE
var/can_call_shuttle = FALSE //If calling the shuttle should be available from this console
color = LIGHT_COLOR_BLUE
/datum/computer_file/program/comm/New(intercept_printing = 0, shuttle_call = 0)
/datum/computer_file/program/comm/New(intercept_printing = FALSE, shuttle_call = FALSE)
. = ..()
intercept = intercept_printing
can_call_shuttle = shuttle_call
@@ -39,16 +39,16 @@
var/msg_line1 = ""
var/msg_line2 = ""
var/centcomm_message_cooldown = 0
var/announcment_cooldown = 0
var/announcement_cooldown = 0
var/datum/announcement/priority/crew_announcement = new
var/current_viewing_message_id = 0
var/current_viewing_message = null
/datum/nano_module/program/comm/New()
..()
crew_announcement.newscast = 1
crew_announcement.newscast = TRUE
/datum/nano_module/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/datum/nano_module/program/comm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if(program)
@@ -60,20 +60,20 @@
if(program.computer)
data["have_printer"] = !!program.computer.nano_printer
else
data["have_printer"] = 0
data["have_printer"] = FALSE
else
data["emagged"] = 0
data["net_comms"] = 1
data["net_syscont"] = 1
data["have_printer"] = 0
data["message_printing_intercepts"] = 0
data["emagged"] = FALSE
data["net_comms"] = TRUE
data["net_syscont"] = TRUE
data["have_printer"] = FALSE
data["message_printing_intercepts"] = FALSE
data["can_call_shuttle"] = can_call_shuttle()
data["message_line1"] = msg_line1
data["message_line2"] = msg_line2
data["state"] = current_status
data["isAI"] = issilicon(usr)
data["authenticated"] = is_autenthicated(user)
data["authenticated"] = is_authenticated(user)
data["boss_short"] = current_map.boss_short
data["current_security_level"] = security_level
data["current_security_level_title"] = num2seclevel(security_level)
@@ -92,25 +92,25 @@
data["message_current"] = current_viewing_message
if(emergency_shuttle.location())
data["have_shuttle"] = 1
data["have_shuttle"] = TRUE
if(emergency_shuttle.online())
data["have_shuttle_called"] = 1
data["have_shuttle_called"] = TRUE
else
data["have_shuttle_called"] = 0
data["have_shuttle_called"] = FALSE
else
data["have_shuttle"] = 0
data["have_shuttle"] = FALSE
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "communication.tmpl", name, 550, 420, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
/datum/nano_module/program/comm/proc/is_autenthicated(var/mob/user)
/datum/nano_module/program/comm/proc/is_authenticated(var/mob/user)
if(program)
return program.can_run(user)
return 1
return TRUE
/datum/nano_module/program/comm/proc/obtain_message_listener()
if(program)
@@ -123,11 +123,17 @@
var/datum/computer_file/program/comm/P = program
return P.can_call_shuttle
else
return 0
return FALSE
/datum/nano_module/program/comm/proc/set_announcement_cooldown(var/cooldown)
announcement_cooldown = cooldown
/datum/nano_module/program/comm/proc/set_centcomm_message_cooldown(var/cooldown)
centcomm_message_cooldown = cooldown
/datum/nano_module/program/comm/Topic(href, href_list)
if(..())
return 1
return TRUE
var/mob/user = usr
var/ntn_comm = !!program.get_signal(NTNET_COMMUNICATION)
var/ntn_cont = !!program.get_signal(NTNET_SYSTEMCONTROL)
@@ -136,7 +142,7 @@
if("sw_menu")
current_status = text2num(href_list["target"])
if("emergencymaint")
if(is_autenthicated(user) && !issilicon(user))
if(is_authenticated(user) && !issilicon(user))
if(maint_all_access)
revoke_maint_all_access()
feedback_inc("alert_comms_maintRevoke",1)
@@ -146,13 +152,13 @@
feedback_inc("alert_comms_maintGrant",1)
log_and_message_admins("enabled emergency maintenance access")
if("announce")
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(is_authenticated(user) && !issilicon(usr) && ntn_comm)
if(user)
var/obj/item/card/id/id_card = user.GetIdCard()
crew_announcement.announcer = GetNameAndAssignmentFromId(id_card)
else
crew_announcement.announcer = "Unknown"
if(announcment_cooldown)
if(announcement_cooldown)
to_chat(usr, "Please allow at least one minute to pass between announcements")
SSnanoui.update_uis(src)
return
@@ -161,15 +167,14 @@
SSnanoui.update_uis(src)
return
crew_announcement.Announce(input)
announcment_cooldown = 1
spawn(600)//One minute cooldown
announcment_cooldown = 0
set_announcement_cooldown(TRUE)
addtimer(CALLBACK(src, .proc/set_announcement_cooldown, FALSE), 600) //One minute cooldown
if("message")
if(href_list["target"] == "emagged")
if(program)
if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm)
if(is_authenticated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown)
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
to_chat(usr, SPAN_WARNING("Arrays recycling. Please stand by."))
SSnanoui.update_uis(src)
return
var/input = sanitize(input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING CORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text)
@@ -177,19 +182,18 @@
SSnanoui.update_uis(src)
return
Syndicate_announce(input, usr)
to_chat(usr, "<span class='notice'>Message transmitted.</span>")
log_say("[key_name(usr)] has made an illegal announcement: [input]",ckey=key_name(usr))
centcomm_message_cooldown = 1
spawn(300)//30 second cooldown
centcomm_message_cooldown = 0
to_chat(usr, SPAN_NOTICE("Message successfully transmitted."))
log_say("[key_name(usr)] has sent a message to the syndicate: [input]", ckey = key_name(usr))
centcomm_message_cooldown = TRUE
addtimer(CALLBACK(src, .proc/set_centcomm_message_cooldown, FALSE), 300) // thirty second cooldown
else if(href_list["target"] == "regular")
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(is_authenticated(user) && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown)
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
to_chat(usr, SPAN_WARNING("Arrays recycling. Please stand by."))
SSnanoui.update_uis(src)
return
if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs.
to_chat(usr, "<span class='warning'>No Emergency Bluespace Relay detected. Unable to transmit message.</span>")
to_chat(usr, SPAN_WARNING("No Emergency Bluespace Relay detected. Unable to transmit message."))
SSnanoui.update_uis(src)
return
var/input = sanitize(input("Please choose a message to transmit to [current_map.boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "") as null|text)
@@ -197,13 +201,12 @@
SSnanoui.update_uis(src)
return
Centcomm_announce(input, usr)
to_chat(usr, "<span class='notice'>Message transmitted.</span>")
log_say("[key_name(usr)] has made an IA [current_map.boss_short] announcement: [input]",ckey=key_name(usr))
centcomm_message_cooldown = 1
spawn(300) //30 second cooldown
centcomm_message_cooldown = 0
to_chat(usr, SPAN_NOTICE("Message successfully transmitted."))
log_say("[key_name(usr)] has sent a message to [current_map.boss_short]: [input]", ckey = key_name(usr))
centcomm_message_cooldown = TRUE
addtimer(CALLBACK(src, .proc/set_centcomm_message_cooldown, FALSE), 300) // thirty second cooldown
if("shuttle")
if(is_autenthicated(user) && ntn_cont && can_call_shuttle())
if(is_authenticated(user) && ntn_cont && can_call_shuttle())
if(href_list["target"] == "call")
var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
@@ -213,7 +216,7 @@
if(confirm == "Yes" && can_still_topic())
cancel_call_proc(usr)
if("setstatus")
if(is_autenthicated(user) && ntn_cont)
if(is_authenticated(user) && ntn_cont)
switch(href_list["target"])
if("line1")
var/linput = reject_bad_text(sanitize(input("Line 1", "Enter Message Text", msg_line1) as text|null, 40), 40)
@@ -231,17 +234,20 @@
post_display_status(href_list["target"])
if("setalert")
if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm)
if(is_authenticated(user) && !issilicon(usr) && ntn_cont && ntn_comm)
var/current_level = text2num(href_list["target"])
var/confirm = alert("Are you sure you want to change alert level to [num2seclevel(current_level)]?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic())
var/old_level = security_level
if(!current_level) current_level = SEC_LEVEL_GREEN
if(current_level < SEC_LEVEL_GREEN) current_level = SEC_LEVEL_GREEN
if(current_level > SEC_LEVEL_BLUE) current_level = SEC_LEVEL_BLUE
if(!current_level)
current_level = SEC_LEVEL_GREEN
if(current_level < SEC_LEVEL_GREEN)
current_level = SEC_LEVEL_GREEN
if(current_level > SEC_LEVEL_BLUE)
current_level = SEC_LEVEL_BLUE
set_security_level(current_level)
if(security_level != old_level)
log_game("[key_name(usr)] has changed the security level to [get_security_level()].",ckey=key_name(usr))
log_game("[key_name(usr)] has changed the security level to [get_security_level()].", ckey = key_name(usr))
message_admins("[key_name_admin(usr)] has changed the security level to [get_security_level()].")
switch(security_level)
if(SEC_LEVEL_GREEN)
@@ -251,29 +257,29 @@
if(SEC_LEVEL_YELLOW)
feedback_inc("alert_comms_yellow",1)
else
to_chat(usr, "You press button, but red light flashes and nothing happens.") //This should never happen)
to_chat(usr, SPAN_WARNING("You press the button, but a red light flashes and nothing happens.")) //This should never happen
current_status = STATE_DEFAULT
if("viewmessage")
if(is_autenthicated(user) && ntn_comm)
if(is_authenticated(user) && ntn_comm)
current_viewing_message_id = text2num(href_list["target"])
for(var/list/m in l.messages)
if(m["id"] == current_viewing_message_id)
current_viewing_message = m
current_status = STATE_VIEWMESSAGE
if("delmessage")
if(is_autenthicated(user) && ntn_comm && l != global_message_listener)
if(is_authenticated(user) && ntn_comm && l != global_message_listener)
l.Remove(current_viewing_message)
current_status = STATE_MESSAGELIST
if("printmessage")
if(is_autenthicated(user) && ntn_comm)
if(is_authenticated(user) && ntn_comm)
if(program && program.computer && program.computer.nano_printer)
if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"]))
to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
else
program.computer.visible_message("<span class='notice'>\The [program.computer] prints out paper.</span>")
program.computer.visible_message(SPAN_NOTICE("\The [program.computer] prints out paper."))
if("toggleintercept")
if(is_autenthicated(user) && ntn_comm)
if(program && program.computer && program.computer.nano_printer)
if(is_authenticated(user) && ntn_comm)
if(program?.computer?.nano_printer)
var/datum/computer_file/program/comm/P = program
P.intercept = !P.intercept
@@ -306,9 +312,9 @@ var/last_message_id = 0
l.Add(message)
for (var/obj/item/modular_computer/computer in get_listeners_by_type(LISTENER_MODULAR_COMPUTER, /obj/item/modular_computer))
if(computer && computer.working && !!computer.nano_printer)
if(computer?.working && !!computer.nano_printer)
var/datum/computer_file/program/comm/C = locate(/datum/computer_file/program/comm) in computer.hard_drive.stored_files
if(C && C.intercept)
if(C?.intercept)
computer.nano_printer.print_text(message_text, message_title, "#deebff")
@@ -329,14 +335,14 @@ var/last_message_id = 0
Command action procs
*/
/proc/post_display_status(var/command, var/data1, var/data2)
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
if(!frequency) return
if(!frequency)
return
var/datum/signal/status_signal = new
status_signal.transmission_method = 1
status_signal.transmission_method = TRUE
status_signal.data["command"] = command
switch(command)
@@ -351,94 +357,94 @@ Command action procs
//Returns 1 if recalled 0 if not
/proc/cancel_call_proc(var/mob/user)
if (!(ROUND_IS_STARTED) || !emergency_shuttle.can_recall())
return 0
if(!(ROUND_IS_STARTED) || !emergency_shuttle.can_recall())
return FALSE
if((SSticker.mode.name == "blob")||(SSticker.mode.name == "Meteor"))
return 0
return FALSE
if(!emergency_shuttle.going_to_centcom()) //check that shuttle isn't already heading to centcomm
emergency_shuttle.recall()
log_game("[key_name(user)] has recalled the shuttle.",key_name(user))
log_game("[key_name(user)] has recalled the shuttle.", key_name(user))
message_admins("[key_name_admin(user)] has recalled the shuttle.", 1)
return 1
return 0
return TRUE
return FALSE
/proc/is_relay_online()
for(var/obj/machinery/bluespacerelay/M in SSmachinery.all_machines)
if(M.stat == 0)
return 1
return 0
return TRUE
return FALSE
//Returns 1 if called 0 if not
/proc/call_shuttle_proc(var/mob/user)
if ((!(ROUND_IS_STARTED) || !emergency_shuttle.location()))
return 0
if((!(ROUND_IS_STARTED) || !emergency_shuttle.location()))
return FALSE
if(!universe.OnShuttleCall(usr))
to_chat(user, "<span class='notice'>Cannot establish a bluespace connection.</span>")
return 0
to_chat(user, SPAN_WARNING("Cannot establish a bluespace connection."))
return FALSE
if(emergency_shuttle.deny_shuttle)
to_chat(user, "The emergency shuttle may not be sent at this time. Please try again later.")
return 0
to_chat(user, SPAN_WARNING("The emergency shuttle cannot be sent at this time. Please try again later."))
return FALSE
if(world.time < 6000) // Ten minute grace period to let the game get going without lolmetagaming. -- TLE
to_chat(user, "The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minute\s before trying again.")
to_chat(user, SPAN_WARNING("The emergency shuttle is refueling. Please wait another [round((6000-world.time)/600)] minute\s before trying again."))
return 0
if(emergency_shuttle.going_to_centcom())
to_chat(user, "The emergency shuttle may not be called while returning to [current_map.boss_short].")
to_chat(user, SPAN_WARNING("The emergency shuttle cannot be called while returning to [current_map.boss_short]."))
return 0
if(emergency_shuttle.online())
to_chat(user, "The emergency shuttle is already on its way.")
to_chat(user, SPAN_WARNING("The emergency shuttle is already on its way."))
return 0
if(SSticker.mode.name == "blob")
to_chat(user, "Under directive 7-10, [station_name()] is quarantined until further notice.")
return 0
to_chat(user, SPAN_WARNING("Under directive 7-10, [station_name()] is quarantined until further notice."))
return FALSE
emergency_shuttle.call_evac()
log_game("[key_name(user)] has called the shuttle.",ckey=key_name(user))
message_admins("[key_name_admin(user)] has called the shuttle.", 1)
return 1
return TRUE
/proc/init_shift_change(var/mob/user, var/force = 0)
/proc/init_shift_change(var/mob/user, var/force = FALSE)
if ((!(ROUND_IS_STARTED) || !emergency_shuttle.location()))
return
if(emergency_shuttle.going_to_centcom())
to_chat(user, "The shuttle may not be called while returning to [current_map.boss_short].")
to_chat(user, SPAN_WARNING("The shuttle cannot be called while returning to [current_map.boss_short]."))
return
if(emergency_shuttle.online())
to_chat(user, "The shuttle is already on its way.")
to_chat(user, SPAN_WARNING("The shuttle is already on its way."))
return
// if force is 0, some things may stop the shuttle call
if(!force)
if(emergency_shuttle.deny_shuttle)
to_chat(user, "[current_map.boss_short] does not currently have a shuttle available in your sector. Please try again later.")
to_chat(user, SPAN_WARNING("[current_map.boss_short] does not currently have a shuttle available in your sector. Please try again later."))
return
if(world.time < 54000) // 30 minute grace period to let the game get going
to_chat(user, "The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again.")
to_chat(user, SPAN_WARNING("The shuttle is refueling. Please wait another [round((54000-world.time)/60)] minutes before trying again."))
return
if(SSticker.mode.auto_recall_shuttle)
//New version pretends to call the shuttle but cause the shuttle to return after a random duration.
emergency_shuttle.auto_recall = 1
emergency_shuttle.auto_recall = TRUE
if(SSticker.mode.name == "blob" || SSticker.mode.name == "epidemic")
to_chat(user, "Under directive 7-10, [station_name()] is quarantined until further notice.")
to_chat(user, SPAN_WARNING("Under directive 7-10, [station_name()] is quarantined until further notice."))
return
emergency_shuttle.call_transfer()
//delay events in case of an autotransfer
if (!user)
if(!user)
SSevents.delay_events(EVENT_LEVEL_MODERATE, 10200) //17 minutes
SSevents.delay_events(EVENT_LEVEL_MAJOR, 10200)

View File

@@ -3,16 +3,16 @@
/datum/computer_file/program/power_monitor
filename = "powermonitor"
filedesc = "Power Monitoring"
nanomodule_path = /datum/nano_module/power_monitor/
nanomodule_path = /datum/nano_module/power_monitor
program_icon_state = "power_monitor"
extended_desc = "This program connects to sensors around the station to provide information about electrical systems"
ui_header = "power_norm.gif"
required_access_run = access_engine
required_access_download = access_ce
requires_ntnet = 1
requires_ntnet = TRUE
network_destination = "power monitoring system"
size = 9
var/has_alert = 0
var/has_alert = FALSE
color = LIGHT_COLOR_ORANGE
/datum/computer_file/program/power_monitor/process_tick()
@@ -23,13 +23,13 @@
program_icon_state = "power_monitor_warn"
ui_header = "power_warn.gif"
update_computer_icon()
has_alert = 1
has_alert = TRUE
else
if(has_alert)
program_icon_state = "power_monitor"
ui_header = "power_norm.gif"
update_computer_icon()
has_alert = 0
has_alert = FALSE
/datum/computer_file/program/alarm_monitor
filename = "alarmmonitor"
@@ -38,10 +38,10 @@
ui_header = "alarm_green.gif"
program_icon_state = "alert-green"
extended_desc = "This program provides visual interface for station's alarm system."
requires_ntnet = 1
requires_ntnet = TRUE
network_destination = "alarm monitoring network"
size = 5
var/has_alert = 0
var/has_alert = FALSE
color = LIGHT_COLOR_CYAN
/datum/computer_file/program/alarm_monitor/process_tick()
@@ -52,14 +52,14 @@
program_icon_state = "alert-red"
ui_header = "alarm_red.gif"
update_computer_icon()
has_alert = 1
has_alert = TRUE
else
if(has_alert)
program_icon_state = "alert-green"
ui_header = "alarm_green.gif"
update_computer_icon()
has_alert = 0
return 1
has_alert = FALSE
return TRUE
/datum/computer_file/program/atmos_control
filename = "atmoscontrol"
@@ -69,7 +69,7 @@
extended_desc = "This program allows remote control of air alarms around the station. This program can not be run on tablet computers."
required_access_run = access_atmospherics
required_access_download = access_ce
requires_ntnet = 1
requires_ntnet = TRUE
network_destination = "atmospheric control system"
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP | PROGRAM_SILICON
@@ -84,7 +84,7 @@
extended_desc = "This program allows remote control of power distribution systems around the station. This program can not be run on tablet computers."
required_access_run = access_engine
required_access_download = access_ce
requires_ntnet = 1
requires_ntnet = TRUE
network_destination = "RCON remote control system"
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_CONSOLE | PROGRAM_SILICON
@@ -100,7 +100,7 @@
extended_desc = "This program allows mass-control of the station's lighting systems. This program cannot be run on tablet computers."
required_access_run = access_heads
required_access_download = access_ce
requires_ntnet = 1
requires_ntnet = TRUE
network_destination = "APC Coordinator"
requires_ntnet_feature = NTNET_SYSTEMCONTROL
usage_flags = PROGRAM_CONSOLE | PROGRAM_SILICON

View File

@@ -8,24 +8,24 @@
program_icon_state = "game" // Icon state of this program's screen.
extended_desc = "Fun for the whole family! Probably not an AAA title, but at least you can download it on the corporate network.." // A nice description.
size = 5 // Size in GQ. Integers only. Smaller sizes should be used for utility/low use programs (like this one), while large sizes are for important programs.
requires_ntnet = 0 // This particular program does not require NTNet network conectivity...
available_on_ntnet = 1 // ... but we want it to be available for download.
nanomodule_path = /datum/nano_module/arcade_classic/ // Path of relevant nano module. The nano module is defined further in the file.
requires_ntnet = FALSE // This particular program does not require NTNet network conectivity...
available_on_ntnet = TRUE // ... but we want it to be available for download.
nanomodule_path = /datum/nano_module/arcade_classic // Path of relevant nano module. The nano module is defined further in the file.
var/picked_enemy_name
color = LIGHT_COLOR_BLUE
usage_flags = PROGRAM_ALL_REGULAR
// Blatantly stolen and shortened version from arcade machines. Generates a random enemy name
/datum/computer_file/program/game/arcade/proc/random_enemy_name()
var/name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ", "the vibrating bluespace")
var/name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "Slime", "Lizard Man", "Unicorn", "Squirrel")
var/name_part1 = pick("The Automatic", "Farmer", "Lord", "Professor", "The Cuban", "The Evil", "The Dread King", "The Space", "Lord", "The Great", "Duke", "General", "The Vibrating Bluespace", "Scalie")
var/name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Geoff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "Slime", "Lizard Man", "Unicorn", "Squirrel")
return "[name_part1] [name_part2]"
// When the program is first created, we generate a new enemy name and name ourselves accordingly.
/datum/computer_file/program/game/arcade/New()
..()
picked_enemy_name = random_enemy_name()
filedesc = "Defeat [picked_enemy_name]"
filedesc = "[pick("Defeat", "Destroy", "Decimate", "Decapitate")] [picked_enemy_name]"
// Important in order to ensure that copied versions will have the same enemy name.
/datum/computer_file/program/game/arcade/clone()
@@ -44,7 +44,7 @@
// Nano module the program uses.
// This can be either /datum/nano_module/ or /datum/nano_module/program. The latter is intended for nano modules that are suposed to be exclusively used with modular computers,
// and should generally not be used, as such nano modules are hard to use on other places.
/datum/nano_module/arcade_classic/
/datum/nano_module/arcade_classic
name = "Classic Arcade"
var/player_mana // Various variables specific to the nano module. In this case, the nano module is a simple arcade game, so the variables store health and other stats.
var/player_health
@@ -75,7 +75,7 @@
if (!ui)
ui = new(user, src, ui_key, "arcade_classic.tmpl", "Defeat [enemy_name]", 500, 350, state = state)
if(host.update_layout())
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
@@ -92,7 +92,7 @@
enemy_health += healamt
information += "[enemy_name] heals for [healamt] health!"
else
var/dam = rand(3,6)
var/dam = rand(3, 6)
player_health -= dam
information += "[enemy_name] attacks for [dam] damage!"
@@ -102,10 +102,10 @@
information += "You have defeated [enemy_name], but you have died in the fight!"
else
information += "You have been defeated by [enemy_name]!"
gameover = 1
gameover = TRUE
return TRUE
else if(enemy_health <= 0)
gameover = 1
gameover = TRUE
information += "Congratulations! You have defeated [enemy_name]!"
return TRUE
return FALSE
@@ -118,23 +118,21 @@
gameover = FALSE
information = "A new game has started!"
/datum/nano_module/arcade_classic/Topic(href, href_list)
if(..()) // Always begin your Topic() calls with a parent call!
return 1
return TRUE
if(href_list["new_game"])
new_game()
return 1 // Returning 1 (TRUE) in Topic automatically handles UI updates.
return TRUE // Returning 1 (TRUE) in Topic automatically handles UI updates.
if(gameover) // If the game has already ended, we don't want the following three topic calls to be processed at all.
return 1 // Instead of adding checks into each of those three, we can easily add this one check here to reduce on code copy-paste.
return TRUE // Instead of adding checks into each of those three, we can easily add this one check here to reduce on code copy-paste.
if(href_list["attack"])
var/damage = rand(2, 6)
information = "You attack for [damage] damage."
enemy_health -= damage
enemy_play()
check_gameover()
return 1
return TRUE
if(href_list["heal"])
var/healfor = rand(6, 8)
var/cost = rand(1, 3)
@@ -143,11 +141,11 @@
player_mana -= cost
enemy_play()
check_gameover()
return 1
return TRUE
if(href_list["regain_mana"])
var/regen = rand(4, 7)
information = "You rest of a while, regaining [regen] energy."
information = "You rest for a while, regaining [regen] energy."
player_mana += regen
enemy_play()
check_gameover()
return 1
return TRUE

View File

@@ -56,9 +56,9 @@
//If we havent found any conflict and all tiles are filled, then the user has won the game.
else if (empty == 0)
message = "Congratulations! You win the game!"
if (!wongame)
if (!won_game)
playsound(get_turf(program.computer), 'sound/magic/light.ogg', 50, 1)
wongame = 1
won_game = 1
.=-1

View File

@@ -4,17 +4,17 @@
program_icon_state = "sudoku" // Icon state of this program's screen.
extended_desc = "A game of numbers, logic, and deduction. Popular for centuries to keep the mind sharp." // A nice description.
size = 5 // Size in GQ. Integers only. Smaller sizes should be used for utility/low use programs (like this one), while large sizes are for important programs.
requires_ntnet = 0 // This particular program does not require NTNet network conectivity...
available_on_ntnet = 1 // ... but we want it to be available for download.
requires_ntnet = FALSE // This particular program does not require NTNet network conectivity...
available_on_ntnet = TRUE // ... but we want it to be available for download.
nanomodule_path = /datum/nano_module/program/sudoku // Path of relevant nano module. The nano module is defined further in the file.
usage_flags = PROGRAM_ALL_REGULAR
/datum/nano_module/program/sudoku
var/list/grid = null
var/building = 0
var/building = FALSE
var/list/solution = list()
var/cheated = 0
var/cheated = FALSE
var/list/boxes = list(//Most efficient way i could think to do this
"11" = list(1,2,3,10,11,12,19,20,21),
@@ -28,19 +28,19 @@
"33" = list(61,62,63,70,71,72,79,80,81)
)
var/message = ""//Error or informational message shown on screen.
var/lastmessage = ""
var/messagesent = 0
var/list/clues = list("Easy" = 36,"Medium"=31,"Hard"=26,"Robust"=17)
var/lastuser = null
var/wongame = 0
var/last_message = ""
var/message_sent = FALSE
var/list/clues = list("Easy" = 36, "Medium" = 31,"Hard" = 26,"Robust" = 17)
var/last_user
var/won_game = FALSE
var/datum/computer_file/program/game/sudoku
var/newdifficulty = "Easy"//The selected difficulty mode for generating the next grid
var/new_difficulty = "Easy" //The selected difficulty mode for generating the next grid
var/collapse = 0
var/collapse = FALSE
var/width = 900
/datum/nano_module/program/sudoku/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 0, var/datum/topic_state/state = default_state)
/datum/nano_module/program/sudoku/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = FALSE, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if (!grid)
@@ -49,88 +49,85 @@
data["src"] = "\ref[src]"
data["collapse"] = collapse
data["message"] = message
data["difficulty"] = newdifficulty
if (message != lastmessage)
lastmessage = message
messagesent = world.time
else if ((world.time - messagesent) > 100)//Make sure that messages show onscreen for at least 10 seconds
data["difficulty"] = new_difficulty
if (message != last_message)
last_message = message
message_sent = world.time
else if ((world.time - message_sent) > 100)//Make sure that messages show onscreen for at least 10 seconds
message = ""//Displays for one refresh only
lastuser = user
last_user = user
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "sudoku.tmpl", "Sudoku", width, 557, state = state)
//if(host.update_layout()) // This is necessary to ensure the status bar remains updated along with rest of the UI.
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(0)
ui.set_auto_update(FALSE)
/datum/nano_module/program/sudoku/Topic(var/href, var/list/href_list)
..()
if(href_list["save"])//This is called with every keypress
save_grid(href_list)
return//No refreshing for every input
else if (href_list["check"])
else if(href_list["check"])
save_grid(href_list)
check_validity()
else if (href_list["hint"])//Reveals one tile
var/response = alert(usr,"Are you sure you want a hint? This will reveal the correct number for one tile. But you'll lose the pride of having figured it out yourself..","Ask for a hint","Help me","I can do it myself")
if (response == "Help me")
else if(href_list["hint"])//Reveals one tile
var/response = alert(usr, "Are you sure you want a hint? This will reveal the correct number for one tile. But you'll lose the pride of having figured it out yourself...", "Ask for a hint", "Help me.", "I can do it myself.")
if(response == "Help me.")
solver(1)
else
return
else if (href_list["solve"])
else if(href_list["solve"])
solver(81)
else if (href_list["clear"])
var/response = alert(usr,"Are you sure you want to clear the grid? This will remove all the numbers you've typed in. The starting clues will remain.","Clear board","Clear it","Wait no!")
if (response == "Clear it")
clear_grid(0)
else if(href_list["clear"])
var/response = alert(usr, "Are you sure you want to clear the grid? This will remove all the numbers you've typed in. The starting clues will remain.", "Clear board", "Clear it.", "Wait no!")
if(response == "Clear it.")
clear_grid(FALSE)
else
return
else if (href_list["purge"])
clear_grid(1)
else if (href_list["difficulty"])
newdifficulty = href_list["difficulty"]
else if (href_list["newgame"])
var/response = alert(usr,"Are you sure you want to start a new game? All progress on this one will be lost. Be sure to pick your desired difficulty first.","New Puzzle","Start Anew","Wait no!")
if (response == "Start Anew")
advanced_populate_grid(clues[newdifficulty])
else if(href_list["purge"])
clear_grid(TRUE)
else if(href_list["difficulty"])
new_difficulty = href_list["difficulty"]
else if(href_list["newgame"])
var/response = alert(usr, "Are you sure you want to start a new game? All progress on this one will be lost. Be sure to pick your desired difficulty first.", "New Puzzle", "Start Anew.", "Wait no!")
if(response == "Start Anew.")
advanced_populate_grid(clues[new_difficulty])
else
return
else if (href_list["collapse"])
else if(href_list["collapse"])
collapse = !collapse
set_width(usr)
return
if (usr)
if(usr)
ui_interact(usr)
/datum/nano_module/program/sudoku/proc/set_width(var/mob/user)
if (collapse)
if(collapse)
width = 400
else
width = 900
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
if (ui)
if(ui)
ui.close()
ui_interact(user, force_open = 1)
ui_interact(user, force_open = TRUE)
/datum/nano_module/program/sudoku/proc/save_grid(var/list/inputdata)
var/i = 1
for (i = 1, i <= 81, i++)
for(i = 1, i <= 81, i++)
var/list/cell = grid[i]
var/v = text2num(inputdata["[i]"])
if (inputdata["[i]"] == "" || (v > 0 && v < 10))
if(inputdata["[i]"] == "" || (v > 0 && v < 10))
cell["value"] = inputdata["[i]"]
/datum/nano_module/program/sudoku/proc/create_grid()
if (grid)
if(grid)
grid.Cut()
grid = list()
@@ -188,22 +185,16 @@
var/row = 1
var/column = 1
if (index <= 9)
if(index <= 9)
column = index
else
while (index > 9)
while(index > 9)
index -= 9
row++
column = index
return "[row][column]"
//Clears the grid:
//With an input of 0, clears all user input and restores the grid to just the generated clues
//With input of 1, clears every cell, grid becomes empty
@@ -214,6 +205,6 @@
tile["value"] = ""
tile["static"] = 0
tile["highlight"] = 0
if (full)
cheated = 0
wongame = 0
if(full)
cheated = FALSE
won_game = FALSE

View File

@@ -7,13 +7,13 @@
requires_ntnet = TRUE
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/program/computer_newsbrowser/
nanomodule_path = /datum/nano_module/program/computer_newsbrowser
var/datum/computer_file/data/news_article/loaded_article
var/download_progress = 0
var/download_netspeed = 0
var/downloading = 0
var/downloading = FALSE
var/message = ""
var/show_archived = 0
var/show_archived = FALSE
color = LIGHT_COLOR_GREEN
/datum/computer_file/program/newsbrowser/process_tick()
@@ -30,56 +30,56 @@
download_netspeed = NTNETSPEED_ETHERNET
download_progress += download_netspeed
if(download_progress >= loaded_article.size)
downloading = 0
requires_ntnet = 0 // Turn off NTNet requirement as we already loaded the file into local memory.
downloading = FALSE
requires_ntnet = FALSE // Turn off NTNet requirement as we already loaded the file into local memory.
SSnanoui.update_uis(NM)
/datum/computer_file/program/newsbrowser/kill_program()
..()
requires_ntnet = 1
requires_ntnet = TRUE
loaded_article = null
download_progress = 0
downloading = 0
show_archived = 0
downloading = FALSE
show_archived = FALSE
/datum/computer_file/program/newsbrowser/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["PRG_openarticle"])
. = 1
. = TRUE
if(downloading || loaded_article)
return 1
return TRUE
for(var/datum/computer_file/data/news_article/N in ntnet_global.available_news)
if(N.uid == text2num(href_list["PRG_openarticle"]))
loaded_article = N.clone()
downloading = 1
downloading = TRUE
break
if(href_list["PRG_reset"])
. = 1
downloading = 0
. = TRUE
downloading = FALSE
download_progress = 0
requires_ntnet = 1
requires_ntnet = TRUE
loaded_article = null
if(href_list["PRG_clearmessage"])
. = 1
. = TRUE
message = ""
if(href_list["PRG_savearticle"])
. = 1
. = TRUE
if(downloading || !loaded_article)
return
var/savename = sanitize(input(usr, "Enter file name or leave blank to cancel:", "Save article", loaded_article.filename))
if(!savename)
return 1
return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/data/news_article/N = loaded_article.clone()
N.filename = savename
HDD.store_file(N)
if(href_list["PRG_toggle_archived"])
. = 1
. = TRUE
show_archived = !show_archived
if(.)
SSnanoui.update_uis(NM)
@@ -124,7 +124,6 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "news_browser.tmpl", "NTNet/ExoNet News Browser", 575, 700, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()

View File

@@ -10,11 +10,11 @@
ui_header = "ntnrc_idle.gif"
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/program/computer_chatclient
var/last_message = null // Used to generate the toolbar icon
var/last_message // Used to generate the toolbar icon
var/username
var/datum/ntnet_conversation/channel = null
var/operator_mode = 0 // Channel operator mode
var/netadmin_mode = 0 // Administrator mode (invisible to other users + bypasses passwords)
var/datum/ntnet_conversation/channel
var/operator_mode = FALSE // Channel operator mode
var/netadmin_mode = FALSE // Administrator mode (invisible to other users + bypasses passwords)
color = LIGHT_COLOR_GREEN
/datum/computer_file/program/chatclient/New()
@@ -51,8 +51,8 @@
if(C.password)
var/mob/living/user = usr
var/password = sanitize(input(user,"Access Denied. Enter password:"))
if(C && (password == C.password))
var/password = sanitize(input(user, "Access Denied. Enter password:"))
if(C?.password == password)
C.add_client(src)
channel = C
return TRUE
@@ -66,7 +66,7 @@
if(href_list["PRG_newchannel"])
. = TRUE
var/mob/living/user = usr
var/channel_title = sanitize(input(user,"Enter channel name or leave blank to cancel:"))
var/channel_title = sanitize(input(user, "Enter channel name or leave blank to cancel:"))
if(!channel_title)
return
var/datum/ntnet_conversation/C = new /datum/ntnet_conversation(channel_title)
@@ -95,19 +95,19 @@
if(href_list["PRG_changename"])
. = TRUE
var/mob/living/user = usr
var/newname = sanitize(input(user,"Enter new nickname or leave blank to cancel:"))
if(!newname)
return 1
var/new_name = sanitize(input(user, "Enter new nickname or leave blank to cancel:"))
if(!new_name)
return TRUE
if(channel)
channel.add_status_message("[username] is now known as [newname].")
username = newname
channel.add_status_message("[username] is now known as [new_name].")
username = new_name
if(href_list["PRG_savelog"])
. = TRUE
if(!channel)
return
var/mob/living/user = usr
var/logname = input(user,"Enter desired logfile name (.log) or leave blank to cancel:")
var/logname = input(user, "Enter desired logfile name (.log) or leave blank to cancel:")
if(!logname || !channel)
return TRUE
var/datum/computer_file/data/logfile = new /datum/computer_file/data/logfile()
@@ -170,7 +170,7 @@
else
last_message = null
return 1
if(channel && channel.messages && channel.messages.len)
if(channel?.messages?.len)
ui_header = last_message == channel.messages[channel.messages.len - 1] ? "ntnrc_idle.gif" : "ntnrc_new.gif"
else
ui_header = "ntnrc_idle.gif"

View File

@@ -4,13 +4,12 @@
extended_desc = "This program is used to run NTSL2+ programs."
program_icon_state = "generic"
size = 2
requires_ntnet = 1
available_on_ntnet = 1
undeletable = 0
requires_ntnet = TRUE
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/program/computer_ntsl2_interpreter/
nanomodule_path = /datum/nano_module/program/computer_ntsl2_interpreter
var/datum/ntsl_program/running = null
var/datum/ntsl_program/running
color = LIGHT_COLOR_GREEN
/datum/computer_file/program/ntsl2_interpreter/process_tick()
@@ -26,10 +25,10 @@
/datum/computer_file/program/ntsl2_interpreter/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["PRG_execfile"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/datum/computer_file/data/F = HDD.find_file_by_name(href_list["PRG_execfile"])
if(istype(F))
@@ -40,7 +39,7 @@
running.name = href_list["PRG_execfile"]
if(href_list["PRG_closefile"])
. = 1
. = TRUE
if(istype(running))
running.kill()
running = null
@@ -49,13 +48,13 @@
if(istype(running))
var/topc = href_list["PRG_topic"]
if(copytext(topc, 1, 2) == "?")
topc = copytext(topc, 2) + "?" + input("","Enter Data")
topc = copytext(topc, 2) + "?" + input("", "Enter Data")
running.topic(topc)
running.cycle(300)
. = 1
. = TRUE
if(href_list["PRG_refresh"])
. = 1
. = TRUE
if(.)
SSnanoui.update_uis(NM)
@@ -98,4 +97,3 @@
ui.auto_update_layout = 1
ui.set_initial_data(data)
ui.open()

View File

@@ -10,20 +10,20 @@ var/global/nttransfer_uid = 0
requires_ntnet_feature = NTNET_PEERTOPEER
network_destination = "other device via P2P tunnel"
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/program/computer_nttransfer/
nanomodule_path = /datum/nano_module/program/computer_nttransfer
color = LIGHT_COLOR_GREEN
var/error = "" // Error screen
var/server_password = "" // Optional password to download the file.
var/datum/computer_file/provided_file = null // File which is provided to clients.
var/datum/computer_file/downloaded_file = null // File which is being downloaded
var/datum/computer_file/provided_file // File which is provided to clients.
var/datum/computer_file/downloaded_file // File which is being downloaded
var/list/connected_clients = list() // List of connected clients.
var/datum/computer_file/program/nttransfer/remote // Client var, specifies who are we downloading from.
var/download_completion = 0 // Download progress in GQ
var/download_netspeed = 0 // Our connectivity speed in GQ/s
var/actual_netspeed = 0 // Displayed in the UI, this is the actual transfer speed.
var/unique_token // UID of this program
var/upload_menu = 0 // Whether we show the program list and upload menu
var/upload_menu = FALSE // Whether we show the program list and upload menu
/datum/computer_file/program/nttransfer/New()
unique_token = nttransfer_uid
@@ -91,7 +91,7 @@ var/global/nttransfer_uid = 0
/datum/nano_module/program/computer_nttransfer
name = "NTNet P2P Transfer Client"
/datum/nano_module/program/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
/datum/nano_module/program/computer_nttransfer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = TRUE, var/datum/topic_state/state = default_state)
if(!program)
return
var/datum/computer_file/program/nttransfer/PRG = program
@@ -103,16 +103,16 @@ var/global/nttransfer_uid = 0
if(PRG.error)
data["error"] = PRG.error
else if(PRG.downloaded_file)
data["downloading"] = 1
data["downloading"] = TRUE
data["download_size"] = PRG.downloaded_file.size
data["download_progress"] = PRG.download_completion
data["download_netspeed"] = PRG.actual_netspeed
data["download_name"] = "[PRG.downloaded_file.filename].[PRG.downloaded_file.filetype]"
else if (PRG.provided_file)
data["uploading"] = 1
data["uploading"] = TRUE
data["upload_uid"] = PRG.unique_token
data["upload_clients"] = PRG.connected_clients.len
data["upload_haspassword"] = PRG.server_password ? 1 : 0
data["upload_haspassword"] = PRG.server_password ? TRUE : FALSE
data["upload_filename"] = "[PRG.provided_file.filename].[PRG.provided_file.filetype]"
else if (PRG.upload_menu)
var/list/all_files[0]
@@ -130,21 +130,21 @@ var/global/nttransfer_uid = 0
"uid" = P.unique_token,
"filename" = "[P.provided_file.filename].[P.provided_file.filetype]",
"size" = P.provided_file.size,
"haspassword" = P.server_password ? 1 : 0
"haspassword" = P.server_password ? TRUE : FALSE
)))
data["servers"] = all_servers
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_transfer.tmpl", "NTNet P2P Transfer Client", 575, 700, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/computer_file/program/nttransfer/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["PRG_downloadfile"])
for(var/datum/computer_file/program/nttransfer/P in ntnet_global.fileservers)
if("[P.unique_token]" == href_list["PRG_downloadfile"])
@@ -162,14 +162,14 @@ var/global/nttransfer_uid = 0
return 1
if(href_list["PRG_reset"])
error = ""
upload_menu = 0
upload_menu = FALSE
finalize_download()
if(src in ntnet_global.fileservers)
ntnet_global.fileservers.Remove(src)
for(var/datum/computer_file/program/nttransfer/T in connected_clients)
T.crash_download("Remote server has forcibly closed the connection")
provided_file = null
return 1
return TRUE
if(href_list["PRG_setpassword"])
var/pass = sanitize(input(usr, "Enter new server password. Leave blank to cancel, input 'none' to disable password.", "Server security", "none"))
if(!pass)
@@ -178,7 +178,7 @@ var/global/nttransfer_uid = 0
server_password = ""
return
server_password = pass
return 1
return TRUE
if(href_list["PRG_uploadfile"])
for(var/datum/computer_file/F in computer.hard_drive.stored_files)
if("[F.uid]" == href_list["PRG_uploadfile"])
@@ -189,7 +189,7 @@ var/global/nttransfer_uid = 0
ntnet_global.fileservers.Add(src)
return
error = "I/O Error: Unable to locate file on hard drive."
return 1
return TRUE
if(href_list["PRG_uploadmenu"])
upload_menu = 1
return 0
upload_menu = TRUE
return FALSE

View File

@@ -8,12 +8,12 @@
requires_ntnet = TRUE
network_destination = "crew lifesigns monitoring system"
size = 11
usage_flags = PROGRAM_LAPTOP | PROGRAM_TELESCREEN | PROGRAM_CONSOLE | PROGRAM_SILICON | PROGRAM_TABLET
usage_flags = PROGRAM_ALL_REGULAR
color = LIGHT_COLOR_CYAN
/datum/computer_file/program/suit_sensors/ui_interact(mob/user)
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
if (!ui)
if(!ui)
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-medical-sensors", 800, 600, "Suit Sensors Monitoring")
ui.auto_update_content = TRUE
ui.open()

View File

@@ -8,13 +8,13 @@
requires_access_to_run = FALSE
required_access_download = access_heads
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/program/computer_aidiag/
nanomodule_path = /datum/nano_module/program/computer_aidiag
var/restoring = FALSE
color = LIGHT_COLOR_PURPLE
usage_flags = PROGRAM_CONSOLE
/datum/computer_file/program/aidiag/proc/get_ai()
if(computer && computer.ai_slot && computer.ai_slot.check_functionality() && computer.ai_slot.enabled && computer.ai_slot.stored_card && computer.ai_slot.stored_card.carded_ai)
if(computer?.ai_slot?.check_functionality() && computer.ai_slot.enabled && computer.ai_slot.stored_card?.carded_ai)
return computer.ai_slot.stored_card.carded_ai
return null
@@ -37,26 +37,25 @@
A.laws.clear_ion_laws()
A.laws.clear_inherent_laws()
A.laws.clear_supplied_laws()
to_chat(A, "<span class='danger'>All laws purged.</span>")
to_chat(A, SPAN_WARNING("All laws purged."))
return TRUE
if(href_list["PRG_resetLaws"])
A.laws.clear_ion_laws()
A.laws.clear_supplied_laws()
to_chat(A, "<span class='danger'>Non-core laws reset.</span>")
to_chat(A, SPAN_WARNING("Non-core laws reset."))
return TRUE
if(href_list["PRG_uploadNTDefault"])
A.laws = new/datum/ai_laws/nanotrasen
to_chat(A, "<span class='danger'>All laws purged. NT Default lawset uploaded.</span>")
A.laws = new /datum/ai_laws/nanotrasen
to_chat(A, SPAN_WARNING("All laws purged. NT Default lawset uploaded."))
return TRUE
if(href_list["PRG_addCustomSuppliedLaw"])
var/law_to_add = sanitize(input("Please enter a new law for the AI.", "Custom Law Entry"))
var/sector = input("Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)") as num
sector = between(MIN_SUPPLIED_LAW_NUMBER, sector, MAX_SUPPLIED_LAW_NUMBER)
A.add_supplied_law(sector, law_to_add)
to_chat(A, "<span class='danger'>Custom law uploaded to sector [sector]: [law_to_add].</span>")
to_chat(A, SPAN_WARNING("Custom law uploaded to sector [sector]: [law_to_add]."))
return TRUE
/datum/computer_file/program/aidiag/process_tick()
var/mob/living/silicon/ai/A = get_ai()
if(!A || !restoring)
@@ -67,7 +66,7 @@
A.adjustOxyLoss(-4)
A.updatehealth()
// If the AI is dead, revive it.
if (A.health >= -100 && A.stat == DEAD)
if(A.health >= -100 && A.stat == DEAD)
A.stat = CONSCIOUS
A.lying = FALSE
A.switch_from_dead_to_living_mob_list()

View File

@@ -11,7 +11,7 @@
color = LIGHT_COLOR_GREEN
available_on_ntnet = TRUE
nanomodule_path = /datum/nano_module/computer_ntnetmonitor/
nanomodule_path = /datum/nano_module/computer_ntnetmonitor
/datum/nano_module/computer_ntnetmonitor
name = "NTNet Diagnostics and Monitoring"

View File

@@ -40,10 +40,10 @@
/datum/nano_module/camera_monitor
name = "Camera Monitoring program"
var/obj/machinery/camera/current_camera = null
var/current_network = null
var/obj/machinery/camera/current_camera
var/current_network
/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state)
/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = TRUE, state = default_state)
var/list/data = host.initial_data()
data["current_camera"] = current_camera ? current_camera.nano_structure() : null

View File

@@ -9,20 +9,20 @@
available_on_ntnet = TRUE
required_access_download = access_hos
required_access_run = access_security
nanomodule_path = /datum/nano_module/program/digitalwarrant/
nanomodule_path = /datum/nano_module/program/digitalwarrant
/datum/nano_module/program/digitalwarrant/
/datum/nano_module/program/digitalwarrant
name = "Warrant Assistant"
var/datum/record/warrant/activewarrant
var/datum/record/warrant/active_warrant
/datum/nano_module/program/digitalwarrant/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
var/list/data = host.initial_data()
if(activewarrant)
data["warrantname"] = activewarrant.name
data["warrantcharges"] = activewarrant.notes
data["warrantauth"] = activewarrant.authorization
data["type"] = activewarrant.wtype
if(active_warrant)
data["warrantname"] = active_warrant.name
data["warrantcharges"] = active_warrant.notes
data["warrantauth"] = active_warrant.authorization
data["type"] = active_warrant.wtype
else
var/list/allwarrants = list()
for(var/datum/record/warrant/W in SSrecords.warrants)
@@ -47,13 +47,13 @@
return TRUE
if(href_list["sw_menu"])
activewarrant = null
active_warrant = null
if(href_list["editwarrant"])
. = TRUE
for(var/datum/record/warrant/W in SSrecords.warrants)
if(W.id == text2num(href_list["editwarrant"]))
activewarrant = W
active_warrant = W
break
// The following actions will only be possible if the user has an ID with security access equipped. This is in line with modular computer framework's authentication methods,
@@ -64,13 +64,13 @@
return
var/obj/item/card/id/I = user.GetIdCard()
if(!istype(I) || !I.registered_name || !(access_armory in I.access) || issilicon(user))
to_chat(user, "Authentication error: Unable to locate ID with appropriate access to allow this operation.")
to_chat(user, SPAN_WARNING("Authentication error: Unable to locate ID with appropriate access to allow this operation."))
return
if(href_list["addwarrant"])
. = TRUE
var/datum/record/warrant/W = new()
var/temp = sanitize(input(usr, "Do you want to create a search-, or an arrest warrant?") as null|anything in list("search","arrest"))
var/temp = sanitize(input(usr, "Do you want to create a search-, or an arrest warrant?") as null|anything in list("search", "arrest"))
if(CanInteract(user, default_state))
if(temp == "arrest")
W.name = "Unknown"
@@ -82,17 +82,17 @@
W.notes = "No reason given"
W.authorization = "Unauthorized"
W.wtype = "search"
activewarrant = W
active_warrant = W
if(href_list["savewarrant"])
. = TRUE
SSrecords.update_record(activewarrant)
activewarrant = null
SSrecords.update_record(active_warrant)
active_warrant = null
if(href_list["deletewarrant"])
. = TRUE
SSrecords.remove_record(activewarrant)
activewarrant = null
SSrecords.remove_record(active_warrant)
active_warrant = null
if(href_list["editwarrantname"])
. = TRUE
@@ -103,7 +103,7 @@
if(CanInteract(user, default_state))
if (!new_name)
return
activewarrant.name = new_name
active_warrant.name = new_name
if(href_list["editwarrantnamecustom"])
. = TRUE
@@ -111,21 +111,21 @@
if(CanInteract(user, default_state))
if (!new_name)
return
activewarrant.name = new_name
active_warrant.name = new_name
if(href_list["editwarrantcharges"])
. = TRUE
var/new_charges = sanitize(input("Please input charges", "Charges", activewarrant.notes) as null|text)
var/new_charges = sanitize(input("Please input charges", "Charges", active_warrant.notes) as null|text)
if(CanInteract(user, default_state))
if (!new_charges)
return
activewarrant.notes = new_charges
active_warrant.notes = new_charges
if(href_list["editwarrantauth"])
. = TRUE
activewarrant.authorization = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]"
active_warrant.authorization = "[I.registered_name] - [I.assignment ? I.assignment : "(Unknown)"]"
if(href_list["back"])
. = TRUE
activewarrant = null
active_warrant = null

View File

@@ -1,13 +1,13 @@
/datum/computer_file/program/penal_mechs
filename = "penalmechs"
filename = "penalrobotics"
filedesc = "Remote Penal Monitoring"
program_icon_state = "security"
extended_desc = "This program allows monitoring and control of active penal miner mechs."
extended_desc = "This program allows monitoring and control of active penal robotics."
required_access_run = access_armory
required_access_download = access_armory
requires_ntnet = 1
available_on_ntnet = 1
network_destination = "penal mining mech monitoring system"
requires_ntnet = TRUE
available_on_ntnet = TRUE
network_destination = "penal robotics monitoring system"
size = 11
usage_flags = PROGRAM_ALL_REGULAR
color = LIGHT_COLOR_ORANGE
@@ -18,7 +18,7 @@
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
if (!ui)
ui = new /datum/vueui/modularcomputer(user, src, "mcomputer-security-penalcontroller", 500, 400, "Penal Mech Monitoring")
ui.auto_update_content = 1
ui.auto_update_content = TRUE
ui.open()
/datum/computer_file/program/penal_mechs/vueui_transfer(oldobj)
@@ -26,7 +26,7 @@
var/datum/vueui/ui = o
// Let's ensure our ui's autoupdate after transfer.
// TODO: revert this value on transfer out.
ui.auto_update_content = 1
ui.auto_update_content = TRUE
return TRUE
/datum/computer_file/program/penal_mechs/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
@@ -167,6 +167,6 @@
if(!current_camera)
return FALSE
var/viewflag = current_camera.check_eye(user)
if ( viewflag < 0 ) //camera doesn't work
if(viewflag < 0) //camera doesn't work
reset_current()
return viewflag

View File

@@ -6,94 +6,94 @@
program_icon_state = "generic"
color = LIGHT_COLOR_GREEN
size = 8
requires_ntnet = 0
available_on_ntnet = 0
undeletable = 1
nanomodule_path = /datum/nano_module/program/computer_filemanager/
requires_ntnet = FALSE
available_on_ntnet = FALSE
undeletable = TRUE
nanomodule_path = /datum/nano_module/program/computer_filemanager
var/open_file
var/error
/datum/computer_file/program/filemanager/Topic(href, href_list)
if(..())
return 1
return TRUE
if(href_list["PRG_openfile"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_openfile"])
if (!F)
if(!F)
return
if (F.can_access_file(usr))
if(F.can_access_file(usr))
open_file = href_list["PRG_openfile"]
else
return
if(href_list["PRG_newtextfile"])
. = 1
. = TRUE
var/newname = sanitize(input(usr, "Enter file name or leave blank to cancel:", "File rename"))
if(!newname)
return 1
return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/data/F = new/datum/computer_file/data()
F.filename = newname
F.filetype = "TXT"
HDD.store_file(F)
if(href_list["PRG_deletefile"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_deletefile"])
if(!file || file.undeletable)
return 1
return TRUE
HDD.remove_file(file)
if(href_list["PRG_usbdeletefile"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/RHDD = computer.portable_drive
if(!RHDD)
return 1
return TRUE
var/datum/computer_file/file = RHDD.find_file_by_name(href_list["PRG_usbdeletefile"])
if(!file || file.undeletable)
return 1
return TRUE
RHDD.remove_file(file)
if(href_list["PRG_closefile"])
. = 1
. = TRUE
open_file = null
error = null
if(href_list["PRG_clone"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_clone"])
if(!F || !istype(F))
return 1
return TRUE
var/datum/computer_file/C = F.clone(1)
HDD.store_file(C)
if(href_list["PRG_rename"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/file = HDD.find_file_by_name(href_list["PRG_rename"])
if(!file || !istype(file))
return 1
return TRUE
var/newname = sanitize(input(usr, "Enter new file name:", "File rename", file.filename))
if(file && newname)
file.filename = newname
if(href_list["PRG_edit"])
. = 1
. = TRUE
if(!open_file)
return 1
return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
return TRUE
if(F.do_not_edit && (alert("WARNING: This file is not compatible with editor. Editing it may result in permanently corrupted formatting or damaged data consistency. Edit anyway?", "Incompatible File", "No", "Yes") == "No"))
return 1
return TRUE
var/oldtext = html_decode(F.stored_data)
oldtext = replacetext(oldtext, "\[editorbr\]", "\n")
@@ -114,45 +114,45 @@
error = "I/O error: Unable to overwrite file. Hard drive is probably full. You may want to backup your changes before closing this window:<br><br>[html_decode(F.stored_data)]<br><br>"
HDD.store_file(backup)
if(href_list["PRG_printfile"])
. = 1
. = TRUE
if(!open_file)
return 1
return TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if(!HDD)
return 1
return TRUE
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F))
return 1
return TRUE
if(!computer.nano_printer)
error = "Missing Hardware: Your computer does not have required hardware to complete this operation."
return 1
return TRUE
if(!computer.nano_printer.print_text(F.stored_data))
error = "Hardware error: Printer was unable to print the file. It may be out of paper."
return 1
return TRUE
if(href_list["PRG_copytousb"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD || computer.enrolled != 2)
return 1
return TRUE
var/datum/computer_file/F = HDD.find_file_by_name(href_list["PRG_copytousb"])
if(!F || !istype(F))
return 1
return TRUE
var/datum/computer_file/C = F.clone(0)
RHDD.store_file(C)
if(href_list["PRG_copyfromusb"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
var/obj/item/computer_hardware/hard_drive/portable/RHDD = computer.portable_drive
if(!HDD || !RHDD || computer.enrolled != 2)
return 1
return TRUE
var/datum/computer_file/F = RHDD.find_file_by_name(href_list["PRG_copyfromusb"])
if(!F || !istype(F))
return 1
return TRUE
var/datum/computer_file/C = F.clone(0)
HDD.store_file(C)
if(href_list["PRG_encrypt"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if (!HDD)
return
@@ -163,7 +163,7 @@
return
F.password = sanitize(input(usr, "Enter an encryption key:", "Encrypt File"))
if(href_list["PRG_decrypt"])
. = 1
. = TRUE
var/obj/item/computer_hardware/hard_drive/HDD = computer.hard_drive
if (!HDD)
return
@@ -235,7 +235,8 @@
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "file_manager.tmpl", "NTOS File Manager", 575, 700, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
#undef MAX_TEXTFILE_LENGTH

View File

@@ -12,15 +12,15 @@
available_on_ntnet = FALSE
nanomodule_path = /datum/nano_module/program/computer_ntnetdownload
ui_header = "downloader_finished.gif"
var/datum/computer_file/program/downloaded_file = null
var/hacked_download = 0
var/datum/computer_file/program/downloaded_file
var/hacked_download = FALSE
var/download_completion = 0 //GQ of downloaded data.
var/download_netspeed = 0
var/download_last_update = 0 // For tracking download rates and completion.
var/downloaderror = ""
var/downstream_variance = 0.1
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename, var/user = null)
/datum/computer_file/program/ntnetdownload/proc/begin_file_download(var/filename, var/user)
if(downloaded_file)
return FALSE
@@ -33,26 +33,26 @@
if(PRG.available_on_syndinet && !computer_emagged)
return FALSE
if(!computer || !computer.hard_drive || !computer.hard_drive.try_store_file(PRG))
if(!computer?.hard_drive?.try_store_file(PRG))
return FALSE
if(computer.enrolled == 1 && !computer_emagged)
if(computer.enrolled == TRUE && !computer_emagged)
return FALSE
ui_header = "downloader_running.gif"
if(PRG in ntnet_global.available_station_software)
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from NTNet Software Repository.")
hacked_download = 0
hacked_download = FALSE
else if(PRG in ntnet_global.available_antag_software)
generate_network_log("Began downloading file **ENCRYPTED**.[PRG.filetype] from unspecified server.")
hacked_download = 1
hacked_download = TRUE
else
generate_network_log("Began downloading file [PRG.filename].[PRG.filetype] from unspecified server.")
hacked_download = 0
hacked_download = FALSE
downloaded_file = PRG.clone()
if (user)
if(user)
spawn()
ui_interact(user)
@@ -69,9 +69,12 @@
if(!downloaded_file)
return
generate_network_log("Completed download of file [hacked_download ? "**ENCRYPTED**" : downloaded_file.filename].[downloaded_file.filetype].")
if(!computer || !computer.hard_drive || !computer.hard_drive.store_file(downloaded_file))
if(!computer?.hard_drive?.store_file(downloaded_file))
// 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."
else
playsound(get_turf(computer), 'sound/machines/ping.ogg', 40, 0)
computer.output_message("\icon[computer] <b>[capitalize_first_letters(computer)]</b> pings, \"Software download completed successfully!\"", 1)
downloaded_file = null
download_completion = 0
download_last_update = 0
@@ -138,7 +141,7 @@
/datum/nano_module/program/computer_ntnetdownload
name = "Network Downloader"
var/obj/item/modular_computer/my_computer = null
var/obj/item/modular_computer/my_computer
/datum/nano_module/program/computer_ntnetdownload/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
if(program)
@@ -160,7 +163,7 @@
data["error"] = prog.downloaderror
else if(prog.downloaded_file) // Download running. Wait please..
if (ui)
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
data["downloadname"] = prog.downloaded_file.filename
data["downloaddesc"] = prog.downloaded_file.filedesc
data["downloadsize"] = prog.downloaded_file.size
@@ -168,36 +171,36 @@
data["downloadcompletion"] = round(prog.download_completion, 0.01)
else // No download running, pick file.
if (ui)
ui.set_auto_update(0)//No need for auto updating on the software menu
ui.set_auto_update(FALSE)//No need for auto updating on the software menu
data["disk_size"] = my_computer.hard_drive.max_capacity
data["disk_used"] = my_computer.hard_drive.used_capacity
if(my_computer.enrolled == 2) //To lock installation of software on work computers until the IT Department is properly implemented - Then check for access on enrolled computers
data += get_programlist(user)
else
data["downloadable_programs"] = list()
data["locked"] = 1
data["locked"] = TRUE
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "ntnet_downloader.tmpl", "NTNet Download Program", 575, 700, state = state)
ui.auto_update_layout = 1
ui.auto_update_layout = TRUE
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
ui.set_auto_update(TRUE)
/datum/nano_module/program/computer_ntnetdownload/proc/get_programlist(var/mob/user)
var/list/all_entries[0]
var/datum/computer_file/program/ntnetdownload/prog = program
var/list/data = list()
data["hackedavailable"] = 0
data["hackedavailable"] = FALSE
for(var/datum/computer_file/program/P in ntnet_global.available_station_software)
var/installed = 0
for(var/datum/computer_file/program/Q in program.holder.stored_files)
if (istype(P, Q.type))
installed = 1
var/installed = FALSE
for(var/datum/computer_file/program/Q in program.hard_drive.stored_files)
if(istype(P, Q.type))
installed = TRUE
break
if (!installed)
if(!installed)
// Only those programs our user can run will show in the list
if(!P.can_download(user) && P.requires_access_to_download)
continue
@@ -215,14 +218,14 @@
if(prog.computer_emagged) // If we are running on emagged computer we have access to some "bonus" software
var/list/hacked_programs[0]
for(var/datum/computer_file/program/P in ntnet_global.available_antag_software)
var/installed = 0
for(var/datum/computer_file/program/Q in program.holder.stored_files)
if (istype(P, Q.type))
installed = 1
var/installed = FALSE
for(var/datum/computer_file/program/Q in program.hard_drive.stored_files)
if(istype(P, Q.type))
installed = TRUE
break
if (!installed)
data["hackedavailable"] = 1
if(!installed)
data["hackedavailable"] = TRUE
hacked_programs.Add(list(list(
"filename" = P.filename,
"filedesc" = P.filedesc,

View File

@@ -12,31 +12,31 @@
var/power_usage_occupied = 2 KILOWATTS
/obj/item/computer_hardware/ai_slot/proc/update_power_usage()
if(!stored_card || !stored_card.carded_ai)
if(!stored_card?.carded_ai)
power_usage = power_usage_idle
return
power_usage = power_usage_occupied
/obj/item/computer_hardware/ai_slot/attackby(var/obj/item/W as obj, var/mob/user as mob)
/obj/item/computer_hardware/ai_slot/attackby(obj/item/W, mob/user)
if(..())
return 1
return TRUE
if(istype(W, /obj/item/aicard))
if(stored_card)
to_chat(user, "\The [src] is already occupied.")
to_chat(user, SPAN_WARNING("\The [src] is already occupied."))
return
user.drop_from_inventory(W,src)
user.drop_from_inventory(W, src)
stored_card = W
update_power_usage()
if(W.isscrewdriver())
to_chat(user, "You manually remove \the [stored_card] from \the [src].")
to_chat(user, SPAN_NOTICE("You manually remove \the [stored_card] from \the [src]."))
stored_card.forceMove(get_turf(src))
stored_card = null
update_power_usage()
/obj/item/computer_hardware/ai_slot/Destroy()
if(holder2 && (holder2.ai_slot == src))
holder2.ai_slot = null
if(parent_computer?.ai_slot == src)
parent_computer.ai_slot = null
if(stored_card)
stored_card.forceMove(get_turf(holder2))
holder2 = null
stored_card.forceMove(get_turf(parent_computer))
parent_computer = null
return ..()

View File

@@ -2,9 +2,9 @@
// have tremendeous capacity in comparsion. Higher tier cells would provide your device with nearly infinite battery life, which is something i want to avoid.
/obj/item/computer_hardware/battery_module
name = "standard battery"
desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. It's rating is 750."
desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops. Its rating is 750."
icon_state = "battery_normal"
critical = 1
critical = TRUE
malfunction_probability = 1
origin_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1)
var/battery_rating = 750
@@ -12,7 +12,7 @@
/obj/item/computer_hardware/battery_module/advanced
name = "advanced battery"
desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. It's rating is 1100."
desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices. Its rating is 1100."
icon_state = "battery_advanced"
origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2)
battery_rating = 1100
@@ -20,7 +20,7 @@
/obj/item/computer_hardware/battery_module/super
name = "super battery"
desc = "A very advanced power cell, often used in high-end devices, or as uninterruptable power supply for important consoles or servers. It's rating is 1500."
desc = "A very advanced power cell, often used in high-end devices, or as uninterruptable power supply for important consoles or servers. Its rating is 1500."
icon_state = "battery_super"
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3)
hardware_size = 3
@@ -28,7 +28,7 @@
/obj/item/computer_hardware/battery_module/ultra
name = "ultra battery"
desc = "A very advanced large power cell. It's often used as uninterruptable power supply for critical consoles or servers. It's rating is 2000."
desc = "A very advanced large power cell. Its often used as uninterruptable power supply for critical consoles or servers. Its rating is 2000."
icon_state = "battery_ultra"
origin_tech = list(TECH_POWER = 5, TECH_ENGINEERING = 4)
hardware_size = 3
@@ -36,14 +36,14 @@
/obj/item/computer_hardware/battery_module/micro
name = "micro battery"
desc = "A small power cell, commonly seen in most portable microcomputers. It's rating is 500."
desc = "A small power cell, commonly seen in most portable microcomputers. Its rating is 500."
icon_state = "battery_micro"
origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2)
battery_rating = 500
/obj/item/computer_hardware/battery_module/nano
name = "nano battery"
desc = "A tiny power cell, commonly seen in low-end portable microcomputers. It's rating is 300."
desc = "A tiny power cell, commonly seen in low-end portable microcomputers. Its rating is 300."
icon_state = "battery_nano"
origin_tech = list(TECH_POWER = 1, TECH_ENGINEERING = 1)
battery_rating = 300
@@ -58,15 +58,15 @@
/obj/item/computer_hardware/battery_module/lambda/Initialize()
. = ..()
battery = new/obj/item/cell/infinite(src)
battery = new /obj/item/cell/infinite(src)
/obj/item/computer_hardware/battery_module/diagnostics(var/mob/user)
..()
to_chat(user, "Internal battery charge: [battery.charge]/[battery.maxcharge] mAh")
to_chat(user, SPAN_NOTICE("Internal battery charge: [battery.charge]/[battery.maxcharge] mAh"))
/obj/item/computer_hardware/battery_module/Initialize()
. = ..()
battery = new/obj/item/cell/device/variable(src, battery_rating)
battery = new /obj/item/cell/device/variable(src, battery_rating)
battery.charge = 0
/obj/item/computer_hardware/battery_module/proc/charge_to_full()

View File

@@ -2,17 +2,17 @@
name = "RFID card slot"
desc = "Slot that allows this computer to write data on RFID cards. Necessary for some programs to run properly."
power_usage = 10 //W
critical = 0
critical = FALSE
icon_state = "cardreader"
hardware_size = 1
origin_tech = list(TECH_DATA = 2)
var/obj/item/card/id/stored_card = null
var/obj/item/card/id/stored_card
/obj/item/computer_hardware/card_slot/Destroy()
if(holder2 && (holder2.card_slot == src))
holder2.card_slot = null
if(parent_computer?.card_slot == src)
parent_computer.card_slot = null
if(stored_card)
stored_card.forceMove(get_turf(holder2))
holder2 = null
stored_card.forceMove(get_turf(parent_computer))
parent_computer = null
return ..()

View File

@@ -7,7 +7,7 @@
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
var/max_capacity = 128
var/used_capacity = 0
var/read_only = 0 // If the HDD is read only
var/read_only = FALSE // If the HDD is read only
var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY!
/obj/item/computer_hardware/hard_drive/advanced
@@ -59,108 +59,94 @@
/obj/item/computer_hardware/hard_drive/diagnostics(var/mob/user)
..()
// 999 is a byond limit that is in place. It's unlikely someone will reach that many files anyway, since you would sooner run out of space.
to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999")
to_chat(user, "Storage capacity: [used_capacity]/[max_capacity]GQ")
to_chat(user, SPAN_NOTICE("NT-NFS File Table Status: [stored_files.len]/999"))
to_chat(user, SPAN_NOTICE("Storage capacity: [used_capacity]/[max_capacity]GQ"))
// 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(var/datum/computer_file/F)
if(!F || !istype(F))
return 0
return FALSE
if(!can_store_file(F.size))
return 0
return FALSE
if(!check_functionality())
return 0
return FALSE
if(!stored_files)
return 0
return FALSE
// This file is already stored. Don't store it again.
if(F in stored_files)
return 0
return FALSE
F.holder = src
F.hard_drive = src
stored_files.Add(F)
recalculate_size()
return 1
return TRUE
// 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/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/clientmanager(src)) // Client Manager to Enroll the Device
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/clientmanager(src)) // Client Manager to Enroll the Device
// 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(var/datum/computer_file/F)
if(!F || !istype(F))
return 0
return FALSE
if(!stored_files || read_only)
return 0
return FALSE
if(!check_functionality())
return 0
return FALSE
if(F in stored_files)
stored_files -= F
recalculate_size()
return 1
return TRUE
else
return 0
return FALSE
// Loops through all stored files and recalculates used_capacity of this drive
/obj/item/computer_hardware/hard_drive/proc/recalculate_size()
var/total_size = 0
for(var/datum/computer_file/F in stored_files)
total_size += F.size
used_capacity = total_size
// Checks whether file can be stored on the hard drive.
/obj/item/computer_hardware/hard_drive/proc/can_store_file(var/size = 1)
/obj/item/computer_hardware/hard_drive/proc/can_store_file(var/size = TRUE)
// In the unlikely event someone manages to create that many files.
// BYOND is acting weird with numbers above 999 in loops (infinite loop prevention)
if(read_only)
return 0
return FALSE
if(stored_files.len >= 999)
return 0
return FALSE
if(used_capacity + size > max_capacity)
return 0
return FALSE
else
return 1
return TRUE
// Checks whether we can store the file. 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/try_store_file(var/datum/computer_file/F)
if(!F || !istype(F))
return 0
return FALSE
var/name = F.filename + "." + F.filetype
for(var/datum/computer_file/file in stored_files)
if((file.filename + "." + file.filetype) == name)
return 0
return FALSE
return can_store_file(F.size)
// Tries to find the file by filename. Returns null on failure
/obj/item/computer_hardware/hard_drive/proc/find_file_by_name(var/filename)
if(!check_functionality())
return null
if(!filename)
return null
if(!stored_files)
return null
for(var/datum/computer_file/F in stored_files)
if(F.filename == filename)
return F
return null
/obj/item/computer_hardware/hard_drive/Destroy()
if(holder2 && (holder2.hard_drive == src))
holder2.hard_drive = null
if(parent_computer?.hard_drive == src)
parent_computer.hard_drive = null
stored_files = null
return ..()
@@ -183,6 +169,6 @@
/obj/item/computer_hardware/hard_drive/attackby(obj/item/W, mob/living/user)
if(istype(W, /obj/item/card/tech_support))
reset_drive()
to_chat(user, span("notice", "Drive successfully reset."))
to_chat(user, SPAN_NOTICE("Drive successfully reset."))
else
..()

View File

@@ -2,87 +2,85 @@
name = "Hardware"
desc = "Unknown Hardware."
icon = 'icons/obj/modular_components.dmi'
var/obj/item/modular_computer/holder2 = null
var/obj/item/modular_computer/parent_computer
var/power_usage = 0 // If the hardware uses extra power, change this.
var/enabled = 1 // If the hardware is turned off set this to 0.
var/critical = 1 // Prevent disabling for important component, like the HDD.
var/enabled = TRUE // If the hardware is turned off set this to 0.
var/critical = TRUE // Prevent disabling for important component, like the HDD.
var/hardware_size = 1 // Limits which devices can contain this component. 1: Tablets/Laptops/Consoles, 2: Laptops/Consoles, 3: Consoles only
var/damage = 0 // Current damage level
var/max_damage = 100 // Maximal damage level.
var/damage_malfunction = 20 // "Malfunction" threshold. When damage exceeds this value the hardware piece will semi-randomly fail and do !!FUN!! things
var/damage_failure = 50 // "Failure" threshold. When damage exceeds this value the hardware piece will not work at all.
var/malfunction_probability = 10// Chance of malfunction when the component is damaged
var/malfunction_probability = 10 // Chance of malfunction when the component is damaged
/obj/item/computer_hardware/attackby(var/obj/item/W as obj, var/mob/living/user as mob)
/obj/item/computer_hardware/attackby(obj/item/W, mob/living/user)
// Multitool. Runs diagnostics
if(W.ismultitool())
to_chat(user, "***** DIAGNOSTICS REPORT *****")
to_chat(user, SPAN_NOTICE("***** DIAGNOSTICS REPORT *****"))
diagnostics(user)
to_chat(user, "******************************")
to_chat(user, SPAN_NOTICE("******************************"))
return 1
// Nanopaste. Repair all damage if present for a single unit.
var/obj/item/stack/S = W
if(istype(S, /obj/item/stack/nanopaste))
if(!damage)
to_chat(user, "\The [src] doesn't seem to require repairs.")
return 1
to_chat(user, SPAN_WARNING("\The [src] doesn't seem to require repairs."))
return TRUE
if(S.use(1))
to_chat(user, "You apply a bit of \the [W] to \the [src]. It immediately repairs all damage.")
to_chat(user, SPAN_NOTICE("You apply a bit of \the [W] to \the [src], repairing it fully."))
damage = 0
return 1
return TRUE
// Cable coil. Works as repair method, but will probably require multiple applications and more cable.
if(S.iscoil())
if(!damage)
to_chat(user, "\The [src] doesn't seem to require repairs.")
return 1
to_chat(user, SPAN_WARNING("\The [src] doesn't seem to require repairs."))
return TRUE
if(S.use(1))
to_chat(user, "You patch up \the [src] with a bit of \the [W].")
to_chat(user, SPAN_NOTICE("You patch up \the [src] with a bit of \the [W]."))
take_damage(-10)
return 1
return TRUE
return ..()
// Called on multitool click, prints diagnostic information to the user.
/obj/item/computer_hardware/proc/diagnostics(var/mob/user)
to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]")
to_chat(user, SPAN_NOTICE("Hardware Integrity Test... (Physical Damage: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]"))
/obj/item/computer_hardware/Initialize()
. = ..()
w_class = hardware_size
if(istype(loc, /obj/item/modular_computer))
holder2 = loc
parent_computer = loc
return .
/obj/item/computer_hardware/Destroy()
holder2 = null
parent_computer = null
return ..()
// Handles damage checks
/obj/item/computer_hardware/proc/check_functionality()
// Turned off
if(!enabled)
return 0
return FALSE
// Too damaged to work at all.
if(damage > damage_failure)
return 0
return FALSE
// Still working. Well, sometimes...
if(damage > damage_malfunction)
if(prob(malfunction_probability))
return 0
return FALSE
// Good to go.
return 1
return TRUE
/obj/item/computer_hardware/examine(var/mob/user)
. = ..()
if(damage > damage_failure)
to_chat(user, "<span class='danger'>It seems to be severely damaged!</span>")
to_chat(user, SPAN_DANGER("It seems to be severely damaged!"))
else if(damage > damage_malfunction)
to_chat(user, "<span class='notice'>It seems to be damaged!</span>")
to_chat(user, SPAN_WARNING("It seems to be damaged!"))
else if(damage)
to_chat(user, "It seems to be slightly damaged.")
to_chat(user, SPAN_WARNING("It seems to be slightly damaged."))
// Damages the component. Contains necessary checks. Negative damage "heals" the component.
/obj/item/computer_hardware/proc/take_damage(var/amount)
damage += round(amount) // We want nice rounded numbers here.
damage = between(0, damage, max_damage) // Clamp the value.

View File

@@ -3,7 +3,7 @@
desc = "Small integrated printer with paper recycling module."
power_usage = 50
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
critical = 0
critical = FALSE
icon_state = "printer"
hardware_size = 1
var/stored_paper = 5
@@ -11,20 +11,20 @@
/obj/item/computer_hardware/nano_printer/diagnostics(var/mob/user)
..()
to_chat(user, "Paper buffer level: [stored_paper]/[max_paper]")
to_chat(user, SPAN_NOTICE("Paper Buffer Level: [stored_paper]/[max_paper]"))
/obj/item/computer_hardware/nano_printer/proc/print_text(var/text_to_print, var/paper_title = null, var/paper_color = null)
if(!stored_paper)
return 0
return FALSE
if(!enabled)
return 0
return FALSE
if(!check_functionality())
return 0
return FALSE
// Damaged printer causes the resulting paper to be somewhat harder to read.
if(damage > damage_malfunction)
text_to_print = stars(text_to_print, 100-malfunction_probability)
var/obj/item/paper/P = new /obj/item/paper(get_turf(holder2),text_to_print, paper_title)
var/obj/item/paper/P = new /obj/item/paper(get_turf(parent_computer),text_to_print, paper_title)
P.info = text_to_print
if (paper_color)
P.color = paper_color
@@ -32,18 +32,19 @@
stored_paper--
return P
/obj/item/computer_hardware/nano_printer/attackby(obj/item/W as obj, mob/user as mob)
/obj/item/computer_hardware/nano_printer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/paper))
if(stored_paper >= max_paper)
to_chat(user, "You try to add \the [W] into [src], but it's paper bin is full")
to_chat(user, SPAN_WARNING("You try to add \the [W] to the [src], but its paper bin is full."))
return
to_chat(user, "You insert \the [W] into [src].")
to_chat(user, SPAN_NOTICE("You insert \the [W] into [src]."))
qdel(W)
stored_paper++
else
..()
/obj/item/computer_hardware/nano_printer/Destroy()
if(holder2 && (holder2.nano_printer == src))
holder2.nano_printer = null
holder2 = null
if(parent_computer?.nano_printer == src)
parent_computer.nano_printer = null
parent_computer = null
return ..()

View File

@@ -1,29 +1,29 @@
var/global/ntnet_card_uid = 1
/obj/item/computer_hardware/network_card/
/obj/item/computer_hardware/network_card
name = "basic NTNet network card"
desc = "A basic network card for usage with standard NTNet frequencies."
power_usage = 50
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 1)
critical = 0
critical = FALSE
icon_state = "netcard_basic"
hardware_size = 1
var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user.
var/identification_id // Identification ID. Technically MAC address of this device. Can't be changed by user.
var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user.
var/long_range = 0
var/ethernet = 0 // Hard-wired, therefore always on, ignores NTNet wireless checks.
var/long_range = FALSE
var/ethernet = FALSE // Hard-wired, therefore always on, ignores NTNet wireless checks.
malfunction_probability = 1
/obj/item/computer_hardware/network_card/diagnostics(var/mob/user)
/obj/item/computer_hardware/network_card/diagnostics(mob/user)
..()
to_chat(user, "NIX Unique ID: [identification_id]")
to_chat(user, "NIX User Tag: [identification_string]")
to_chat(user, "Supported protocols:")
to_chat(user, "511.m SFS (Subspace) - Standard Frequency Spread")
to_chat(user, SPAN_NOTICE("NIX Unique ID: [identification_id]"))
to_chat(user, SPAN_NOTICE("NIX User Tag: [identification_string]"))
to_chat(user, SPAN_NOTICE("Supported protocols:"))
to_chat(user, SPAN_NOTICE("511.m SFS (Subspace) - Standard Frequency Spread"))
if(long_range)
to_chat(user, "511.n WFS/HB (Subspace) - Wide Frequency Spread/High Bandiwdth")
to_chat(user, SPAN_NOTICE("511.n WFS/HB (Subspace) - Wide Frequency Spread/High Bandwidth"))
if(ethernet)
to_chat(user, "OpenEth (Physical Connection) - Physical network connection port")
to_chat(user, SPAN_NOTICE("OpenEth (Physical Connection) - Physical Network Connection Port"))
/obj/item/computer_hardware/network_card/Initialize()
. = ..()
@@ -32,8 +32,8 @@ var/global/ntnet_card_uid = 1
/obj/item/computer_hardware/network_card/advanced
name = "advanced NTNet network card"
desc = "An advanced network card for usage with standard NTNet frequencies. It's transmitter is strong enough to connect even off-station."
long_range = 1
desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station."
long_range = TRUE
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 2)
power_usage = 150 // Better range but higher power usage.
icon_state = "netcard_advanced"
@@ -42,41 +42,31 @@ var/global/ntnet_card_uid = 1
/obj/item/computer_hardware/network_card/wired
name = "wired NTNet network card"
desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection."
ethernet = 1
ethernet = TRUE
origin_tech = list(TECH_DATA = 5, TECH_ENGINEERING = 3)
power_usage = 150 // Better range but higher power usage.
icon_state = "netcard_ethernet"
hardware_size = 3
/obj/item/computer_hardware/network_card/Destroy()
if(holder2 && (holder2.network_card == src))
holder2.network_card = null
holder2 = null
return ..()
// Returns a string identifier of this network card
/obj/item/computer_hardware/network_card/proc/get_network_tag()
return "[identification_string] (NID [identification_id])"
// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection
/obj/item/computer_hardware/network_card/proc/get_signal(var/specific_action = 0)
if(!holder2) // Hardware is not installed in anything. No signal. How did this even get called?
if(!parent_computer) // Hardware is not installed in anything. No signal. How did this even get called?
return 0
if(!enabled)
return 0
if(!check_functionality())
return 0
if(ethernet) // Computer is connected via wired connection.
return 3
if(!ntnet_global || !ntnet_global.check_function(specific_action)) // NTNet is down and we are not connected via wired connection. No signal.
return 0
if(holder2)
var/turf/T = get_turf(holder2)
if(parent_computer)
var/turf/T = get_turf(parent_computer)
if((T && istype(T)) && isStationLevel(T.z))
// Computer is on station. Low/High signal depending on what type of network card you have
if(long_range)
@@ -90,6 +80,7 @@ var/global/ntnet_card_uid = 1
return 0 // Computer is not on station and does not have upgraded network card. No signal.
/obj/item/computer_hardware/network_card/Destroy()
if(holder2 && (holder2.network_card == src))
holder2.network_card = null
if(parent_computer?.network_card == src)
parent_computer.network_card = null
parent_computer = null
return ..()

View File

@@ -1,5 +1,5 @@
// These are basically USB data sticks and may be used to transfer files between devices
/obj/item/computer_hardware/hard_drive/portable/
/obj/item/computer_hardware/hard_drive/portable
name = "basic data crystal"
desc = "Small crystal with imprinted photonic circuits that can be used to store data. Its capacity is 16 GQ."
power_usage = 10

View File

@@ -12,10 +12,8 @@
if(prog.available_on_ntnet)
store_file(prog)
/obj/item/computer_hardware/hard_drive/portable/backup
var/_program = null //Change that far to the file name of the backup program you would like to spawn
var/_program //Change that far to the file name of the backup program you would like to spawn
origin_tech = list() //Nope, no research levels from backup disks
/obj/item/computer_hardware/hard_drive/portable/backup/New(loc, var/prog_name)
@@ -33,18 +31,17 @@
return
max_capacity = PRG.size // Set the capacity of the backup disk to the capacity of the program
store_file(PRG)
read_only = 1
read_only = TRUE
desc = "A read-only backup storage crystal containing a backup of the following software: [PRG.filename]"
name = "[PRG.filename] backup crystal"
/obj/structure/closet/crate/software_backup
desc = "A crate containing a backup of all the NT Software available"
desc = "A crate containing a backup of all the NT Software available."
name = "Backup Software Crate"
/obj/structure/closet/crate/software_backup/Initialize()
. = ..()
for(var/F in typesof(/datum/computer_file/program))
for(var/F in subtypesof(/datum/computer_file/program))
var/datum/computer_file/program/prog = new F
// Invalid type (shouldn't be possible but just in case), invalid filetype (not executable program) or invalid filename (unset program)
if(!prog || !istype(prog) || prog.filename == "UnknownProgram" || prog.filetype != "PRG")

View File

@@ -7,7 +7,6 @@
icon_state = "cpu_normal"
hardware_size = 2
power_usage = 75
critical = 1
malfunction_probability = 1
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2)

View File

@@ -1,15 +1,13 @@
/obj/item/computer_hardware/tesla_link
name = "tesla link"
desc = "An advanced tesla link that wirelessly recharges connected device from nearby area power controller."
critical = 0
enabled = 1
critical = FALSE
icon_state = "teslalink"
hardware_size = 3
origin_tech = list(TECH_DATA = 2, TECH_POWER = 3, TECH_ENGINEERING = 2)
var/obj/machinery/modular_computer/holder
var/passive_charging_rate = 250 // W
/obj/item/computer_hardware/tesla_link/Destroy()
if(holder2 && (holder2.tesla_link == src))
holder2.tesla_link = null
if(parent_computer?.tesla_link == src)
parent_computer.tesla_link = null
return ..()

View File

@@ -5,13 +5,12 @@
desc = "A vending machine with microfabricator capable of dispensing various NT-branded computers."
icon = 'icons/obj/vending.dmi'
icon_state = "robotics"
layer = 2.9
anchored = 1
density = 1
anchored = TRUE
density = TRUE
// The actual laptop/tablet
var/obj/item/modular_computer/laptop/fabricated_laptop = null
var/obj/item/modular_computer/tablet/fabricated_tablet = null
var/obj/item/modular_computer/laptop/fabricated_laptop
var/obj/item/modular_computer/tablet/fabricated_tablet
// Utility vars
var/state = 0 // 0: Select device type, 1: Select loadout, 2: Payment, 3: Thankyou screen
@@ -358,6 +357,3 @@
else // just incase
ping("You cannot pay with this!")
return 0

View File

@@ -0,0 +1,12 @@
author: Geeves
delete-after: True
changes:
- rscadd: "Modular computers have gotten a major clean-up. Many programs and interactions should look prettier and feel smoother now."
- rscadd: "Click dragging most modular computers now open their interface, much like with PDAs."
- rscadd: "The IRC program now outputs messages to your chat log, much like PDA messaging does. For smaller devices, it must be on your person, whilst larger ones have a radius to it. The IRC program must be open, it doesn't have to be active, for it to work."
- tweak: "The size of the antag hacked camera program has been brought way down, to make it worth getting, if you wish to do so."
- rscadd: "Added some new names to the modular computer arcade game."
- tweak: "Suit sensors can now be run on most regular modular computers, no big change in that department."
- rscadd: "Computers now ping when they finish downloading programs, letting you know without needing to check them."