mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-12 16:37:19 +01:00
e4192f9b8f
we have a gorillion hard deletions and it turns out half of them are because we set the "ALWAYS HARD DELETE THIS" flag rather than just like. fixing the hard delete. cool
186 lines
5.6 KiB
Plaintext
186 lines
5.6 KiB
Plaintext
// VISUAL NET
|
|
//
|
|
// The datum containing all the chunks.
|
|
|
|
/datum/visualnet
|
|
// The chunks of the map, mapping the areas that an object can see.
|
|
var/list/chunks = list()
|
|
var/list/sources = list()
|
|
var/chunk_type = /datum/chunk
|
|
var/list/valid_source_types
|
|
|
|
/datum/visualnet/New()
|
|
..()
|
|
GLOB.visual_nets += src
|
|
if(!valid_source_types)
|
|
valid_source_types = list()
|
|
|
|
/datum/visualnet/Destroy()
|
|
GLOB.visual_nets -= src
|
|
for(var/source in sources)
|
|
remove_source(source, FALSE)
|
|
sources.Cut()
|
|
for(var/chunk in chunks)
|
|
var/chunk_datum = chunks[chunk]
|
|
qdel(chunk_datum)
|
|
chunks.Cut()
|
|
return ..()
|
|
|
|
// Checks if a chunk has been Generated in x, y, z.
|
|
/datum/visualnet/proc/is_chunk_generated(x, y, z)
|
|
x &= ~0xf
|
|
y &= ~0xf
|
|
var/key = "[x],[y],[z]"
|
|
return !isnull(chunks[key])
|
|
|
|
// Returns the chunk in the x, y, z.
|
|
// If there is no chunk, it creates a new chunk and returns that.
|
|
/datum/visualnet/proc/get_chunk(x, y, z)
|
|
x &= ~0xf
|
|
y &= ~0xf
|
|
var/key = "[x],[y],[z]"
|
|
if(!chunks[key])
|
|
chunks[key] = new chunk_type(src, x, y, z)
|
|
|
|
return chunks[key]
|
|
|
|
// Updates what the eye can see. It is recommended you use this when the eye moves or it's location is set.
|
|
|
|
/datum/visualnet/proc/update_eye_chunks(mob/abstract/eye/freelook/eye, var/full_update = FALSE)
|
|
. = list()
|
|
var/turf/T = get_turf(eye)
|
|
if(T)
|
|
// 0xf = 15
|
|
var/x1 = max(0, T.x - 16) & ~0xf
|
|
var/y1 = max(0, T.y - 16) & ~0xf
|
|
var/x2 = min(world.maxx, T.x + 16) & ~0xf
|
|
var/y2 = min(world.maxy, T.y + 16) & ~0xf
|
|
|
|
for(var/x = x1; x <= x2; x += 16)
|
|
for(var/y = y1; y <= y2; y += 16)
|
|
. += get_chunk(x, y, T.z)
|
|
|
|
if(full_update)
|
|
eye.visibleChunks.Cut()
|
|
|
|
var/list/remove = eye.visibleChunks - .
|
|
var/list/add = . - eye.visibleChunks
|
|
|
|
for(var/chunk in remove)
|
|
var/datum/chunk/c = chunk
|
|
c.remove_eye(eye)
|
|
|
|
for(var/chunk in add)
|
|
var/datum/chunk/c = chunk
|
|
c.add_eye(eye)
|
|
|
|
/datum/visualnet/proc/remove_eye(mob/abstract/eye/freelook/eye)
|
|
for(var/chunk in chunks)
|
|
var/datum/chunk/c = chunks[chunk]
|
|
c.remove_eye(eye)
|
|
|
|
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
|
|
|
/datum/visualnet/proc/update_visibility(atom/A, var/opacity_check = TRUE)
|
|
if((opacity_check && !A.opacity))
|
|
return
|
|
major_chunk_change(A)
|
|
|
|
/datum/visualnet/proc/update_visibility_nocheck(atom/A)
|
|
update_visibility(A, FALSE)
|
|
|
|
// Will check if an atom is on a viewable turf. Returns TRUE if it is, otherwise FALSE.
|
|
/datum/visualnet/proc/is_visible(var/atom/target)
|
|
var/turf/position = get_turf(target)
|
|
return position && is_turf_visible(position)
|
|
|
|
/datum/visualnet/proc/is_turf_visible(var/turf/position)
|
|
if(!position)
|
|
return FALSE
|
|
var/datum/chunk/chunk = get_chunk(position.x, position.y, position.z)
|
|
if(chunk)
|
|
if(chunk.dirty)
|
|
chunk.update(TRUE) // Update if it's visible or not
|
|
if(position in chunk.visibleTurfs)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
// Never access this proc directly!!!!
|
|
// This will update the chunk and all the surrounding chunks.
|
|
|
|
/datum/visualnet/proc/major_chunk_change(var/atom/source)
|
|
for_all_chunks_in_range(source, /datum/chunk/proc/visibility_changed, list())
|
|
|
|
/datum/visualnet/proc/add_source(var/atom/source, var/update_visibility = TRUE, var/opacity_check = FALSE)
|
|
if(!(source && is_type_in_list(source, valid_source_types)))
|
|
log_visualnet("Was given an unhandled source", source)
|
|
return FALSE
|
|
if(source in sources)
|
|
return FALSE
|
|
sources += source
|
|
RegisterSignal(source, COMSIG_MOVABLE_MOVED, PROC_REF(source_moved))
|
|
RegisterSignal(source, COMSIG_QDELETING, PROC_REF(remove_source))
|
|
for_all_chunks_in_range(source, TYPE_PROC_REF(/datum/chunk, add_source), list(source))
|
|
if(update_visibility)
|
|
update_visibility(source, opacity_check)
|
|
return TRUE
|
|
|
|
/datum/visualnet/proc/remove_source(var/atom/source, var/update_visibility = TRUE, var/opacity_check = FALSE)
|
|
if(!sources.Remove(source))
|
|
return FALSE
|
|
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
|
|
UnregisterSignal(source, COMSIG_QDELETING)
|
|
for_all_chunks_in_range(source, /datum/chunk/proc/remove_source, list(source))
|
|
if(update_visibility)
|
|
update_visibility(source, opacity_check)
|
|
return TRUE
|
|
|
|
/datum/visualnet/proc/source_moved(atom/movable/source, atom/old_loc, dir, forced, list/old_locs)
|
|
var/turf/old_turf = get_turf(old_loc)
|
|
var/turf/new_turf = get_turf(source)
|
|
|
|
if(old_turf == new_turf)
|
|
return
|
|
|
|
// A more proper way would be to figure out which chunks have gone out of range, and which have come into range
|
|
// and only remove/add to those.
|
|
if(old_turf)
|
|
for_all_chunks_in_range(source, /datum/chunk/proc/remove_source, list(source), old_turf)
|
|
if(new_turf)
|
|
for_all_chunks_in_range(source, /datum/chunk/proc/add_source, list(source), new_turf)
|
|
|
|
/datum/visualnet/proc/for_all_chunks_in_range(var/atom/source, var/proc_call, var/list/proc_args, var/turf/T)
|
|
T = T ? T : get_turf(source)
|
|
if(!T)
|
|
return
|
|
|
|
var/x1 = max(0, T.x - 8) & ~0xf
|
|
var/y1 = max(0, T.y - 8) & ~0xf
|
|
var/x2 = min(world.maxx, T.x + 8) & ~0xf
|
|
var/y2 = min(world.maxy, T.y + 8) & ~0xf
|
|
|
|
for(var/x = x1; x <= x2; x += 16)
|
|
for(var/y = y1; y <= y2; y += 16)
|
|
if(is_chunk_generated(x, y, T.z))
|
|
var/datum/chunk/c = get_chunk(x, y, T.z)
|
|
call(c, proc_call)(arglist(proc_args))
|
|
|
|
// Debug verb for VVing the chunk that the turf is in.
|
|
/turf/proc/view_chunk()
|
|
set name = "View Chunk"
|
|
set category = "Debug"
|
|
set src in world
|
|
|
|
if(GLOB.cameranet.is_chunk_generated(x, y, z))
|
|
var/datum/chunk/chunk = GLOB.cameranet.get_chunk(x, y, z)
|
|
usr.client.debug_variables(chunk)
|
|
|
|
/turf/proc/update_chunk()
|
|
set name = "Update Chunk"
|
|
set category = "Debug"
|
|
set src in world
|
|
|
|
if(GLOB.cameranet.is_chunk_generated(x, y, z))
|
|
var/datum/chunk/chunk = GLOB.cameranet.get_chunk(x, y, z)
|
|
chunk.visibility_changed(TRUE)
|