From d187ca3ba96e5199d861c16637f8fdb6457dbd29 Mon Sep 17 00:00:00 2001 From: "petethegoat@gmail.com" Date: Wed, 19 Oct 2011 18:47:47 +0000 Subject: [PATCH] Committing Uristqwerty's AI freelook. Thank you! The extent of my implementation of this involves commenting out some multi z-level specific stuff, and adding a dmi of the overlays it uses. This currently causes runtime errors due to my lazy implementation! Only -you- can fix them. http://pastebin.com/AqU8sA4b So far as I can tell, it just needs some sanity checks. I would leave this unchecked until the runtimes are fixed. Additionally, our map doesn't actually fair too badly with proper camera LOS, but there are a couple of areas that need improvement. Please update the map when you tick this! git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2395 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/AI_Visibility.dm | 310 +++++++++++++++++++++++++++ icons/effects/cameravis.dmi | Bin 0 -> 281 bytes 2 files changed, 310 insertions(+) create mode 100644 code/WorkInProgress/AI_Visibility.dm create mode 100644 icons/effects/cameravis.dmi diff --git a/code/WorkInProgress/AI_Visibility.dm b/code/WorkInProgress/AI_Visibility.dm new file mode 100644 index 0000000000..faf505229d --- /dev/null +++ b/code/WorkInProgress/AI_Visibility.dm @@ -0,0 +1,310 @@ +//All credit for this goes to Uristqwerty. + +/turf + var/image/obscured + var/image/dim + +/turf/proc/visibilityChanged() + cameranet.updateVisibility(src) + +/datum/camerachunk + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/dimTurfs = list() + var/list/obscured = list() + var/list/dim = list() + var/list/cameras = list() + var/list/turfs = list() + var/list/seenby = list() + var/visible = 0 + var/changed = 0 + var/updating = 0 + +/mob/aiEye + var/list/visibleCameraChunks = list() + var/mob/ai = null + density = 0 + +/datum/camerachunk/proc/add(mob/aiEye/ai) + ai.visibleCameraChunks += src + if(ai.ai.client) + ai.ai.client.images += obscured + ai.ai.client.images += dim + visible++ + seenby += ai + if(changed && !updating) + update() + +/datum/camerachunk/proc/remove(mob/aiEye/ai) + ai.visibleCameraChunks -= src + if(ai.ai.client) + ai.ai.client.images -= obscured + ai.ai.client.images -= dim + seenby -= ai + if(visible > 0) + visible-- + +/datum/camerachunk/proc/visibilityChanged(turf/loc) + if(!(loc in visibleTurfs)) + return + + hasChanged() + +/datum/camerachunk/proc/hasChanged() + if(visible) + if(!updating) + updating = 1 + spawn(10)//Batch large changes, such as many doors opening or closing at once + update() + updating = 0 + else + changed = 1 + +/datum/camerachunk/proc/update() + var/list/newDimTurfs = list() + var/list/newVisibleTurfs = list() + + for(var/obj/machinery/camera/c in cameras) + var/lum = c.luminosity + c.luminosity = 6 + for(var/turf/t in view(7, c)) + if(t in turfs) + newDimTurfs += t + + for(var/turf/t in view(6, c)) + if(t in turfs) + newVisibleTurfs += t + + c.luminosity = lum + + var/list/dimAdded = newDimTurfs - dimTurfs + var/list/dimRemoved = dimTurfs - newDimTurfs + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + dimTurfs = newDimTurfs + obscuredTurfs = turfs - dimTurfs + dimTurfs -= visibleTurfs + + for(var/turf/t in dimRemoved) + if(t.dim) + dim -= t.dim + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images -= t.dim + + if(!(t in visibleTurfs)) + if(!t.obscured) + t.obscured = image('cameravis.dmi', t, "black", 15) + + obscured += t.obscured + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images += t.obscured + + for(var/turf/t in dimAdded) + if(!(t in visibleTurfs)) + if(!t.dim) + t.dim = image('cameravis.dmi', t, "dim", 15) + t.mouse_opacity = 0 + + dim += t.dim + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images += t.dim + + if(t.obscured) + obscured -= t.obscured + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images -= t.obscured + + for(var/turf/t in visAdded) + if(t.obscured) + obscured -= t.obscured + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images -= t.obscured + + for(var/turf/t in visRemoved) + if(t in obscuredTurfs) + if(!t.obscured) + t.obscured = image('cameravis.dmi', t, "black", 15) + + obscured += t.obscured + for(var/mob/aiEye/m in seenby) + if(m.ai.client) + m.ai.client.images += t.obscured + + + +/datum/camerachunk/New(loc, x, y, z) + x &= ~0xf + y &= ~0xf + + for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z))) + if(c.status) + 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 + + for(var/obj/machinery/camera/c in cameras) + var/lum = c.luminosity + c.luminosity = 6 + for(var/turf/t in view(7, c)) + if(t in turfs) + dimTurfs += t + + for(var/turf/t in view(6, c)) + if(t in turfs) + visibleTurfs += t + + c.luminosity = lum + + obscuredTurfs = turfs - dimTurfs + dimTurfs -= visibleTurfs + + for(var/turf/t in obscuredTurfs) + if(!t.obscured) + t.obscured = image('cameravis.dmi', t, "black", 15) + + obscured += t.obscured + + for(var/turf/t in dimTurfs) + if(!(t in visibleTurfs)) + if(!t.dim) + t.dim = image('cameravis.dmi', t, "dim", TURF_LAYER) + + dim += t.dim + +var/datum/cameranet/cameranet = new() + +/datum/cameranet + var/list/cameras = list() + var/list/chunks = list() + var/network = "net1" + var/ready = 0 + +/datum/cameranet/New() + ..() + +/datum/cameranet/proc/chunkGenerated(x, y, z) + var/key = "[x],[y],[z]" + return key in chunks + +/datum/cameranet/proc/getCameraChunk(x, y, z) + var/key = "[x],[y],[z]" + + if(!(key in chunks)) + chunks[key] = new /datum/camerachunk(null, x, y, z) + + return chunks[key] + +/datum/cameranet/proc/visibility(mob/aiEye/ai) + 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/datum/camerachunk/c in remove) + c.remove(ai) + + for(var/datum/camerachunk/c in add) + c.add(ai) + +/datum/cameranet/proc/updateVisibility(turf/loc) + if(!chunkGenerated(loc.x & ~0xf, loc.y & ~0xf, loc.z)) + return + + var/datum/camerachunk/chunk = getCameraChunk(loc.x & ~0xf, loc.y & ~0xf, loc.z) + chunk.visibilityChanged(loc) + +/datum/cameranet/proc/addCamera(obj/machinery/camera/c) + var/x1 = max(0, c.x - 16) & ~0xf + var/y1 = max(0, c.y - 16) & ~0xf + var/x2 = min(world.maxx, c.x + 16) & ~0xf + var/y2 = min(world.maxy, c.y + 16) & ~0xf + + for(var/x = x1; x <= x2; x += 16) + for(var/y = y1; y <= y2; y += 16) + if(chunkGenerated(x, y, c.z)) + var/datum/camerachunk/chunk = getCameraChunk(x, y, c.z) + if(!(c in chunk.cameras)) + chunk.cameras += c + chunk.hasChanged() + + +/mob/living/silicon/ai/var/mob/aiEye/eyeobj = new() + +/mob/living/silicon/ai/New() + ..() + eyeobj.ai = src + +/mob/living/silicon/ai/verb/freelook() + set category = "AI Commands" + set name = "freelook" + current = null //cancel camera view first, it causes problems + cameraFollow = null + machine = null + if(client.eye == eyeobj) + client.eye = src + for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks) + c.remove(eyeobj) + else + client.eye = eyeobj + eyeobj.loc = loc + cameranet.visibility(eyeobj) + cameraFollow = null +/mob/aiEye/Move() + . = ..() + if(.) + cameranet.visibility(src) + +/client/AIMove(n, direct, var/mob/living/silicon/ai/user) + if(eye == user.eyeobj) + user.eyeobj.loc = get_step(user.eyeobj, direct) + cameranet.visibility(user.eyeobj) + + else + return ..() + +/* +/client/AIMoveZ(direct, var/mob/living/silicon/ai/user) + if(eye == user.eyeobj) + var/dif = 0 + if(direct == UP && user.eyeobj.z > 1) + dif = -1 + else if(direct == DOWN && user.eyeobj.z < 4) + dif = 1 + user.eyeobj.loc = locate(user.eyeobj.x, user.eyeobj.y, user.eyeobj.z + dif) + cameranet.visibility(user.eyeobj) + else + return ..() +*/ + +/turf/move_camera_by_click() + if(istype(usr, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/AI = usr + if(AI.client.eye == AI.eyeobj) + return + return ..() + +/obj/machinery/door/update_nearby_tiles(need_rebuild) + . = ..(need_rebuild) + cameranet.updateVisibility(loc) + +/obj/machinery/camera/New() + ..() + cameranet.addCamera(src) \ No newline at end of file diff --git a/icons/effects/cameravis.dmi b/icons/effects/cameravis.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f68c73888718954239b27f762dd6c95ce936b24a GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQe{;k5hX6E#mPmP1tppJc?=8{ zbArPPib}tK2`>2f^@*0ZuGYCT=Yuzd8eBAf@JQ#pkLJk$Ajj;{qca|7ea>q%7Ib+F zc?XH+h)$VQBs6*R)EySVM%`UNKF>~z%Uwdn!HPLMR!un*6O%PXH0E!NNKB3GPKNDs zlppx6vQ`JWAkNdpF(jk$?FC0c1_gnJ1DBtvU6**x%ynQx+Oxi=9zUmjlFw-1yI|tL zo*}h>*@X83<1Drp48F`I4a*p<94<4+F37|!{h2{v4da1}@6KHX+Qi`L>gTe~DWM4f D%JXV6 literal 0 HcmV?d00001