diff --git a/baystation12.dme b/baystation12.dme
index c4dd061a2f1..6a86a5eedee 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -176,6 +176,11 @@
#include "code\datums\spells\trigger.dm"
#include "code\datums\spells\turf_teleport.dm"
#include "code\datums\spells\wizard.dm"
+#include "code\datums\visibility_networks\chunk.dm"
+#include "code\datums\visibility_networks\dictionary.dm"
+#include "code\datums\visibility_networks\update_triggers.dm"
+#include "code\datums\visibility_networks\visibility_interface.dm"
+#include "code\datums\visibility_networks\visibility_network.dm"
#include "code\datums\wires\airlock.dm"
#include "code\datums\wires\alarm.dm"
#include "code\datums\wires\apc.dm"
@@ -1106,6 +1111,7 @@
#include "code\modules\mob\living\silicon\ai\freelook\eye.dm"
#include "code\modules\mob\living\silicon\ai\freelook\read_me.dm"
#include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm"
+#include "code\modules\mob\living\silicon\ai\freelook\visibility_interface.dm"
#include "code\modules\mob\living\silicon\decoy\death.dm"
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
#include "code\modules\mob\living\silicon\decoy\life.dm"
diff --git a/code/ZAS/Airflow.dm b/code/ZAS/Airflow.dm
index 9c628b963e3..691cb3b041b 100644
--- a/code/ZAS/Airflow.dm
+++ b/code/ZAS/Airflow.dm
@@ -251,6 +251,6 @@ zone/proc/movables()
. = list()
for(var/turf/T in contents)
for(var/atom/A in T)
- if(istype(A, /obj/effect) || istype(A, /mob/camera/aiEye))
+ if(istype(A, /obj/effect) || istype(A, /mob/aiEye))
continue
. += A
\ No newline at end of file
diff --git a/code/datums/visibility_networks/dictionary.dm b/code/datums/visibility_networks/dictionary.dm
index 3dcb1bc427f..5f57ddd7a17 100644
--- a/code/datums/visibility_networks/dictionary.dm
+++ b/code/datums/visibility_networks/dictionary.dm
@@ -1,6 +1,6 @@
-var/datum/visibility_network/cameras/cameraNetwork = new()
+var/datum/visibility_network/cameras/cameranet = new()
var/datum/visibility_network/cult/cultNetwork = new()
-var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameraNetwork, "CULT" = cultNetwork)
+var/datum/visibility_network/list/visibility_networks = list("ALL_CAMERAS"=cameranet, "CULT" = cultNetwork)
// used by turfs and objects to update all visibility networks
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index d4104f4bee9..f155cd3ff55 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -478,7 +478,7 @@
/obj/item/weapon/camera_bug/attack_self(mob/usr as mob)
var/list/cameras = new/list()
- for (var/obj/machinery/camera/C in cameranet.cameras)
+ for (var/obj/machinery/camera/C in cameranet.viewpoints)
if (C.bugged && C.status)
cameras.Add(C)
if (length(cameras) == 0)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index ec4a6e40099..1db2ba3bee4 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -218,9 +218,10 @@ rcd light flash thingy on matter drain
uses = 10
cost = 15
- power_type = /mob/living/silicon/ai/proc/reactivate_camera
+ power_type = /client/proc/reactivate_camera
-/mob/living/silicon/ai/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
+
+/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.viewpoints)
set name = "Reactivate Camera"
set category = "Malfunction"
if (istype (C, /obj/machinery/camera))
@@ -241,9 +242,9 @@ rcd light flash thingy on matter drain
uses = 10
cost = 15
- power_type = /mob/living/silicon/ai/proc/upgrade_camera
+ power_type = /client/proc/upgrade_camera
-/mob/living/silicon/ai/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
+/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.viewpoints)
set name = "Upgrade Camera"
set category = "Malfunction"
if(istype(C))
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 23a398ca8c8..b0d44d31d9b 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -35,7 +35,7 @@
assembly = new(src)
assembly.state = 4
/* // Use this to look for cameras that have the same c_tag.
- for(var/obj/machinery/camera/C in cameranet.cameras)
+ for(var/obj/machinery/camera/C in cameranet.viewpoints)
var/list/tempnetwork = C.network&src.network
if(C != src && C.c_tag == src.c_tag && tempnetwork.len)
world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]"
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 9b9394fb88d..d08962bf611 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -4,7 +4,7 @@
return
var/list/L = list()
- for (var/obj/machinery/camera/C in cameranet.cameras)
+ for (var/obj/machinery/camera/C in cameranet.viewpoints)
L.Add(C)
camera_sort(L)
@@ -222,6 +222,7 @@
return 0
return 1
+
/obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob)
if (!istype(user))
return
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index f6c834036e9..51e420b52f2 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -36,7 +36,7 @@
user.set_machine(src)
var/list/L = list()
- for (var/obj/machinery/camera/C in cameranet.cameras)
+ for (var/obj/machinery/camera/C in cameranet.viewpoints)
L.Add(C)
camera_sort(L)
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index 03ed85b6e00..e17dbc023fa 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -126,24 +126,14 @@ var/global/normal_ooc_colour = "#002eb8"
return
log_ooc("(LOCAL) [mob.name]/[key] : [msg]")
- var/list/heard
- var/mob/living/silicon/ai/AI
- if(!isAI(src.mob))
- heard = get_mobs_in_view(7, src.mob)
- else
- AI = src.mob
- heard = get_mobs_in_view(7, (istype(AI.eyeobj) ? AI.eyeobj : AI)) //if it doesn't have an eye somehow give it just the AI mob itself
+ var/list/heard = get_mobs_in_view(7, src.mob)
for(var/mob/M in heard)
- if(AI == M) continue
if(!M.client)
continue
var/client/C = M.client
if (C in admins)
continue //they are handled after that
- if(isAIEye(M))
- var/mob/camera/aiEye/E = M
- if(E.ai)
- C = E.ai.client
+
if(C.prefs.toggles & CHAT_LOOC)
var/display_name = src.key
if(holder)
@@ -153,24 +143,9 @@ var/global/normal_ooc_colour = "#002eb8"
else
display_name = holder.fakekey
C << "LOOC: [display_name]: [msg]"
-
for(var/client/C in admins)
if(C.prefs.toggles & CHAT_LOOC)
var/prefix = "(R)LOOC"
if (C.mob in heard)
prefix = "LOOC"
- C << "[prefix]: [src.key]: [msg]"
- if(istype(AI))
- var/client/C = AI.client
- if (C in admins)
- return //already been handled
-
- if(C.prefs.toggles & CHAT_LOOC)
- var/display_name = src.key
- if(holder)
- if(holder.fakekey)
- if(C.holder)
- display_name = "[holder.fakekey]/([src.key])"
- else
- display_name = holder.fakekey
- C << "LOOC: [display_name]: [msg]"
+ C << "[prefix]: [src.key]: [msg]"
\ No newline at end of file
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index b1b5098be40..e1ed1222f3a 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -58,7 +58,7 @@ var/intercom_range_display_status = 0
del(C)
if(camera_range_display_status)
- for(var/obj/machinery/camera/C in cameranet.cameras)
+ for(var/obj/machinery/camera/C in cameranet.viewpoints)
new/obj/effect/debugging/camera_range(C.loc)
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -74,7 +74,7 @@ var/intercom_range_display_status = 0
var/list/obj/machinery/camera/CL = list()
- for(var/obj/machinery/camera/C in cameranet.cameras)
+ for(var/obj/machinery/camera/C in cameranet.viewpoints)
CL += C
var/output = {"CAMERA ANOMALIES REPORT
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 24c827c46ad..daf78c7997f 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -396,7 +396,7 @@ var/list/ai_list = list()
unset_machine()
src << browse(null, t1)
if (href_list["switchcamera"])
- switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
+ switchCamera(locate(href_list["switchcamera"])) in cameranet.viewpoints
if (href_list["showalerts"])
ai_alerts()
//Carn: holopad requests
@@ -626,7 +626,7 @@ var/list/ai_list = list()
var/mob/living/silicon/ai/U = usr
- for (var/obj/machinery/camera/C in cameranet.cameras)
+ for (var/obj/machinery/camera/C in cameranet.viewpoints)
if(!C.can_use())
continue
@@ -644,7 +644,7 @@ var/list/ai_list = list()
if(isnull(network))
network = old_network // If nothing is selected
else
- for(var/obj/machinery/camera/C in cameranet.cameras)
+ for(var/obj/machinery/camera/C in cameranet.viewpoints)
if(!C.can_use())
continue
if(network in C.network)
diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
index c80f6d72fe1..31e4cae6a61 100644
--- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
@@ -1,150 +1,14 @@
-// CAMERA NET
-//
-// The datum containing all the chunks.
-
-var/const/CHUNK_SIZE = 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
-
-var/datum/cameranet/cameranet = new()
-
-/datum/cameranet
- // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Destroy().
- var/list/cameras = list()
- // The chunks of the map, mapping the areas that the cameras can see.
- var/list/chunks = list()
- var/ready = 0
-
-// 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])
-
-// 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]"
- if(!chunks[key])
- chunks[key] = new /datum/camerachunk(null, x, y, z)
-
- return chunks[key]
-
-// 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(mob/camera/aiEye/ai)
- // 0xf = 15
- var/x1 = max(0, ai.x - 16) & ~(CHUNK_SIZE - 1)
- var/y1 = max(0, ai.y - 16) & ~(CHUNK_SIZE - 1)
- var/x2 = min(world.maxx, ai.x + 16) & ~(CHUNK_SIZE - 1)
- var/y2 = min(world.maxy, ai.y + 16) & ~(CHUNK_SIZE - 1)
-
- var/list/visibleChunks = list()
-
- for(var/x = x1; x <= x2; x += CHUNK_SIZE)
- for(var/y = y1; y <= y2; y += CHUNK_SIZE)
- visibleChunks |= getCameraChunk(x, y, ai.z)
-
- var/list/remove = ai.visibleCameraChunks - visibleChunks
- var/list/add = visibleChunks - ai.visibleCameraChunks
-
- for(var/chunk in remove)
- var/datum/camerachunk/c = chunk
- c.remove(ai)
-
- for(var/chunk in add)
- var/datum/camerachunk/c = chunk
- c.add(ai)
-
-// 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, var/opacity_check = 1)
-
- if(!ticker || (opacity_check && !A.opacity))
- return
- majorChunkChange(A, 2)
-
-/datum/cameranet/proc/updateChunk(x, y, z)
- // 0xf = 15
- if(!chunkGenerated(x, y, z))
- return
- var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
- chunk.hasChanged()
-
-// Removes a camera from a chunk.
-
-/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
- if(c.can_use())
- majorChunkChange(c, 0)
-
-// 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.
-
-/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
- if(c.can_use())
- majorChunkChange(c, 1)
- //else
- // majorChunkChange(c, 0)
-
-// 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, var/choice)
- // 0xf = 15
- if(!c)
- return
-
- 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)
-
- //world << "X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]"
-
- 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)
- if(choice == 0)
- // Remove the camera.
- chunk.cameras -= c
- else if(choice == 1)
- // You can't have the same camera in the list twice.
- chunk.cameras |= c
- 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 as mob)
-
- // 0xf = 15
- var/turf/position = get_turf(target)
- 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.
- if(chunk.visibleTurfs[position])
- return 1
- return 0
-
-
-// Debug verb for VVing the chunk that the turf is in.
-/*
-/turf/verb/view_chunk()
- set src in world
-
- if(cameranet.chunkGenerated(x, y, z))
- var/datum/camerachunk/chunk = cameranet.getCameraChunk(x, y, z)
- usr.client.debug_variables(chunk)
-*/
\ No newline at end of file
+/datum/visibility_network/cameras
+ ChunkType = /datum/visibility_chunk/camera
+
+/datum/visibility_network/cameras/getViewpointFromMob(var/mob/currentMob)
+ var/mob/living/silicon/robot/currentRobot=currentMob
+ if(currentRobot)
+ return currentRobot.camera
+ return FALSE
+
+/datum/visibility_network/cameras/validViewpoint(var/viewpoint)
+ var/obj/machinery/camera/c = viewpoint
+ if (!c)
+ return FALSE
+ return c.can_use()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
index e2778c534e8..ba4e7892f57 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm
@@ -1,174 +1,23 @@
-#define UPDATE_BUFFER 25 // 2.5 seconds
-
-// CAMERA CHUNK
-//
-// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
-// Allows the AI Eye to stream these chunks and know what it can and cannot see.
-
-/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 = 0
- var/changed = 0
- var/updating = 0
- var/x = 0
- var/y = 0
- var/z = 0
-
-// Add an AI eye to the chunk, then update if changed.
-
-/datum/camerachunk/proc/add(mob/camera/aiEye/ai)
- if(!ai.ai)
- return
- ai.visibleCameraChunks += src
- if(ai.ai.client)
- ai.ai.client.images += obscured
- visible++
- seenby += ai
- if(changed && !updating)
- update()
-
-// Remove an AI eye from the chunk, then update if changed.
-
-/datum/camerachunk/proc/remove(mob/camera/aiEye/ai)
- if(!ai.ai)
- return
- ai.visibleCameraChunks -= src
- if(ai.ai.client)
- ai.ai.client.images -= obscured
- seenby -= ai
- if(visible > 0)
- visible--
-
-// 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.
-
-/datum/camerachunk/proc/hasChanged(var/update_now = 0)
- if(visible || update_now)
- if(!updating)
- updating = 1
- spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
- update()
- updating = 0
- else
- changed = 1
-
-// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
-
-/datum/camerachunk/proc/update()
-
- //set background = 1
-
- var/list/newVisibleTurfs = list()
-
- for(var/camera in cameras)
- var/obj/machinery/camera/c = camera
-
- if(!c)
- continue
-
- if(!c.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))
- 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
-
- var/list/visAdded = newVisibleTurfs - visibleTurfs
- var/list/visRemoved = visibleTurfs - newVisibleTurfs
-
- visibleTurfs = newVisibleTurfs
- obscuredTurfs = turfs - newVisibleTurfs
-
- 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 || !m.ai)
- continue
- if(m.ai.client)
- m.ai.client.images -= t.obscured
-
- for(var/turf in visRemoved)
- var/turf/t = turf
- if(obscuredTurfs[t])
- if(!t.obscured)
- t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
-
- obscured += t.obscured
- for(var/eye in seenby)
- var/mob/camera/aiEye/m = eye
- if(!m || !m.ai)
- seenby -= m
- continue
- if(m.ai.client)
- m.ai.client.images += t.obscured
-
- 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
- x &= ~(CHUNK_SIZE - 1)
- y &= ~(CHUNK_SIZE - 1)
-
- src.x = x
- src.y = y
- src.z = z
-
- for(var/obj/machinery/camera/c in range(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z)))
- if(c.can_use())
- cameras += c
-
- for(var/turf/t in block(locate(x, y, 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)
- continue
-
- if(!c.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
-
- obscuredTurfs = turfs - visibleTurfs
-
- for(var/turf in obscuredTurfs)
- var/turf/t = turf
- if(!t.obscured)
- t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
- obscured += t.obscured
-
-#undef UPDATE_BUFFER
\ No newline at end of file
+/datum/visibility_chunk/camera
+
+/datum/visibility_chunk/camera/validViewpoint(var/viewpoint)
+ var/obj/machinery/camera/c = viewpoint
+ if(!c)
+ return FALSE
+ if(!c.can_use())
+ return FALSE
+ var/turf/point = locate(src.x + 8, src.y + 8, src.z)
+ if(get_dist(point, c) > 24)
+ return FALSE
+ return TRUE
+
+
+/datum/visibility_chunk/camera/getVisibleTurfsForViewpoint(var/viewpoint)
+ var/obj/machinery/camera/c = viewpoint
+ return c.can_see()
+
+
+/datum/visibility_chunk/camera/findNearbyViewpoints()
+ for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
+ if(c.can_use())
+ viewpoints += c
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index d9ae699c6b5..cd49a089a38 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -3,17 +3,43 @@
// An invisible (no icon) mob that the AI controls to look around the station with.
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
-/mob/camera/aiEye
+/mob/aiEye
name = "Inactive AI Eye"
- var/list/visibleCameraChunks = list()
+ icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o
var/mob/living/silicon/ai/ai = null
+ density = 0
+ status_flags = GODMODE // You can't damage it.
+ mouse_opacity = 0
+ see_in_dark = 7
+/mob/aiEye/New()
+ ..()
+ visibility_interface = new /datum/visibility_interface/ai_eye(src)
+
+// Movement code. Returns 0 to stop air movement from moving it.
+/mob/aiEye/Move()
+ return 0
+
+// Hide popout menu verbs
+/mob/aiEye/examine()
+ set popup_menu = 0
+ set src = usr.contents
+ return 0
+
+/mob/aiEye/pull()
+ set popup_menu = 0
+ set src = usr.contents
+ return 0
+
+/mob/aiEye/point()
+ set popup_menu = 0
+ set src = usr.contents
+ return 0
// Use this when setting the aiEye's location.
// It will also stream the chunk that the new loc is in.
-/mob/camera/aiEye/proc/setLoc(var/T)
-
+/mob/aiEye/proc/setLoc(var/T)
if(ai)
if(!isturf(ai.loc))
return
@@ -28,7 +54,7 @@
H.move_hologram()
-/mob/camera/aiEye/Move()
+/mob/aiEye/Move()
return 0
// AI MOVEMENT
@@ -36,7 +62,7 @@
// The AI's "eye". Described on the top of the page.
/mob/living/silicon/ai
- var/mob/camera/aiEye/eyeobj = new()
+ var/mob/aiEye/eyeobj = new()
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
@@ -116,7 +142,8 @@
if(client && client.eye)
client.eye = src
- for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
+
+ for(var/datum/visibility_chunk/camera/c in eyeobj.visibility_interface.visible_chunks)
c.remove(eyeobj)
/mob/living/silicon/ai/verb/toggle_acceleration()
diff --git a/code/modules/mob/living/silicon/ai/freelook/read_me.dm b/code/modules/mob/living/silicon/ai/freelook/read_me.dm
index 8ddb0689409..e71b0903b85 100644
--- a/code/modules/mob/living/silicon/ai/freelook/read_me.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/read_me.dm
@@ -43,7 +43,7 @@
WHERE IS EVERYTHING?
- cameranet.dm = Everything about the cameranet datum.
+ cameraNetwork.dm = Everything about the cameraNetwork datum.
chunk.dm = Everything about the chunk datum.
eye.dm = Everything about the AI and the AIEye.
updating.dm = Everything about triggers that will update chunks.
diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
index e4b13366d92..775d8864751 100644
--- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm
@@ -1,79 +1,3 @@
-#define BORG_CAMERA_BUFFER 30
-
-//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
-
-// TURFS
-
-/turf
- var/image/obscured
-
-/turf/proc/visibilityChanged()
- if(ticker)
- cameranet.updateVisibility(src)
-
-/turf/simulated/Destroy()
- visibilityChanged()
- ..()
-
-/turf/simulated/New()
- ..()
- visibilityChanged()
-
-
-
-// STRUCTURES
-
-/obj/structure/Destroy()
- if(ticker)
- cameranet.updateVisibility(src)
- ..()
-
-/obj/structure/New()
- ..()
- if(ticker)
- cameranet.updateVisibility(src)
-
-// EFFECTS
-
-/obj/effect/Destroy()
- if(ticker)
- cameranet.updateVisibility(src)
- ..()
-
-/obj/effect/New()
- ..()
- if(ticker)
- cameranet.updateVisibility(src)
-
-
-// DOORS
-
-// Simply updates the visibility of the area when it opens/closes/destroyed.
-/obj/machinery/door/proc/update_freelok_sight()
- // Glass door glass = 1
- // don't check then?
- if(!glass && cameranet)
- cameranet.updateVisibility(src, 0)
-
-
-// ROBOT MOVEMENT
-
-// Update the portable camera everytime the Robot moves.
-// This might be laggy, comment it out if there are problems.
-/mob/living/silicon/robot/var/updating = 0
-
-/mob/living/silicon/robot/Move()
- var/oldLoc = src.loc
- . = ..()
- if(.)
- if(src.camera && src.camera.network.len)
- if(!updating)
- updating = 1
- spawn(BORG_CAMERA_BUFFER)
- if(oldLoc != src.loc)
- cameranet.updatePortableCamera(src.camera)
- updating = 0
-
// CAMERA
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
@@ -81,23 +5,23 @@
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
..(user, choice)
if(src.can_use())
- cameranet.addCamera(src)
+ cameranet.addViewpoint(src)
else
src.SetLuminosity(0)
- cameranet.removeCamera(src)
+ cameranet.removeViewpoint(src)
/obj/machinery/camera/New()
..()
- cameranet.cameras += src //Camera must be added to global list of all cameras no matter what...
+ cameranet.viewpoints += src //Camera must be added to global list of all cameras no matter what...
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS) //...but if all of camera's networks are restricted, it only works for specific camera consoles.
if(open_networks.len) //If there is at least one open network, chunk is available for AI usage.
- cameranet.addCamera(src)
+ cameranet.addViewpoint(src)
-/obj/machinery/camera/Destroy()
- cameranet.cameras -= src
+/obj/machinery/camera/Del()
+ cameranet.viewpoints -= src
var/list/open_networks = difflist(network,RESTRICTED_CAMERA_NETWORKS)
if(open_networks.len)
- cameranet.removeCamera(src)
+ cameranet.removeViewpoint(src)
..()
#undef BORG_CAMERA_BUFFER
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm
new file mode 100644
index 00000000000..b55598c6090
--- /dev/null
+++ b/code/modules/mob/living/silicon/ai/freelook/visibility_interface.dm
@@ -0,0 +1,10 @@
+/datum/visibility_interface/ai_eye
+ chunk_type = /datum/visibility_chunk/camera
+
+/datum/visibility_interface/ai_eye/getClient()
+ var/mob/aiEye/eye = controller
+ if (!eye)
+ return FALSE
+ if (!eye.ai)
+ return FALSE
+ return eye.ai.client
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index c763a7b6f91..59dae2f979d 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -205,6 +205,7 @@
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
+ var/datum/visibility_interface/visibility_interface = null // used by the visibility system to provide an interface for the visibility networks
//Whether or not mobs can understand other mobtypes. These stay in /mob so that ghosts can hear everything.
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
@@ -224,4 +225,4 @@
var/list/active_genes=list()
- var/last_movement = -100 // Last world.time the mob actually moved of its own accord.
\ No newline at end of file
+ var/last_movement = -100 // Last world.time the mob actually moved of its own accord.
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 34fda885462..0b203c92eb3 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -101,7 +101,7 @@ proc/isembryo(A)
return 0
/proc/isAIEye(A)
- if(istype(A, /mob/camera/aiEye))
+ if(istype(A, /mob/aiEye))
return 1
return 0