mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-31 12:41:46 +00:00
174 lines
5.9 KiB
Plaintext
174 lines
5.9 KiB
Plaintext
/// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
|
/// Allows camera eyes to stream these chunks and know what they can and cannot see.
|
|
/datum/camerachunk
|
|
var/list/obscured_turfs = list()
|
|
var/list/visible_turfs = list()
|
|
var/list/obscured = list()
|
|
var/list/active_cameras = list()
|
|
var/list/inactive_cameras = list()
|
|
var/list/turfs = list()
|
|
var/list/seenby = list()
|
|
var/changed = FALSE
|
|
var/updating = FALSE
|
|
var/x = 0
|
|
var/y = 0
|
|
var/z = 0
|
|
|
|
/// Adds a camera to the chunk if it has not already been added.
|
|
/datum/camerachunk/proc/add_camera(obj/machinery/camera/cam)
|
|
if(active_cameras[cam] || inactive_cameras[cam])
|
|
return
|
|
if(cam.non_chunking_camera)
|
|
return
|
|
// Register all even though it is active/inactive. Won't get called incorrectly
|
|
RegisterSignal(cam, COMSIG_CAMERA_OFF, PROC_REF(deactivate_camera), TRUE)
|
|
RegisterSignal(cam, COMSIG_CAMERA_ON, PROC_REF(activate_camera), TRUE)
|
|
RegisterSignal(cam, COMSIG_PARENT_QDELETING, PROC_REF(remove_camera), TRUE)
|
|
RegisterSignal(cam, COMSIG_CAMERA_MOVED, PROC_REF(camera_moved), TRUE)
|
|
if(cam.can_use())
|
|
active_cameras[cam] = cam
|
|
else
|
|
inactive_cameras[cam] = cam
|
|
|
|
/// Handles each movement by a camera that has been added to the chunk.
|
|
/datum/camerachunk/proc/camera_moved(obj/machinery/camera/cam, atom/old_loc)
|
|
var/turf/T = get_turf(cam)
|
|
|
|
// Falls outside of the chunk view distance
|
|
if(T.x + CAMERA_VIEW_DISTANCE < x || T.x - CAMERA_VIEW_DISTANCE >= x + CAMERA_CHUNK_SIZE || T.y + CAMERA_VIEW_DISTANCE < y || T.y - CAMERA_VIEW_DISTANCE >= y + CAMERA_CHUNK_SIZE || T.z != z)
|
|
remove_camera(cam)
|
|
|
|
/// Removes a camera from the chunk.
|
|
/datum/camerachunk/proc/remove_camera(obj/machinery/camera/cam)
|
|
UnregisterSignal(cam, list(COMSIG_CAMERA_OFF, COMSIG_CAMERA_ON, COMSIG_PARENT_QDELETING, COMSIG_CAMERA_MOVED))
|
|
active_cameras -= cam
|
|
inactive_cameras -= cam
|
|
SScamera.queue(src)
|
|
|
|
/datum/camerachunk/proc/activate_camera(obj/machinery/camera/cam)
|
|
inactive_cameras -= cam
|
|
active_cameras += cam
|
|
SScamera.queue(src)
|
|
|
|
/datum/camerachunk/proc/deactivate_camera(obj/machinery/camera/cam)
|
|
inactive_cameras += cam
|
|
active_cameras -= cam
|
|
SScamera.queue(src)
|
|
|
|
/// Add a camera eye to the chunk, then update if changed.
|
|
/datum/camerachunk/proc/add(mob/camera/eye/eye, add_images = TRUE)
|
|
if(add_images)
|
|
var/client/client = eye.get_viewer_client()
|
|
if(client)
|
|
client.images += obscured
|
|
eye.visible_camera_chunks += src
|
|
seenby += eye
|
|
RegisterSignal(eye, COMSIG_PARENT_QDELETING, PROC_REF(eye_destroyed))
|
|
if(changed)
|
|
SScamera.queue(src)
|
|
|
|
/datum/camerachunk/proc/eye_destroyed(mob/camera/eye/eye)
|
|
remove(eye, FALSE)
|
|
|
|
/// Remove a camera eye from the chunk, then update if changed.
|
|
/datum/camerachunk/proc/remove(mob/camera/eye/eye, remove_images = TRUE)
|
|
if(remove_images)
|
|
var/client/client = eye.get_viewer_client()
|
|
if(client)
|
|
client.images -= obscured
|
|
eye.visible_camera_chunks -= src
|
|
seenby -= eye
|
|
UnregisterSignal(eye, COMSIG_PARENT_QDELETING)
|
|
|
|
/// Called when a chunk has changed. I.E: A wall was deleted.
|
|
/datum/camerachunk/proc/visibility_changed(turf/loc)
|
|
if(!visible_turfs[loc])
|
|
return
|
|
has_changed()
|
|
|
|
/// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
|
|
/// instead be flagged to update the next time a camera eye moves near it.
|
|
/datum/camerachunk/proc/has_changed(update_now = 0)
|
|
if(update_now)
|
|
update()
|
|
SScamera.remove_from_queue(src)
|
|
|
|
if(length(seenby))
|
|
SScamera.queue(src)
|
|
else
|
|
changed = TRUE
|
|
|
|
/// Gathers the visible turfs from cameras and puts them into the appropiate lists.
|
|
/datum/camerachunk/proc/update()
|
|
var/list/new_visible_turfs = list()
|
|
|
|
for(var/obj/machinery/camera/c as anything in active_cameras)
|
|
var/turf/point = locate(src.x + (CAMERA_CHUNK_SIZE / 2), src.y + (CAMERA_CHUNK_SIZE / 2), src.z)
|
|
var/turf/T = get_turf(c)
|
|
if(get_dist(point, T) > CAMERA_VIEW_DISTANCE + (CAMERA_CHUNK_SIZE / 2))
|
|
// Still needed for Ais who get created on Z level 1 on the spot of the new player
|
|
continue
|
|
|
|
for(var/turf/t in c.can_see())
|
|
if(turfs[t])
|
|
new_visible_turfs[t] = t
|
|
|
|
var/list/vis_added = new_visible_turfs - visible_turfs
|
|
var/list/vis_removed = visible_turfs - new_visible_turfs
|
|
|
|
visible_turfs = new_visible_turfs
|
|
obscured_turfs = turfs - new_visible_turfs
|
|
var/list/images_to_remove = list()
|
|
var/list/images_to_add = list()
|
|
for(var/turf/t as anything in vis_added)
|
|
if(t.obscured)
|
|
obscured -= t.obscured
|
|
images_to_remove += t.obscured
|
|
|
|
for(var/turf/t as anything in vis_removed)
|
|
if(!t.obscured)
|
|
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER + 0.1)
|
|
t.obscured.appearance_flags = RESET_TRANSFORM
|
|
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
|
|
obscured += t.obscured
|
|
images_to_add += t.obscured
|
|
|
|
for(var/mob/camera/eye/eye as anything in seenby)
|
|
var/client/client = eye.get_viewer_client()
|
|
if(client)
|
|
client.images -= images_to_remove
|
|
client.images += images_to_add
|
|
changed = FALSE
|
|
|
|
/// Create a new camera chunk, since the chunks are made as they are needed.
|
|
/datum/camerachunk/New(loc, x, y, z)
|
|
|
|
// 0xf = 15
|
|
x &= ~(CAMERA_CHUNK_SIZE - 1)
|
|
y &= ~(CAMERA_CHUNK_SIZE - 1)
|
|
|
|
src.x = x
|
|
src.y = y
|
|
src.z = z
|
|
|
|
var/half_chunk = CAMERA_CHUNK_SIZE / 2
|
|
for(var/obj/machinery/camera/c in urange(half_chunk + CAMERA_VIEW_DISTANCE, locate(x + half_chunk, y + half_chunk, z)))
|
|
add_camera(c)
|
|
|
|
for(var/turf/t in block(max(x, 1), max(y, 1), max(z, 1), min(x + CAMERA_CHUNK_SIZE - 1, world.maxx), min(y + CAMERA_CHUNK_SIZE - 1, world.maxy), z))
|
|
turfs[t] = t
|
|
|
|
for(var/obj/machinery/camera/c as anything in active_cameras)
|
|
for(var/turf/t in c.can_see())
|
|
if(turfs[t])
|
|
visible_turfs[t] = t
|
|
|
|
obscured_turfs = turfs - visible_turfs
|
|
|
|
for(var/turf/t as anything in obscured_turfs)
|
|
if(!t.obscured)
|
|
t.obscured = image('icons/effects/cameravis.dmi', t, "black", BYOND_LIGHTING_LAYER + 0.1)
|
|
t.obscured.appearance_flags = RESET_TRANSFORM
|
|
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
|
|
obscured += t.obscured
|