mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-27 14:08:44 +01:00
Whitespace Standardization [MDB IGNORE] (#15748)
* Update settings * Whitespace changes * Comment out merger hooks in gitattributes Corrupt maps would have to be resolved in repo before hooks could be updated * Revert "Whitespace changes" This reverts commitafbdd1d844. * Whitespace again minus example * Gitignore example changelog * Restore changelog merge setting * Keep older dmi hook attribute until hooks can be updated * update vscode settings too * Renormalize remaining * Revert "Gitignore example changelog" This reverts commitde22ad375d. * Attempt to normalize example.yml (and another file I guess) * Try again
This commit is contained in:
@@ -1,44 +1,44 @@
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visualnet/camera
|
||||
// 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()
|
||||
var/cameras_unsorted = 1
|
||||
chunk_type = /datum/chunk/camera
|
||||
|
||||
/datum/visualnet/camera/proc/process_sort()
|
||||
if(cameras_unsorted)
|
||||
cameras = dd_sortedObjectList(cameras)
|
||||
cameras_unsorted = 0
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
/datum/visualnet/camera/proc/removeCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Add a camera to a chunk.
|
||||
|
||||
/datum/visualnet/camera/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/visualnet/camera/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
//else
|
||||
// majorChunkChange(c, 0)
|
||||
|
||||
/datum/visualnet/camera/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/camera/chunk)
|
||||
// Only add actual cameras to the list of cameras
|
||||
if(istype(c, /obj/machinery/camera))
|
||||
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
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visualnet/camera
|
||||
// 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()
|
||||
var/cameras_unsorted = 1
|
||||
chunk_type = /datum/chunk/camera
|
||||
|
||||
/datum/visualnet/camera/proc/process_sort()
|
||||
if(cameras_unsorted)
|
||||
cameras = dd_sortedObjectList(cameras)
|
||||
cameras_unsorted = 0
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
/datum/visualnet/camera/proc/removeCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// Add a camera to a chunk.
|
||||
|
||||
/datum/visualnet/camera/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/visualnet/camera/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
//else
|
||||
// majorChunkChange(c, 0)
|
||||
|
||||
/datum/visualnet/camera/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/camera/chunk)
|
||||
// Only add actual cameras to the list of cameras
|
||||
if(istype(c, /obj/machinery/camera))
|
||||
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
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/chunk/camera
|
||||
var/list/cameras = list()
|
||||
|
||||
/datum/chunk/camera/acquireVisibleTurfs(var/list/visible)
|
||||
for(var/obj/machinery/camera/c as anything in cameras)
|
||||
|
||||
if(!istype(c))
|
||||
cameras -= c
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
continue
|
||||
|
||||
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
|
||||
if(get_dist(point, c) > 24)
|
||||
cameras -= c
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
visible[t] = t
|
||||
|
||||
for(var/mob/living/silicon/ai/AI in living_mob_list)
|
||||
for(var/turf/t in AI.seen_camera_turfs())
|
||||
visible[t] = t
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/chunk/camera/New(loc, x, y, z)
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.can_use())
|
||||
cameras += c
|
||||
..()
|
||||
|
||||
/mob/living/silicon/proc/provides_camera_vision()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/provides_camera_vision()
|
||||
return stat != DEAD
|
||||
|
||||
/mob/living/silicon/robot/provides_camera_vision()
|
||||
return src.camera && src.camera.network.len && (z in using_map.contact_levels) //VOREStation Edit
|
||||
|
||||
/mob/living/silicon/ai/proc/seen_camera_turfs()
|
||||
return seen_turfs_in_range(src, world.view)
|
||||
// CAMERA CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/chunk/camera
|
||||
var/list/cameras = list()
|
||||
|
||||
/datum/chunk/camera/acquireVisibleTurfs(var/list/visible)
|
||||
for(var/obj/machinery/camera/c as anything in cameras)
|
||||
|
||||
if(!istype(c))
|
||||
cameras -= c
|
||||
continue
|
||||
|
||||
if(!c.can_use())
|
||||
continue
|
||||
|
||||
var/turf/point = locate(src.x + 8, src.y + 8, src.z)
|
||||
if(get_dist(point, c) > 24)
|
||||
cameras -= c
|
||||
|
||||
for(var/turf/t in c.can_see())
|
||||
visible[t] = t
|
||||
|
||||
for(var/mob/living/silicon/ai/AI in living_mob_list)
|
||||
for(var/turf/t in AI.seen_camera_turfs())
|
||||
visible[t] = t
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/chunk/camera/New(loc, x, y, z)
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.can_use())
|
||||
cameras += c
|
||||
..()
|
||||
|
||||
/mob/living/silicon/proc/provides_camera_vision()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/provides_camera_vision()
|
||||
return stat != DEAD
|
||||
|
||||
/mob/living/silicon/robot/provides_camera_vision()
|
||||
return src.camera && src.camera.network.len && (z in using_map.contact_levels) //VOREStation Edit
|
||||
|
||||
/mob/living/silicon/ai/proc/seen_camera_turfs()
|
||||
return seen_turfs_in_range(src, world.view)
|
||||
|
||||
+115
-115
@@ -1,115 +1,115 @@
|
||||
// AI EYE
|
||||
//
|
||||
// A 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/observer/eye/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
icon_state = "AI-eye"
|
||||
|
||||
/mob/observer/eye/aiEye/New()
|
||||
..()
|
||||
visualnet = cameranet
|
||||
|
||||
/mob/observer/eye/aiEye/Destroy()
|
||||
if(owner)
|
||||
var/mob/living/silicon/ai/ai = owner
|
||||
ai.all_eyes -= src
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/mob/observer/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1)
|
||||
if(owner)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
|
||||
var/mob/living/silicon/ai/ai = owner
|
||||
if(cancel_tracking)
|
||||
ai.ai_cancel_tracking()
|
||||
|
||||
if(use_static)
|
||||
ai.camera_visibility(src)
|
||||
|
||||
if(ai.client && !ai.multicam_on)
|
||||
ai.client.eye = src
|
||||
|
||||
if(ai.master_multicam)
|
||||
ai.master_multicam.refresh_view()
|
||||
|
||||
if(ai.holo)
|
||||
if(ai.hologram_follow)
|
||||
ai.holo.move_hologram(ai)
|
||||
|
||||
return 1
|
||||
|
||||
// AI MOVEMENT
|
||||
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/obj/machinery/hologram/holopad/holo = null
|
||||
|
||||
/mob/living/silicon/ai/proc/destroy_eyeobj(var/atom/new_eye)
|
||||
if(!eyeobj) return
|
||||
if(!new_eye)
|
||||
new_eye = src
|
||||
eyeobj.owner = null
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
eyeobj = null
|
||||
if(client)
|
||||
client.eye = new_eye
|
||||
|
||||
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
|
||||
if(eyeobj)
|
||||
destroy_eyeobj()
|
||||
if(!newloc)
|
||||
newloc = src.loc
|
||||
eyeobj = new /mob/observer/eye/aiEye(newloc)
|
||||
all_eyes += eyeobj
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
if(client)
|
||||
client.eye = eyeobj
|
||||
SetName(src.name)
|
||||
|
||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||
/mob/living/silicon/ai/Initialize()
|
||||
. = ..()
|
||||
create_eyeobj()
|
||||
if(eyeobj)
|
||||
eyeobj.loc = src.loc
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
destroy_eyeobj()
|
||||
return ..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)))
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
AI.eyeobj.setLoc(T)
|
||||
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
camera = null
|
||||
unset_machine()
|
||||
|
||||
if(!src.eyeobj)
|
||||
return
|
||||
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
for(var/datum/chunk/c in eyeobj.visibleChunks)
|
||||
c.remove(eyeobj)
|
||||
src.eyeobj.setLoc(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/toggle_acceleration()
|
||||
set category = "AI Settings"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
eyeobj.acceleration = !eyeobj.acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [eyeobj.acceleration ? "on" : "off"].")
|
||||
// AI EYE
|
||||
//
|
||||
// A 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/observer/eye/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
icon_state = "AI-eye"
|
||||
|
||||
/mob/observer/eye/aiEye/New()
|
||||
..()
|
||||
visualnet = cameranet
|
||||
|
||||
/mob/observer/eye/aiEye/Destroy()
|
||||
if(owner)
|
||||
var/mob/living/silicon/ai/ai = owner
|
||||
ai.all_eyes -= src
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/mob/observer/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1)
|
||||
if(owner)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
|
||||
var/mob/living/silicon/ai/ai = owner
|
||||
if(cancel_tracking)
|
||||
ai.ai_cancel_tracking()
|
||||
|
||||
if(use_static)
|
||||
ai.camera_visibility(src)
|
||||
|
||||
if(ai.client && !ai.multicam_on)
|
||||
ai.client.eye = src
|
||||
|
||||
if(ai.master_multicam)
|
||||
ai.master_multicam.refresh_view()
|
||||
|
||||
if(ai.holo)
|
||||
if(ai.hologram_follow)
|
||||
ai.holo.move_hologram(ai)
|
||||
|
||||
return 1
|
||||
|
||||
// AI MOVEMENT
|
||||
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/obj/machinery/hologram/holopad/holo = null
|
||||
|
||||
/mob/living/silicon/ai/proc/destroy_eyeobj(var/atom/new_eye)
|
||||
if(!eyeobj) return
|
||||
if(!new_eye)
|
||||
new_eye = src
|
||||
eyeobj.owner = null
|
||||
qdel(eyeobj) // No AI, no Eye
|
||||
eyeobj = null
|
||||
if(client)
|
||||
client.eye = new_eye
|
||||
|
||||
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
|
||||
if(eyeobj)
|
||||
destroy_eyeobj()
|
||||
if(!newloc)
|
||||
newloc = src.loc
|
||||
eyeobj = new /mob/observer/eye/aiEye(newloc)
|
||||
all_eyes += eyeobj
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
if(client)
|
||||
client.eye = eyeobj
|
||||
SetName(src.name)
|
||||
|
||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||
/mob/living/silicon/ai/Initialize()
|
||||
. = ..()
|
||||
create_eyeobj()
|
||||
if(eyeobj)
|
||||
eyeobj.loc = src.loc
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
destroy_eyeobj()
|
||||
return ..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)))
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
AI.eyeobj.setLoc(T)
|
||||
|
||||
/mob/living/silicon/ai/proc/view_core()
|
||||
camera = null
|
||||
unset_machine()
|
||||
|
||||
if(!src.eyeobj)
|
||||
return
|
||||
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
for(var/datum/chunk/c in eyeobj.visibleChunks)
|
||||
c.remove(eyeobj)
|
||||
src.eyeobj.setLoc(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/toggle_acceleration()
|
||||
set category = "AI Settings"
|
||||
set name = "Toggle Camera Acceleration"
|
||||
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
eyeobj.acceleration = !eyeobj.acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [eyeobj.acceleration ? "on" : "off"].")
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
#define BORG_CAMERA_BUFFER 30
|
||||
|
||||
// ROBOT MOVEMENT
|
||||
|
||||
// Update the portable camera everytime the Robot moves.
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
/mob/living/silicon/var/updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/ai/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updateVisibility(old_loc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
updating = 0
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
|
||||
// CAMERA
|
||||
|
||||
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
|
||||
|
||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||
..(user, choice)
|
||||
if(src.can_use())
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
src.set_light(0)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
//Camera must be added to global list of all cameras no matter what...
|
||||
if(cameranet.cameras_unsorted || !ticker)
|
||||
cameranet.cameras += src
|
||||
cameranet.cameras_unsorted = 1
|
||||
else
|
||||
dd_insertObjectList(cameranet.cameras, src)
|
||||
update_coverage(1)
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
clear_all_networks()
|
||||
cameranet.cameras -= src
|
||||
return ..()
|
||||
|
||||
// Mobs
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
..()
|
||||
if(was_dead && stat != DEAD)
|
||||
// Arise!
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/silicon/ai/death(gibbed)
|
||||
if(..())
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
#define BORG_CAMERA_BUFFER 30
|
||||
|
||||
// ROBOT MOVEMENT
|
||||
|
||||
// Update the portable camera everytime the Robot moves.
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
/mob/living/silicon/var/updating = 0
|
||||
|
||||
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/ai/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!provides_camera_vision())
|
||||
return
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cameranet.updateVisibility(old_loc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
updating = 0
|
||||
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
|
||||
// CAMERA
|
||||
|
||||
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
|
||||
|
||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||
..(user, choice)
|
||||
if(src.can_use())
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
src.set_light(0)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
//Camera must be added to global list of all cameras no matter what...
|
||||
if(cameranet.cameras_unsorted || !ticker)
|
||||
cameranet.cameras += src
|
||||
cameranet.cameras_unsorted = 1
|
||||
else
|
||||
dd_insertObjectList(cameranet.cameras, src)
|
||||
update_coverage(1)
|
||||
|
||||
/obj/machinery/camera/Destroy()
|
||||
clear_all_networks()
|
||||
cameranet.cameras -= src
|
||||
return ..()
|
||||
|
||||
// Mobs
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
..()
|
||||
if(was_dead && stat != DEAD)
|
||||
// Arise!
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/silicon/ai/death(gibbed)
|
||||
if(..())
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
+149
-149
@@ -1,149 +1,149 @@
|
||||
#define UPDATE_BUFFER 25 // 2.5 seconds
|
||||
|
||||
// CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/obfuscation
|
||||
var/icon = 'icons/effects/cameravis.dmi'
|
||||
var/icon_state = "black"
|
||||
|
||||
/datum/chunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = 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
|
||||
var/datum/obfuscation/obfuscation = new()
|
||||
|
||||
// Add an eye to the chunk, then update if changed.
|
||||
|
||||
/datum/chunk/proc/add(mob/observer/eye/eye, add_images = TRUE)
|
||||
if(add_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images += obscured
|
||||
eye.visibleChunks += src
|
||||
visible++
|
||||
seenby += eye
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
// Remove an eye from the chunk, then update if changed.
|
||||
|
||||
/datum/chunk/proc/remove(mob/observer/eye/eye, remove_images = TRUE)
|
||||
if(remove_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= obscured
|
||||
eye.visibleChunks -= src
|
||||
seenby -= eye
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
/datum/chunk/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/chunk/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.
|
||||
|
||||
/datum/chunk/proc/update()
|
||||
|
||||
set background = 1
|
||||
|
||||
var/list/newVisibleTurfs = new()
|
||||
acquireVisibleTurfs(newVisibleTurfs)
|
||||
|
||||
// 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/t as anything in visAdded)
|
||||
if(LAZYLEN(t.obfuscations) && t.obfuscations[obfuscation.type])
|
||||
obscured -= t.obfuscations[obfuscation.type]
|
||||
for(var/mob/observer/eye/m as anything in seenby)
|
||||
if(!m)
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= t.obfuscations[obfuscation.type]
|
||||
|
||||
for(var/turf/t as anything in visRemoved)
|
||||
if(obscuredTurfs[t])
|
||||
LAZYINITLIST(t.obfuscations)
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
ob_image.plane = PLANE_FULLSCREEN
|
||||
t.obfuscations[obfuscation.type] = ob_image
|
||||
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
for(var/mob/observer/eye/m as anything in seenby)
|
||||
if(!m)
|
||||
seenby -= m
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images += t.obfuscations[obfuscation.type]
|
||||
|
||||
/datum/chunk/proc/acquireVisibleTurfs(var/list/visible)
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/chunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs[t] = t
|
||||
|
||||
acquireVisibleTurfs(visibleTurfs)
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
visibleTurfs &= turfs
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf/t as anything in obscuredTurfs)
|
||||
LAZYINITLIST(t.obfuscations)
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
ob_image.plane = PLANE_FULLSCREEN
|
||||
t.obfuscations[obfuscation.type] = ob_image
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
#define UPDATE_BUFFER 25 // 2.5 seconds
|
||||
|
||||
// CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/obfuscation
|
||||
var/icon = 'icons/effects/cameravis.dmi'
|
||||
var/icon_state = "black"
|
||||
|
||||
/datum/chunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = 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
|
||||
var/datum/obfuscation/obfuscation = new()
|
||||
|
||||
// Add an eye to the chunk, then update if changed.
|
||||
|
||||
/datum/chunk/proc/add(mob/observer/eye/eye, add_images = TRUE)
|
||||
if(add_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images += obscured
|
||||
eye.visibleChunks += src
|
||||
visible++
|
||||
seenby += eye
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
// Remove an eye from the chunk, then update if changed.
|
||||
|
||||
/datum/chunk/proc/remove(mob/observer/eye/eye, remove_images = TRUE)
|
||||
if(remove_images)
|
||||
var/client/client = eye.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= obscured
|
||||
eye.visibleChunks -= src
|
||||
seenby -= eye
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
/datum/chunk/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/chunk/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.
|
||||
|
||||
/datum/chunk/proc/update()
|
||||
|
||||
set background = 1
|
||||
|
||||
var/list/newVisibleTurfs = new()
|
||||
acquireVisibleTurfs(newVisibleTurfs)
|
||||
|
||||
// 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/t as anything in visAdded)
|
||||
if(LAZYLEN(t.obfuscations) && t.obfuscations[obfuscation.type])
|
||||
obscured -= t.obfuscations[obfuscation.type]
|
||||
for(var/mob/observer/eye/m as anything in seenby)
|
||||
if(!m)
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images -= t.obfuscations[obfuscation.type]
|
||||
|
||||
for(var/turf/t as anything in visRemoved)
|
||||
if(obscuredTurfs[t])
|
||||
LAZYINITLIST(t.obfuscations)
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
ob_image.plane = PLANE_FULLSCREEN
|
||||
t.obfuscations[obfuscation.type] = ob_image
|
||||
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
for(var/mob/observer/eye/m as anything in seenby)
|
||||
if(!m)
|
||||
seenby -= m
|
||||
continue
|
||||
var/client/client = m.GetViewerClient()
|
||||
if(client)
|
||||
client.images += t.obfuscations[obfuscation.type]
|
||||
|
||||
/datum/chunk/proc/acquireVisibleTurfs(var/list/visible)
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/chunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs[t] = t
|
||||
|
||||
acquireVisibleTurfs(visibleTurfs)
|
||||
|
||||
// Removes turf that isn't in turfs.
|
||||
visibleTurfs &= turfs
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf/t as anything in obscuredTurfs)
|
||||
LAZYINITLIST(t.obfuscations)
|
||||
if(!t.obfuscations[obfuscation.type])
|
||||
var/image/ob_image = image(obfuscation.icon, t, obfuscation.icon_state, OBFUSCATION_LAYER)
|
||||
ob_image.plane = PLANE_FULLSCREEN
|
||||
t.obfuscations[obfuscation.type] = ob_image
|
||||
obscured += t.obfuscations[obfuscation.type]
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
|
||||
+111
-111
@@ -1,111 +1,111 @@
|
||||
// EYE
|
||||
//
|
||||
// A mob that another mob controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the controller can and cannot see.
|
||||
|
||||
/mob/observer/eye
|
||||
name = "Eye"
|
||||
icon = 'icons/mob/eye.dmi'
|
||||
icon_state = "default-eye"
|
||||
alpha = 127
|
||||
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
var/owner_follows_eye = 0
|
||||
|
||||
see_in_dark = 7
|
||||
status_flags = GODMODE
|
||||
plane = PLANE_AI_EYE
|
||||
|
||||
var/mob/owner = null
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
var/ghostimage = null
|
||||
var/datum/visualnet/visualnet
|
||||
var/use_static = TRUE
|
||||
var/static_visibility_range = 16
|
||||
|
||||
/mob/observer/eye/Destroy()
|
||||
if(owner)
|
||||
if(owner.eyeobj == src)
|
||||
owner.eyeobj = null
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/mob/observer/eye/Move(n, direct)
|
||||
if(owner == src)
|
||||
return EyeMove(n, direct)
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
/mob/observer/eye/examinate()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/pointed()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
// Use this when setting the eye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
/mob/observer/eye/proc/setLoc(var/T)
|
||||
if(owner)
|
||||
T = get_turf(T)
|
||||
if(T != loc)
|
||||
loc = T
|
||||
|
||||
if(owner.client)
|
||||
owner.client.eye = src
|
||||
|
||||
if(owner_follows_eye)
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
owner.loc = loc
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
if(use_static)
|
||||
visualnet.visibility(src, owner.client)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/proc/getLoc()
|
||||
if(owner)
|
||||
if(!isturf(owner.loc) || !owner.client)
|
||||
return
|
||||
return loc
|
||||
/mob
|
||||
var/mob/observer/eye/eyeobj
|
||||
|
||||
/mob/proc/EyeMove(n, direct)
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
return eyeobj.EyeMove(n, direct)
|
||||
|
||||
/mob/observer/eye/proc/GetViewerClient()
|
||||
if(owner)
|
||||
return owner.client
|
||||
return null
|
||||
|
||||
/mob/observer/eye/EyeMove(n, direct)
|
||||
var/initial = initial(sprint)
|
||||
var/max_sprint = 50
|
||||
|
||||
if(cooldown && cooldown < world.timeofday)
|
||||
sprint = initial
|
||||
|
||||
for(var/i = 0; i < max(sprint, initial); i += 20)
|
||||
var/turf/step = get_turf(get_step(src, direct))
|
||||
if(step)
|
||||
setLoc(step)
|
||||
|
||||
cooldown = world.timeofday + 5
|
||||
if(acceleration)
|
||||
sprint = min(sprint + 0.5, max_sprint)
|
||||
else
|
||||
sprint = initial
|
||||
return 1
|
||||
// EYE
|
||||
//
|
||||
// A mob that another mob controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the controller can and cannot see.
|
||||
|
||||
/mob/observer/eye
|
||||
name = "Eye"
|
||||
icon = 'icons/mob/eye.dmi'
|
||||
icon_state = "default-eye"
|
||||
alpha = 127
|
||||
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
var/owner_follows_eye = 0
|
||||
|
||||
see_in_dark = 7
|
||||
status_flags = GODMODE
|
||||
plane = PLANE_AI_EYE
|
||||
|
||||
var/mob/owner = null
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
var/ghostimage = null
|
||||
var/datum/visualnet/visualnet
|
||||
var/use_static = TRUE
|
||||
var/static_visibility_range = 16
|
||||
|
||||
/mob/observer/eye/Destroy()
|
||||
if(owner)
|
||||
if(owner.eyeobj == src)
|
||||
owner.eyeobj = null
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/mob/observer/eye/Move(n, direct)
|
||||
if(owner == src)
|
||||
return EyeMove(n, direct)
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/airflow_hit(atom/A)
|
||||
airflow_speed = 0
|
||||
airflow_dest = null
|
||||
|
||||
/mob/observer/eye/examinate()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/pointed()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
// Use this when setting the eye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
/mob/observer/eye/proc/setLoc(var/T)
|
||||
if(owner)
|
||||
T = get_turf(T)
|
||||
if(T != loc)
|
||||
loc = T
|
||||
|
||||
if(owner.client)
|
||||
owner.client.eye = src
|
||||
|
||||
if(owner_follows_eye)
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
owner.loc = loc
|
||||
visualnet.updateVisibility(owner, 0)
|
||||
if(use_static)
|
||||
visualnet.visibility(src, owner.client)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/observer/eye/proc/getLoc()
|
||||
if(owner)
|
||||
if(!isturf(owner.loc) || !owner.client)
|
||||
return
|
||||
return loc
|
||||
/mob
|
||||
var/mob/observer/eye/eyeobj
|
||||
|
||||
/mob/proc/EyeMove(n, direct)
|
||||
if(!eyeobj)
|
||||
return
|
||||
|
||||
return eyeobj.EyeMove(n, direct)
|
||||
|
||||
/mob/observer/eye/proc/GetViewerClient()
|
||||
if(owner)
|
||||
return owner.client
|
||||
return null
|
||||
|
||||
/mob/observer/eye/EyeMove(n, direct)
|
||||
var/initial = initial(sprint)
|
||||
var/max_sprint = 50
|
||||
|
||||
if(cooldown && cooldown < world.timeofday)
|
||||
sprint = initial
|
||||
|
||||
for(var/i = 0; i < max(sprint, initial); i += 20)
|
||||
var/turf/step = get_turf(get_step(src, direct))
|
||||
if(step)
|
||||
setLoc(step)
|
||||
|
||||
cooldown = world.timeofday + 5
|
||||
if(acceleration)
|
||||
sprint = min(sprint + 0.5, max_sprint)
|
||||
else
|
||||
sprint = initial
|
||||
return 1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/observer/eye/Life()
|
||||
..()
|
||||
// If we lost our client, reset the list of visible chunks so they update properly on return
|
||||
if(owner == src && !client)
|
||||
visibleChunks.Cut()
|
||||
/*else if(owner && !owner.client)
|
||||
visibleChunks.Cut()*/
|
||||
/mob/observer/eye/Life()
|
||||
..()
|
||||
// If we lost our client, reset the list of visible chunks so they update properly on return
|
||||
if(owner == src && !client)
|
||||
visibleChunks.Cut()
|
||||
/*else if(owner && !owner.client)
|
||||
visibleChunks.Cut()*/
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
// CULT CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/obfuscation/cult
|
||||
icon_state = "white"
|
||||
|
||||
/datum/chunk/cult
|
||||
obfuscation = new /datum/obfuscation/cult()
|
||||
|
||||
/datum/chunk/cult/acquireVisibleTurfs(var/list/visible)
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
for(var/turf/t in L.seen_cult_turfs())
|
||||
visible[t] = t
|
||||
|
||||
/mob/living/proc/seen_cult_turfs()
|
||||
return seen_turfs_in_range(src, 3)
|
||||
|
||||
/mob/living/carbon/human/seen_cult_turfs()
|
||||
if(mind in cult.current_antagonists)
|
||||
return seen_turfs_in_range(src, world.view)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/seen_cult_turfs()
|
||||
return list()
|
||||
|
||||
/mob/living/simple_mob/seen_cult_turfs()
|
||||
return seen_turfs_in_range(src, 1)
|
||||
|
||||
/mob/living/simple_mob/construct/shade/seen_cult_turfs()
|
||||
return view(2, src)
|
||||
|
||||
/proc/seen_turfs_in_range(var/source, var/range)
|
||||
var/turf/pos = get_turf(source)
|
||||
return hear(range, pos)
|
||||
// CULT CHUNK
|
||||
//
|
||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
||||
// Allows the Eye to stream these chunks and know what it can and cannot see.
|
||||
|
||||
/datum/obfuscation/cult
|
||||
icon_state = "white"
|
||||
|
||||
/datum/chunk/cult
|
||||
obfuscation = new /datum/obfuscation/cult()
|
||||
|
||||
/datum/chunk/cult/acquireVisibleTurfs(var/list/visible)
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
for(var/turf/t in L.seen_cult_turfs())
|
||||
visible[t] = t
|
||||
|
||||
/mob/living/proc/seen_cult_turfs()
|
||||
return seen_turfs_in_range(src, 3)
|
||||
|
||||
/mob/living/carbon/human/seen_cult_turfs()
|
||||
if(mind in cult.current_antagonists)
|
||||
return seen_turfs_in_range(src, world.view)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/seen_cult_turfs()
|
||||
return list()
|
||||
|
||||
/mob/living/simple_mob/seen_cult_turfs()
|
||||
return seen_turfs_in_range(src, 1)
|
||||
|
||||
/mob/living/simple_mob/construct/shade/seen_cult_turfs()
|
||||
return view(2, src)
|
||||
|
||||
/proc/seen_turfs_in_range(var/source, var/range)
|
||||
var/turf/pos = get_turf(source)
|
||||
return hear(range, pos)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// CULT NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visualnet/cult
|
||||
chunk_type = /datum/chunk/cult
|
||||
|
||||
/datum/visualnet/cult/proc/provides_vision(var/mob/living/L)
|
||||
return L.provides_cult_vision()
|
||||
|
||||
/mob/living/proc/provides_cult_vision()
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/provides_cult_vision()
|
||||
return 0
|
||||
// CULT NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
/datum/visualnet/cult
|
||||
chunk_type = /datum/chunk/cult
|
||||
|
||||
/datum/visualnet/cult/proc/provides_vision(var/mob/living/L)
|
||||
return L.provides_cult_vision()
|
||||
|
||||
/mob/living/proc/provides_cult_vision()
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/provides_cult_vision()
|
||||
return 0
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// MASK EYE
|
||||
//
|
||||
// A mob that a cultists controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the cultist can and cannot see.
|
||||
|
||||
/mob/observer/eye/maskEye
|
||||
name = "Eye of Nar-Sie"
|
||||
acceleration = 0
|
||||
owner_follows_eye = 1
|
||||
|
||||
/mob/observer/eye/maskEye/New()
|
||||
..()
|
||||
visualnet = cultnet
|
||||
// MASK EYE
|
||||
//
|
||||
// A mob that a cultists controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the cultist can and cannot see.
|
||||
|
||||
/mob/observer/eye/maskEye
|
||||
name = "Eye of Nar-Sie"
|
||||
acceleration = 0
|
||||
owner_follows_eye = 1
|
||||
|
||||
/mob/observer/eye/maskEye/New()
|
||||
..()
|
||||
visualnet = cultnet
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
#define CULT_UPDATE_BUFFER 30
|
||||
|
||||
/mob/living/var/updating_cult_vision = 0
|
||||
|
||||
/mob/living/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!cultnet.provides_vision(src))
|
||||
return
|
||||
if(!updating_cult_vision)
|
||||
updating_cult_vision = 1
|
||||
spawn(CULT_UPDATE_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cultnet.updateVisibility(old_loc, 0)
|
||||
cultnet.updateVisibility(loc, 0)
|
||||
updating_cult_vision = 0
|
||||
|
||||
#undef CULT_UPDATE_BUFFER
|
||||
|
||||
/mob/living/New()
|
||||
..()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/Destroy()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
return ..()
|
||||
|
||||
/mob/living/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
..()
|
||||
if(was_dead && stat != DEAD)
|
||||
// Arise!
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/death(gibbed, deathmessage="seizes up and falls limp...")
|
||||
if(..(gibbed, deathmessage))
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cultnet.updateVisibility(src)
|
||||
|
||||
/datum/antagonist/add_antagonist(var/datum/mind/player)
|
||||
. = ..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
|
||||
/datum/antagonist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
|
||||
..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
#define CULT_UPDATE_BUFFER 30
|
||||
|
||||
/mob/living/var/updating_cult_vision = 0
|
||||
|
||||
/mob/living/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(!cultnet.provides_vision(src))
|
||||
return
|
||||
if(!updating_cult_vision)
|
||||
updating_cult_vision = 1
|
||||
spawn(CULT_UPDATE_BUFFER)
|
||||
if(old_loc != src.loc)
|
||||
cultnet.updateVisibility(old_loc, 0)
|
||||
cultnet.updateVisibility(loc, 0)
|
||||
updating_cult_vision = 0
|
||||
|
||||
#undef CULT_UPDATE_BUFFER
|
||||
|
||||
/mob/living/New()
|
||||
..()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/Destroy()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
return ..()
|
||||
|
||||
/mob/living/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
..()
|
||||
if(was_dead && stat != DEAD)
|
||||
// Arise!
|
||||
cultnet.updateVisibility(src, 0)
|
||||
|
||||
/mob/living/death(gibbed, deathmessage="seizes up and falls limp...")
|
||||
if(..(gibbed, deathmessage))
|
||||
// If true, the mob went from living to dead (assuming everyone has been overriding as they should...)
|
||||
cultnet.updateVisibility(src)
|
||||
|
||||
/datum/antagonist/add_antagonist(var/datum/mind/player)
|
||||
. = ..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
|
||||
/datum/antagonist/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
|
||||
..()
|
||||
if(src == cult)
|
||||
cultnet.updateVisibility(player.current, 0)
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
// CREDITS
|
||||
/*
|
||||
Initial code credit for this goes to Uristqwerty.
|
||||
Debugging, functionality, all comments and porting by Giacom.
|
||||
|
||||
Everything about freelook (or what we can put in here) will be stored here.
|
||||
|
||||
|
||||
WHAT IS THIS?
|
||||
|
||||
This is a replacement for the current camera movement system, of the AI. Before this, the AI had to move between cameras and could
|
||||
only see what the cameras could see. Not only this but the cameras could see through walls, which created problems.
|
||||
With this, the AI controls an "AI Eye" mob, which moves just like a ghost; such as moving through walls and being invisible to players.
|
||||
The AI's eye is set to this mob and then we use a system (explained below) to determine what the cameras around the AI Eye can and
|
||||
cannot see. If the camera cannot see a turf, it will black it out, otherwise it won't and the AI will be able to see it.
|
||||
This creates several features, such as.. no more see-through-wall cameras, easier to control camera movement, easier tracking,
|
||||
the AI only being able to track mobs which are visible to a camera, only trackable mobs appearing on the mob list and many more.
|
||||
|
||||
|
||||
HOW IT WORKS
|
||||
|
||||
It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be
|
||||
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Destroy().
|
||||
|
||||
Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk.
|
||||
These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside
|
||||
the 16x16 block, it is listed as an "obscured" turf. Meaning the AI won't be able to see it.
|
||||
|
||||
|
||||
HOW IT UPDATES
|
||||
|
||||
The camera network uses a streaming method in order to effeciently update chunks. Since the server will have doors opening, doors closing,
|
||||
turf being destroyed and other lag inducing stuff, we want to update it under certain conditions and not every tick.
|
||||
|
||||
The chunks are not created straight away, only when an AI eye moves into it's area is when it gets created.
|
||||
One a chunk is created, when a non glass door opens/closes or an opacity turf is destroyed, we check to see if an AI Eye is looking in the area.
|
||||
We do this with the "seenby" list, which updates everytime an AI is near a chunk. If there is an AI eye inside the area, we update the chunk
|
||||
that the changed atom is inside and all surrounding chunks, since a camera's vision could leak onto another chunk. If there is no AI Eye, we instead
|
||||
flag the chunk to update whenever it is loaded by an AI Eye. This is basically how the chunks update and keep it in sync. We then add some lag reducing
|
||||
measures, such as an UPDATE_BUFFER which stops a chunk from updating too many times in a certain time-frame, only updating if the changed atom was blocking
|
||||
sight; for example, we don't update glass airlocks or floors.
|
||||
|
||||
|
||||
WHERE IS EVERYTHING?
|
||||
|
||||
cameranet.dm = Everything about the cameranet 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.
|
||||
|
||||
// CREDITS
|
||||
/*
|
||||
Initial code credit for this goes to Uristqwerty.
|
||||
Debugging, functionality, all comments and porting by Giacom.
|
||||
|
||||
Everything about freelook (or what we can put in here) will be stored here.
|
||||
|
||||
|
||||
WHAT IS THIS?
|
||||
|
||||
This is a replacement for the current camera movement system, of the AI. Before this, the AI had to move between cameras and could
|
||||
only see what the cameras could see. Not only this but the cameras could see through walls, which created problems.
|
||||
With this, the AI controls an "AI Eye" mob, which moves just like a ghost; such as moving through walls and being invisible to players.
|
||||
The AI's eye is set to this mob and then we use a system (explained below) to determine what the cameras around the AI Eye can and
|
||||
cannot see. If the camera cannot see a turf, it will black it out, otherwise it won't and the AI will be able to see it.
|
||||
This creates several features, such as.. no more see-through-wall cameras, easier to control camera movement, easier tracking,
|
||||
the AI only being able to track mobs which are visible to a camera, only trackable mobs appearing on the mob list and many more.
|
||||
|
||||
|
||||
HOW IT WORKS
|
||||
|
||||
It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be
|
||||
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Destroy().
|
||||
|
||||
Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk.
|
||||
These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside
|
||||
the 16x16 block, it is listed as an "obscured" turf. Meaning the AI won't be able to see it.
|
||||
|
||||
|
||||
HOW IT UPDATES
|
||||
|
||||
The camera network uses a streaming method in order to effeciently update chunks. Since the server will have doors opening, doors closing,
|
||||
turf being destroyed and other lag inducing stuff, we want to update it under certain conditions and not every tick.
|
||||
|
||||
The chunks are not created straight away, only when an AI eye moves into it's area is when it gets created.
|
||||
One a chunk is created, when a non glass door opens/closes or an opacity turf is destroyed, we check to see if an AI Eye is looking in the area.
|
||||
We do this with the "seenby" list, which updates everytime an AI is near a chunk. If there is an AI eye inside the area, we update the chunk
|
||||
that the changed atom is inside and all surrounding chunks, since a camera's vision could leak onto another chunk. If there is no AI Eye, we instead
|
||||
flag the chunk to update whenever it is loaded by an AI Eye. This is basically how the chunks update and keep it in sync. We then add some lag reducing
|
||||
measures, such as an UPDATE_BUFFER which stops a chunk from updating too many times in a certain time-frame, only updating if the changed atom was blocking
|
||||
sight; for example, we don't update glass airlocks or floors.
|
||||
|
||||
|
||||
WHERE IS EVERYTHING?
|
||||
|
||||
cameranet.dm = Everything about the cameranet 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.
|
||||
|
||||
*/
|
||||
@@ -1,59 +1,59 @@
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
// TURFS
|
||||
|
||||
/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
if(ticker)
|
||||
for(var/datum/visualnet/VN in visual_nets)
|
||||
VN.updateVisibility(A, opacity_check)
|
||||
|
||||
/turf
|
||||
var/list/image/obfuscations
|
||||
|
||||
/turf/drain_power()
|
||||
return -1
|
||||
|
||||
/turf/simulated/Destroy()
|
||||
updateVisibility(src)
|
||||
if(zone)
|
||||
if(can_safely_remove_from_zone())
|
||||
c_copy_air()
|
||||
zone.remove(src)
|
||||
else
|
||||
zone.rebuild()
|
||||
return ..()
|
||||
|
||||
/turf/simulated/Initialize()
|
||||
. = ..()
|
||||
updateVisibility(src)
|
||||
|
||||
|
||||
// STRUCTURES
|
||||
|
||||
/obj/structure/Destroy()
|
||||
updateVisibility(src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
updateVisibility(src)
|
||||
|
||||
// EFFECTS
|
||||
|
||||
/obj/effect/Destroy()
|
||||
updateVisibility(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/Initialize()
|
||||
. = ..()
|
||||
updateVisibility(src)
|
||||
|
||||
// DOORS
|
||||
|
||||
// Simply updates the visibility of the area when it opens/closes/destroyed.
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass)
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
// TURFS
|
||||
|
||||
/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
if(ticker)
|
||||
for(var/datum/visualnet/VN in visual_nets)
|
||||
VN.updateVisibility(A, opacity_check)
|
||||
|
||||
/turf
|
||||
var/list/image/obfuscations
|
||||
|
||||
/turf/drain_power()
|
||||
return -1
|
||||
|
||||
/turf/simulated/Destroy()
|
||||
updateVisibility(src)
|
||||
if(zone)
|
||||
if(can_safely_remove_from_zone())
|
||||
c_copy_air()
|
||||
zone.remove(src)
|
||||
else
|
||||
zone.rebuild()
|
||||
return ..()
|
||||
|
||||
/turf/simulated/Initialize()
|
||||
. = ..()
|
||||
updateVisibility(src)
|
||||
|
||||
|
||||
// STRUCTURES
|
||||
|
||||
/obj/structure/Destroy()
|
||||
updateVisibility(src)
|
||||
return ..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
updateVisibility(src)
|
||||
|
||||
// EFFECTS
|
||||
|
||||
/obj/effect/Destroy()
|
||||
updateVisibility(src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/Initialize()
|
||||
. = ..()
|
||||
updateVisibility(src)
|
||||
|
||||
// DOORS
|
||||
|
||||
// Simply updates the visibility of the area when it opens/closes/destroyed.
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass)
|
||||
updateVisibility(src, 0)
|
||||
@@ -1,161 +1,161 @@
|
||||
// VISUAL NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
#define CHUNK_SIZE 16
|
||||
|
||||
/datum/visualnet
|
||||
// The chunks of the map, mapping the areas that an object can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
var/chunk_type = /datum/chunk
|
||||
|
||||
/datum/visualnet/New()
|
||||
..()
|
||||
visual_nets += src
|
||||
|
||||
/datum/visualnet/Destroy()
|
||||
visual_nets -= src
|
||||
return ..()
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/visualnet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
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/visualnet/proc/getChunk(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!chunks[key])
|
||||
chunks[key] = new chunk_type(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/visualnet/proc/visibility(list/moved_eyes, client/C, list/other_eyes)
|
||||
if(!islist(moved_eyes))
|
||||
moved_eyes = moved_eyes ? list(moved_eyes) : list()
|
||||
if(islist(other_eyes))
|
||||
other_eyes = (other_eyes - moved_eyes)
|
||||
else
|
||||
other_eyes = list()
|
||||
|
||||
var/list/chunks_pre_seen = list()
|
||||
var/list/chunks_post_seen = list()
|
||||
|
||||
for(var/mob/observer/eye/eye as anything in moved_eyes)
|
||||
if(C)
|
||||
chunks_pre_seen |= eye.visibleChunks
|
||||
// 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)
|
||||
var/x2 = min(world.maxx, eye.x + static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, eye.y + static_range) & ~(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 |= getChunk(x, y, eye.z)
|
||||
|
||||
var/list/remove = eye.visibleChunks - visibleChunks
|
||||
var/list/add = visibleChunks - eye.visibleChunks
|
||||
|
||||
for(var/datum/chunk/c as anything in remove)
|
||||
c.remove(eye, FALSE)
|
||||
|
||||
for(var/datum/chunk/c as anything in add)
|
||||
c.add(eye, FALSE)
|
||||
|
||||
if(C)
|
||||
chunks_post_seen |= eye.visibleChunks
|
||||
|
||||
if(C)
|
||||
for(var/mob/observer/eye/eye as anything in other_eyes)
|
||||
chunks_post_seen |= eye.visibleChunks
|
||||
|
||||
var/list/remove = chunks_pre_seen - chunks_post_seen
|
||||
var/list/add = chunks_post_seen - chunks_pre_seen
|
||||
|
||||
for(var/datum/chunk/c as anything in remove)
|
||||
C.images -= c.obscured
|
||||
|
||||
for(var/datum/chunk/c as anything in add)
|
||||
C.images += c.obscured
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
|
||||
/datum/visualnet/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
/datum/visualnet/proc/updateChunk(x, y, z)
|
||||
// 0xf = 15
|
||||
if(!chunkGenerated(x, y, z))
|
||||
return
|
||||
var/datum/chunk/chunk = getChunk(x, y, z)
|
||||
chunk.hasChanged()
|
||||
|
||||
// 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/visualnet/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 - 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
|
||||
|
||||
//to_world("X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]")
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/chunk/chunk = getChunk(x, y, T.z)
|
||||
onMajorChunkChange(c, choice, chunk)
|
||||
chunk.hasChanged()
|
||||
|
||||
/datum/visualnet/proc/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/chunk)
|
||||
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/datum/visualnet/proc/checkVis(mob/living/target as mob)
|
||||
// 0xf = 15
|
||||
var/turf/position = get_turf(target)
|
||||
return checkTurfVis(position)
|
||||
|
||||
/datum/visualnet/proc/checkTurfVis(var/turf/position)
|
||||
var/datum/chunk/chunk = getChunk(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/chunk/chunk = cameranet.getCameraChunk(x, y, z)
|
||||
usr.client.debug_variables(chunk)
|
||||
*/
|
||||
// VISUAL NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
#define CHUNK_SIZE 16
|
||||
|
||||
/datum/visualnet
|
||||
// The chunks of the map, mapping the areas that an object can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
var/chunk_type = /datum/chunk
|
||||
|
||||
/datum/visualnet/New()
|
||||
..()
|
||||
visual_nets += src
|
||||
|
||||
/datum/visualnet/Destroy()
|
||||
visual_nets -= src
|
||||
return ..()
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/visualnet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
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/visualnet/proc/getChunk(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!chunks[key])
|
||||
chunks[key] = new chunk_type(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/visualnet/proc/visibility(list/moved_eyes, client/C, list/other_eyes)
|
||||
if(!islist(moved_eyes))
|
||||
moved_eyes = moved_eyes ? list(moved_eyes) : list()
|
||||
if(islist(other_eyes))
|
||||
other_eyes = (other_eyes - moved_eyes)
|
||||
else
|
||||
other_eyes = list()
|
||||
|
||||
var/list/chunks_pre_seen = list()
|
||||
var/list/chunks_post_seen = list()
|
||||
|
||||
for(var/mob/observer/eye/eye as anything in moved_eyes)
|
||||
if(C)
|
||||
chunks_pre_seen |= eye.visibleChunks
|
||||
// 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)
|
||||
var/x2 = min(world.maxx, eye.x + static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, eye.y + static_range) & ~(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 |= getChunk(x, y, eye.z)
|
||||
|
||||
var/list/remove = eye.visibleChunks - visibleChunks
|
||||
var/list/add = visibleChunks - eye.visibleChunks
|
||||
|
||||
for(var/datum/chunk/c as anything in remove)
|
||||
c.remove(eye, FALSE)
|
||||
|
||||
for(var/datum/chunk/c as anything in add)
|
||||
c.add(eye, FALSE)
|
||||
|
||||
if(C)
|
||||
chunks_post_seen |= eye.visibleChunks
|
||||
|
||||
if(C)
|
||||
for(var/mob/observer/eye/eye as anything in other_eyes)
|
||||
chunks_post_seen |= eye.visibleChunks
|
||||
|
||||
var/list/remove = chunks_pre_seen - chunks_post_seen
|
||||
var/list/add = chunks_post_seen - chunks_pre_seen
|
||||
|
||||
for(var/datum/chunk/c as anything in remove)
|
||||
C.images -= c.obscured
|
||||
|
||||
for(var/datum/chunk/c as anything in add)
|
||||
C.images += c.obscured
|
||||
|
||||
// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
|
||||
|
||||
/datum/visualnet/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
/datum/visualnet/proc/updateChunk(x, y, z)
|
||||
// 0xf = 15
|
||||
if(!chunkGenerated(x, y, z))
|
||||
return
|
||||
var/datum/chunk/chunk = getChunk(x, y, z)
|
||||
chunk.hasChanged()
|
||||
|
||||
// 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/visualnet/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 - 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
|
||||
|
||||
//to_world("X1: [x1] - Y1: [y1] - X2: [x2] - Y2: [y2]")
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/chunk/chunk = getChunk(x, y, T.z)
|
||||
onMajorChunkChange(c, choice, chunk)
|
||||
chunk.hasChanged()
|
||||
|
||||
/datum/visualnet/proc/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/chunk)
|
||||
|
||||
// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
|
||||
|
||||
/datum/visualnet/proc/checkVis(mob/living/target as mob)
|
||||
// 0xf = 15
|
||||
var/turf/position = get_turf(target)
|
||||
return checkTurfVis(position)
|
||||
|
||||
/datum/visualnet/proc/checkTurfVis(var/turf/position)
|
||||
var/datum/chunk/chunk = getChunk(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/chunk/chunk = cameranet.getCameraChunk(x, y, z)
|
||||
usr.client.debug_variables(chunk)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user