diff --git a/baystation12.dme b/baystation12.dme index fbe5aba289..3ace652aeb 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1052,6 +1052,7 @@ #include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\observer.dm" #include "code\modules\mob\dead\observer\say.dm" +#include "code\modules\mob\freelook\eye.dm" #include "code\modules\mob\language\generic.dm" #include "code\modules\mob\language\language.dm" #include "code\modules\mob\language\outsider.dm" diff --git a/code/modules/mob/freelook/eye.dm b/code/modules/mob/freelook/eye.dm new file mode 100644 index 0000000000..153609cfa5 --- /dev/null +++ b/code/modules/mob/freelook/eye.dm @@ -0,0 +1,67 @@ +// 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/eye + name = "Eye" + icon = 'icons/mob/eye.dmi' + icon_state = "default-eye" + alpha = 127 + var/list/visibleChunks = list() + var/mob/living/owner = null + density = 0 + status_flags = GODMODE // You can't damage it. + see_in_dark = 7 + invisibility = INVISIBILITY_EYE + var/ghostimage = null + var/datum/cameranet/visualnet + +/mob/eye/New() + ghostimage = image(src.icon,src,src.icon_state) + ghost_darkness_images |= ghostimage //so ghosts can see the eye when they disable darkness + ghost_sightless_images |= ghostimage //so ghosts can see the eye when they disable ghost sight + updateallghostimages() + ..() + +mob/eye/Del() + if (ghostimage) + ghost_darkness_images -= ghostimage + ghost_sightless_images -= ghostimage + del(ghostimage) + ghostimage = null; + updateallghostimages() + ..() + +// Movement code. Returns 0 to stop air movement from moving it. +/mob/eye/Move() + return 0 + +/mob/eye/examinate() + set popup_menu = 0 + set src = usr.contents + return 0 + +/mob/eye/pointed() + set popup_menu = 0 + set src = usr.contents + return 0 + +/mob/eye/examine(mob/user) + +// Use this when setting the eye's location. +// It will also stream the chunk that the new loc is in. +/mob/eye/proc/setLoc(var/T) + if(owner) + T = get_turf(T) + loc = T + + visualnet.visibility(src) + return 1 + return 0 + +/mob/eye/proc/getLoc() + if(owner) + if(!isturf(owner.loc) || !owner.client) + return + return loc diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index f05fdda45f..45523a10b6 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -37,29 +37,29 @@ var/datum/cameranet/cameranet = new() // 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/aiEye/ai) +/datum/cameranet/proc/visibility(mob/eye/eye) // 0xf = 15 - var/x1 = max(0, ai.x - 16) & ~0xf - var/y1 = max(0, ai.y - 16) & ~0xf - var/x2 = min(world.maxx, ai.x + 16) & ~0xf - var/y2 = min(world.maxy, ai.y + 16) & ~0xf + var/x1 = max(0, eye.x - 16) & ~0xf + var/y1 = max(0, eye.y - 16) & ~0xf + var/x2 = min(world.maxx, eye.x + 16) & ~0xf + var/y2 = min(world.maxy, eye.y + 16) & ~0xf var/list/visibleChunks = list() for(var/x = x1; x <= x2; x += 16) for(var/y = y1; y <= y2; y += 16) - visibleChunks += getCameraChunk(x, y, ai.z) + visibleChunks += getCameraChunk(x, y, eye.z) - var/list/remove = ai.visibleCameraChunks - visibleChunks - var/list/add = visibleChunks - ai.visibleCameraChunks + var/list/remove = eye.visibleChunks - visibleChunks + var/list/add = visibleChunks - eye.visibleChunks for(var/chunk in remove) var/datum/camerachunk/c = chunk - c.remove(ai) + c.remove(eye) for(var/chunk in add) var/datum/camerachunk/c = chunk - c.add(ai) + c.add(eye) // Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 90147f5b26..0b07e4cd61 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -3,7 +3,7 @@ // 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. +// Allows the Eye to stream these chunks and know what it can and cannot see. /datum/camerachunk var/list/obscuredTurfs = list() @@ -19,28 +19,28 @@ var/y = 0 var/z = 0 -// Add an AI eye to the chunk, then update if changed. +// Add an eye to the chunk, then update if changed. -/datum/camerachunk/proc/add(mob/aiEye/ai) - if(!ai.ai) +/datum/camerachunk/proc/add(mob/eye/eye) + if(!eye.owner) return - ai.visibleCameraChunks += src - if(ai.ai.client) - ai.ai.client.images += obscured + eye.visibleChunks += src + if(eye.owner.client) + eye.owner.client.images += obscured visible++ - seenby += ai + seenby += eye if(changed && !updating) update() -// Remove an AI eye from the chunk, then update if changed. +// Remove an eye from the chunk, then update if changed. -/datum/camerachunk/proc/remove(mob/aiEye/ai) - if(!ai.ai) +/datum/camerachunk/proc/remove(mob/eye/eye) + if(!eye.owner) return - ai.visibleCameraChunks -= src - if(ai.ai.client) - ai.ai.client.images -= obscured - seenby -= ai + eye.visibleChunks -= src + if(eye.owner.client) + eye.owner.client.images -= obscured + seenby -= eye if(visible > 0) visible-- @@ -103,11 +103,11 @@ if(t.obscured) obscured -= t.obscured for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) + var/mob/eye/m = eye + if(!m || !m.owner) continue - if(m.ai.client) - m.ai.client.images -= t.obscured + if(m.owner.client) + m.owner.client.images -= t.obscured for(var/turf in visRemoved) var/turf/t = turf @@ -117,12 +117,12 @@ obscured += t.obscured for(var/eye in seenby) - var/mob/aiEye/m = eye - if(!m || !m.ai) + var/mob/eye/m = eye + if(!m || !m.owner) seenby -= m continue - if(m.ai.client) - m.ai.client.images += t.obscured + if(m.owner.client) + m.owner.client.images += t.obscured // Create a new camera chunk, since the chunks are made as they are needed. diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 7bfaf6eac6..e22ab39190 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -3,84 +3,29 @@ // 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/aiEye +/mob/eye/aiEye name = "Inactive AI Eye" - icon = 'icons/mob/AI.dmi' - icon_state = "eye" - alpha = 127 - var/list/visibleCameraChunks = list() + icon_state = "AI-eye" var/mob/living/silicon/ai/ai = null - density = 0 - status_flags = GODMODE // You can't damage it. - see_in_dark = 7 - invisibility = INVISIBILITY_AI_EYE - var/ghostimage = null - -/mob/aiEye/New() - ghostimage = image(src.icon,src,src.icon_state) - ghost_darkness_images |= ghostimage //so ghosts can see the AI eye when they disable darkness - ghost_sightless_images |= ghostimage //so ghosts can see the AI eye when they disable ghost sight - updateallghostimages() - ..() - -mob/aiEye/Del() - if (ghostimage) - ghost_darkness_images -= ghostimage - ghost_sightless_images -= ghostimage - del(ghostimage) - ghostimage = null; - updateallghostimages() - ..() - -// Movement code. Returns 0 to stop air movement from moving it. -/mob/aiEye/Move() - return 0 - -/mob/aiEye/examinate() - set popup_menu = 0 - set src = usr.contents - return 0 - -/mob/aiEye/pointed() - set popup_menu = 0 - set src = usr.contents - return 0 - -/mob/aiEye/examine(mob/user) - -// Use this when setting the aiEye's location. -// It will also stream the chunk that the new loc is in. -/mob/aiEye/proc/setLoc(var/T, var/cancel_tracking = 1) - - if(ai) - if(!isturf(ai.loc)) - return +/mob/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1) + if(..()) if(cancel_tracking) ai.ai_cancel_tracking() - T = get_turf(T) - loc = T - cameranet.visibility(src) if(ai.client) ai.client.eye = src //Holopad if(ai.holo) ai.holo.move_hologram(ai) - -/mob/aiEye/proc/getLoc() - - if(ai) - if(!isturf(ai.loc) || !ai.client) - return - return ai.eyeobj.loc + return 1 // AI MOVEMENT // The AI's "eye". Described on the top of the page. /mob/living/silicon/ai - var/mob/aiEye/eyeobj = new() + var/mob/eye/aiEye/eyeobj = new() var/sprint = 10 var/cooldown = 0 var/acceleration = 1 @@ -90,7 +35,9 @@ mob/aiEye/Del() /mob/living/silicon/ai/New() ..() eyeobj.ai = src + eyeobj.owner = src eyeobj.name = "[src.name] (AI Eye)" // Give it a name + eyeobj.visualnet = cameranet spawn(5) eyeobj.loc = src.loc @@ -152,7 +99,7 @@ mob/aiEye/Del() if(client && client.eye) client.eye = src - for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) + for(var/datum/camerachunk/c in eyeobj.visibleChunks) c.remove(eyeobj) src.eyeobj.setLoc(src) diff --git a/code/setup.dm b/code/setup.dm index cee4313d93..efad87a5dd 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -457,7 +457,7 @@ #define INVISIBILITY_LEVEL_ONE 35 #define INVISIBILITY_LEVEL_TWO 45 #define INVISIBILITY_OBSERVER 60 -#define INVISIBILITY_AI_EYE 61 +#define INVISIBILITY_EYE 61 #define SEE_INVISIBLE_LIVING 25 #define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15 diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi index 0653f3b482..4525fea606 100644 Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ diff --git a/icons/mob/eye.dmi b/icons/mob/eye.dmi new file mode 100644 index 0000000000..3bcd997165 Binary files /dev/null and b/icons/mob/eye.dmi differ