From b710d139e6c8d34c8efb2f4defb3d594fd4071f2 Mon Sep 17 00:00:00 2001 From: Markolie Date: Sat, 22 Oct 2016 20:51:49 +0200 Subject: [PATCH] Update camera console based on mob refactor --- code/game/machinery/computer/camera.dm | 291 ++++++++++++----------- code/game/machinery/computer/computer.dm | 4 +- code/modules/nano/interaction/base.dm | 2 +- code/modules/paperwork/photography.dm | 4 +- 4 files changed, 156 insertions(+), 145 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 97a976ddc41..4db6a28cc05 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,75 +1,97 @@ /obj/machinery/computer/security - name = "Camera Monitor" + name = "security camera console" desc = "Used to access the various cameras networks on the station." + icon_keyboard = "security_key" icon_screen = "cameras" - circuit = /obj/item/weapon/circuitboard/camera - var/obj/machinery/camera/current = null - var/list/network = list("") - var/last_pic = 1 light_color = LIGHT_COLOR_RED - var/mapping = 0 - var/list/networks[0] - var/list/data[0] - var/list/access[0] + circuit = /obj/item/weapon/circuitboard/camera + + var/mapping = 0 // For the overview file (overview.dm), not used on this page + + var/list/network = list() + var/list/available_networks = list() + var/list/watchers = list() //who's using the console, associated with the camera they're on. -/obj/machinery/computer/security/New() // Lists existing networks and their required access. Format: networks[] = list() - networks["SS13"] = list(access_hos,access_captain) - networks["Telecomms"] = list(access_hos,access_captain) - networks["Research Outpost"] = list(access_rd,access_hos,access_captain) - networks["Mining Outpost"] = list(access_qm,access_hop,access_hos,access_captain) - networks["Research"] = list(access_rd,access_hos,access_captain) - networks["Prison"] = list(access_hos,access_captain) - networks["Labor"] = list(access_hos,access_captain) - networks["Interrogation"] = list(access_hos,access_captain) - networks["Atmosphere Alarms"] = list(access_ce,access_hos,access_captain) - networks["Fire Alarms"] = list(access_ce,access_hos,access_captain) - networks["Power Alarms"] = list(access_ce,access_hos,access_captain) - networks["Supermatter"] = list(access_ce,access_hos,access_captain) - networks["MiniSat"] = list(access_rd,access_hos,access_captain) - networks["Singularity"] = list(access_ce,access_hos,access_captain) - networks["Anomaly Isolation"] = list(access_rd,access_hos,access_captain) - networks["Toxins"] = list(access_rd,access_hos,access_captain) - networks["Telepad"] = list(access_rd,access_hos,access_captain) - networks["TestChamber"] = list(access_rd,access_hos,access_captain) - networks["ERT"] = list(access_cent_specops_commander,access_cent_commander) - networks["CentComm"] = list(access_cent_security,access_cent_commander) - networks["Thunderdome"] = list(access_cent_thunder,access_cent_commander) +/obj/machinery/computer/security/New() // Lists existing networks and their required access. Format: available_networks[] = list() + available_networks["SS13"] = list(access_hos,access_captain) + available_networks["Telecomms"] = list(access_hos,access_captain) + available_networks["Research Outpost"] = list(access_rd,access_hos,access_captain) + available_networks["Mining Outpost"] = list(access_qm,access_hop,access_hos,access_captain) + available_networks["Research"] = list(access_rd,access_hos,access_captain) + available_networks["Prison"] = list(access_hos,access_captain) + available_networks["Labor"] = list(access_hos,access_captain) + available_networks["Interrogation"] = list(access_hos,access_captain) + available_networks["Atmosphere Alarms"] = list(access_ce,access_hos,access_captain) + available_networks["Fire Alarms"] = list(access_ce,access_hos,access_captain) + available_networks["Power Alarms"] = list(access_ce,access_hos,access_captain) + available_networks["Supermatter"] = list(access_ce,access_hos,access_captain) + available_networks["MiniSat"] = list(access_rd,access_hos,access_captain) + available_networks["Singularity"] = list(access_ce,access_hos,access_captain) + available_networks["Anomaly Isolation"] = list(access_rd,access_hos,access_captain) + available_networks["Toxins"] = list(access_rd,access_hos,access_captain) + available_networks["Telepad"] = list(access_rd,access_hos,access_captain) + available_networks["TestChamber"] = list(access_rd,access_hos,access_captain) + available_networks["ERT"] = list(access_cent_specops_commander,access_cent_commander) + available_networks["CentComm"] = list(access_cent_security,access_cent_commander) + available_networks["Thunderdome"] = list(access_cent_thunder,access_cent_commander) ..() + +/obj/machinery/computer/security/Destroy() + if(watchers.len) + for(var/mob/M in watchers) + M.unset_machine() //to properly reset the view of the users if the console is deleted. + return ..() -/obj/machinery/computer/security/attack_ai(var/mob/user as mob) - return attack_hand(user) +/obj/machinery/computer/security/check_eye(mob/user) + var/obj/machinery/camera/C = watchers[user] + if(!can_access_camera(C, user)) + user.unset_machine() + return + if(!(user in watchers)) + user.unset_machine() + return + if(!watchers[user]) + user.unset_machine() + return + +/obj/machinery/computer/security/on_unset_machine(mob/user) + watchers.Remove(user) + user.reset_perspective(null) + +/obj/machinery/computer/security/attack_hand(mob/user) + if(stat || ..()) + user.unset_machine() + return + ui_interact(user) -/obj/machinery/computer/security/check_eye(var/mob/user as mob) - if((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded || !( current ) || !( current.status )) && (!istype(user, /mob/living/silicon))) - return null - user.reset_view(current) - return 1 - -// Network configuration /obj/machinery/computer/security/attackby(obj/item/I, user as mob, params) - access = I.GetAccess() - if(access.len) // If hit by something with access. - ui_interact(user) + if(I.GetAccess()) // If hit by something with access. + attack_hand(user) else ..() /obj/machinery/computer/security/emag_act(user as mob) if(!emagged) emagged = 1 - to_chat(user, "\blue You have authorized full network access!") - ui_interact(user) + to_chat(user, "You have authorized full network access!") + attack_hand(user) else - ui_interact(user) + attack_hand(user) + +/obj/machinery.computer/security/proc/get_user_access(mob/user) + var/list/access = list() + if(ishuman(user)) + access = user.get_access() + else if((isAI(user) || isrobot(user)) && CanUseTopic(user)) + access = get_all_accesses() // Assume captain level access when AI + else if(isobserver(user) && check_rights(R_ADMIN,0)) + access = get_all_accesses() + return access /obj/machinery/computer/security/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) - if(stat & (NOPOWER|BROKEN)) - return - if(user.stat) - return - var/data[0] data["current"] = null @@ -90,30 +112,30 @@ cameras.Swap(j, j + 1) data["cameras"] = cameras + + var/list/access = get_user_access(user) if(emagged) - access = list(access_captain) // Assume captain level access when emagged + access = get_all_accesses() // Assume captain level access when emagged data["emagged"] = 1 - if(isAI(user) || isrobot(user)) - access = list(access_captain) // Assume captain level access when AI - - var/tempnets[0] + var/list/networks_list = list() // Loop through the ID's permission, and check which networks the ID has access to. - for(var/net in networks) // Loop through networks. - for(var/req in networks[net]) // Loop through access levels of the networks. + for(var/net in available_networks) // Loop through networks. + for(var/req in available_networks[net]) // Loop through access levels of the networks. if(req in access) if(net in network) // Checks if the network is currently active. - tempnets.Add(list(list("name" = net, "active" = 1))) + networks_list.Add(list(list("name" = net, "active" = 1))) else - tempnets.Add(list(list("name" = net, "active" = 0))) + networks_list.Add(list(list("name" = net, "active" = 0))) break - if(tempnets.len) - data["networks"] = tempnets + if(networks_list.len) + data["networks"] = networks_list - if(current) - data["current"] = current.nano_structure() + if(watchers[user]) + var/obj/machinery/camera/watched = watchers[user] + data["current"] = watched.nano_structure() ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) @@ -130,108 +152,95 @@ /obj/machinery/computer/security/Topic(href, href_list) if(..()) + usr.unset_machine() return 1 if(href_list["switchTo"]) - if(stat & (NOPOWER|BROKEN)) - return 1 var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras if(!C) return 1 - if(!can_access_camera(C)) - return 1 // No href exploits for you. - switch_to_camera(usr, C) else if(href_list["reset"]) - if(stat & (NOPOWER|BROKEN)) - return 1 - reset_current() - usr.check_eye(current) + usr.unset_machine() else if(href_list["activate"]) // Activate: enable or disable networks var/net = href_list["activate"] // Network to be enabled or disabled. var/active = href_list["active"] // Is the network currently active. - for(var/a in networks[net]) + var/list/access = get_user_access(usr) + for(var/a in available_networks[net]) if(a in access) // Re-check for authorization. if(text2num(active) == 1) - src.network -= net + network -= net break else - src.network += net + network += net break - nanomanager.update_uis(src) - - -/obj/machinery/computer/security/attack_hand(mob/user) - access = list() - if(stat & (NOPOWER|BROKEN)) - return - - if(!isAI(user)) - user.set_machine(src) - - if(ishuman(user)) - access = user.get_access() - - ui_interact(user) + + nanomanager.update_uis(src) // Check if camera is accessible when jumping -/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C) - var/list/shared_networks = src.network & C.network - if(shared_networks.len) - return 1 - return 0 +/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C, var/mob/M) + if(!CanUseTopic(M) || M.incapacitated() || !M.can_see()) + return 0 + + if(isrobot(M)) + var/list/viewing = viewers(src) + if(!viewing.Find(M)) + return 0 + + if(isAI(M)) + var/mob/living/silicon/ai/A = M + if(!A.is_in_chassis()) + return 0 + + if(!issilicon(M) && !Adjacent(M)) + return 0 + + var/list/shared_networks = network & C.network + if(!shared_networks.len || !C.can_use()) + return 0 + + return 1 // Switching to cameras /obj/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C) - if((get_dist(user, src) > 1 || user.machine != src || user.blinded || !(user.canmove) || !C.can_use()) && !(istype(user, /mob/living/silicon/ai))) - if(!C.can_use() && !isAI(user)) - current = null - return 0 - else - 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 - else - set_current(C) - use_power(50) + if(!can_access_camera(C, usr)) + usr.unset_machine() return 1 - -/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C) - if(current == C) - return - - if(current) - reset_current() - - current = C - if(current) - use_power = 2 - -/obj/machinery/computer/security/proc/reset_current() - current = null - use_power = 1 + + if(isAI(usr)) + var/mob/living/silicon/ai/A = usr + A.eyeobj.setLoc(get_turf(C)) + A.client.eye = A.eyeobj + else + usr.reset_perspective(C) + watchers[user] = C + use_power(50) //Camera control: moving. -/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A) +/obj/machinery/computer/security/proc/jump_on_click(var/mob/user, var/A) if(user.machine != src) return + var/obj/machinery/camera/jump_to - if(istype(A,/obj/machinery/camera)) + + if(istype(A, /obj/machinery/camera)) jump_to = A + else if(ismob(A)) if(ishuman(A)) - jump_to = locate() in A:head + var/mob/living/carbon/human/H = A + jump_to = locate() in H.head else if(isrobot(A)) - jump_to = A:camera + var/mob/living/silicon/robot/R = A + jump_to = R.camera + else if(isobj(A)) - jump_to = locate() in A + var/obj/O = A + jump_to = locate() in O + else if(isturf(A)) var/best_dist = INFINITY for(var/obj/machinery/camera/camera in get_area(A)) @@ -243,26 +252,28 @@ if(dist < best_dist) best_dist = dist jump_to = camera + if(isnull(jump_to)) return + if(can_access_camera(jump_to)) - switch_to_camera(user,jump_to) + switch_to_camera(user, jump_to) // Camera control: mouse. /atom/DblClick() ..() - if(istype(usr.machine,/obj/machinery/computer/security)) + if(istype(usr.machine, /obj/machinery/computer/security)) var/obj/machinery/computer/security/console = usr.machine - console.jump_on_click(usr,src) + console.jump_on_click(usr, src) // Camera control: arrow keys. -/mob/Move(n,direct) - if(istype(machine,/obj/machinery/computer/security)) +/mob/Move(n, direct) + if(istype(machine, /obj/machinery/computer/security)) var/obj/machinery/computer/security/console = machine - var/turf/T = get_turf(console.current) - for(var/i;i<10;i++) - T = get_step(T,direct) - console.jump_on_click(src,T) + var/turf/T = get_turf(console.watchers[src]) + for(var/i; i < 10; i++) + T = get_step(T, direct) + console.jump_on_click(src, T) return return ..(n,direct) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index d50bdbb8bc5..71f9760c0a6 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -102,7 +102,7 @@ return text /obj/machinery/computer/attack_ghost(user as mob) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/computer/attack_hand(user as mob) /* Observers can view computers, but not actually use them via Topic*/ @@ -130,7 +130,7 @@ A.icon_state = "4" qdel(src) else - src.attack_hand(user) + attack_hand(user) return /obj/machinery/computer/attack_alien(mob/living/user) diff --git a/code/modules/nano/interaction/base.dm b/code/modules/nano/interaction/base.dm index 113c9e2878b..3f8897eb5c8 100644 --- a/code/modules/nano/interaction/base.dm +++ b/code/modules/nano/interaction/base.dm @@ -14,7 +14,7 @@ /mob/proc/shared_nano_interaction() if(stat || !client) return STATUS_CLOSE // no updates, close the interface - else if(restrained() || lying || stunned || weakened) + else if(incapacitated()) return STATUS_UPDATE // update only (orange visibility) return STATUS_INTERACTIVE diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 364f7b50f02..f2af678c97d 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -532,13 +532,13 @@ var/list/SpookyGhosts = list("ghost","shade","shade2","ghost-narsie","horror","s if(get_dist(src, M) <= canhear_range) talk_into(M, msg) for(var/obj/machinery/computer/security/telescreen/T in machines) - if(T.current == camera) + if(T.watchers[M] == camera) T.audible_message("(Newscaster) [M] says, '[msg]'", hearing_distance = 2) /obj/item/device/videocam/hear_message(mob/M as mob, msg) if(camera && on) for(var/obj/machinery/computer/security/telescreen/T in machines) - if(T.current == camera) + if(T.watchers[M] == camera) T.audible_message("(Newscaster) [M] [msg]", hearing_distance = 2)