mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 14:31:59 +01:00
NTNet Extensibility (#22908)
Fixes https://github.com/Aurorastation/Aurora.3/issues/21944 Spiritual successor of https://github.com/Aurorastation/Aurora.3/pull/22352 Cherrypicked changes from the C3 Crew Management branch, this PR contains all NTNet extensibility features, including Field Relay construction, off-site camera usage (contingent on standing up remote hardware and being out of jamming), etc. This also fixes a handful of outstanding telecomms and view/mobeye-related bugs adjacent to where I was working. changes: - rscadd: "Adds NTNet extensibility, requires new machinery constructed on away-site z-levels." - rscadd: "Breaks NTNet Relay machinery into Quantum Relay ('core' obj on Horizon) and Field Relay (deployable off-site constructions)." - qol: "Embedded cameras (basically every video camera EXCEPT those which are installed on walls) can now be viewed from NTNet-connected z-level, not just connected ones." - rscadd: "Adds several public camera monitor consoles to the Horizon (near where public sensor grid feed consoles already exist)." - rscadd: "Adds some spare camera console boards to Horizon technical storage." - qol: "Adds action button for 'cancel-camera-view' verb while viewing cameras or looking up/down z-level." - bugfix: "Fixes Jockey comms (frequency was missing from ANTAG_FREQS)." - bugfix: "Fixes look-up/look-down actions intermittently failing without first using cancel-camera-view."
This commit is contained in:
@@ -102,7 +102,7 @@
|
||||
#define NETWORK_MEDICAL "Medical"
|
||||
#define NETWORK_MERCENARY "MercurialNet"
|
||||
#define NETWORK_TCAF "TCAF"
|
||||
#define NETWORK_MINE "MINE"
|
||||
#define NETWORK_MINE "Mining"
|
||||
#define NETWORK_RESEARCH "Research"
|
||||
#define NETWORK_RESEARCH_OUTPOST "Research Outpost"
|
||||
#define NETWORK_ROBOTS "Robots"
|
||||
|
||||
+20
-10
@@ -162,23 +162,33 @@
|
||||
#define MATERIAL_BRITTLE 0x2
|
||||
#define MATERIAL_PADDING 0x4
|
||||
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
/// Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
|
||||
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4
|
||||
|
||||
#define BOMBCAP_DVSTN_RADIUS (GLOB.max_explosion_range/4)
|
||||
#define BOMBCAP_HEAVY_RADIUS (GLOB.max_explosion_range/2)
|
||||
#define BOMBCAP_LIGHT_RADIUS GLOB.max_explosion_range
|
||||
#define BOMBCAP_FLASH_RADIUS (GLOB.max_explosion_range*1.5)
|
||||
// NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc)
|
||||
#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet
|
||||
#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices
|
||||
#define NTNET_COMMUNICATION 3 // Communication (messaging)
|
||||
#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc.
|
||||
|
||||
// NTNet module-configuration values.
|
||||
/// Downloads of software from NTNet
|
||||
#define NTNET_SOFTWAREDOWNLOAD 1
|
||||
/// P2P transfers of files between devices
|
||||
#define NTNET_PEERTOPEER 2
|
||||
/// Communication (messaging)
|
||||
#define NTNET_COMMUNICATION 3
|
||||
/// Control of various systems, RCon, air alarm control, etc.
|
||||
#define NTNET_SYSTEMCONTROL 4
|
||||
|
||||
// NTNet transfer speeds, used when downloading/uploading a file/program.
|
||||
#define NTNETSPEED_LOWSIGNAL 0.05 // GQ/s transfer speed when the device is wirelessly connected and on Low signal
|
||||
#define NTNETSPEED_HIGHSIGNAL 0.25 // GQ/s transfer speed when the device is wirelessly connected and on High signal
|
||||
#define NTNETSPEED_ETHERNET 1 // GQ/s transfer speed when the device is using wired connection
|
||||
#define NTNETSPEED_DOS_AMPLIFICATION 20 // Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device
|
||||
/// GQ/s transfer speed when the device is wirelessly connected and on Low signal
|
||||
#define NTNETSPEED_LOWSIGNAL 0.05
|
||||
/// GQ/s transfer speed when the device is wirelessly connected and on High signal
|
||||
#define NTNETSPEED_HIGHSIGNAL 0.25
|
||||
/// GQ/s transfer speed when the device is using wired connection
|
||||
#define NTNETSPEED_ETHERNET 1
|
||||
/// Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device
|
||||
#define NTNETSPEED_DOS_AMPLIFICATION 20
|
||||
|
||||
// Program bitflags
|
||||
#define PROGRAM_CONSOLE 1
|
||||
|
||||
@@ -114,7 +114,8 @@ var/list/ANTAG_FREQS = list(
|
||||
RAID_FREQ,
|
||||
NINJ_FREQ,
|
||||
BLSP_FREQ,
|
||||
BURG_FREQ
|
||||
BURG_FREQ,
|
||||
JOCK_FREQ
|
||||
)
|
||||
|
||||
var/list/ANTAG_FREQS_ASSOC = list(
|
||||
@@ -122,7 +123,8 @@ var/list/ANTAG_FREQS_ASSOC = list(
|
||||
"[RAID_FREQ]" = TRUE,
|
||||
"[NINJ_FREQ]" = TRUE,
|
||||
"[BURG_FREQ]" = TRUE,
|
||||
"[BLSP_FREQ]" = TRUE
|
||||
"[BLSP_FREQ]" = TRUE,
|
||||
"[JOCK_FREQ]" = TRUE
|
||||
)
|
||||
|
||||
/// Department channels, arranged lexically
|
||||
|
||||
@@ -323,6 +323,18 @@
|
||||
var/obj/item/clothing/wrists/watch/target_clothing = target
|
||||
target_clothing.checktime(usr)
|
||||
|
||||
/datum/action/cancel_camera_view
|
||||
name = "Cancel Camera View"
|
||||
button_icon_state = "cancel"
|
||||
|
||||
/datum/action/cancel_camera_view/Trigger()
|
||||
if(!Checks())
|
||||
return
|
||||
owner.cancel_remote_view()
|
||||
|
||||
/datum/action/cancel_camera_view/CheckRemoval(mob/living/user)
|
||||
return !user || !user.is_viewing_remote_view()
|
||||
|
||||
/datum/action/eye
|
||||
action_type = AB_GENERIC
|
||||
check_flags = AB_CHECK_LYING|AB_CHECK_STUNNED
|
||||
|
||||
@@ -156,7 +156,7 @@ SUBSYSTEM_DEF(radio)
|
||||
|
||||
return frequency
|
||||
|
||||
// Used to test connectivity to the telecomms network.
|
||||
/// Used to test connectivity to the telecomms network.
|
||||
/datum/controller/subsystem/radio/proc/telecomms_ping(obj/O, test_freq = PUB_FREQ)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
@@ -167,7 +167,7 @@ SUBSYSTEM_DEF(radio)
|
||||
|
||||
// Some misc procs not technically part of the subsystem, but are related.
|
||||
|
||||
//callback used by objects to react to incoming radio signals
|
||||
/// Callback used by objects to react to incoming radio signals
|
||||
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
R = new /obj/item/radio/headset/bluespace(player)
|
||||
if(BURG_FREQ)
|
||||
R = new /obj/item/radio/headset/burglar(player)
|
||||
if(JOCK_FREQ)
|
||||
R = new /obj/item/radio/headset/jockey(player)
|
||||
if(SYND_FREQ)
|
||||
R = new /obj/item/radio/headset/syndicate(player)
|
||||
if(RAID_FREQ)
|
||||
|
||||
@@ -9,7 +9,7 @@ GLOBAL_DATUM(jockeys, /datum/antagonist/jockey)
|
||||
landmark_id = "jockeyspawn"
|
||||
welcome_text = "You are a Jockey, one of the best damn mech pilots in the spur.<br>\
|
||||
Your uplink will grant you access to various tools you may need to attempt to accomplish your goal.<br>\
|
||||
You can use :H or :B to talk on your encrypted channel, which only you and your partner can read.<br>"
|
||||
You can use :k to talk on your encrypted channel, which only you and your partner can read.<br>"
|
||||
flags = ANTAG_OVERRIDE_JOB | ANTAG_CLEAR_EQUIPMENT | ANTAG_CHOOSE_NAME | ANTAG_VOTABLE | ANTAG_SET_APPEARANCE | ANTAG_HAS_LEADER
|
||||
antaghud_indicator = "hudjockey"
|
||||
required_age = 7
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
console_networks = list("MINE")
|
||||
req_access = list()
|
||||
|
||||
/obj/item/circuitboard/security/public
|
||||
name = T_BOARD("public camera monitor")
|
||||
build_path = /obj/structure/machinery/computer/security/terminal/public
|
||||
console_networks = list(NETWORK_EXPEDITION, NETWORK_NEWS)
|
||||
req_access = list()
|
||||
|
||||
/obj/item/circuitboard/security/construct(var/obj/structure/machinery/computer/security/C)
|
||||
if (..(C))
|
||||
C.console_networks = console_networks.Copy()
|
||||
|
||||
@@ -91,11 +91,3 @@
|
||||
"/obj/item/stock_parts/capacitor" = 1,
|
||||
"/obj/item/stack/cable_coil" = 1,
|
||||
"/obj/item/stock_parts/console_screen" = 1)
|
||||
|
||||
/obj/item/circuitboard/ntnet_relay
|
||||
name = T_BOARD("NTNet Quantum Relay")
|
||||
build_path = /obj/structure/machinery/ntnet_relay
|
||||
board_type = BOARD_MACHINE
|
||||
origin_tech = list(TECH_DATA = 4)
|
||||
req_components = list(
|
||||
"/obj/item/stack/cable_coil" = 15)
|
||||
|
||||
@@ -60,3 +60,18 @@
|
||||
"/obj/item/stock_parts/subspace/filter" = 1,
|
||||
"/obj/item/stock_parts/subspace/crystal" = 1,
|
||||
"/obj/item/stock_parts/micro_laser/high" = 2)
|
||||
|
||||
/obj/item/circuitboard/ntnet_relay
|
||||
name = T_BOARD("NTNet Quantum Relay")
|
||||
build_path = /obj/structure/machinery/ntnet_relay
|
||||
board_type = BOARD_MACHINE
|
||||
origin_tech = list(TECH_DATA = 4)
|
||||
req_components = list(
|
||||
"/obj/item/stack/cable_coil" = 15,
|
||||
"/obj/item/stock_parts/subspace/filter" = 1,
|
||||
"/obj/item/stock_parts/subspace/crystal" = 1,
|
||||
"/obj/item/stock_parts/micro_laser/high" = 2)
|
||||
|
||||
/obj/item/circuitboard/ntnet_relay/field
|
||||
name = T_BOARD("NTNet Field Relay")
|
||||
build_path = /obj/structure/machinery/ntnet_relay/field
|
||||
|
||||
@@ -258,7 +258,10 @@
|
||||
return
|
||||
|
||||
/mob/proc/unset_machine()
|
||||
var/was_viewing_machine_remote_view = is_viewing_camera() || is_viewing_overmap()
|
||||
src.machine = null
|
||||
if(was_viewing_machine_remote_view)
|
||||
reset_view(null)
|
||||
|
||||
/mob/proc/set_machine(var/obj/O)
|
||||
if(src.machine)
|
||||
|
||||
@@ -381,14 +381,23 @@
|
||||
alarm_on = 0
|
||||
GLOB.camera_alarm.clearAlarm(loc, src)
|
||||
|
||||
//if false, then the camera is listed as DEACTIVATED and cannot be used
|
||||
/// If FALSE, then the camera is listed as DEACTIVATED and cannot be used
|
||||
/obj/structure/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
return 0
|
||||
if(stat & (EMPED|BROKEN))
|
||||
return 0
|
||||
if(is_wireless_jammed())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/// Only used below, but has separate proc for potential future use.
|
||||
/obj/structure/machinery/camera/proc/is_wireless_camera()
|
||||
return !isturf(loc)
|
||||
|
||||
/obj/structure/machinery/camera/proc/is_wireless_jammed()
|
||||
return is_wireless_camera() && get_turf(src) && within_jamming_range(src)
|
||||
|
||||
/obj/structure/machinery/camera/proc/can_see()
|
||||
var/list/see = null
|
||||
var/turf/pos = get_turf(src)
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
|
||||
state = 4
|
||||
var/obj/structure/machinery/camera/C = new(src.loc)
|
||||
QDEL_NULL(C.assembly)
|
||||
src.forceMove(C)
|
||||
C.assembly = src
|
||||
|
||||
@@ -106,6 +107,10 @@
|
||||
C.replace_networks(uniquelist(tempnetwork))
|
||||
|
||||
C.c_tag = input
|
||||
C.setPowerUsage()
|
||||
if(C.isMotion() && !(SSmachinery.processing[C]))
|
||||
START_PROCESSING_MACHINE(C, MACHINERY_PROCESS_SELF)
|
||||
C.update_coverage()
|
||||
|
||||
for(var/i = 5; i >= 0; i -= 1)
|
||||
var/direct = tgui_input_list(user, "Direction?", "Assembling Camera", list("Confirm", "NORTH", "EAST", "SOUTH", "WEST"))
|
||||
@@ -127,20 +132,35 @@
|
||||
return TRUE
|
||||
|
||||
// Upgrades!
|
||||
if(is_type_in_list(attacking_item, possible_upgrades) && !is_type_in_list(attacking_item, upgrades)) // Is a possible upgrade and isn't in the camera already.
|
||||
var/upgrade_type
|
||||
for(var/possible_upgrade in possible_upgrades)
|
||||
if(istype(attacking_item, possible_upgrade))
|
||||
upgrade_type = possible_upgrade
|
||||
break
|
||||
|
||||
if(upgrade_type)
|
||||
if(state != 3)
|
||||
to_chat(user, SPAN_WARNING("You need to wire the assembly before installing upgrades."))
|
||||
return TRUE
|
||||
if(locate(upgrade_type) in upgrades)
|
||||
to_chat(user, SPAN_WARNING("\The [src] already has that upgrade installed."))
|
||||
return TRUE
|
||||
if(istype(attacking_item, /obj/item/stock_parts/scanning_module))
|
||||
var/obj/item/stock_parts/scanning_module/SM = attacking_item
|
||||
if(SM.rating < 2)
|
||||
to_chat(user, SPAN_WARNING("That scanning module doesn't seem advanced enough."))
|
||||
return
|
||||
return TRUE
|
||||
to_chat(user, "You attach \the [attacking_item] into the assembly inner circuits.")
|
||||
upgrades += attacking_item
|
||||
user.remove_from_mob(attacking_item)
|
||||
attacking_item.forceMove(src)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
// Taking out upgrades
|
||||
else if(attacking_item.tool_behaviour == TOOL_CROWBAR && upgrades.len)
|
||||
if(state != 3)
|
||||
to_chat(user, SPAN_WARNING("You need access to the wired circuits before removing upgrades."))
|
||||
return TRUE
|
||||
var/obj/U = locate(/obj) in upgrades
|
||||
if(U)
|
||||
to_chat(user, "You unattach an upgrade from the assembly.")
|
||||
|
||||
@@ -80,6 +80,9 @@ GLOBAL_LIST_INIT(engineering_networks, list(
|
||||
/obj/structure/machinery/camera/network/news
|
||||
network = list(NETWORK_NEWS)
|
||||
|
||||
/obj/structure/machinery/camera/network/expedition
|
||||
network = list(NETWORK_EXPEDITION)
|
||||
|
||||
// EMP
|
||||
|
||||
/obj/structure/machinery/camera/emp_proof/Initialize()
|
||||
|
||||
@@ -26,13 +26,23 @@
|
||||
camera_monitor_program = new("Compless")
|
||||
// Make sure that camera_monitor knows its been generated from a dedicated console; this will define its network access.
|
||||
camera_monitor_program.monitored_networks = console_networks
|
||||
camera_monitor_program.ntnet_endpoint = src
|
||||
camera_monitor_program.ntnet_endpoint_ethernet = TRUE
|
||||
|
||||
/obj/structure/machinery/computer/security/Destroy()
|
||||
reset_remote_viewers()
|
||||
if(camera_monitor_program)
|
||||
camera_monitor_program.reset_current()
|
||||
camera_monitor_program = null
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/structure/machinery/computer/security/proc/reset_remote_viewers()
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.machine == src && M.is_viewing_remote_view())
|
||||
M.unset_machine()
|
||||
M.reset_view(null)
|
||||
|
||||
/obj/structure/machinery/computer/security/attack_ai(var/mob/user as mob)
|
||||
if(!ai_can_interact(user))
|
||||
return
|
||||
@@ -41,6 +51,8 @@
|
||||
/obj/structure/machinery/computer/security/check_eye(var/mob/user as mob)
|
||||
if (user.stat || user.blinded || !operable())
|
||||
return -1
|
||||
if(camera_monitor_program?.current_camera)
|
||||
return camera_monitor_program.check_eye(user)
|
||||
if(!current_camera)
|
||||
return 0
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
@@ -51,6 +63,8 @@
|
||||
/obj/structure/machinery/computer/security/grants_equipment_vision(var/mob/user as mob)
|
||||
if(user.stat || user.blinded || !operable())
|
||||
return FALSE
|
||||
if(camera_monitor_program?.current_camera)
|
||||
return camera_monitor_program.grants_equipment_vision(user)
|
||||
if(!current_camera)
|
||||
return FALSE
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
@@ -91,7 +105,7 @@
|
||||
. = camera_monitor_program.ui_act(action, params, ui, state)
|
||||
|
||||
/obj/structure/machinery/computer/security/attack_hand(var/mob/user as mob)
|
||||
if (!(src.z in GetConnectedZlevels(starting_z_level)))
|
||||
if (!(src.z in GetConnectedZlevels(starting_z_level)) && !SSatlas.current_map.is_always_available_network_level(src.z))
|
||||
to_chat(user, "Unable to establish a connection.")
|
||||
return
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
@@ -115,9 +129,11 @@
|
||||
|
||||
if (user.stat || user.blinded || !operable())
|
||||
return 0
|
||||
if(!C.can_use())
|
||||
return 0
|
||||
set_current(C)
|
||||
|
||||
if (!(C.z in GetConnectedZlevels(starting_z_level)))
|
||||
if (!(C.z in GetConnectedZlevels(starting_z_level)) && !(SSatlas.current_map.is_always_available_network_level(src.z) && C.z == src.z))
|
||||
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
|
||||
return FALSE
|
||||
|
||||
@@ -311,7 +327,7 @@
|
||||
req_access = list(150)
|
||||
|
||||
/obj/structure/machinery/computer/security/terminal
|
||||
name = "camera monitor terminal"
|
||||
name = "public camera monitor"
|
||||
icon = 'icons/obj/modular_computers/modular_terminal.dmi'
|
||||
icon_screen = "cameras"
|
||||
icon_keyboard = "security_key"
|
||||
@@ -320,3 +336,7 @@
|
||||
has_off_keyboards = TRUE
|
||||
can_pass_under = FALSE
|
||||
light_power_on = 1
|
||||
|
||||
/obj/structure/machinery/computer/security/terminal/public
|
||||
console_networks = list(NETWORK_EXPEDITION, NETWORK_NEWS)
|
||||
circuit = /obj/item/circuitboard/security/public
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
. = ..()
|
||||
if(camera)
|
||||
verbs += /obj/item/clothing/head/helmet/proc/toggle_camera
|
||||
verbs += /obj/item/clothing/head/helmet/proc/toggle_expedition_camera_network
|
||||
if(has_storage)
|
||||
hold = new /obj/item/storage/internal/helmet(src)
|
||||
hold.storage_slots = slots
|
||||
@@ -81,10 +82,13 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/toggle_camera()
|
||||
set name = "Toggle Helmet Camera"
|
||||
set name = "Helmet Camera - Toggle On/Off"
|
||||
set category = "Object.Equipped"
|
||||
set src in usr
|
||||
|
||||
toggle_camera_for(usr)
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/toggle_camera_for(mob/user)
|
||||
if(ispath(camera))
|
||||
camera = new camera(src)
|
||||
camera.set_status(0)
|
||||
@@ -92,15 +96,42 @@
|
||||
if(camera)
|
||||
camera.set_status(!camera.status)
|
||||
if(camera.status)
|
||||
camera.c_tag = FindNameFromID(usr)
|
||||
to_chat(usr, SPAN_NOTICE("User scanned as [camera.c_tag]. Camera activated."))
|
||||
camera.c_tag = FindNameFromID(user)
|
||||
to_chat(user, SPAN_NOTICE("User scanned as [camera.c_tag]. Camera activated."))
|
||||
else
|
||||
to_chat(usr, SPAN_NOTICE("Camera deactivated."))
|
||||
to_chat(user, SPAN_NOTICE("Camera deactivated."))
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/toggle_expedition_camera_network()
|
||||
set name = "Helmet Camera - Toggle Expedition Network"
|
||||
set category = "Object.Equipped"
|
||||
set src in usr
|
||||
|
||||
toggle_expedition_camera_network_for(usr)
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/toggle_expedition_camera_network_for(mob/user)
|
||||
if(ispath(camera))
|
||||
camera = new camera(src)
|
||||
camera.set_status(0)
|
||||
|
||||
if(!camera)
|
||||
return
|
||||
|
||||
if(NETWORK_EXPEDITION in camera.network)
|
||||
if(length(camera.network) == 1)
|
||||
to_chat(user, SPAN_WARNING("This camera is already an expedition camera."))
|
||||
return
|
||||
|
||||
camera.remove_network(NETWORK_EXPEDITION)
|
||||
to_chat(user, SPAN_NOTICE("Camera disconnected from the expedition network."))
|
||||
return
|
||||
|
||||
camera.add_network(NETWORK_EXPEDITION)
|
||||
to_chat(user, SPAN_NOTICE("Camera connected to the expedition network."))
|
||||
|
||||
/obj/item/clothing/head/helmet/space/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
|
||||
. = ..()
|
||||
if((distance <= 1) && camera)
|
||||
. += FONT_SMALL(SPAN_NOTICE("To toggle the helmet camera, right click the helmet and press <b>Toggle Helmet Camera</b>."))
|
||||
. += FONT_SMALL(SPAN_NOTICE("To toggle or configure the helmet camera, right-click the helmet for options, or equip it and view your new Object verbs."))
|
||||
. += "This helmet has a built-in camera. It's [!ispath(camera) && camera.status ? "" : "in"]active."
|
||||
|
||||
/obj/item/clothing/head/helmet/hos
|
||||
|
||||
@@ -25,6 +25,36 @@
|
||||
|
||||
module.holder.ui_interact(usr)
|
||||
|
||||
/obj/item/ai_verbs/verb/toggle_hardsuit_camera()
|
||||
set category = "Hardsuit"
|
||||
set name = "Helmet Camera - Toggle On/Off"
|
||||
set src in usr
|
||||
|
||||
var/obj/item/rig/rig = usr.get_rig()
|
||||
if(!istype(rig) || !rig.is_integrated_rig_ai(usr))
|
||||
to_chat(usr, SPAN_WARNING("You are not loaded into a hardsuit."))
|
||||
return
|
||||
if(!rig.helmet?.camera)
|
||||
to_chat(usr, SPAN_WARNING("\The [rig] has no helmet camera."))
|
||||
return
|
||||
|
||||
rig.helmet.toggle_camera_for(usr)
|
||||
|
||||
/obj/item/ai_verbs/verb/toggle_hardsuit_expedition_camera_network()
|
||||
set category = "Hardsuit"
|
||||
set name = "Helmet Camera - Toggle Expedition Network"
|
||||
set src in usr
|
||||
|
||||
var/obj/item/rig/rig = usr.get_rig()
|
||||
if(!istype(rig) || !rig.is_integrated_rig_ai(usr))
|
||||
to_chat(usr, SPAN_WARNING("You are not loaded into a hardsuit."))
|
||||
return
|
||||
if(!rig.helmet?.camera)
|
||||
to_chat(usr, SPAN_WARNING("\The [rig] has no helmet camera."))
|
||||
return
|
||||
|
||||
rig.helmet.toggle_expedition_camera_network_for(usr)
|
||||
|
||||
/obj/item/rig_module/ai_container
|
||||
name = "IIS module"
|
||||
desc = "An integrated intelligence system module suitable for most hardsuits."
|
||||
@@ -59,10 +89,17 @@
|
||||
/obj/item/rig_module/ai_container/proc/update_verb_holder()
|
||||
if(!verb_holder)
|
||||
verb_holder = new(src)
|
||||
var/mob/previous_user
|
||||
if(ismob(verb_holder.loc))
|
||||
previous_user = verb_holder.loc
|
||||
if(integrated_ai)
|
||||
verb_holder.forceMove(integrated_ai)
|
||||
else
|
||||
verb_holder.forceMove(src)
|
||||
if(previous_user?.client)
|
||||
previous_user.client.init_verbs()
|
||||
if(integrated_ai?.client && integrated_ai != previous_user)
|
||||
integrated_ai.client.init_verbs()
|
||||
|
||||
/obj/item/rig_module/ai_container/accepts_item(var/obj/item/input_device, var/mob/living/user)
|
||||
// Check if there's actually an AI to deal with.
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
icon_state = "syndicate"
|
||||
item_state = "bl_suit"
|
||||
worn_state = "syndicate"
|
||||
has_sensor = SUIT_NO_SENSORS
|
||||
armor = list(
|
||||
MELEE = ARMOR_MELEE_MINOR
|
||||
)
|
||||
@@ -36,6 +35,7 @@
|
||||
icon_state = "ninja"
|
||||
item_state = "ninja"
|
||||
worn_state = "ninja"
|
||||
has_sensor = SUIT_NO_SENSORS
|
||||
|
||||
/obj/item/clothing/under/syndicate/hammertail
|
||||
name = "\improper crimson jumpsuit"
|
||||
@@ -49,3 +49,4 @@
|
||||
item_state = "hammertail"
|
||||
worn_state = "hammertail"
|
||||
contained_sprite = TRUE
|
||||
has_sensor = SUIT_NO_SENSORS
|
||||
|
||||
@@ -240,6 +240,8 @@
|
||||
to_chat(user, SPAN_NOTICE("You climb into \the [src]."))
|
||||
user.forceMove(src)
|
||||
LAZYDISTINCTADD(pilots, user)
|
||||
add_verb(user, /mob/proc/toggle_exosuit_camera)
|
||||
add_verb(user, /mob/proc/change_exosuit_camera_network)
|
||||
RegisterSignal(user, COMSIG_MOB_FACEDIR, PROC_REF(handle_user_turn))
|
||||
RegisterSignal(user, COMSIG_INPUT_KEY_QUICK_EQUIP, PROC_REF(strafe_left))
|
||||
RegisterSignal(user, COMSIG_INPUT_KEY_DROP, PROC_REF(strafe_right))
|
||||
@@ -274,12 +276,92 @@
|
||||
user.client.eye = user
|
||||
if(user in pilots)
|
||||
set_intent(I_HURT)
|
||||
remove_verb(user, /mob/proc/toggle_exosuit_camera)
|
||||
remove_verb(user, /mob/proc/change_exosuit_camera_network)
|
||||
LAZYREMOVE(pilots, user)
|
||||
UnregisterSignal(user, COMSIG_MOB_FACEDIR)
|
||||
UnregisterSignal(user, COMSIG_INPUT_KEY_QUICK_EQUIP)
|
||||
UnregisterSignal(user, COMSIG_INPUT_KEY_DROP)
|
||||
UNSETEMPTY(pilots)
|
||||
|
||||
/mob/proc/change_exosuit_camera_network()
|
||||
set name = "Change Exosuit Camera Network"
|
||||
set category = "Exosuit Interface"
|
||||
|
||||
var/mob/living/heavy_vehicle/exosuit = loc
|
||||
if(!istype(exosuit) || !(src in exosuit.pilots))
|
||||
remove_verb(src, /mob/proc/change_exosuit_camera_network)
|
||||
return
|
||||
|
||||
var/obj/structure/machinery/camera/mech_camera = exosuit.camera
|
||||
if(!mech_camera)
|
||||
to_chat(src, SPAN_WARNING("\The [exosuit] has no camera."))
|
||||
return
|
||||
|
||||
var/datum/mind/controller_mind = old_mob ? old_mob.mind : mind
|
||||
var/list/available_networks = list(
|
||||
NETWORK_COMMAND,
|
||||
NETWORK_ENGINEERING,
|
||||
NETWORK_MEDICAL,
|
||||
NETWORK_MINE,
|
||||
NETWORK_RESEARCH,
|
||||
NETWORK_SECURITY,
|
||||
NETWORK_SUPPLY,
|
||||
NETWORK_SERVICE,
|
||||
NETWORK_EXPEDITION,
|
||||
NETWORK_NEWS
|
||||
)
|
||||
if(player_is_antag(controller_mind))
|
||||
available_networks += NETWORK_MECHS
|
||||
|
||||
var/default_network = mech_camera.network[1]
|
||||
if(!(default_network in available_networks))
|
||||
default_network = null
|
||||
|
||||
var/chosen_network = tgui_input_list(src, "Select a camera network for \the [exosuit].", "Exosuit Camera Network", available_networks, default_network)
|
||||
if(!chosen_network || !(chosen_network in available_networks))
|
||||
return
|
||||
if(chosen_network == NETWORK_MECHS && !player_is_antag(controller_mind))
|
||||
return
|
||||
if(QDELETED(exosuit) || loc != exosuit || !(src in exosuit.pilots) || QDELETED(mech_camera) || exosuit.camera != mech_camera)
|
||||
return
|
||||
|
||||
if(length(mech_camera.network) == 1 && mech_camera.network[1] == chosen_network)
|
||||
to_chat(src, SPAN_NOTICE("\The [exosuit]'s camera is already connected to [chosen_network]."))
|
||||
return
|
||||
|
||||
var/list/old_networks = mech_camera.network.Copy()
|
||||
for(var/old_network in old_networks)
|
||||
if(old_network != chosen_network)
|
||||
mech_camera.remove_network(old_network)
|
||||
mech_camera.add_network(chosen_network)
|
||||
to_chat(src, SPAN_NOTICE("\The [exosuit]'s camera network is now [chosen_network]."))
|
||||
|
||||
/mob/proc/toggle_exosuit_camera()
|
||||
set name = "Exosuit Camera - Toggle On/Off"
|
||||
set category = "Exosuit Interface"
|
||||
|
||||
var/mob/living/heavy_vehicle/exosuit = loc
|
||||
if(!istype(exosuit) || !(src in exosuit.pilots))
|
||||
remove_verb(src, /mob/proc/toggle_exosuit_camera)
|
||||
return
|
||||
|
||||
if(!exosuit.camera)
|
||||
to_chat(src, SPAN_WARNING("\The [exosuit] has no camera."))
|
||||
return
|
||||
|
||||
exosuit.camera_enabled = !exosuit.camera_enabled
|
||||
var/camera_functional = exosuit.head?.camera && exosuit.head.camera.is_functional()
|
||||
exosuit.camera.set_status(exosuit.camera_enabled && camera_functional)
|
||||
|
||||
if(exosuit.camera_enabled)
|
||||
if(exosuit.camera.status)
|
||||
to_chat(src, SPAN_NOTICE("\The [exosuit]'s camera is now active."))
|
||||
else
|
||||
to_chat(src, SPAN_WARNING("\The [exosuit]'s camera cannot be activated due to hardware damage."))
|
||||
else
|
||||
to_chat(src, SPAN_NOTICE("\The [exosuit]'s camera is now inactive."))
|
||||
|
||||
/mob/living/heavy_vehicle/proc/handle_user_turn(var/mob/living/user, var/direction)
|
||||
SIGNAL_HANDLER
|
||||
INVOKE_ASYNC(src, TYPE_PROC_REF(/atom, relaymove), user, direction, TRUE)
|
||||
@@ -655,6 +737,9 @@ GLOBAL_DATUM_INIT(mech_state, /datum/ui_state/default, new())
|
||||
if(!new_name || new_name == name || (user != src && !(user in pilots)))
|
||||
return
|
||||
name = new_name
|
||||
if(camera)
|
||||
camera.c_tag = name
|
||||
invalidateCameraCache()
|
||||
to_chat(user, SPAN_NOTICE("You have redesignated this exosuit as \the [name]."))
|
||||
|
||||
/mob/living/heavy_vehicle/proc/trample(var/mob/living/H)
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
for(var/thing in pilots)
|
||||
var/mob/pilot = thing
|
||||
if(pilot.loc != src) // Admin jump or teleport/grab.
|
||||
remove_verb(pilot, /mob/proc/toggle_exosuit_camera)
|
||||
remove_verb(pilot, /mob/proc/change_exosuit_camera_network)
|
||||
if(pilot.client)
|
||||
pilot.client.screen -= hud_elements
|
||||
LAZYREMOVE(pilots, pilot)
|
||||
UNSETEMPTY(pilots)
|
||||
LAZYREMOVE(pilots, pilot)
|
||||
UNSETEMPTY(pilots)
|
||||
|
||||
if(radio)
|
||||
var/radio_check = head?.radio && head.radio.is_functional() && get_cell()
|
||||
@@ -26,7 +28,9 @@
|
||||
radio.set_on(radio_check)
|
||||
|
||||
if(camera)
|
||||
camera.status = (head?.camera && head.camera.is_functional())
|
||||
var/camera_status = camera_enabled && head?.camera && head.camera.is_functional()
|
||||
if(camera.status != camera_status)
|
||||
camera.set_status(camera_status)
|
||||
|
||||
if(body)
|
||||
body.update_air(hatch_closed && use_air)
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
var/obj/item/radio/exosuit/radio
|
||||
var/obj/structure/machinery/camera/camera
|
||||
/// Whether pilots want the external camera to broadcast while its hardware is functional
|
||||
var/camera_enabled = TRUE
|
||||
|
||||
var/wreckage_path = /obj/structure/mech_wreckage
|
||||
|
||||
@@ -119,6 +121,8 @@
|
||||
pilot.client.screen -= hud_elements
|
||||
pilot.client.images -= hud_elements
|
||||
if (!QDELETED(pilot)) // Forcemove doesn't accept QDELETED inputs.
|
||||
remove_verb(pilot, /mob/proc/toggle_exosuit_camera)
|
||||
remove_verb(pilot, /mob/proc/change_exosuit_camera_network)
|
||||
pilot.forceMove(get_turf(src))
|
||||
pilots = null
|
||||
|
||||
@@ -337,6 +341,9 @@
|
||||
|
||||
remote = TRUE
|
||||
name = name + " \"[pick("Jaeger", "Reaver", "Templar", "Juggernaut", "Basilisk")]-[rand(0, 999)]\""
|
||||
if(camera)
|
||||
camera.c_tag = name
|
||||
invalidateCameraCache()
|
||||
if(!remote_network)
|
||||
remote_network = REMOTE_GENERIC_MECH
|
||||
SSvirtualreality.add_mech(src, remote_network)
|
||||
|
||||
@@ -361,8 +361,8 @@
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera
|
||||
name = "video camera circuit"
|
||||
desc = "Creates a camera feed from the assembly's position."
|
||||
extended_desc = "Creates a camera feed. It uses the Research camera network by default, but the network can be changed."
|
||||
desc = "This small camera allows a remote viewer to see what it sees."
|
||||
extended_desc = "Creates a camera feed. It uses the Expedition camera network by default, but the network can be changed."
|
||||
icon_state = "video_camera"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 10
|
||||
@@ -372,12 +372,12 @@
|
||||
"camera active" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
inputs_default = list("1" = "video camera circuit",
|
||||
"2" = "Research")
|
||||
"2" = "Expedition")
|
||||
outputs = list()
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_idle = 5 // Raises to 200 when on.
|
||||
var/obj/structure/machinery/camera/network/research/camera
|
||||
var/obj/structure/machinery/camera/network/expedition/camera
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
on_open_network = TRUE
|
||||
GLOB.cameranet.add_source(src)
|
||||
else
|
||||
GLOB.cameranet.update_visibility(src)
|
||||
GLOB.cameranet.update_visibility(src, FALSE)
|
||||
|
||||
invalidateCameraCache()
|
||||
|
||||
@@ -2325,9 +2325,7 @@
|
||||
|
||||
/mob/living/proc/look_up_open_space(var/turf/T)
|
||||
if(client && !MOB_IS_INCAPACITATED(INCAPACITATION_DISABLED))
|
||||
if(z_eye)
|
||||
reset_view(null)
|
||||
QDEL_NULL(z_eye)
|
||||
if(z_eye && clear_z_eye())
|
||||
return
|
||||
var/turf/above = GET_TURF_ABOVE(T)
|
||||
if(TURF_IS_MIMICING(above))
|
||||
@@ -2348,9 +2346,7 @@
|
||||
|
||||
/mob/living/proc/look_down_open_space(var/turf/T)
|
||||
if(client && !MOB_IS_INCAPACITATED(INCAPACITATION_DISABLED))
|
||||
if(z_eye)
|
||||
reset_view(null)
|
||||
QDEL_NULL(z_eye)
|
||||
if(z_eye && clear_z_eye())
|
||||
return
|
||||
if(TURF_IS_MIMICING(T) && GET_TURF_BELOW(T))
|
||||
z_eye = new /atom/movable/z_observer/z_down(T, src, T)
|
||||
|
||||
@@ -923,6 +923,9 @@ default behaviour is:
|
||||
|
||||
/mob/living/Destroy()
|
||||
cameraFollow = null
|
||||
if(camera_view_cancel_action)
|
||||
camera_view_cancel_action.Remove(src)
|
||||
QDEL_NULL(camera_view_cancel_action)
|
||||
if (length(actions))
|
||||
for (var/datum/action/action in actions)
|
||||
action.Remove(src)
|
||||
|
||||
@@ -502,6 +502,8 @@
|
||||
if(A.CheckRemoval(src))
|
||||
A.Remove(src)
|
||||
|
||||
update_camera_view_action()
|
||||
|
||||
for(var/obj/item/I in src)
|
||||
if(!I.action_button_name)
|
||||
continue
|
||||
@@ -549,6 +551,41 @@
|
||||
|
||||
return
|
||||
|
||||
/mob/living/proc/is_viewing_z_eye()
|
||||
return client && z_eye && client.eye == z_eye
|
||||
|
||||
/mob/living/is_viewing_remote_view()
|
||||
return ..() || is_viewing_z_eye()
|
||||
|
||||
/mob/living/proc/clear_z_eye()
|
||||
if(!z_eye)
|
||||
return FALSE
|
||||
var/was_viewing_z_eye = is_viewing_z_eye()
|
||||
if(was_viewing_z_eye)
|
||||
reset_view(null)
|
||||
QDEL_NULL(z_eye)
|
||||
update_camera_view_action()
|
||||
return was_viewing_z_eye
|
||||
|
||||
/mob/living/proc/update_camera_view_action()
|
||||
if(is_viewing_remote_view())
|
||||
if(!camera_view_cancel_action)
|
||||
camera_view_cancel_action = new
|
||||
camera_view_cancel_action.Grant(src)
|
||||
else if(camera_view_cancel_action?.owner)
|
||||
camera_view_cancel_action.Remove(src)
|
||||
|
||||
/mob/living/proc/cancel_remote_view()
|
||||
if(istype(machine, /obj/structure/machinery/computer/ship))
|
||||
var/obj/structure/machinery/computer/ship/ship_console = machine
|
||||
if(ship_console.viewing_overmap(src))
|
||||
ship_console.unlook(src)
|
||||
update_camera_view_action()
|
||||
return
|
||||
|
||||
cancel_camera()
|
||||
update_camera_view_action()
|
||||
|
||||
/mob/living/update_action_buttons()
|
||||
if(!hud_used) return
|
||||
if(!client) return
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
var/mob/living/cameraFollow = null
|
||||
var/list/datum/action/actions = list()
|
||||
var/datum/action/cancel_camera_view/camera_view_cancel_action
|
||||
|
||||
/// Time of death
|
||||
var/tod = null
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
src.unset_machine()
|
||||
src.reset_view(null)
|
||||
return 0
|
||||
if (stat == 2 || !C.status || !(src.network in C.network)) return 0
|
||||
if (stat == 2 || !C.can_use() || !(src.network in C.network)) return 0
|
||||
|
||||
// ok, we're alive, camera is good and in our network...
|
||||
|
||||
|
||||
@@ -411,8 +411,20 @@
|
||||
else
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
client.eye = loc
|
||||
if(istype(src, /mob/living))
|
||||
var/mob/living/living_mob = src
|
||||
living_mob.update_camera_view_action()
|
||||
return
|
||||
|
||||
/mob/proc/is_viewing_camera()
|
||||
return client && istype(client.eye, /obj/structure/machinery/camera)
|
||||
|
||||
/mob/proc/is_viewing_overmap()
|
||||
return client && istype(client.eye, /obj/effect/overmap)
|
||||
|
||||
/mob/proc/is_viewing_remote_view()
|
||||
return is_viewing_camera() || is_viewing_overmap()
|
||||
|
||||
|
||||
/mob/proc/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
@@ -716,6 +728,9 @@
|
||||
set name = "Cancel Camera View"
|
||||
set category = "OOC"
|
||||
unset_machine()
|
||||
if(isliving(src))
|
||||
var/mob/living/living_mob = src
|
||||
living_mob.clear_z_eye()
|
||||
reset_view(null)
|
||||
|
||||
/mob/Topic(href, href_list)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
|
||||
|
||||
// This is the NTNet datum. There can be only one NTNet datum in game at once. Modular computers read data from this.
|
||||
/// This is the NTNet datum. There can be only one NTNet datum in game at once. Modular computers read data from this.
|
||||
/datum/ntnet
|
||||
var/list/relays = list()
|
||||
var/list/logs = list()
|
||||
@@ -13,22 +13,24 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
var/list/available_news = list()
|
||||
var/list/fileservers = list()
|
||||
var/list/datum/ntnet_account/users = list()
|
||||
// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.
|
||||
// High values make displaying logs much laggier.
|
||||
/// Amount of logs the system tries to keep in memory. Keep below 999 to prevent byond from acting weirdly.
|
||||
/// High values make displaying logs much laggier.
|
||||
var/setting_maxlogcount = 100
|
||||
|
||||
// These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections
|
||||
/// These only affect wireless. LAN (consoles) are unaffected since it would be possible to create scenario where someone turns off NTNet, and is unable to turn it back on since it refuses connections
|
||||
var/setting_softwaredownload = TRUE
|
||||
var/setting_peertopeer = TRUE
|
||||
var/setting_communication = TRUE
|
||||
var/setting_systemcontrol = TRUE
|
||||
var/setting_disabled = FALSE // Setting to 1 will disable all wireless, independently on relays status.
|
||||
|
||||
var/intrusion_detection_enabled = TRUE // Whether the IDS warning system is enabled
|
||||
var/intrusion_detection_alarm = FALSE // Set when there is an IDS warning due to malicious (antag) software.
|
||||
/// Setting to 1 will disable all wireless, independently on relays status.
|
||||
var/setting_disabled = FALSE
|
||||
/// Whether the IDS warning system is enabled
|
||||
var/intrusion_detection_enabled = TRUE
|
||||
/// Set when there is an IDS warning due to malicious (antag) software.
|
||||
var/intrusion_detection_alarm = FALSE
|
||||
|
||||
|
||||
// If new NTNet datum is spawned, it replaces the old one.
|
||||
/// If new NTNet datum is spawned, it replaces the old one.
|
||||
/datum/ntnet/New()
|
||||
if(GLOB.ntnet_global && (GLOB.ntnet_global != src))
|
||||
GLOB.ntnet_global = src // There can be only one.
|
||||
@@ -41,7 +43,7 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
//add some default channels
|
||||
new /datum/ntnet_conversation("NTNet Relay", TRUE)
|
||||
|
||||
// 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.
|
||||
/datum/ntnet/proc/add_log(var/log_string, var/obj/item/computer_hardware/network_card/source = null, var/messaging=FALSE)
|
||||
var/log_text = "[worldtime2text()] - "
|
||||
if(source)
|
||||
@@ -62,18 +64,9 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
else
|
||||
break
|
||||
|
||||
// Checks whether NTNet operates. If parameter is passed checks whether specific function is enabled.
|
||||
/// Checks whether NTNet's core service operates. If parameter is passed checks whether specific function is enabled.
|
||||
/datum/ntnet/proc/check_function(var/specific_action = 0)
|
||||
if(!relays || !relays.len) // No relays found. NTNet is down
|
||||
return FALSE
|
||||
|
||||
var/operating = FALSE
|
||||
|
||||
// Check all relays. If we have at least one working relay, network is up.
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in relays)
|
||||
if(R.operable())
|
||||
operating = TRUE
|
||||
break
|
||||
var/operating = has_operable_core()
|
||||
|
||||
if(setting_disabled)
|
||||
return FALSE
|
||||
@@ -88,7 +81,79 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
return (operating && setting_systemcontrol)
|
||||
return operating
|
||||
|
||||
// Builds lists that contain downloadable software.
|
||||
/datum/ntnet/proc/check_endpoint_function(var/specific_action = 0, var/ethernet = FALSE)
|
||||
// Wireless firewall toggles do not affect wired endpoints, but wired endpoints still need a live core service
|
||||
if(ethernet)
|
||||
return has_operable_core()
|
||||
return check_function(specific_action)
|
||||
|
||||
/datum/ntnet/proc/has_operable_core()
|
||||
if(!relays || !relays.len)
|
||||
return FALSE
|
||||
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in relays)
|
||||
if(R.provides_core_service())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// 'For endpoint' signifies that sometimes we will abstract a device as being a modular computer when really all we care about is whether it is networked.
|
||||
/// This will likely need to be simplified in future.
|
||||
/datum/ntnet/proc/get_signal_for_endpoint(var/atom/endpoint, var/specific_action = 0, var/ethernet = FALSE, var/long_range = FALSE)
|
||||
if(!istype(endpoint))
|
||||
return 0
|
||||
|
||||
var/turf/endpoint_turf = get_turf(endpoint)
|
||||
if(SSatlas.current_map.is_always_available_network_level(endpoint_turf?.z))
|
||||
if(ethernet)
|
||||
return 3
|
||||
if(long_range)
|
||||
return 2
|
||||
return 1
|
||||
|
||||
if(!check_endpoint_function(specific_action, ethernet))
|
||||
return 0
|
||||
|
||||
var/area/A = get_area(endpoint)
|
||||
if(A?.centcomm_area && ethernet)
|
||||
return 3
|
||||
|
||||
var/signal = 0
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in relays)
|
||||
signal = max(signal, R.get_signal_for_endpoint(endpoint, ethernet, long_range))
|
||||
return signal
|
||||
|
||||
/datum/ntnet/proc/get_signal(var/obj/item/computer_hardware/network_card/card, var/specific_action = 0)
|
||||
if(!istype(card) || !card.parent_computer)
|
||||
return 0
|
||||
return get_signal_for_endpoint(card.parent_computer, specific_action, card.ethernet, card.long_range)
|
||||
|
||||
/datum/ntnet/proc/get_reachable_z_levels_for_endpoint(var/atom/endpoint, var/specific_action = 0, var/ethernet = FALSE, var/long_range = FALSE)
|
||||
. = list()
|
||||
var/turf/endpoint_turf = get_turf(endpoint)
|
||||
if(SSatlas.current_map.is_always_available_network_level(endpoint_turf?.z))
|
||||
. |= endpoint_turf.z
|
||||
return
|
||||
if(get_signal_for_endpoint(endpoint, specific_action, ethernet, long_range) <= 0)
|
||||
return
|
||||
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in relays)
|
||||
if(R.can_route_to_core())
|
||||
. |= R.get_covered_z_levels()
|
||||
|
||||
/datum/ntnet/proc/get_reachable_z_levels(var/obj/item/computer_hardware/network_card/card, var/specific_action = 0)
|
||||
. = list()
|
||||
var/turf/endpoint_turf = get_turf(card?.parent_computer)
|
||||
if(SSatlas.current_map.is_always_available_network_level(endpoint_turf?.z))
|
||||
. |= endpoint_turf.z
|
||||
return
|
||||
if(get_signal(card, specific_action) <= 0)
|
||||
return
|
||||
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in relays)
|
||||
if(R.can_route_to_core())
|
||||
. |= R.get_covered_z_levels()
|
||||
|
||||
/// Builds lists that contain downloadable software.
|
||||
/datum/ntnet/proc/build_software_lists()
|
||||
available_station_software = list()
|
||||
available_antag_software = list()
|
||||
@@ -109,7 +174,7 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
var/datum/modular_computer_app_presets/prs = new path()
|
||||
available_software_presets.Add(prs)
|
||||
|
||||
// Builds lists that contain downloadable software.
|
||||
/// 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/))
|
||||
@@ -117,14 +182,13 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
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)
|
||||
for(var/datum/computer_file/program/P in available_software)
|
||||
if(filename == P.filename)
|
||||
return P
|
||||
|
||||
// Resets the IDS alarm
|
||||
/// Resets the IDS alarm
|
||||
/datum/ntnet/proc/resetIDS()
|
||||
intrusion_detection_alarm = FALSE
|
||||
|
||||
@@ -132,13 +196,13 @@ GLOBAL_DATUM_INIT(ntnet_global, /datum/ntnet, new)
|
||||
resetIDS()
|
||||
intrusion_detection_enabled = !intrusion_detection_enabled
|
||||
|
||||
// Removes all logs
|
||||
/// Removes all logs
|
||||
/datum/ntnet/proc/purge_logs()
|
||||
logs = list()
|
||||
messages = list()
|
||||
add_log("-!- LOGS DELETED BY SYSTEM OPERATOR -!-")
|
||||
|
||||
// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
|
||||
/// Updates maximal amount of stored logs. Use this instead of setting the number, it performs required checks.
|
||||
/datum/ntnet/proc/update_max_log_count(var/lognumber)
|
||||
if(!lognumber)
|
||||
return FALSE
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Relays don't handle any actual communication. Global NTNet datum does that, relays only tell the datum if it should or shouldn't work.
|
||||
/obj/structure/machinery/ntnet_relay
|
||||
name = "NTNet Quantum Relay"
|
||||
desc = "A very complex router and transmitter capable of connecting electronic devices together. Looks fragile."
|
||||
desc = "A very complex core router and transmitter capable of connecting electronic devices together. Looks fragile."
|
||||
use_power = POWER_USE_ACTIVE
|
||||
active_power_usage = 20000 //20kW, appropriate for machine that keeps massive cross-Zlevel wireless network operational.
|
||||
idle_power_usage = 100
|
||||
@@ -9,22 +8,34 @@
|
||||
icon = 'icons/obj/machinery/telecomms.dmi'
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/datum/ntnet/NTNet // This is mostly for backwards reference and to allow varedit modifications from ingame.
|
||||
var/enabled = TRUE // Set to FALSE if the relay was turned off
|
||||
var/dos_failure = FALSE // Set to TRUE if the relay failed due to (D)DoS attack
|
||||
var/list/dos_sources = list() // Backwards reference for qdel() stuff
|
||||
/// This is mostly for backwards reference and to allow varedit modifications from ingame.
|
||||
var/datum/ntnet/NTNet
|
||||
/// Set to FALSE if the relay was turned off
|
||||
var/enabled = TRUE
|
||||
/// Set to TRUE if the relay failed due to (D)DoS attack
|
||||
var/dos_failure = FALSE
|
||||
/// Backwards reference for qdel() stuff
|
||||
var/list/dos_sources = list()
|
||||
/// Core relays are the NTNet source of truth. Field relays only extend a live core.
|
||||
var/core_service = TRUE
|
||||
/// Overmap tile range from this relay's sector to an operable core.
|
||||
var/backhaul_range = 0
|
||||
|
||||
// Denial of Service attack variables
|
||||
var/dos_overload = 0 // Amount of DoS "packets" in this relay's buffer
|
||||
var/dos_capacity = 500 // Amount of DoS "packets" in buffer required to crash the relay
|
||||
var/dos_dissipate = 1 // Amount of DoS "packets" dissipated over time.
|
||||
|
||||
/// Amount of DoS "packets" in this relay's buffer
|
||||
var/dos_overload = 0
|
||||
/// Amount of DoS "packets" in buffer required to crash the relay
|
||||
var/dos_capacity = 500
|
||||
/// Amount of DoS "packets" dissipated over time.
|
||||
var/dos_dissipate = 1
|
||||
component_types = list(
|
||||
/obj/item/stack/cable_coil{amount = 15},
|
||||
/obj/item/circuitboard/ntnet_relay
|
||||
/obj/item/circuitboard/ntnet_relay,
|
||||
/obj/item/stack/cable_coil = 15,
|
||||
/obj/item/stock_parts/micro_laser/high = 2,
|
||||
/obj/item/stock_parts/subspace/filter,
|
||||
/obj/item/stock_parts/subspace/crystal
|
||||
)
|
||||
|
||||
// TODO: Implement more logic here. For now it's only a placeholder.
|
||||
/obj/structure/machinery/ntnet_relay/operable()
|
||||
if(!..(EMPED))
|
||||
return FALSE
|
||||
@@ -34,6 +45,90 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/provides_core_service()
|
||||
return core_service && operable() && is_valid_core_location()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/ensure_linked()
|
||||
if(!SSatlas.current_map.use_overmap)
|
||||
return linked
|
||||
if(istype(linked) && (z in linked.map_z))
|
||||
return linked
|
||||
linked = null
|
||||
return sync_linked()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/is_valid_core_location()
|
||||
if(!SSatlas.current_map.use_overmap)
|
||||
return TRUE
|
||||
var/obj/effect/overmap/visitable/sector = ensure_linked()
|
||||
if(istype(sector))
|
||||
return sector.base
|
||||
var/obj/effect/overmap/visitable/known_sector = GLOB.map_sectors["[z]"]
|
||||
if(istype(known_sector))
|
||||
return FALSE
|
||||
return is_station_level(z)
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/can_route_to_core()
|
||||
if(!operable())
|
||||
return FALSE
|
||||
if(core_service)
|
||||
return provides_core_service()
|
||||
if(!GLOB.ntnet_global)
|
||||
return FALSE
|
||||
return !!get_backhaul_core()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/get_backhaul_core()
|
||||
if(!GLOB.ntnet_global)
|
||||
return
|
||||
ensure_linked()
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in GLOB.ntnet_global.relays)
|
||||
if(R == src || !R.provides_core_service())
|
||||
continue
|
||||
if(can_backhaul_to(R))
|
||||
return R
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/can_backhaul_to(var/obj/structure/machinery/ntnet_relay/core)
|
||||
if(!istype(core) || !core.provides_core_service())
|
||||
return FALSE
|
||||
if(SSatlas.current_map.use_overmap)
|
||||
var/obj/effect/overmap/visitable/source_sector = ensure_linked()
|
||||
var/obj/effect/overmap/visitable/core_sector = core.ensure_linked()
|
||||
if(!istype(source_sector) || !istype(core_sector))
|
||||
return FALSE
|
||||
return get_dist(source_sector, core_sector) <= backhaul_range
|
||||
return AreConnectedZLevels(z, core.z)
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/get_covered_z_levels()
|
||||
if(SSatlas.current_map.use_overmap)
|
||||
var/obj/effect/overmap/visitable/sector = ensure_linked()
|
||||
if(istype(sector))
|
||||
return sector.map_z.Copy()
|
||||
return list()
|
||||
return GetConnectedZlevels(z)
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/covers_z(var/z_level)
|
||||
if(!z_level || !can_route_to_core())
|
||||
return FALSE
|
||||
return z_level in get_covered_z_levels()
|
||||
|
||||
/// 'For endpoint' signifies that sometimes we will abstract a device as being a modular computer when really all we care about is whether it is networked.
|
||||
/// This will likely need to be simplified in future.
|
||||
/obj/structure/machinery/ntnet_relay/proc/get_signal_for_endpoint(var/atom/endpoint, var/ethernet = FALSE, var/long_range = FALSE)
|
||||
if(!istype(endpoint))
|
||||
return 0
|
||||
var/turf/T = get_turf(endpoint)
|
||||
if(!istype(T) || !covers_z(T.z))
|
||||
return 0
|
||||
if(ethernet)
|
||||
return 3
|
||||
if(long_range)
|
||||
return 2
|
||||
return 1
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/proc/get_signal(var/obj/item/computer_hardware/network_card/card)
|
||||
if(!istype(card) || !card.parent_computer)
|
||||
return 0
|
||||
return get_signal_for_endpoint(card.parent_computer, card.ethernet, card.long_range)
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/update_icon()
|
||||
ClearOverlays()
|
||||
if(operable())
|
||||
@@ -76,11 +171,18 @@
|
||||
ui.open()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/ui_data(mob/user)
|
||||
var/obj/structure/machinery/ntnet_relay/backhaul_core = core_service ? null : get_backhaul_core()
|
||||
var/backhaul_online = core_service ? can_route_to_core() : !!backhaul_core
|
||||
var/list/data = list()
|
||||
data["enabled"] = enabled
|
||||
data["dos_capacity"] = dos_capacity
|
||||
data["dos_overload"] = dos_overload
|
||||
data["dos_crashed"] = dos_failure
|
||||
data["relay_class"] = core_service ? "Core" : "Field"
|
||||
data["linked_sector"] = linked ? linked.name : "Unlinked"
|
||||
data["backhaul_range"] = backhaul_range
|
||||
data["backhaul_online"] = backhaul_online
|
||||
data["backhaul_core"] = core_service ? "Self" : (backhaul_core?.linked ? backhaul_core.linked.name : "None")
|
||||
|
||||
return data
|
||||
|
||||
@@ -113,8 +215,13 @@
|
||||
if(GLOB.ntnet_global)
|
||||
GLOB.ntnet_global.relays.Add(src)
|
||||
NTNet = GLOB.ntnet_global
|
||||
sync_linked()
|
||||
GLOB.ntnet_global.add_log("New quantum relay activated. Current amount of linked relays: [NTNet.relays.len]")
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/LateInitialize()
|
||||
. = ..()
|
||||
sync_linked()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/Destroy()
|
||||
if(GLOB.ntnet_global)
|
||||
GLOB.ntnet_global.relays.Remove(src)
|
||||
@@ -140,3 +247,18 @@
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/machinery/ntnet_relay/field
|
||||
name = "NTNet Field Relay"
|
||||
desc = "A deployable NTNet relay that extends local network coverage while it has short-range backhaul to an operational core relay."
|
||||
active_power_usage = 5000
|
||||
enabled = FALSE
|
||||
core_service = FALSE
|
||||
backhaul_range = 1
|
||||
component_types = list(
|
||||
/obj/item/circuitboard/ntnet_relay/field,
|
||||
/obj/item/stack/cable_coil = 15,
|
||||
/obj/item/stock_parts/micro_laser/high = 2,
|
||||
/obj/item/stock_parts/subspace/filter,
|
||||
/obj/item/stock_parts/subspace/crystal
|
||||
)
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
/obj/item/modular_computer/Destroy()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
|
||||
reset_remote_viewers(TRUE)
|
||||
|
||||
SStgui.close_uis(src)
|
||||
enabled = FALSE
|
||||
|
||||
@@ -289,6 +291,7 @@
|
||||
active_program = null
|
||||
else
|
||||
return FALSE
|
||||
reset_remote_viewers()
|
||||
var/mob/user = usr
|
||||
if(user && istype(user) && !forced && !QDELETED(src))
|
||||
INVOKE_ASYNC(src, TYPE_PROC_REF(/datum, ui_interact), user) // Re-open the UI on this computer. It should show the main screen now.
|
||||
@@ -304,6 +307,14 @@
|
||||
active_program = null
|
||||
else
|
||||
return FALSE
|
||||
reset_remote_viewers()
|
||||
|
||||
/obj/item/modular_computer/proc/reset_remote_viewers(var/unset_viewers_machine = FALSE)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.machine == src && M.is_viewing_remote_view())
|
||||
if(unset_viewers_machine)
|
||||
M.unset_machine()
|
||||
M.reset_view(null)
|
||||
|
||||
// Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on)
|
||||
/obj/item/modular_computer/proc/get_ntnet_status(var/specific_action = 0)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
data["isAI"] = isAI(user)
|
||||
data["crewmembers"] = list()
|
||||
if(SSradio.telecomms_ping(computer))
|
||||
for(var/z_level in SSatlas.current_map.map_levels)
|
||||
for(var/z_level in GLOB.ntnet_global.get_reachable_z_levels(computer.network_card))
|
||||
data["crewmembers"] += GLOB.crew_repository.health_data(z_level)
|
||||
|
||||
data["security_level"] = seclevel2num(get_security_level())
|
||||
|
||||
@@ -21,6 +21,16 @@
|
||||
|
||||
data["ntnetstatus"] = GLOB.ntnet_global.check_function()
|
||||
data["ntnetrelays"] = GLOB.ntnet_global.relays.len
|
||||
data["ntnetcores"] = 0
|
||||
data["ntnetfieldrelays"] = 0
|
||||
data["ntnetroutedrelays"] = 0
|
||||
for(var/obj/structure/machinery/ntnet_relay/R in GLOB.ntnet_global.relays)
|
||||
if(R.core_service)
|
||||
data["ntnetcores"]++
|
||||
else
|
||||
data["ntnetfieldrelays"]++
|
||||
if(R.can_route_to_core())
|
||||
data["ntnetroutedrelays"]++
|
||||
data["idsstatus"] = GLOB.ntnet_global.intrusion_detection_enabled
|
||||
data["idsalarm"] = GLOB.ntnet_global.intrusion_detection_alarm
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
return
|
||||
|
||||
switch(network)
|
||||
if(NETWORK_THUNDER, NETWORK_NEWS)
|
||||
if(NETWORK_THUNDER, NETWORK_NEWS, NETWORK_EXPEDITION)
|
||||
return FALSE
|
||||
if(NETWORK_REACTOR,NETWORK_ENGINEERING,NETWORK_ENGINEERING_OUTPOST,NETWORK_ALARM_ATMOS,NETWORK_ALARM_FIRE,NETWORK_ALARM_POWER)
|
||||
return ACCESS_ENGINE
|
||||
@@ -46,6 +46,15 @@
|
||||
var/current_network
|
||||
/// Used for camera monitor consoles from which this interface can be launched. If it exists, only provide that console's "console_networks" networks.
|
||||
var/list/monitored_networks = list()
|
||||
/// Used by non-modular camera consoles that run this program - abstracts as modular comp w/ network card.
|
||||
var/atom/ntnet_endpoint
|
||||
var/ntnet_endpoint_ethernet = FALSE
|
||||
var/ntnet_endpoint_long_range = FALSE
|
||||
|
||||
/datum/computer_file/program/camera_monitor/ui_host()
|
||||
if(ntnet_endpoint)
|
||||
return ntnet_endpoint
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/camera_monitor/ui_data(mob/user)
|
||||
var/list/data = initial_data()
|
||||
@@ -108,6 +117,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
/// If no network_access is passed, or if 0 is returned, we treat this as no camera access required. Allowed it.
|
||||
/datum/computer_file/program/camera_monitor/proc/can_access_network(var/mob/user, var/network_access)
|
||||
// No access passed, or 0 which is considered no access requirement. Allow it.
|
||||
if(!network_access)
|
||||
@@ -115,6 +125,19 @@
|
||||
|
||||
return (check_network_access(user, ACCESS_SECURITY) && GLOB.security_level >= SEC_LEVEL_BLUE) || check_network_access(user, network_access)
|
||||
|
||||
/datum/computer_file/program/camera_monitor/proc/can_reach_camera(var/obj/structure/machinery/camera/C)
|
||||
if(!C?.can_use())
|
||||
return FALSE
|
||||
|
||||
var/turf/camera_turf = get_turf(C)
|
||||
if(!camera_turf || !GLOB.ntnet_global)
|
||||
return FALSE
|
||||
|
||||
if(computer?.network_card)
|
||||
return (camera_turf.z in GLOB.ntnet_global.get_reachable_z_levels(computer.network_card, requires_ntnet_feature))
|
||||
|
||||
return (camera_turf.z in GLOB.ntnet_global.get_reachable_z_levels_for_endpoint(ntnet_endpoint, requires_ntnet_feature, ntnet_endpoint_ethernet, ntnet_endpoint_long_range))
|
||||
|
||||
/datum/computer_file/program/camera_monitor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -152,6 +175,10 @@
|
||||
usr.reset_view(current_camera)
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/camera_monitor/kill_program(forced)
|
||||
reset_current()
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/structure/machinery/camera/C)
|
||||
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
|
||||
if(isAI(user))
|
||||
@@ -164,7 +191,7 @@
|
||||
A.client.eye = A.eyeobj
|
||||
return TRUE
|
||||
|
||||
if(!is_contact_area(get_area(C)))
|
||||
if(!can_reach_camera(C))
|
||||
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
|
||||
return FALSE
|
||||
|
||||
@@ -186,6 +213,10 @@
|
||||
if(!current_camera)
|
||||
return 0
|
||||
|
||||
if(!can_reach_camera(current_camera))
|
||||
reset_current()
|
||||
return -1
|
||||
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
if(viewflag < 0)
|
||||
reset_current()
|
||||
@@ -194,6 +225,8 @@
|
||||
/datum/computer_file/program/camera_monitor/grants_equipment_vision(mob/user)
|
||||
if(user.stat || user.blinded || !current_camera)
|
||||
return FALSE
|
||||
if(!can_reach_camera(current_camera))
|
||||
return FALSE
|
||||
return current_camera.grants_equipment_vision(user)
|
||||
|
||||
/datum/computer_file/program/camera_monitor/proc/set_current(var/obj/structure/machinery/camera/C)
|
||||
@@ -233,8 +266,8 @@
|
||||
|
||||
/datum/computer_file/program/camera_monitor/news
|
||||
filename = "idcammon"
|
||||
filedesc = "Journalism Camera Monitoring"
|
||||
extended_desc = "This program allows remote access to station's camera system. Some camera networks may have additional access requirements. This version has has a connection to news networks."
|
||||
filedesc = "Public Camera Monitoring"
|
||||
extended_desc = "This program allows remote access to station's camera system. Some camera networks may have additional access requirements. This version has has a connection to news and expeditionary networks."
|
||||
size = 2
|
||||
required_access_download = null
|
||||
usage_flags = PROGRAM_ALL
|
||||
@@ -242,5 +275,5 @@
|
||||
/datum/computer_file/program/camera_monitor/news/modify_networks_list(var/list/networks)
|
||||
networks = list()
|
||||
networks.Add(list(list("tag" = NETWORK_NEWS, "has_access" = 1)))
|
||||
networks.Add(list(list("tag" = NETWORK_THUNDER, "has_access" = 1)))
|
||||
networks.Add(list(list("tag" = NETWORK_EXPEDITION, "has_access" = 1)))
|
||||
return networks
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
var/turf/mech_turf = get_turf(M)
|
||||
mechData["location"] = "[mech_turf.x], [mech_turf.y], [mech_turf.z]"
|
||||
|
||||
mechData["camera_status"] = M.camera.status
|
||||
mechData["camera_status"] = M.camera.can_use()
|
||||
mechData["lockdown"] = M.lockdown
|
||||
mechs += list(mechData)
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
A.client.eye = A.eyeobj
|
||||
return TRUE
|
||||
|
||||
if(!is_contact_area(get_area(C)))
|
||||
if(!can_reach_camera(C))
|
||||
to_chat(user, SPAN_NOTICE("This camera is too far away to connect to!"))
|
||||
return FALSE
|
||||
|
||||
@@ -130,6 +130,16 @@
|
||||
user.reset_view(current_camera)
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/penal_mechs/proc/can_reach_camera(var/obj/structure/machinery/camera/C)
|
||||
if(!C?.can_use())
|
||||
return FALSE
|
||||
|
||||
var/turf/camera_turf = get_turf(C)
|
||||
if(!camera_turf || !computer?.network_card || !GLOB.ntnet_global)
|
||||
return FALSE
|
||||
|
||||
return (camera_turf.z in GLOB.ntnet_global.get_reachable_z_levels(computer.network_card, requires_ntnet_feature))
|
||||
|
||||
/datum/computer_file/program/penal_mechs/proc/set_current(var/obj/structure/machinery/camera/C)
|
||||
if(current_camera == C)
|
||||
return
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/datum/computer_file/program/clientmanager/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["ntnet_status"] = GLOB.ntnet_global.check_function(NTNET_SOFTWAREDOWNLOAD)
|
||||
data["ntnet_status"] = computer.get_ntnet_status(NTNET_SOFTWAREDOWNLOAD)
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/clientmanager/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
if(action == "enroll")
|
||||
. = TRUE
|
||||
if(!GLOB.ntnet_global.check_function(NTNET_SOFTWAREDOWNLOAD))
|
||||
if(!computer.get_ntnet_status(NTNET_SOFTWAREDOWNLOAD))
|
||||
to_chat(ui.user, SPAN_WARNING("Cannot connect to NTNet download servers. Please try again later."))
|
||||
return
|
||||
if(params["enroll_type"] & DEVICE_COMPANY)
|
||||
|
||||
@@ -8,13 +8,19 @@ GLOBAL_VAR_INIT(ntnet_card_uid, 1)
|
||||
critical = FALSE
|
||||
icon_state = "netcard_basic"
|
||||
hardware_size = 1
|
||||
var/identification_id // Identification ID. Technically MAC address of this device. Can't be changed by user.
|
||||
var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user.
|
||||
/// Identification ID. Technically MAC address of this device. Can't be changed by user.
|
||||
var/identification_id
|
||||
/// Identification string, technically nickname seen in the network. Can be set by user.
|
||||
var/identification_string = ""
|
||||
var/long_range = FALSE
|
||||
var/ethernet = FALSE // Hard-wired, therefore always on, ignores NTNet wireless checks.
|
||||
var/obj/item/integrated_signaler/signal/sradio = FALSE // integrated signaler - not present on basic model.
|
||||
var/obj/item/integrated_signaler/signal/secondary_sradio = FALSE // second receiver for NTOS signaler software.
|
||||
var/obj/item/integrated_signaler/signal/transmit_sradio = FALSE // transmitter for NTOS signaler software.
|
||||
/// Hard-wired, therefore always on, ignores NTNet wireless checks.
|
||||
var/ethernet = FALSE
|
||||
/// integrated signaler - not present on basic model.
|
||||
var/obj/item/integrated_signaler/signal/sradio = FALSE
|
||||
/// second receiver for NTOS signaler software.
|
||||
var/obj/item/integrated_signaler/signal/secondary_sradio = FALSE
|
||||
/// transmitter for NTOS signaler software.
|
||||
var/obj/item/integrated_signaler/signal/transmit_sradio = FALSE
|
||||
malfunction_probability = 1
|
||||
|
||||
/obj/item/computer_hardware/network_card/diagnostics(mob/user)
|
||||
@@ -47,7 +53,7 @@ GLOBAL_VAR_INIT(ntnet_card_uid, 1)
|
||||
|
||||
/obj/item/computer_hardware/network_card/advanced
|
||||
name = "advanced NTNet network card"
|
||||
desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station."
|
||||
desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter can sustain high-bandwidth links to nearby NTNet relays."
|
||||
long_range = TRUE
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 2)
|
||||
power_usage = 150 // Better range but higher power usage.
|
||||
@@ -110,11 +116,11 @@ GLOBAL_VAR_INIT(ntnet_card_uid, 1)
|
||||
|
||||
return TRUE
|
||||
|
||||
// Returns a string identifier of this network card
|
||||
/// Returns a string identifier of this network card
|
||||
/obj/item/computer_hardware/network_card/proc/get_network_tag()
|
||||
return "[identification_string] (NID [identification_id])"
|
||||
|
||||
// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection
|
||||
/// 0 - No signal, 1 - Low signal, 2 - High signal. 3 - Wired Connection
|
||||
/obj/item/computer_hardware/network_card/proc/get_signal(var/specific_action = 0)
|
||||
if(!parent_computer) // Hardware is not installed in anything. No signal. How did this even get called?
|
||||
return 0
|
||||
@@ -122,27 +128,10 @@ GLOBAL_VAR_INIT(ntnet_card_uid, 1)
|
||||
return 0
|
||||
if(!check_functionality())
|
||||
return 0
|
||||
if(!GLOB.ntnet_global || !GLOB.ntnet_global.check_function(specific_action))
|
||||
if(!GLOB.ntnet_global)
|
||||
return 0
|
||||
|
||||
if(parent_computer)
|
||||
var/turf/T = get_turf(parent_computer)
|
||||
if((T && istype(T)) && is_station_level(T.z))
|
||||
// Computer is on station. Low/High signal depending on what type of network card you have
|
||||
if(ethernet)
|
||||
return 3
|
||||
else if(long_range)
|
||||
return 2
|
||||
else
|
||||
return 1
|
||||
var/area/A = get_area(parent_computer)
|
||||
if(A.centcomm_area && ethernet)
|
||||
return 3
|
||||
|
||||
if(long_range) // Computer is not on station, but it has upgraded network card. Low signal.
|
||||
return 1
|
||||
|
||||
return 0 // Computer is not on station and does not have upgraded network card. No signal.
|
||||
return GLOB.ntnet_global.get_signal_for_endpoint(parent_computer, specific_action, ethernet, long_range)
|
||||
|
||||
/obj/item/computer_hardware/network_card/Destroy()
|
||||
if(sradio)
|
||||
|
||||
@@ -112,6 +112,10 @@ GLOBAL_DATUM(map_overmap, /area/overmap)
|
||||
for(var/obj/structure/machinery/telecomms/T in SSmachinery.all_telecomms)
|
||||
if(T.linked == src)
|
||||
T.linked = null
|
||||
if(GLOB.ntnet_global)
|
||||
for(var/obj/structure/machinery/ntnet_relay/R as anything in GLOB.ntnet_global.relays)
|
||||
if(R.linked == src)
|
||||
R.linked = null
|
||||
if(entry_points)
|
||||
entry_points.Cut()
|
||||
for(var/obj/structure/machinery/ship_weapon/SW in ship_weapons)
|
||||
@@ -150,6 +154,9 @@ GLOBAL_DATUM(map_overmap, /area/overmap)
|
||||
H.attempt_hook_up(src)
|
||||
for(var/obj/structure/machinery/telecomms/T in SSmachinery.all_telecomms)
|
||||
T.attempt_hook_up(src)
|
||||
if(GLOB.ntnet_global)
|
||||
for(var/obj/structure/machinery/ntnet_relay/R as anything in GLOB.ntnet_global.relays)
|
||||
R.attempt_hook_up(src)
|
||||
|
||||
/obj/effect/overmap/visitable/proc/get_areas()
|
||||
return get_filtered_areas(list(/proc/area_belongs_to_zlevels = map_z))
|
||||
|
||||
@@ -254,6 +254,20 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
/obj/structure/machinery/computer/ship/proc/viewing_overmap(mob/user)
|
||||
return (WEAKREF(user) in viewers) || (linked && (WEAKREF(user) in linked.navigation_viewers))
|
||||
|
||||
/obj/structure/machinery/computer/ship/proc/unlook_all_viewers()
|
||||
if(!LAZYLEN(viewers))
|
||||
return
|
||||
|
||||
var/list/current_viewers = viewers.Copy()
|
||||
for(var/datum/weakref/W in current_viewers)
|
||||
var/mob/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
if(M.machine == src)
|
||||
M.unset_machine()
|
||||
else
|
||||
LAZYREMOVE(viewers, W)
|
||||
|
||||
/obj/structure/machinery/computer/ship/CouldNotUseTopic(mob/user)
|
||||
. = ..()
|
||||
unlook(user)
|
||||
@@ -274,6 +288,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
return SEE_THRU
|
||||
|
||||
/obj/structure/machinery/computer/ship/Destroy()
|
||||
unlook_all_viewers()
|
||||
if(linked)
|
||||
linked = null
|
||||
if(connected)
|
||||
@@ -284,13 +299,6 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
sensor_ref = null
|
||||
identification = null
|
||||
QDEL_NULL(sound_token)
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/datum/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
if(linked)
|
||||
LAZYREMOVE(linked.navigation_viewers, W)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/machinery/computer/ship/on_user_login(mob/M)
|
||||
|
||||
@@ -32,3 +32,8 @@
|
||||
name = "NTNet Quantum Relay"
|
||||
req_tech = list(TECH_DATA = 4)
|
||||
build_path = /obj/item/circuitboard/ntnet_relay
|
||||
|
||||
/datum/design/circuit/tcom/ntnet_relay/field
|
||||
name = "NTNet Field Relay"
|
||||
req_tech = list(TECH_DATA = 4)
|
||||
build_path = /obj/item/circuitboard/ntnet_relay/field
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
author: Batrachophrenoboocosmomachia
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds NTNet extensibility, requires new machinery constructed on away-site z-levels."
|
||||
- rscadd: "Breaks NTNet Relay machinery into Quantum Relay ('core' obj on Horizon) and Field Relay (deployable off-site constructions)."
|
||||
- rscadd: "Adds several public camera monitor consoles to the Horizon."
|
||||
- rscadd: "Adds some spare camera console boards to Horizon technical storage."
|
||||
- rscadd: "Adds camera toggle verb for hardsuits and exosuits."
|
||||
- rscadd: "Adds camera network configuration verb for helmet cams, hardsuits, and exosuits."
|
||||
- rscadd: "Adds linked AI/VR handling for new camera toggle/configuration verbs."
|
||||
- qol: "Embedded cameras (basically every video camera EXCEPT those which are installed on walls) can now be viewed from NTNet-connected z-level, not just connected ones."
|
||||
- qol: "Adds action button for 'cancel-camera-view' verb while viewing cameras or looking up/down z-level."
|
||||
- qol: "Antags get always-access to NTNet for crew manifest, apps, etc. while on z-level 4."
|
||||
- bugfix: "Fixes Jockey comms (frequency was missing from ANTAG_FREQS)."
|
||||
- bugfix: "Fixes look-up/look-down actions intermittently failing without first using cancel-camera-view."
|
||||
- bugfix: "Fixes camera assembly upgrades not applying correctly and not providing feedback text."
|
||||
@@ -84,6 +84,8 @@
|
||||
|
||||
/// Camera networks that will show up on the console.
|
||||
var/list/station_networks = list()
|
||||
/// Z-levels with local, always-on NTNet and camera connectivity, independent of station relays.
|
||||
var/list/always_available_network_levels = list()
|
||||
|
||||
/// map of string ids to /datum/holodeck_program instances
|
||||
var/list/holodeck_programs = list()
|
||||
@@ -189,6 +191,9 @@
|
||||
/datum/map/proc/get_network_access(var/network)
|
||||
return 0
|
||||
|
||||
/datum/map/proc/is_always_available_network_level(var/z_level)
|
||||
return z_level && (z_level in always_available_network_levels)
|
||||
|
||||
// By default transition randomly to another zlevel
|
||||
/datum/map/proc/get_transit_zlevel(var/current_z_level)
|
||||
var/list/candidates = SSatlas.current_map.accessible_z_levels.Copy()
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
admin_levels = list(4)
|
||||
contact_levels = list(1, 2, 3)
|
||||
always_available_network_levels = list(4)
|
||||
player_levels = list(1, 2, 3, 5)
|
||||
restricted_levels = list()
|
||||
accessible_z_levels = list("1" = 5, "2" = 5, "3" = 5, "5" = 75)
|
||||
@@ -72,7 +73,8 @@
|
||||
NETWORK_SECOND_DECK,
|
||||
NETWORK_THIRD_DECK,
|
||||
NETWORK_INTREPID,
|
||||
NETWORK_NEWS
|
||||
NETWORK_NEWS,
|
||||
NETWORK_EXPEDITION
|
||||
)
|
||||
|
||||
shuttle_docked_message = "Attention all hands: the shift change preparations are over. It will start in approximately %ETA%."
|
||||
|
||||
+4049
-4014
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,9 @@ import { NtosWindow } from '../layouts';
|
||||
export type MonitorData = {
|
||||
ntnetstatus: BooleanLike;
|
||||
ntnetrelays: number;
|
||||
ntnetcores: number;
|
||||
ntnetfieldrelays: number;
|
||||
ntnetroutedrelays: number;
|
||||
idsstatus: BooleanLike;
|
||||
idsalarm: BooleanLike;
|
||||
config_softwaredownload: BooleanLike;
|
||||
@@ -36,6 +39,15 @@ export const NTMonitor = (props) => {
|
||||
<LabeledList.Item label="Active NTNet Relays">
|
||||
{data.ntnetrelays}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Core Relays">
|
||||
{data.ntnetcores}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Field Relays">
|
||||
{data.ntnetfieldrelays}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Routed Relays">
|
||||
{data.ntnetroutedrelays}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="System Status">
|
||||
{data.ntnetstatus ? 'Enabled' : 'Disabled'}
|
||||
</LabeledList.Item>
|
||||
|
||||
@@ -8,6 +8,11 @@ export type NTNetData = {
|
||||
dos_capacity: number;
|
||||
dos_overload: number;
|
||||
dos_crashed: BooleanLike;
|
||||
relay_class: string;
|
||||
linked_sector: string;
|
||||
backhaul_range: number;
|
||||
backhaul_online: BooleanLike;
|
||||
backhaul_core: string;
|
||||
};
|
||||
|
||||
export const NTNetRelay = (props) => {
|
||||
@@ -42,6 +47,21 @@ export const NTNetRelay = (props) => {
|
||||
) : (
|
||||
<Section title="NTNet Server Status">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Relay Class">
|
||||
{data.relay_class}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Linked Sector">
|
||||
{data.linked_sector}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Backhaul">
|
||||
{data.backhaul_online ? 'Online' : 'Offline'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Backhaul Core">
|
||||
{data.backhaul_core}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Backhaul Range">
|
||||
{data.backhaul_range}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Network buffer status">
|
||||
{data.dos_overload} / {data.dos_capacity} GQ
|
||||
</LabeledList.Item>
|
||||
|
||||
@@ -76,6 +76,57 @@
|
||||
background-size: 70%;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
.Table {
|
||||
background-color: hsla(0, 0%, 3%, 0.45);
|
||||
border: 1px solid hsla(0, 0%, 35%, 0.22);
|
||||
border-collapse: separate;
|
||||
border-spacing: 0;
|
||||
box-shadow: inset 0 0 0 1px hsla(0, 0%, 50%, 0.06);
|
||||
|
||||
&__row {
|
||||
background-color: hsla(0, 0%, 5%, 0.42);
|
||||
|
||||
&:nth-child(even):not(&--header) {
|
||||
background-color: hsla(0, 0%, 15%, 0.34);
|
||||
}
|
||||
|
||||
&:hover:not(&--header) {
|
||||
background-color: hsla(0, 0%, 18%, 0.45);
|
||||
}
|
||||
|
||||
&--header {
|
||||
background-color: hsla(0, 0%, 14%, 0.65);
|
||||
color: hsl(31, 0%, 72%);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.035em;
|
||||
box-shadow: inset 0 -1px 0 hsla(0, 0%, 50%, 0.28);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Tabs {
|
||||
border-bottom: 1px solid hsl(0, 0%, 15%);
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
&__tab {
|
||||
background-color: hsla(0, 0%, 3%, 0.7);
|
||||
border: 1px solid hsl(0, 0%, 14%);
|
||||
color: hsl(0, 0%, 55%);
|
||||
|
||||
&:hover {
|
||||
background-color: hsla(0, 0%, 28%, 0.18);
|
||||
color: hsl(0, 0%, 72%);
|
||||
}
|
||||
|
||||
&--selected {
|
||||
background-color: hsl(0, 0%, 18%);
|
||||
border-color: hsl(0, 0%, 42%);
|
||||
color: hsl(30, 0%, 75%);
|
||||
box-shadow: inset 0 -2px 0 hsl(30, 0%, 55%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// A default, in case someone uses the vp() function outside of a <Window>
|
||||
:root {
|
||||
|
||||
Reference in New Issue
Block a user