diff --git a/code/WorkInProgress/AI_Visibility.dm b/code/WorkInProgress/AI_Visibility.dm index a18da5b5f43..cf3eadb2b38 100644 --- a/code/WorkInProgress/AI_Visibility.dm +++ b/code/WorkInProgress/AI_Visibility.dm @@ -8,6 +8,9 @@ //(And therefore also be portable to another similar codebase simply by transferring the file and including it after the other AI code files.) //There are probably a few parts that don't do that at the moment, but I'll fix them at some point. + +#define MINIMAP_UPDATE_DELAY 1200 + /turf var/image/obscured var/image/dim @@ -33,9 +36,128 @@ var/list/turfs = list() var/list/seenby = list() var/visible = 0 - var/changed = 0 + var/changed = 1 var/updating = 0 + var/x + var/y + var/z + + var/minimap_updating = 0 + + var/icon/minimap_icon = new('minimap.dmi', "chunk_base") + var/obj/minimap_obj/minimap_obj = new() + +/obj/minimap_obj/Click(location, control, params) + if(!istype(usr, /mob/dead) && !istype(usr, /mob/living/silicon/ai) && !(usr.client && usr.client.holder && usr.client.holder.level >= 4)) + return + + var/list/par = params2list(params) + var/screen_loc = par["screen-loc"] + + if(findtext(screen_loc, "minimap:") != 1) + return + + screen_loc = copytext(screen_loc, length("minimap:") + 1) + + var/x_text = copytext(screen_loc, 1, findtext(screen_loc, ",")) + var/y_text = copytext(screen_loc, findtext(screen_loc, ",") + 1) + + var/x = (text2num(copytext(x_text, 1, findtext(x_text, ":"))) - 1) * 16 + x += round((text2num(copytext(x_text, findtext(x_text, ":") + 1)) + 1) / 2) + + var/y = (text2num(copytext(y_text, 1, findtext(y_text, ":"))) - 1) * 16 + y += round((text2num(copytext(y_text, findtext(y_text, ":") + 1)) + 1) / 2) + + if(istype(usr, /mob/living/silicon/ai)) + var/mob/living/silicon/ai/ai = usr + ai.freelook() + ai.eyeobj.loc = locate(max(1, x - 1), max(1, y - 1), ai.eyeobj.z) + cameranet.visibility(ai.eyeobj) + + else + usr.loc = locate(max(1, x - 1), max(1, y - 1), usr.z) + +/mob/dead/verb/Open_Minimap() + set category = "Ghost" + winshow(src, "minimapwindow", 1) + client.screen |= cameranet.minimap + + if(cameranet.generating_minimap) + cameranet.minimap_viewers += src + +/mob/living/silicon/ai/verb/Open_Minimap() + set category = "AI Commands" + winshow(src, "minimapwindow", 1) + client.screen |= cameranet.minimap + + if(cameranet.generating_minimap) + cameranet.minimap_viewers += src + +/client/proc/Open_Minimap() + set category = "Admin" + winshow(src, "minimapwindow", 1) + screen |= cameranet.minimap + + if(cameranet.generating_minimap) + cameranet.minimap_viewers += src.mob + +/datum/camerachunk/proc/update_minimap() + if(changed && !updating) + update() + + minimap_icon.Blend(rgb(255, 0, 0), ICON_MULTIPLY) + + var/list/turfs = visibleTurfs | dimTurfs + + for(var/turf/turf in turfs) + var/x = (turf.x & 0xf) * 2 + var/y = (turf.y & 0xf) * 2 + + if(turf.density) + minimap_icon.DrawBox(rgb(100, 100, 100), x + 1, y + 1, x + 2, y + 2) + continue + + else if(istype(turf, /turf/space)) + minimap_icon.DrawBox(rgb(0, 0, 0), x + 1, y + 1, x + 2, y + 2) + + else + minimap_icon.DrawBox(rgb(200, 200, 200), x + 1, y + 1, x + 2, y + 2) + + for(var/obj/structure/o in turf) + if(o.density) + if(istype(o, /obj/structure/window) && (o.dir == NORTH || o.dir == SOUTH || o.dir == EAST || o.dir == WEST)) + if(o.dir == NORTH) + minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 2, x + 2, y + 2) + else if(o.dir == SOUTH) + minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 2, y + 1) + else if(o.dir == EAST) + minimap_icon.DrawBox(rgb(150, 150, 200), x + 3, y + 1, x + 2, y + 2) + else if(o.dir == WEST) + minimap_icon.DrawBox(rgb(150, 150, 200), x + 1, y + 1, x + 1, y + 2) + + else + minimap_icon.DrawBox(rgb(150, 150, 150), x + 1, y + 1, x + 2, y + 2) + break + + for(var/obj/machinery/door/o in turf) + if(istype(o, /obj/machinery/door/window)) + if(o.dir == NORTH) + minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 2, x + 2, y + 2) + else if(o.dir == SOUTH) + minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 1) + else if(o.dir == EAST) + minimap_icon.DrawBox(rgb(100, 150, 100), x + 2, y + 1, x + 2, y + 2) + else if(o.dir == WEST) + minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 1, y + 2) + + else + minimap_icon.DrawBox(rgb(100, 150, 100), x + 1, y + 1, x + 2, y + 2) + break + + minimap_obj.screen_loc = "minimap:[src.x / 16],[src.y / 16]" + minimap_obj.icon = minimap_icon + /mob/aiEye var/list/visibleCameraChunks = list() var/mob/ai = null @@ -50,6 +172,7 @@ seenby += ai if(changed && !updating) update() + changed = 0 /datum/camerachunk/proc/remove(mob/aiEye/ai) ai.visibleCameraChunks -= src @@ -76,20 +199,28 @@ else changed = 1 + if(!minimap_updating) + minimap_updating = 1 + + spawn(MINIMAP_UPDATE_DELAY) + if(changed && !updating) + update() + changed = 0 + + update_minimap() + minimap_updating = 0 + /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 = 7 - 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 + newDimTurfs |= turfs & view(7, c) + newVisibleTurfs |= turfs & view(6, c) c.luminosity = lum @@ -154,29 +285,26 @@ m.ai.client.images += t.obscured - /datum/camerachunk/New(loc, x, y, z) 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))) 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 + turfs = block(locate(x, y, z), locate(min(world.maxx, x + 15), min(world.maxy, y + 15), z)) for(var/obj/machinery/camera/c in cameras) var/lum = c.luminosity c.luminosity = 7 - 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 + dimTurfs |= turfs & view(7, c) + visibleTurfs |= turfs & view(6, c) c.luminosity = lum @@ -197,6 +325,8 @@ dim += t.dim + cameranet.minimap += minimap_obj + var/datum/cameranet/cameranet = new() /datum/cameranet @@ -205,9 +335,27 @@ var/datum/cameranet/cameranet = new() var/network = "net1" var/ready = 0 + var/list/minimap = list() + + var/generating_minimap = TRUE + var/list/minimap_viewers = list() + /datum/cameranet/New() ..() + spawn(200) + for(var/x = 0, x <= world.maxx, x += 16) + for(var/y = 0, y <= world.maxy, y += 16) + sleep(1) + var/datum/camerachunk/c = getCameraChunk(x, y, 1) + c.update_minimap() + + for(var/mob/m in minimap_viewers) + m.client.screen |= c.minimap_obj + + generating_minimap = FALSE + minimap_viewers = list() + /datum/cameranet/proc/chunkGenerated(x, y, z) var/key = "[x],[y],[z]" return key in chunks @@ -422,4 +570,4 @@ var/datum/cameranet/cameranet = new() else eyeobj.loc = locate(src.x, src.y, src.z) - cameranet.visibility(eyeobj) \ No newline at end of file + cameranet.visibility(eyeobj) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index a585e8a09ec..09e76ce0d1e 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -220,6 +220,7 @@ verbs += /client/proc/jumptokey verbs += /client/proc/jumptomob verbs += /client/proc/jumptoturf + verbs += /client/proc/Open_Minimap verbs += /client/proc/cmd_admin_delete verbs += /client/proc/cmd_admin_add_freeform_ai_law verbs += /client/proc/cmd_admin_add_random_ai_law diff --git a/icons/minimap.dmi b/icons/minimap.dmi new file mode 100644 index 00000000000..26aecb84b96 Binary files /dev/null and b/icons/minimap.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index 3defcc522f6..a7fb4994df9 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -327,6 +327,53 @@ menu "menu" is-disabled = false saved-params = "is-checked" +menu "minimap_menu" + elem + name = "Size" + command = "" + category = "" + is-checked = false + can-check = false + group = "" + is-disabled = false + saved-params = "is-checked" + elem + name = "50%" + command = ".winset \"minimap.icon-size=16\"" + category = "Size" + is-checked = false + can-check = true + group = "minimap_size" + is-disabled = false + saved-params = "is-checked" + elem + name = "100%" + command = ".winset \"minimap.icon-size=32\"" + category = "Size" + is-checked = true + can-check = true + group = "minimap_size" + is-disabled = false + saved-params = "is-checked" + elem + name = "200%" + command = ".winset \"minimap.icon-size=64\"" + category = "Size" + is-checked = false + can-check = true + group = "minimap_size" + is-disabled = false + saved-params = "is-checked" + elem + name = "stretch" + command = ".winset \"minimap.icon-size=0\"" + category = "Size" + is-checked = false + can-check = true + group = "minimap_size" + is-disabled = false + saved-params = "is-checked" + window "Telecomms IDE" elem "Telecomms IDE" @@ -1207,6 +1254,71 @@ window "mapwindow" on-show = ".winset\"mainwindow.mainvsplit.left=mapwindow\"" on-hide = ".winset\"mainwindow.mainvsplit.left=\"" +window "minimapwindow" + elem "minimapwindow" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = none + anchor2 = none + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = false + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = false + right-click = false + saved-params = "pos;size;is-minimized;is-maximized" + on-size = "" + title = "" + titlebar = true + statusbar = true + can-close = true + can-minimize = true + can-resize = true + is-pane = false + is-minimized = false + is-maximized = false + can-scroll = none + icon = "" + image = "" + image-mode = stretch + keep-aspect = false + transparent-color = none + alpha = 255 + macro = "" + menu = "minimap_menu" + on-close = "" + elem "minimap" + type = MAP + pos = 0,0 + size = 640x480 + anchor1 = 0,0 + anchor2 = 100,100 + font-family = "" + font-size = 0 + font-style = "" + text-color = #000000 + background-color = none + is-visible = true + is-disabled = false + is-transparent = false + is-default = false + border = none + drop-zone = true + right-click = false + saved-params = "icon-size" + on-size = "" + icon-size = 32 + text-mode = false + on-show = "" + on-hide = "" + window "outputwindow" elem "outputwindow" type = MAIN