Updates Part Nine

This commit is contained in:
Unknown
2019-04-11 19:14:25 -04:00
parent 30474e627f
commit e62eb3b068
33 changed files with 537 additions and 167 deletions

View File

@@ -7,6 +7,7 @@ var/global/datum/ntnet/ntnet_global = new()
var/list/logs = list() var/list/logs = list()
var/list/available_station_software = list() var/list/available_station_software = list()
var/list/available_antag_software = list() var/list/available_antag_software = list()
var/list/available_news = list()
var/list/chat_channels = list() var/list/chat_channels = list()
var/list/fileservers = list() var/list/fileservers = list()
// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly. // 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) relays.Add(R)
R.NTNet = src R.NTNet = src
build_software_lists() build_software_lists()
build_news_list()
add_log("NTNet logging system activated.") add_log("NTNet logging system activated.")
// Simplified logging: Adds a log. log_string is mandatory parameter, source is optional. // 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. // Check all relays. If we have at least one working relay, network is up.
for(var/obj/machinery/ntnet_relay/R in relays) for(var/obj/machinery/ntnet_relay/R in relays)
if(R.is_operational()) if(R.operable())
operating = 1 operating = 1
break break
@@ -93,6 +95,15 @@ var/global/datum/ntnet/ntnet_global = new()
if(prog.available_on_syndinet) if(prog.available_on_syndinet)
available_antag_software.Add(prog) 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 // Attempts to find a downloadable file according to filename var
/datum/ntnet/proc/find_ntnet_file_by_name(var/filename) /datum/ntnet/proc/find_ntnet_file_by_name(var/filename)
for(var/datum/computer_file/program/P in available_station_software) for(var/datum/computer_file/program/P in available_station_software)
@@ -145,3 +156,4 @@ var/global/datum/ntnet/ntnet_global = new()

View File

@@ -20,8 +20,8 @@
// TODO: Implement more logic here. For now it's only a placeholder. // TODO: Implement more logic here. For now it's only a placeholder.
/obj/machinery/ntnet_relay/proc/is_operational() /obj/machinery/ntnet_relay/operable()
if(stat & (BROKEN | NOPOWER | EMPED)) if(!..(EMPED))
return 0 return 0
if(dos_failure) if(dos_failure)
return 0 return 0
@@ -30,13 +30,13 @@
return 1 return 1
/obj/machinery/ntnet_relay/update_icon() /obj/machinery/ntnet_relay/update_icon()
if(is_operational()) if(operable())
icon_state = "bus" icon_state = "bus"
else else
icon_state = "bus_off" icon_state = "bus_off"
/obj/machinery/ntnet_relay/process() /obj/machinery/ntnet_relay/process()
if(is_operational()) if(operable())
use_power = 2 use_power = 2
else else
use_power = 1 use_power = 1
@@ -113,14 +113,14 @@
if(W.is_screwdriver()) if(W.is_screwdriver())
playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1)
panel_open = !panel_open 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 return
if(W.is_crowbar()) if(W.is_crowbar())
if(!panel_open) if(!panel_open)
user << "Open the maintenance panel first." to_chat(user, "Open the maintenance panel first.")
return return
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) 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) for(var/atom/movable/A in component_parts)
A.forceMove(src.loc) A.forceMove(src.loc)

View File

@@ -3,7 +3,7 @@
// consoles and laptops use "procssor" item that is held inside machinery piece // consoles and laptops use "procssor" item that is held inside machinery piece
/obj/item/modular_computer /obj/item/modular_computer
name = "Modular Microcomputer" name = "Modular Microcomputer"
desc = "A small portable microcomputer" desc = "A small portable microcomputer."
var/enabled = 0 // Whether the computer is turned on. 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/screen_on = 1 // Whether the computer is active/opened/it's screen is on.
@@ -55,27 +55,27 @@
set src in view(1) set src in view(1)
if(usr.incapacitated() || !istype(usr, /mob/living)) if(usr.incapacitated() || !istype(usr, /mob/living))
usr << "<span class='warning'>You can't do that.</span>" to_chat(usr, "<span class='warning'>You can't do that.</span>")
return return
if(!Adjacent(usr)) if(!Adjacent(usr))
usr << "<span class='warning'>You can't reach it.</span>" to_chat(usr, "<span class='warning'>You can't reach it.</span>")
return return
proc_eject_id(usr) proc_eject_id(usr)
// Eject ID card from computer, if it has ID slot with card inside. // Eject ID card from computer, if it has ID slot with card inside.
/obj/item/modular_computer/verb/eject_usb() /obj/item/modular_computer/verb/eject_usb()
set name = "Eject Portable Device" set name = "Eject Portable Storage"
set category = "Object" set category = "Object"
set src in view(1) set src in view(1)
if(usr.incapacitated() || !istype(usr, /mob/living)) if(usr.incapacitated() || !istype(usr, /mob/living))
usr << "<span class='warning'>You can't do that.</span>" to_chat(usr, "<span class='warning'>You can't do that.</span>")
return return
if(!Adjacent(usr)) if(!Adjacent(usr))
usr << "<span class='warning'>You can't reach it.</span>" to_chat(usr, "<span class='warning'>You can't reach it.</span>")
return return
proc_eject_usb(usr) proc_eject_usb(usr)
@@ -85,11 +85,11 @@
user = usr user = usr
if(!card_slot) 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 return
if(!card_slot.stored_card) if(!card_slot.stored_card)
user << "There is no card in \the [src]" to_chat(user, "There is no card in \the [src]")
return return
if(active_program) if(active_program)
@@ -101,14 +101,15 @@
card_slot.stored_card.forceMove(get_turf(src)) card_slot.stored_card.forceMove(get_turf(src))
card_slot.stored_card = null card_slot.stored_card = null
update_uis() 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) /obj/item/modular_computer/proc/proc_eject_usb(mob/user)
if(!user) if(!user)
user = usr user = usr
if(!portable_drive) 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 return
uninstall_component(user, portable_drive) uninstall_component(user, portable_drive)
@@ -124,19 +125,19 @@
/obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user) /obj/item/modular_computer/emag_act(var/remaining_charges, var/mob/user)
if(computer_emagged) if(computer_emagged)
user << "\The [src] was already emagged." to_chat(user, "\The [src] was already emagged.")
return return
else else
computer_emagged = 1 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 return 1
/obj/item/modular_computer/examine(var/mob/user) /obj/item/modular_computer/examine(var/mob/user)
..() ..()
if(damage > broken_damage) if(damage > broken_damage)
user << "<span class='danger'>It is heavily damaged!</span>" to_chat(user, "<span class='danger'>It is heavily damaged!</span>")
else if(damage) else if(damage)
user << "It is damaged." to_chat(user, "It is damaged.")
/obj/item/modular_computer/New() /obj/item/modular_computer/New()
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
@@ -235,23 +236,23 @@
var/issynth = issilicon(user) // Robots and AIs get different activation messages. var/issynth = issilicon(user) // Robots and AIs get different activation messages.
if(damage > broken_damage) if(damage > broken_damage)
if(issynth) 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 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 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(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) 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 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 enabled = 1
update_icon() update_icon()
ui_interact(user) ui_interact(user)
else // Unpowered else // Unpowered
if(issynth) 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 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. // Process currently calls handle_power(), may be expanded in future if more things are added.
/obj/item/modular_computer/process() /obj/item/modular_computer/process()
@@ -418,7 +419,7 @@
P.kill_program(1) P.kill_program(1)
update_uis() update_uis()
user << "<span class='notice'>Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.</span>" to_chat(user, "<span class='notice'>Program [P.filename].[P.filetype] with PID [rand(100,999)] has been killed.</span>")
if( href_list["PC_runprogram"] ) if( href_list["PC_runprogram"] )
var/prog = href_list["PC_runprogram"] var/prog = href_list["PC_runprogram"]
@@ -428,7 +429,7 @@
P = hard_drive.find_file_by_name(prog) P = hard_drive.find_file_by_name(prog)
if(!P || !istype(P)) // Program not found or it's not executable program. if(!P || !istype(P)) // Program not found or it's not executable program.
user << "<span class='danger'>\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.</span>" to_chat(user, "<span class='danger'>\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.</span>")
return return
P.computer = src P.computer = src
@@ -445,11 +446,11 @@
return return
if(idle_threads.len >= processor_unit.max_idle_programs+1) if(idle_threads.len >= processor_unit.max_idle_programs+1)
user << "<span class='notice'>\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error</span>" to_chat(user, "<span class='notice'>\The [src] displays a \"Maximal CPU load reached. Unable to run another program.\" error</span>")
return return
if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet. if(P.requires_ntnet && !get_ntnet_status(P.requires_ntnet_feature)) // The program requires NTNet connection, but we are not connected to NTNet.
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, "<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>")
return return
if(P.run_program(user)) if(P.run_program(user))
@@ -493,17 +494,17 @@
if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it. if(istype(W, /obj/item/weapon/card/id)) // ID Card, try to insert it.
var/obj/item/weapon/card/id/I = W var/obj/item/weapon/card/id/I = W
if(!card_slot) 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 return
if(card_slot.stored_card) 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 return
user.drop_from_inventory(I) user.drop_from_inventory(I)
card_slot.stored_card = I card_slot.stored_card = I
I.forceMove(src) I.forceMove(src)
update_uis() update_uis()
user << "You insert \the [I] into \the [src]." to_chat(user, "You insert \the [I] into \the [src].")
return return
if(istype(W, /obj/item/weapon/paper)) if(istype(W, /obj/item/weapon/paper))
if(!nano_printer) if(!nano_printer)
@@ -514,11 +515,11 @@
if(C.hardware_size <= max_hardware_size) if(C.hardware_size <= max_hardware_size)
try_install_component(user, C) try_install_component(user, C)
else 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()) if(W.is_wrench())
var/list/components = get_all_components() var/list/components = get_all_components()
if(components.len) 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 return
new /obj/item/stack/material/steel( get_turf(src.loc), steel_sheet_cost ) new /obj/item/stack/material/steel( get_turf(src.loc), steel_sheet_cost )
src.visible_message("\The [src] has been disassembled by [user].") src.visible_message("\The [src] has been disassembled by [user].")
@@ -528,23 +529,23 @@
if(istype(W, /obj/item/weapon/weldingtool)) if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W var/obj/item/weapon/weldingtool/WT = W
if(!WT.isOn()) if(!WT.isOn())
user << "\The [W] is off." to_chat(user, "\The [W] is off.")
return return
if(!damage) if(!damage)
user << "\The [src] does not require repairs." to_chat(user, "\The [src] does not require repairs.")
return 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)) if(WT.remove_fuel(round(damage/75)) && do_after(usr, damage/10))
damage = 0 damage = 0
user << "You repair \the [src]." to_chat(user, "You repair \the [src].")
return return
if(W.is_screwdriver()) if(W.is_screwdriver())
var/list/all_components = get_all_components() var/list/all_components = get_all_components()
if(!all_components.len) 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 return
var/list/component_names = list() var/list/component_names = list()
for(var/obj/item/weapon/computer_hardware/H in all_components) for(var/obj/item/weapon/computer_hardware/H in all_components)
@@ -578,48 +579,48 @@
// "USB" flash drive. // "USB" flash drive.
if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable)) if(istype(H, /obj/item/weapon/computer_hardware/hard_drive/portable))
if(portable_drive) 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 return
found = 1 found = 1
portable_drive = H portable_drive = H
else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive)) else if(istype(H, /obj/item/weapon/computer_hardware/hard_drive))
if(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 return
found = 1 found = 1
hard_drive = H hard_drive = H
else if(istype(H, /obj/item/weapon/computer_hardware/network_card)) else if(istype(H, /obj/item/weapon/computer_hardware/network_card))
if(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 return
found = 1 found = 1
network_card = H network_card = H
else if(istype(H, /obj/item/weapon/computer_hardware/nano_printer)) else if(istype(H, /obj/item/weapon/computer_hardware/nano_printer))
if(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 return
found = 1 found = 1
nano_printer = H nano_printer = H
else if(istype(H, /obj/item/weapon/computer_hardware/card_slot)) else if(istype(H, /obj/item/weapon/computer_hardware/card_slot))
if(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 return
found = 1 found = 1
card_slot = H card_slot = H
else if(istype(H, /obj/item/weapon/computer_hardware/battery_module)) else if(istype(H, /obj/item/weapon/computer_hardware/battery_module))
if(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 return
found = 1 found = 1
battery_module = H battery_module = H
else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit)) else if(istype(H, /obj/item/weapon/computer_hardware/processor_unit))
if(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 return
found = 1 found = 1
processor_unit = H processor_unit = H
if(found) if(found)
user << "You install \the [H] into \the [src]" to_chat(user, "You install \the [H] into \the [src]")
H.holder2 = src H.holder2 = src
user.drop_from_inventory(H) user.drop_from_inventory(H)
H.forceMove(src) H.forceMove(src)
@@ -651,12 +652,12 @@
critical = 1 critical = 1
if(found) if(found)
if(user) 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.forceMove(get_turf(src))
H.holder2 = null H.holder2 = null
if(critical && enabled) if(critical && enabled)
if(user) if(user)
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 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>")
shutdown_computer() shutdown_computer()
update_icon() update_icon()
@@ -783,4 +784,4 @@
if(active_program) if(active_program)
return active_program.check_eye(user) return active_program.check_eye(user)
else else
return ..() return ..()

View File

@@ -30,9 +30,9 @@
/obj/item/modular_computer/processor/examine(var/mob/user) /obj/item/modular_computer/processor/examine(var/mob/user)
if(damage > broken_damage) if(damage > broken_damage)
user << "<span class='danger'>It is heavily damaged!</span>" to_chat(user, "<span class='danger'>It is heavily damaged!</span>")
else if(damage) 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. // Power interaction is handled by our machinery part, due to machinery having APC connection.
/obj/item/modular_computer/processor/handle_power() /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) /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(istype(H, /obj/item/weapon/computer_hardware/tesla_link))
if(machinery_computer.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 return
var/obj/item/weapon/computer_hardware/tesla_link/L = H var/obj/item/weapon/computer_hardware/tesla_link/L = H
L.holder = machinery_computer 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 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) if(machinery_computer && machinery_computer.tesla_link)
machinery_computer.tesla_link.enabled = 1 machinery_computer.tesla_link.enabled = 1
..() ..()

View File

@@ -6,5 +6,5 @@
icon_state_menu = "menu" icon_state_menu = "menu"
hardware_flag = PROGRAM_TABLET hardware_flag = PROGRAM_TABLET
max_hardware_size = 1 max_hardware_size = 1
w_class = 2 w_class = ITEMSIZE_SMALL
light_strength = 2 // Same as PDAs light_strength = 2 // Same as PDAs

View File

@@ -2,7 +2,7 @@
// Available as custom loadout item, this is literally the worst possible cheap tablet // Available as custom loadout item, this is literally the worst possible cheap tablet
/obj/item/modular_computer/tablet/preset/custom_loadout/cheap/New() /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) 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 = new/obj/item/weapon/computer_hardware/battery_module/nano(src)
battery_module.charge_to_full() battery_module.charge_to_full()

View File

@@ -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 // Modular Computer - device that runs various programs and operates with hardware
// DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead. // DO NOT SPAWN THIS TYPE. Use /laptop/ or /console/ instead.
/obj/machinery/modular_computer/ /obj/machinery/modular_computer/
name = "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 var/battery_powered = 0 // Whether computer should be battery powered. It is set automatically
use_power = 0 use_power = 0
@@ -64,7 +67,7 @@
// Eject ID card from computer, if it has ID slot with card inside. // Eject ID card from computer, if it has ID slot with card inside.
/obj/machinery/modular_computer/verb/eject_usb() /obj/machinery/modular_computer/verb/eject_usb()
set name = "Eject Portable Device" set name = "Eject Portable Storage"
set category = "Object" set category = "Object"
set src in view(1) set src in view(1)
@@ -74,6 +77,7 @@
/obj/machinery/modular_computer/New() /obj/machinery/modular_computer/New()
..() ..()
cpu = new(src) cpu = new(src)
global_modular_computers.Add(src)
/obj/machinery/modular_computer/Destroy() /obj/machinery/modular_computer/Destroy()
if(cpu) if(cpu)
@@ -162,9 +166,7 @@
/obj/machinery/modular_computer/power_change() /obj/machinery/modular_computer/power_change()
if(battery_powered) if(battery_powered)
return return
else ..()
..()
update_icon()
/obj/machinery/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) /obj/machinery/modular_computer/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
if(cpu) if(cpu)
@@ -194,3 +196,4 @@
if(cpu) if(cpu)
return cpu.check_eye(user) return cpu.check_eye(user)
return -1 return -1

View File

@@ -15,22 +15,22 @@
set src in view(1) set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
usr << "<span class='warning'>You can't do that.</span>" to_chat(usr, "<span class='warning'>You can't do that.</span>")
return return
if(!Adjacent(usr)) if(!Adjacent(usr))
usr << "You can't reach it." to_chat(usr, "You can't reach it.")
return return
if(!istype(loc,/turf)) 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 return
if(!stored_computer) if(!stored_computer)
if(contents.len) if(contents.len)
for(var/obj/O in contents) for(var/obj/O in contents)
O.forceMove(src.loc) O.forceMove(src.loc)
usr << "\The [src] crumbles to pieces." to_chat(usr, "\The [src] crumbles to pieces.")
spawn(5) spawn(5)
qdel(src) qdel(src)
return return
@@ -41,7 +41,7 @@
if(stored_computer.cpu) if(stored_computer.cpu)
stored_computer.cpu.screen_on = 1 stored_computer.cpu.screen_on = 1
loc = stored_computer loc = stored_computer
usr << "You open \the [src]." to_chat(usr, "You open \the [src].")
/obj/item/laptop/AltClick() /obj/item/laptop/AltClick()
@@ -51,7 +51,7 @@
// The actual laptop // The actual laptop
/obj/machinery/modular_computer/laptop /obj/machinery/modular_computer/laptop
name = "laptop computer" 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. 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 hardware_flag = PROGRAM_LAPTOP
icon_state_unpowered = "laptop-open" // Icon state when the computer is turned off icon_state_unpowered = "laptop-open" // Icon state when the computer is turned off
@@ -78,11 +78,11 @@
set src in view(1) set src in view(1)
if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living)) if(usr.stat || usr.restrained() || usr.lying || !istype(usr, /mob/living))
usr << "<span class='warning'>You can't do that.</span>" to_chat(usr, "<span class='warning'>You can't do that.</span>")
return return
if(!Adjacent(usr)) if(!Adjacent(usr))
usr << "<span class='warning'>You can't reach it.</span>" to_chat(usr, "<span class='warning'>You can't reach it.</span>")
return return
close_laptop(usr) close_laptop(usr)
@@ -101,10 +101,10 @@
src.forceMove(portable) src.forceMove(portable)
stat |= MAINT stat |= MAINT
if(user) if(user)
user << "You close \the [src]." to_chat(user, "You close \the [src].")
if(cpu) if(cpu)
cpu.screen_on = 0 cpu.screen_on = 0
/obj/machinery/modular_computer/laptop/AltClick() /obj/machinery/modular_computer/laptop/AltClick()
if(Adjacent(usr)) if(Adjacent(usr))
close_laptop() close_laptop()

View File

@@ -3,6 +3,8 @@
/datum/computer_file/data /datum/computer_file/data
var/stored_data = "" // Stored data in string format. var/stored_data = "" // Stored data in string format.
filetype = "DAT" 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() /datum/computer_file/data/clone()
var/datum/computer_file/data/temp = ..() var/datum/computer_file/data/temp = ..()
@@ -10,7 +12,7 @@
return temp return temp
// Calculates file size from amount of characters in saved string // 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)) size = max(1, round(length(stored_data) / block_size))
/datum/computer_file/data/logfile /datum/computer_file/data/logfile

View File

@@ -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'

View File

@@ -59,7 +59,7 @@
/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 = 0, var/mob/user = null)
if(!(hardware_flag & usage_flags)) if(!(hardware_flag & usage_flags))
if(loud && computer && user) if(loud && computer && user)
user << "<span class='danger'>\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.</span>" to_chat(user, "<span class='danger'>\The [computer] flashes an \"Hardware Error - Incompatible software\" warning.</span>")
return 0 return 0
return 1 return 1
@@ -88,13 +88,13 @@
var/obj/item/weapon/card/id/I = user.GetIdCard() var/obj/item/weapon/card/id/I = user.GetIdCard()
if(!I) if(!I)
if(loud) if(loud)
user << "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>" to_chat(user, "<span class='danger'>\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.</span>")
return 0 return 0
if(access_to_check in I.access) if(access_to_check in I.access)
return 1 return 1
else if(loud) else if(loud)
user << "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>" to_chat(user, "<span class='danger'>\The [computer] flashes an \"Access Denied\" warning.</span>")
// This attempts to retrieve header data for NanoUIs. If implementing completely new device of different type than existing ones // 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. // 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) if(NM)
return NM.check_eye(user) return NM.check_eye(user)
else else
return -1 return -1

View File

@@ -7,7 +7,7 @@
/obj/item/modular_computer/initial_data() /obj/item/modular_computer/initial_data()
return get_header_data() return get_header_data()
/obj/item/modular_computer/update_layout() /obj/machinery/modular_computer/update_layout()
return TRUE return TRUE
/datum/nano_module/program /datum/nano_module/program

View File

@@ -24,14 +24,15 @@
dos_speed = NTNETSPEED_ETHERNET * NTNETSPEED_DOS_AMPLIFICATION dos_speed = NTNETSPEED_ETHERNET * NTNETSPEED_DOS_AMPLIFICATION
if(target && executed) if(target && executed)
target.dos_overload += dos_speed target.dos_overload += dos_speed
if(!target.is_operational()) if(!target.operable())
target.dos_sources.Remove(src) target.dos_sources.Remove(src)
target = null target = null
error = "Connection to destination relay lost." error = "Connection to destination relay lost."
/datum/computer_file/program/ntnet_dos/kill_program(var/forced) /datum/computer_file/program/ntnet_dos/kill_program(var/forced)
target.dos_sources.Remove(src) if(target)
target = null target.dos_sources.Remove(src)
target = null
executed = 0 executed = 0
..(forced) ..(forced)

View File

@@ -24,6 +24,7 @@
/datum/nano_module/camera_monitor/hacked /datum/nano_module/camera_monitor/hacked
name = "Hacked Camera Monitoring Program" name = "Hacked Camera Monitoring Program"
//available_to_ai = FALSE
/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access) /datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access)
return 1 return 1
@@ -33,4 +34,4 @@
networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1))) 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_ERT, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
return networks return networks

View File

@@ -36,7 +36,7 @@
var/obj/machinery/camera/current_camera = null var/obj/machinery/camera/current_camera = null
var/current_network = 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() var/list/data = host.initial_data()
data["current_camera"] = current_camera ? current_camera.nano_structure() : null data["current_camera"] = current_camera ? current_camera.nano_structure() : null
@@ -92,14 +92,11 @@
return 1 return 1
else if(href_list["switch_network"]) 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. // 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"]))) if(can_access_network(usr, get_camera_access(href_list["switch_network"])))
current_network = href_list["switch_network"] current_network = href_list["switch_network"]
else 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 return 1
else if(href_list["reset"]) else if(href_list["reset"])
@@ -164,9 +161,10 @@
/datum/nano_module/camera_monitor/ert /datum/nano_module/camera_monitor/ert
name = "Advanced Camera Monitoring Program" 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. // 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_ERT, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1))) networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))

View File

@@ -141,7 +141,7 @@
contents += " [get_access_desc(A)]" contents += " [get_access_desc(A)]"
if(!computer.nano_printer.print_text(contents,"access report")) if(!computer.nano_printer.print_text(contents,"access report"))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>" to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
return return
else else
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>") computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
@@ -151,7 +151,7 @@
[data_core ? data_core.get_manifest(0) : ""] [data_core ? data_core.get_manifest(0) : ""]
"} "}
if(!computer.nano_printer.print_text(contents,text("crew manifest ([])", stationtime2text()))) if(!computer.nano_printer.print_text(contents,text("crew manifest ([])", stationtime2text())))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>" to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
return return
else else
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>") computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
@@ -196,7 +196,7 @@
jobdatum = J jobdatum = J
break break
if(!jobdatum) if(!jobdatum)
usr << "<span class='warning'>No log exists for this job: [t1]</span>" to_chat(usr, "<span class='warning'>No log exists for this job: [t1]</span>")
return return
access = jobdatum.get_access() access = jobdatum.get_access()

View File

@@ -8,7 +8,7 @@
filedesc = "Command and communications program." filedesc = "Command and communications program."
program_icon_state = "comm" program_icon_state = "comm"
nanomodule_path = /datum/nano_module/program/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 required_access = access_heads
requires_ntnet = 1 requires_ntnet = 1
size = 12 size = 12
@@ -24,6 +24,7 @@
/datum/nano_module/program/comm /datum/nano_module/program/comm
name = "Command and communications program" name = "Command and communications program"
//available_to_ai = TRUE
var/current_status = STATE_DEFAULT var/current_status = STATE_DEFAULT
var/msg_line1 = "" var/msg_line1 = ""
var/msg_line2 = "" var/msg_line2 = ""
@@ -104,13 +105,15 @@
if(..()) if(..())
return 1 return 1
var/mob/user = usr var/mob/user = usr
var/ntn_comm = !!program.get_signal(NTNET_COMMUNICATION) var/ntn_comm = program ? !!program.get_signal(NTNET_COMMUNICATION) : 1
var/ntn_cont = !!program.get_signal(NTNET_SYSTEMCONTROL) var/ntn_cont = program ? !!program.get_signal(NTNET_SYSTEMCONTROL) : 1
var/datum/comm_message_listener/l = obtain_message_listener() var/datum/comm_message_listener/l = obtain_message_listener()
switch(href_list["action"]) switch(href_list["action"])
if("sw_menu") if("sw_menu")
. = 1
current_status = text2num(href_list["target"]) current_status = text2num(href_list["target"])
if("announce") if("announce")
. = 1
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(user) if(user)
var/obj/item/weapon/card/id/id_card = user.GetIdCard() var/obj/item/weapon/card/id/id_card = user.GetIdCard()
@@ -118,31 +121,29 @@
else else
crew_announcement.announcer = "Unknown" crew_announcement.announcer = "Unknown"
if(announcment_cooldown) if(announcment_cooldown)
usr << "Please allow at least one minute to pass between announcements" to_chat(usr, "Please allow at least one minute to pass between announcements")
SSnanoui.update_uis(src) return TRUE
return
var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text var/input = input(usr, "Please write a message to announce to the station crew.", "Priority Announcement") as null|text
if(!input || !can_still_topic()) if(!input || !can_still_topic())
SSnanoui.update_uis(src) return 1
return
crew_announcement.Announce(input) crew_announcement.Announce(input)
announcment_cooldown = 1 announcment_cooldown = 1
spawn(600)//One minute cooldown spawn(600)//One minute cooldown
announcment_cooldown = 0 announcment_cooldown = 0
if("message") if("message")
. = 1
if(href_list["target"] == "emagged") if(href_list["target"] == "emagged")
if(program) if(program)
if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm) if(is_autenthicated(user) && program.computer_emagged && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown) if(centcomm_message_cooldown)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>" to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
SSnanoui.update_uis(src) SSnanoui.update_uis(src)
return 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) 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()) if(!input || !can_still_topic())
SSnanoui.update_uis(src) return 1
return
Syndicate_announce(input, usr) Syndicate_announce(input, usr)
usr << "<span class='notice'>Message transmitted.</span>" to_chat(usr, "<span class='notice'>Message transmitted.</span>")
log_say("[key_name(usr)] has made an illegal announcement: [input]") log_say("[key_name(usr)] has made an illegal announcement: [input]")
centcomm_message_cooldown = 1 centcomm_message_cooldown = 1
spawn(300)//30 second cooldown spawn(300)//30 second cooldown
@@ -150,34 +151,35 @@
else if(href_list["target"] == "regular") else if(href_list["target"] == "regular")
if(is_autenthicated(user) && !issilicon(usr) && ntn_comm) if(is_autenthicated(user) && !issilicon(usr) && ntn_comm)
if(centcomm_message_cooldown) if(centcomm_message_cooldown)
usr << "<span class='warning'>Arrays recycling. Please stand by.</span>" to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
SSnanoui.update_uis(src) SSnanoui.update_uis(src)
return return
if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs. if(!is_relay_online())//Contact Centcom has a check, Syndie doesn't to allow for Traitor funs.
usr <<"<span class='warning'>No Emergency Bluespace Relay detected. Unable to transmit message.</span>" to_chat(usr, "<span class='warning'>No Emergency Bluespace Relay detected. Unable to transmit message.</span>")
SSnanoui.update_uis(src) return 1
return
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) 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()) if(!input || !can_still_topic())
SSnanoui.update_uis(src) return 1
return
CentCom_announce(input, usr) CentCom_announce(input, usr)
usr << "<span class='notice'>Message transmitted.</span>" to_chat(usr, "<span class='notice'>Message transmitted.</span>")
log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]") log_say("[key_name(usr)] has made an IA Centcomm announcement: [input]")
centcomm_message_cooldown = 1 centcomm_message_cooldown = 1
spawn(300) //30 second cooldown spawn(300) //30 second cooldown
centcomm_message_cooldown = 0 centcomm_message_cooldown = 0
if("shuttle") if("shuttle")
. = 1
if(is_autenthicated(user) && ntn_cont) if(is_autenthicated(user) && ntn_cont)
if(href_list["target"] == "call") if(href_list["target"] == "call")
var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes") var/confirm = alert("Are you sure you want to call the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic()) if(confirm == "Yes" && can_still_topic())
call_shuttle_proc(usr) call_shuttle_proc(usr)
if(href_list["target"] == "cancel" && !issilicon(usr)) if(href_list["target"] == "cancel" && !issilicon(usr))
var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes") var/confirm = alert("Are you sure you want to cancel the shuttle?", name, "No", "Yes")
if(confirm == "Yes" && can_still_topic()) if(confirm == "Yes" && can_still_topic())
cancel_call_proc(usr) cancel_call_proc(usr)
if("setstatus") if("setstatus")
. = 1
if(is_autenthicated(user) && ntn_cont) if(is_autenthicated(user) && ntn_cont)
switch(href_list["target"]) switch(href_list["target"])
if("line1") if("line1")
@@ -194,8 +196,8 @@
post_status("alert", href_list["alert"]) post_status("alert", href_list["alert"])
else else
post_status(href_list["target"]) post_status(href_list["target"])
if("setalert") if("setalert")
. = 1
if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm) if(is_autenthicated(user) && !issilicon(usr) && ntn_cont && ntn_comm)
var/current_level = text2num(href_list["target"]) 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") 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) if(SEC_LEVEL_BLUE)
feedback_inc("alert_comms_blue",1) feedback_inc("alert_comms_blue",1)
else 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 current_status = STATE_DEFAULT
if("viewmessage") if("viewmessage")
. = 1
if(is_autenthicated(user) && ntn_comm) if(is_autenthicated(user) && ntn_comm)
current_viewing_message_id = text2num(href_list["target"]) current_viewing_message_id = text2num(href_list["target"])
for(var/list/m in l.messages) for(var/list/m in l.messages)
@@ -224,18 +228,19 @@
current_viewing_message = m current_viewing_message = m
current_status = STATE_VIEWMESSAGE current_status = STATE_VIEWMESSAGE
if("delmessage") if("delmessage")
. = 1
if(is_autenthicated(user) && ntn_comm && l != global_message_listener) if(is_autenthicated(user) && ntn_comm && l != global_message_listener)
l.Remove(current_viewing_message) l.Remove(current_viewing_message)
current_status = STATE_MESSAGELIST current_status = STATE_MESSAGELIST
if("printmessage") if("printmessage")
. = 1
if(is_autenthicated(user) && ntn_comm) if(is_autenthicated(user) && ntn_comm)
if(program && program.computer && program.computer.nano_printer) if(program && program.computer && program.computer.nano_printer)
if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"])) if(!program.computer.nano_printer.print_text(current_viewing_message["contents"],current_viewing_message["title"]))
usr << "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>" to_chat(usr, "<span class='notice'>Hardware error: Printer was unable to print the file. It may be out of paper.</span>")
else else
program.computer.visible_message("<span class='notice'>\The [program.computer] prints out paper.</span>") program.computer.visible_message("<span class='notice'>\The [program.computer] prints out paper.</span>")
SSnanoui.update_uis(src)
/datum/nano_module/program/comm/proc/post_status(var/command, var/data1, var/data2) /datum/nano_module/program/comm/proc/post_status(var/command, var/data1, var/data2)

View File

@@ -85,8 +85,16 @@
var/datum/computer_file/data/F = HDD.find_file_by_name(open_file) var/datum/computer_file/data/F = HDD.find_file_by_name(open_file)
if(!F || !istype(F)) if(!F || !istype(F))
return 1 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. 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"))
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) 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) if(F)
var/datum/computer_file/data/backup = F.clone() var/datum/computer_file/data/backup = F.clone()
HDD.remove_file(F) HDD.remove_file(F)
@@ -235,5 +243,4 @@
ui.auto_update_layout = 1 ui.auto_update_layout = 1
ui.set_initial_data(data) ui.set_initial_data(data)
ui.open() ui.open()
#undef MAX_TEXTFILE_LENGTH

View File

@@ -69,7 +69,7 @@
data["gameover"] = gameover data["gameover"] = gameover
data["information"] = information 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) if (!ui)
ui = new(user, src, ui_key, "arcade_classic.tmpl", "Defeat [enemy_name]", 500, 350, state = state) ui = new(user, src, ui_key, "arcade_classic.tmpl", "Defeat [enemy_name]", 500, 350, state = state)
if(host.update_layout()) if(host.update_layout())
@@ -148,4 +148,4 @@
player_mana += regen player_mana += regen
enemy_play() enemy_play()
check_gameover() check_gameover()
return 1 return 1

View File

@@ -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()

View File

@@ -11,6 +11,7 @@
/datum/nano_module/computer_ntnetmonitor /datum/nano_module/computer_ntnetmonitor
name = "NTNet Diagnostics and Monitoring" 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) /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) if(!ntnet_global)

View File

@@ -51,14 +51,18 @@
// This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes. // This is not intended to be obtainable in-game. Intended for adminbus and debugging purposes.
/obj/item/weapon/computer_hardware/battery_module/lambda /obj/item/weapon/computer_hardware/battery_module/lambda
name = "lambda coil" 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" icon_state = "battery_lambda"
hardware_size = 1 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) /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() /obj/item/weapon/computer_hardware/battery_module/New()
battery = new/obj/item/weapon/cell(src) battery = new/obj/item/weapon/cell(src)
@@ -68,4 +72,4 @@
/obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full() /obj/item/weapon/computer_hardware/battery_module/proc/charge_to_full()
if(battery) if(battery)
battery.charge = battery.maxcharge battery.charge = battery.maxcharge

View File

@@ -58,8 +58,8 @@
/obj/item/weapon/computer_hardware/hard_drive/diagnostics(var/mob/user) /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. // 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" to_chat(user, "NT-NFS File Table Status: [stored_files.len]/999")
user << "Storage capacity: [used_capacity]/[max_capacity]GQ" 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. // 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) /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() /obj/item/weapon/computer_hardware/hard_drive/New()
install_default_programs() install_default_programs()
..() ..()

View File

@@ -1,6 +1,6 @@
/obj/item/weapon/computer_hardware/ /obj/item/weapon/computer_hardware/
name = "Hardware" name = "Hardware"
desc = "Unknown Hardware" desc = "Unknown Hardware."
icon = 'icons/obj/modular_components.dmi' icon = 'icons/obj/modular_components.dmi'
var/obj/item/modular_computer/holder2 = null var/obj/item/modular_computer/holder2 = null
var/power_usage = 0 // If the hardware uses extra power, change this. 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) /obj/item/weapon/computer_hardware/attackby(var/obj/item/W as obj, var/mob/living/user as mob)
// Multitool. Runs diagnostics // Multitool. Runs diagnostics
if(istype(W, /obj/item/device/multitool)) if(istype(W, /obj/item/device/multitool))
user << "***** DIAGNOSTICS REPORT *****" to_chat(user, "***** DIAGNOSTICS REPORT *****")
diagnostics(user) diagnostics(user)
user << "******************************" to_chat(user, "******************************")
return 1 return 1
// Nanopaste. Repair all damage if present for a single unit. // Nanopaste. Repair all damage if present for a single unit.
var/obj/item/stack/S = W var/obj/item/stack/S = W
if(istype(S, /obj/item/stack/nanopaste)) if(istype(S, /obj/item/stack/nanopaste))
if(!damage) if(!damage)
user << "\The [src] doesn't seem to require repairs." to_chat(user, "\The [src] doesn't seem to require repairs.")
return 1 return 1
if(S.use(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 damage = 0
return 1 return 1
// Cable coil. Works as repair method, but will probably require multiple applications and more cable. // Cable coil. Works as repair method, but will probably require multiple applications and more cable.
if(istype(S, /obj/item/stack/cable_coil)) if(istype(S, /obj/item/stack/cable_coil))
if(!damage) if(!damage)
user << "\The [src] doesn't seem to require repairs." to_chat(user, "\The [src] doesn't seem to require repairs.")
return 1 return 1
if(S.use(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) take_damage(-10)
return 1 return 1
return ..() return ..()
@@ -44,7 +44,7 @@
// Called on multitool click, prints diagnostic information to the user. // Called on multitool click, prints diagnostic information to the user.
/obj/item/weapon/computer_hardware/proc/diagnostics(var/mob/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) /obj/item/weapon/computer_hardware/New(var/obj/L)
w_class = hardware_size w_class = hardware_size
@@ -76,13 +76,14 @@
/obj/item/weapon/computer_hardware/examine(var/mob/user) /obj/item/weapon/computer_hardware/examine(var/mob/user)
. = ..() . = ..()
if(damage > damage_failure) if(damage > damage_failure)
user << "<span class='danger'>It seems to be severely damaged!</span>" to_chat(user, "<span class='danger'>It seems to be severely damaged!</span>")
else if(damage > damage_malfunction) else if(damage > damage_malfunction)
user << "<span class='notice'>It seems to be damaged!</span>" to_chat(user, "<span class='notice'>It seems to be damaged!</span>")
else if(damage) 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. // Damages the component. Contains necessary checks. Negative damage "heals" the component.
/obj/item/weapon/computer_hardware/proc/take_damage(var/amount) /obj/item/weapon/computer_hardware/proc/take_damage(var/amount)
damage += round(amount) // We want nice rounded numbers here. damage += round(amount) // We want nice rounded numbers here.
damage = between(0, damage, max_damage) // Clamp the value. damage = between(0, damage, max_damage) // Clamp the value.

View File

@@ -2,6 +2,7 @@
name = "nano printer" name = "nano printer"
desc = "Small integrated printer with paper recycling module." desc = "Small integrated printer with paper recycling module."
power_usage = 50 power_usage = 50
origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2)
critical = 0 critical = 0
icon_state = "printer" icon_state = "printer"
hardware_size = 1 hardware_size = 1
@@ -10,7 +11,7 @@
/obj/item/weapon/computer_hardware/nano_printer/diagnostics(var/mob/user) /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) /obj/item/weapon/computer_hardware/nano_printer/proc/print_text(var/text_to_print, var/paper_title = null)
if(!stored_paper) if(!stored_paper)
@@ -20,27 +21,21 @@
if(!check_functionality()) if(!check_functionality())
return 0 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. // Damaged printer causes the resulting paper to be somewhat harder to read.
if(damage > damage_malfunction) if(damage > damage_malfunction)
P.info = stars(text_to_print, 100-malfunction_probability) text_to_print = stars(text_to_print, 100-malfunction_probability)
else new/obj/item/weapon/paper(get_turf(holder2),text_to_print, paper_title)
P.info = text_to_print
if(paper_title)
P.name = paper_title
P.update_icon()
stored_paper-- stored_paper--
P = null
return 1 return 1
/obj/item/weapon/computer_hardware/nano_printer/attackby(obj/item/W as obj, mob/user as mob) /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(istype(W, /obj/item/weapon/paper))
if(stored_paper >= max_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 return
user << "You insert \the [W] into [src]." to_chat(user, "You insert \the [W] into [src].")
qdel(W) qdel(W)
stored_paper++ stored_paper++
@@ -48,4 +43,4 @@
if(holder2 && (holder2.nano_printer == src)) if(holder2 && (holder2.nano_printer == src))
holder2.nano_printer = null holder2.nano_printer = null
holder2 = null holder2 = null
..() ..()

View File

@@ -16,14 +16,14 @@ var/global/ntnet_card_uid = 1
/obj/item/weapon/computer_hardware/network_card/diagnostics(var/mob/user) /obj/item/weapon/computer_hardware/network_card/diagnostics(var/mob/user)
..() ..()
user << "NIX Unique ID: [identification_id]" to_chat(user, "NIX Unique ID: [identification_id]")
user << "NIX User Tag: [identification_string]" to_chat(user, "NIX User Tag: [identification_string]")
user << "Supported protocols:" to_chat(user, "Supported protocols:")
user << "511.m SFS (Subspace) - Standard Frequency Spread" to_chat(user, "511.m SFS (Subspace) - Standard Frequency Spread")
if(long_range) 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) 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) /obj/item/weapon/computer_hardware/network_card/New(var/l)
..(l) ..(l)

View File

@@ -1,7 +1,7 @@
// These are basically USB data sticks and may be used to transfer files between devices // These are basically USB data sticks and may be used to transfer files between devices
/obj/item/weapon/computer_hardware/hard_drive/portable/ /obj/item/weapon/computer_hardware/hard_drive/portable/
name = "basic data crystal" 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 power_usage = 10
icon_state = "flashdrive_basic" icon_state = "flashdrive_basic"
hardware_size = 1 hardware_size = 1
@@ -10,7 +10,7 @@
/obj/item/weapon/computer_hardware/hard_drive/portable/advanced /obj/item/weapon/computer_hardware/hard_drive/portable/advanced
name = "advanced data crystal" 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 power_usage = 20
icon_state = "flashdrive_advanced" icon_state = "flashdrive_advanced"
hardware_size = 1 hardware_size = 1
@@ -19,7 +19,7 @@
/obj/item/weapon/computer_hardware/hard_drive/portable/super /obj/item/weapon/computer_hardware/hard_drive/portable/super
name = "super data crystal" 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 power_usage = 40
icon_state = "flashdrive_super" icon_state = "flashdrive_super"
hardware_size = 1 hardware_size = 1
@@ -29,4 +29,4 @@
/obj/item/weapon/computer_hardware/hard_drive/portable/New() /obj/item/weapon/computer_hardware/hard_drive/portable/New()
..() ..()
stored_files = list() stored_files = list()
recalculate_size() recalculate_size()

View File

@@ -38,4 +38,4 @@
hardware_size = 1 hardware_size = 1
power_usage = 75 power_usage = 75
max_idle_programs = 2 max_idle_programs = 2
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3) origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 3)

View File

@@ -17,4 +17,4 @@
/obj/item/weapon/computer_hardware/tesla_link/Destroy() /obj/item/weapon/computer_hardware/tesla_link/Destroy()
if(holder && (holder.tesla_link == src)) if(holder && (holder.tesla_link == src))
holder.tesla_link = null holder.tesla_link = null
..() ..()

View File

@@ -5,7 +5,7 @@
desc = "A vending machine with microfabricator capable of dispensing various NT-branded computers" desc = "A vending machine with microfabricator capable of dispensing various NT-branded computers"
icon = 'icons/obj/vending.dmi' icon = 'icons/obj/vending.dmi'
icon_state = "robotics" icon_state = "robotics"
layer = 2.9 layer = OBJ_LAYER - 0.1
anchored = 1 anchored = 1
density = 1 density = 1

View File

@@ -0,0 +1,62 @@
{{if data.message}}
<div class='item'>
{{:data.message}}
{{:helper.link('CLEAR', null, { "PRG_clearmessage" : 1 })}}
</div>
{{/if}}
{{if data.article}}
Viewing: {{:data.title}}<br><br>
{{:data.article}}
<br><br>
{{:helper.link('CLOSE', null, { "PRG_reset" : 1 })}}
{{:helper.link('SAVE', null, { "PRG_savearticle" : 1 })}}
{{else data.download_progress}}
Downloading file...<br><br>
<div class='item'>
<div class='itemLabel'>
Progress:
</div>
<div class='itemContent'>
{{:helper.displayBar(data.download_progress, 0, data.download_maxprogress, 'good')}}
{{:data.download_progress}} / {{:data.download_maxprogress}} GQ
</div>
<div class='itemLabel'>
Download speed:
</div>
<div class='itemContent'>
{{data.download_rate}} GQ/s
</div>
<div class='itemLabel'>
Controls:
</div>
<div class='itemContent'>
{{:helper.link('ABORT', null, { "PRG_reset" : 1 })}}
</div>
</div>
{{else}}
<b>Listing available files</b><hr>
{{for data.all_articles}}
<div class='item'>
<div class='itemLabel'>
Name:
</div>
<div class='itemContent'>
{{:value.name}}
</div>
<div class='itemLabel'>
Size:
</div>
<div class='itemContent'>
{{:value.size}} GQ
</div>
<div class='itemLabel'>
Actions:
</div>
<div class='itemContent'>
{{:helper.link('OPEN', null, { "PRG_openarticle" : value.uid })}}
</div>
</div>
{{/for}}
{{/if}}

View File

@@ -0,0 +1,135 @@
<img
src="https://lh5.googleusercontent.com/M7bp_Lz-ceoXJc3WGI4vGOyXME3Gaix6-yxC1a4kV37XmZjfmqMujXO6Q-TE1aJ-ZNZDn5Gp97m_-iTyc8ilnWbN76KorqlHSycP-Ihs89kGg506VWvQDjONjEgs9JcvrR654UKD"
height = 400px
/>
</p>
<p><title> Welcome to SPACE Magazine </title></p>
<br>
<br>
<p>
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<61>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.
</p>
<p>
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.
</p>
<br><br>
<h2>Pirates Underestimate Colonial Defenses</h2>
<br>
<p>
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.
</p>
<p>
<20>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.
</p>
<p>
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.
</p>
<p>
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.<2E> -Written by Liun Asitero, Onaios Daily
</p>
<i> Written by Lucas Shiito </i>
<br><br>
<h2>Brinkburn Refugees and Sapient<6E>s Rights</h2>
<br>
<p>
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.
</p>
<p>
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.
</p>
<p>
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.
</p>
<p>
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.
</p>
<i> Written by Laura Hunton </i>
<br><br>
<h2>Terror Attack on Asilliss VII</h2>
<br>
<p>
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.
</p>
<p>
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."
</p>
<p>
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!
</p>
<i>Written by Johnathan Townsend</i>
<br><br>
<h2>The Great Carp Migration</h2>
<br>
<p>
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."
</p>
<p>
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.
</p>
<i>Written by Peggy Re<52>saih</i>

View File

@@ -2107,6 +2107,7 @@
#include "code\modules\modular_computers\computers\machinery\modular_laptop.dm" #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\computer_file.dm"
#include "code\modules\modular_computers\file_system\data.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.dm"
#include "code\modules\modular_computers\file_system\program_events.dm" #include "code\modules\modular_computers\file_system\program_events.dm"
#include "code\modules\modular_computers\file_system\programs\_engineering.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\configurator.dm"
#include "code\modules\modular_computers\file_system\programs\file_browser.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\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\ntdownloader.dm"
#include "code\modules\modular_computers\file_system\programs\ntmonitor.dm" #include "code\modules\modular_computers\file_system\programs\ntmonitor.dm"
#include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm"