diff --git a/code/modules/modular_computers/NTNet/NTNet.dm b/code/modules/modular_computers/NTNet/NTNet.dm index a925c726e3..6dd5785df9 100644 --- a/code/modules/modular_computers/NTNet/NTNet.dm +++ b/code/modules/modular_computers/NTNet/NTNet.dm @@ -7,6 +7,7 @@ var/global/datum/ntnet/ntnet_global = new() var/list/logs = list() var/list/available_station_software = list() var/list/available_antag_software = list() + var/list/available_news = list() var/list/chat_channels = list() var/list/fileservers = list() // Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly. @@ -32,6 +33,7 @@ var/global/datum/ntnet/ntnet_global = new() relays.Add(R) R.NTNet = src build_software_lists() + build_news_list() add_log("NTNet logging system activated.") // Simplified logging: Adds a log. log_string is mandatory parameter, source is optional. @@ -61,7 +63,7 @@ var/global/datum/ntnet/ntnet_global = new() // 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.is_operational()) + if(R.operable()) operating = 1 break @@ -93,6 +95,15 @@ var/global/datum/ntnet/ntnet_global = new() if(prog.available_on_syndinet) available_antag_software.Add(prog) +// Builds lists that contain downloadable software. +/datum/ntnet/proc/build_news_list() + available_news = list() + for(var/F in typesof(/datum/computer_file/data/news_article/)) + var/datum/computer_file/data/news_article/news = new F(1) + if(news.stored_data) + available_news.Add(news) + + // Attempts to find a downloadable file according to filename var /datum/ntnet/proc/find_ntnet_file_by_name(var/filename) for(var/datum/computer_file/program/P in available_station_software) @@ -145,3 +156,4 @@ var/global/datum/ntnet/ntnet_global = new() + diff --git a/code/modules/modular_computers/NTNet/NTNet_relay.dm b/code/modules/modular_computers/NTNet/NTNet_relay.dm index a73e356622..bd91ab88b3 100644 --- a/code/modules/modular_computers/NTNet/NTNet_relay.dm +++ b/code/modules/modular_computers/NTNet/NTNet_relay.dm @@ -20,8 +20,8 @@ // TODO: Implement more logic here. For now it's only a placeholder. -/obj/machinery/ntnet_relay/proc/is_operational() - if(stat & (BROKEN | NOPOWER | EMPED)) +/obj/machinery/ntnet_relay/operable() + if(!..(EMPED)) return 0 if(dos_failure) return 0 @@ -30,13 +30,13 @@ return 1 /obj/machinery/ntnet_relay/update_icon() - if(is_operational()) + if(operable()) icon_state = "bus" else icon_state = "bus_off" /obj/machinery/ntnet_relay/process() - if(is_operational()) + if(operable()) use_power = 2 else use_power = 1 @@ -113,14 +113,14 @@ if(W.is_screwdriver()) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) panel_open = !panel_open - user << "You [panel_open ? "open" : "close"] the maintenance hatch" + to_chat(user, "You [panel_open ? "open" : "close"] the maintenance hatch") return if(W.is_crowbar()) if(!panel_open) - user << "Open the maintenance panel first." + to_chat(user, "Open the maintenance panel first.") return playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) - user << "You disassemble \the [src]!" + to_chat(user, "You disassemble \the [src]!") for(var/atom/movable/A in component_parts) A.forceMove(src.loc) diff --git a/code/modules/modular_computers/computers/item/modular_computer.dm b/code/modules/modular_computers/computers/item/modular_computer.dm index 2a6a57a1df..225587e2b3 100644 --- a/code/modules/modular_computers/computers/item/modular_computer.dm +++ b/code/modules/modular_computers/computers/item/modular_computer.dm @@ -3,7 +3,7 @@ // consoles and laptops use "procssor" item that is held inside machinery piece /obj/item/modular_computer name = "Modular Microcomputer" - desc = "A small portable microcomputer" + desc = "A small portable microcomputer." var/enabled = 0 // Whether the computer is turned on. var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. @@ -55,27 +55,27 @@ set src in view(1) if(usr.incapacitated() || !istype(usr, /mob/living)) - usr << "You can't do that." + to_chat(usr, "You can't do that.") return if(!Adjacent(usr)) - usr << "You can't reach it." + to_chat(usr, "You can't reach it.") return proc_eject_id(usr) // Eject ID card from computer, if it has ID slot with card inside. /obj/item/modular_computer/verb/eject_usb() - set name = "Eject Portable Device" + set name = "Eject Portable Storage" set category = "Object" set src in view(1) if(usr.incapacitated() || !istype(usr, /mob/living)) - usr << "You can't do that." + to_chat(usr, "You can't do that.") return if(!Adjacent(usr)) - usr << "You can't reach it." + to_chat(usr, "You can't reach it.") return proc_eject_usb(usr) @@ -85,11 +85,11 @@ user = usr if(!card_slot) - user << "\The [src] does not have an ID card slot" + to_chat(user, "\The [src] does not have an ID card slot") return if(!card_slot.stored_card) - user << "There is no card in \the [src]" + to_chat(user, "There is no card in \the [src]") return if(active_program) @@ -101,14 +101,15 @@ card_slot.stored_card.forceMove(get_turf(src)) card_slot.stored_card = null update_uis() - user << "You remove the card from \the [src]" + to_chat(user, "You remove the card from \the [src]") + /obj/item/modular_computer/proc/proc_eject_usb(mob/user) if(!user) user = usr if(!portable_drive) - user << "There is no portable device connected to \the [src]." + to_chat(user, "There is no portable device connected to \the [src].") return uninstall_component(user, portable_drive) @@ -124,19 +125,19 @@ /obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user) if(computer_emagged) - user << "\The [src] was already emagged." + to_chat(user, "\The [src] was already emagged.") return else computer_emagged = 1 - user << "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message." + to_chat(user, "You emag \the [src]. It's screen briefly shows a \"OVERRIDE ACCEPTED: New software downloads available.\" message.") return 1 /obj/item/modular_computer/examine(var/mob/user) ..() if(damage > broken_damage) - user << "It is heavily damaged!" + to_chat(user, "It is heavily damaged!") else if(damage) - user << "It is damaged." + to_chat(user, "It is damaged.") /obj/item/modular_computer/New() START_PROCESSING(SSobj, src) @@ -235,23 +236,23 @@ var/issynth = issilicon(user) // Robots and AIs get different activation messages. if(damage > broken_damage) if(issynth) - user << "You send an activation signal to \the [src], but it responds with an error code. It must be damaged." + to_chat(user, "You send an activation signal to \the [src], but it responds with an error code. It must be damaged.") else - user << "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again." + to_chat(user, "You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.") return if(processor_unit && ((battery_module && battery_module.battery.charge && battery_module.check_functionality()) || check_power_override())) // Battery-run and charged or non-battery but powered by APC. if(issynth) - user << "You send an activation signal to \the [src], turning it on" + to_chat(user, "You send an activation signal to \the [src], turning it on") else - user << "You press the power button and start up \the [src]" + to_chat(user, "You press the power button and start up \the [src]") enabled = 1 update_icon() ui_interact(user) else // Unpowered if(issynth) - user << "You send an activation signal to \the [src] but it does not respond" + to_chat(user, "You send an activation signal to \the [src] but it does not respond") else - user << "You press the power button but \the [src] does not respond" + to_chat(user, "You press the power button but \the [src] does not respond") // Process currently calls handle_power(), may be expanded in future if more things are added. /obj/item/modular_computer/process() @@ -418,7 +419,7 @@ P.kill_program(1) update_uis() - user << "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed." + to_chat(user, "Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.") if( href_list["PC_runprogram"] ) var/prog = href_list["PC_runprogram"] @@ -428,7 +429,7 @@ P = hard_drive.find_file_by_name(prog) if(!P || !istype(P)) // Program not found or it's not executable program. - user << "\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning." + to_chat(user, "\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.") return P.computer = src @@ -445,11 +446,11 @@ return if(idle_threads.len >= processor_unit.max_idle_programs+1) - user << "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error" + to_chat(user, "\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error") return if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet. - user << "\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning." + to_chat(user, "\The [src]'s screen shows \"NETWORK ERROR - Unable to connect to NTNet. Please retry. If problem persists contact your system administrator.\" warning.") return if(P.run_program(user)) @@ -493,17 +494,17 @@ if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it. var/obj/item/weapon/card/id/I = W if(!card_slot) - user << "You try to insert \the [I] into \the [src], but it does not have an ID card slot installed." + to_chat(user, "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) - user << "You try to insert \the [I] into \the [src], but it's ID card slot is occupied." + 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) card_slot.stored_card = I I.forceMove(src) update_uis() - user << "You insert \the [I] into \the [src]." + to_chat(user, "You insert \the [I] into \the [src].") return if(istype(W, /obj/item/weapon/paper)) if(!nano_printer) @@ -514,11 +515,11 @@ if(C.hardware_size <= max_hardware_size) try_install_component(user, C) else - user << "This component is too large for \the [src]." + to_chat(user, "This component is too large for \the [src].") if(W.is_wrench()) var/list/components = get_all_components() if(components.len) - user << "Remove all components from \the [src] before disassembling it." + to_chat(user, "Remove all components from \the [src] before disassembling it.") return new /obj/item/stack/material/steel( get_turf(src.loc), steel_sheet_cost ) src.visible_message("\The [src] has been disassembled by [user].") @@ -528,23 +529,23 @@ if(istype(W, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/WT = W if(!WT.isOn()) - user << "\The [W] is off." + to_chat(user, "\The [W] is off.") return if(!damage) - user << "\The [src] does not require repairs." + to_chat(user, "\The [src] does not require repairs.") return - user << "You begin repairing damage to \the [src]..." + to_chat(user, "You begin repairing damage to \the [src]...") if(WT.remove_fuel(round(damage/75)) && do_after(usr, damage/10)) damage = 0 - user << "You repair \the [src]." + to_chat(user, "You repair \the [src].") return if(W.is_screwdriver()) var/list/all_components = get_all_components() if(!all_components.len) - user << "This device doesn't have any components installed." + to_chat(user, "This device doesn't have any components installed.") return var/list/component_names = list() for(var/obj/item/weapon/computer_hardware/H in all_components) @@ -578,48 +579,48 @@ // "USB" flash drive. if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable)) if(portable_drive) - user << "This computer's portable drive slot is already occupied by \the [portable_drive]." + to_chat(user, "This computer's portable drive slot is already occupied by \the [portable_drive].") return found = 1 portable_drive = H else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive)) if(hard_drive) - user << "This computer's hard drive slot is already occupied by \the [hard_drive]." + to_chat(user, "This computer's hard drive slot is already occupied by \the [hard_drive].") return found = 1 hard_drive = H else if(istype(H, /obj/item/weapon/computer_hardware/network_card)) if(network_card) - user << "This computer's network card slot is already occupied by \the [network_card]." + to_chat(user, "This computer's network card slot is already occupied by \the [network_card].") return found = 1 network_card = H else if(istype(H, /obj/item/weapon/computer_hardware/nano_printer)) if(nano_printer) - user << "This computer's nano printer slot is already occupied by \the [nano_printer]." + to_chat(user, "This computer's nano printer slot is already occupied by \the [nano_printer].") return found = 1 nano_printer = H else if(istype(H, /obj/item/weapon/computer_hardware/card_slot)) if(card_slot) - user << "This computer's card slot is already occupied by \the [card_slot]." + to_chat(user, "This computer's card slot is already occupied by \the [card_slot].") return found = 1 card_slot = H else if(istype(H, /obj/item/weapon/computer_hardware/battery_module)) if(battery_module) - user << "This computer's battery slot is already occupied by \the [battery_module]." + to_chat(user, "This computer's battery slot is already occupied by \the [battery_module].") return found = 1 battery_module = H else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit)) if(processor_unit) - user << "This computer's processor slot is already occupied by \the [processor_unit]." + to_chat(user, "This computer's processor slot is already occupied by \the [processor_unit].") return found = 1 processor_unit = H if(found) - user << "You install \the [H] into \the [src]" + to_chat(user, "You install \the [H] into \the [src]") H.holder2 = src user.drop_from_inventory(H) H.forceMove(src) @@ -651,12 +652,12 @@ critical = 1 if(found) if(user) - user << "You remove \the [H] from \the [src]." + to_chat(user, "You remove \the [H] from \the [src].") H.forceMove(get_turf(src)) H.holder2 = null if(critical && enabled) if(user) - user << "\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." + to_chat(user, "\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.") shutdown_computer() update_icon() @@ -783,4 +784,4 @@ if(active_program) return active_program.check_eye(user) else - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm index 86bd00f9c2..6b77dfb3ee 100644 --- a/code/modules/modular_computers/computers/item/processor.dm +++ b/code/modules/modular_computers/computers/item/processor.dm @@ -30,9 +30,9 @@ /obj/item/modular_computer/processor/examine(var/mob/user) if(damage > broken_damage) - user << "It is heavily damaged!" + to_chat(user, "It is heavily damaged!") else if(damage) - user << "It is damaged." + to_chat(user, "It is damaged.") // Power interaction is handled by our machinery part, due to machinery having APC connection. /obj/item/modular_computer/processor/handle_power() @@ -98,7 +98,7 @@ /obj/item/modular_computer/processor/try_install_component(var/mob/living/user, var/obj/item/weapon/computer_hardware/H, var/found = 0) if(istype(H, /obj/item/weapon/computer_hardware/tesla_link)) if(machinery_computer.tesla_link) - user << "This computer's tesla link slot is already occupied by \the [machinery_computer.tesla_link]." + to_chat(user, "This computer's tesla link slot is already occupied by \the [machinery_computer.tesla_link].") return var/obj/item/weapon/computer_hardware/tesla_link/L = H L.holder = machinery_computer @@ -130,4 +130,4 @@ // If we have a tesla link on our machinery counterpart, enable it automatically. Lets computer without a battery work. if(machinery_computer && machinery_computer.tesla_link) machinery_computer.tesla_link.enabled = 1 - ..() \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index 2154b83e54..2b02f58696 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -6,5 +6,5 @@ icon_state_menu = "menu" hardware_flag = PROGRAM_TABLET max_hardware_size = 1 - w_class = 2 - light_strength = 2 // Same as PDAs \ No newline at end of file + w_class = ITEMSIZE_SMALL + light_strength = 2 // Same as PDAs \ No newline at end of file diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm index d9c9905203..86c31b668d 100644 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/tablet_presets.dm @@ -2,7 +2,7 @@ // Available as custom loadout item, this is literally the worst possible cheap tablet /obj/item/modular_computer/tablet/preset/custom_loadout/cheap/New() . = ..() - desc = "A low-end tablet often seen among low ranked station personnel" + desc = "A low-end tablet often seen among low ranked station personnel." processor_unit = new/obj/item/weapon/computer_hardware/processor_unit/small(src) battery_module = new/obj/item/weapon/computer_hardware/battery_module/nano(src) battery_module.charge_to_full() diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 06daed0dda..33d6e54e1a 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -1,8 +1,11 @@ +// Global var to track modular computers +var/list/global_modular_computers = list() + // Modular Computer - device that runs various programs and operates with hardware // DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead. /obj/machinery/modular_computer/ name = "modular computer" - desc = "An advanced computer" + desc = "An advanced computer." var/battery_powered = 0 // Whether computer should be battery powered. It is set automatically use_power = 0 @@ -64,7 +67,7 @@ // Eject ID card from computer, if it has ID slot with card inside. /obj/machinery/modular_computer/verb/eject_usb() - set name = "Eject Portable Device" + set name = "Eject Portable Storage" set category = "Object" set src in view(1) @@ -74,6 +77,7 @@ /obj/machinery/modular_computer/New() ..() cpu = new(src) + global_modular_computers.Add(src) /obj/machinery/modular_computer/Destroy() if(cpu) @@ -162,9 +166,7 @@ /obj/machinery/modular_computer/power_change() if(battery_powered) return - else - ..() - update_icon() + ..() /obj/machinery/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) if(cpu) @@ -194,3 +196,4 @@ if(cpu) return cpu.check_eye(user) return -1 + diff --git a/code/modules/modular_computers/computers/machinery/modular_laptop.dm b/code/modules/modular_computers/computers/machinery/modular_laptop.dm index bce2d5192d..cd0f4ac666 100644 --- a/code/modules/modular_computers/computers/machinery/modular_laptop.dm +++ b/code/modules/modular_computers/computers/machinery/modular_laptop.dm @@ -15,22 +15,22 @@ set src in view(1) if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) - usr << "You can't do that." + to_chat(usr, "You can't do that.") return if(!Adjacent(usr)) - usr << "You can't reach it." + to_chat(usr, "You can't reach it.") return if(!istype(loc,/turf)) - usr << "[src] is too bulky! You'll have to set it down." + to_chat(usr, "[src] is too bulky! You'll have to set it down.") return if(!stored_computer) if(contents.len) for(var/obj/O in contents) O.forceMove(src.loc) - usr << "\The [src] crumbles to pieces." + to_chat(usr, "\The [src] crumbles to pieces.") spawn(5) qdel(src) return @@ -41,7 +41,7 @@ if(stored_computer.cpu) stored_computer.cpu.screen_on = 1 loc = stored_computer - usr << "You open \the [src]." + to_chat(usr, "You open \the [src].") /obj/item/laptop/AltClick() @@ -51,7 +51,7 @@ // The actual laptop /obj/machinery/modular_computer/laptop name = "laptop computer" - desc = "A portable computer" + desc = "A portable computer." var/obj/item/laptop/portable = null // Portable version of this computer, dropped on alt-click to allow transport. Used by laptops. hardware_flag = PROGRAM_LAPTOP icon_state_unpowered = "laptop-open" // Icon state when the computer is turned off @@ -78,11 +78,11 @@ set src in view(1) if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) - usr << "You can't do that." + to_chat(usr, "You can't do that.") return if(!Adjacent(usr)) - usr << "You can't reach it." + to_chat(usr, "You can't reach it.") return close_laptop(usr) @@ -101,10 +101,10 @@ src.forceMove(portable) stat |= MAINT if(user) - user << "You close \the [src]." + to_chat(user, "You close \the [src].") if(cpu) cpu.screen_on = 0 /obj/machinery/modular_computer/laptop/AltClick() if(Adjacent(usr)) - close_laptop() \ No newline at end of file + close_laptop() \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/data.dm b/code/modules/modular_computers/file_system/data.dm index a87ce1ae72..7ad48bea54 100644 --- a/code/modules/modular_computers/file_system/data.dm +++ b/code/modules/modular_computers/file_system/data.dm @@ -3,6 +3,8 @@ /datum/computer_file/data var/stored_data = "" // Stored data in string format. filetype = "DAT" + var/block_size = 250 + var/do_not_edit = 0 // 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 = ..() @@ -10,7 +12,7 @@ return temp // Calculates file size from amount of characters in saved string -/datum/computer_file/data/proc/calculate_size(var/block_size = 250) +/datum/computer_file/data/proc/calculate_size() size = max(1, round(length(stored_data) / block_size)) /datum/computer_file/data/logfile diff --git a/code/modules/modular_computers/file_system/news_article.dm b/code/modules/modular_computers/file_system/news_article.dm new file mode 100644 index 0000000000..2a4a25c7d0 --- /dev/null +++ b/code/modules/modular_computers/file_system/news_article.dm @@ -0,0 +1,21 @@ +// /data/ files store data in string format. +// They don't contain other logic for now. +/datum/computer_file/data/news_article + filetype = "XNML" + filename = "Unknown News Entry" + block_size = 1000 // 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. + 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! + +/datum/computer_file/data/news_article/New(var/load_from_file = 0) + ..() + if(server_file_path && load_from_file) + stored_data = file2text(server_file_path) + calculate_size() + + +// NEWS DEFINITIONS BELOW THIS LINE + +/datum/computer_file/data/news_article/space/vol_one + filename = "SPACE Magazine vol. 1" + server_file_path = 'news_articles/space_magazine_1.html' \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index d3878bd025..21cd6403c4 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -59,7 +59,7 @@ /datum/computer_file/program/proc/is_supported_by_hardware(var/hardware_flag = 0, var/loud = 0, var/mob/user = null) if(!(hardware_flag & usage_flags)) if(loud && computer && user) - user << "\The [computer] flashes an \"Hardware Error - Incompatible software\" warning." + to_chat(user, "\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.") return 0 return 1 @@ -88,13 +88,13 @@ var/obj/item/weapon/card/id/I = user.GetIdCard() if(!I) if(loud) - user << "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning." + to_chat(user, "\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.") return 0 if(access_to_check in I.access) return 1 else if(loud) - user << "\The [computer] flashes an \"Access Denied\" warning." + to_chat(user, "\The [computer] flashes an \"Access Denied\" warning.") // 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. @@ -154,4 +154,4 @@ if(NM) return NM.check_eye(user) else - return -1 \ No newline at end of file + return -1 diff --git a/code/modules/modular_computers/file_system/programs/_program.dm b/code/modules/modular_computers/file_system/programs/_program.dm index 2cba7960c9..149c6e8926 100644 --- a/code/modules/modular_computers/file_system/programs/_program.dm +++ b/code/modules/modular_computers/file_system/programs/_program.dm @@ -7,7 +7,7 @@ /obj/item/modular_computer/initial_data() return get_header_data() -/obj/item/modular_computer/update_layout() +/obj/machinery/modular_computer/update_layout() return TRUE /datum/nano_module/program diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm index a913e3ddf2..44e5fd8cfe 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -24,14 +24,15 @@ dos_speed = NTNETSPEED_ETHERNET * NTNETSPEED_DOS_AMPLIFICATION if(target && executed) target.dos_overload += dos_speed - if(!target.is_operational()) + if(!target.operable()) target.dos_sources.Remove(src) target = null error = "Connection to destination relay lost." /datum/computer_file/program/ntnet_dos/kill_program(var/forced) - target.dos_sources.Remove(src) - target = null + if(target) + target.dos_sources.Remove(src) + target = null executed = 0 ..(forced) diff --git a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm index be69b012b9..2bc063a8eb 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/hacked_camera.dm @@ -24,6 +24,7 @@ /datum/nano_module/camera_monitor/hacked name = "Hacked Camera Monitoring Program" + //available_to_ai = FALSE /datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access) return 1 @@ -33,4 +34,4 @@ networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1))) networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) - return networks \ No newline at end of file + return networks \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/camera.dm b/code/modules/modular_computers/file_system/programs/camera.dm index 939e1b0812..d56c29fdca 100644 --- a/code/modules/modular_computers/file_system/programs/camera.dm +++ b/code/modules/modular_computers/file_system/programs/camera.dm @@ -36,7 +36,7 @@ var/obj/machinery/camera/current_camera = null var/current_network = null -/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) +/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state) var/list/data = host.initial_data() data["current_camera"] = current_camera ? current_camera.nano_structure() : null @@ -92,14 +92,11 @@ return 1 else if(href_list["switch_network"]) - if(!(href_list["switch_network"] in using_map.station_networks)) - return - // Either security access, or access to the specific camera network's department is required in order to access the network. if(can_access_network(usr, get_camera_access(href_list["switch_network"]))) current_network = href_list["switch_network"] else - usr << "\The [nano_host()] shows an \"Network Access Denied\" error message." + to_chat(usr, "\The [nano_host()] shows an \"Network Access Denied\" error message.") return 1 else if(href_list["reset"]) @@ -164,9 +161,10 @@ /datum/nano_module/camera_monitor/ert name = "Advanced Camera Monitoring Program" + //available_to_ai = FALSE // The ERT variant has access to ERT and crescent cams, but still checks for accesses. ERT members should be able to use it. -/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks) +/datum/nano_module/camera_monitor/ert/modify_networks_list(var/list/networks) ..() networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1))) networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 5e012dd902..b8dc33af34 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -141,7 +141,7 @@ contents += " [get_access_desc(A)]" if(!computer.nano_printer.print_text(contents,"access report")) - usr << "Hardware error: Printer was unable to print the file. It may be out of paper." + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") return else computer.visible_message("\The [computer] prints out paper.") @@ -151,7 +151,7 @@ [data_core ? data_core.get_manifest(0) : ""] "} if(!computer.nano_printer.print_text(contents,text("crew manifest ([])", stationtime2text()))) - usr << "Hardware error: Printer was unable to print the file. It may be out of paper." + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") return else computer.visible_message("\The [computer] prints out paper.") @@ -196,7 +196,7 @@ jobdatum = J break if(!jobdatum) - usr << "No log exists for this job: [t1]" + to_chat(usr, "No log exists for this job: [t1]") return access = jobdatum.get_access() diff --git a/code/modules/modular_computers/file_system/programs/comm.dm b/code/modules/modular_computers/file_system/programs/comm.dm index 2fd3639ecc..2089c987f3 100644 --- a/code/modules/modular_computers/file_system/programs/comm.dm +++ b/code/modules/modular_computers/file_system/programs/comm.dm @@ -8,7 +8,7 @@ filedesc = "Command and communications program." program_icon_state = "comm" nanomodule_path = /datum/nano_module/program/comm - extended_desc = "Used to command and control the station. Can relay long-range communications." + extended_desc = "Used to command and control the station. Can relay long-range communications. This program can not be run on tablet computers." required_access = access_heads requires_ntnet = 1 size = 12 @@ -24,6 +24,7 @@ /datum/nano_module/program/comm name = "Command and communications program" + //available_to_ai = TRUE var/current_status = STATE_DEFAULT var/msg_line1 = "" var/msg_line2 = "" @@ -104,13 +105,15 @@ if(..()) return 1 var/mob/user = usr - var/ntn_comm = !!program.get_signal(NTNET_COMMUNICATION) - var/ntn_cont = !!program.get_signal(NTNET_SYSTEMCONTROL) + var/ntn_comm = program ? !!program.get_signal(NTNET_COMMUNICATION) : 1 + var/ntn_cont = program ? !!program.get_signal(NTNET_SYSTEMCONTROL) : 1 var/datum/comm_message_listener/l = obtain_message_listener() switch(href_list["action"]) if("sw_menu") + . = 1 current_status = text2num(href_list["target"]) if("announce") + . = 1 if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) if(user) var/obj/item/weapon/card/id/id_card = user.GetIdCard() @@ -118,31 +121,29 @@ else crew_announcement.announcer = "Unknown" if(announcment_cooldown) - usr << "Please allow at least one minute to pass between announcements" - SSnanoui.update_uis(src) - return + to_chat(usr, "Please allow at least one minute to pass between announcements") + return TRUE var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text if(!input || !can_still_topic()) - SSnanoui.update_uis(src) - return + return 1 crew_announcement.Announce(input) announcment_cooldown = 1 spawn(600)//One minute cooldown announcment_cooldown = 0 if("message") + . = 1 if(href_list["target"] == "emagged") if(program) if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm) if(centcomm_message_cooldown) - usr << "Arrays recycling. Please stand by." + to_chat(usr, "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) if(!input || !can_still_topic()) - SSnanoui.update_uis(src) - return + return 1 Syndicate_announce(input, usr) - usr << "Message transmitted." + to_chat(usr, "Message transmitted.") log_say("[key_name(usr)] has made an illegal announcement: [input]") centcomm_message_cooldown = 1 spawn(300)//30 second cooldown @@ -150,34 +151,35 @@ else if(href_list["target"] == "regular") if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) if(centcomm_message_cooldown) - usr << "Arrays recycling. Please stand by." + to_chat(usr, "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. - usr <<"No Emergency Bluespace Relay detected. Unable to transmit message." - SSnanoui.update_uis(src) - return + to_chat(usr, "No Emergency Bluespace Relay detected. Unable to transmit message.") + return 1 var/input = sanitize(input("Please choose a message to transmit to Centcomm 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) if(!input || !can_still_topic()) - SSnanoui.update_uis(src) - return + return 1 CentCom_announce(input, usr) - usr << "Message transmitted." + to_chat(usr, "Message transmitted.") log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]") centcomm_message_cooldown = 1 spawn(300) //30 second cooldown centcomm_message_cooldown = 0 if("shuttle") + . = 1 if(is_autenthicated(user) && ntn_cont) 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()) call_shuttle_proc(usr) + if(href_list["target"] == "cancel" && !issilicon(usr)) var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes") if(confirm == "Yes" && can_still_topic()) cancel_call_proc(usr) if("setstatus") + . = 1 if(is_autenthicated(user) && ntn_cont) switch(href_list["target"]) if("line1") @@ -194,8 +196,8 @@ post_status("alert", href_list["alert"]) else post_status(href_list["target"]) - if("setalert") + . = 1 if(is_autenthicated(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") @@ -214,9 +216,11 @@ if(SEC_LEVEL_BLUE) feedback_inc("alert_comms_blue",1) else - usr << "You press button, but red light flashes and nothing happens." //This should never happen + to_chat(usr, "You press button, but red light flashes and nothing happens.")//This should never happen + current_status = STATE_DEFAULT if("viewmessage") + . = 1 if(is_autenthicated(user) && ntn_comm) current_viewing_message_id = text2num(href_list["target"]) for(var/list/m in l.messages) @@ -224,18 +228,19 @@ current_viewing_message = m current_status = STATE_VIEWMESSAGE if("delmessage") + . = 1 if(is_autenthicated(user) && ntn_comm && l != global_message_listener) l.Remove(current_viewing_message) current_status = STATE_MESSAGELIST if("printmessage") + . = 1 if(is_autenthicated(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"])) - usr << "Hardware error: Printer was unable to print the file. It may be out of paper." + to_chat(usr, "Hardware error: Printer was unable to print the file. It may be out of paper.") else program.computer.visible_message("\The [program.computer] prints out paper.") - SSnanoui.update_uis(src) /datum/nano_module/program/comm/proc/post_status(var/command, var/data1, var/data2) diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index fd2b935069..a47669662c 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -85,8 +85,16 @@ var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) if(!F || !istype(F)) return 1 - // 16384 is the limit for file length in characters. Currently, papers have value of 2048 so this is 8 times as long, since we can't edit parts of the file independently. - var/newtext = sanitize(html_decode(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", F.stored_data) as message), 16384) + 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 + + var/oldtext = html_decode(F.stored_data) + oldtext = replacetext(oldtext, "\[editorbr\]", "\n") + + var/newtext = sanitize(replacetext(input(usr, "Editing file [open_file]. You may use most tags used in paper formatting:", "Text Editor", oldtext) as message|null, "\n", "\[editorbr\]"), MAX_TEXTFILE_LENGTH) + if(!newtext) + return + if(F) var/datum/computer_file/data/backup = F.clone() HDD.remove_file(F) @@ -235,5 +243,4 @@ ui.auto_update_layout = 1 ui.set_initial_data(data) ui.open() - - +#undef MAX_TEXTFILE_LENGTH \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/game.dm b/code/modules/modular_computers/file_system/programs/game.dm index 42d3e35eac..e947bea365 100644 --- a/code/modules/modular_computers/file_system/programs/game.dm +++ b/code/modules/modular_computers/file_system/programs/game.dm @@ -69,7 +69,7 @@ data["gameover"] = gameover data["information"] = information - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) ui = new(user, src, ui_key, "arcade_classic.tmpl", "Defeat [enemy_name]", 500, 350, state = state) if(host.update_layout()) @@ -148,4 +148,4 @@ player_mana += regen enemy_play() check_gameover() - return 1 \ No newline at end of file + return 1 \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/news_browser.dm b/code/modules/modular_computers/file_system/programs/news_browser.dm new file mode 100644 index 0000000000..42836024c5 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/news_browser.dm @@ -0,0 +1,119 @@ +/datum/computer_file/program/newsbrowser + filename = "newsbrowser" + filedesc = "NTNet/ExoNet News Browser" + extended_desc = "This program may be used to view and download news articles from the network." + program_icon_state = "generic" + size = 8 + requires_ntnet = 1 + available_on_ntnet = 1 + + 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/message = "" + +/datum/computer_file/program/newsbrowser/process_tick() + if(!downloading) + return + download_netspeed = 0 + // Speed defines are found in misc.dm + switch(ntnet_status) + if(1) + download_netspeed = NTNETSPEED_LOWSIGNAL + if(2) + download_netspeed = NTNETSPEED_HIGHSIGNAL + if(3) + 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. + SSnanoui.update_uis(NM) + +/datum/computer_file/program/newsbrowser/kill_program() + ..() + requires_ntnet = 1 + loaded_article = null + download_progress = 0 + downloading = 0 + +/datum/computer_file/program/newsbrowser/Topic(href, href_list) + if(..()) + return 1 + if(href_list["PRG_openarticle"]) + . = 1 + if(downloading || loaded_article) + return 1 + + 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 + break + if(href_list["PRG_reset"]) + . = 1 + downloading = 0 + download_progress = 0 + requires_ntnet = 1 + loaded_article = null + if(href_list["PRG_clearmessage"]) + . = 1 + message = "" + if(href_list["PRG_savearticle"]) + . = 1 + 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 + var/obj/item/weapon/computer_hardware/hard_drive/HDD = computer.hard_drive + if(!HDD) + return 1 + var/datum/computer_file/data/news_article/N = loaded_article.clone() + N.filename = savename + HDD.store_file(N) + if(.) + SSnanoui.update_uis(NM) + + +/datum/nano_module/program/computer_newsbrowser + name = "NTNet/ExoNet News Browser" + +/datum/nano_module/program/computer_newsbrowser/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) + + var/datum/computer_file/program/newsbrowser/PRG + var/list/data = list() + if(program) + data = program.get_header_data() + PRG = program + else + return + + data["message"] = PRG.message + if(PRG.loaded_article && !PRG.downloading) // Viewing an article. + data["title"] = PRG.loaded_article.filename + data["article"] = PRG.loaded_article.stored_data + else if(PRG.downloading) // Downloading an article. + data["download_running"] = 1 + data["download_progress"] = PRG.download_progress + data["download_maxprogress"] = PRG.loaded_article.size + data["download_rate"] = PRG.download_netspeed + else // Viewing list of articles + var/list/all_articles[0] + for(var/datum/computer_file/data/news_article/F in ntnet_global.available_news) + all_articles.Add(list(list( + "name" = F.filename, + "size" = F.size, + "uid" = F.uid + ))) + data["all_articles"] = all_articles + + 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.set_initial_data(data) + ui.open() diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index 9400ad538e..ed3b37ac64 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -11,6 +11,7 @@ /datum/nano_module/computer_ntnetmonitor name = "NTNet Diagnostics and Monitoring" + //available_to_ai = TRUE /datum/nano_module/computer_ntnetmonitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state) if(!ntnet_global) diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index f14d99e115..f77aa386b5 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -51,14 +51,18 @@ // This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. /obj/item/weapon/computer_hardware/battery_module/lambda name = "lambda coil" - desc = "A very complex device that creates it's own bluespace dimension. This dimension may be used to store massive amounts of energy." + desc = "A very complex power source compatible with various computers. It is capable of providing power for nearly unlimited duration." icon_state = "battery_lambda" hardware_size = 1 - battery_rating = 1000000 + battery_rating = 30000 + +/obj/item/weapon/computer_hardware/battery_module/lambda/New() + ..() + battery = new/obj/item/weapon/cell/infinite(src) /obj/item/weapon/computer_hardware/battery_module/diagnostics(var/mob/user) ..() - user << "Internal battery charge: [battery.charge]/[battery.maxcharge] CU" + to_chat(user, "Internal battery charge: [battery.charge]/[battery.maxcharge] CU") /obj/item/weapon/computer_hardware/battery_module/New() battery = new/obj/item/weapon/cell(src) @@ -68,4 +72,4 @@ /obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full() if(battery) - battery.charge = battery.maxcharge \ No newline at end of file + battery.charge = battery.maxcharge \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 3699eaedcd..93cbf8526d 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -58,8 +58,8 @@ /obj/item/weapon/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. - user << "NT-NFS File Table Status: [stored_files.len]/999" - user << "Storage capacity: [used_capacity]/[max_capacity]GQ" + to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999") + to_chat(user, "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/weapon/computer_hardware/hard_drive/proc/store_file(var/datum/computer_file/F) @@ -164,4 +164,4 @@ /obj/item/weapon/computer_hardware/hard_drive/New() install_default_programs() - ..() \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/hardware.dm b/code/modules/modular_computers/hardware/hardware.dm index 43c7dbc4dc..7cd79ceb09 100644 --- a/code/modules/modular_computers/hardware/hardware.dm +++ b/code/modules/modular_computers/hardware/hardware.dm @@ -1,6 +1,6 @@ /obj/item/weapon/computer_hardware/ name = "Hardware" - desc = "Unknown Hardware" + desc = "Unknown Hardware." icon = 'icons/obj/modular_components.dmi' var/obj/item/modular_computer/holder2 = null var/power_usage = 0 // If the hardware uses extra power, change this. @@ -16,27 +16,27 @@ /obj/item/weapon/computer_hardware/attackby(var/obj/item/W as obj, var/mob/living/user as mob) // Multitool. Runs diagnostics if(istype(W, /obj/item/device/multitool)) - user << "***** DIAGNOSTICS REPORT *****" + to_chat(user, "***** DIAGNOSTICS REPORT *****") diagnostics(user) - user << "******************************" + to_chat(user, "******************************") 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) - user << "\The [src] doesn't seem to require repairs." + to_chat(user, "\The [src] doesn't seem to require repairs.") return 1 if(S.use(1)) - user << "You apply a bit of \the [W] to \the [src]. It immediately repairs all damage." + to_chat(user, "You apply a bit of \the [W] to \the [src]. It immediately repairs all damage.") damage = 0 return 1 // Cable coil. Works as repair method, but will probably require multiple applications and more cable. if(istype(S, /obj/item/stack/cable_coil)) if(!damage) - user << "\The [src] doesn't seem to require repairs." + to_chat(user, "\The [src] doesn't seem to require repairs.") return 1 if(S.use(1)) - user << "You patch up \the [src] with a bit of \the [W]." + to_chat(user, "You patch up \the [src] with a bit of \the [W].") take_damage(-10) return 1 return ..() @@ -44,7 +44,7 @@ // Called on multitool click, prints diagnostic information to the user. /obj/item/weapon/computer_hardware/proc/diagnostics(var/mob/user) - user << "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]" + to_chat(user, "Hardware Integrity Test... (Corruption: [damage]/[max_damage]) [damage > damage_failure ? "FAIL" : damage > damage_malfunction ? "WARN" : "PASS"]") /obj/item/weapon/computer_hardware/New(var/obj/L) w_class = hardware_size @@ -76,13 +76,14 @@ /obj/item/weapon/computer_hardware/examine(var/mob/user) . = ..() if(damage > damage_failure) - user << "It seems to be severely damaged!" + to_chat(user, "It seems to be severely damaged!") else if(damage > damage_malfunction) - user << "It seems to be damaged!" + to_chat(user, "It seems to be damaged!") else if(damage) - user << "It seems to be slightly damaged." + to_chat(user, "It seems to be slightly damaged.") // Damages the component. Contains necessary checks. Negative damage "heals" the component. /obj/item/weapon/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. + diff --git a/code/modules/modular_computers/hardware/nano_printer.dm b/code/modules/modular_computers/hardware/nano_printer.dm index 11caa79794..996d2dfb62 100644 --- a/code/modules/modular_computers/hardware/nano_printer.dm +++ b/code/modules/modular_computers/hardware/nano_printer.dm @@ -2,6 +2,7 @@ name = "nano printer" desc = "Small integrated printer with paper recycling module." power_usage = 50 + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) critical = 0 icon_state = "printer" hardware_size = 1 @@ -10,7 +11,7 @@ /obj/item/weapon/computer_hardware/nano_printer/diagnostics(var/mob/user) ..() - user << "Paper buffer level: [stored_paper]/[max_paper]" + to_chat(user, "Paper buffer level: [stored_paper]/[max_paper]") /obj/item/weapon/computer_hardware/nano_printer/proc/print_text(var/text_to_print, var/paper_title = null) if(!stored_paper) @@ -20,27 +21,21 @@ if(!check_functionality()) return 0 - var/obj/item/weapon/paper/P = new/obj/item/weapon/paper(get_turf(holder2)) - // Damaged printer causes the resulting paper to be somewhat harder to read. if(damage > damage_malfunction) - P.info = stars(text_to_print, 100-malfunction_probability) - else - P.info = text_to_print - if(paper_title) - P.name = paper_title - P.update_icon() + text_to_print = stars(text_to_print, 100-malfunction_probability) + new/obj/item/weapon/paper(get_turf(holder2),text_to_print, paper_title) + stored_paper-- - P = null return 1 /obj/item/weapon/computer_hardware/nano_printer/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/paper)) if(stored_paper >= max_paper) - user << "You try to add \the [W] into [src], but it's paper bin is full" + to_chat(user, "You try to add \the [W] into [src], but it's paper bin is full") return - user << "You insert \the [W] into [src]." + to_chat(user, "You insert \the [W] into [src].") qdel(W) stored_paper++ @@ -48,4 +43,4 @@ if(holder2 && (holder2.nano_printer == src)) holder2.nano_printer = null holder2 = null - ..() \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index 8ffc802dbd..01c9167c19 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -16,14 +16,14 @@ var/global/ntnet_card_uid = 1 /obj/item/weapon/computer_hardware/network_card/diagnostics(var/mob/user) ..() - user << "NIX Unique ID: [identification_id]" - user << "NIX User Tag: [identification_string]" - user << "Supported protocols:" - user << "511.m SFS (Subspace) - Standard Frequency Spread" + 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") if(long_range) - user << "511.n WFS/HB (Subspace) - Wide Frequency Spread/High Bandiwdth" + to_chat(user, "511.n WFS/HB (Subspace) - Wide Frequency Spread/High Bandiwdth") if(ethernet) - user << "OpenEth (Physical Connection) - Physical network connection port" + to_chat(user, "OpenEth (Physical Connection) - Physical network connection port") /obj/item/weapon/computer_hardware/network_card/New(var/l) ..(l) diff --git a/code/modules/modular_computers/hardware/portable_hard_drive.dm b/code/modules/modular_computers/hardware/portable_hard_drive.dm index 7e86cba6ca..b6b42a51c8 100644 --- a/code/modules/modular_computers/hardware/portable_hard_drive.dm +++ b/code/modules/modular_computers/hardware/portable_hard_drive.dm @@ -1,7 +1,7 @@ // These are basically USB data sticks and may be used to transfer files between devices /obj/item/weapon/computer_hardware/hard_drive/portable/ name = "basic data crystal" - desc = "Small crystal with imprinted photonic circuits that can be used to store data. It's capacity is 16 GQ" + desc = "Small crystal with imprinted photonic circuits that can be used to store data. Its capacity is 16 GQ." power_usage = 10 icon_state = "flashdrive_basic" hardware_size = 1 @@ -10,7 +10,7 @@ /obj/item/weapon/computer_hardware/hard_drive/portable/advanced name = "advanced data crystal" - desc = "Small crystal with imprinted high-density photonic circuits that can be used to store data. It's capacity is 64 GQ" + desc = "Small crystal with imprinted high-density photonic circuits that can be used to store data. Its capacity is 64 GQ." power_usage = 20 icon_state = "flashdrive_advanced" hardware_size = 1 @@ -19,7 +19,7 @@ /obj/item/weapon/computer_hardware/hard_drive/portable/super name = "super data crystal" - desc = "Small crystal with imprinted ultra-density photonic circuits that can be used to store data. It's capacity is 256 GQ" + desc = "Small crystal with imprinted ultra-density photonic circuits that can be used to store data. Its capacity is 256 GQ." power_usage = 40 icon_state = "flashdrive_super" hardware_size = 1 @@ -29,4 +29,4 @@ /obj/item/weapon/computer_hardware/hard_drive/portable/New() ..() stored_files = list() - recalculate_size() \ No newline at end of file + recalculate_size() \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/processor_unit.dm b/code/modules/modular_computers/hardware/processor_unit.dm index d84bd1fc01..8f9009f72b 100644 --- a/code/modules/modular_computers/hardware/processor_unit.dm +++ b/code/modules/modular_computers/hardware/processor_unit.dm @@ -38,4 +38,4 @@ hardware_size = 1 power_usage = 75 max_idle_programs = 2 - origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) \ No newline at end of file + origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/tesla_link.dm b/code/modules/modular_computers/hardware/tesla_link.dm index 9b9d87738b..5296f0e120 100644 --- a/code/modules/modular_computers/hardware/tesla_link.dm +++ b/code/modules/modular_computers/hardware/tesla_link.dm @@ -17,4 +17,4 @@ /obj/item/weapon/computer_hardware/tesla_link/Destroy() if(holder && (holder.tesla_link == src)) holder.tesla_link = null - ..() \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index a7ed86a207..49eb797994 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -5,7 +5,7 @@ desc = "A vending machine with microfabricator capable of dispensing various NT-branded computers" icon = 'icons/obj/vending.dmi' icon_state = "robotics" - layer = 2.9 + layer = OBJ_LAYER - 0.1 anchored = 1 density = 1 diff --git a/nano/templates/news_browser.tmpl b/nano/templates/news_browser.tmpl new file mode 100644 index 0000000000..17b02614f3 --- /dev/null +++ b/nano/templates/news_browser.tmpl @@ -0,0 +1,62 @@ +{{if data.message}} +
+ SPACE Magazine is a new force in Journalism in the 26th Century- bringing news and information to the multitudes of Star Systems settled by Sentient Life, + letting everyone know what’s happening across the Stars, millions of miles away. News if first and foremost our forte, but articles over important + individuals and new developments will also be here in the magazine, which we shall ship out every month with a new issue. This, is our very first issue, + and we hope to continue for many years to come. +
++ In this first issue, we will address a few incidents that have come up as of recent days- a attempted, but disastrous attack by Pirates against the colony + of Onaios Prime, thwarted by the latest in weapons technology. A meteor shower that rained disaster on the colonial world of Brinkburn in the lucrative + system of Nyx, causing many citizens to leave the planet. An attack by terrorists on the colony of Asilliss VII, resulting in many deaths, and the Great + Carp Migrations that have been occurring in recent days in the Nyx System. +
+ + ++ This week, a pirate group that has stolen a SolGov Battlecruiser has attempted to commit a raid with it upon a colony world Onaios Prime, in the Onaios + system. However, it was quickly eradicated along with its escort by a planetside battery of Mass Drivers produced recently by Dawnlight Celestial Defence. + After this incident Dawnlight has registered an influx of demand from other colonies, as their weapons are relatively affordable, registering slight growth + in stock ratings for the first time in 250 years, when the success of Dawnlight even competed with corporations like Hephaestus. We have found a written + account of one of the writers of local news agency, and with their permission are including it in this article. +
++ “It was almost midnight when I was driving around the AURA 2, a new anti-orbital installation, on my way home from my office, after some overtime. I have + heard of its construction project and have never paid much attention to it, the world of Onaios Prime that I live on has always been only moderately + wealthy, and peaceful... until last night. A loud siren played from the complex's direction, breaking the silence of the night. I stopped my vehicle where + an overhang down to the valley let me look at the platform, from 50 meters above it, and about 300 meters away from it, and I saw it for my first time. +
++ A great bunker in the middle was having its windows shut in blast doors, shying away from the reason this is an anti-orbital installation: The jeeps and + trucks that were scurrying to hide in the bunker were but the tiniest little dot, compared to the massive Mass Drivers, that slowly, but so steadily, with + a bass, gentle hum, began towering to the sky, reaching out to it with a barrel so long you would need two loaded semi-trucks to cover the length. The + barrels aligned, and I could still hear the humming, but it started growing stronger, stronger... before one of the barrels sparked inside a few times, and + I was blinded by a vast flash... Only then, the humming cut off, only then, I heard the lightning, and only then, a spiking, overwhelming pitch of + capacitor discharge plummeted to my eardrums, only to be followed by an encroaching thunder of a blastwave, shunting masses of air against me. +
++ Only after a few seconds, I regained my hearing and sight to feel the echoes of the blast, and to see another Mass Driver was discharging, sparking. I + covered the sight of it in time, to see the entire valley was lit for a split second as well as the sun could do, and I heard the discharge again, and I + heard its calling. Every spike, a declaration of freedom. Every thunderblast, a declaration of sovereignty. The Mass Drivers would flash, marking dawn upon + the invaders to signal the humanity made its stand here, and it shall persevere. The warhead that it would expel was our fist that would smite them from + our sky. I did not know who have we fought against at that time, but at that moment, and ever since, I never looked at the night sky the same way again. I + believe that that sky is our home.” -Written by Liun Asitero, Onaios Daily +
+ Written by Lucas Shiito + + ++ One of Nyx's planets, Brinkburn, has had a catastrophe happen in form of a meteor storm three days ago. Nyx has lashed out with a solar corona that, while + having a miniscule effect on traffic and stations, has managed to deflect several asteroids from the belt natively present around Brinkburn. This caused + massive, unsustainable damage to the habitation complexes present on the planet that are occupied by several hundreds of settlers, and given their scarce + material stocks, they had no other choice but to escape, to find another place to survive in. +
++ The situation was further complicated by the very asteroid rings that have started this misfortune; the refugees did not have sufficiently advanced + navigation computers on their pods to steer them safely through the rings. Approximately 20% of population is estimated to have not made it through. The + shuttles that have shipped the settlers on the world in the first place needed to be dismantled and used for scrap to expand the living area, and the more + advanced components were used to wrangle the escape pods together. +
++ Most of the refugees have found their way to Emerald Habitation, a station in Nyx. The station already has issues with over-population and air + purification, and the sudden influx of human settlers has introduced even more problems. Firstly, it has made it much harder to process travelers passing + through, making travel in Nyx either very dangerous through Void Star, or very expensive through NAS Crescent. Secondly, Emerald Habitation has been + housing a large number of Unathi, which have been harassing the refugees, some of them are even a part of the station's security, making appeals to them + only worsen the situation. +
++ We can only hope a new home will be found and built for the poor refugees, and that the Skrell present on station, that are keeping the situation + relatively free of casualties, continue to sustain a safe, if not non-hostile environment on the overpopulated station. +
+ Written by Laura Hunton + + ++ Planet Asilliss VI has been a civil uprising hotspot for a few weeks now, and things have recently yet again escalated. A research facility belonging to + NanoTrasen, one of several to be specific, that specializes on an undisclosed project, has been attacked by a group of masked raiders armed with automatic + weapons, using several buggies for transport. Two hours after the incident, Asilliss Liberation Force claimed responsibility. "Companies like NanoTrasen + are advancing us, but into slavery and containment! Their technology only brings control to the corrupt over the honest people of Asilliss! We cannot stand + idle! Join us and befall those who take our lives from our control!", claimed a man hiding in a shade on video that was sent to a local entertainment + station to be broadcasted under threat of attack. +
++ Up until now, the government's militia has been relatively ineffective at quelling this terrorist cell, while their statistics register a number of arrests + and casualties, the group is still registering influx of recruits. However, NanoTrasen seems to have been highly impacted by this attack, judging from + press release of NanoTrasen, Nyx Division: "As a company, we must maintain our safety standard for our employees, as well as secure our installations. The + continued unrest on Asilliss that is resulting in loss of investments is forcing our hand to resort to particularly prejudicial measures and we are + arranging cooperation with the governmental forces." +
++ We have information from a trusted source, who we shall allow to remain unnamed, that NanoTrasen is arranging a loan to Asiliss in form of acquisition of a + small number of vehicles from Terraphistus Military Armor and small arms shipped all the way from Mars Security Industries, as well as hiring services from + a newly instated PMC, SAARE, to protect other NanoTrasen's installations. We have very little information on SAARE due to its novelty, except that it has + accepted several decorated veterans from various security forces and armies, and specializes on top secret operations. Only time will tell if these + measures shall be taken and how shall they affect the unrest on Asilliss IV, but be sure that we shall provide our readers with full coverage! +
+Written by Johnathan Townsend + + ++ Carp and Pike have plagued space station windows and ship paint jobs for the past hundred years, and while local businesses make money off of eradicating + them by the hundreds, they only seem to increase in number and size. Xenobiologists at Brickburn have come to the conclusion that that these pests most + likely came from Erebus. "Was really hard to figure out at first," says researcher Gregory Hills, "They really like to, you know, bite things. But once we + got a few hundred tagged ones out there the answer became pretty obvious." He went further on to explain that through their research they've created a + basic carp life cycle, starting at the center of the gas giant and ending in the upper atmosphere, "They tend to die there.", he remarks, "Carp don't + really survive in space unless they are really, really big. Hence why we get so many." When asked why the carp come to space in the first place, he shrugs, + "We don't really know. We think maybe they can sense the stations up there somehow and are looking for food." +
++ Sadly this does not help much in protecting the citizens of the stars from the dreadful beasts. In the last month, there have been a reported 37 deaths due + to Carp and Pike related incidents, making the Erebus Beasts a serious threat to people thinking of working on a station. Scientists believe that at some + point this year, stations and ships in the Nyx System will be subjected to the largest migration of Carp and Pike that has ever been seen, and it may cause + serious damage to interests in the system. +
+Written by Peggy Re’saih \ No newline at end of file diff --git a/polaris.dme b/polaris.dme index a48bf6b7bb..9a8cebeaf4 100644 --- a/polaris.dme +++ b/polaris.dme @@ -2107,6 +2107,7 @@ #include "code\modules\modular_computers\computers\machinery\modular_laptop.dm" #include "code\modules\modular_computers\file_system\computer_file.dm" #include "code\modules\modular_computers\file_system\data.dm" +#include "code\modules\modular_computers\file_system\news_article.dm" #include "code\modules\modular_computers\file_system\program.dm" #include "code\modules\modular_computers\file_system\program_events.dm" #include "code\modules\modular_computers\file_system\programs\_engineering.dm" @@ -2118,6 +2119,7 @@ #include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\game.dm" +#include "code\modules\modular_computers\file_system\programs\news_browser.dm" #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm" #include "code\modules\modular_computers\file_system\programs\ntmonitor.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm"