mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
[MIRROR] (i found some cigs) touches up cameranet code and makes it add only one vis_contents to all turfs for static (adding and removing when ai moves in/out of chunk gone) (#5785)
* Touches up cameranet code (#59165) makes it add only one vis_contents to all turfs for static (adding and removing when ai moves in/out of chunk gone) original pr: #58522 basically the same but ai's moving in/out of the chunk doesnt affect vis_contents anymore because that was really racking up tidi for some reason. Why It's Good For The Game less maptick because theres only 1 vis_contents added instead of 2 and general optimizations to cameranet code * (i found some cigs) touches up cameranet code and makes it add only one vis_contents to all turfs for static (adding and removing when ai moves in/out of chunk gone) Co-authored-by: Kylerace <kylerlumpkin1@gmail.com>
This commit is contained in:
@@ -1021,7 +1021,7 @@
|
||||
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct
|
||||
|
||||
/mob/living/silicon/ai/proc/camera_visibility(mob/camera/ai_eye/moved_eye)
|
||||
GLOB.cameranet.visibility(moved_eye, client, all_eyes, USE_STATIC_OPAQUE)
|
||||
GLOB.cameranet.visibility(moved_eye, client, all_eyes, TRUE)
|
||||
|
||||
/mob/living/silicon/ai/forceMove(atom/destination)
|
||||
. = ..()
|
||||
|
||||
@@ -18,26 +18,19 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
// The object used for the clickable stat() button.
|
||||
var/obj/effect/statclick/statclick
|
||||
|
||||
// The objects used in vis_contents of obscured turfs
|
||||
var/list/vis_contents_objects
|
||||
///this object is the static that ais see on obscured turfs, added to the turfs vis_contents
|
||||
var/obj/effect/overlay/camera_static/vis_contents_opaque
|
||||
var/obj/effect/overlay/camera_static/vis_contents_transparent
|
||||
// The image given to the effect in vis_contents on AI clients
|
||||
|
||||
///The image given to the effect in vis_contents on AI clients
|
||||
var/image/obscured
|
||||
var/image/obscured_transparent
|
||||
|
||||
/datum/cameranet/New()
|
||||
vis_contents_opaque = new /obj/effect/overlay/camera_static()
|
||||
vis_contents_transparent = new /obj/effect/overlay/camera_static/transparent()
|
||||
vis_contents_objects = list(vis_contents_opaque, vis_contents_transparent)
|
||||
|
||||
obscured = new('icons/effects/cameravis.dmi', vis_contents_opaque, null)
|
||||
obscured.plane = CAMERA_STATIC_PLANE
|
||||
|
||||
obscured_transparent = new('icons/effects/cameravis.dmi', vis_contents_transparent, null)
|
||||
obscured_transparent.plane = CAMERA_STATIC_PLANE
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/// 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)
|
||||
@@ -53,9 +46,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
if(!.)
|
||||
chunks[key] = . = new /datum/camerachunk(x, y, z)
|
||||
|
||||
// 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 = USE_STATIC_OPAQUE)
|
||||
/// 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()
|
||||
if(islist(other_eyes))
|
||||
@@ -63,15 +55,10 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
else
|
||||
other_eyes = list()
|
||||
|
||||
if(C)
|
||||
switch(use_static)
|
||||
if(USE_STATIC_TRANSPARENT)
|
||||
C.images += obscured_transparent
|
||||
if(USE_STATIC_OPAQUE)
|
||||
C.images += obscured
|
||||
if(C && use_static)
|
||||
C.images += obscured
|
||||
|
||||
for(var/V in moved_eyes)
|
||||
var/mob/camera/ai_eye/eye = V
|
||||
for(var/mob/camera/ai_eye/eye as anything in moved_eyes)
|
||||
var/list/visibleChunks = list()
|
||||
if(eye.loc)
|
||||
// 0xf = 15
|
||||
@@ -89,25 +76,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
var/list/remove = eye.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - eye.visibleCameraChunks
|
||||
|
||||
for(var/chunk in remove)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.remove(eye, FALSE)
|
||||
for(var/datum/camerachunk/chunk as anything in remove)
|
||||
chunk.remove(eye, FALSE)
|
||||
|
||||
for(var/chunk in add)
|
||||
var/datum/camerachunk/c = chunk
|
||||
c.add(eye)
|
||||
for(var/datum/camerachunk/chunk as anything in add)
|
||||
chunk.add(eye)
|
||||
|
||||
if(!eye.visibleCameraChunks.len)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
switch(eye.use_static)
|
||||
if(USE_STATIC_TRANSPARENT)
|
||||
client.images -= GLOB.cameranet.obscured_transparent
|
||||
if(USE_STATIC_OPAQUE)
|
||||
client.images -= GLOB.cameranet.obscured
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
if(client && eye.use_static)
|
||||
client.images -= obscured
|
||||
|
||||
/// 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
|
||||
@@ -119,29 +99,27 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
return
|
||||
chunk.hasChanged()
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
/// Removes a camera from a chunk.
|
||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Add a camera to a chunk.
|
||||
|
||||
/// Add a camera to a chunk.
|
||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
|
||||
// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
|
||||
|
||||
/// 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)
|
||||
|
||||
// Never access this proc directly!!!!
|
||||
// This will update the chunk and all the surrounding chunks.
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* Never access this proc directly!!!!
|
||||
* This will update the chunk and all the surrounding chunks.
|
||||
* 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.
|
||||
*/
|
||||
/datum/cameranet/proc/majorChunkChange(atom/c, choice)
|
||||
if(!c)
|
||||
return
|
||||
@@ -164,8 +142,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
chunk.cameras |= c
|
||||
chunk.hasChanged()
|
||||
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/// 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)
|
||||
return checkTurfVis(position)
|
||||
@@ -177,8 +154,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
if(chunk.changed)
|
||||
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
|
||||
if(chunk.visibleTurfs[position])
|
||||
return 1
|
||||
return 0
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/effect/overlay/camera_static
|
||||
name = "static"
|
||||
@@ -192,6 +169,3 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
plane = CAMERA_STATIC_PLANE
|
||||
|
||||
/obj/effect/overlay/camera_static/transparent
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define UPDATE_BUFFER 25 // 2.5 seconds
|
||||
#define UPDATE_BUFFER_TIME (2.5 SECONDS)
|
||||
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
@@ -6,100 +6,90 @@
|
||||
// Allows the AI Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/camerachunk
|
||||
///turfs our cameras cant see but are inside our grid
|
||||
var/list/obscuredTurfs = list()
|
||||
///turfs our cameras can see inside our grid
|
||||
var/list/visibleTurfs = list()
|
||||
///cameras that can see into our grid
|
||||
var/list/cameras = list()
|
||||
///list of all turfs
|
||||
var/list/turfs = list()
|
||||
///camera mobs that can see turfs in our grid
|
||||
var/list/seenby = list()
|
||||
var/changed = 0
|
||||
var/changed = FALSE
|
||||
var/x = 0
|
||||
var/y = 0
|
||||
var/z = 0
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/// Add an AI eye to the chunk, then update if changed.
|
||||
/datum/camerachunk/proc/add(mob/camera/ai_eye/eye)
|
||||
eye.visibleCameraChunks += src
|
||||
seenby += eye
|
||||
if(changed)
|
||||
update()
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/// Remove an AI eye from the chunk, then update if changed.
|
||||
/datum/camerachunk/proc/remove(mob/camera/ai_eye/eye, remove_static_with_last_chunk = TRUE)
|
||||
eye.visibleCameraChunks -= src
|
||||
seenby -= eye
|
||||
|
||||
if(remove_static_with_last_chunk && !eye.visibleCameraChunks.len)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
switch(eye.use_static)
|
||||
if(USE_STATIC_TRANSPARENT)
|
||||
client.images -= GLOB.cameranet.obscured_transparent
|
||||
if(USE_STATIC_OPAQUE)
|
||||
client.images -= GLOB.cameranet.obscured
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
if(client && eye.use_static)
|
||||
client.images -= GLOB.cameranet.obscured
|
||||
|
||||
/// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!visibleTurfs[loc])
|
||||
return
|
||||
hasChanged()
|
||||
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
/datum/camerachunk/proc/hasChanged(update_now = 0)
|
||||
if(seenby.len || update_now)
|
||||
addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER, TIMER_UNIQUE)
|
||||
addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER_TIME, TIMER_UNIQUE)
|
||||
else
|
||||
changed = 1
|
||||
|
||||
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
changed = TRUE
|
||||
|
||||
/// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
/datum/camerachunk/proc/update()
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/camera in cameras)
|
||||
var/obj/machinery/camera/c = camera
|
||||
|
||||
if(!c)
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
for(var/obj/machinery/camera/current_camera as anything in cameras)
|
||||
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, c) > CHUNK_SIZE + (CHUNK_SIZE / 2))
|
||||
if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2))
|
||||
continue
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
// Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards.
|
||||
// List associations use a tree or hashmap of some sort (alongside the list itself)
|
||||
// so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing)
|
||||
newVisibleTurfs[t] = t
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
newVisibleTurfs &= turfs
|
||||
for(var/turf/vis_turf in current_camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
newVisibleTurfs[vis_turf] = vis_turf
|
||||
|
||||
//new turfs will be in visibleTurfs but werent last update
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
//old turfs that will no longer be in visibleTurfs but were last update
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
//turfs that are included in the chunks normal turfs list minus the turfs the cameras CAN see
|
||||
obscuredTurfs = turfs - newVisibleTurfs
|
||||
|
||||
for(var/turf in visAdded)
|
||||
var/turf/t = turf
|
||||
t.vis_contents -= GLOB.cameranet.vis_contents_objects
|
||||
var/static/list/vis_contents_opaque = GLOB.cameranet.vis_contents_opaque //ba dum tsss
|
||||
for(var/turf/added_turf as anything in visAdded)
|
||||
added_turf.vis_contents -= vis_contents_opaque
|
||||
|
||||
for(var/turf in visRemoved)
|
||||
var/turf/t = turf
|
||||
if(obscuredTurfs[t] && !istype(t, /turf/open/ai_visible))
|
||||
t.vis_contents += GLOB.cameranet.vis_contents_objects
|
||||
for(var/turf/removed_turf as anything in visRemoved)
|
||||
if(obscuredTurfs[removed_turf] && !istype(removed_turf, /turf/open/ai_visible))
|
||||
removed_turf.vis_contents += vis_contents_opaque
|
||||
|
||||
changed = 0
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
changed = FALSE
|
||||
|
||||
/// 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)
|
||||
@@ -108,39 +98,33 @@
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
for(var/obj/machinery/camera/c in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z)))
|
||||
if(c.can_use())
|
||||
cameras += c
|
||||
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/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z)))
|
||||
if(sillycone.builtInCamera?.can_use())
|
||||
cameras += sillycone.builtInCamera
|
||||
|
||||
for(var/turf/t 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)))
|
||||
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/camera in cameras)
|
||||
var/obj/machinery/camera/c = camera
|
||||
if(!c)
|
||||
for(var/obj/machinery/camera/camera as anything in cameras)
|
||||
if(!camera)
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
if(!camera.can_use())
|
||||
continue
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
// Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards.
|
||||
// List associations use a tree or hashmap of some sort (alongside the list itself)
|
||||
// so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing)
|
||||
visibleTurfs[t] = t
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
visibleTurfs &= turfs
|
||||
for(var/turf/vis_turf in camera.can_see())
|
||||
if(turfs[vis_turf])
|
||||
visibleTurfs[vis_turf] = vis_turf
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf in obscuredTurfs)
|
||||
var/turf/t = turf
|
||||
t.vis_contents += GLOB.cameranet.vis_contents_objects
|
||||
var/list/vis_contents_opaque = GLOB.cameranet.vis_contents_opaque
|
||||
for(var/turf/obscured_turf as anything in obscuredTurfs)
|
||||
obscured_turf.vis_contents += vis_contents_opaque
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
#undef UPDATE_BUFFER_TIME
|
||||
#undef CHUNK_SIZE
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
var/relay_speech = FALSE
|
||||
var/use_static = USE_STATIC_OPAQUE
|
||||
var/use_static = TRUE
|
||||
var/static_visibility_range = 16
|
||||
var/ai_detector_visible = TRUE
|
||||
var/ai_detector_color = COLOR_RED
|
||||
@@ -44,12 +44,12 @@
|
||||
return
|
||||
hud.remove_from_hud(src)
|
||||
|
||||
var/static/list/vis_contents_objects = list()
|
||||
var/obj/effect/overlay/ai_detect_hud/hud_obj = vis_contents_objects[ai_detector_color]
|
||||
var/static/list/vis_contents_opaque = list()
|
||||
var/obj/effect/overlay/ai_detect_hud/hud_obj = vis_contents_opaque[ai_detector_color]
|
||||
if(!hud_obj)
|
||||
hud_obj = new /obj/effect/overlay/ai_detect_hud()
|
||||
hud_obj.color = ai_detector_color
|
||||
vis_contents_objects[ai_detector_color] = hud_obj
|
||||
vis_contents_opaque[ai_detector_color] = hud_obj
|
||||
|
||||
var/list/new_images = list()
|
||||
var/list/turfs = get_visible_turfs()
|
||||
@@ -86,7 +86,7 @@
|
||||
abstract_move(T)
|
||||
else
|
||||
moveToNullspace()
|
||||
if(use_static != USE_STATIC_NONE)
|
||||
if(use_static != FALSE)
|
||||
ai.camera_visibility(src)
|
||||
if(ai.client && !ai.multicam_on)
|
||||
ai.client.eye = src
|
||||
|
||||
Reference in New Issue
Block a user