Updates Part Seven

This commit is contained in:
Unknown
2019-04-10 22:33:48 -04:00
parent 2e8acaf5a4
commit eb62911b9d
23 changed files with 412 additions and 70 deletions

View File

@@ -56,6 +56,9 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called
#define NETWORK_TELECOM "Tcomms" #define NETWORK_TELECOM "Tcomms"
#define NETWORK_THUNDER "Thunderdome" #define NETWORK_THUNDER "Thunderdome"
#define NETWORK_COMMUNICATORS "Communicators" #define NETWORK_COMMUNICATORS "Communicators"
#define NETWORK_ALARM_ATMOS "Atmosphere Alarms"
#define NETWORK_ALARM_POWER "Power Alarms"
#define NETWORK_ALARM_FIRE "Fire Alarms"
// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. // Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them.
var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS) var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret", NETWORK_COMMUNICATORS)

View File

@@ -191,6 +191,7 @@
#define NTNETSPEED_LOWSIGNAL 0.1 // GQ/s transfer speed when the device is wirelessly connected and on Low signal #define NTNETSPEED_LOWSIGNAL 0.1 // GQ/s transfer speed when the device is wirelessly connected and on Low signal
#define NTNETSPEED_HIGHSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on High signal #define NTNETSPEED_HIGHSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on High signal
#define NTNETSPEED_ETHERNET 1.0 // GQ/s transfer speed when the device is using wired connection #define NTNETSPEED_ETHERNET 1.0 // GQ/s transfer speed when the device is using wired connection
#define NTNETSPEED_DOS_AMPLIFICATION 5 // Multiplier for Denial of Service program. Resulting load on NTNet relay is this multiplied by NTNETSPEED of the device
// Program bitflags // Program bitflags
#define PROGRAM_ALL 7 #define PROGRAM_ALL 7

View File

@@ -57,9 +57,6 @@ var/const/CAMERA_WIRE_NOTHING2 = 32
var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range)) var/new_range = (C.view_range == initial(C.view_range) ? C.short_range : initial(C.view_range))
C.setViewRange(new_range) C.setViewRange(new_range)
if(CAMERA_WIRE_POWER)
C.kick_viewers() // Kicks anyone watching the camera
if(CAMERA_WIRE_LIGHT) if(CAMERA_WIRE_LIGHT)
C.light_disabled = !C.light_disabled C.light_disabled = !C.light_disabled

View File

@@ -39,7 +39,6 @@ var/const/BORG_WIRE_CAMERA = 16
if (BORG_WIRE_CAMERA) if (BORG_WIRE_CAMERA)
if(!isnull(R.camera) && !R.scrambledcodes) if(!isnull(R.camera) && !R.scrambledcodes)
R.camera.status = mended R.camera.status = mended
R.camera.kick_viewers() // Will kick anyone who is watching the Cyborg's camera.
if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh
if (R.lawupdate) if (R.lawupdate)
@@ -59,7 +58,6 @@ var/const/BORG_WIRE_CAMERA = 16
if (BORG_WIRE_CAMERA) if (BORG_WIRE_CAMERA)
if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes) if(!isnull(R.camera) && R.camera.can_use() && !R.scrambledcodes)
R.camera.kick_viewers() // Kick anyone watching the Cyborg's camera
R.visible_message("[R]'s camera lense focuses loudly.") R.visible_message("[R]'s camera lense focuses loudly.")
R << "Your camera lense focuses loudly." R << "Your camera lense focuses loudly."

View File

@@ -88,7 +88,6 @@
stat |= EMPED stat |= EMPED
set_light(0) set_light(0)
triggerCameraAlarm() triggerCameraAlarm()
kick_viewers()
update_icon() update_icon()
update_coverage() update_coverage()
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
@@ -241,26 +240,25 @@
user = null user = null
if(choice != 1) if(choice != 1)
//legacy support, if choice is != 1 then just kick viewers without changing status return
kick_viewers()
else set_status(!src.status)
set_status(!src.status) if (!(src.status))
if (!(src.status)) if(user)
if(user) visible_message("<span class='notice'> [user] has deactivated [src]!</span>")
visible_message("<span class='notice'> [user] has deactivated [src]!</span>")
else
visible_message("<span class='notice'> [src] clicks and shuts down. </span>")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = "[initial(icon_state)]1"
add_hiddenprint(user)
else else
if(user) visible_message("<span class='notice'> [src] clicks and shuts down. </span>")
visible_message("<span class='notice'> [user] has reactivated [src]!</span>") playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
else icon_state = "[initial(icon_state)]1"
visible_message("<span class='notice'> [src] clicks and reactivates itself. </span>") add_hiddenprint(user)
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) else
icon_state = initial(icon_state) if(user)
add_hiddenprint(user) visible_message("<span class='notice'> [user] has reactivated [src]!</span>")
else
visible_message("<span class='notice'> [src] clicks and reactivates itself. </span>")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = initial(icon_state)
add_hiddenprint(user)
/obj/machinery/camera/proc/take_damage(var/force, var/message) /obj/machinery/camera/proc/take_damage(var/force, var/message)
//prob(25) gives an average of 3-4 hits //prob(25) gives an average of 3-4 hits
@@ -272,7 +270,6 @@
stat |= BROKEN stat |= BROKEN
wires.RandomCutAll() wires.RandomCutAll()
kick_viewers()
triggerCameraAlarm() triggerCameraAlarm()
update_icon() update_icon()
update_coverage() update_coverage()
@@ -287,26 +284,12 @@
if (status != newstatus) if (status != newstatus)
status = newstatus status = newstatus
update_coverage() update_coverage()
// now disconnect anyone using the camera
//Apparently, this will disconnect anyone even if the camera was re-activated.
//I guess that doesn't matter since they couldn't use it anyway?
kick_viewers()
/obj/machinery/camera/check_eye(mob/user) /obj/machinery/camera/check_eye(mob/user)
if(!can_use()) return -1 if(!can_use()) return -1
if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS if(isXRay()) return SEE_TURFS|SEE_MOBS|SEE_OBJS
return 0 return 0
//This might be redundant, because of check_eye()
/obj/machinery/camera/proc/kick_viewers()
for(var/mob/O in player_list)
if (istype(O.machine, /obj/machinery/computer/security))
var/obj/machinery/computer/security/S = O.machine
if (S.current_camera == src)
O.unset_machine()
O.reset_view(null)
O << "The screen bursts into static."
/obj/machinery/camera/update_icon() /obj/machinery/camera/update_icon()
if (!status || (stat & BROKEN)) if (!status || (stat & BROKEN))
icon_state = "[initial(icon_state)]1" icon_state = "[initial(icon_state)]1"

View File

@@ -26,9 +26,9 @@ var/global/list/engineering_networks = list(
NETWORK_ENGINE, NETWORK_ENGINE,
NETWORK_ENGINEERING, NETWORK_ENGINEERING,
NETWORK_ENGINEERING_OUTPOST, NETWORK_ENGINEERING_OUTPOST,
"Atmosphere Alarms", NETWORK_ALARM_ATMOS,
"Fire Alarms", NETWORK_ALARM_FIRE,
"Power Alarms") NETWORK_ALARM_POWER)
/obj/machinery/camera/network/crescent /obj/machinery/camera/network/crescent
network = list(NETWORK_CRESCENT) network = list(NETWORK_CRESCENT)

View File

@@ -8,6 +8,10 @@
return return
if(!loc) if(!loc)
return return
if(machine && !CanMouseDrop(machine, src))
machine = null
var/datum/gas_mixture/environment = loc.return_air() var/datum/gas_mixture/environment = loc.return_air()
handle_modifiers() // Do this early since it might affect other things later. handle_modifiers() // Do this early since it might affect other things later.

View File

@@ -145,9 +145,6 @@
/datum/robot_component/camera/update_power_state() /datum/robot_component/camera/update_power_state()
..() ..()
if (camera) if (camera)
//check if camera component was deactivated
if (!powered && camera.status != powered)
camera.kick_viewers()
camera.status = powered camera.status = powered
/datum/robot_component/camera/install() /datum/robot_component/camera/install()
@@ -157,12 +154,10 @@
/datum/robot_component/camera/uninstall() /datum/robot_component/camera/uninstall()
if (camera) if (camera)
camera.status = 0 camera.status = 0
camera.kick_viewers()
/datum/robot_component/camera/destroy() /datum/robot_component/camera/destroy()
if (camera) if (camera)
camera.status = 0 camera.status = 0
camera.kick_viewers()
// SELF DIAGNOSIS MODULE // SELF DIAGNOSIS MODULE
// Analyses cyborg's modules, providing damage readouts and basic information // Analyses cyborg's modules, providing damage readouts and basic information

View File

@@ -776,4 +776,11 @@
if(HALLOSS) if(HALLOSS)
take_damage(Proj.damage, Proj.damage / 3, 0) take_damage(Proj.damage, Proj.damage / 3, 0)
if(BURN) if(BURN)
take_damage(Proj.damage, Proj.damage / 1.5) take_damage(Proj.damage, Proj.damage / 1.5)
// Used by camera monitor program
/obj/item/modular_computer/check_eye(var/mob/user)
if(active_program)
return active_program.check_eye(user)
else
return ..()

View File

@@ -17,7 +17,6 @@
cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(cpu) cpu.battery_module = new/obj/item/weapon/computer_hardware/battery_module/super(cpu)
install_programs() install_programs()
// Override in child types to install preset-specific programs.
/obj/machinery/modular_computer/console/preset/proc/install_programs() /obj/machinery/modular_computer/console/preset/proc/install_programs()
return return
@@ -31,6 +30,7 @@
cpu.hard_drive.store_file(new/datum/computer_file/program/alarm_monitor()) cpu.hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
cpu.hard_drive.store_file(new/datum/computer_file/program/atmos_control()) cpu.hard_drive.store_file(new/datum/computer_file/program/atmos_control())
cpu.hard_drive.store_file(new/datum/computer_file/program/rcon_console()) cpu.hard_drive.store_file(new/datum/computer_file/program/rcon_console())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
// ===== MEDICAL CONSOLE ===== // ===== MEDICAL CONSOLE =====
@@ -40,6 +40,7 @@
/obj/machinery/modular_computer/console/preset/medical/install_programs() /obj/machinery/modular_computer/console/preset/medical/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/suit_sensors()) cpu.hard_drive.store_file(new/datum/computer_file/program/suit_sensors())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
// ===== RESEARCH CONSOLE ===== // ===== RESEARCH CONSOLE =====
@@ -51,6 +52,7 @@
cpu.hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor()) cpu.hard_drive.store_file(new/datum/computer_file/program/ntnetmonitor())
cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer()) cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer())
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
// ===== COMMAND CONSOLE ===== // ===== COMMAND CONSOLE =====
@@ -64,6 +66,7 @@
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod()) cpu.hard_drive.store_file(new/datum/computer_file/program/card_mod())
cpu.hard_drive.store_file(new/datum/computer_file/program/comm()) cpu.hard_drive.store_file(new/datum/computer_file/program/comm())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
// ===== SECURITY CONSOLE ===== // ===== SECURITY CONSOLE =====
@@ -72,7 +75,7 @@
desc = "A stationary computer. This one comes preloaded with security programs." desc = "A stationary computer. This one comes preloaded with security programs."
/obj/machinery/modular_computer/console/preset/security/install_programs() /obj/machinery/modular_computer/console/preset/security/install_programs()
return // No security programs exist, yet, but the preset is ready so it may be mapped in. cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor())
// ===== CIVILIAN CONSOLE ===== // ===== CIVILIAN CONSOLE =====
@@ -83,3 +86,27 @@
/obj/machinery/modular_computer/console/preset/civilian/install_programs() /obj/machinery/modular_computer/console/preset/civilian/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient()) cpu.hard_drive.store_file(new/datum/computer_file/program/chatclient())
cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer()) cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor()) // Mainly for the entertainment channel, won't allow connection to other channels without access anyway
// ===== ERT CONSOLE =====
/obj/machinery/modular_computer/console/preset/ert
console_department = "Crescent"
desc = "A stationary computer. This one comes preloaded with various programs used by Nanotrasen response teams."
/obj/machinery/modular_computer/console/preset/ert/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/nttransfer())
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor/ert())
cpu.hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())
cpu.hard_drive.store_file(new/datum/computer_file/program/comm())
// ===== MERCENARY CONSOLE =====
/obj/machinery/modular_computer/console/preset/mercenary
console_department = "Unset"
desc = "A stationary computer. This one comes preloaded with various programs used by shady organizations."
_has_printer = 1
_has_id_slot = 1
emagged = 1 // Allows download of other antag programs for free.
/obj/machinery/modular_computer/console/preset/ert/install_programs()
cpu.hard_drive.store_file(new/datum/computer_file/program/camera_monitor/hacked())
cpu.hard_drive.store_file(new/datum/computer_file/program/alarm_monitor())

View File

@@ -190,4 +190,7 @@
if(cpu) if(cpu)
cpu.bullet_act(Proj) cpu.bullet_act(Proj)
/obj/machinery/modular_computer/check_eye(var/mob/user)
if(cpu)
return cpu.check_eye(user)
return -1

View File

@@ -2,7 +2,9 @@
/datum/computer_file/program /datum/computer_file/program
filetype = "PRG" filetype = "PRG"
filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET! filename = "UnknownProgram" // File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET!
var/required_access = null // List of required accesses to *run* the program. var/required_access = null // List of required accesses to run/download the program.
var/requires_access_to_run = 1 // Whether the program checks for required_access when run.
var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading.
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact. var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program. var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running. var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
@@ -80,6 +82,9 @@
if(!access_to_check) // No required_access, allow it. if(!access_to_check) // No required_access, allow it.
return 1 return 1
if(!istype(user))
return 0
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)
@@ -101,7 +106,7 @@
// This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure. // This is performed on program startup. May be overriden to add extra logic. Remember to include ..() call. Return 1 on success, 0 on failure.
// When implementing new program based device, use this to run the program. // When implementing new program based device, use this to run the program.
/datum/computer_file/program/proc/run_program(var/mob/living/user) /datum/computer_file/program/proc/run_program(var/mob/living/user)
if(can_run(user, 1)) if(can_run(user, 1) || !requires_access_to_run)
if(nanomodule_path) if(nanomodule_path)
NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src) NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
if(requires_ntnet && network_destination) if(requires_ntnet && network_destination)
@@ -143,3 +148,10 @@
return 1 return 1
if(computer) if(computer)
return computer.Topic(href, href_list) return computer.Topic(href, href_list)
// Relays the call to nano module, if we have one
/datum/computer_file/program/proc/check_eye(var/mob/user)
if(NM)
return NM.check_eye(user)
else
return -1

View File

@@ -28,4 +28,4 @@
// Calls forwarded to PROGRAM itself should begin with "PRG_" // Calls forwarded to PROGRAM itself should begin with "PRG_"
// Calls forwarded to COMPUTER running the program should begin with "PC_" // Calls forwarded to COMPUTER running the program should begin with "PC_"
/datum/topic_manager/program/Topic(href, href_list) /datum/topic_manager/program/Topic(href, href_list)
return program && program.Topic(href, href_list) return program && program.Topic(href, href_list)

View File

@@ -17,11 +17,11 @@
dos_speed = 0 dos_speed = 0
switch(ntnet_status) switch(ntnet_status)
if(1) if(1)
dos_speed = NTNETSPEED_LOWSIGNAL * 10 dos_speed = NTNETSPEED_LOWSIGNAL * NTNETSPEED_DOS_AMPLIFICATION
if(2) if(2)
dos_speed = NTNETSPEED_HIGHSIGNAL * 10 dos_speed = NTNETSPEED_HIGHSIGNAL * NTNETSPEED_DOS_AMPLIFICATION
if(3) if(3)
dos_speed = NTNETSPEED_ETHERNET * 10 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.is_operational())

View File

@@ -0,0 +1,36 @@
/datum/computer_file/program/camera_monitor/hacked
filename = "camcrypt"
filedesc = "Camera Decryption Tool"
nanomodule_path = /datum/nano_module/camera_monitor/hacked
program_icon_state = "hostile"
extended_desc = "This very advanced piece of software uses adaptive programming and large database of cipherkeys to bypass most encryptions used on camera networks. Be warned that system administrator may notice this."
size = 73 // Very large, a price for bypassing ID checks completely.
available_on_ntnet = 0
available_on_syndinet = 1
/datum/computer_file/program/camera_monitor/hacked/process_tick()
..()
if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms.
return
var/datum/nano_module/camera_monitor/hacked/HNM = NM
// The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick.
if(HNM.current_network && (HNM.current_network in using_map.station_networks) && prob(0.1))
if(ntnet_global.intrusion_detection_enabled)
ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]")
ntnet_global.intrusion_detection_alarm = 1
/datum/nano_module/camera_monitor/hacked
name = "Hacked Camera Monitoring Program"
/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access)
return 1
// The hacked variant has access to all commonly used networks.
/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks)
networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
return networks

View File

@@ -0,0 +1,173 @@
// Returns which access is relevant to passed network. Used by the program.
/proc/get_camera_access(var/network)
if(!network)
return 0
switch(network)
if(NETWORK_THUNDER)
return 0
if(NETWORK_ENGINE || NETWORK_ENGINEERING || NETWORK_ENGINEERING_OUTPOST || NETWORK_ALARM_ATMOS || NETWORK_ALARM_FIRE || NETWORK_ALARM_POWER)
return access_engine
if(NETWORK_MEDICAL)
return access_medical
if(NETWORK_RESEARCH || NETWORK_RESEARCH_OUTPOST)
return access_research
if(NETWORK_MINE || NETWORK_SUPPLY )
return access_mailsorting // Cargo office - all cargo staff should have access here.
if(NETWORK_COMMAND || NETWORK_TELECOM)
return access_heads
if(NETWORK_ERT)
return access_cent_specops
return access_security // Default for all other networks
/datum/computer_file/program/camera_monitor
filename = "cammon"
filedesc = "Camera Monitoring"
nanomodule_path = /datum/nano_module/camera_monitor
program_icon_state = "generic"
extended_desc = "This program allows remote access to station's camera system. Some camera networks may have additional access requirements."
size = 12
available_on_ntnet = 1
requires_ntnet = 1
/datum/nano_module/camera_monitor
name = "Camera Monitoring program"
var/obj/machinery/camera/current_camera = null
var/current_network = null
/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
var/list/data = host.initial_data()
data["current_camera"] = current_camera ? current_camera.nano_structure() : null
data["current_network"] = current_network
var/list/all_networks[0]
for(var/network in using_map.station_networks)
all_networks.Add(list(list(
"tag" = network,
"has_access" = can_access_network(usr, get_camera_access(network))
)))
all_networks = modify_networks_list(all_networks)
data["networks"] = all_networks
if(current_network)
data["cameras"] = camera_repository.cameras_in_network(current_network)
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "mod_sec_camera.tmpl", "Camera Monitoring", 900, 800)
// ui.auto_update_layout = 1 // Disabled as with suit sensors monitor - breaks the UI map. Re-enable once it's fixed somehow.
ui.add_template("mapContent", "sec_camera_map_content.tmpl")
ui.add_template("mapHeader", "mod_sec_camera_map_header.tmpl")
ui.set_initial_data(data)
ui.open()
// Intended to be overriden by subtypes to manually add non-station networks to the list.
/datum/nano_module/camera_monitor/proc/modify_networks_list(var/list/networks)
return networks
/datum/nano_module/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)
return 1
return check_access(user, access_security) || check_access(user, network_access)
/datum/nano_module/camera_monitor/Topic(href, href_list)
if(..())
return 1
if(href_list["switch_camera"])
var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras
if(!C)
return
if(!(current_network in C.network))
return
switch_to_camera(usr, C)
return 1
else if(href_list["switch_network"])
if(!(href_list["switch_network"] in using_map.station_networks))
return
// Either security access, or access to the specific camera network's department is required in order to access the network.
if(can_access_network(usr, get_camera_access(href_list["switch_network"])))
current_network = href_list["switch_network"]
else
usr << "\The [nano_host()] shows an \"Network Access Denied\" error message."
return 1
else if(href_list["reset"])
reset_current()
usr.reset_view(current_camera)
return 1
/datum/nano_module/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/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))
var/mob/living/silicon/ai/A = user
// Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise.
if(!A.is_in_chassis())
return 0
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
return 1
set_current(C)
user.machine = nano_host()
user.reset_view(C)
return 1
/datum/nano_module/camera_monitor/proc/set_current(var/obj/machinery/camera/C)
if(current_camera == C)
return
if(current_camera)
reset_current()
current_camera = C
if(current_camera)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_initiated()
/datum/nano_module/camera_monitor/proc/reset_current()
if(current_camera)
var/mob/living/L = current_camera.loc
if(istype(L))
L.tracking_cancelled()
current_camera = null
/datum/nano_module/camera_monitor/check_eye(var/mob/user as mob)
if(!current_camera)
return 0
var/viewflag = current_camera.check_eye(user)
if ( viewflag < 0 ) //camera doesn't work
reset_current()
return viewflag
// ERT Variant of the program
/datum/computer_file/program/camera_monitor/ert
filename = "ntcammon"
filedesc = "Advanced 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 an integrated database with additional encrypted keys."
size = 14
nanomodule_path = /datum/nano_module/camera_monitor/ert
available_on_ntnet = 0
/datum/nano_module/camera_monitor/ert
name = "Advanced Camera Monitoring Program"
// 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)
..()
networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1)))
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
return networks

View File

@@ -133,7 +133,7 @@
var/list/all_entries[0] var/list/all_entries[0]
for(var/datum/computer_file/program/P in ntnet_global.available_station_software) for(var/datum/computer_file/program/P in ntnet_global.available_station_software)
// Only those programs our user can run will show in the list // Only those programs our user can run will show in the list
if(!P.can_run(user)) if(!P.can_run(user) && P.requires_access_to_download)
continue continue
all_entries.Add(list(list( all_entries.Add(list(list(
"filename" = P.filename, "filename" = P.filename,

View File

@@ -221,15 +221,17 @@
var/list/data[0] var/list/data[0]
data["state"] = state data["state"] = state
data["devtype"] = devtype if(state == 1)
data["hw_battery"] = dev_battery data["devtype"] = devtype
data["hw_disk"] = dev_disk data["hw_battery"] = dev_battery
data["hw_netcard"] = dev_netcard data["hw_disk"] = dev_disk
data["hw_tesla"] = dev_tesla data["hw_netcard"] = dev_netcard
data["hw_nanoprint"] = dev_nanoprint data["hw_tesla"] = dev_tesla
data["hw_card"] = dev_card data["hw_nanoprint"] = dev_nanoprint
data["hw_cpu"] = dev_cpu data["hw_card"] = dev_card
data["totalprice"] = "[total_price]$" data["hw_cpu"] = dev_cpu
if(state == 1 || state == 2)
data["totalprice"] = total_price
ui = SSnanoui.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)

View File

@@ -14,6 +14,25 @@
/datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state) /datum/nano_module/proc/can_still_topic(var/datum/topic_state/state = default_state)
return CanUseTopic(usr, state) == STATUS_INTERACTIVE return CanUseTopic(usr, state) == STATUS_INTERACTIVE
/datum/nano_module/proc/check_eye(var/mob/user)
return -1
/datum/nano_module/proc/check_access(var/mob/user, var/access)
if(!access)
return 1
if(!istype(user))
return 0
var/obj/item/weapon/card/id/I = user.GetIdCard()
if(!I)
return 0
if(access in I.access)
return 1
return 0
/datum/nano_module/Topic(href, href_list) /datum/nano_module/Topic(href, href_list)
if(topic_manager && topic_manager.Topic(href, href_list)) if(topic_manager && topic_manager.Topic(href, href_list))
return TRUE return TRUE

View File

@@ -12,7 +12,7 @@
<table> <table>
<tr> <tr>
<td><b>Current Price:</b> <td><b>Current Price:</b>
<td>{{:data.totalprice}} <td>{{:data.totalprice}}T
<tr> <tr>
<td><b>Battery:</b> <td><b>Battery:</b>
<td>{{:helper.link('Standard', null, { "hw_battery" : 1 }, data.hw_battery == 1 ? 'selected' : null)}} <td>{{:helper.link('Standard', null, { "hw_battery" : 1 }, data.hw_battery == 1 ? 'selected' : null)}}
@@ -63,7 +63,7 @@
<h2>Step 3: Payment</h2> <h2>Step 3: Payment</h2>
<b>Your device is now ready for fabrication..</b><br> <b>Your device is now ready for fabrication..</b><br>
<i>Please swipe your identification card to finish purchase.</i><br> <i>Please swipe your identification card to finish purchase.</i><br>
<i>Total price: <b>{{:data.totalprice}}</b></i> <i>Total price: <b>{{:data.totalprice}}T</b></i>
{{else data.state == 3}} {{else data.state == 3}}
<h2>Step 4: Thank you for your purchase</h2> <h2>Step 4: Thank you for your purchase</h2>
<b>Should you experience any issues with your new device, contact technical support at support@computerservice.nt</b> <b>Should you experience any issues with your new device, contact technical support at support@computerservice.nt</b>

View File

@@ -0,0 +1,36 @@
<div class='item'>
{{:helper.link('Show Map', 'pin-s', {'showMap' : 1})}}
{{:helper.link('Reset', 'refresh', {'reset' : 1})}}
</div>
<div class='item'>
<div class='itemLabel'>Current Camera:</div>
{{if data.current_camera}}
<div class='itemContentWide'><b>{{:data.current_camera.name}}</b></div>
{{else}}
<div class='itemContentWide'>None</div>
{{/if}}
</div>
<div class='item'>
<div class='itemLabel'>Networks:</div>
</div>
{{for data.networks}}
{{if value.has_access}}
{{:helper.link(value.tag, '', {'switch_network' : value.tag}, null, data.current_network == value.tag ? 'selected' : null)}}
{{else}}
{{:helper.link(value.tag, '', {}, null, data.current_network == value.tag ? 'selected' : 'redButton')}}
{{/if}}
{{/for}}
<div class='item'>
<div class='itemLabel'>Cameras:</div>
</div>
{{for data.cameras}}
{{if data.current_camera && value.name == data.current_camera.name}}
{{:helper.link(value.name, '', {'switch_camera' : value.camera}, 'selected')}}
{{else value.deact}}
{{:helper.link(value.name + " (deactivated)", '', {}, 'inactive')}}
{{else}}
{{:helper.link(value.name, '', {'switch_camera' : value.camera})}}
{{/if}}
{{/for}}

View File

@@ -0,0 +1,44 @@
<div class='item'>
{{:helper.link('Show Camera List', 'script', {'showMap' : 0})}}
{{:helper.link('Reset', 'refresh', {'reset' : 1})}}
</div>
<div class='item'>
<div class='itemLabel'>Current Camera:</div>
{{if data.current_camera}}
<div class='itemContentWide'><b>{{:data.current_camera.name}}</b></div>
{{else}}
<div class='itemContentWide'>None</div>
{{/if}}
</div>
<div class='item'>
<div class='itemLabel'>
Z-Level:
</div>
<div class='itemContentWide'>
{{for config.mapZLevels :zValue:zIndex}}
{{:helper.link(zValue, 'close', {'mapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}}
{{/for}}
</div>
</div>
<div class='item'>
<div class='itemLabel'>
Zoom Level:
</div>
<div class='itemContentWide'>
<div unselectable="on" class="link zoomLink" data-zoom-level="4">x1.0</div>
<div unselectable="on" class="link zoomLink" data-zoom-level="6">x1.5</div>
<div unselectable="on" class="link zoomLink" data-zoom-level="8">x2.0</div>
<div unselectable="on" class="link zoomLink" data-zoom-level="12">x2.5</div>
</div>
</div>
<div class='item'>
<div class='itemLabel'>Networks:</div>
</div>
{{for data.networks}}
{{if value.has_access}}
{{:helper.link(value.tag, '', {'switch_network' : value.tag}, null, data.current_network == value.tag ? 'selected' : null)}}
{{else}}
{{:helper.link(value.tag, '', {}, null, data.current_network == value.tag ? 'selected' : 'redButton')}}
{{/if}}
{{/for}}

View File

@@ -2112,6 +2112,7 @@
#include "code\modules\modular_computers\file_system\programs\_engineering.dm" #include "code\modules\modular_computers\file_system\programs\_engineering.dm"
#include "code\modules\modular_computers\file_system\programs\_medical.dm" #include "code\modules\modular_computers\file_system\programs\_medical.dm"
#include "code\modules\modular_computers\file_system\programs\_program.dm" #include "code\modules\modular_computers\file_system\programs\_program.dm"
#include "code\modules\modular_computers\file_system\programs\camera.dm"
#include "code\modules\modular_computers\file_system\programs\card.dm" #include "code\modules\modular_computers\file_system\programs\card.dm"
#include "code\modules\modular_computers\file_system\programs\comm.dm" #include "code\modules\modular_computers\file_system\programs\comm.dm"
#include "code\modules\modular_computers\file_system\programs\configurator.dm" #include "code\modules\modular_computers\file_system\programs\configurator.dm"
@@ -2121,6 +2122,7 @@
#include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm"
#include "code\modules\modular_computers\file_system\programs\nttransfer.dm" #include "code\modules\modular_computers\file_system\programs\nttransfer.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\hacked_camera.dm"
#include "code\modules\modular_computers\file_system\programs\antagonist\revelation.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\revelation.dm"
#include "code\modules\modular_computers\hardware\battery_module.dm" #include "code\modules\modular_computers\hardware\battery_module.dm"
#include "code\modules\modular_computers\hardware\card_slot.dm" #include "code\modules\modular_computers\hardware\card_slot.dm"