mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
HTML UI Interfaces
# Version 1.0 THEY DON'T LAG LIKE NANOUI Only crew monitoring computer exists Doesn't display coordinate data that I've seen Takes a few seconds to populate with information as well None of the improvements/bugfixes have been applied yet
This commit is contained in:
105
code/modules/html_interface/crew/crew.css
Normal file
105
code/modules/html_interface/crew/crew.css
Normal file
@@ -0,0 +1,105 @@
|
||||
body
|
||||
{
|
||||
padding-left: 490px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#ntbgcenter
|
||||
{
|
||||
background-position: 550px 0px !important;
|
||||
}
|
||||
|
||||
#minimap
|
||||
{
|
||||
position: fixed;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
border: 2px inset #888;
|
||||
}
|
||||
|
||||
#textbased
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
a { display: none; }
|
||||
|
||||
.health
|
||||
{
|
||||
width: 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; }
|
||||
|
||||
.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;
|
||||
}
|
||||
567
code/modules/html_interface/crew/crew.dm
Normal file
567
code/modules/html_interface/crew/crew.dm
Normal file
@@ -0,0 +1,567 @@
|
||||
/obj/machinery/computer/crew
|
||||
name = "Crew monitoring computer"
|
||||
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
|
||||
icon_state = "crew"
|
||||
use_power = 1
|
||||
idle_power_usage = 250
|
||||
active_power_usage = 500
|
||||
circuit = "/obj/item/weapon/circuitboard/crew"
|
||||
var/list/tracked = list( )
|
||||
var/track_special_role
|
||||
|
||||
light_color = LIGHT_COLOR_BLUE
|
||||
light_range_on = 2
|
||||
|
||||
/obj/machinery/computer/crew/New()
|
||||
tracked = list()
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/crew/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/crew/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
crewmonitor.show(user)
|
||||
|
||||
/obj/machinery/computer/crew/update_icon()
|
||||
|
||||
if(stat & BROKEN)
|
||||
icon_state = "crewb"
|
||||
else
|
||||
if(stat & NOPOWER)
|
||||
src.icon_state = "c_unpowered"
|
||||
stat |= NOPOWER
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
stat &= ~NOPOWER
|
||||
|
||||
var/global/datum/crewmonitor/crewmonitor = new
|
||||
|
||||
/datum/crewmonitor
|
||||
var/list/jobs
|
||||
var/list/interfaces
|
||||
var/list/data
|
||||
var/const/MAX_ICON_DIMENSION = 1024
|
||||
var/const/ICON_SIZE = 4
|
||||
var/initialized = FALSE
|
||||
|
||||
/datum/crewmonitor/New()
|
||||
. = ..()
|
||||
|
||||
var/list/jobs = new/list()
|
||||
jobs["Captain"] = 00
|
||||
jobs["Head of Personnel"] = 50
|
||||
jobs["Head of Security"] = 10
|
||||
jobs["Warden"] = 11
|
||||
jobs["Security Officer"] = 12
|
||||
jobs["Detective"] = 13
|
||||
jobs["Chief Medical Officer"] = 20
|
||||
jobs["Chemist"] = 21
|
||||
jobs["Geneticist"] = 22
|
||||
jobs["Virologist"] = 23
|
||||
jobs["Medical Doctor"] = 24
|
||||
jobs["Research Director"] = 30
|
||||
jobs["Scientist"] = 31
|
||||
jobs["Roboticist"] = 32
|
||||
jobs["Chief Engineer"] = 40
|
||||
jobs["Station Engineer"] = 41
|
||||
jobs["Atmospheric Technician"] = 42
|
||||
jobs["Quartermaster"] = 51
|
||||
jobs["Shaft Miner"] = 52
|
||||
jobs["Cargo Technician"] = 53
|
||||
jobs["Bartender"] = 61
|
||||
jobs["Cook"] = 62
|
||||
jobs["Botanist"] = 63
|
||||
jobs["Librarian"] = 64
|
||||
jobs["Chaplain"] = 65
|
||||
jobs["Clown"] = 66
|
||||
jobs["Mime"] = 67
|
||||
jobs["Janitor"] = 68
|
||||
jobs["Lawyer"] = 69
|
||||
jobs["Admiral"] = 200
|
||||
jobs["Centcom Commander"] = 210
|
||||
jobs["Custodian"] = 211
|
||||
jobs["Medical Officer"] = 212
|
||||
jobs["Research Officer"] = 213
|
||||
jobs["Emergency Response Team Commander"] = 220
|
||||
jobs["Security Response Officer"] = 221
|
||||
jobs["Engineer Response Officer"] = 222
|
||||
jobs["Medical Response Officer"] = 223
|
||||
jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants
|
||||
|
||||
src.jobs = jobs
|
||||
src.interfaces = list()
|
||||
src.data = list()
|
||||
|
||||
/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 (!z) z = mob.z
|
||||
|
||||
if (z > 0 && src.interfaces)
|
||||
var/datum/html_interface/hi
|
||||
|
||||
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>")
|
||||
|
||||
hi = src.interfaces["[z]"]
|
||||
|
||||
hi.updateContent("content", "<a href=\"javascript:switchTo(0);\">Switch to mini map</a> <a href=\"javascript:switchTo(1);\">Switch to text-based</a><div id=\"minimap\"></div><div id=\"textbased\"></div>")
|
||||
|
||||
src.update(z, TRUE)
|
||||
else
|
||||
hi = src.interfaces["[z]"]
|
||||
|
||||
hi = src.interfaces["[z]"]
|
||||
hi.show(mob)
|
||||
src.updateFor(mob, hi, z)
|
||||
|
||||
/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.
|
||||
var/list/parameters = list(ismob(hclient_or_mob) && isAI(hclient_or_mob) ? "true" : "false")
|
||||
|
||||
hi.callJavaScript("clearAll", parameters, hclient_or_mob)
|
||||
|
||||
for (var/list/L in data)
|
||||
hi.callJavaScript("add", L, hclient_or_mob)
|
||||
|
||||
/datum/crewmonitor/proc/update(z, ignore_unused = FALSE)
|
||||
if (src.interfaces["[z]"])
|
||||
var/datum/html_interface/hi = src.interfaces["[z]"]
|
||||
|
||||
if (ignore_unused || hi.isUsed())
|
||||
var/list/results = list()
|
||||
var/obj/item/clothing/under/U
|
||||
var/obj/item/weapon/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
|
||||
|
||||
for(var/mob/living/carbon/human/H in mob_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
|
||||
|
||||
// Are the suit sensors on?
|
||||
if (U.has_sensor && U.sensor_mode)
|
||||
pos = H.z == 0 || U.sensor_mode == 3 ? get_turf(H) : null
|
||||
|
||||
// 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
|
||||
|
||||
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 >= 1) life_status = (!H.stat ? "true" : "false")
|
||||
else life_status = null
|
||||
|
||||
if (U.sensor_mode >= 2)
|
||||
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 >= 3)
|
||||
if (!pos) pos = get_turf(H)
|
||||
var/area/player_area = get_area(H)
|
||||
|
||||
area = format_text(player_area.name)
|
||||
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())
|
||||
|
||||
src.data = results
|
||||
src.updateFor(null, hi, z) // updates for everyone
|
||||
|
||||
/mob/living/carbon/human/proc/can_track()
|
||||
//basic fast checks go first. When overriding this proc, I recommend calling ..() at the end.
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T)
|
||||
return 0
|
||||
if(T.z == CENTCOMM_Z) //dont detect mobs on centcomm
|
||||
return 0
|
||||
if(T.z >= map.zLevels.len)
|
||||
return 0
|
||||
. = 1
|
||||
|
||||
/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
|
||||
|
||||
return (hclient.client.mob && hclient.client.mob.stat == 0 && hclient.client.mob.z == text2num(z) && ( isAI(hclient.client.mob) || (locate(/obj/machinery/computer/crew, range(1, hclient.client.mob))) ) )
|
||||
|
||||
/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 range(10, tile)
|
||||
if (!C) C = locate(/obj/machinery/camera) in range(15, tile)
|
||||
|
||||
if (C)
|
||||
var/turf/current_loc = AI.eyeobj.loc
|
||||
|
||||
spawn(min(30, get_dist(get_turf(C), AI.eyeobj) / 4))
|
||||
if (AI && AI.eyeobj && current_loc == AI.eyeobj.loc)
|
||||
AI.switchCamera(C)
|
||||
|
||||
/mob/living/carbon/human/Move()
|
||||
if(src.w_uniform)
|
||||
var/old_z = src.z
|
||||
|
||||
. = ..()
|
||||
|
||||
if (old_z != src.z) crewmonitor.queueUpdate(old_z)
|
||||
crewmonitor.queueUpdate(src.z)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/datum/crewmonitor/proc/queueUpdate(z)
|
||||
var/datum/controller/process/html/html = processScheduler.getProcess("html")
|
||||
html.queue(crewmonitor, "update", z)
|
||||
|
||||
/datum/crewmonitor/proc/generateMiniMaps()
|
||||
spawn
|
||||
for (var/z = 1 to world.maxz) src.generateMiniMap(z)
|
||||
|
||||
testing("MINIMAP: All minimaps have been generated.")
|
||||
|
||||
for (var/client/C in clients)
|
||||
src.sendResources(C)
|
||||
|
||||
src.initialized = TRUE
|
||||
|
||||
/datum/crewmonitor/proc/sendResources(client/C)
|
||||
C << browse_rsc('crew.js', "crewmonitor.js")
|
||||
C << browse_rsc('crew.css', "crewmonitor.css")
|
||||
for (var/z = 1 to world.maxz) C << browse_rsc(file("[getMinimapFile(z)].png"), "minimap_[z].png")
|
||||
|
||||
/datum/crewmonitor/proc/getMinimapFile(z)
|
||||
return "data/minimaps/map_[z]"
|
||||
|
||||
// Activate this to debug tile mismatches in the minimap.
|
||||
// This will store the full information on each tile and compare it the next time you run the minimap.
|
||||
// It can be used to find out what's changed since the last iteration.
|
||||
// Only activate this when you need it - this should never be active on a live server!
|
||||
// #define MINIMAP_DEBUG
|
||||
|
||||
/datum/crewmonitor/proc/generateMiniMap(z, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
|
||||
var/result_path = "[src.getMinimapFile(z)].png"
|
||||
var/hash_path = "[src.getMinimapFile(z)].md5"
|
||||
var/list/tiles = block(locate(x1, y1, z), locate(x2, y2, z))
|
||||
var/hash = ""
|
||||
var/temp
|
||||
var/obj/obj
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
var/tiledata_path = "data/minimaps/debug_tiledata_[z].sav"
|
||||
var/savefile/F = new/savefile(tiledata_path)
|
||||
#endif
|
||||
|
||||
// Note for future developer: If you have tiles on the map with random or dynamic icons this hash check will fail
|
||||
// every time. You'll have to modify this code to generate a unique hash for your object.
|
||||
// Don't forget to modify the minimap generation code to use a default icon (or skip generation altogether).
|
||||
for (var/turf/tile in tiles)
|
||||
if (istype(tile.loc, /area/asteroid) || istype(tile.loc, /area/mine/unexplored) || istype(tile, /turf/unsimulated/mineral) || (tile.loc.name == "Space" && istype(tile, /turf/unsimulated/floor/asteroid)))
|
||||
temp = "/area/asteroid"
|
||||
else if (istype(tile.loc, /area/mine) && istype(tile, /turf/unsimulated/floor/asteroid))
|
||||
temp = "/area/mine/explored"
|
||||
else if (tile.loc.type == /area/start || (tile.type == /turf/space && !(locate(/obj/structure/lattice) in tile)) || istype(tile, /turf/space/transit))
|
||||
temp = "/turf/space"
|
||||
if (locate(/obj/structure/catwalk) in tile)
|
||||
|
||||
else
|
||||
else if (tile.type == /turf/space)
|
||||
if (locate(/obj/structure/catwalk) in tile)
|
||||
temp = "/obj/structure/lattice/catwalk"
|
||||
else
|
||||
temp = "/obj/structure/lattice"
|
||||
else if (tile.type == /turf/simulated/floor/plating && (locate(/obj/structure/shuttle/window) in tile))
|
||||
temp = "/obj/structure/window/shuttle"
|
||||
else
|
||||
temp = "[tile.icon][tile.icon_state][tile.dir]"
|
||||
|
||||
obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
if (obj) temp = "[temp]/obj/structure/transit_tube[obj.icon_state][obj.dir]"
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
if (F["/[tile.y]/[tile.x]"] && F["/[tile.y]/[tile.x]"] != temp)
|
||||
CRASH("Mismatch: [tile.type] at [tile.x],[tile.y],[tile.z] ([tile.icon], [tile.icon_state], [tile.dir])")
|
||||
else
|
||||
F["/[tile.y]/[tile.x]"] << temp
|
||||
#endif
|
||||
|
||||
hash = md5("[hash][temp]")
|
||||
|
||||
if (fexists(result_path))
|
||||
if (!fexists(hash_path) || trim(file2text(hash_path)) != hash)
|
||||
fdel(result_path)
|
||||
fdel(hash_path)
|
||||
|
||||
if (!fexists(result_path))
|
||||
ASSERT(x1 > 0)
|
||||
ASSERT(y1 > 0)
|
||||
ASSERT(x2 <= world.maxx)
|
||||
ASSERT(y2 <= world.maxy)
|
||||
|
||||
var/icon/map_icon = new/icon('html/mapbase1024.png')
|
||||
|
||||
// map_icon is fine and contains only 1 direction at this point.
|
||||
|
||||
ASSERT(map_icon.Width() == MAX_ICON_DIMENSION && map_icon.Height() == MAX_ICON_DIMENSION)
|
||||
|
||||
testing("MINIMAP: Generating minimap for z-level [z].")
|
||||
|
||||
var/i = 0
|
||||
var/icon/turf_icon
|
||||
var/icon/obj_icon
|
||||
var/old_icon
|
||||
var/old_icon_state
|
||||
var/old_dir
|
||||
var/new_icon
|
||||
var/new_icon_state
|
||||
var/new_dir
|
||||
|
||||
for (var/turf/tile in tiles)
|
||||
if (tile.loc.type != /area/start && (tile.type != /turf/space || (locate(/obj/structure/lattice) in tile) || (locate(/obj/structure/transit_tube) in tile)) && !istype(tile, /turf/space/transit))
|
||||
if (istype(tile.loc, /area/asteroid) || istype(tile.loc, /area/mine/unexplored) || istype(tile, /turf/unsimulated/mineral) || (tile.loc.name == "Space" && istype(tile, /turf/unsimulated/floor/asteroid)))
|
||||
new_icon = 'icons/turf/walls.dmi'
|
||||
new_icon_state = "rock"
|
||||
new_dir = 2
|
||||
else if (istype(tile.loc, /area/mine) && istype(tile, /turf/unsimulated/floor/asteroid))
|
||||
new_icon = 'icons/turf/floors.dmi'
|
||||
new_icon_state = "asteroid"
|
||||
new_dir = 2
|
||||
else if (tile.type == /turf/space)
|
||||
obj = locate(/obj/structure/lattice) in tile
|
||||
|
||||
if (!obj) obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
ASSERT(obj != null)
|
||||
|
||||
if (obj)
|
||||
new_icon = obj.icon
|
||||
new_dir = obj.dir
|
||||
new_icon_state = obj.icon_state
|
||||
else if (tile.type == /turf/simulated/floor/plating && (locate(/obj/structure/shuttle/window) in tile))
|
||||
new_icon = 'icons/obj/structures.dmi'
|
||||
new_dir = 2
|
||||
new_icon_state = "swindow"
|
||||
else
|
||||
new_icon = tile.icon
|
||||
new_icon_state = tile.icon_state
|
||||
new_dir = tile.dir
|
||||
|
||||
if (new_icon != old_icon || new_icon_state != old_icon_state || new_dir != old_dir)
|
||||
old_icon = new_icon
|
||||
old_icon_state = new_icon_state
|
||||
old_dir = new_dir
|
||||
|
||||
turf_icon = new/icon(new_icon, new_icon_state, new_dir, 1, 0)
|
||||
turf_icon.Scale(ICON_SIZE, ICON_SIZE)
|
||||
|
||||
if (tile.type != /turf/space || (locate(/obj/structure/lattice) in tile))
|
||||
obj = locate(/obj/structure/transit_tube) in tile
|
||||
|
||||
if (obj)
|
||||
obj_icon = new/icon(obj.icon, obj.icon_state, obj.dir, 1, 0)
|
||||
obj_icon.Scale(ICON_SIZE, ICON_SIZE)
|
||||
turf_icon.Blend(obj_icon, ICON_OVERLAY)
|
||||
|
||||
map_icon.Blend(turf_icon, ICON_OVERLAY, ((tile.x - 1) * ICON_SIZE), ((tile.y - 1) * ICON_SIZE))
|
||||
|
||||
if ((++i) % 512 == 0) sleep(1) // deliberate delay to avoid lag spikes
|
||||
|
||||
if ((i % 1024) == 0) testing("MINIMAP: Generated [i] of [tiles.len] tiles.")
|
||||
else
|
||||
sleep(-1) // avoid sleeping if possible: prioritize pending procs
|
||||
|
||||
testing("MINIMAP: Generated [tiles.len] of [tiles.len] tiles.")
|
||||
|
||||
// BYOND BUG: map_icon now contains 4 directions? Create a new icon with only a single state.
|
||||
var/icon/result_icon = new/icon()
|
||||
|
||||
result_icon.Insert(map_icon, "", SOUTH, 1, 0)
|
||||
|
||||
fcopy(result_icon, result_path)
|
||||
text2file(hash, hash_path)
|
||||
|
||||
#ifdef MINIMAP_DEBUG
|
||||
#undef MINIMAP_DEBUG
|
||||
#endif
|
||||
/*
|
||||
/obj/machinery/computer/crew/interact(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
user.set_machine(src)
|
||||
src.scan()
|
||||
|
||||
var/data[0]
|
||||
var/list/crewmembers = list()
|
||||
|
||||
for(var/mob/living/carbon/brain/B in mob_list)
|
||||
var/turf/pos = get_turf(B)
|
||||
if(!pos) continue
|
||||
var/obj/item/device/mmi/M = B.loc
|
||||
if(istype(M) && M.brainmob == B)
|
||||
if(isrobot(M.loc))
|
||||
continue
|
||||
var/list/crewmemberData = list()
|
||||
crewmemberData["sensor_type"] = 3
|
||||
crewmemberData["dead"] = 0
|
||||
crewmemberData["oxy"] = 0
|
||||
crewmemberData["tox"] = 0
|
||||
crewmemberData["fire"] = 0
|
||||
crewmemberData["brute"] = 0
|
||||
crewmemberData["name"] = M.name
|
||||
crewmemberData["rank"] = "Unknown"
|
||||
crewmemberData["area"] = get_area(M)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
crewmemberData["z"] = pos.z
|
||||
crewmemberData["xoffset"] = pos.x-WORLD_X_OFFSET[pos.z]
|
||||
crewmemberData["yoffset"] = pos.y-WORLD_Y_OFFSET[pos.z]
|
||||
crewmembers += list(crewmemberData)
|
||||
|
||||
|
||||
for(var/obj/item/clothing/under/C in src.tracked)
|
||||
|
||||
var/turf/pos = get_turf(C)
|
||||
|
||||
if((C) && (C.has_sensor) && (pos) && (pos.z != CENTCOMM_Z) && C.sensor_mode)
|
||||
if(istype(C.loc, /mob/living/carbon/human))
|
||||
|
||||
var/mob/living/carbon/human/H = C.loc
|
||||
|
||||
var/list/crewmemberData = list()
|
||||
|
||||
crewmemberData["sensor_type"] = C.sensor_mode
|
||||
crewmemberData["dead"] = H.stat > 1
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
|
||||
|
||||
crewmemberData["name"] = "Unknown"
|
||||
crewmemberData["rank"] = "Unknown"
|
||||
if(H.wear_id && istype(H.wear_id, /obj/item/weapon/card/id) )
|
||||
var/obj/item/weapon/card/id/I = H.wear_id
|
||||
crewmemberData["name"] = I.name
|
||||
crewmemberData["rank"] = I.rank
|
||||
else if(H.wear_id && istype(H.wear_id, /obj/item/device/pda) )
|
||||
var/obj/item/device/pda/P = H.wear_id
|
||||
crewmemberData["name"] = (P.id ? P.id.name : "Unknown")
|
||||
crewmemberData["rank"] = (P.id ? P.id.rank : "Unknown")
|
||||
|
||||
crewmemberData["area"] = get_area(H)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
crewmemberData["z"] = pos.z
|
||||
crewmemberData["xoffset"] = pos.x-WORLD_X_OFFSET[pos.z]
|
||||
crewmemberData["yoffset"] = pos.y-WORLD_Y_OFFSET[pos.z]
|
||||
|
||||
crewmembers += list(crewmemberData)
|
||||
// Works around list += list2 merging lists; it's not pretty but it works
|
||||
//crewmembers += "temporary item"
|
||||
//crewmembers[crewmembers.len] = crewmemberData
|
||||
|
||||
crewmembers = sortList(crewmembers)
|
||||
|
||||
data["crewmembers"] = crewmembers
|
||||
|
||||
//ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui) // no ui has been passed, so we'll search for one
|
||||
ui = nanomanager.get_open_ui(user, src, ui_key)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800)
|
||||
|
||||
// adding a template with the key "mapContent" enables the map ui functionality
|
||||
ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
|
||||
// adding a template with the key "mapHeader" replaces the map header content
|
||||
ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
|
||||
|
||||
// we want to show the map by default
|
||||
ui.set_show_map(1)
|
||||
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
|
||||
// should make the UI auto-update; doesn't seem to?
|
||||
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/crew/proc/is_scannable(const/obj/item/clothing/under/C, const/mob/living/carbon/human/H)
|
||||
if(!istype(H) || H.iscorpse)
|
||||
return 0
|
||||
|
||||
if(isnull(track_special_role))
|
||||
return C.has_sensor
|
||||
|
||||
return (H.mind ? H.mind.special_role == track_special_role : 1)
|
||||
|
||||
/obj/machinery/computer/crew/proc/scan()
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
if (C.has_sensor)
|
||||
if(is_scannable(C, H))
|
||||
tracked |= C
|
||||
return 1*/
|
||||
196
code/modules/html_interface/crew/crew.js
Normal file
196
code/modules/html_interface/crew/crew.js
Normal file
@@ -0,0 +1,196 @@
|
||||
var isAI = null;
|
||||
var scale_x;
|
||||
var scale_y;
|
||||
|
||||
function disableSelection(){ return false; };
|
||||
|
||||
$(window).on("onUpdateContent", function()
|
||||
{
|
||||
$("#textbased").html("<table><colgroup><col /><col style=\"width: 24px;\" /><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: 480px;\" />");
|
||||
|
||||
$("body")[0].onselectstart = disableSelection;
|
||||
|
||||
var width = $("#minimap").width();
|
||||
|
||||
scale_x = width / (maxx * tile_size);
|
||||
scale_y = width / (maxy * tile_size); // height is assumed to be the same
|
||||
|
||||
$("#minimap").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;
|
||||
});
|
||||
});
|
||||
|
||||
var updateMap = true;
|
||||
|
||||
function switchTo(i)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
$("#minimap").hide();
|
||||
$("#textbased").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#textbased").hide();
|
||||
$("#minimap").show();
|
||||
}
|
||||
}
|
||||
|
||||
function clearAll(ai)
|
||||
{
|
||||
if (isAI === null) { isAI = (ai == "true"); }
|
||||
$("#textbased-tbody").empty();
|
||||
$("#minimap .dot").remove();
|
||||
}
|
||||
|
||||
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 (isAI) { i = -1; }
|
||||
else
|
||||
{
|
||||
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 + " 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)) + " 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=\"text-align: center; 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 + ")")))); }
|
||||
else { tdElem.text("Not Available"); }
|
||||
|
||||
trElem.append(tdElem);
|
||||
|
||||
$("#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 = (translate(x - 1, scale_x) - 1.5).toFixed(0);
|
||||
var ty = (translate(y - 1, scale_y) + 3).toFixed(0);
|
||||
|
||||
var dotElem = $("<div class=\"dot\" style=\"transition: .2s all; position: absolute; top: " + ty + "px; left: " + tx + "px; background-color: " + color + "; border: 1px solid transparent; width: 3px; height: 3px; z-index: " + ijob + ";\"></div>");
|
||||
|
||||
$("#minimap").append(dotElem);
|
||||
|
||||
function enable()
|
||||
{
|
||||
dotElem.css({ "border-color": color, "z-index": 9999, "width": "8px", "height": "8px", "margin-top": "-2px", "margin-left": "-3px" });
|
||||
}
|
||||
|
||||
function disable()
|
||||
{
|
||||
dotElem.css({ "border-color": "transparent", "z-index": ijob, "width": "3px", "height": "3px", "margin-top": "0px", "margin-left": "0px", "filter": "" });
|
||||
}
|
||||
|
||||
function click(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
window.location.href = "byond://?src=" + hSrc + "&action=select_person&name=" + encodeURIComponent(name);
|
||||
}
|
||||
|
||||
trElem.on("mouseover", enable).on("mouseout", disable).on("click", click);
|
||||
|
||||
dotElem.on("mouseover", function()
|
||||
{
|
||||
trElem.addClass("hover");
|
||||
enable();
|
||||
}).on("mouseout", function()
|
||||
{
|
||||
trElem.removeClass("hover");
|
||||
disable();
|
||||
}).on("click", click);
|
||||
}
|
||||
}
|
||||
|
||||
function translate(n, scale)
|
||||
{
|
||||
return (n * tile_size) * scale;
|
||||
}
|
||||
@@ -54,6 +54,10 @@ Hides the HTML interface from the provided client. This will close the browser w
|
||||
|
||||
Returns TRUE if the interface is being used (has an active client) or FALSE if not.
|
||||
|
||||
hi.closeAll()
|
||||
|
||||
Closes the interface on all clients.
|
||||
|
||||
** Additional notes **
|
||||
|
||||
When working with byond:// links make sure to reference the HTML interface object and NOT the original object. Topic() will still be called on
|
||||
@@ -68,12 +72,13 @@ mob/verb/test()
|
||||
if (!hi) hi = new/datum/html_interface(src, "[src.key]")
|
||||
|
||||
hi.updateLayout("<div id=\"content\"></div>")
|
||||
hi.updateContent("content", "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque porttitor, leo nec facilisis aliquam, elit ligula iaculis sapien, non vulputate neque metus id quam. Cras mauris nisl, pharetra malesuada massa nec, volutpat feugiat metus. Duis sed condimentum purus. In ex leo, laoreet ac rhoncus quis, volutpat ac risus. Ut et tempus magna. Vestibulum in nisl vitae metus commodo tempus et dapibus urna. Integer nec vestibulum lacus. Donec quis metus non lacus bibendum lacinia. Aenean tincidunt libero vestibulum metus blandit pharetra. Nunc quis magna volutpat, bibendum nulla in, sagittis risus. Sed id velit sodales, bibendum purus accumsan, eleifend purus.</p><p>Suspendisse potenti. Proin lorem orci, euismod at elit in, molestie dapibus leo. Nulla lacinia vel urna nec vulputate. Praesent non enim metus. Quisque non pharetra justo. Integer efficitur massa orci, vitae placerat libero eleifend sit amet. Fusce in placerat quam. Praesent quis lectus turpis. Aenean mattis lacus sed laoreet sagittis. Aliquam efficitur nisl at tellus ultrices auctor. Quisque hendrerit, mi quis suscipit interdum, justo magna gravida libero, et venenatis sapien ante quis odio.</p><p>Etiam ullamcorper condimentum lacus, eu laoreet ipsum gravida et. Fusce odio libero, iaculis euismod finibus sit amet, condimentum ac ante. Etiam pretium lorem mauris, sit amet varius tortor efficitur eget. Pellentesque at lacinia lectus. Integer tristique nibh hendrerit purus placerat dapibus. Cras elementum est elementum, bibendum orci nec, consequat elit. Fusce porttitor neque quis libero placerat, vel varius arcu aliquet. Aenean vitae rhoncus nunc, non tempus magna. Aliquam lacinia sit amet dolor id maximus. Curabitur eget eleifend nisl. Mauris interdum nibh feugiat lectus lacinia fringilla. Aliquam nec magna vel leo ultricies dignissim. Duis eu luctus odio, finibus dictum nulla.</p>Mauris fringilla a lorem vel euismod. Sed auctor eget lorem sed lacinia. Maecenas vel posuere sapien. In lobortis odio non tincidunt ultricies. Sed consequat molestie orci et pharetra. Suspendisse potenti. Vestibulum vitae ornare risus, nec semper arcu. Duis et interdum lacus.</p><p>Etiam urna nulla, pulvinar at est auctor, varius feugiat orci. Vestibulum efficitur maximus imperdiet. Donec vehicula, leo sit amet condimentum pulvinar, urna felis aliquet velit, bibendum placerat dui libero sed tortor. Vivamus ac diam commodo nisi facilisis lacinia. Aenean a rhoncus risus, venenatis efficitur arcu. Curabitur tincidunt nulla eget augue malesuada imperdiet. Quisque ligula purus, dictum a imperdiet eget, eleifend eu leo. Phasellus massa ipsum, molestie nec pellentesque eu, scelerisque et mi. Vivamus at libero varius, lacinia magna non, imperdiet tortor. Donec scelerisque ipsum sollicitudin justo ornare accumsan. In velit orci, lobortis eget maximus et, scelerisque ut nulla. Cras sit amet finibus sapien. Aenean metus lorem, gravida a rutrum quis, varius eu arcu. Integer ac hendrerit purus. Aliquam cursus ultricies tortor. Fusce scelerisque, arcu id pellentesque accumsan, nulla turpis tempus lectus, tincidunt blandit mi nisi non metus.</p>")
|
||||
|
||||
hi.updateContent("content", "<p>Head of Security Announcement: WHY"</p>)
|
||||
hi.show(src)
|
||||
|
||||
*/
|
||||
|
||||
/var/list/html_interfaces = new/list()
|
||||
|
||||
/datum/html_interface
|
||||
// The atom we should report to.
|
||||
var/atom/ref
|
||||
@@ -100,6 +105,8 @@ mob/verb/test()
|
||||
var/height
|
||||
|
||||
/datum/html_interface/New(atom/ref, title, width = 700, height = 480, head = "")
|
||||
html_interfaces.Add(src)
|
||||
|
||||
. = ..()
|
||||
|
||||
src.ref = ref
|
||||
@@ -109,9 +116,9 @@ mob/verb/test()
|
||||
src.head = head
|
||||
|
||||
/datum/html_interface/Del()
|
||||
if (src.clients)
|
||||
for (var/client in src.clients)
|
||||
src.hide(src.clients[client])
|
||||
src.closeAll()
|
||||
|
||||
html_interfaces.Remove(src)
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -160,7 +167,19 @@ mob/verb/test()
|
||||
if (istype(hclient))
|
||||
if (hclient.is_loaded) hclient.client << output(list2params(list(jscript)), "browser_\ref[src].browser:eval")
|
||||
else
|
||||
for (var/client in src.clients) src.executeJavaScript(jscript, src.clients[client])
|
||||
for (var/client in src.clients) if(src.clients[client]) src.executeJavaScript(jscript, src.clients[client])
|
||||
|
||||
/datum/html_interface/proc/callJavaScript(func, list/arguments, datum/html_interface_client/hclient = null)
|
||||
if (!arguments) arguments = new/list()
|
||||
|
||||
if (hclient)
|
||||
hclient = getClient(hclient)
|
||||
|
||||
if (istype(hclient))
|
||||
if (hclient.is_loaded)
|
||||
hclient.client << output(list2params(arguments), "browser_\ref[src].browser:[func]")
|
||||
else
|
||||
for (var/client in src.clients) if (src.clients[client]) src.callJavaScript(func, arguments, src.clients[client])
|
||||
|
||||
/datum/html_interface/proc/updateLayout(layout)
|
||||
src.layout = layout
|
||||
@@ -180,8 +199,8 @@ mob/verb/test()
|
||||
for (var/client in src.clients)
|
||||
hclient = src._getClient(src.clients[client])
|
||||
|
||||
if (hclient && hclient.active) src._renderContent(id, hclient, ignore_cache)
|
||||
|
||||
if (hclient && hclient.active)
|
||||
spawn (-1) src._renderContent(id, hclient, ignore_cache)
|
||||
/datum/html_interface/proc/show(datum/html_interface_client/hclient)
|
||||
hclient = getClient(hclient, TRUE)
|
||||
|
||||
@@ -200,6 +219,8 @@ mob/verb/test()
|
||||
hclient.client << output(replacetextEx(replacetextEx(file2text('html_interface.html'), "\[hsrc\]", "\ref[src]"), "</head>", "[head]</head>"), "browser_\ref[src].browser")
|
||||
winshow(hclient.client, "browser_\ref[src]", TRUE)
|
||||
|
||||
while (hclient.client && hclient.active && !hclient.is_loaded) sleep(2)
|
||||
|
||||
/datum/html_interface/proc/hide(datum/html_interface_client/hclient)
|
||||
hclient = getClient(hclient)
|
||||
|
||||
@@ -243,24 +264,34 @@ mob/verb/test()
|
||||
/datum/html_interface/proc/isUsed()
|
||||
if (src.clients && src.clients.len > 0)
|
||||
var/datum/html_interface_client/hclient
|
||||
|
||||
for (var/key in clients)
|
||||
hclient = clients[key]
|
||||
if (hclient.active) return TRUE
|
||||
hclient = _getClient(clients[key])
|
||||
|
||||
if (hclient)
|
||||
if (hclient.active) return TRUE
|
||||
else
|
||||
clients.Remove(key)
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/html_interface/proc/closeAll()
|
||||
if (src.clients)
|
||||
for (var/client in src.clients)
|
||||
src.hide(src.clients[client])
|
||||
|
||||
/* * Danger Zone */
|
||||
|
||||
/datum/html_interface/proc/_getClient(datum/html_interface_client/hclient)
|
||||
if (hclient)
|
||||
if (hclient.client)
|
||||
if (hascall(src.ref, "hiIsValidClient"))
|
||||
var/res = call(src.ref, "hiIsValidClient")(hclient)
|
||||
// res = if the client has been active in the past 10 minutes and the client is allowed to view the object (context-sensitive).
|
||||
var/res = hclient.client.inactivity <= 6000 && (hascall(src.ref, "hiIsValidClient") ? call(src.ref, "hiIsValidClient")(hclient, src) : TRUE)
|
||||
|
||||
if (res)
|
||||
if (!hclient.active) src.enableFor(hclient)
|
||||
else
|
||||
if (hclient.active) src.disableFor(hclient)
|
||||
if (res)
|
||||
if (!hclient.active) src.enableFor(hclient)
|
||||
else
|
||||
if (hclient.active) src.disableFor(hclient)
|
||||
|
||||
return hclient
|
||||
else
|
||||
@@ -268,8 +299,9 @@ mob/verb/test()
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/html_interface/proc/_renderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE)
|
||||
if (hclient && hclient.is_loaded)
|
||||
/datum/html_interface/proc/_renderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE, ignore_loaded = FALSE)
|
||||
if (hclient && (ignore_loaded || hclient.is_loaded))
|
||||
|
||||
// Only render if we have new content.
|
||||
|
||||
if (ignore_cache || src.title != hclient.title)
|
||||
@@ -279,8 +311,9 @@ mob/verb/test()
|
||||
|
||||
hclient.client << output(list2params(list(title)), "browser_\ref[src].browser:setTitle")
|
||||
|
||||
/datum/html_interface/proc/_renderLayout(datum/html_interface_client/hclient)
|
||||
if (hclient && hclient.is_loaded)
|
||||
/datum/html_interface/proc/_renderLayout(datum/html_interface_client/hclient, ignore_loaded = FALSE)
|
||||
if (hclient && (ignore_loaded || hclient.is_loaded))
|
||||
|
||||
var/html = src.layout
|
||||
|
||||
// Only render if we have new content.
|
||||
@@ -289,10 +322,10 @@ mob/verb/test()
|
||||
|
||||
hclient.client << output(list2params(list(html)), "browser_\ref[src].browser:updateLayout")
|
||||
|
||||
for (var/id in src.content_elements) src._renderContent(id, hclient)
|
||||
for (var/id in src.content_elements) src._renderContent(id, hclient, ignore_loaded = ignore_loaded)
|
||||
|
||||
/datum/html_interface/proc/_renderContent(id, datum/html_interface_client/hclient, ignore_cache = FALSE)
|
||||
if (hclient && hclient.is_loaded)
|
||||
/datum/html_interface/proc/_renderContent(id, datum/html_interface_client/hclient, ignore_cache = FALSE, ignore_loaded = FALSE)
|
||||
if (hclient && (ignore_loaded || hclient.is_loaded))
|
||||
var/html = src.content_elements[id]
|
||||
|
||||
// Only render if we have new content.
|
||||
@@ -311,11 +344,12 @@ mob/verb/test()
|
||||
if ("onload")
|
||||
hclient.layout = null
|
||||
hclient.content_elements.len = 0
|
||||
src._renderTitle(hclient, TRUE, TRUE)
|
||||
src._renderLayout(hclient, TRUE)
|
||||
|
||||
hclient.is_loaded = TRUE
|
||||
|
||||
src._renderTitle(hclient, TRUE)
|
||||
src._renderLayout(hclient)
|
||||
|
||||
if ("onclose")
|
||||
src.hide(hclient)
|
||||
else if (src.ref && hclient.active) src.ref.Topic(href, href_list, hclient)
|
||||
else if (src.ref && hclient.active) src.ref.Topic(href, href_list, hclient)
|
||||
|
||||
@@ -40,4 +40,4 @@
|
||||
return .
|
||||
|
||||
/datum/html_interface_client/proc/getExtraVar(key)
|
||||
if (src.extra_vars) return src.extra_vars[key]
|
||||
if (src.extra_vars) return src.extra_vars[key]
|
||||
|
||||
@@ -11,6 +11,14 @@ body
|
||||
line-height: 170%; /* NullQuery: 170% of what? */
|
||||
}
|
||||
|
||||
/* Fix for IE8 */
|
||||
body
|
||||
{
|
||||
background-color: #1F1F1F\9 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ntbgcenter
|
||||
{
|
||||
position: absolute;
|
||||
|
||||
Reference in New Issue
Block a user