diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm
index 16d5f690d7e..3db669bb5a8 100644
--- a/code/_onclick/adjacent.dm
+++ b/code/_onclick/adjacent.dm
@@ -73,9 +73,8 @@
/atom/movable/Adjacent(var/atom/neighbor)
if(neighbor == loc) return 1
if(!isturf(loc)) return 0
- for(var/turf/T in locs)
- if(isnull(T)) continue
- if(T.Adjacent(neighbor,src)) return 1
+ var/turf/T = get_turf(src)
+ if(T.Adjacent(neighbor,src)) return 1
return 0
// This is necessary for storage items not on your person.
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index fcdc13199f5..8c642006e04 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -91,6 +91,7 @@ datum/controller/game_controller/proc/setup()
setup_economy()
SetupXenoarch()
cachedamageicons()
+ buildcamlist()
world << "Caching Jukebox playlists..."
load_juke_playlists()
world << "Caching Jukebox playlists complete."
@@ -112,6 +113,28 @@ datum/controller/game_controller/proc/setup()
lighting_controller.Initialize()
*/
+datum/controller/game_controller/proc/buildcamlist()
+ adv_camera.camerasbyzlevel = list()
+ for(var/key in adv_camera.zlevels)
+ adv_camera.camerasbyzlevel["[key]"] = list()
+ //camerasbyzlevel = list("1" = list(), "5" = list())
+ if(!istype(cameranet) || !istype(cameranet.cameras) || !cameranet.cameras.len)
+ world.log << "cameranet has not been initialized before us, finding cameras manually."
+ for(var/obj/machinery/camera/C in world) //can't use machines list because cameras are removed from it.
+ if(C.z == 1 || C.z == 5)
+ var/list/ourlist = adv_camera.camerasbyzlevel["[C.z]"]
+ ourlist += C
+ else
+ for(var/obj/machinery/camera/C in cameranet.cameras) //can't use machines list because cameras are removed from it.
+ if(C.z == 1 || C.z == 5)
+ var/list/ourlist = adv_camera.camerasbyzlevel["[C.z]"]
+ ourlist += C
+ for(var/key in adv_camera.camerasbyzlevel)
+ var/list/keylist = adv_camera.camerasbyzlevel[key]
+ world.log << "[key] has [keylist.len] entries"
+
+ adv_camera.initialized = 1
+
datum/controller/game_controller/proc/cachedamageicons()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\datum/controller/game_controller/proc/cachedamageicons() called tick#: [world.time]")
var/mob/living/carbon/human/H = new(locate(1,1,2))
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 5d6bf8cd054..2d22934642d 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -62,6 +62,8 @@ var/list/camera_names=list()
if(!c_tag)
name_camera()
..()
+ if(adv_camera && adv_camera.initialized && !(src in adv_camera.camerasbyzlevel["[z]"]))
+ adv_camera.update(z, 0, src, adding=1)
/obj/machinery/camera/proc/name_camera()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/camera/proc/name_camera() called tick#: [world.time]")
@@ -109,6 +111,7 @@ var/list/camera_names=list()
update_icon()
if(can_use())
cameranet.addCamera(src)
+ adv_camera.update(z, 0, src, adding=1)
for(var/mob/O in mob_list)
if (istype(O.machine, /obj/machinery/computer/security))
var/obj/machinery/computer/security/S = O.machine
@@ -274,9 +277,15 @@ var/list/camera_names=list()
O.unset_machine()
O.reset_view(null)
O << "The screen bursts into static."
+ if(choice && can_use()) //camera reactivated
+ adv_camera.update(z, 0, src, adding=1)
+ else //either deactivated OR being destroyed
+ adv_camera.update(z, 0, src, adding=2)
/obj/machinery/camera/proc/triggerCameraAlarm()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/camera/proc/triggerCameraAlarm() called tick#: [world.time]")
+ if(!alarm_on)
+ adv_camera.update(z, 0, src, adding=4) //1 is alarming, 0 is nothing wrong
alarm_on = 1
for(var/mob/living/silicon/S in mob_list)
S.triggerAlarm("Camera", areaMaster, list(src), src)
@@ -284,6 +293,8 @@ var/list/camera_names=list()
/obj/machinery/camera/proc/cancelCameraAlarm()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/machinery/camera/proc/cancelCameraAlarm() called tick#: [world.time]")
+ if(alarm_on)
+ adv_camera.update(z, 0, src, adding=4) //1 is alarming, 0 is nothing wrong
alarm_on = 0
for(var/mob/living/silicon/S in mob_list)
S.cancelAlarm("Camera", areaMaster, list(src), src)
diff --git a/code/game/machinery/computer/adv_camera.dm b/code/game/machinery/computer/adv_camera.dm
deleted file mode 100644
index 57aece1570d..00000000000
--- a/code/game/machinery/computer/adv_camera.dm
+++ /dev/null
@@ -1,110 +0,0 @@
-/obj/machinery/computer/security/advanced
- name = "Advanced Security Cameras"
- desc = "Used to access the various cameras on the station with an interactive user interface."
- circuit = "/obj/item/weapon/circuitboard/security/advanced"
-
-/obj/item/weapon/circuitboard/security/advanced
- name = "Circuit board (Advanced Security)"
- build_path = /obj/machinery/computer/security/advanced
-
-/obj/machinery/computer/security/advanced/attack_hand(var/mob/user as mob)
- if (src.z > 6)
- user << "Unable to establish a connection: You're too far away from the station!"
- return
- if(stat & (NOPOWER|BROKEN)) return
- ui_interact(user)
-
- return
-
-/obj/machinery/computer/security/advanced/check_eye(var/mob/user as mob)
- if (( ( get_dist(user, src) > 1 ) || !( user.canmove ) || ( user.blinded )) && (!istype(user, /mob/living/silicon)))
- return null
- if(stat & (NOPOWER|BROKEN)) return null
- user.reset_view(current)
- return 1
-
-/obj/machinery/computer/security/advanced/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
- if((user.stat && !isobserver(user)) || !check_eye(user))
- if(current)
- user.reset_view(null)
- return
- if(current)
- if(!( current.status ) || (current.stat & (EMPED)))
- user << "The screen bursts into static!"
- user.reset_view(null)
- current = null
- else
- user.reset_view(current)
- var/list/data[0]
- data["camera"]=null
- if(current)
- data["camera"] = "\ref[current]"
-
- var/list/L = list()
- for (var/obj/machinery/camera/C in cameranet.cameras)
- L.Add(C)
-
- camera_sort(L)
-
- var/list/cams=list()
- for(var/obj/machinery/camera/C in L) // removing sortAtom because nano updates it just enough for the lag to happen
- var/turf/pos = get_turf(C)
- var/list/camera_data=list()
- camera_data["ID"]="\ref[C]"
- camera_data["status"] = ((C.stat & (NOPOWER|BROKEN|EMPED)) ? 2 : (C.status ? 0 : 1))
- camera_data["name"] = text("[]", C.c_tag)
- camera_data["area"] = get_area(C)
- camera_data["x"] = pos.x
- camera_data["y"] = pos.y
- camera_data["z"] = pos.z
- cams+=list(camera_data)
- data["cameras"]=cams
-
- if (!ui) // no ui has been passed, so we'll search for one
- ui = nanomanager.get_open_ui(user, src, ui_key)
-
- if (!ui)
- // the ui does not exist, so we'll create a new one
- ui = new(user, src, ui_key, "adv_camera.tmpl", name, 900, 800)
- // adding a template with the key "mapContent" enables the map ui functionality
- ui.add_template("mapContent", "adv_camera_map_content.tmpl")
- // adding a template with the key "mapHeader" replaces the map header content
- ui.add_template("mapHeader", "adv_camera_map_header.tmpl")
- // When the UI is first opened this is the data it will use
- // we want to show the map by default
- ui.set_show_map(1)
-
- ui.set_initial_data(data)
-
- ui.open()
- // Auto update every Master Controller tick
- if(current)
- ui.set_auto_update(1)
- else
- // The UI is already open so push the new data to it
- ui.push_data(data)
- return
-
-/obj/machinery/computer/security/advanced/Topic(href, href_list)
- if(..())
- return 0
-
- if(href_list["cancel"])
- usr.reset_view(null)
- current = null
- if(href_list["close"])
- usr.reset_view(null)
- if(usr.machine == src)
- usr.unset_machine()
- if(href_list["view"])
- var/obj/machinery/camera/cam = locate(href_list["view"])
- if(cam)
- if(isAI(usr))
- var/mob/living/silicon/ai/A = usr
- A.eyeobj.forceMove(get_turf(cam))
- A.client.eye = A.eyeobj
- else
- use_power(50)
- current = cam
- usr.reset_view(current)
- return 1
\ No newline at end of file
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 3352aa04553..c0cc2052883 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -552,6 +552,8 @@
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/send_html_resources() called tick#: [world.time]")
if(crewmonitor && minimapinit)
crewmonitor.sendResources(src)
+ if(adv_camera && minimapinit)
+ adv_camera.sendResources(src)
/proc/get_role_desire_str(var/rolepref)
//writepanic("[__FILE__].[__LINE__] (no type)([usr ? usr.ckey : ""]) \\/proc/get_role_desire_str() called tick#: [world.time]")
diff --git a/code/modules/html_interface/html_interface.dm b/code/modules/html_interface/html_interface.dm
index a8fc023ed50..8eb0f89c926 100644
--- a/code/modules/html_interface/html_interface.dm
+++ b/code/modules/html_interface/html_interface.dm
@@ -181,7 +181,6 @@ mob/verb/test()
/datum/html_interface/proc/callJavaScript(func, list/arguments, datum/html_interface_client/hclient = null)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/html_interface/proc/callJavaScript() called tick#: [world.time]")
if (!arguments) arguments = new/list()
-
if (hclient)
hclient = getClient(hclient)
@@ -214,7 +213,7 @@ mob/verb/test()
if (hclient && hclient.active)
spawn (-1) src._renderContent(id, hclient, ignore_cache)
-/datum/html_interface/proc/show(datum/html_interface_client/hclient)
+/datum/html_interface/proc/show(datum/html_interface_client/hclient, var/datum/html_interface/oldwindow)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/html_interface/proc/show() called tick#: [world.time]")
hclient = getClient(hclient, TRUE)
@@ -233,6 +232,8 @@ mob/verb/test()
hclient.is_loaded = FALSE
hclient.client << output(replacetextEx(replacetextEx(file2text('html_interface.html'), "\[hsrc\]", "\ref[src]"), "", "[head]"), "browser_\ref[src].browser")
winshow(hclient.client, "browser_\ref[src]", TRUE)
+ if(oldwindow && winexists(hclient.client, "browser_\ref[oldwindow]"))
+ winshow(hclient.client, "browser_\ref[oldwindow]", FALSE)
while (hclient.client && hclient.active && !hclient.is_loaded) sleep(2)
@@ -376,4 +377,4 @@ mob/verb/test()
if ("onclose")
src.hide(hclient)
- else if (src.ref && hclient.active) src.ref.Topic(href, href_list, hclient)
+ else if (src.ref) src.ref.Topic(href, href_list, hclient, src)
diff --git a/code/modules/html_interface/map/adv_sec/adv_camera.dm b/code/modules/html_interface/map/adv_sec/adv_camera.dm
new file mode 100644
index 00000000000..930bc9b7c4e
--- /dev/null
+++ b/code/modules/html_interface/map/adv_sec/adv_camera.dm
@@ -0,0 +1,209 @@
+/obj/machinery/computer/security/advanced
+ name = "Advanced Security Cameras"
+ desc = "Used to access the various cameras on the station with an interactive user interface."
+ circuit = "/obj/item/weapon/circuitboard/security/advanced"
+
+/obj/machinery/computer/security/advanced/New()
+ ..()
+ html_machines += src
+
+/obj/item/weapon/circuitboard/security/advanced
+ name = "Circuit board (Advanced Security)"
+ build_path = /obj/machinery/computer/security/advanced
+
+/obj/machinery/computer/security/advanced/attack_hand(var/mob/user as mob)
+ if (src.z > 6)
+ user << "Unable to establish a connection: You're too far away from the station!"
+ return
+ if(stat & (NOPOWER|BROKEN)) return
+ adv_camera.show(user, (current ? current.z : z))
+ if(current) user.reset_view(current)
+ user.machine = src
+ return
+
+/obj/machinery/computer/security/advanced/check_eye(var/mob/user as mob)
+ if (( ( get_dist(user, src) > 1 ) || !( user.canmove ) || ( user.blinded )) && (!istype(user, /mob/living/silicon)))
+ return null
+ if(stat & (NOPOWER|BROKEN)) return null
+ user.reset_view(current)
+ return 1
+
+var/global/datum/interactive_map/camera/adv_camera = new
+/client/verb/lookatdatum()
+ set category = "Debug"
+ debug_variables(adv_camera)
+
+/datum/interactive_map/camera
+ var/list/zlevel_data
+ var/list/zlevels
+ var/list/camerasbyzlevel
+ var/initialized = 0
+
+/datum/interactive_map/camera/New()
+ . = ..()
+
+ zlevels = list(1,5)
+ zlevel_data = list("1" = list(),"5" = list())
+
+/obj/machinery/computer/camera/Destroy()
+ ..()
+ html_machines -= src
+
+/datum/interactive_map/camera/show(mob/mob, z, datum/html_interface/currui)
+ z = text2num(z)
+ if (!z) z = mob.z
+ if (!(z in zlevels))
+ mob << "zlevel([z]) good levels: [list2text(zlevels, " ")]"
+ mob << "Unable to establish a connection: You're too far away from the station!"
+ return
+
+ if (src.interfaces)
+ var/datum/html_interface/hi
+
+ if (!src.interfaces["[z]"])
+ src.interfaces["[z]"] = new/datum/html_interface/nanotrasen(src, "Security Cameras", 900, 800, "[MAPHEADER] ")
+
+ hi = src.interfaces["[z]"]
+
+ hi.updateContent("content", "
")
+
+ src.update(z, TRUE)
+ else
+ hi = src.interfaces["[z]"]
+
+ hi = src.interfaces["[z]"]
+ hi.show(mob, currui)
+ src.updateFor(mob, hi, z)
+
+/datum/interactive_map/camera/updateFor(hclient_or_mob, datum/html_interface/hi, z, single)
+ //copy pasted code but given so many cameras i dont want to iterate over the entire worlds worth of cams, so we save our data based on zlevel
+ if(!single) hi.callJavaScript("clearAll", new/list(), hclient_or_mob)
+ data = zlevel_data["[z]"]
+ for (var/list/L in data)
+ hi.callJavaScript("add", L, hclient_or_mob)
+
+#define toAdd 1
+#define toRemove 2
+#define toChange 4
+/datum/interactive_map/camera/update(z, ignore_unused = FALSE, var/obj/machinery/camera/single, adding = 0)
+ if (src.interfaces["[z]"])
+ var/zz = text2num(z)
+ if(!zz) zz = z
+ var/datum/html_interface/hi = src.interfaces["[zz]"]
+ var/ID
+ var/status
+ var/name
+ var/area
+ var/pos_x
+ var/pos_y
+ var/pos_z
+ var/see_x
+ var/see_y
+ if (ignore_unused || hi.isUsed())
+ var/list/results = list()
+ var/list/ourcams = camerasbyzlevel["[z]"]
+ if(!istype(single))
+ for (var/obj/machinery/camera/C in ourcams)
+ var/turf/pos = get_turf(C)
+ if(pos.z != zz)
+ camerasbyzlevel["[zz]"] -= C //bad zlevel
+ if(pos.z == 1 || pos.z == 5)
+ camerasbyzlevel["[zz]"] |= C //try to fix the zlevel list.
+ continue
+ ID="\ref[C]"
+ status = C.alarm_on //1 = alarming 0 = all is well
+ if(!C.can_use())
+ continue
+ // weve already cleared the board son.status = -1 //mark this shit for removal
+ name = C.c_tag
+ var/area/AA = get_area(C)
+ area = format_text(AA.name)
+ pos_x = pos.x
+ pos_y = pos.y
+ pos_z = pos.z
+ see_x = pos.x - WORLD_X_OFFSET[z]
+ see_y = pos.y - WORLD_Y_OFFSET[z]
+ results[++results.len]=list(ID, status, name,area,pos_x,pos_y,pos_z,see_x,see_y)
+ else
+ var/turf/pos = get_turf(single)
+ if(pos.z != zz)
+ camerasbyzlevel["[zz]"] -= single //bad zlevel
+ if(pos.z == 1 || pos.z == 5)
+ camerasbyzlevel["[zz]"] |= single //try to fix the zlevel list
+ else adding = 2 //Set to remove
+ ID="\ref[single]"
+ status = single.alarm_on //1 = alarming 0 = all is well
+ if(!single.can_use())
+ adding = 2 //mark this shit for removal
+ name = single.c_tag
+ var/area/AA = get_area(single)
+ area = format_text(AA.name)
+ pos_x = pos.x
+ pos_y = pos.y
+ pos_z = pos.z
+ see_x = pos.x - WORLD_X_OFFSET[z]
+ see_y = pos.y - WORLD_Y_OFFSET[z]
+ results[++results.len]=list(ID, status, name,area,pos_x,pos_y,pos_z,see_x,see_y,adding)
+
+ //src.data = results
+ zlevel_data["[z]"] = results
+ src.updateFor(null, hi, z, single) // updates for everyone
+#undef toAdd
+#undef toRemove
+#undef toChange
+/datum/interactive_map/camera/hiIsValidClient(datum/html_interface_client/hclient, datum/html_interface/hi)
+/* zlevel limit removed on /vg/
+ var/z = ""
+
+ for (z in src.interfaces)
+ if (src.interfaces[z] == hi) break
+*/
+ . = ..()
+
+ var/los = hclient.client.mob.html_mob_check(/obj/machinery/computer/security/advanced)
+ if(!los) hclient.client.mob.reset_view(hclient.client.mob)
+
+ return (. && los)
+
+/datum/interactive_map/camera/Topic(href, href_list[], datum/html_interface_client/hclient)
+ //world.log << "[src.type] topic call"
+ if(..())
+ //world.log << "[src.type] topic call handled by parent"
+ return // Our parent handled it the topic call
+ if (istype(hclient))
+ if (hclient && hclient.client && hclient.client.mob && isliving(hclient.client.mob))
+ var/mob/living/L = hclient.client.mob
+ usr = L
+ for(var/obj/machinery/computer/security/advanced/A in html_machines)
+ if(usr.machine == A)
+ A.Topic(href, href_list, hclient)
+ break
+
+/datum/interactive_map/camera/queueUpdate(z)
+ var/datum/controller/process/html/html = processScheduler.getProcess("html")
+ html.queue(crewmonitor, "update", z)
+
+/datum/interactive_map/camera/sendResources(client/C)
+ ..()
+ C << browse_rsc('camera.js', "advcamera.js")
+
+/obj/machinery/computer/security/advanced/Topic(href, href_list)
+ //world.log << "[src.type] topic call"
+ if(..())
+ return 0
+
+ if(href_list["cancel"])
+ usr.reset_view(null)
+ current = null
+ if(href_list["view"])
+ var/obj/machinery/camera/cam = locate(href_list["view"])
+ if(cam)
+ if(isAI(usr))
+ var/mob/living/silicon/ai/A = usr
+ A.eyeobj.forceMove(get_turf(cam))
+ A.client.eye = A.eyeobj
+ else
+ use_power(50)
+ current = cam
+ usr.reset_view(current)
+ return 1
\ No newline at end of file
diff --git a/code/modules/html_interface/map/adv_sec/camera.js b/code/modules/html_interface/map/adv_sec/camera.js
new file mode 100644
index 00000000000..79d9a69db10
--- /dev/null
+++ b/code/modules/html_interface/map/adv_sec/camera.js
@@ -0,0 +1,137 @@
+/*!
+ * Advanced Security Camera script
+ */
+
+$(window).on("onUpdateContent", function(){
+ $("#textbased").html("");
+
+ $("#uiMap").append("
");
+ $("#uiMapContainer").append("");
+ if(!html5compat){
+ var i = document.createElement("input");
+ i.setAttribute("type", "range");
+ html5compat = i.type !== "text";
+ }
+ if(html5compat){
+ $("#switches").append("");
+ }
+ else{
+ $("#switches").append(" Zoom: -- ++ 100%");
+
+ }
+
+ var width = $("#uiMap").width();
+
+ scale_x = width / (maxx * tile_size);
+ scale_y = width / (maxy * tile_size); // height is assumed to be the same
+ $("#uiMap").css({ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ margin: '-512px 0 0 -512px',
+ width: '256px',
+ height: '256px',
+ overflow: 'hidden',
+ zoom: '4'
+ });
+ $('#uiMap').drags({handle : '#uiMapImage'});
+ $('#uiMapTooltip')
+ .off('click')
+ .on('click', function (event) {
+ event.preventDefault();
+ $(this).fadeOut(400);
+ });
+ $('#uiMap').click(function(ev) {
+ var el = document.getElementById('uiMap');
+ var rect = el.getBoundingClientRect();
+ var tileX = (((ev.clientX - rect.left - el.clientLeft + el.scrollLeft)) / defaultzoom + 7).toFixed(0);
+ var tileY = (maxy-((ev.clientY - rect.top - el.clientTop + el.scrollTop)) / defaultzoom).toFixed(0);
+ var xx = ((ev.clientX - rect.left - el.clientLeft + el.scrollLeft) / defaultzoom).toFixed(0);
+ var yy = ((ev.clientY - rect.top - el.clientTop + el.scrollTop) / defaultzoom).toFixed(0);
+ //var dot = document.createElement('div');
+ //dot.setAttribute('style', 'position:absolute; width: 2px; height: 2px; top: '+top+'px; left: '+left+'px; background: red; z-index: 99999999;');
+ //el.appendChild(dot);
+ //alert(tileX + ' ' + tileY);
+ window.location.href = "byond://?src=" + hSrc + "&action=crewclick&x=" + tileX + "&y=" + tileY + "&z=" + z;
+ });
+}
+)
+
+var updateMap = true;
+
+function add(ID, status, name, area, pos_x, pos_y, see_pos_x, see_pos_y, adding)
+{
+ if(adding > 0 && !(adding & 1)){ //let additions fall through.
+ if(adding & 2){ //removal
+ var toRemove = document.getElementById(ID);
+ if(toRemove) toRemove.remove();
+ return;
+ }
+ else if(adding & 4) //status change!
+ var toChange = document.getElementById(ID);
+ if(toChange){
+ toChange.removeClass((status == 1 ? "good" : "average")); //remove the coloring
+ toChange.addClass((status == 1 ? "average" : "good"));
+ return;
+ }
+ }
+ if (updateMap && pos_x && pos_y)
+ {
+ var translated = tileToMapCoords(pos_x,pos_y);
+ var href = "byond://?src="+hSrc+"&view="+ID;
+ var dotElem = $("" + name + (status == 1 ? " Alarming" : "") + " (" + area + ": "+see_pos_x+", "+see_pos_y+")
");
+ //$("#uiMap").append("");
+ dotElem.data("href",href);
+ $("#uiMap").append(dotElem);
+ //$("#uiMapContainer").append(dotElem);
+ //$("minimapImage").append(dotElem);
+ //alert($("#uiMap").html());
+ //$("#textbased").html(dotElem);
+
+
+ function enable()
+ {
+ dotElem.addClass("active").css({ "border-color": color });
+ }
+
+ function disable()
+ {
+ dotElem.removeClass("active").css({ "border-color": "transparent" });
+ }
+
+ function click(e)
+ {
+ e.preventDefault();
+ e.stopPropagation();
+
+ window.location.href = "byond://?src=" + hSrc + "&action=select_person&name=" + encodeURIComponent(name);
+ }
+
+ $('.mapIcon')
+ .off('mouseenter mouseleave')
+ .on('mouseenter',
+ function (event) {
+ var self = this;
+ $('#uiMapTooltip')
+ .html($(this).children('.tooltip').html())
+ .show()
+ .stopTime()
+ .oneTime(5000, 'hideTooltip', function () {
+ $(this).fadeOut(500);
+ });
+ }
+ );
+ dotElem.on('click', function (event) {
+ //event.preventDefault();
+ var href = $(this).data('href');
+ //alert(href);
+ if (href != null)
+ {
+ window.location.href = href;
+ }
+ });
+
+ }
+
+
+}
+
diff --git a/code/modules/html_interface/map/crew/crew.css b/code/modules/html_interface/map/crew/crew.css
index 946cb166c19..0d0bc9ce235 100644
--- a/code/modules/html_interface/map/crew/crew.css
+++ b/code/modules/html_interface/map/crew/crew.css
@@ -63,23 +63,3 @@ body
top: -2px;
}
-.dot
-{
- transition: .2s all;
- position: absolute;
- width: 3px;
- height: 3px;
- margin-top: 0px;
- margin-left: 0px;
- border: 1px solid transparent;
-}
-
-.dot.active
-{
- z-index: 9999 !important;
- width: 8px;
- height: 8px;
- margin-top: -2px;
- margin-left: -3px;
-}
-
diff --git a/code/modules/html_interface/map/crew/crew.dm b/code/modules/html_interface/map/crew/crew.dm
index 2fff05d4fab..39f6d46f02a 100644
--- a/code/modules/html_interface/map/crew/crew.dm
+++ b/code/modules/html_interface/map/crew/crew.dm
@@ -91,7 +91,7 @@ var/global/datum/interactive_map/crewmonitor/crewmonitor = new
src.jobs = jobs
-/datum/interactive_map/crewmonitor/show(mob/mob, z)
+/datum/interactive_map/crewmonitor/show(mob/mob, z, datum/html_interface/currui = null)
if (!z) z = mob.z
if (z == CENTCOMM_Z) return
@@ -110,7 +110,7 @@ var/global/datum/interactive_map/crewmonitor/crewmonitor = new
hi = src.interfaces["[z]"]
hi = src.interfaces["[z]"]
- hi.show(mob)
+ hi.show(mob, currui)
src.updateFor(mob, hi, z)
/datum/interactive_map/crewmonitor/updateFor(hclient_or_mob, datum/html_interface/hi, z)
diff --git a/code/modules/html_interface/map/crew/crew.js b/code/modules/html_interface/map/crew/crew.js
index d2a8b9231c8..f9f84deb5bf 100644
--- a/code/modules/html_interface/map/crew/crew.js
+++ b/code/modules/html_interface/map/crew/crew.js
@@ -246,6 +246,68 @@
* Crew manifest script
*/
+$(window).on("onUpdateContent", function(){
+ $("#textbased").html("");
+
+ $("#uiMap").append("
");
+ $("#uiMapContainer").append("");
+ if(!html5compat){
+ var i = document.createElement("input");
+ i.setAttribute("type", "range");
+ html5compat = i.type !== "text";
+ }
+ if(html5compat){
+ $("#switches").append("");
+ }
+ else{
+ $("#switches").append(" Zoom: -- ++ 100%");
+
+ }
+ //$("body")[0].onselectstart = disableSelection;
+
+ var width = $("#uiMap").width();
+
+ scale_x = width / (maxx * tile_size);
+ scale_y = width / (maxy * tile_size); // height is assumed to be the same
+/*
+ $("#uiMap").on("click", function(e)
+ {
+ var x = ((((e.clientX - 8) / scale_x) / tile_size) + 1).toFixed(0);
+ var y = ((maxy - (((e.clientY - 8) / scale_y) / tile_size)) + 1).toFixed(0);
+
+ window.location.href = "byond://?src=" + hSrc + "&action=select_position&x=" + x + "&y=" + y;
+ });*/
+ $("#uiMap").css({ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ margin: '-512px 0 0 -512px',
+ width: '256px',
+ height: '256px',
+ overflow: 'hidden',
+ zoom: '4'
+ });
+ $('#uiMap').drags({handle : '#uiMapImage'});
+ $('#uiMapTooltip')
+ .off('click')
+ .on('click', function (event) {
+ event.preventDefault();
+ $(this).fadeOut(400);
+ });
+ $('#uiMap').click(function(ev) {
+ var el = document.getElementById('uiMap');
+ var rect = el.getBoundingClientRect();
+ var tileX = (((ev.clientX - rect.left - el.clientLeft + el.scrollLeft)) / defaultzoom + 7).toFixed(0);
+ var tileY = (maxy-((ev.clientY - rect.top - el.clientTop + el.scrollTop)) / defaultzoom).toFixed(0);
+ var xx = ((ev.clientX - rect.left - el.clientLeft + el.scrollLeft) / defaultzoom).toFixed(0);
+ var yy = ((ev.clientY - rect.top - el.clientTop + el.scrollTop) / defaultzoom).toFixed(0);
+ //var dot = document.createElement('div');
+ //dot.setAttribute('style', 'position:absolute; width: 2px; height: 2px; top: '+top+'px; left: '+left+'px; background: red; z-index: 99999999;');
+ //el.appendChild(dot);
+ //alert(tileX + ' ' + tileY);
+ window.location.href = "byond://?src=" + hSrc + "&action=crewclick&x=" + tileX + "&y=" + tileY + "&z=" + z;
+ });
+}
+)
var updateMap = true;
var ijobNames = {
diff --git a/code/modules/html_interface/map/interactive_map.dm b/code/modules/html_interface/map/interactive_map.dm
index 2aeafee6637..f7f1b80bb7b 100644
--- a/code/modules/html_interface/map/interactive_map.dm
+++ b/code/modules/html_interface/map/interactive_map.dm
@@ -31,9 +31,7 @@ var/const/ALLOW_CENTCOMM = FALSE
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\datum/interactive_map/proc/updateFor() called tick#: [world.time]")
// This check will succeed if updateFor is called after showing to the player, but will fail
// on regular updates. Since we only really need this once we don't care if it fails.
-
hi.callJavaScript("clearAll", new/list(), hclient_or_mob)
-
for (var/list/L in data)
hi.callJavaScript("add", L, hclient_or_mob)
@@ -45,7 +43,8 @@ var/const/ALLOW_CENTCOMM = FALSE
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\datum/interactive_map/proc/hiIsValidClient() called tick#: [world.time]")
return (hclient.client.mob && hclient.client.mob.stat == CONSCIOUS)
-/datum/interactive_map/Topic(href, href_list[], datum/html_interface_client/hclient)
+/datum/interactive_map/Topic(href, href_list[], datum/html_interface_client/hclient, datum/html_interface/currui)
+ ..()
if (istype(hclient))
if(hclient && hclient.client && hclient.client.mob)
var/mob/living/L = hclient.client.mob
@@ -54,7 +53,7 @@ var/const/ALLOW_CENTCOMM = FALSE
if("changez")
var/newz = text2num(href_list["value"])
if(newz)
- show(L,newz)
+ show(L,newz,currui)
return 1 //Tell children we handled the topic
// Override this to queue an interface to be updated
diff --git a/code/modules/html_interface/map/map_shared.css b/code/modules/html_interface/map/map_shared.css
index 3c036906b20..f212f9f9de7 100644
--- a/code/modules/html_interface/map/map_shared.css
+++ b/code/modules/html_interface/map/map_shared.css
@@ -117,4 +117,24 @@ a { display: inline; }
.oxygen_light {
color: #6698FF;
-}
\ No newline at end of file
+}
+
+.dot
+{
+ transition: .2s all;
+ position: absolute;
+ width: 3px;
+ height: 3px;
+ margin-top: 0px;
+ margin-left: 0px;
+ border: 1px solid transparent;
+}
+
+.dot.active
+{
+ z-index: 9999 !important;
+ width: 8px;
+ height: 8px;
+ margin-top: -2px;
+ margin-left: -3px;
+}
diff --git a/code/modules/html_interface/map/map_shared.js b/code/modules/html_interface/map/map_shared.js
index 0d6ebe6ec4d..83db1aaa115 100644
--- a/code/modules/html_interface/map/map_shared.js
+++ b/code/modules/html_interface/map/map_shared.js
@@ -239,70 +239,7 @@ var scale_x;
var scale_y;
var defaultzoom = 4;
var html5compat = false;
-function disableSelection(){ return false; };
-$(window).on("onUpdateContent", function(){
- $("#textbased").html("");
-
- $("#uiMap").append("
");
- $("#uiMapContainer").append("");
- if(!html5compat){
- var i = document.createElement("input");
- i.setAttribute("type", "range");
- html5compat = i.type !== "text";
- }
- if(html5compat){
- $("#switches").append("");
- }
- else{
- $("#switches").append(" Zoom: -- ++ 100%");
-
- }
- //$("body")[0].onselectstart = disableSelection;
-
- var width = $("#uiMap").width();
-
- scale_x = width / (maxx * tile_size);
- scale_y = width / (maxy * tile_size); // height is assumed to be the same
-/*
- $("#uiMap").on("click", function(e)
- {
- var x = ((((e.clientX - 8) / scale_x) / tile_size) + 1).toFixed(0);
- var y = ((maxy - (((e.clientY - 8) / scale_y) / tile_size)) + 1).toFixed(0);
-
- window.location.href = "byond://?src=" + hSrc + "&action=select_position&x=" + x + "&y=" + y;
- });*/
- $("#uiMap").css({ position: 'absolute',
- top: '50%',
- left: '50%',
- margin: '-512px 0 0 -512px',
- width: '256px',
- height: '256px',
- overflow: 'hidden',
- zoom: '4'
- });
- $('#uiMap').drags({handle : '#uiMapImage'});
- $('#uiMapTooltip')
- .off('click')
- .on('click', function (event) {
- event.preventDefault();
- $(this).fadeOut(400);
- });
- $('#uiMap').click(function(ev) {
- var el = document.getElementById('uiMap');
- var rect = el.getBoundingClientRect();
- var tileX = (((ev.clientX - rect.left - el.clientLeft + el.scrollLeft)) / defaultzoom + 7).toFixed(0);
- var tileY = (maxy-((ev.clientY - rect.top - el.clientTop + el.scrollTop)) / defaultzoom).toFixed(0);
- var xx = ((ev.clientX - rect.left - el.clientLeft + el.scrollLeft) / defaultzoom).toFixed(0);
- var yy = ((ev.clientY - rect.top - el.clientTop + el.scrollTop) / defaultzoom).toFixed(0);
- //var dot = document.createElement('div');
- //dot.setAttribute('style', 'position:absolute; width: 2px; height: 2px; top: '+top+'px; left: '+left+'px; background: red; z-index: 99999999;');
- //el.appendChild(dot);
- //alert(tileX + ' ' + tileY);
- window.location.href = "byond://?src=" + hSrc + "&action=crewclick&x=" + tileX + "&y=" + tileY + "&z=" + z;
- });
-}
-)
function switchTo(i)
{
if (i == 1)
diff --git a/vgstation13.dme b/vgstation13.dme
index 66893444166..6c25116f594 100644
--- a/vgstation13.dme
+++ b/vgstation13.dme
@@ -436,7 +436,6 @@
#include "code\game\machinery\camera\motion.dm"
#include "code\game\machinery\camera\presets.dm"
#include "code\game\machinery\camera\tracking.dm"
-#include "code\game\machinery\computer\adv_camera.dm"
#include "code\game\machinery\computer\ai_core.dm"
#include "code\game\machinery\computer\aifixer.dm"
#include "code\game\machinery\computer\arcade.dm"
@@ -1053,6 +1052,7 @@
#include "code\modules\html_interface\html_interface_client.dm"
#include "code\modules\html_interface\cards\cards.dm"
#include "code\modules\html_interface\map\interactive_map.dm"
+#include "code\modules\html_interface\map\adv_sec\adv_camera.dm"
#include "code\modules\html_interface\map\crew\crew.dm"
#include "code\modules\html_interface\nanotrasen\nanotrasen.dm"
#include "code\modules\hydroponics\grown_inedible.dm"