mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge pull request #8587 from PsiOmegaDelta/EyeRefactoring
Refactoring of the AI eye code.
This commit is contained in:
@@ -1052,6 +1052,10 @@
|
|||||||
#include "code\modules\mob\dead\observer\logout.dm"
|
#include "code\modules\mob\dead\observer\logout.dm"
|
||||||
#include "code\modules\mob\dead\observer\observer.dm"
|
#include "code\modules\mob\dead\observer\observer.dm"
|
||||||
#include "code\modules\mob\dead\observer\say.dm"
|
#include "code\modules\mob\dead\observer\say.dm"
|
||||||
|
#include "code\modules\mob\freelook\chunk.dm"
|
||||||
|
#include "code\modules\mob\freelook\eye.dm"
|
||||||
|
#include "code\modules\mob\freelook\update_triggers.dm"
|
||||||
|
#include "code\modules\mob\freelook\visualnet.dm"
|
||||||
#include "code\modules\mob\language\generic.dm"
|
#include "code\modules\mob\language\generic.dm"
|
||||||
#include "code\modules\mob\language\language.dm"
|
#include "code\modules\mob\language\language.dm"
|
||||||
#include "code\modules\mob\language\monkey.dm"
|
#include "code\modules\mob\language\monkey.dm"
|
||||||
|
|||||||
@@ -213,7 +213,7 @@
|
|||||||
mob/living/proc/near_camera()
|
mob/living/proc/near_camera()
|
||||||
if (!isturf(loc))
|
if (!isturf(loc))
|
||||||
return 0
|
return 0
|
||||||
else if(!cameranet.checkCameraVis(src))
|
else if(!cameranet.checkVis(src))
|
||||||
return 0
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ Class Procs:
|
|||||||
user.set_machine(src)
|
user.set_machine(src)
|
||||||
|
|
||||||
/obj/machinery/CouldNotUseTopic(var/mob/user)
|
/obj/machinery/CouldNotUseTopic(var/mob/user)
|
||||||
usr.unset_machine()
|
user.unset_machine()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -100,4 +100,35 @@
|
|||||||
body_parts_covered = HEAD|FACE|EYES
|
body_parts_covered = HEAD|FACE|EYES
|
||||||
w_class = 2
|
w_class = 2
|
||||||
var/voicechange = 0
|
var/voicechange = 0
|
||||||
siemens_coefficient = 0.9
|
siemens_coefficient = 0.9
|
||||||
|
|
||||||
|
/obj/item/clothing/mask/ai
|
||||||
|
name = "camera MIU"
|
||||||
|
desc = "Allows for direct mental connection to accessible camera networks."
|
||||||
|
icon_state = "s-ninja"
|
||||||
|
item_state = "s-ninja"
|
||||||
|
flags_inv = HIDEFACE
|
||||||
|
body_parts_covered = 0
|
||||||
|
var/mob/eye/aiEye/eye
|
||||||
|
|
||||||
|
/obj/item/clothing/mask/ai/New()
|
||||||
|
eye = new(src)
|
||||||
|
|
||||||
|
/obj/item/clothing/mask/ai/equipped(var/mob/user, var/slot)
|
||||||
|
..(user, slot)
|
||||||
|
if(slot == slot_wear_mask)
|
||||||
|
eye.owner = user
|
||||||
|
user.eyeobj = eye
|
||||||
|
|
||||||
|
for(var/datum/chunk/c in eye.visibleChunks)
|
||||||
|
c.remove(eye)
|
||||||
|
eye.setLoc(user)
|
||||||
|
|
||||||
|
/obj/item/clothing/mask/ai/dropped(var/mob/user)
|
||||||
|
..()
|
||||||
|
if(eye.owner == user)
|
||||||
|
for(var/datum/chunk/c in eye.visibleChunks)
|
||||||
|
c.remove(eye)
|
||||||
|
|
||||||
|
eye.owner.eyeobj = null
|
||||||
|
eye.owner = null
|
||||||
|
|||||||
146
code/modules/mob/freelook/chunk.dm
Normal file
146
code/modules/mob/freelook/chunk.dm
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#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/eye/eye)
|
||||||
|
if(!eye.owner)
|
||||||
|
return
|
||||||
|
eye.visibleChunks += src
|
||||||
|
if(eye.owner.client)
|
||||||
|
eye.owner.client.images += obscured
|
||||||
|
visible++
|
||||||
|
seenby += eye
|
||||||
|
if(changed && !updating)
|
||||||
|
update()
|
||||||
|
|
||||||
|
// Remove an eye from the chunk, then update if changed.
|
||||||
|
|
||||||
|
/datum/chunk/proc/remove(mob/eye/eye)
|
||||||
|
if(!eye.owner)
|
||||||
|
return
|
||||||
|
eye.visibleChunks -= src
|
||||||
|
if(eye.owner.client)
|
||||||
|
eye.owner.client.images -= obscured
|
||||||
|
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 in visAdded)
|
||||||
|
var/turf/t = turf
|
||||||
|
if(t.obfuscations[obfuscation.type])
|
||||||
|
obscured -= t.obfuscations[obfuscation.type]
|
||||||
|
for(var/eye in seenby)
|
||||||
|
var/mob/eye/m = eye
|
||||||
|
if(!m || !m.owner)
|
||||||
|
continue
|
||||||
|
if(m.owner.client)
|
||||||
|
m.owner.client.images -= t.obfuscations[obfuscation.type]
|
||||||
|
|
||||||
|
for(var/turf in visRemoved)
|
||||||
|
var/turf/t = turf
|
||||||
|
if(obscuredTurfs[t])
|
||||||
|
if(!t.obfuscations[obfuscation.type])
|
||||||
|
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
|
||||||
|
|
||||||
|
obscured += t.obfuscations[obfuscation.type]
|
||||||
|
for(var/eye in seenby)
|
||||||
|
var/mob/eye/m = eye
|
||||||
|
if(!m || !m.owner)
|
||||||
|
seenby -= m
|
||||||
|
continue
|
||||||
|
if(m.owner.client)
|
||||||
|
m.owner.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 in obscuredTurfs)
|
||||||
|
var/turf/t = turf
|
||||||
|
if(!t.obfuscations[obfuscation.type])
|
||||||
|
t.obfuscations[obfuscation.type] = image(obfuscation.icon, t, obfuscation.icon_state, 15)
|
||||||
|
obscured += t.obfuscations[obfuscation.type]
|
||||||
|
|
||||||
|
#undef UPDATE_BUFFER
|
||||||
103
code/modules/mob/freelook/eye.dm
Normal file
103
code/modules/mob/freelook/eye.dm
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
// 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/sprint = 10
|
||||||
|
var/cooldown = 0
|
||||||
|
var/acceleration = 1
|
||||||
|
|
||||||
|
see_in_dark = 7
|
||||||
|
status_flags = GODMODE
|
||||||
|
invisibility = INVISIBILITY_EYE
|
||||||
|
|
||||||
|
var/mob/owner = null
|
||||||
|
var/list/visibleChunks = list()
|
||||||
|
|
||||||
|
var/ghostimage = null
|
||||||
|
var/datum/visualnet/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
|
||||||
|
|
||||||
|
if(owner.client)
|
||||||
|
owner.client.eye = src
|
||||||
|
|
||||||
|
visualnet.visibility(src)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/mob/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
|
||||||
|
|
||||||
|
/mob/eye/proc/getLoc()
|
||||||
|
if(owner)
|
||||||
|
if(!isturf(owner.loc) || !owner.client)
|
||||||
|
return
|
||||||
|
return loc
|
||||||
|
|
||||||
|
/mob
|
||||||
|
var/mob/eye/eyeobj
|
||||||
|
|
||||||
|
/mob/proc/EyeMove(n, direct)
|
||||||
|
if(!eyeobj)
|
||||||
|
return
|
||||||
|
|
||||||
|
return eyeobj.EyeMove(n, direct)
|
||||||
53
code/modules/mob/freelook/update_triggers.dm
Normal file
53
code/modules/mob/freelook/update_triggers.dm
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
//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 = new()
|
||||||
|
|
||||||
|
/turf/drain_power()
|
||||||
|
return -1
|
||||||
|
|
||||||
|
/turf/simulated/Del()
|
||||||
|
updateVisibility(src)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/turf/simulated/New()
|
||||||
|
..()
|
||||||
|
updateVisibility(src)
|
||||||
|
|
||||||
|
|
||||||
|
// STRUCTURES
|
||||||
|
|
||||||
|
/obj/structure/Del()
|
||||||
|
updateVisibility(src)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/structure/New()
|
||||||
|
..()
|
||||||
|
updateVisibility(src)
|
||||||
|
|
||||||
|
// EFFECTS
|
||||||
|
|
||||||
|
/obj/effect/Del()
|
||||||
|
updateVisibility(src)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/effect/New()
|
||||||
|
..()
|
||||||
|
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)
|
||||||
133
code/modules/mob/freelook/visualnet.dm
Normal file
133
code/modules/mob/freelook/visualnet.dm
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// VISUAL NET
|
||||||
|
//
|
||||||
|
// The datum containing all the chunks.
|
||||||
|
|
||||||
|
var/global/list/visual_nets = new()
|
||||||
|
|
||||||
|
/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/Del()
|
||||||
|
visual_nets -= src
|
||||||
|
..()
|
||||||
|
|
||||||
|
// 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(mob/eye/eye)
|
||||||
|
// 0xf = 15
|
||||||
|
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 += getChunk(x, y, eye.z)
|
||||||
|
|
||||||
|
var/list/remove = eye.visibleChunks - visibleChunks
|
||||||
|
var/list/add = visibleChunks - eye.visibleChunks
|
||||||
|
|
||||||
|
for(var/chunk in remove)
|
||||||
|
var/datum/chunk/c = chunk
|
||||||
|
c.remove(eye)
|
||||||
|
|
||||||
|
for(var/chunk in add)
|
||||||
|
var/datum/chunk/c = chunk
|
||||||
|
c.add(eye)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
//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)
|
||||||
|
*/
|
||||||
@@ -1345,6 +1345,12 @@
|
|||||||
if(machine)
|
if(machine)
|
||||||
if(!machine.check_eye(src))
|
if(!machine.check_eye(src))
|
||||||
reset_view(null)
|
reset_view(null)
|
||||||
|
else if(eyeobj)
|
||||||
|
if(eyeobj.owner != src)
|
||||||
|
|
||||||
|
reset_view(null)
|
||||||
|
else
|
||||||
|
src.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||||
else
|
else
|
||||||
var/isRemoteObserve = 0
|
var/isRemoteObserve = 0
|
||||||
if((mRemote in mutations) && remoteview_target)
|
if((mRemote in mutations) && remoteview_target)
|
||||||
|
|||||||
@@ -2,157 +2,45 @@
|
|||||||
//
|
//
|
||||||
// The datum containing all the chunks.
|
// The datum containing all the chunks.
|
||||||
|
|
||||||
var/datum/cameranet/cameranet = new()
|
var/datum/visualnet/camera/cameranet = new()
|
||||||
|
|
||||||
/datum/cameranet
|
/datum/visualnet/camera
|
||||||
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||||
var/list/cameras = list()
|
var/list/cameras = list()
|
||||||
var/cameras_unsorted = 1
|
var/cameras_unsorted = 1
|
||||||
// The chunks of the map, mapping the areas that the cameras can see.
|
chunk_type = /datum/chunk/camera
|
||||||
var/list/chunks = list()
|
|
||||||
var/ready = 0
|
|
||||||
|
|
||||||
/datum/cameranet/proc/process_sort()
|
/datum/visualnet/camera/proc/process_sort()
|
||||||
if(cameras_unsorted)
|
if(cameras_unsorted)
|
||||||
cameras = dd_sortedObjectList(cameras)
|
cameras = dd_sortedObjectList(cameras)
|
||||||
cameras_unsorted = 0
|
cameras_unsorted = 0
|
||||||
|
|
||||||
// Checks if a chunk has been Generated in x, y, z.
|
|
||||||
/datum/cameranet/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/cameranet/proc/getCameraChunk(x, y, z)
|
|
||||||
x &= ~0xf
|
|
||||||
y &= ~0xf
|
|
||||||
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/aiEye/ai)
|
|
||||||
// 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/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)
|
|
||||||
|
|
||||||
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.
|
// Removes a camera from a chunk.
|
||||||
|
|
||||||
/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
|
/datum/visualnet/camera/proc/removeCamera(obj/machinery/camera/c)
|
||||||
if(c.can_use())
|
if(c.can_use())
|
||||||
majorChunkChange(c, 0)
|
majorChunkChange(c, 0)
|
||||||
|
|
||||||
// Add a camera to a chunk.
|
// Add a camera to a chunk.
|
||||||
|
|
||||||
/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
|
/datum/visualnet/camera/proc/addCamera(obj/machinery/camera/c)
|
||||||
if(c.can_use())
|
if(c.can_use())
|
||||||
majorChunkChange(c, 1)
|
majorChunkChange(c, 1)
|
||||||
|
|
||||||
// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
|
// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
|
||||||
|
|
||||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
|
/datum/visualnet/camera/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||||
if(c.can_use())
|
if(c.can_use())
|
||||||
majorChunkChange(c, 1)
|
majorChunkChange(c, 1)
|
||||||
//else
|
//else
|
||||||
// majorChunkChange(c, 0)
|
// majorChunkChange(c, 0)
|
||||||
|
|
||||||
// Never access this proc directly!!!!
|
/datum/visualnet/camera/onMajorChunkChange(atom/c, var/choice, var/datum/chunk/camera/chunk)
|
||||||
// This will update the chunk and all the surrounding chunks.
|
// Only add actual cameras to the list of cameras
|
||||||
// It will also add the atom to the cameras list if you set the choice to 1.
|
if(istype(c, /obj/machinery/camera))
|
||||||
// Setting the choice to 0 will remove the camera from the chunks.
|
if(choice == 0)
|
||||||
// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
|
// Remove the camera.
|
||||||
|
chunk.cameras -= c
|
||||||
/datum/cameranet/proc/majorChunkChange(atom/c, var/choice)
|
else if(choice == 1)
|
||||||
// 0xf = 15
|
// You can't have the same camera in the list twice.
|
||||||
if(!c)
|
chunk.cameras |= 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
|
|
||||||
|
|
||||||
//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/camerachunk/chunk = getCameraChunk(x, y, T.z)
|
|
||||||
// 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
|
|
||||||
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)
|
|
||||||
return checkTurfVis(position)
|
|
||||||
|
|
||||||
/datum/cameranet/proc/checkTurfVis(var/turf/position)
|
|
||||||
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)
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,77 +1,12 @@
|
|||||||
#define UPDATE_BUFFER 25 // 2.5 seconds
|
|
||||||
|
|
||||||
// CAMERA CHUNK
|
// CAMERA CHUNK
|
||||||
//
|
//
|
||||||
// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
|
// 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
|
/datum/chunk/camera
|
||||||
var/list/obscuredTurfs = list()
|
|
||||||
var/list/visibleTurfs = list()
|
|
||||||
var/list/obscured = list()
|
|
||||||
var/list/cameras = 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/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/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 appropriate lists.
|
|
||||||
|
|
||||||
/datum/camerachunk/proc/update()
|
|
||||||
|
|
||||||
set background = 1
|
|
||||||
|
|
||||||
var/list/newVisibleTurfs = list()
|
|
||||||
|
|
||||||
|
/datum/chunk/camera/acquireVisibleTurfs(var/list/visible)
|
||||||
for(var/camera in cameras)
|
for(var/camera in cameras)
|
||||||
var/obj/machinery/camera/c = camera
|
var/obj/machinery/camera/c = camera
|
||||||
|
|
||||||
@@ -87,77 +22,12 @@
|
|||||||
cameras -= c
|
cameras -= c
|
||||||
|
|
||||||
for(var/turf/t in c.can_see())
|
for(var/turf/t in c.can_see())
|
||||||
newVisibleTurfs[t] = t
|
visible[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/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/aiEye/m = eye
|
|
||||||
if(!m || !m.ai)
|
|
||||||
seenby -= m
|
|
||||||
continue
|
|
||||||
if(m.ai.client)
|
|
||||||
m.ai.client.images += t.obscured
|
|
||||||
|
|
||||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||||
|
|
||||||
/datum/camerachunk/New(loc, x, y, z)
|
/datum/chunk/camera/New(loc, x, y, z)
|
||||||
|
|
||||||
// 0xf = 15
|
|
||||||
x &= ~0xf
|
|
||||||
y &= ~0xf
|
|
||||||
|
|
||||||
src.x = x
|
|
||||||
src.y = y
|
|
||||||
src.z = z
|
|
||||||
|
|
||||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||||
if(c.can_use())
|
if(c.can_use())
|
||||||
cameras += c
|
cameras += c
|
||||||
|
..()
|
||||||
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
|
|
||||||
|
|
||||||
// At this point we only have functional cameras
|
|
||||||
for(var/obj/machinery/camera/c in cameras)
|
|
||||||
for(var/turf/t in c.can_see())
|
|
||||||
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
|
|
||||||
|
|||||||
@@ -3,99 +3,43 @@
|
|||||||
// A mob that the AI controls to look around the station with.
|
// 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.
|
// 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"
|
name = "Inactive AI Eye"
|
||||||
icon = 'icons/mob/AI.dmi'
|
icon_state = "AI-eye"
|
||||||
icon_state = "eye"
|
|
||||||
alpha = 127
|
|
||||||
var/list/visibleCameraChunks = list()
|
|
||||||
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()
|
/mob/eye/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()
|
|
||||||
..()
|
..()
|
||||||
|
visualnet = cameranet
|
||||||
|
|
||||||
mob/aiEye/Del()
|
/mob/eye/aiEye/setLoc(var/T, var/cancel_tracking = 1)
|
||||||
if (ghostimage)
|
if(..())
|
||||||
ghost_darkness_images -= ghostimage
|
var/mob/living/silicon/ai/ai = owner
|
||||||
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
|
|
||||||
|
|
||||||
if(cancel_tracking)
|
if(cancel_tracking)
|
||||||
ai.ai_cancel_tracking()
|
ai.ai_cancel_tracking()
|
||||||
|
|
||||||
T = get_turf(T)
|
|
||||||
loc = T
|
|
||||||
cameranet.visibility(src)
|
|
||||||
if(ai.client)
|
|
||||||
ai.client.eye = src
|
|
||||||
//Holopad
|
//Holopad
|
||||||
if(ai.holo)
|
if(ai.holo)
|
||||||
ai.holo.move_hologram(ai)
|
ai.holo.move_hologram(ai)
|
||||||
|
return 1
|
||||||
/mob/aiEye/proc/getLoc()
|
|
||||||
|
|
||||||
if(ai)
|
|
||||||
if(!isturf(ai.loc) || !ai.client)
|
|
||||||
return
|
|
||||||
return ai.eyeobj.loc
|
|
||||||
|
|
||||||
// AI MOVEMENT
|
// AI MOVEMENT
|
||||||
|
|
||||||
// The AI's "eye". Described on the top of the page.
|
// The AI's "eye". Described on the top of the page.
|
||||||
|
|
||||||
/mob/living/silicon/ai
|
/mob/living/silicon/ai
|
||||||
var/mob/aiEye/eyeobj = new()
|
eyeobj = new /mob/eye/aiEye()
|
||||||
var/sprint = 10
|
|
||||||
var/cooldown = 0
|
|
||||||
var/acceleration = 1
|
|
||||||
var/obj/machinery/hologram/holopad/holo = null
|
var/obj/machinery/hologram/holopad/holo = null
|
||||||
|
|
||||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||||
/mob/living/silicon/ai/New()
|
/mob/living/silicon/ai/New()
|
||||||
..()
|
..()
|
||||||
eyeobj.ai = src
|
eyeobj.owner = src
|
||||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||||
spawn(5)
|
spawn(5)
|
||||||
eyeobj.loc = src.loc
|
eyeobj.loc = src.loc
|
||||||
|
|
||||||
/mob/living/silicon/ai/Del()
|
/mob/living/silicon/ai/Del()
|
||||||
eyeobj.ai = null
|
eyeobj.owner = null
|
||||||
del(eyeobj) // No AI, no Eye
|
del(eyeobj) // No AI, no Eye
|
||||||
..()
|
..()
|
||||||
|
|
||||||
@@ -105,32 +49,6 @@ mob/aiEye/Del()
|
|||||||
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
|
if(AI.eyeobj && AI.client.eye == AI.eyeobj)
|
||||||
AI.eyeobj.setLoc(src)
|
AI.eyeobj.setLoc(src)
|
||||||
|
|
||||||
// This will move the AIEye. It will also cause lights near the eye to light up, if toggled.
|
|
||||||
// This is handled in the proc below this one.
|
|
||||||
|
|
||||||
/client/proc/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
|
||||||
|
|
||||||
var/initial = initial(user.sprint)
|
|
||||||
var/max_sprint = 50
|
|
||||||
|
|
||||||
if(user.cooldown && user.cooldown < world.timeofday) // 3 seconds
|
|
||||||
user.sprint = initial
|
|
||||||
|
|
||||||
for(var/i = 0; i < max(user.sprint, initial); i += 20)
|
|
||||||
var/turf/step = get_turf(get_step(user.eyeobj, direct))
|
|
||||||
if(step)
|
|
||||||
user.eyeobj.setLoc(step)
|
|
||||||
|
|
||||||
user.cooldown = world.timeofday + 5
|
|
||||||
if(user.acceleration)
|
|
||||||
user.sprint = min(user.sprint + 0.5, max_sprint)
|
|
||||||
else
|
|
||||||
user.sprint = initial
|
|
||||||
|
|
||||||
//user.unset_machine() //Uncomment this if it causes problems.
|
|
||||||
//user.lightNearbyCamera()
|
|
||||||
|
|
||||||
|
|
||||||
// Return to the Core.
|
// Return to the Core.
|
||||||
|
|
||||||
/mob/living/silicon/ai/proc/core()
|
/mob/living/silicon/ai/proc/core()
|
||||||
@@ -147,12 +65,12 @@ mob/aiEye/Del()
|
|||||||
if(!src.eyeobj)
|
if(!src.eyeobj)
|
||||||
src << "ERROR: Eyeobj not found. Creating new eye..."
|
src << "ERROR: Eyeobj not found. Creating new eye..."
|
||||||
src.eyeobj = new(src.loc)
|
src.eyeobj = new(src.loc)
|
||||||
src.eyeobj.ai = src
|
src.eyeobj.owner = src
|
||||||
src.SetName(src.name)
|
src.SetName(src.name)
|
||||||
|
|
||||||
if(client && client.eye)
|
if(client && client.eye)
|
||||||
client.eye = src
|
client.eye = src
|
||||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
for(var/datum/chunk/c in eyeobj.visibleChunks)
|
||||||
c.remove(eyeobj)
|
c.remove(eyeobj)
|
||||||
src.eyeobj.setLoc(src)
|
src.eyeobj.setLoc(src)
|
||||||
|
|
||||||
@@ -160,5 +78,8 @@ mob/aiEye/Del()
|
|||||||
set category = "AI Commands"
|
set category = "AI Commands"
|
||||||
set name = "Toggle Camera Acceleration"
|
set name = "Toggle Camera Acceleration"
|
||||||
|
|
||||||
acceleration = !acceleration
|
if(!eyeobj)
|
||||||
usr << "Camera acceleration has been toggled [acceleration ? "on" : "off"]."
|
return
|
||||||
|
|
||||||
|
eyeobj.acceleration = !eyeobj.acceleration
|
||||||
|
usr << "Camera acceleration has been toggled [eyeobj.acceleration ? "on" : "off"]."
|
||||||
|
|||||||
@@ -1,65 +1,5 @@
|
|||||||
#define BORG_CAMERA_BUFFER 30
|
#define BORG_CAMERA_BUFFER 30
|
||||||
|
|
||||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
|
||||||
|
|
||||||
// TURFS
|
|
||||||
|
|
||||||
/turf
|
|
||||||
var/image/obscured
|
|
||||||
|
|
||||||
/turf/drain_power()
|
|
||||||
return -1
|
|
||||||
|
|
||||||
/turf/proc/visibilityChanged()
|
|
||||||
if(ticker)
|
|
||||||
cameranet.updateVisibility(src)
|
|
||||||
|
|
||||||
/turf/simulated/Del()
|
|
||||||
visibilityChanged()
|
|
||||||
..()
|
|
||||||
|
|
||||||
/turf/simulated/New()
|
|
||||||
..()
|
|
||||||
visibilityChanged()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// STRUCTURES
|
|
||||||
|
|
||||||
/obj/structure/Del()
|
|
||||||
if(ticker)
|
|
||||||
cameranet.updateVisibility(src)
|
|
||||||
..()
|
|
||||||
|
|
||||||
/obj/structure/New()
|
|
||||||
..()
|
|
||||||
if(ticker)
|
|
||||||
cameranet.updateVisibility(src)
|
|
||||||
|
|
||||||
// EFFECTS
|
|
||||||
|
|
||||||
/obj/effect/Del()
|
|
||||||
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/update_nearby_tiles(need_rebuild)
|
|
||||||
. = ..(need_rebuild)
|
|
||||||
// Glass door glass = 1
|
|
||||||
// don't check then?
|
|
||||||
if(!glass && cameranet)
|
|
||||||
cameranet.updateVisibility(src, 0)
|
|
||||||
|
|
||||||
|
|
||||||
// ROBOT MOVEMENT
|
// ROBOT MOVEMENT
|
||||||
|
|
||||||
// Update the portable camera everytime the Robot moves.
|
// Update the portable camera everytime the Robot moves.
|
||||||
|
|||||||
@@ -188,9 +188,9 @@
|
|||||||
|
|
||||||
if(mob.stat==2) return
|
if(mob.stat==2) return
|
||||||
|
|
||||||
// handle possible AI movement
|
// handle possible Eye movement
|
||||||
if(isAI(mob))
|
if(mob.eyeobj)
|
||||||
return AIMove(n,direct,mob)
|
return mob.EyeMove(n,direct)
|
||||||
|
|
||||||
if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var
|
if(mob.monkeyizing) return//This is sota the goto stop mobs from moving var
|
||||||
|
|
||||||
@@ -457,12 +457,12 @@
|
|||||||
var/area/A = turf.loc
|
var/area/A = turf.loc
|
||||||
if(istype(A) && A.has_gravity == 0)
|
if(istype(A) && A.has_gravity == 0)
|
||||||
var/can_walk = 0
|
var/can_walk = 0
|
||||||
|
|
||||||
if(ishuman(src)) // Only humans can wear magboots, so we give them a chance to.
|
if(ishuman(src)) // Only humans can wear magboots, so we give them a chance to.
|
||||||
var/mob/living/carbon/human/H = src
|
var/mob/living/carbon/human/H = src
|
||||||
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))
|
if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP))
|
||||||
can_walk = 1
|
can_walk = 1
|
||||||
|
|
||||||
if(!can_walk)
|
if(!can_walk)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -457,7 +457,7 @@
|
|||||||
#define INVISIBILITY_LEVEL_ONE 35
|
#define INVISIBILITY_LEVEL_ONE 35
|
||||||
#define INVISIBILITY_LEVEL_TWO 45
|
#define INVISIBILITY_LEVEL_TWO 45
|
||||||
#define INVISIBILITY_OBSERVER 60
|
#define INVISIBILITY_OBSERVER 60
|
||||||
#define INVISIBILITY_AI_EYE 61
|
#define INVISIBILITY_EYE 61
|
||||||
|
|
||||||
#define SEE_INVISIBLE_LIVING 25
|
#define SEE_INVISIBLE_LIVING 25
|
||||||
#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15
|
#define SEE_INVISIBLE_OBSERVER_NOLIGHTING 15
|
||||||
|
|||||||
BIN
icons/mob/AI.dmi
BIN
icons/mob/AI.dmi
Binary file not shown.
|
Before Width: | Height: | Size: 221 KiB After Width: | Height: | Size: 220 KiB |
BIN
icons/mob/eye.dmi
Normal file
BIN
icons/mob/eye.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 845 B |
Reference in New Issue
Block a user