Merge pull request #38644 from AutomaticFrenzy/patch/cameranet

Port AI static to vis_contents
This commit is contained in:
Jordan Brown
2018-06-25 21:22:58 -04:00
committed by letterjay
parent 6b42e20e2a
commit a14bc0615d
8 changed files with 74 additions and 115 deletions
@@ -18,12 +18,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
// The object used in vis_contents of obscured turfs
var/vis_contents
// The image given to the effect in vis_contents on AI clients
var/image/obscured
/datum/cameranet/New()
vis_contents = new /obj/effect/overlay/camera_static()
obscured = new('icons/effects/cameravis.dmi', vis_contents, null, BYOND_LIGHTING_LAYER + 0.1)
obscured.plane = BYOND_LIGHTING_PLANE + 1
// 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)
var/key = "[x],[y],[z]"
return (chunks[key])
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.
@@ -31,10 +40,9 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
x &= ~(CHUNK_SIZE - 1)
y &= ~(CHUNK_SIZE - 1)
var/key = "[x],[y],[z]"
if(!chunks[key])
chunks[key] = new /datum/camerachunk(null, x, y, z)
return chunks[key]
. = chunks[key]
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.
@@ -46,14 +54,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
else
other_eyes = list()
var/list/chunks_pre_seen = list()
var/list/chunks_post_seen = list()
for(var/V in moved_eyes)
var/mob/camera/aiEye/eye = V
if(C)
chunks_pre_seen |= eye.visibleCameraChunks
// 0xf = 15
var/static_range = eye.static_visibility_range
var/x1 = max(0, eye.x - static_range) & ~(CHUNK_SIZE - 1)
var/y1 = max(0, eye.y - static_range) & ~(CHUNK_SIZE - 1)
@@ -71,44 +73,26 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
c.remove(eye, FALSE)
c.remove(eye)
for(var/chunk in add)
var/datum/camerachunk/c = chunk
c.add(eye, FALSE)
if(C)
chunks_post_seen |= eye.visibleCameraChunks
c.add(eye)
if(C)
for(var/V in other_eyes)
var/mob/camera/aiEye/eye = V
chunks_post_seen |= eye.visibleCameraChunks
var/list/remove = chunks_pre_seen - chunks_post_seen
var/list/add = chunks_post_seen - chunks_pre_seen
for(var/chunk in remove)
var/datum/camerachunk/c = chunk
C.images -= c.obscured
for(var/chunk in add)
var/datum/camerachunk/c = chunk
C.images += c.obscured
C.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
majorChunkChange(A, 2)
/datum/cameranet/proc/updateChunk(x, y, z)
// 0xf = 15
if(!chunkGenerated(x, y, z))
var/datum/camerachunk/chunk = chunkGenerated(x, y, z)
if (!chunk)
return
var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
chunk.hasChanged()
// Removes a camera from a chunk.
@@ -135,7 +119,6 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// 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)
// 0xf = 15
if(!c)
return
@@ -147,8 +130,8 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
if(chunkGenerated(x, y, T.z))
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z)
if(chunk)
if(choice == 0)
// Remove the camera.
chunk.cameras -= c
@@ -160,14 +143,12 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
// 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)
// 0xf = 15
var/turf/position = get_turf(target)
return checkTurfVis(position)
/datum/cameranet/proc/checkTurfVis(turf/position)
var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z)
if(chunk)
if(chunk.changed)
chunk.hasChanged(1) // Update now, no matter if it's visible or not.
@@ -180,3 +161,17 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]"))
/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
// 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 = BYOND_LIGHTING_LAYER + 0.1
plane = BYOND_LIGHTING_PLANE + 1
@@ -8,11 +8,9 @@
/datum/camerachunk
var/list/obscuredTurfs = list()
var/list/visibleTurfs = list()
var/list/obscured = list()
var/list/cameras = list()
var/list/turfs = list()
var/list/seenby = list()
var/visible = FALSE
var/changed = 0
var/x = 0
var/y = 0
@@ -20,28 +18,17 @@
// Add an AI eye to the chunk, then update if changed.
/datum/camerachunk/proc/add(mob/camera/aiEye/eye, add_images = TRUE)
if(add_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images += obscured
/datum/camerachunk/proc/add(mob/camera/aiEye/eye)
eye.visibleCameraChunks += src
visible++
seenby += eye
if(changed)
update()
// Remove an AI eye from the chunk, then update if changed.
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_images = TRUE)
if(remove_images)
var/client/client = eye.GetViewerClient()
if(client)
client.images -= obscured
/datum/camerachunk/proc/remove(mob/camera/aiEye/eye)
eye.visibleCameraChunks -= src
seenby -= eye
if(visible > 0)
visible--
// Called when a chunk has changed. I.E: A wall was deleted.
@@ -54,7 +41,7 @@
// instead be flagged to update the next time an AI Eye moves near it.
/datum/camerachunk/proc/hasChanged(update_now = 0)
if(visible || update_now)
if(seenby.len || update_now)
addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER, TIMER_UNIQUE)
else
changed = 1
@@ -94,41 +81,18 @@
for(var/turf in visAdded)
var/turf/t = turf
if(t.obscured)
obscured -= t.obscured
for(var/eye in seenby)
var/mob/camera/aiEye/m = eye
if(!m)
continue
var/client/client = m.GetViewerClient()
if(client)
client.images -= t.obscured
t.vis_contents -= GLOB.cameranet.vis_contents
for(var/turf in visRemoved)
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
t.obscured.pixel_x = -t.pixel_x
t.obscured.pixel_y = -t.pixel_y
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
obscured += t.obscured
for(var/eye in seenby)
var/mob/camera/aiEye/m = eye
if(!m)
seenby -= m
continue
var/client/client = m.GetViewerClient()
if(client)
client.images += t.obscured
if(obscuredTurfs[t] && !istype(t, /turf/open/ai_visible))
t.vis_contents += GLOB.cameranet.vis_contents
changed = 0
// Create a new camera chunk, since the chunks are made as they are needed.
/datum/camerachunk/New(loc, x, y, z)
// 0xf = 15
/datum/camerachunk/New(x, y, z)
x &= ~(CHUNK_SIZE - 1)
y &= ~(CHUNK_SIZE - 1)
@@ -164,12 +128,7 @@
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER+0.1)
t.obscured.pixel_x = -t.pixel_x
t.obscured.pixel_y = -t.pixel_y
t.obscured.plane = BYOND_LIGHTING_PLANE+0.1
obscured += t.obscured
t.vis_contents += GLOB.cameranet.vis_contents
#undef UPDATE_BUFFER
#undef CHUNK_SIZE
@@ -50,9 +50,7 @@
/mob/camera/aiEye/proc/RemoveImages()
var/client/C = GetViewerClient()
if(C && use_static)
for(var/V in visibleCameraChunks)
var/datum/camerachunk/c = V
C.images -= c.obscured
C.images -= GLOB.cameranet.obscured
/mob/camera/aiEye/Destroy()
if(ai)
@@ -88,10 +88,6 @@
icon_state = "room_background"
flags_1 = NOJAUNT_1
/turf/open/ai_visible/Initialize()
. = ..()
obscured = image(null, src, null)
/area/ai_multicam_room
name = "ai_multicam_room"
icon_state = "ai_camera_room"