mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Fucks up the camera net + chunk
why
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
|
||||
#define CHUNK_SIZE 16
|
||||
/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always
|
||||
#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1))
|
||||
|
||||
|
||||
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
|
||||
|
||||
GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
/datum/cameranet
|
||||
@@ -11,38 +16,54 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
var/name = "Camera Net"
|
||||
|
||||
/// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||
var/list/cameras = list()
|
||||
var/list/obj/machinery/camera/cameras = list()
|
||||
/// The chunks of the map, mapping the areas that the cameras can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
// The object used for the clickable stat() button.
|
||||
var/obj/effect/statclick/statclick
|
||||
///The image given to the effect in vis_contents on AI clients
|
||||
var/image/obscured
|
||||
|
||||
/// List of images cloned by all chunk static images put onto turfs cameras cant see
|
||||
/// Indexed by the plane offset to use
|
||||
var/list/image/obscured_images
|
||||
|
||||
/datum/cameranet/New()
|
||||
obscured = new('icons/effects/cameravis.dmi')
|
||||
obscured.plane = CAMERA_STATIC_PLANE
|
||||
obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART
|
||||
obscured.override = TRUE
|
||||
obscured_images = list()
|
||||
update_offsets(SSmapping.max_plane_offset)
|
||||
RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth))
|
||||
|
||||
/datum/cameranet/proc/update_offsets(new_offset)
|
||||
for(var/i in length(obscured_images) to new_offset)
|
||||
var/image/obscured = new('icons/effects/cameravis.dmi')
|
||||
SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i)
|
||||
obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART
|
||||
obscured.override = TRUE
|
||||
obscured_images += obscured
|
||||
|
||||
/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset)
|
||||
SIGNAL_HANDLER
|
||||
update_offsets(new_offset)
|
||||
|
||||
/// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
if(GET_LOWEST_STACK_OFFSET(z) != 0)
|
||||
var/turf/lowest = get_lowest_turf(locate(x, y, z))
|
||||
return chunks["[x],[y],[lowest.z]"]
|
||||
|
||||
return chunks["[x],[y],[z]"]
|
||||
|
||||
// Returns the chunk in the x, y, z.
|
||||
// If there is no chunk, it creates a new chunk and returns that.
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
var/key = "[x],[y],[z]"
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
var/turf/lowest = get_lowest_turf(locate(x, y, z))
|
||||
var/key = "[x],[y],[lowest.z]"
|
||||
. = chunks[key]
|
||||
if(!.)
|
||||
chunks[key] = . = new /datum/camerachunk(x, y, z)
|
||||
chunks[key] = . = new /datum/camerachunk(x, y, lowest.z)
|
||||
|
||||
/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set.
|
||||
/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
|
||||
/datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE)
|
||||
if(!islist(moved_eyes))
|
||||
moved_eyes = moved_eyes ? list(moved_eyes) : list()
|
||||
@@ -53,21 +74,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
for(var/mob/camera/aiEye/eye as anything in moved_eyes)
|
||||
var/list/visibleChunks = list()
|
||||
//Get the eye's turf in case it's located in an object like a mecha
|
||||
var/turf/eye_turf = get_turf(eye)
|
||||
if(eye.loc)
|
||||
var/x_value = eye.x
|
||||
var/y_value = eye.y
|
||||
var/z_value = eye.z
|
||||
// 0xf = 15
|
||||
var/static_range = eye.static_visibility_range
|
||||
var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1)
|
||||
|
||||
var/x1 = max(1, eye_turf.x - static_range)
|
||||
var/y1 = max(1, eye_turf.y - static_range)
|
||||
var/x2 = min(world.maxx, eye_turf.x + static_range)
|
||||
var/y2 = min(world.maxy, eye_turf.y + static_range)
|
||||
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
visibleChunks |= getCameraChunk(x, y, z_value)
|
||||
visibleChunks |= getCameraChunk(x, y, eye_turf.z)
|
||||
|
||||
var/list/remove = eye.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - eye.visibleCameraChunks
|
||||
@@ -78,7 +96,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
for(var/datum/camerachunk/chunk as anything in add)
|
||||
chunk.add(eye)
|
||||
|
||||
/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
/datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1)
|
||||
if(!SSticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
@@ -99,10 +117,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
|
||||
/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
|
||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
/**
|
||||
* Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk.
|
||||
* update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement
|
||||
* to change the time between static updates.
|
||||
*/
|
||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer)
|
||||
if(updating_camera.can_use())
|
||||
majorChunkChange(updating_camera, 1, update_delay_buffer)
|
||||
|
||||
/**
|
||||
* Never access this proc directly!!!!
|
||||
@@ -110,37 +132,52 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
* It will also add the atom to the cameras list if you set the choice to 1.
|
||||
* Setting the choice to 0 will remove the camera from the chunks.
|
||||
* If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
|
||||
* update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement
|
||||
* to change the time between static updates.
|
||||
*/
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, choice)
|
||||
if(!c)
|
||||
return
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer)
|
||||
if(QDELETED(c) && choice == 1)
|
||||
CRASH("Tried to add a qdeleting camera to the net")
|
||||
|
||||
var/turf/T = get_turf(c)
|
||||
if(T)
|
||||
var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/x1 = max(1, T.x - (CHUNK_SIZE / 2))
|
||||
var/y1 = max(1, T.y - (CHUNK_SIZE / 2))
|
||||
var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2))
|
||||
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2))
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z)
|
||||
if(chunk)
|
||||
if(choice == 0)
|
||||
// Remove the camera.
|
||||
chunk.cameras -= c
|
||||
chunk.cameras["[T.z]"] -= c
|
||||
else if(choice == 1)
|
||||
// You can't have the same camera in the list twice.
|
||||
chunk.cameras |= c
|
||||
chunk.hasChanged()
|
||||
chunk.cameras["[T.z]"] |= c
|
||||
chunk.hasChanged(update_delay_buffer = update_delay_buffer)
|
||||
|
||||
/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange]
|
||||
/// For use in sensitive code, be careful with it
|
||||
/datum/cameranet/proc/bareMajorChunkChange(turf/changed)
|
||||
var/x1 = max(1, changed.x - (CHUNK_SIZE / 2))
|
||||
var/y1 = max(1, changed.y - (CHUNK_SIZE / 2))
|
||||
var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2))
|
||||
var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2))
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z)
|
||||
chunk?.hasChanged()
|
||||
|
||||
/// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
/datum/cameranet/proc/checkCameraVis(mob/living/target)
|
||||
var/turf/position = get_turf(target)
|
||||
if(!position)
|
||||
return
|
||||
return checkTurfVis(position)
|
||||
|
||||
|
||||
/datum/cameranet/proc/checkTurfVis(turf/position)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z)
|
||||
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
|
||||
if(chunk)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
@@ -148,22 +185,25 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/cameranet/proc/stat_entry()
|
||||
if(!statclick)
|
||||
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
|
||||
|
||||
stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]"))
|
||||
/datum/cameranet/proc/getTurfVis(turf/position)
|
||||
RETURN_TYPE(/datum/camerachunk)
|
||||
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
|
||||
if(!chunk)
|
||||
return FALSE
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
if(chunk.visibleTurfs[position])
|
||||
return chunk
|
||||
|
||||
/obj/effect/overlay/camera_static
|
||||
name = "static"
|
||||
icon = null
|
||||
icon_state = null
|
||||
anchored = TRUE // should only appear in vis_contents, but to be safe
|
||||
appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR
|
||||
appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE
|
||||
// this combination makes the static block clicks to everything below it,
|
||||
// without appearing in the right-click menu for non-AI clients
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
layer = CAMERA_STATIC_LAYER
|
||||
plane = CAMERA_STATIC_PLANE
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#define UPDATE_BUFFER_TIME (2.5 SECONDS)
|
||||
|
||||
/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you
|
||||
#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0)
|
||||
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
@@ -11,20 +14,21 @@
|
||||
///turfs our cameras can see inside our grid
|
||||
var/list/visibleTurfs = list()
|
||||
///cameras that can see into our grid
|
||||
///indexed by the z level of the camera
|
||||
var/list/cameras = list()
|
||||
///list of all turfs
|
||||
///list of all turfs, associative with that turf's static image
|
||||
///turf -> /image
|
||||
var/list/turfs = list()
|
||||
///camera mobs that can see turfs in our grid
|
||||
var/list/seenby = list()
|
||||
///images created to represent obscured turfs
|
||||
var/list/inactive_static_images = list()
|
||||
///images currently in use on obscured turfs.
|
||||
var/list/active_static_images = list()
|
||||
|
||||
var/changed = FALSE
|
||||
var/x = 0
|
||||
var/y = 0
|
||||
var/z = 0
|
||||
var/lower_z
|
||||
var/upper_z
|
||||
|
||||
/// Add an AI eye to the chunk, then update if changed.
|
||||
/datum/camerachunk/proc/add(mob/camera/aiEye/eye)
|
||||
@@ -55,28 +59,33 @@
|
||||
/**
|
||||
* 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 an AI Eye moves near it.
|
||||
* update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and
|
||||
* mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because
|
||||
* otherwise a moving camera can run out of its own view before updating static.
|
||||
*/
|
||||
/datum/camerachunk/proc/hasChanged(update_now = 0)
|
||||
/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME)
|
||||
if(seenby.len || update_now)
|
||||
addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE)
|
||||
addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE)
|
||||
else
|
||||
changed = TRUE
|
||||
|
||||
/// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
/datum/camerachunk/proc/update()
|
||||
/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below
|
||||
/datum/camerachunk/proc/update(partial_update = FALSE)
|
||||
var/list/updated_visible_turfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/current_camera as anything in cameras)
|
||||
if(!current_camera || !current_camera.can_use())
|
||||
continue
|
||||
for(var/z_level in lower_z to upper_z)
|
||||
for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"])
|
||||
if(!current_camera || !current_camera.can_use())
|
||||
continue
|
||||
|
||||
var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z)
|
||||
if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2))
|
||||
continue
|
||||
var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level)
|
||||
if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2))
|
||||
continue
|
||||
|
||||
for(var/turf/vis_turf in current_camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
updated_visible_turfs[vis_turf] = vis_turf
|
||||
for(var/turf/vis_turf in current_camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
updated_visible_turfs[vis_turf] = vis_turf
|
||||
|
||||
///new turfs that we couldnt see last update but can now
|
||||
var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs
|
||||
@@ -91,31 +100,24 @@
|
||||
client.images -= active_static_images
|
||||
|
||||
for(var/turf/visible_turf as anything in newly_visible_turfs)
|
||||
var/image/static_image_to_deallocate = obscuredTurfs[visible_turf]
|
||||
if(!static_image_to_deallocate)
|
||||
var/image/static_image = obscuredTurfs[visible_turf]
|
||||
if(!static_image)
|
||||
continue
|
||||
|
||||
static_image_to_deallocate.loc = null
|
||||
active_static_images -= static_image_to_deallocate
|
||||
inactive_static_images += static_image_to_deallocate
|
||||
|
||||
active_static_images -= static_image
|
||||
obscuredTurfs -= visible_turf
|
||||
|
||||
for(var/turf/obscured_turf as anything in newly_obscured_turfs)
|
||||
if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible))
|
||||
continue
|
||||
|
||||
var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)]
|
||||
if(!static_image_to_allocate)
|
||||
stack_trace("somehow a camera chunk ran out of static images!")
|
||||
var/image/static_image = turfs[obscured_turf]
|
||||
if(!static_image)
|
||||
stack_trace("somehow a camera chunk used a turf it didn't contain!!")
|
||||
break
|
||||
|
||||
obscuredTurfs[obscured_turf] = static_image_to_allocate
|
||||
static_image_to_allocate.loc = obscured_turf
|
||||
|
||||
inactive_static_images -= static_image_to_allocate
|
||||
active_static_images += static_image_to_allocate
|
||||
|
||||
obscuredTurfs[obscured_turf] = static_image
|
||||
active_static_images += static_image
|
||||
visibleTurfs = updated_visible_turfs
|
||||
|
||||
changed = FALSE
|
||||
@@ -127,39 +129,51 @@
|
||||
|
||||
client.images += active_static_images
|
||||
|
||||
|
||||
/// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
/datum/camerachunk/New(x, y, z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
/datum/camerachunk/New(x, y, lower_z)
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
src.z = z
|
||||
src.lower_z = lower_z
|
||||
var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z))
|
||||
src.upper_z = upper_turf.z
|
||||
|
||||
for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z)))
|
||||
if(camera.can_use())
|
||||
cameras += camera
|
||||
for(var/z_level in lower_z to upper_z)
|
||||
var/list/local_cameras = list()
|
||||
for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level)))
|
||||
if(camera.can_use())
|
||||
local_cameras += camera
|
||||
|
||||
for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z)))
|
||||
turfs[t] = t
|
||||
for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level)))
|
||||
if(sillycone.builtInCamera?.can_use())
|
||||
local_cameras += sillycone.builtInCamera
|
||||
|
||||
for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses
|
||||
inactive_static_images += new/image(GLOB.cameranet.obscured)
|
||||
cameras["[z_level]"] = local_cameras
|
||||
|
||||
for(var/obj/machinery/camera/camera as anything in cameras)
|
||||
if(!camera || !camera.can_use())
|
||||
continue
|
||||
var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level)]
|
||||
var/turf/chunk_corner = locate(x, y, z_level)
|
||||
for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself
|
||||
var/image/our_image = new /image(mirror_from)
|
||||
our_image.loc = lad
|
||||
turfs[lad] = our_image
|
||||
|
||||
for(var/turf/vis_turf in camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
visibleTurfs[vis_turf] = vis_turf
|
||||
for(var/obj/machinery/camera/camera as anything in local_cameras)
|
||||
if(!camera)
|
||||
continue
|
||||
|
||||
if(!camera.can_use())
|
||||
continue
|
||||
|
||||
for(var/turf/vis_turf in camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
visibleTurfs[vis_turf] = vis_turf
|
||||
|
||||
for(var/turf/obscured_turf as anything in turfs - visibleTurfs)
|
||||
var/image/new_static = inactive_static_images[inactive_static_images.len]
|
||||
new_static.loc = obscured_turf
|
||||
var/image/new_static = turfs[obscured_turf]
|
||||
active_static_images += new_static
|
||||
inactive_static_images -= new_static
|
||||
obscuredTurfs[obscured_turf] = new_static
|
||||
|
||||
#undef UPDATE_BUFFER_TIME
|
||||
#undef CHUNK_SIZE
|
||||
|
||||
Reference in New Issue
Block a user