mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-21 03:56:47 +01:00
Camera fixes and performance tweaks.
Improves camera EMP handling. Now uses a var and processing to determine when the EMP should end, preventing inconsistent states when a camera is EMPd multiple times. Reduces the process and bandwidth need for cameras. * There is now a common camera repository, responsible for setting up cameras once for every invalidation. * Camera consoles now only updates when the camera cache is invalidated, not every second. * The console now only presents one network at a time, and only sends the data necessary to view that network (as opposed to sending the data for all cameras).
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
var/global/datum/repository/cameras/camera_repository = new()
|
||||
|
||||
/proc/invalidateCameraCache()
|
||||
camera_repository.networks.Cut()
|
||||
camera_repository.invalidated = 1
|
||||
camera_repository.camera_cache_id = (++camera_repository.camera_cache_id % 999999)
|
||||
|
||||
/datum/repository/cameras
|
||||
var/list/networks
|
||||
var/invalidated = 1
|
||||
var/camera_cache_id = 1
|
||||
|
||||
/datum/repository/cameras/New()
|
||||
networks = list()
|
||||
..()
|
||||
|
||||
/datum/repository/cameras/proc/cameras_in_network(var/network)
|
||||
setup_cache()
|
||||
var/list/network_list = networks[network]
|
||||
return network_list
|
||||
|
||||
/datum/repository/cameras/proc/setup_cache()
|
||||
if(!invalidated)
|
||||
return
|
||||
invalidated = 0
|
||||
|
||||
cameranet.process_sort()
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
var/cam = C.nano_structure()
|
||||
for(var/network in C.network)
|
||||
if(!networks[network])
|
||||
networks[network] = list()
|
||||
var/list/netlist = networks[network]
|
||||
netlist[++netlist.len] = cam
|
||||
@@ -1,9 +1,5 @@
|
||||
var/global/datum/repository/crew/crew_repository = new()
|
||||
|
||||
/datum/cache_entry
|
||||
var/timestamp
|
||||
var/data
|
||||
|
||||
/datum/repository/crew
|
||||
var/list/cache_data
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/datum/cache_entry
|
||||
var/timestamp
|
||||
var/data
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
var/on_open_network = 0
|
||||
|
||||
var/affected_by_emp_until = 0
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
wires = new(src)
|
||||
assembly = new(src)
|
||||
@@ -62,22 +64,29 @@
|
||||
wires = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/process()
|
||||
if((stat & EMPED) && world.time >= affected_by_emp_until)
|
||||
stat &= ~EMPED
|
||||
cancelCameraAlarm()
|
||||
update_icon()
|
||||
update_coverage()
|
||||
return internal_process()
|
||||
|
||||
/obj/machinery/camera/proc/internal_process()
|
||||
return
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
if(!isEmpProof())
|
||||
if(prob(100/severity))
|
||||
if(!isEmpProof() && prob(100/severity))
|
||||
if(!affected_by_emp_until || (world.time < affected_by_emp_until))
|
||||
affected_by_emp_until = max(affected_by_emp_until, world.time + (90 SECONDS / severity))
|
||||
else
|
||||
stat |= EMPED
|
||||
set_light(0)
|
||||
triggerCameraAlarm()
|
||||
kick_viewers()
|
||||
triggerCameraAlarm(30 / severity)
|
||||
update_icon()
|
||||
update_coverage()
|
||||
|
||||
spawn(900)
|
||||
stat &= ~EMPED
|
||||
cancelCameraAlarm()
|
||||
update_icon()
|
||||
update_coverage()
|
||||
..()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/machinery/camera/bullet_act(var/obj/item/projectile/P)
|
||||
take_damage(P.get_structure_damage())
|
||||
@@ -105,7 +114,6 @@
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
/obj/machinery/camera/attack_hand(mob/living/carbon/human/user as mob)
|
||||
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
@@ -114,7 +122,6 @@
|
||||
user.do_attack_animation(src)
|
||||
visible_message("<span class='warning'>\The [user] slashes at [src]!</span>")
|
||||
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
|
||||
icon_state = "[initial(icon_state)]1"
|
||||
add_hiddenprint(user)
|
||||
destroy()
|
||||
|
||||
@@ -176,7 +183,7 @@
|
||||
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 == src)
|
||||
if (S.current_camera == src)
|
||||
O << "[U] holds \a [itemname] up to one of the cameras ..."
|
||||
O << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", itemname, info), text("window=[]", itemname))
|
||||
|
||||
@@ -214,8 +221,7 @@
|
||||
//legacy support, if choice is != 1 then just kick viewers without changing status
|
||||
kick_viewers()
|
||||
else
|
||||
update_coverage()
|
||||
set_status( !src.status )
|
||||
set_status(!src.status)
|
||||
if (!(src.status))
|
||||
if(user)
|
||||
visible_message("<span class='notice'> [user] has deactivated [src]!</span>")
|
||||
@@ -257,7 +263,7 @@
|
||||
/obj/machinery/camera/proc/set_status(var/newstatus)
|
||||
if (status != newstatus)
|
||||
status = newstatus
|
||||
invalidateCameraCache()
|
||||
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?
|
||||
@@ -273,7 +279,7 @@
|
||||
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 == src)
|
||||
if (S.current_camera == src)
|
||||
O.unset_machine()
|
||||
O.reset_view(null)
|
||||
O << "The screen bursts into static."
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/alarm_delay = 100 // Don't forget, there's another 10 seconds in queueAlarm()
|
||||
flags = PROXMOVE
|
||||
|
||||
/obj/machinery/camera/process()
|
||||
/obj/machinery/camera/internal_process()
|
||||
// motion camera event loop
|
||||
if (stat & (EMPED|NOPOWER))
|
||||
return
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
/var/camera_cache_id = 1
|
||||
|
||||
/proc/invalidateCameraCache()
|
||||
camera_cache_id = (++camera_cache_id % 999999)
|
||||
|
||||
/obj/machinery/computer/security
|
||||
name = "security camera monitor"
|
||||
desc = "Used to access the various cameras on the station."
|
||||
icon_keyboard = "security_key"
|
||||
icon_screen = "cameras"
|
||||
light_color = "#a91515"
|
||||
var/obj/machinery/camera/current = null
|
||||
var/current_network = null
|
||||
var/obj/machinery/camera/current_camera = null
|
||||
var/last_pic = 1.0
|
||||
var/list/network
|
||||
var/mapping = 0//For the overview file, interesting bit of code.
|
||||
var/cache_id = 0
|
||||
circuit = /obj/item/weapon/circuitboard/security
|
||||
var/camera_cache = null
|
||||
|
||||
New()
|
||||
if(!network)
|
||||
network = station_networks
|
||||
network = station_networks.Copy()
|
||||
..()
|
||||
if(network.len)
|
||||
current_network = network[1]
|
||||
|
||||
attack_ai(var/mob/user as mob)
|
||||
return attack_hand(user)
|
||||
@@ -30,9 +27,9 @@
|
||||
check_eye(var/mob/user as mob)
|
||||
if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here.
|
||||
return -1
|
||||
if(!current)
|
||||
if(!current_camera)
|
||||
return 0
|
||||
var/viewflag = current.check_eye(user)
|
||||
var/viewflag = current_camera.check_eye(user)
|
||||
if ( viewflag < 0 ) //camera doesn't work
|
||||
reset_current()
|
||||
return viewflag
|
||||
@@ -44,7 +41,11 @@
|
||||
|
||||
var/data[0]
|
||||
|
||||
data["current"] = null
|
||||
data["current_camera"] = current_camera ? current_camera.nano_structure() : null
|
||||
data["current_network"] = current_network
|
||||
data["networks"] = network ? network : list()
|
||||
if(current_network)
|
||||
data["cameras"] = camera_repository.cameras_in_network(current_network)
|
||||
|
||||
if(camera_cache_id != cache_id)
|
||||
cache_id = camera_cache_id
|
||||
@@ -75,22 +76,32 @@
|
||||
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
Topic(href, href_list)
|
||||
if(href_list["switchTo"])
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["switch_camera"])
|
||||
if(src.z>6 || stat&(NOPOWER|BROKEN)) return
|
||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
||||
var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras
|
||||
if(!C) return
|
||||
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(src.z>6 || stat&(NOPOWER|BROKEN)) return
|
||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
||||
if(href_list["switch_network"] in network)
|
||||
current_network = href_list["switch_network"]
|
||||
return 1
|
||||
else if(href_list["reset"])
|
||||
if(src.z>6 || stat&(NOPOWER|BROKEN)) return
|
||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
||||
reset_current()
|
||||
usr.reset_view(current)
|
||||
usr.reset_view(current_camera)
|
||||
return 1
|
||||
else
|
||||
. = ..()
|
||||
@@ -105,12 +116,6 @@
|
||||
user.set_machine(src)
|
||||
ui_interact(user)
|
||||
|
||||
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
|
||||
|
||||
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))
|
||||
@@ -126,7 +131,7 @@
|
||||
if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon)))
|
||||
return 0
|
||||
set_current(C)
|
||||
user.reset_view(current)
|
||||
user.reset_view(current_camera)
|
||||
check_eye(user)
|
||||
return 1
|
||||
|
||||
@@ -160,26 +165,37 @@
|
||||
if(can_access_camera(jump_to))
|
||||
switch_to_camera(user,jump_to)
|
||||
|
||||
/obj/machinery/computer/security/process()
|
||||
if(cache_id != camera_repository.camera_cache_id)
|
||||
cache_id = camera_repository.camera_cache_id
|
||||
nanomanager.update_uis(src)
|
||||
|
||||
/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/set_current(var/obj/machinery/camera/C)
|
||||
if(current == C)
|
||||
if(current_camera == C)
|
||||
return
|
||||
|
||||
if(current)
|
||||
if(current_camera)
|
||||
reset_current()
|
||||
|
||||
src.current = C
|
||||
if(current)
|
||||
src.current_camera = C
|
||||
if(current_camera)
|
||||
use_power = 2
|
||||
var/mob/living/L = current.loc
|
||||
var/mob/living/L = current_camera.loc
|
||||
if(istype(L))
|
||||
L.tracking_initiated()
|
||||
|
||||
/obj/machinery/computer/security/proc/reset_current()
|
||||
if(current)
|
||||
var/mob/living/L = current.loc
|
||||
if(current_camera)
|
||||
var/mob/living/L = current_camera.loc
|
||||
if(istype(L))
|
||||
L.tracking_cancelled()
|
||||
current = null
|
||||
current_camera = null
|
||||
use_power = 1
|
||||
|
||||
//Camera control: mouse.
|
||||
@@ -192,7 +208,7 @@
|
||||
/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)
|
||||
var/turf/T = get_turf(console.current_camera)
|
||||
for(var/i;i<10;i++)
|
||||
T = get_step(T,direct)
|
||||
console.jump_on_click(src,T)
|
||||
@@ -248,7 +264,7 @@
|
||||
|
||||
/obj/machinery/computer/security/engineering/New()
|
||||
if(!network)
|
||||
network = engineering_networks
|
||||
network = engineering_networks.Copy()
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/security/nuclear
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
|
||||
/obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C)
|
||||
if (..(C))
|
||||
C.network = network
|
||||
C.network = network.Copy()
|
||||
|
||||
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
|
||||
if (..(C))
|
||||
network = C.network
|
||||
network = C.network.Copy()
|
||||
|
||||
/obj/item/weapon/circuitboard/security/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(emagged)
|
||||
|
||||
@@ -76,9 +76,9 @@
|
||||
|
||||
/datum/alarm/proc/cameras()
|
||||
// reset camera cache
|
||||
if(camera_cache_id != cache_id)
|
||||
if(camera_repository.camera_cache_id != cache_id)
|
||||
cameras = null
|
||||
cache_id = camera_cache_id
|
||||
cache_id = camera_repository.camera_cache_id
|
||||
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
||||
else if(cameras && (last_camera_area != alarm_area()))
|
||||
cameras = null
|
||||
|
||||
@@ -4,20 +4,31 @@ Used In File(s): \code\game\machinery\computer\camera.dm
|
||||
-->
|
||||
{{:helper.link('Show Map', 'pin-s', {'showMap' : 1})}}
|
||||
{{:helper.link('Reset', 'refresh', {'reset' : 1})}}
|
||||
<div style="float:left;">
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Current Camera: </div>
|
||||
{{if data.current_camera}}
|
||||
<div class='itemContent'><b>{{:data.current_camera.name}}</b></div>
|
||||
{{else}}
|
||||
<div class='itemContent'>None</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Current Camera: </div>
|
||||
{{if data.current}}
|
||||
<div class='itemContent'><b>{{:data.current.name}}</b></div>
|
||||
{{else}}
|
||||
<div class='itemContent'>None</div>
|
||||
{{/if}}
|
||||
<div class='itemLabel'>Networks:</div>
|
||||
</div>
|
||||
{{for data.networks}}
|
||||
{{:helper.link(value, '', {'switch_network' : value}, null, data.current_network == value ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Cameras:</div>
|
||||
</div>
|
||||
{{for data.cameras}}
|
||||
{{if data.current && value.name == data.current.name}}
|
||||
{{:helper.link(value.name, '', {'switchTo' : value.camera}, 'selected')}}
|
||||
{{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, '', {'switchTo' : value.camera})}}
|
||||
{{:helper.link(value.name, '', {'switch_camera' : value.camera})}}
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
|
||||
@@ -6,11 +6,11 @@ Used In File(s): \code\game\machinery\computer\camera.dm
|
||||
{{if value.z == 1}}
|
||||
<div class="mapIcon mapIcon16" style="left: {{:(value.x)}}px; bottom: {{:(value.y - 1)}}px;">
|
||||
{{if data.current && value.name == data.current.name}}
|
||||
{{:helper.link("#", '', {'switchTo' : value.camera}, 'selected')}}
|
||||
{{:helper.link("#", '', {'switch_camera' : value.camera}, 'selected')}}
|
||||
{{else value.deact}}
|
||||
{{:helper.link('#', '', {}, 'inactive')}}
|
||||
{{else}}
|
||||
{{:helper.link("#", '', {'switchTo' : value.camera})}}
|
||||
{{:helper.link("#", '', {'switch_camera' : value.camera})}}
|
||||
{{/if}}
|
||||
<div class="tooltip hidden">
|
||||
{{:value.name}}
|
||||
|
||||
@@ -5,14 +5,14 @@ Used In File(s): \code\game\machinery\computer\camera.dm
|
||||
{{:helper.link('Show Camera List', 'script', {'showMap' : 0})}}
|
||||
{{:helper.link('Reset', 'refresh', {'reset' : 1})}}
|
||||
<div style="float:left;">
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Current Camera: </div>
|
||||
{{if data.current}}
|
||||
<div class='itemContent'><b>{{:data.current.name}}</b></div>
|
||||
{{else}}
|
||||
<div class='itemContent'>None</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Current Camera: </div>
|
||||
{{if data.current_camera}}
|
||||
<div class='itemContent'><b>{{:data.current_camera.name}}</b></div>
|
||||
{{else}}
|
||||
<div class='itemContent'>None</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div style="float: right; width: 240px;">
|
||||
<span style="float: left;">Zoom Level: </span>
|
||||
@@ -20,4 +20,11 @@ Used In File(s): \code\game\machinery\computer\camera.dm
|
||||
<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>
|
||||
<div class='item'>
|
||||
<div class='itemLabel'>Networks:</div>
|
||||
</div>
|
||||
{{for data.networks}}
|
||||
{{:helper.link(value, '', {'switch_network' : value}, null, data.current_network == value ? 'selected' : null)}}
|
||||
{{/for}}
|
||||
@@ -154,7 +154,6 @@
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\category.dm"
|
||||
#include "code\datums\computerfiles.dm"
|
||||
#include "code\datums\crew.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
#include "code\datums\EPv2.dm"
|
||||
#include "code\datums\mind.dm"
|
||||
|
||||
Reference in New Issue
Block a user