From 2c7daa751d0ff56143888bb00afe5aa3c6ecc8b2 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Wed, 19 May 2021 15:17:25 +0200 Subject: [PATCH] [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 --- code/__DEFINES/sight.dm | 4 - .../machinery/computer/camera_advanced.dm | 4 +- code/game/objects/items/devices/multitool.dm | 7 +- code/game/turfs/turf.dm | 4 +- code/modules/mob/living/silicon/ai/ai.dm | 2 +- .../living/silicon/ai/freelook/cameranet.dm | 84 +++++-------- .../mob/living/silicon/ai/freelook/chunk.dm | 118 ++++++++---------- .../mob/living/silicon/ai/freelook/eye.dm | 10 +- code/modules/shuttle/navigation_computer.dm | 2 +- 9 files changed, 94 insertions(+), 141 deletions(-) diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index a0ce649dd04..8bdd4be0b89 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -29,7 +29,3 @@ #define VISOR_DARKNESSVIEW (1<<3) #define VISOR_INVISVIEW (1<<4) -//for whether AI eyes see static, and whether it is mouse-opaque or not -#define USE_STATIC_NONE 0 -#define USE_STATIC_TRANSPARENT 1 -#define USE_STATIC_OPAQUE 2 diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 76da0bab45c..e63c4325b88 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -136,7 +136,7 @@ if(!eyeobj.eye_initialized) var/camera_location var/turf/myturf = get_turf(src) - if(eyeobj.use_static != USE_STATIC_NONE) + if(eyeobj.use_static != FALSE) if((!z_lock.len || (myturf.z in z_lock)) && GLOB.cameranet.checkTurfVis(myturf)) camera_location = myturf else @@ -223,7 +223,7 @@ else moveToNullspace() update_ai_detect_hud() - if(use_static != USE_STATIC_NONE) + if(use_static != FALSE) GLOB.cameranet.visibility(src, GetViewerClient(), null, use_static) if(visible_icon) if(eye_user.client) diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 377c08e0d15..9c9691ded16 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -106,7 +106,7 @@ /obj/item/multitool/ai_detect/proc/show_hud(mob/user) if(user && hud_type) var/atom/movable/screen/plane_master/camera_static/PM = user.hud_used.plane_masters["[CAMERA_STATIC_PLANE]"] - PM.alpha = 150 + PM.alpha = 64 var/datum/atom_hud/H = GLOB.huds[hud_type] if(!H.hudusers[user]) H.add_hud_to(user) @@ -148,7 +148,6 @@ /mob/camera/ai_eye/remote/ai_detector name = "AI detector eye" ai_detector_visible = FALSE - use_static = USE_STATIC_TRANSPARENT visible_icon = FALSE /datum/action/item_action/toggle_multitool @@ -157,11 +156,11 @@ /datum/action/item_action/toggle_multitool/Trigger() if(!..()) - return 0 + return FALSE if(target) var/obj/item/multitool/ai_detect/M = target M.toggle_hud(owner) - return 1 + return TRUE /obj/item/multitool/abductor name = "alien multitool" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 75194c81522..db37ab50c1b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -462,9 +462,9 @@ GLOBAL_LIST_EMPTY(station_turfs) var/datum/camerachunk/C = GLOB.cameranet.chunkGenerated(x, y, z) if(C) if(C.obscuredTurfs[src]) - vis_contents += GLOB.cameranet.vis_contents_objects + vis_contents += GLOB.cameranet.vis_contents_opaque else - vis_contents -= GLOB.cameranet.vis_contents_objects + vis_contents -= GLOB.cameranet.vis_contents_opaque /turf/proc/burn_tile() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index dc5e38a4867..995db437ead 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -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) . = ..() diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 618315eb834..0e729c4241e 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -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 diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 43388ed6729..7ad840e5f0c 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -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 diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index d5f72e0015d..2edaeefecd4 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -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 diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index ec92f2fc870..dd24b20cd54 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -297,7 +297,7 @@ /mob/camera/ai_eye/remote/shuttle_docker visible_icon = FALSE - use_static = USE_STATIC_NONE + use_static = FALSE var/list/placement_images = list() var/list/placed_images = list()