html_interface removal and crew monitoring console refactor.
This commit is contained in:
committed by
CitadelStationBot
parent
1cda9ef2b4
commit
35b8e410be
@@ -143,10 +143,6 @@
|
||||
var/datum/atom_hud/data/human/medical/basic/B = GLOB.huds[DATA_HUD_MEDICAL_BASIC]
|
||||
B.update_suit_sensors(src)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (T)
|
||||
GLOB.crewmonitor.queueUpdate(T.z)
|
||||
|
||||
//called when a living mob changes health
|
||||
/mob/living/proc/med_hud_set_health()
|
||||
var/image/holder = hud_list[HEALTH_HUD]
|
||||
@@ -158,10 +154,6 @@
|
||||
/mob/living/carbon/med_hud_set_health()
|
||||
..()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
GLOB.crewmonitor.queueUpdate(T.z)
|
||||
|
||||
//called when a carbon changes stat, virus or XENO_HOST
|
||||
/mob/living/proc/med_hud_set_status()
|
||||
var/image/holder = hud_list[STATUS_HUD]
|
||||
@@ -216,10 +208,6 @@
|
||||
holder.icon_state = "hud[ckey(wear_id.GetJobName())]"
|
||||
sec_hud_set_security_status()
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (T)
|
||||
GLOB.crewmonitor.queueUpdate(T.z)
|
||||
|
||||
/mob/living/carbon/human/proc/sec_hud_set_implants()
|
||||
var/image/holder
|
||||
for(var/i in list(IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD))
|
||||
|
||||
@@ -456,21 +456,6 @@ Class Procs:
|
||||
/obj/machinery/proc/on_deconstruction()
|
||||
return
|
||||
|
||||
// Hook for html_interface module to prevent updates to clients who don't have this as their active machine.
|
||||
/obj/machinery/proc/hiIsValidClient(datum/html_interface_client/hclient, datum/html_interface/hi)
|
||||
if (hclient.client.mob && (hclient.client.mob.stat == 0 || IsAdminGhost(hclient.client.mob)))
|
||||
if (isAI(hclient.client.mob) || IsAdminGhost(hclient.client.mob))
|
||||
return TRUE
|
||||
else
|
||||
return hclient.client.mob.machine == src && Adjacent(hclient.client.mob)
|
||||
else
|
||||
return FALSE
|
||||
|
||||
// Hook for html_interface module to unset the active machine when the window is closed by the player.
|
||||
/obj/machinery/proc/hiOnHide(datum/html_interface_client/hclient)
|
||||
if (hclient.client.mob && hclient.client.mob.machine == src)
|
||||
hclient.client.mob.unset_machine()
|
||||
|
||||
/obj/machinery/proc/can_be_overridden()
|
||||
. = 1
|
||||
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
switchCamera(cameras[camera])
|
||||
|
||||
/datum/trackable
|
||||
var/initialized = FALSE
|
||||
var/list/names = list()
|
||||
var/list/namecounts = list()
|
||||
var/list/humans = list()
|
||||
var/list/others = list()
|
||||
|
||||
/mob/living/silicon/ai/proc/trackable_mobs()
|
||||
|
||||
track.initialized = TRUE
|
||||
track.names.Cut()
|
||||
track.namecounts.Cut()
|
||||
track.humans.Cut()
|
||||
@@ -63,6 +64,9 @@
|
||||
if(!target_name)
|
||||
return
|
||||
|
||||
if(!track.initialized)
|
||||
trackable_mobs()
|
||||
|
||||
var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name])
|
||||
|
||||
ai_actual_track(target)
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
body
|
||||
{
|
||||
padding-left: 53%;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#ntbgcenter
|
||||
{
|
||||
background-position: 550px 0px !important;
|
||||
}
|
||||
|
||||
#minimap
|
||||
{
|
||||
position: fixed;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
border: 2px inset #888;
|
||||
overflow: hidden;
|
||||
min-width: 480px;
|
||||
min-height: 480px;
|
||||
width: 53%;
|
||||
height: 100%;
|
||||
max-width: 480px;
|
||||
max-height: 480px;
|
||||
}
|
||||
|
||||
#textbased
|
||||
{
|
||||
width: 100%;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
#textbased table
|
||||
{
|
||||
min-width: 380px;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
#textbased td
|
||||
{
|
||||
vertical-align: top;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#textbased tbody td
|
||||
{
|
||||
transition: .2s all;
|
||||
}
|
||||
|
||||
#textbased tbody tr:hover td, #textbased tbody tr.hover td
|
||||
{
|
||||
background-color: #515151;
|
||||
}
|
||||
|
||||
#textarea:after
|
||||
{
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.health
|
||||
{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #FFF;
|
||||
border: 1px solid #434343;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.health-5 { background-color: #17d568; }
|
||||
.health-4 { background-color: #2ecc71; }
|
||||
.health-3 { background-color: #e67e22; }
|
||||
.health-2 { background-color: #ed5100; }
|
||||
.health-1 { background-color: #e74c3c; }
|
||||
.health-0 { background-color: #ed2814; }
|
||||
|
||||
.health > div
|
||||
{
|
||||
margin-left: 20px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.tt
|
||||
{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.tt > div
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tt:hover > div
|
||||
{
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 50%;
|
||||
margin-left: -64px;
|
||||
|
||||
display: block;
|
||||
width: 128px;
|
||||
height: 24px;
|
||||
border: 1px solid #313131;
|
||||
background-color: #434343;
|
||||
padding: 4px;
|
||||
z-index: 999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tt > div > span
|
||||
{
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.dot
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
.zoom
|
||||
{
|
||||
position: fixed;
|
||||
left: 53%;
|
||||
top: 10px;
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
text-align: center;
|
||||
margin-left: 20px !important;
|
||||
}
|
||||
|
||||
.zoom.in
|
||||
{
|
||||
margin-left: -3px !important;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#define SENSORS_UPDATE_PERIOD 100 //How often the sensor data updates.
|
||||
|
||||
/obj/machinery/computer/crew
|
||||
name = "crew monitoring console"
|
||||
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
|
||||
@@ -16,21 +18,22 @@
|
||||
/obj/machinery/computer/crew/attack_ai(mob/user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
GLOB.crewmonitor.show(user)
|
||||
GLOB.crewmonitor.show(user,src)
|
||||
|
||||
/obj/machinery/computer/crew/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
GLOB.crewmonitor.show(user)
|
||||
GLOB.crewmonitor.show(user,src)
|
||||
|
||||
GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
||||
|
||||
/datum/crewmonitor
|
||||
var/list/ui_sources = list() //List of user -> ui source
|
||||
var/list/jobs
|
||||
var/list/interfaces
|
||||
var/list/data
|
||||
var/list/data_by_z = list()
|
||||
var/list/last_update = list()
|
||||
|
||||
/datum/crewmonitor/New()
|
||||
. = ..()
|
||||
@@ -77,196 +80,119 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
||||
jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants
|
||||
|
||||
src.jobs = jobs
|
||||
src.interfaces = list()
|
||||
src.data = list()
|
||||
register_asset("crewmonitor.js",'crew.js')
|
||||
register_asset("crewmonitor.css",'crew.css')
|
||||
|
||||
/datum/crewmonitor/Destroy()
|
||||
if (src.interfaces)
|
||||
for (var/datum/html_interface/hi in interfaces)
|
||||
qdel(hi)
|
||||
src.interfaces = null
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/crewmonitor/proc/show(mob/mob, z)
|
||||
if (mob.client)
|
||||
sendResources(mob.client)
|
||||
if (!z)
|
||||
z = mob.z
|
||||
/datum/crewmonitor/ui_interact(mob/user, ui_key = "crew", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "crew", "crew monitor", 800, 600 , master_ui, state)
|
||||
ui.open()
|
||||
|
||||
if (z > 0 && src.interfaces)
|
||||
var/datum/html_interface/hi
|
||||
/datum/crewmonitor/proc/show(mob/M, source)
|
||||
ui_sources[M] = source
|
||||
ui_interact(M)
|
||||
|
||||
if (!src.interfaces["[z]"])
|
||||
src.interfaces["[z]"] = new/datum/html_interface/nanotrasen(src, "Crew Monitoring", 900, 540, "<link rel=\"stylesheet\" type=\"text/css\" href=\"crewmonitor.css\" /><script type=\"text/javascript\">var z = [z]; var tile_size = [world.icon_size]; var maxx = [world.maxx]; var maxy = [world.maxy];</script><script type=\"text/javascript\" src=\"crewmonitor.js\"></script>")
|
||||
/datum/crewmonitor/ui_host(mob/user)
|
||||
return ui_sources[user]
|
||||
|
||||
hi = src.interfaces["[z]"]
|
||||
/datum/crewmonitor/ui_data(mob/user)
|
||||
var/z = user.z
|
||||
if(!z)
|
||||
var/turf/T = get_turf(user)
|
||||
z = T.z
|
||||
var/list/zdata = update_data(z)
|
||||
. = list()
|
||||
.["sensors"] = zdata
|
||||
.["link_allowed"] = isAI(user)
|
||||
|
||||
hi.updateContent("content", "<div id=\"minimap\"><a href=\"javascript:zoomIn();\" class=\"zoom in\">+</a><a href=\"javascript:zoomOut();\" class=\"zoom\">-</a></div><div id=\"textbased\"></div>")
|
||||
/datum/crewmonitor/proc/update_data(z)
|
||||
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)
|
||||
return data_by_z["[z]"]
|
||||
|
||||
src.update(z, TRUE)
|
||||
else
|
||||
hi = src.interfaces["[z]"]
|
||||
src.update(z,TRUE)
|
||||
var/list/results = list()
|
||||
var/obj/item/clothing/under/U
|
||||
var/obj/item/card/id/I
|
||||
var/turf/pos
|
||||
var/ijob
|
||||
var/name
|
||||
var/assignment
|
||||
var/oxydam
|
||||
var/toxdam
|
||||
var/burndam
|
||||
var/brutedam
|
||||
var/area
|
||||
var/pos_x
|
||||
var/pos_y
|
||||
var/life_status
|
||||
|
||||
// Debugging purposes
|
||||
mob << browse_rsc(file("code/game/machinery/computer/crew.js"), "crew.js")
|
||||
mob << browse_rsc(file("code/game/machinery/computer/crew.css"), "crew.css")
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
// Check if their z-level is correct and if they are wearing a uniform.
|
||||
// Accept H.z==0 as well in case the mob is inside an object.
|
||||
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
U = H.w_uniform
|
||||
|
||||
hi = src.interfaces["[z]"]
|
||||
hi.show(mob)
|
||||
src.updateFor(mob, hi, z)
|
||||
// Are the suit sensors on?
|
||||
if ((U.has_sensor > 0) && U.sensor_mode)
|
||||
pos = H.z == 0 || U.sensor_mode == SENSOR_COORDS ? get_turf(H) : null
|
||||
|
||||
/datum/crewmonitor/proc/updateFor(hclient_or_mob, datum/html_interface/hi, z)
|
||||
// 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", null, hclient_or_mob)
|
||||
// Special case: If the mob is inside an object confirm the z-level on turf level.
|
||||
if (H.z == 0 && (!pos || pos.z != z))
|
||||
continue
|
||||
|
||||
for (var/list/L in data)
|
||||
hi.callJavaScript("add", L, hclient_or_mob)
|
||||
I = H.wear_id ? H.wear_id.GetID() : null
|
||||
|
||||
hi.callJavaScript("onAfterUpdate", null, hclient_or_mob)
|
||||
if (I)
|
||||
name = I.registered_name
|
||||
assignment = I.assignment
|
||||
ijob = jobs[I.assignment]
|
||||
else
|
||||
name = "Unknown"
|
||||
assignment = ""
|
||||
ijob = 80
|
||||
|
||||
/datum/crewmonitor/proc/update(z, ignore_unused = FALSE)
|
||||
if (src.interfaces["[z]"])
|
||||
var/datum/html_interface/hi = src.interfaces["[z]"]
|
||||
if (U.sensor_mode >= SENSOR_LIVING)
|
||||
life_status = (!H.stat ? TRUE : FALSE)
|
||||
else
|
||||
life_status = null
|
||||
|
||||
if (ignore_unused || hi.isUsed())
|
||||
var/list/results = list()
|
||||
var/obj/item/clothing/under/U
|
||||
var/obj/item/card/id/I
|
||||
var/turf/pos
|
||||
var/ijob
|
||||
var/name
|
||||
var/assignment
|
||||
var/dam1
|
||||
var/dam2
|
||||
var/dam3
|
||||
var/dam4
|
||||
var/area
|
||||
var/pos_x
|
||||
var/pos_y
|
||||
var/life_status
|
||||
if (U.sensor_mode >= SENSOR_VITALS)
|
||||
oxydam = round(H.getOxyLoss(),1)
|
||||
toxdam = round(H.getToxLoss(),1)
|
||||
burndam = round(H.getFireLoss(),1)
|
||||
brutedam = round(H.getBruteLoss(),1)
|
||||
else
|
||||
oxydam = null
|
||||
toxdam = null
|
||||
burndam = null
|
||||
brutedam = null
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
// Check if their z-level is correct and if they are wearing a uniform.
|
||||
// Accept H.z==0 as well in case the mob is inside an object.
|
||||
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
U = H.w_uniform
|
||||
if (U.sensor_mode >= SENSOR_COORDS)
|
||||
if (!pos)
|
||||
pos = get_turf(H)
|
||||
area = get_area_name(H, TRUE)
|
||||
pos_x = pos.x
|
||||
pos_y = pos.y
|
||||
else
|
||||
area = null
|
||||
pos_x = null
|
||||
pos_y = null
|
||||
|
||||
// Are the suit sensors on?
|
||||
if ((U.has_sensor > 0) && U.sensor_mode)
|
||||
pos = H.z == 0 || U.sensor_mode == SENSOR_COORDS ? get_turf(H) : null
|
||||
results[++results.len] = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null))
|
||||
|
||||
data_by_z["[z]"] = results
|
||||
last_update["[z]"] = world.time
|
||||
|
||||
return results
|
||||
|
||||
// Special case: If the mob is inside an object confirm the z-level on turf level.
|
||||
if (H.z == 0 && (!pos || pos.z != z))
|
||||
continue
|
||||
/datum/crewmonitor/ui_act(action,params)
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(!istype(AI))
|
||||
return
|
||||
switch (action)
|
||||
if ("select_person")
|
||||
AI.ai_camera_track(params["name"])
|
||||
|
||||
I = H.wear_id ? H.wear_id.GetID() : null
|
||||
|
||||
if (I)
|
||||
name = I.registered_name
|
||||
assignment = I.assignment
|
||||
ijob = jobs[I.assignment]
|
||||
else
|
||||
name = "<i>Unknown</i>"
|
||||
assignment = ""
|
||||
ijob = 80
|
||||
|
||||
if (U.sensor_mode >= SENSOR_LIVING)
|
||||
life_status = (!H.stat ? "true" : "false")
|
||||
else
|
||||
life_status = null
|
||||
|
||||
if (U.sensor_mode >= SENSOR_VITALS)
|
||||
dam1 = round(H.getOxyLoss(),1)
|
||||
dam2 = round(H.getToxLoss(),1)
|
||||
dam3 = round(H.getFireLoss(),1)
|
||||
dam4 = round(H.getBruteLoss(),1)
|
||||
else
|
||||
dam1 = null
|
||||
dam2 = null
|
||||
dam3 = null
|
||||
dam4 = null
|
||||
|
||||
if (U.sensor_mode >= SENSOR_COORDS)
|
||||
if (!pos)
|
||||
pos = get_turf(H)
|
||||
area = get_area_name(H, TRUE)
|
||||
pos_x = pos.x
|
||||
pos_y = pos.y
|
||||
else
|
||||
area = null
|
||||
pos_x = null
|
||||
pos_y = null
|
||||
|
||||
results[++results.len] = list(name, assignment, ijob, life_status, dam1, dam2, dam3, dam4, area, pos_x, pos_y, H.can_track(null))
|
||||
|
||||
src.data = results
|
||||
src.updateFor(null, hi, z) // updates for everyone
|
||||
|
||||
/datum/crewmonitor/proc/hiIsValidClient(datum/html_interface_client/hclient, datum/html_interface/hi)
|
||||
var/z = ""
|
||||
|
||||
for (z in src.interfaces)
|
||||
if (src.interfaces[z] == hi)
|
||||
break
|
||||
|
||||
if(hclient.client.mob && IsAdminGhost(hclient.client.mob))
|
||||
return TRUE
|
||||
|
||||
if (hclient.client.mob && hclient.client.mob.stat == 0 && hclient.client.mob.z == text2num(z))
|
||||
if (isAI(hclient.client.mob))
|
||||
return TRUE
|
||||
else if (iscyborg(hclient.client.mob))
|
||||
return (locate(/obj/machinery/computer/crew, range(world.view, hclient.client.mob))) || (locate(/obj/item/device/sensor_device, hclient.client.mob.contents))
|
||||
else
|
||||
return (locate(/obj/machinery/computer/crew, range(1, hclient.client.mob))) || (locate(/obj/item/device/sensor_device, hclient.client.mob.contents))
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/datum/crewmonitor/Topic(href, href_list[], datum/html_interface_client/hclient)
|
||||
if (istype(hclient))
|
||||
if (hclient && hclient.client && hclient.client.mob && isAI(hclient.client.mob))
|
||||
var/mob/living/silicon/ai/AI = hclient.client.mob
|
||||
|
||||
switch (href_list["action"])
|
||||
if ("select_person")
|
||||
AI.ai_camera_track(href_list["name"])
|
||||
|
||||
if ("select_position")
|
||||
var/x = text2num(href_list["x"])
|
||||
var/y = text2num(href_list["y"])
|
||||
var/turf/tile = locate(x, y, AI.z)
|
||||
|
||||
var/obj/machinery/camera/C = locate(/obj/machinery/camera) in range(5, tile)
|
||||
|
||||
if (!C)
|
||||
C = locate(/obj/machinery/camera) in urange(10, tile)
|
||||
if (!C)
|
||||
C = locate(/obj/machinery/camera) in urange(15, tile)
|
||||
|
||||
if (C)
|
||||
addtimer(CALLBACK(src, .proc/update_ai, AI, C, AI.eyeobj.loc), min(30, get_dist(get_turf(C), AI.eyeobj) / 4))
|
||||
|
||||
/datum/crewmonitor/proc/update_ai(mob/living/silicon/ai/AI, obj/machinery/camera/C, turf/current_loc)
|
||||
if (AI && AI.eyeobj && current_loc == AI.eyeobj.loc)
|
||||
AI.switchCamera(C)
|
||||
|
||||
/mob/living/carbon/human/Move()
|
||||
var/old_z = src.z
|
||||
. = ..()
|
||||
if (src.w_uniform)
|
||||
if (old_z != src.z)
|
||||
GLOB.crewmonitor.queueUpdate(old_z)
|
||||
GLOB.crewmonitor.queueUpdate(src.z)
|
||||
|
||||
/datum/crewmonitor/proc/queueUpdate(z)
|
||||
addtimer(CALLBACK(src, .proc/update, z), 5, TIMER_UNIQUE)
|
||||
|
||||
/datum/crewmonitor/proc/sendResources(var/client/client)
|
||||
send_asset(client, "crewmonitor.js")
|
||||
send_asset(client, "crewmonitor.css")
|
||||
SSminimap.send(client)
|
||||
#undef SENSORS_UPDATE_PERIOD
|
||||
@@ -1,588 +0,0 @@
|
||||
/*!
|
||||
* jQuery scrollintoview() plugin and :scrollable selector filter
|
||||
*
|
||||
* Version 1.8 (14 Jul 2011)
|
||||
* Requires jQuery 1.4 or newer
|
||||
*/
|
||||
|
||||
(function ($) {
|
||||
var converter = {
|
||||
vertical: { x: false, y: true },
|
||||
horizontal: { x: true, y: false },
|
||||
both: { x: true, y: true },
|
||||
x: { x: true, y: false },
|
||||
y: { x: false, y: true }
|
||||
};
|
||||
|
||||
var settings = {
|
||||
duration: "fast",
|
||||
direction: "both"
|
||||
};
|
||||
|
||||
var rootrx = /^(?:html)$/i;
|
||||
|
||||
// gets border dimensions
|
||||
var borders = function (domElement, styles) {
|
||||
styles = styles || (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(domElement, null) : domElement.currentStyle);
|
||||
var px = document.defaultView && document.defaultView.getComputedStyle ? true : false;
|
||||
var b = {
|
||||
top: (parseFloat(px ? styles.borderTopWidth : $.css(domElement, "borderTopWidth")) || 0),
|
||||
left: (parseFloat(px ? styles.borderLeftWidth : $.css(domElement, "borderLeftWidth")) || 0),
|
||||
bottom: (parseFloat(px ? styles.borderBottomWidth : $.css(domElement, "borderBottomWidth")) || 0),
|
||||
right: (parseFloat(px ? styles.borderRightWidth : $.css(domElement, "borderRightWidth")) || 0)
|
||||
};
|
||||
return {
|
||||
top: b.top,
|
||||
left: b.left,
|
||||
bottom: b.bottom,
|
||||
right: b.right,
|
||||
vertical: b.top + b.bottom,
|
||||
horizontal: b.left + b.right
|
||||
};
|
||||
};
|
||||
|
||||
var dimensions = function ($element) {
|
||||
var win = $(window);
|
||||
var isRoot = rootrx.test($element[0].nodeName);
|
||||
return {
|
||||
border: isRoot ? { top: 0, left: 0, bottom: 0, right: 0} : borders($element[0]),
|
||||
scroll: {
|
||||
top: (isRoot ? win : $element).scrollTop(),
|
||||
left: (isRoot ? win : $element).scrollLeft()
|
||||
},
|
||||
scrollbar: {
|
||||
right: isRoot ? 0 : $element.innerWidth() - $element[0].clientWidth,
|
||||
bottom: isRoot ? 0 : $element.innerHeight() - $element[0].clientHeight
|
||||
},
|
||||
rect: (function () {
|
||||
var r = $element[0].getBoundingClientRect();
|
||||
return {
|
||||
top: isRoot ? 0 : r.top,
|
||||
left: isRoot ? 0 : r.left,
|
||||
bottom: isRoot ? $element[0].clientHeight : r.bottom,
|
||||
right: isRoot ? $element[0].clientWidth : r.right
|
||||
};
|
||||
})()
|
||||
};
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
scrollintoview: function (options) {
|
||||
/// <summary>Scrolls the first element in the set into view by scrolling its closest scrollable parent.</summary>
|
||||
/// <param name="options" type="Object">Additional options that can configure scrolling:
|
||||
/// duration (default: "fast") - jQuery animation speed (can be a duration string or number of milliseconds)
|
||||
/// direction (default: "both") - select possible scrollings ("vertical" or "y", "horizontal" or "x", "both")
|
||||
/// complete (default: none) - a function to call when scrolling completes (called in context of the DOM element being scrolled)
|
||||
/// </param>
|
||||
/// <return type="jQuery">Returns the same jQuery set that this function was run on.</return>
|
||||
|
||||
options = $.extend({}, settings, options);
|
||||
options.direction = converter[typeof (options.direction) === "string" && options.direction.toLowerCase()] || converter.both;
|
||||
|
||||
var dirStr = "";
|
||||
if (options.direction.x === true) dirStr = "horizontal";
|
||||
if (options.direction.y === true) dirStr = dirStr ? "both" : "vertical";
|
||||
|
||||
var el = this.eq(0);
|
||||
var scroller = el.closest(":scrollable(" + dirStr + ")");
|
||||
|
||||
// check if there's anything to scroll in the first place
|
||||
if (scroller.length > 0)
|
||||
{
|
||||
scroller = scroller.eq(0);
|
||||
|
||||
var dim = {
|
||||
e: dimensions(el),
|
||||
s: dimensions(scroller)
|
||||
};
|
||||
|
||||
var rel = {
|
||||
top: dim.e.rect.top - (dim.s.rect.top + dim.s.border.top),
|
||||
bottom: dim.s.rect.bottom - dim.s.border.bottom - dim.s.scrollbar.bottom - dim.e.rect.bottom,
|
||||
left: dim.e.rect.left - (dim.s.rect.left + dim.s.border.left),
|
||||
right: dim.s.rect.right - dim.s.border.right - dim.s.scrollbar.right - dim.e.rect.right
|
||||
};
|
||||
|
||||
var animOptions = {};
|
||||
|
||||
// vertical scroll
|
||||
if (options.direction.y === true)
|
||||
{
|
||||
if (rel.top < 0)
|
||||
{
|
||||
animOptions.scrollTop = dim.s.scroll.top + rel.top;
|
||||
}
|
||||
else if (rel.top > 0 && rel.bottom < 0)
|
||||
{
|
||||
animOptions.scrollTop = dim.s.scroll.top + Math.min(rel.top, -rel.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
// horizontal scroll
|
||||
if (options.direction.x === true)
|
||||
{
|
||||
if (rel.left < 0)
|
||||
{
|
||||
animOptions.scrollLeft = dim.s.scroll.left + rel.left;
|
||||
}
|
||||
else if (rel.left > 0 && rel.right < 0)
|
||||
{
|
||||
animOptions.scrollLeft = dim.s.scroll.left + Math.min(rel.left, -rel.right);
|
||||
}
|
||||
}
|
||||
|
||||
// scroll if needed
|
||||
if (!$.isEmptyObject(animOptions))
|
||||
{
|
||||
if (rootrx.test(scroller[0].nodeName))
|
||||
{
|
||||
scroller = $("html,body");
|
||||
}
|
||||
scroller
|
||||
.animate(animOptions, options.duration)
|
||||
.eq(0) // we want function to be called just once (ref. "html,body")
|
||||
.queue(function (next) {
|
||||
$.isFunction(options.complete) && options.complete.call(scroller[0]);
|
||||
next();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// when there's nothing to scroll, just call the "complete" function
|
||||
$.isFunction(options.complete) && options.complete.call(scroller[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// return set back
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var scrollValue = {
|
||||
auto: true,
|
||||
scroll: true,
|
||||
visible: false,
|
||||
hidden: false
|
||||
};
|
||||
|
||||
$.extend($.expr[":"], {
|
||||
scrollable: function (element, index, meta, stack) {
|
||||
var direction = converter[typeof (meta[3]) === "string" && meta[3].toLowerCase()] || converter.both;
|
||||
var styles = (document.defaultView && document.defaultView.getComputedStyle ? document.defaultView.getComputedStyle(element, null) : element.currentStyle);
|
||||
var overflow = {
|
||||
x: scrollValue[styles.overflowX.toLowerCase()] || false,
|
||||
y: scrollValue[styles.overflowY.toLowerCase()] || false,
|
||||
isRoot: rootrx.test(element.nodeName)
|
||||
};
|
||||
|
||||
// check if completely unscrollable (exclude HTML element because it's special)
|
||||
if (!overflow.x && !overflow.y && !overflow.isRoot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var size = {
|
||||
height: {
|
||||
scroll: element.scrollHeight,
|
||||
client: element.clientHeight
|
||||
},
|
||||
width: {
|
||||
scroll: element.scrollWidth,
|
||||
client: element.clientWidth
|
||||
},
|
||||
// check overflow.x/y because iPad (and possibly other tablets) don't dislay scrollbars
|
||||
scrollableX: function () {
|
||||
return (overflow.x || overflow.isRoot) && this.width.scroll > this.width.client;
|
||||
},
|
||||
scrollableY: function () {
|
||||
return (overflow.y || overflow.isRoot) && this.height.scroll > this.height.client;
|
||||
}
|
||||
};
|
||||
return direction.y && size.scrollableY() || direction.x && size.scrollableX();
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
/*!
|
||||
* Crew manifest script
|
||||
*/
|
||||
|
||||
var minimap_height = 480;
|
||||
var scale_x;
|
||||
var scale_y;
|
||||
var zoom_factor = null;
|
||||
var minimap_mousedown = false;
|
||||
var minimap_mousedown_scrollLeft;
|
||||
var minimap_mousedown_scrollTop;
|
||||
var minimap_mousedown_clientX;
|
||||
var minimap_mousedown_clientY;
|
||||
var minimap_mousedown_counter = 0;
|
||||
|
||||
function disableSelection(){ return false; };
|
||||
|
||||
$(window).on("onUpdateContent", function()
|
||||
{
|
||||
$("#textbased").html("<table><colgroup><col /><col style=\"width: 24px;\" class=\"colhealth\" /><col style=\"width: 180px;\" /></colgroup><thead><tr><td><h3>Name</h3></td><td><h3> </h3></td><td><h3>Position</h3></td></tr></thead><tbody id=\"textbased-tbody\"></tbody></table>");
|
||||
|
||||
$("#minimap").append("<img src=\"minimap_" + z + ".png\" id=\"map\" style=\"width: auto; height: " + minimap_height + "px;\" />");
|
||||
|
||||
$("body")[0].onselectstart = disableSelection;
|
||||
|
||||
$("#minimap").on("click", function(e)
|
||||
{
|
||||
if (!$(e.target).is(".zoom,.dot"))
|
||||
{
|
||||
var x = ((((e.clientX + this.scrollLeft - 8) / scale_x) / tile_size) + 1).toFixed(0);
|
||||
var y = ((maxy - (((e.clientY + this.scrollTop - 8) / scale_y) / tile_size)) + 1).toFixed(0);
|
||||
|
||||
window.location.href = "byond://?src=" + hSrc + "&action=select_position&x=" + x + "&y=" + y;
|
||||
}
|
||||
}).on("mousedown", function(e)
|
||||
{
|
||||
minimap_mousedown_scrollLeft = this.scrollLeft;
|
||||
minimap_mousedown_scrollTop = this.scrollTop;
|
||||
minimap_mousedown_clientX = e.clientX;
|
||||
minimap_mousedown_clientY = e.clientY;
|
||||
|
||||
var c = ++minimap_mousedown_counter;
|
||||
setTimeout(function()
|
||||
{
|
||||
if (c == minimap_mousedown_counter)
|
||||
{
|
||||
minimap_mousedown = true;
|
||||
$("#minimap").css("cursor", "move");
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$(document).on("mousemove", function(e)
|
||||
{
|
||||
if (minimap_mousedown)
|
||||
{
|
||||
var offsetX = minimap_mousedown_clientX - e.clientX;
|
||||
var offsetY = minimap_mousedown_clientY - e.clientY;
|
||||
|
||||
var minimap = document.getElementById("minimap");
|
||||
minimap.scrollLeft = minimap_mousedown_scrollLeft + offsetX;
|
||||
minimap.scrollTop = minimap_mousedown_scrollTop + offsetY;
|
||||
}
|
||||
}).on("mouseup", function()
|
||||
{
|
||||
++minimap_mousedown_counter;
|
||||
if (minimap_mousedown)
|
||||
{
|
||||
document.body.focus();
|
||||
minimap_mousedown = false;
|
||||
$("#minimap").css("cursor", "");
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on("resize", onResize);
|
||||
|
||||
scaleMinimap(1.00);
|
||||
});
|
||||
|
||||
function zoomIn()
|
||||
{
|
||||
scaleMinimap(Math.min(6.00, zoom_factor + 1.00));
|
||||
}
|
||||
|
||||
function zoomOut()
|
||||
{
|
||||
scaleMinimap(Math.max(1.00, zoom_factor - 1.00));
|
||||
}
|
||||
|
||||
function scaleMinimap(factor)
|
||||
{
|
||||
var $minimap = $("#minimap");
|
||||
|
||||
if (factor != zoom_factor)
|
||||
{
|
||||
zoom_factor = factor;
|
||||
|
||||
var old_map_width = $minimap.width();
|
||||
var old_map_height = $minimap.height();
|
||||
var old_canvas_size = $("#minimap > img").height(); // height is assumed to be the same
|
||||
var new_canvas_size = minimap_height * factor; // ditto
|
||||
|
||||
var old_scrollLeft = $minimap[0].scrollLeft;
|
||||
var old_scrollTop = $minimap[0].scrollTop;
|
||||
|
||||
var old_factor = old_canvas_size / minimap_height;
|
||||
var diff_factor = factor - old_factor;
|
||||
|
||||
var old_centerX = ((old_map_width / 2) * diff_factor) + old_scrollLeft;
|
||||
var old_centerY = ((old_map_height / 2) * diff_factor) + old_scrollTop;
|
||||
|
||||
$("#minimap > img").css("height", new_canvas_size + "px");
|
||||
$minimap.css("max-width", new_canvas_size + "px");
|
||||
|
||||
var new_map_width = $minimap.width();
|
||||
var new_map_height = $minimap.height();
|
||||
|
||||
var new_centerX = (new_map_width / 2) + old_centerX;
|
||||
var new_centerY = (new_map_height / 2) + old_centerY;
|
||||
|
||||
var scrollLeft = new_centerX - (new_map_width / 2);
|
||||
var scrollTop = new_centerY - (new_map_height / 2);
|
||||
|
||||
scale_x = new_canvas_size / (maxx * tile_size);
|
||||
scale_y = new_canvas_size / (maxy * tile_size);
|
||||
|
||||
onResize();
|
||||
|
||||
$minimap[0].scrollLeft = scrollLeft;
|
||||
$minimap[0].scrollTop = scrollTop;
|
||||
|
||||
$(".dot").each(function()
|
||||
{
|
||||
var $this = $(this);
|
||||
var tx = translateX(parseInt($this.attr("data-x")));
|
||||
var ty = translateY(parseInt($this.attr("data-y")));
|
||||
|
||||
// Workaround for IE bug where it doesn't modify the positions.
|
||||
setTimeout(function(){ $this.css({ "top": ty + "px", "left": tx + "px" });}, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onResize()
|
||||
{
|
||||
if (zoom_factor == 1.00)
|
||||
{
|
||||
$(".zoom").css("left", "442px");
|
||||
$("#minimap").css("max-height", Math.min($(window).height() - 16, 480) + "px");
|
||||
}
|
||||
else
|
||||
{
|
||||
$(".zoom").css("left", ($("#minimap").width() - 34) + "px");
|
||||
$("#minimap").css("max-height", Math.min($(window).height() - 16, $("#minimap > img").height()) + "px");
|
||||
}
|
||||
|
||||
if (expandHealth())
|
||||
{
|
||||
$(".colhealth").css("width", "150px");
|
||||
$(".health").removeClass("tt");
|
||||
}
|
||||
else
|
||||
{
|
||||
$(".colhealth").css("width", "24px");
|
||||
$(".health").addClass("tt");
|
||||
}
|
||||
|
||||
$("body").css("padding-left", Math.min($(window).width() - 400, $("#minimap").width() - 10) + "px");
|
||||
}
|
||||
|
||||
function expandHealth()
|
||||
{
|
||||
return $("#textbased").width() > 510;
|
||||
}
|
||||
|
||||
var updateMap = true;
|
||||
|
||||
function switchTo(i)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
$("#minimap").hide();
|
||||
$("#textbased").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#textbased").hide();
|
||||
$("#minimap").show();
|
||||
}
|
||||
}
|
||||
|
||||
var orig_scrollTop = 0;
|
||||
|
||||
function clearAll()
|
||||
{
|
||||
orig_scrollTop = $(window).scrollTop();
|
||||
$("#textbased-tbody").empty();
|
||||
$("#minimap .dot").remove();
|
||||
}
|
||||
|
||||
function onAfterUpdate()
|
||||
{
|
||||
$(window).scrollTop(orig_scrollTop);
|
||||
}
|
||||
|
||||
function isHead(ijob)
|
||||
{
|
||||
return (ijob % 10 == 0); // head roles always end in 0
|
||||
}
|
||||
|
||||
function getColor(ijob)
|
||||
{
|
||||
if (ijob == 0) { return "#C06616"; } // captain
|
||||
else if (ijob >= 10 && ijob < 20) { return "#E74C3C"; } // security
|
||||
else if (ijob >= 20 && ijob < 30) { return "#3498DB"; } // medical
|
||||
else if (ijob >= 30 && ijob < 40) { return "#9B59B6"; } // science
|
||||
else if (ijob >= 40 && ijob < 50) { return "#F1C40F"; } // engineering
|
||||
else if (ijob >= 50 && ijob < 60) { return "#F39C12"; } // cargo
|
||||
else if (ijob >= 200 && ijob < 230) { return "#00C100"; } // CentCom
|
||||
else { return "#C38312"; } // other / unknown
|
||||
}
|
||||
|
||||
function add(name, assignment, ijob, life_status, dam1, dam2, dam3, dam4, area, pos_x, pos_y, in_range)
|
||||
{
|
||||
try { ijob = parseInt(ijob); }
|
||||
catch (ex) { ijob = 0; }
|
||||
|
||||
var ls = "";
|
||||
|
||||
if (life_status === null) { ls = (life_status ? "<span class=\"bad\">Deceased</span>" : "<span class=\"good\">Living</span>"); }
|
||||
|
||||
var healthHTML = "";
|
||||
|
||||
if (dam1 != "" || dam2 != "" || dam3 != "" || dam4 != "")
|
||||
{
|
||||
var avg_dam = parseInt(dam1) + parseInt(dam2) + parseInt(dam3) + parseInt(dam4);
|
||||
var i;
|
||||
|
||||
if (avg_dam <= 0) { i = 5; }
|
||||
else if (avg_dam <= 25) { i = 4; }
|
||||
else if (avg_dam <= 50) { i = 3; }
|
||||
else if (avg_dam <= 75) { i = 2; }
|
||||
else { i = 0; }
|
||||
|
||||
healthHTML = "<div class=\"health health-" + i + (expandHealth() ? "" : " tt") + "\"><div><span>(<font color=\"#3498db\">" + dam1 + "</font>/<font color=\"#2ecc71\">" + dam2 + "</font>/<font color=\"#e67e22\">" + dam3 + "</font>/<font color=\"#e74c3c\">" + dam4 + "</font>)</span></div></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
healthHTML = "<div class=\"health health-" + (life_status == "" ? -1 : (life_status == "true" ? 4 : 0)) + (expandHealth() ? "" : " tt") + "\"><div><span>Not Available</span></div></div>";
|
||||
}
|
||||
|
||||
var trElem = $("<tr></tr>").attr("data-ijob", ijob);
|
||||
var tdElem;
|
||||
var spanElem;
|
||||
|
||||
tdElem = $("<td></td>");
|
||||
|
||||
var italics = false;
|
||||
|
||||
if (name.length >= 7 && name.substring(0, 3) == "<i>")
|
||||
{
|
||||
name = name.substring(3, name.length - 4);
|
||||
italics = true;
|
||||
}
|
||||
|
||||
spanElem = $("<span></span>").text(name);
|
||||
|
||||
if (italics)
|
||||
{
|
||||
spanElem.css("font-style", "italic");
|
||||
}
|
||||
|
||||
if (isHead(ijob)) { spanElem.css("font-weight", "bold"); }
|
||||
|
||||
var color = getColor(ijob);
|
||||
|
||||
if (color) { spanElem.css("color", color); }
|
||||
|
||||
tdElem.append(spanElem);
|
||||
|
||||
if (assignment) { tdElem.append($("<span></span>").text(" (" + assignment + ")")); }
|
||||
|
||||
trElem.append(tdElem);
|
||||
|
||||
tdElem = $("<td style=\"vertical-align: top; cursor: default;\"></td>");
|
||||
tdElem.html(healthHTML);
|
||||
|
||||
trElem.append(tdElem);
|
||||
|
||||
tdElem = $("<td style=\"cursor: default;\"></td>");
|
||||
|
||||
if (area && pos_x && pos_y)
|
||||
{
|
||||
tdElem.append($("<div></div>").text(area).addClass("tt").append($("<div></div>").append($("<span></span>").text("(" + pos_x + ", " + pos_y + ")"))));
|
||||
tdElem.css("cursor", "pointer").on("click", function()
|
||||
{
|
||||
window.clipboardData.setData("Text", pos_x + ", " + pos_y);
|
||||
});
|
||||
}
|
||||
else { tdElem.text("Not Available"); }
|
||||
|
||||
trElem.append(tdElem);
|
||||
|
||||
var item = $("#textbased-tbody > tr").filter(function(){ return parseInt($(this).attr("data-ijob")) >= ijob; }).eq(0);
|
||||
|
||||
if (item.length > 0) { trElem.insertBefore(item); }
|
||||
else { $("#textbased-tbody").append(trElem); }
|
||||
|
||||
if (updateMap && pos_x && pos_y && (in_range == "1"))
|
||||
{
|
||||
var x = parseInt(pos_x);
|
||||
var y = maxy - parseInt(pos_y);
|
||||
|
||||
var tx = translateX(x);
|
||||
var ty = translateY(y);
|
||||
|
||||
var dotElem = $("<div class=\"dot\" style=\"top: " + ty + "px; left: " + tx + "px; background-color: " + color + "; z-index: " + ijob + ";\" data-x=\"" + x + "\" data-y=\"" + y + "\"></div>");
|
||||
|
||||
$("#minimap").append(dotElem);
|
||||
|
||||
var counter = 0;
|
||||
|
||||
function enable()
|
||||
{
|
||||
++counter;
|
||||
dotElem.addClass("active").css({ "border-color": color });
|
||||
}
|
||||
|
||||
function disable()
|
||||
{
|
||||
++counter;
|
||||
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);
|
||||
}
|
||||
|
||||
trElem.on("mouseover", function()
|
||||
{
|
||||
enable();
|
||||
|
||||
if (zoom_factor > 1.00)
|
||||
{
|
||||
var c = counter;
|
||||
setTimeout(function()
|
||||
{
|
||||
if (c == counter)
|
||||
{
|
||||
var minimap = document.getElementById("minimap");
|
||||
var half = $(minimap).height() / 2;
|
||||
var offset = $(dotElem).offset();
|
||||
|
||||
minimap.scrollLeft = offset.left + minimap.scrollLeft - half;
|
||||
minimap.scrollTop = offset.top + minimap.scrollTop - half;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}).on("mouseout", disable).on("click", click);
|
||||
dotElem.on("mouseover", function()
|
||||
{
|
||||
trElem.addClass("hover");
|
||||
enable();
|
||||
trElem.scrollintoview();
|
||||
}).on("mouseout", function()
|
||||
{
|
||||
trElem.removeClass("hover");
|
||||
disable();
|
||||
}).on("click", click);
|
||||
}
|
||||
}
|
||||
|
||||
function translateX(n) { return (translate(n - 1.5, scale_x) ).toFixed(0); }
|
||||
function translateY(n) { return (translate(n + 0.75, scale_y) ).toFixed(0); }
|
||||
|
||||
function translate(n, scale)
|
||||
{
|
||||
return (n * tile_size) * scale;
|
||||
}
|
||||
@@ -7,4 +7,4 @@
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/device/sensor_device/attack_self(mob/user)
|
||||
GLOB.crewmonitor.show(user) //Proc already exists, just had to call it
|
||||
GLOB.crewmonitor.show(user,src) //Proc already exists, just had to call it
|
||||
|
||||
Reference in New Issue
Block a user