diff --git a/code/_macros.dm b/code/_macros.dm
index e6f8f46..cd06def 100644
--- a/code/_macros.dm
+++ b/code/_macros.dm
@@ -121,6 +121,8 @@ var/list/global_spawn_dbg = list()
#define issimulatedturf(x) istype(x, /turf/simulated)
#define isfloor(x) (istype(x, /turf/simulated/floor) || istype(x, /turf/unsimulated/floor))
+#define DIST_CHECK(A, B, R) (get_dist(A, B) <= (R) && get_step(A, 0).z == get_step(B, 0).z)
+
#define return_if_overlay_or_effect(x) if (istype(x, /obj/overlay) || istype(x, /obj/effects)) return
// maps
@@ -143,4 +145,7 @@ var/list/global_spawn_dbg = list()
#define usr_admin_only if(usr && usr.client && !usr.client.holder) {boutput(usr, "Only administrators may use this command."); return}
#define GLOBAL_PROC "THIS_IS_A_GLOBAL_PROC_CALLBACK" //used instead of null because clients can be callback targets and then go null from disconnect before invoked, and we need to be able to differentiate when that happens or when it's just a global proc.
-#define CALLBACK new /datum/callback //not a macro to make it 510 compatible
\ No newline at end of file
+#define CALLBACK new /datum/callback //not a macro to make it 510 compatible
+
+#define START_TRACKING do { var/_type = text2path(replacetext("[.disposing]", "/disposing", "")); if(!by_type[_type]) { by_type[_type] = list(src) } else { by_type[_type].Add(src) } } while (FALSE)
+#define STOP_TRACKING do { var/_type = text2path(replacetext("[.disposing]", "/disposing", "")); by_type[_type].Remove(src) } while (FALSE)
\ No newline at end of file
diff --git a/code/_plane.dm b/code/_plane.dm
index d3d34a9..9e69843 100644
--- a/code/_plane.dm
+++ b/code/_plane.dm
@@ -1,67 +1,76 @@
-#define PLANE_FLOOR -10
-#define PLANE_NOSHADOW_BELOW -1
-#define PLANE_DEFAULT 0
-#define PLANE_NOSHADOW_ABOVE 1
-#define PLANE_HIDDENGAME 2
-#define PLANE_LIGHTING 10
-#define PLANE_SELFILLUM 20
-#define PLANE_AICAMERA 22
-#define PLANE_FLOCKVISION 25
-#define PLANE_HUD 30
-
-/obj/screen/plane_parent
- name = ""
- icon = null
- screen_loc = "1,1"
-
- // hey you know what would be really cool? if these could be overlays on the same object so we could animate them sanely
- // haha fuck you of course mouse_opacity on overlays is never gonna work
- // fucking christ lummox
- New(plane, appearance_flags = 0, blend_mode = BLEND_DEFAULT, color, mouse_opacity = 1, name = "unnamed_plane")
- src.name = name
- src.plane = plane
- src.appearance_flags = PLANE_MASTER | appearance_flags
- src.blend_mode = blend_mode
- src.color = color
- src.mouse_opacity = mouse_opacity
-
- proc/add_depth_shadow()
- src.filters += filter(type="drop_shadow", x=2, y=-2, color=rgb(4, 8, 16, 150), size=5, offset=1)
-
-client
- var/list/plane_parents = list()
-
- New()
- plane_parents += new /obj/screen/plane_parent(PLANE_DEFAULT, name = "game_plane")
- plane_parents += new /obj/screen/plane_parent(PLANE_LIGHTING, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_MULTIPLY, mouse_opacity = 0, name = "lighting_plane")
- plane_parents += new /obj/screen/plane_parent(PLANE_SELFILLUM, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_ADD, mouse_opacity = 0, name = "selfillum_plane")
- plane_parents += new /obj/screen/plane_parent(PLANE_FLOCKVISION, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_OVERLAY, mouse_opacity = 0, name = "flockvision_plane")
- plane_parents += new /obj/screen/plane_parent(PLANE_HUD, appearance_flags = NO_CLIENT_COLOR, name = "hud_plane")
- plane_parents += new /obj/screen/plane_parent(PLANE_AICAMERA, appearance_flags = NO_CLIENT_COLOR, mouse_opacity = 0, name = "aicamera_plane")
- SPAWN_DBG(50) //Because everything needs to wait!
- apply_depth_filter()
- ..()
-
- proc/apply_depth_filter()
- var/shadows_checked = winget( src, "menu.set_shadow", "is-checked" ) == "true"
- for (var/obj/screen/plane_parent/P in plane_parents)
- if (P.name == "game_plane")
- if (shadows_checked)
- P.add_depth_shadow()
- else
- P.filters = null
- break
-
- proc/setup_special_screens()
- for (var/atom in plane_parents)
- var/atom/A = atom
- screen += A
- if (A.name == "aicamera_plane")
- if (isAI(src.mob))
- A.alpha = 255
- else
- A.alpha = 0
-
- proc/get_plane(var/plane)
- for (var/atom/A in plane_parents)
+#define PLANE_FLOOR -10
+#define PLANE_NOSHADOW_BELOW -1
+#define PLANE_DEFAULT 0
+#define PLANE_NOSHADOW_ABOVE 1
+#define PLANE_HIDDENGAME 2
+#define PLANE_LIGHTING 10
+#define PLANE_SELFILLUM 20
+#define PLANE_AICAMERA 22
+#define PLANE_FLOCKVISION 25
+#define PLANE_HUD 30
+#define PLANE_SCREEN_OVERLAYS 40
+
+/obj/screen/plane_parent
+ name = ""
+ icon = null
+ screen_loc = "1,1"
+
+ // hey you know what would be really cool? if these could be overlays on the same object so we could animate them sanely
+ // haha fuck you of course mouse_opacity on overlays is never gonna work
+ // fucking christ lummox
+ New(plane, appearance_flags = 0, blend_mode = BLEND_DEFAULT, color, mouse_opacity = 1, name = "unnamed_plane")
+ src.name = name
+ src.plane = plane
+ src.appearance_flags = PLANE_MASTER | appearance_flags
+ src.blend_mode = blend_mode
+ src.color = color
+ src.mouse_opacity = mouse_opacity
+ src.render_target = name
+
+ proc/add_depth_shadow()
+ src.filters += filter(type="drop_shadow", x=2, y=-2, color=rgb(4, 8, 16, 150), size=5, offset=1)
+
+client
+ var/list/plane_parents = list()
+
+ New()
+ plane_parents += new /obj/screen/plane_parent(PLANE_FLOOR, name = "floor_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_DEFAULT, name = "game_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_LIGHTING, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_MULTIPLY, mouse_opacity = 0, name = "lighting_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_SELFILLUM, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_ADD, mouse_opacity = 0, name = "selfillum_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_FLOCKVISION, appearance_flags = NO_CLIENT_COLOR, blend_mode = BLEND_OVERLAY, mouse_opacity = 0, name = "flockvision_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_HUD, appearance_flags = NO_CLIENT_COLOR, name = "hud_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_AICAMERA, appearance_flags = NO_CLIENT_COLOR, mouse_opacity = 0, name = "aicamera_plane")
+ plane_parents += new /obj/screen/plane_parent(PLANE_SCREEN_OVERLAYS, appearance_flags = NO_CLIENT_COLOR, mouse_opacity = 0, name = "screen_overlays_plane")
+
+ var/obj/screen/plane_parent/P = new /obj/screen/plane_parent(PLANE_HIDDENGAME, name = "hidden_game_plane")
+ P.render_target = "*[P.render_target]"
+ plane_parents += P
+
+ SPAWN_DBG(5 SECONDS) //Because everything needs to wait!
+ apply_depth_filter()
+ ..()
+
+ proc/apply_depth_filter()
+ var/shadows_checked = winget( src, "menu.set_shadow", "is-checked" ) == "true"
+ for (var/obj/screen/plane_parent/P in plane_parents)
+ if (P.name == "game_plane")
+ if (shadows_checked)
+ P.add_depth_shadow()
+ else
+ P.filters = null
+ break
+
+ proc/setup_special_screens()
+ for (var/atom in plane_parents)
+ var/atom/A = atom
+ screen += A
+ if (A.name == "aicamera_plane")
+ if (isAI(src.mob))
+ A.alpha = 255
+ else
+ A.alpha = 0
+
+ proc/get_plane(var/plane)
+ for (var/atom/A in plane_parents)
if(A.plane == plane) return A
\ No newline at end of file
diff --git a/code/global.dm b/code/global.dm
index c29015c..683a069 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -545,6 +545,8 @@ var/global
list/escape_pod_success = list() // escape pods flying to the shuttle
list/polarisfall = list() // list of locations for people to fall if they enter the deep in the trench
+ list/by_type = list()
+
#ifdef TWITCH_BOT_ALLOWED
list/billspawn = list() // shitty bill twitch bot respawn
#endif
diff --git a/code/modules/admin/diagnostics.dm b/code/modules/admin/diagnostics.dm
index 796cc81..e1c8391 100644
--- a/code/modules/admin/diagnostics.dm
+++ b/code/modules/admin/diagnostics.dm
@@ -1,358 +1,679 @@
-/client/proc
- map_debug_panel()
- set category = "Debug"
-
- var/area_txt = "APC LOCATION REPORT
"
- var/apc_count = 0
- var/list/apcs = new()
- for(var/area/area in world)
- if (!area.requires_power)
- continue
-
- for(var/obj/machinery/power/apc/current_apc in area)
- if (!apcs.Find(current_apc)) apcs += current_apc
-
- apc_count = apcs.len
- if (apc_count != 1)
- area_txt += "[area.name] [area.type] has [apc_count] APCs.
"
- apcs.len = 0
-
- LAGCHECK(LAG_LOW)
-
- usr.Browse(area_txt,"window=mapdebugpanel")
-
-
- general_report()
- set category = "Debug"
-
- if(!processScheduler)
- usr << alert("Process Scheduler not found.")
-
- var/mobs = 0
- for(var/mob/M in mobs)
- mobs++
-
- var/output = {"GENERAL SYSTEMS REPORT
-General Processing Data
-# of Machines: [machines.len + atmos_machines.len]
-# of Pipe Networks: [pipe_networks.len]
-# of Processing Items: [processing_items.len]
-# of Power Nets: [powernets.len]
-# of Mobs: [mobs]
-"}
-
- usr.Browse(output,"window=generalreport")
-
- air_report()
- set category = "Debug"
-
- if(!processScheduler || !air_master)
- alert(usr,"processScheduler or air_master not found.","Air Report")
- return 0
-
- var/active_groups = 0
- var/inactive_groups = 0
- var/active_tiles = 0
- for(var/datum/air_group/group in air_master.air_groups)
- if(group.group_processing)
- active_groups++
- else
- inactive_groups++
- active_tiles += group.members.len
-
- var/hotspots = 0
- for(var/obj/hotspot/hotspot in world)
- hotspots++
- LAGCHECK(LAG_LOW)
-
- var/output = {"AIR SYSTEMS REPORT
-General Processing Data
-# of Groups: [air_master.air_groups.len]
----- Active: [active_groups]
----- Inactive: [inactive_groups]
--------- Tiles: [active_tiles]
-# of Active Singletons: [air_master.active_singletons.len]
-
-Total # of Gas Mixtures In Existence: [total_gas_mixtures]
-Special Processing Data
-Hotspot Processing: [hotspots]
-High Temperature Processing: [air_master.active_super_conductivity.len]
-High Pressure Processing: [air_master.high_pressure_delta.len] (not yet implemented)
-
-Geometry Processing Data
-Group Rebuild: [air_master.groups_to_rebuild.len]
-Tile Update: [air_master.tiles_to_update.len]
-[air_histogram()]
-"}
-
- usr.Browse(output,"window=airreport")
-
- air_histogram()
-
- var/html = ""
- var/list/ghistogram = new
- var/list/ughistogram = new
- var/p
-
- for(var/datum/air_group/g in air_master.air_groups)
- if (g.group_processing)
- for(var/turf/simulated/member in g.members)
- p = round(max(-1, member.air.return_pressure()), 10)/10 + 1
- if (p > ghistogram.len)
- ghistogram.len = p
- ghistogram[p]++
- else
- for(var/turf/simulated/member in g.members)
- p = round(max(-1, member.air.return_pressure()), 10)/10 + 1
- if (p > ughistogram.len)
- ughistogram.len = p
- ughistogram[p]++
-
- html += "Group processing tiles pressure histogram data:\n"
- for(var/i=1,i<=ghistogram.len,i++)
- html += "[10*(i-1)]\t\t[ghistogram[i]]\n"
- html += "Non-group processing tiles pressure histogram data:\n"
- for(var/i=1,i<=ughistogram.len,i++)
- html += "[10*(i-1)]\t\t[ughistogram[i]]\n"
- return html
-
- air_status(turf/target as turf)
- set category = "Debug"
- set name = "Air Status"
-
- if(!isturf(target))
- return
-
- var/datum/gas_mixture/GM = target.return_air()
- var/burning = 0
- if(istype(target, /turf/simulated))
- var/turf/simulated/T = target
- if(T.active_hotspot)
- burning = 1
-
- boutput(usr, "@[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] t:[GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("BURNING"):(null)]")
-
- if(GM.trace_gases)
- for(var/datum/gas/trace_gas in GM.trace_gases)
- boutput(usr, "[trace_gas.type]: [trace_gas.moles]")
-
- fix_next_move()
- set category = "Debug"
- set name = "Press this if everybody freezes up"
- var/largest_click_time = 0
- var/mob/largest_click_mob = null
- if (disable_next_click)
- boutput(usr, "next_click is disabled and therefore so is this command!")
- return
- for(var/mob/M in mobs)
- if(!M.client)
- continue
- if(M.next_click >= largest_click_time)
- largest_click_mob = M
- if(M.next_click > world.time)
- largest_click_time = M.next_click - world.time
- else
- largest_click_time = 0
- logTheThing("admin", M, null, "lastDblClick = [M.next_click] world.time = [world.time]")
- logTheThing("diary", M, null, "lastDblClick = [M.next_click] world.time = [world.time]", "admin")
- M.next_click = 0
- message_admins("[key_name(largest_click_mob, 1)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!")
- message_admins("world.time = [world.time]")
- return
-
- debug_profiler()
- set category = "Debug"
- set name = "Open Profiler"
-
- admin_only
- world.SetConfig( "APP/admin", src.key, "role=admin" )
- input( src, "Enter '.debug profile' in the next command box. Blame BYOND.", "BYONDSucks", ".debug profile" )
- winset( usr, null, "command=.command" )
-
-/datum/infooverlay
- var/help = "Huh."
- var/restricted = 0//if only coders+ can use it
- proc/GetInfo(var/turf/theTurf, var/image/theImage)
- //ono
- teleblocked/help = "Red tiles are ones that are teleblocked, green ones can be teleported to."
- teleblocked/GetInfo(var/turf/theTurf, var/image/theImage)
- if(1)
- theImage.desc = "This is disabled cus its SLOW."
- return
- if( theTurf in telesci )
- theImage.color = "#0f0"
- return
-
- if( theTurf.loc:teleport_blocked || isrestrictedz(theTurf.z) )
- theImage.color = "#f00"
- return
- for (var/obj/machinery/telejam/T)
- if (!T.active || T.z != theTurf.z)
- continue
- var/r = get_dist(T, theTurf)
- if (r > T.range)
- continue
- theImage.color = "#f00"
- return
- for (var/obj/item/device/flockblocker/F)
- if (!F.active || F.z != theTurf.z)
- continue
- var/r = get_dist(F, theTurf)
- if (r > F.range)
- continue
- theImage.color = "#f00"
- return
- for (var/obj/blob/nucleus/N in range(theTurf, 3))
- theImage.color = "#f00"
- return
- theImage.color = "#0f0"
- blowout/help = "Green tiles are safe from irradiation, red tiles are ones that are not."
- blowout/GetInfo(var/turf/theTurf, var/image/theImage)
- if(theTurf.loc:do_not_irradiate)
- theImage.color = "#0f0"
- else
- theImage.color = "#f00"
- areas/help = "Differentiates between different areas. Also gives you area names because thats cool and stuff."
- areas/GetInfo(var/turf/theTurf, var/image/theImage)
- if(!theTurf.loc:gencolor)
- theTurf.loc:gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
- theImage.desc = "Area: [theTurf.loc:name]
Type: [theTurf.loc:type]"
- theImage.color = theTurf.loc:gencolor
- theImage.mouse_opacity = 1
- atmos_air/help = "Debug atmospherics and contents and stuffs"
- atmos_air/GetInfo(var/turf/theTurf, var/image/theImage)
- var/turf/simulated/sim = theTurf
- theImage.mouse_opacity = 1
- if(istype(sim, /turf/simulated))//byondood
- var/datum/air_group/group = sim.parent
- if(group)
- if(!group.gencolor)
- group.gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
- theImage.color = group.gencolor
- theImage.desc = "Group \ref[group]
O2=[group.air.oxygen]
Nitrogen=[group.air.nitrogen]
CO2=[group.air.carbon_dioxide]
Plasma=[group.air.toxins]
Temperature=[group.air.temperature]
Spaced=[group.spaced]"
- if (group.spaced) theImage.overlays += image('icons/misc/air_debug.dmi', icon_state = "spaced")
- var/list/borders_space = list()
- for(var/turf/spaceses in group.space_borders)
- if(get_dist(spaceses, theTurf) == 1)
- var/dir = get_dir(theTurf, spaceses)
- if((dir & (dir-1)) == 0)
- if(dir & NORTH) borders_space[++borders_space.len] = "NORTH"
- if(dir & SOUTH) borders_space[++borders_space.len] = "SOUTH"
- if(dir & EAST) borders_space[++borders_space.len] = "EAST"
- if(dir & WEST) borders_space[++borders_space.len] = "WEST"
- var/image/airrowe = image('icons/misc/air_debug.dmi', icon_state = "space", dir = dir)
- airrowe.appearance_flags = RESET_COLOR
- theImage.overlays += airrowe
- if(borders_space.len)
- theImage.desc += "
(borders space to the [borders_space.Join(" ")])"
- else
- theImage.color = "#ffffff"
- theImage.desc = "No Atmos Group
O2=[sim.oxygen]
Nitrogen=[sim.nitrogen]
CO2=[sim.carbon_dioxide]
Plasma=[sim.toxins]
Temperature=[sim.temperature]"
- else
- theImage.desc = "-unsimulated-"
- theImage.color = "#202020"
- artists/help = "Shows you the artists of the wonderful writing thats' been written on the station."
- artists/GetInfo(var/turf/theTurf, var/image/theImage)
- var/list/built = list()
- for(var/obj/decal/cleanable/writing/arte in theTurf)
- built += "[arte.icon_state] artpiece by [arte.artist]"
- if(built.len)
- theTurf.color = "#7f0000"
- theImage.desc = built.Join("
")
-
-/client/var/list/infoOverlayImages
-/client/var/datum/infooverlay/activeOverlay
-/obj/overlay/debugoverlay
- mouse_opacity = 0
- icon = 'icons/effects/white.dmi'
- plane = PLANE_HUD - 1
-/client/proc/RenderOverlay()
- var/width
- var/height
- if(istext( view ))
- var/split = splittext(view, "x")
- width = text2num(split[1])+1
- height = text2num(split[2])+1
- else
- width = view*2+1
- height = view*2+1
- for(var/x = 1, x<=width , x++)
- for(var/y = 1, y<=height, y++)
- var/turf/t = locate( eye:x + x - width/2 - 1, eye:y + y - height/2 - 1, eye:z )
- var/image/overlay = infoOverlayImages[ "[x]-[y]" ]
- overlay.loc = t
- overlay.mouse_opacity = 0
- overlay.override = 0
- //overlay.plane = 100
- //overlay.layer = 100
- overlay.overlays = list()
- if(!t)
- overlay.icon_state = "notwhite"
- overlay.alpha = 0
- else
- overlay.icon_state = ""
- activeOverlay.GetInfo( t, overlay )
- overlay.alpha = 64
-/client/proc/GenerateOverlay()
- var/width = view
- var/height = view
-
- if(istext( view ))
- var/split = splittext(view, "x")
- width = text2num(split[1])/2
- height = text2num(split[2])/2
- if( !infoOverlayImages ) infoOverlayImages = list()
- for(var/x = 1, x<=width*2+1, x++)
- for(var/y = 1, y<=height*2+1, y++)
- if(!infoOverlayImages[ "[x]-[y]" ])
- var/image/overlay = new('icons/effects/white.dmi')
- infoOverlayImages[ "[x]-[y]" ] = overlay
- src.images += overlay
-/client/proc/SetInfoOverlay( )
- set name = "Debug Overlay"
- set category = "Debug"
- admin_only
- var/name = input("Choose an overlay") in (childrentypesof( /datum/infooverlay ) + "Remove")
- if(!name || name == "Remove")
- if(infoOverlayImages)
- for(var/img in infoOverlayImages)
- img = infoOverlayImages[img]//shhh
- screen -= img
- img:loc = null
- qdel(img)
- infoOverlayImages = list()
- activeOverlay = null
- qdel(activeOverlay)
- else
- activeOverlay = new name()
- boutput( src, "[activeOverlay.help]" )
- GenerateOverlay()
- RenderOverlay()
-/turf
- MouseEntered(location, control, params)
- if(usr.client.activeOverlay)
- var/list/lparams = params2list(params)
- var/offs = splittext(lparams["screen-loc"], ",")
-
- var/x = text2num(splittext(offs[1], ":")[1])+1
- var/y = text2num(splittext(offs[2], ":")[1])+1
- var/image/im = usr.client.infoOverlayImages["[x]-[y]"]
- if(im && im.desc)
- usr.client.tooltipHolder.transient.show(src, list(
- "params" = params,
- "title" = "Diagnostics",
- "content" = (im.desc)
- ))
- else
- .=..()
- MouseExited()
- if(usr.client.activeOverlay)
- usr.client.tooltipHolder.transient.hide()
- else
- .=..()
-/mob/OnMove()
-
- if(client && client.activeOverlay)
- client.GenerateOverlay()
- client.RenderOverlay()
- .=..()
+var/global/list/color_caching = list()
+
+proc/debug_color_of(var/thing)
+ if(isnum(thing))
+ thing = "[thing]"
+ else if(!istext(thing))
+ thing = "\ref[thing]"
+ if(!thing || thing == "0" || thing == "null" || thing == "\[0x0\]")
+ return "#ffffff"
+ if(!(thing in color_caching))
+ color_caching[thing] = "#[copytext(md5(thing), 1, 7)]"
+ return color_caching[thing]
+
+/client/proc
+ map_debug_panel()
+ set category = "Debug"
+
+ var/area_txt = "APC LOCATION REPORT
"
+ var/apc_count = 0
+ var/list/apcs = new()
+ for(var/area/area in world)
+ if (!area.requires_power)
+ continue
+
+ for(var/obj/machinery/power/apc/current_apc in area)
+ if (!apcs.Find(current_apc)) apcs += current_apc
+
+ apc_count = apcs.len
+ if (apc_count != 1)
+ area_txt += "[area.name] [area.type] has [apc_count] APCs.
"
+ apcs.len = 0
+
+ LAGCHECK(LAG_LOW)
+
+ usr.Browse(area_txt,"window=mapdebugpanel")
+
+
+ general_report()
+ set category = "Debug"
+
+ if(!processScheduler)
+ usr << alert("Process Scheduler not found.")
+
+ var/mobs = 0
+ for(var/mob/M in mobs)
+ mobs++
+
+
+ var/output = {"GENERAL SYSTEMS REPORT
+General Processing Data
+# of Machines: [machines.len + atmos_machines.len]
+# of Pipe Networks: [pipe_networks.len]
+# of Processing Items: [processing_items.len]
+# of Power Nets: [powernets.len]
+# of Mobs: [mobs]
+"}
+
+ usr.Browse(output,"window=generalreport")
+
+ air_report()
+ set category = "Debug"
+
+ if(!processScheduler || !air_master)
+ alert(usr,"processScheduler or air_master not found.","Air Report")
+ return 0
+
+ var/active_groups = 0
+ var/inactive_groups = 0
+ var/active_tiles = 0
+ for(var/datum/air_group/group in air_master.air_groups)
+ if(group.group_processing)
+ active_groups++
+ else
+ inactive_groups++
+ active_tiles += group.members.len
+
+ var/hotspots = 0
+ for(var/obj/hotspot/hotspot in world)
+ hotspots++
+ LAGCHECK(LAG_LOW)
+
+ var/output = {"AIR SYSTEMS REPORT
+General Processing Data
+# of Groups: [air_master.air_groups.len]
+---- Active: [active_groups]
+---- Inactive: [inactive_groups]
+-------- Tiles: [active_tiles]
+# of Active Singletons: [air_master.active_singletons.len]
+
+Total # of Gas Mixtures In Existence: [total_gas_mixtures]
+Special Processing Data
+Hotspot Processing: [hotspots]
+High Temperature Processing: [air_master.active_super_conductivity.len]
+High Pressure Processing: [air_master.high_pressure_delta.len] (not yet implemented)
+
+Geometry Processing Data
+Group Rebuild: [air_master.groups_to_rebuild.len]
+Tile Update: [air_master.tiles_to_update.len]
+[air_histogram()]
+"}
+
+ usr.Browse(output,"window=airreport")
+
+ air_histogram()
+
+ var/html = ""
+ var/list/ghistogram = new
+ var/list/ughistogram = new
+ var/p
+
+ for(var/datum/air_group/g in air_master.air_groups)
+ if (g.group_processing)
+ for(var/turf/simulated/member in g.members)
+ p = round(max(-1, member.air.return_pressure()), 10)/10 + 1
+ if (p > ghistogram.len)
+ ghistogram.len = p
+ ghistogram[p]++
+ else
+ for(var/turf/simulated/member in g.members)
+ p = round(max(-1, member.air.return_pressure()), 10)/10 + 1
+ if (p > ughistogram.len)
+ ughistogram.len = p
+ ughistogram[p]++
+
+ html += "Group processing tiles pressure histogram data:\n"
+ for(var/i=1,i<=ghistogram.len,i++)
+ html += "[10*(i-1)]\t\t[ghistogram[i]]\n"
+ html += "Non-group processing tiles pressure histogram data:\n"
+ for(var/i=1,i<=ughistogram.len,i++)
+ html += "[10*(i-1)]\t\t[ughistogram[i]]\n"
+ return html
+
+ air_status(turf/target as turf)
+ set category = "Debug"
+ set name = "Air Status"
+
+ if(!isturf(target))
+ return
+
+ var/datum/gas_mixture/GM = target.return_air()
+ var/burning = 0
+ if(istype(target, /turf/simulated))
+ var/turf/simulated/T = target
+ if(T.active_hotspot)
+ burning = 1
+
+ boutput(usr, "@[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] t:[GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("BURNING"):(null)]")
+
+ if(GM.trace_gases)
+ for(var/datum/gas/trace_gas in GM.trace_gases)
+ boutput(usr, "[trace_gas.type]: [trace_gas.moles]")
+
+ fix_next_move()
+ set category = "Debug"
+ set name = "Press this if everybody freezes up"
+ var/largest_click_time = 0
+ var/mob/largest_click_mob = null
+ if (disable_next_click)
+ boutput(usr, "next_click is disabled and therefore so is this command!")
+ return
+ for(var/mob/M in mobs)
+ if(!M.client)
+ continue
+ if(M.next_click >= largest_click_time)
+ largest_click_mob = M
+ if(M.next_click > world.time)
+ largest_click_time = M.next_click - world.time
+ else
+ largest_click_time = 0
+ logTheThing("admin", M, null, "lastDblClick = [M.next_click] world.time = [world.time]")
+ logTheThing("diary", M, null, "lastDblClick = [M.next_click] world.time = [world.time]", "admin")
+ M.next_click = 0
+ message_admins("[key_name(largest_click_mob, 1)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!")
+ message_admins("world.time = [world.time]")
+ return
+
+ debug_profiler()
+ set category = "Debug"
+ set name = "Open Profiler"
+
+ admin_only
+ world.SetConfig( "APP/admin", src.key, "role=admin" )
+ input( src, "Enter '.debug profile' in the next command box. Blame BYOND.", "BYONDSucks", ".debug profile" )
+ winset( usr, null, "command=.command" )
+
+/datum/infooverlay
+ var/help = "Huh."
+ var/restricted = 0//if only coders+ can use it
+ proc/GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ proc/OnEnabled(var/client/C)
+ proc/OnDisabled(var/client/C)
+
+ proc/makeText(text)
+ var/mutable_appearance/mt = new
+ mt.icon = 'icons/effects/effects.dmi'
+ mt.icon_state = "nothing"
+ mt.maptext = "[text]"
+ mt.maptext_x = -3
+ mt.appearance_flags = RESET_COLOR
+ return mt
+
+ teleblocked
+ help = "Red tiles are ones that are teleblocked, green ones can be teleported to."
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ img.app.color = is_teleportation_allowed(theTurf) ? "#0f0" : "#f00"
+
+ blowout
+ help = "Green tiles are safe from irradiation, red tiles are ones that are not."
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ if(theTurf.loc:do_not_irradiate)
+ img.app.color = "#0f0"
+ else
+ img.app.color = "#f00"
+
+
+ areas
+ help = "Differentiates between different areas. Also gives you area names because thats cool and stuff."
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ if(!theTurf.loc:gencolor)
+ theTurf.loc:gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
+ img.app.desc = "Area: [theTurf.loc:name]
Type: [theTurf.loc:type]"
+ img.app.color = theTurf.loc:gencolor
+ img.mouse_opacity = 1
+
+
+ atmos_air
+ help = "Tile colors are based on what air group turf belongs to. Hover over a turf to get its atmos readout"
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ var/turf/simulated/sim = theTurf
+ img.mouse_opacity = 1
+ if(istype(sim, /turf/simulated))//byondood
+ var/datum/air_group/group = sim.parent
+ if(group)
+ if(!group.gencolor)
+ group.gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
+ img.app.color = group.gencolor
+ img.app.desc = "Group \ref[group]
O2=[group.air.oxygen]
Nitrogen=[group.air.nitrogen]
CO2=[group.air.carbon_dioxide]
Plasma=[group.air.toxins]
Temperature=[group.air.temperature]
Spaced=[group.spaced]"
+ if (group.spaced) img.app.overlays += image('icons/misc/air_debug.dmi', icon_state = "spaced")
+ /*
+ var/list/borders_space = list()
+ for(var/turf/spaceses in group.space_borders)
+ if(get_dist(spaceses, theTurf) == 1)
+ var/dir = get_dir(theTurf, spaceses)
+ if((dir & (dir-1)) == 0)
+ if(dir & NORTH) borders_space[++borders_space.len] = "NORTH"
+ if(dir & SOUTH) borders_space[++borders_space.len] = "SOUTH"
+ if(dir & EAST) borders_space[++borders_space.len] = "EAST"
+ if(dir & WEST) borders_space[++borders_space.len] = "WEST"
+ var/image/airrowe = image('icons/misc/air_debug.dmi', icon_state = "space", dir = dir)
+ airrowe.appearance_flags = RESET_COLOR
+ img.app.overlays += airrowe
+ if(borders_space.len)
+ img.app.desc += "
(borders space to the [borders_space.Join(" ")])"
+ */
+ var/list/borders_individual = list()
+ for(var/turf/ind in group.border_individual)
+ if(get_dist(ind, theTurf) == 1)
+ var/dir = get_dir(theTurf, ind)
+ if((dir & (dir-1)) == 0)
+ if(dir & NORTH) borders_individual[++borders_individual.len] = "NORTH"
+ if(dir & SOUTH) borders_individual[++borders_individual.len] = "SOUTH"
+ if(dir & EAST) borders_individual[++borders_individual.len] = "EAST"
+ if(dir & WEST) borders_individual[++borders_individual.len] = "WEST"
+ var/image/airrowe = image('icons/misc/air_debug.dmi', icon_state = "space", dir = dir)
+ airrowe.appearance_flags = RESET_COLOR
+ img.app.overlays += airrowe
+ if(borders_individual.len)
+ img.app.desc += "
(borders individual to the [borders_individual.Join(" ")])"
+ var/list/borders_group = list()
+ for(var/turf/simulated/T in group.enemies)
+ if(get_dist(T, theTurf) == 1)
+ var/dir = get_dir(theTurf, T)
+ if((dir & (dir-1)) == 0)
+ if(dir & NORTH) borders_group[++borders_group.len] = "NORTH"
+ if(dir & SOUTH) borders_group[++borders_group.len] = "SOUTH"
+ if(dir & EAST) borders_group[++borders_group.len] = "EAST"
+ if(dir & WEST) borders_group[++borders_group.len] = "WEST"
+ var/image/airrowe = image('icons/misc/air_debug.dmi', icon_state = "space", dir = dir)
+ airrowe.appearance_flags = RESET_COLOR
+ if(T.parent)
+ if(!T.parent.gencolor)
+ T.parent.gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
+ airrowe.color = T.parent.gencolor
+ img.app.overlays += airrowe
+ if(borders_group.len)
+ img.app.desc += "
(borders groups to the [borders_group.Join(" ")])"
+ if(theTurf in group.borders)
+ var/image/mark = image('icons/misc/air_debug.dmi', icon_state = "border")
+ mark.appearance_flags = RESET_COLOR
+ img.app.overlays += mark
+ if(theTurf in group.space_borders)
+ var/image/mark = image('icons/misc/air_debug.dmi', icon_state = "space_border")
+ mark.appearance_flags = RESET_COLOR
+ img.app.overlays += mark
+ if(theTurf in group.self_tile_borders)
+ var/image/mark = image('icons/misc/air_debug.dmi', icon_state = "individual_border")
+ mark.appearance_flags = RESET_COLOR
+ img.app.overlays += mark
+ if(theTurf in group.self_group_borders)
+ var/image/mark = image('icons/misc/air_debug.dmi', icon_state = "group_border")
+ mark.appearance_flags = RESET_COLOR
+ img.app.overlays += mark
+ else
+ img.app.color = "#ffffff"
+ img.app.desc = "No Atmos Group
O2=[sim.oxygen]
Nitrogen=[sim.nitrogen]
CO2=[sim.carbon_dioxide]
Plasma=[sim.toxins]
Temperature=[sim.temperature]"
+ else
+ img.app.desc = "-unsimulated-"
+ img.app.color = "#202020"
+
+
+
+ atmos_status
+ help = "turf color: black (no air), gray (less than normal), white (normal pressure), red (over normal)
top number: o2 pp%. white = breathable, orange = breathable w/ cyberlung, otherwise no good
middle number: atmos pressure (kPa)
bottom number: air temp (°C)
colored square in bottom left:
color indicates group membership
solid: group mode on
outline: group mode off
no square: not in a group"
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ var/turf/simulated/sim = theTurf
+ img.mouse_opacity = 1
+ img.app.desc = ""
+ img.app.color = null
+ img.app.maptext = null
+ if (istype(sim, /turf/simulated))
+ img.app.alpha = 200
+
+ var/datum/air_group/group = sim.parent
+ var/datum/gas_mixture/air = null
+ var/is_group = 0
+ var/is_group_active = 0
+ if (sim && sim.parent)
+ if (!sim.parent.gencolor)
+ group.gencolor = rgb( rand(1,255),rand(1,255),rand(1,255) )
+ is_group = group.gencolor
+ if (sim.parent.group_processing)
+ is_group_active = 1
+ air = sim.parent.air
+ else
+ air = sim.air
+ else if (sim && sim.air)
+ air = sim.air
+
+ if (!air)
+ img.app.color = "#6666FF"
+ img.app.desc = "no air mix"
+ else
+
+ var/pressure = air.return_pressure()
+ img.app.desc = ""
+
+
+ var/breath_pressure = ((air.total_moles() * R_IDEAL_GAS_EQUATION * air.temperature) * BREATH_PERCENTAGE) / BREATH_VOLUME
+ //Partial pressure of the O2 in our breath
+ var/O2_pp = (air.total_moles()) && (air.oxygen / air.total_moles()) * breath_pressure
+ var/O2_color
+ var/T_color
+ switch (O2_pp)
+ if (17 to INFINITY)
+ O2_color = "#eeeeff"
+ if (9 to 17)
+ O2_color = "#ff8800"
+ if (-INFINITY to 0.01)
+ O2_color = "#888888"
+ else
+ O2_color = "#ff0000"
+
+ switch (air.temperature - T0C)
+ if (100 to INFINITY)
+ T_color = "#ff0000"
+ if (75 to 100)
+ T_color = "#ff8800"
+ if (40 to 65)
+ T_color = "#ffff00"
+ if (15 to 40)
+ T_color = "#ffffff"
+ if (-15 to 0)
+ T_color = "#99bbff"
+ if (-40 to -15)
+ T_color = "#5599ff"
+ if (-INFINITY to -40)
+ T_color = "#0000ff"
+
+ T_color = "#ffffff"
+
+ //mt.maptext = "[round(air.total_moles(), 0.1)]\n[round(pressure, 1)]\n[round(air.temperature - T0C, 1)]"
+ img.app.overlays = null
+
+ if (is_group)
+ var/image/gt = image('icons/Testing/atmos_testing.dmi', "group[is_group_active ? "" : "-paused"]")
+ gt.appearance_flags = RESET_COLOR
+ gt.color = is_group
+ img.app.overlays += gt
+
+ if (group && group.spaced) img.app.overlays += image('icons/misc/air_debug.dmi', icon_state = "spaced")
+
+ img.app.overlays += src.makeText("[round(O2_pp, 0.01)]\n[round(pressure, 0.1)]\n[round(air.temperature - T0C, 1)]")
+
+
+ if (pressure > ONE_ATMOSPHERE)
+ var/color1 = 255
+ var/color2 = 255 - clamp(((pressure - ONE_ATMOSPHERE) / (ONE_ATMOSPHERE * 4)) * 255, 0, 255)
+ img.app.color = rgb(color1, color2, color2)
+ else
+ var/color1 = clamp(pressure / ONE_ATMOSPHERE * 255, 0, 255)
+ img.app.color = rgb(color1, color1, color1)
+
+
+ else
+ img.app.desc = "" //"unsim"
+ img.app.color = "#0000ff"
+
+
+ artists
+ help = "Shows you the artists of the wonderful writing that's been written on the station."
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ var/list/artists = list()
+ var/list/built = list()
+ for(var/obj/decal/cleanable/writing/arte in theTurf)
+ built += "[arte.icon_state] artpiece by [arte.artist]"
+ artists |= arte.artist
+ if(artists.len >= 2)
+ img.app.color = "#7f0000"
+ else if(artists.len == 1)
+ img.app.color = debug_color_of(artists[1])
+ img.app.desc = built.Join("
")
+
+ powernet
+ help = {"red - contains 0 (no powernet), that's probably bad
white - contains multiple powernets
other - coloured based on the single powernet
numbers - ids of all powernets on the tile"}
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ img.mouse_opacity = 0
+ var/list/netnums = list()
+ for(var/obj/machinery/power/M in theTurf)
+ if(M.netnum >= 0)
+ netnums |= M.netnum
+ for(var/obj/cable/C in theTurf)
+ if(C.netnum >= 0)
+ netnums |= C.netnum
+ img.app.overlays = list(src.makeText(jointext(netnums, " ")))
+ if(!netnums.len)
+ img.app.color = "#00000000"
+ img.app.alpha = 0
+ else if(0 in netnums)
+ img.app.color = "#ff0000"
+ else if(netnums.len >= 2)
+ img.app.color = "#ffffff"
+ else
+ img.app.color = debug_color_of(netnums[1])
+
+ disposals
+ help = {"shows all disposal pipes as an overlay
if there's stuff in a pipe it's highlighted in blue if moving and in red if stuck
number - how many objects are in the pipe"}
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ img.app.color = "#ffffff"
+ img.app.overlays = list()
+ img.app.alpha = 0
+ for(var/obj/disposalpipe/pipe in theTurf)
+ var/image/pipe_image = image(pipe.icon, icon_state = pipe.icon_state, dir = pipe.dir)
+ img.app.alpha = 64
+ pipe_image.alpha = 160
+ pipe_image.appearance_flags = RESET_ALPHA | RESET_COLOR
+ var/n_objects = 0
+ for(var/obj/disposalholder/DH in pipe)
+ n_objects += DH.contents.len
+ if(DH.active)
+ pipe_image.color = "#0000ff"
+ else
+ pipe_image.color = "#ff0000"
+ if(n_objects)
+ pipe_image.maptext = "[n_objects]"
+ pipe_image.maptext_x = -3
+ img.app.overlays += pipe_image
+
+ camera_coverage
+ help = {"blue - tile visible by a camera
without overlay - tile not visible by a camera
number - number of cameras seeing the tile"}
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ if(theTurf.cameras && theTurf.cameras.len)
+ img.app.overlays = list(src.makeText(theTurf.cameras.len))
+ img.app.color = "#0000ff"
+ else
+ img.app.alpha = 0
+
+ atmos_pipes
+ help = {"highlights all atmos machinery
pipe color - the pipeline to which it belongs
numbers:
temperature
moles
pressure"}
+ var/show_numbers = 1
+ var/show_pipe_networks = 0
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ img.app.color = "#ffffff"
+ img.app.overlays = list()
+ img.app.alpha = 0
+ for(var/obj/machinery/atmospherics/thing in theTurf)
+ var/image/pipe_image = image(thing.icon, icon_state = thing.icon_state, dir = thing.dir)
+ if(img.app.alpha == 0)
+ img.app.alpha = 40
+ pipe_image.alpha = 200
+ pipe_image.appearance_flags = RESET_ALPHA | RESET_COLOR
+ var/obj/machinery/atmospherics/pipe/pipe = thing
+ if(istype(pipe))
+ img.app.alpha = 80
+ if(show_pipe_networks)
+ pipe_image.color = debug_color_of(pipe.parent?.network)
+ else
+ pipe_image.color = debug_color_of(pipe.parent)
+ var/datum/gas_mixture/air = pipe.return_air()
+ if(show_numbers)
+ if(air.total_moles() > 0.01)
+ pipe_image.maptext = "[round(air.temperature, 0.1)]
[round(air.total_moles(), 0.1)]
[round(air.return_pressure(), 0.1)]"
+ pipe_image.maptext_x = -3
+ else if(air.total_moles() > 0)
+ pipe_image.maptext = ">0"
+ pipe_image.maptext_x = -3
+ img.app.overlays += pipe_image
+
+ atmos_pipes/without_numbers
+ show_numbers = 0
+
+ atmos_pipes/pipe_networks_instead_of_pipelines
+ show_numbers = 0
+ show_pipe_networks = 1
+
+ interesting_stuff
+ help = {"highlights turfs with stuff that has the var "interesting" set to something
red - only the turf is interesting
blue - interesting stuff is on the turf
number - number of interesting things
hover over the overlay to see what's interesting"}
+ GetInfo(var/turf/theTurf, var/image/debugoverlay/img)
+ img.app.alpha = 0
+ var/list/lines = list()
+ if(theTurf.interesting)
+ img.app.alpha = 128
+ lines += "[theTurf] - [theTurf.interesting]"
+ img.app.color = "#ff0000"
+ for(var/atom/A in theTurf)
+ if(A.interesting)
+ img.app.alpha = 128
+ lines += "[A] - [A.interesting]"
+ img.app.color = "#0000ff"
+ if(lines.len)
+ img.app.overlays = list(src.makeText(lines.len))
+ img.app.desc = lines.Join("
")
+ else
+ img.app.desc = ""
+
+
+/client/var/list/infoOverlayImages
+/client/var/datum/infooverlay/activeOverlay
+
+/image/debugoverlay
+ mouse_opacity = 0
+ icon = 'icons/effects/white.dmi'
+ plane = PLANE_SCREEN_OVERLAYS
+ override = 0
+ desc = ""
+ color = null
+ maptext = null
+ alpha = 128
+ var/mutable_appearance/debug_overlay_appearance/app = new
+
+ proc/reset()
+ src.app.reset()
+ src.mouse_opacity = initial(src.mouse_opacity)
+
+ proc/apply()
+ src.appearance = app
+
+/mutable_appearance/debug_overlay_appearance
+ icon = 'icons/effects/white.dmi'
+ plane = PLANE_SCREEN_OVERLAYS
+ override = 0
+ desc = ""
+ color = null
+ maptext = null
+ alpha = 128
+
+ proc/reset()
+ src.icon = initial(src.icon)
+ src.color = initial(src.color)
+ src.override = initial(src.override)
+ src.desc = initial(src.desc)
+ src.plane = initial(src.plane)
+ src.overlays = initial(src.overlays)
+ src.maptext = initial(src.maptext)
+ src.alpha = initial(src.alpha)
+
+
+/client/proc/RenderOverlay()
+ var/width
+ var/height
+ if(istext( view ))
+ var/split = splittext(view, "x")
+ width = text2num(split[1])+1
+ height = text2num(split[2])+1
+ else
+ width = view*2+1
+ height = view*2+1
+ var/turf/center = get_turf(eye)
+ for(var/x = 1, x<=width , x++)
+ for(var/y = 1, y<=height, y++)
+ var/turf/t = locate( center.x + x - width/2 - 1, center.y + y - height/2 - 1, center.z )
+ var/image/debugoverlay/overlay = infoOverlayImages[ "[x]-[y]" ]
+ if(!overlay)
+ continue
+ overlay.loc = t
+ overlay.reset()
+ if(!t)
+ overlay.app.icon_state = "notwhite"
+ overlay.app.alpha = 0
+ else
+ overlay.app.icon_state = ""
+ activeOverlay.GetInfo( t, overlay )
+ overlay.apply()
+
+/client/proc/GenerateOverlay()
+ var/width = view
+ var/height = view
+
+ if(istext( view ))
+ var/split = splittext(view, "x")
+ width = text2num(split[1])/2
+ height = text2num(split[2])/2
+ if( !infoOverlayImages ) infoOverlayImages = list()
+ for(var/x = 1, x<=width*2+1, x++)
+ for(var/y = 1, y<=height*2+1, y++)
+ if(!infoOverlayImages[ "[x]-[y]" ])
+ var/image/debugoverlay/overlay = new
+ infoOverlayImages[ "[x]-[y]" ] = overlay
+ src.images += overlay
+
+/client/proc/SetInfoOverlay( )
+ set name = "Debug Overlay"
+ set category = "Debug"
+ admin_only
+ var/name = input("Choose an overlay") in (childrentypesof( /datum/infooverlay ) + "Remove")
+ if(activeOverlay)
+ activeOverlay.OnDisabled(src)
+ if(!name || name == "Remove")
+ if(infoOverlayImages)
+ for(var/img in infoOverlayImages)
+ img = infoOverlayImages[img]//shhh
+ screen -= img
+ img:loc = null
+ qdel(img)
+ infoOverlayImages = list()
+ activeOverlay = null
+ qdel(activeOverlay)
+ else
+ activeOverlay = new name()
+ boutput( src, "[activeOverlay.help]" )
+ GenerateOverlay()
+ activeOverlay.OnEnabled(src)
+ RenderOverlay()
+ SPAWN_DBG(1 DECI SECOND)
+ var/client/X = src
+ while (X && X.activeOverlay)
+ // its a debug overlay so f u
+ X.RenderOverlay()
+ sleep(10)
+/turf
+ MouseEntered(location, control, params)
+ if(usr.client.activeOverlay)
+ var/list/lparams = params2list(params)
+ var/offs = splittext(lparams["screen-loc"], ",")
+
+ var/x = text2num(splittext(offs[1], ":")[1])+1
+ var/y = text2num(splittext(offs[2], ":")[1])+1
+ var/image/im = usr.client.infoOverlayImages["[x]-[y]"]
+ if(im && im.desc)
+ usr.client.tooltipHolder.transient.show(src, list(
+ "params" = params,
+ "title" = "Diagnostics",
+ "content" = (im.desc)
+ ))
+ else
+ .=..()
+ MouseExited()
+ if(usr.client.activeOverlay)
+ usr.client.tooltipHolder.transient.hide()
+ else
+ .=..()
+
+/*
+// having to wiggle around to update the overlay dumb, bad, esp when you can move real fast
+/mob/OnMove()
+ if(client && client.activeOverlay)
+ client.GenerateOverlay()
+ client.RenderOverlay()
+ .=..()
+*/
diff --git a/code/modules/networks/computer3/mainframe2/telesci.dm b/code/modules/networks/computer3/mainframe2/telesci.dm
index 43e2c9e..d45cfbc 100644
--- a/code/modules/networks/computer3/mainframe2/telesci.dm
+++ b/code/modules/networks/computer3/mainframe2/telesci.dm
@@ -1,1278 +1,1276 @@
-/datum/computer/file/coords
- name = "coordinates"
- extension = "GPS"
- var/destx = 0
- var/desty = 0
- var/destz = 0
-
- var/origx = 0 //Only used for relaying stuff.
- var/origy = 0 //Fun for people who can't spell.
- var/origz = 0
-
- var/can_cheat = 0 //Flag to ignore destination restrictions.
-
-var/telesci_modifiers_set = 0
-
-/obj/machinery/networked/telepad
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "pad0"
- name = "teleport pad"
- anchored = 1
- density = 0
- layer = FLOOR_EQUIP_LAYER1
- mats = 16
- timeout = 10
- desc = "Stand on this to have your wildest dreams come true!"
- device_tag = "PNET_S_TELEPAD"
- var/recharging = 0
- var/realx = 0
- var/realy = 0
- var/realz = 0
- var/tmp/session = null
- var/obj/perm_portal/start_portal
- var/obj/perm_portal/end_portal
- var/image/disconnectedImage
-
- New()
- ..()
- if (!telesci_modifiers_set)
- telesci_modifiers_set = 1
- XMULTIPLY = pick(1,2,4) //If it is three, perfect precision is impossible because fractions will be recurring.
- XSUBTRACT = rand(0,100)
- YMULTIPLY = pick(1,2,4) // same as above
- YSUBTRACT = rand(0,100)
- ZSUBTRACT = rand(0,world.maxz)
-
- disconnectedImage = image('icons/obj/stationobjs.dmi', "pad-noconnect")
-
- SPAWN_DBG(5 DECI SECONDS)
- src.net_id = generate_net_id(src)
-
- if(!src.link)
- var/turf/T = get_turf(src)
- var/obj/machinery/power/data_terminal/test_link = locate() in T
- if(test_link && !test_link.is_valid_master(test_link.master))
- src.link = test_link
- src.link.master = src
-
- ex_act()
- return
-
- examine()
- set src in view()
- ..()
- if (!src.host_id)
- boutput(usr, "The [src.name]'s \"disconnected from host\" light is flashing.")
-
- attack_hand(mob/user as mob)
- if(..())
- return
-
- user.machine = src
-
- var/dat = "Telepad"
-
- var/readout_color = "#000000"
- var/readout = "ERROR"
- if(src.host_id)
- readout_color = "#33FF00"
- readout = "OK CONNECTION"
- else
- readout_color = "#F80000"
- readout = "NO CONNECTION"
-
- dat += "Host Connection: "
- dat += "
"
-
- dat += "Reset Connection
"
-
- if (src.panel_open)
- dat += net_switch_html()
-
- user.Browse(dat,"window=telepad;size=245x302")
- onclose(user,"telepad")
- return
-
- Topic(href, href_list)
- if(..())
- return
-
- usr.machine = src
- if (href_list["reset"])
- if(last_reset && (last_reset + NETWORK_MACHINE_RESET_DELAY >= world.time))
- return
-
- if(!host_id && !old_host_id)
- return
-
- src.last_reset = world.time
- var/rem_host = src.host_id ? host_id : old_host_id
- src.host_id = null
- //src.old_host_id = null
- src.post_status(rem_host, "command","term_disconnect")
- SPAWN_DBG(5 DECI SECONDS)
- src.post_status(rem_host, "command","term_connect","device",src.device_tag)
-
- src.updateUsrDialog()
- return
-
-
- src.add_fingerprint(usr)
- return
-
- updateUsrDialog()
- ..()
- if (src.host_id)
- src.overlays.len = 0
- else if (!src.overlays.len)
- src.overlays += src.disconnectedImage
-
- receive_signal(datum/signal/signal)
- if(status & (NOPOWER|BROKEN) || !src.link)
- return
- if(!signal || !src.net_id || signal.encryption)
- return
-
- if(signal.transmission_method != TRANSMISSION_WIRE) //No radio for us thanks
- return
-
- var/target = signal.data["sender"]
-
- if(signal.data["address_1"] != src.net_id)
- if((signal.data["address_1"] == "ping") && ((signal.data["net"] == null) || ("[signal.data["net"]]" == "[src.net_number]")) && signal.data["sender"])
- SPAWN_DBG(5 DECI SECONDS)
- src.post_status(target, "command", "ping_reply", "device", src.device_tag, "netid", src.net_id, "net", "[net_number]")
-
- return
-
- var/sigcommand = lowertext(signal.data["command"])
- if(!sigcommand || !signal.data["sender"])
- return
-
- switch(sigcommand)
- if("term_connect") //Terminal interface stuff.
- if(target == src.host_id)
- src.host_id = null
- src.updateUsrDialog()
- SPAWN_DBG(3 DECI SECONDS)
- src.post_status(target, "command","term_disconnect")
- return
-
- if(src.host_id)
- return
-
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- src.host_id = target
- src.old_host_id = target
- if(signal.data["data"] != "noreply")
- src.post_status(target, "command","term_connect","data","noreply","device",src.device_tag)
- src.updateUsrDialog()
- SPAWN_DBG(2 DECI SECONDS) //Sign up with the driver (if a mainframe contacted us)
- src.post_status(target,"command","term_message","data","command=register")
- return
-
- if("term_message","term_file")
- if(target != src.host_id) //Huh, who is this?
- return
-
- var/list/data = params2list(signal.data["data"])
- if(!data)
- return
-
- session = data["session"]
-
- switch(data["command"])
- if ("set_coords")
- var/datum/computer/file/coords/coords = signal.data_file
- if (!istype(coords))
- message_host("command=nack")
- return
-
- src.realx = round( max(0, min(coords.destx, world.maxx+1)) )
- src.realy = round( max(0, min(coords.desty, world.maxy+1)) )
- src.realz = round( max(0, min(coords.destz, world.maxz+1)) )
- signal.data_file = null
- pool(coords)
- message_host("command=ack")
-
- if ("send")
- if (recharging)
- message_host("command=nack&cause=recharge")
- return
-
- src.icon_state = "pad1"
- recharging = 1
- SPAWN_DBG(0)
-
- var/turf/turfcheck = doturfcheck(1)
- if(!istype(turfcheck))
- src.badsend()
- if (isnum(turfcheck))
- src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
- else
- src.message_host("command=nack&cause=badxyz")
- else if(!is_allowed(turfcheck))
- src.message_host("command=nack&cause=interference")
- else
- message_host("command=ack")
- sleep(10)
- src.send(turfcheck)
- sleep(5)
-
- src.icon_state = "pad0"
- sleep(10)
-
- recharging = 0
-
- if ("receive")
- if (recharging)
- message_host("command=nack&cause=recharge")
- return
-
- src.icon_state = "pad1"
- recharging = 1
- SPAWN_DBG(0)
-
- var/turf/turfcheck = doturfcheck(1)
- if(!istype(turfcheck))
- if (isnum(turfcheck))
- src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
- else
- src.message_host("command=nack&cause=badxyz")
- sleep(10)
- src.badreceive()
- else if(!is_allowed(turfcheck))
- src.message_host("command=nack&cause=interference")
- else
- message_host("command=ack")
- sleep(10)
- src.receive(turfcheck)
- sleep(5)
-
- src.icon_state = "pad0"
- sleep(10)
-
- recharging = 0
-
- if ("relay")
- if (recharging)
- message_host("command=nack&cause=recharge")
- return
-
- var/datum/computer/file/coords/coords = signal.data_file
- if (!istype(coords))
- message_host("command=nack")
- return
-
- var/original_realx = realx
- var/original_realy = realy
- var/original_realz = realz
-
- realx = coords.origx
- realy = coords.origy
- realz = coords.origz
-
-
- var/turf/sourceturf = doturfcheck(0)
- realx = coords.destx
- realy = coords.desty
- realz = coords.destz
-
- var/turf/endturf = doturfcheck(0)
- if (istype(sourceturf) && istype(endturf))
- if (coords.can_cheat || (is_allowed(endturf) && is_allowed(sourceturf)))
- src.receive(sourceturf)
- SPAWN_DBG(5 SECONDS) //nurf
- src.send(endturf)
- message_host("command=ack")
-
- else
- src.message_host("command=nack&cause=interference")
-
- else
- src.message_host("command=nack&cause=badxyz")
-
- realx = original_realx
- realy = original_realy
- realz = original_realz
-
- if ("portal")
- if (src.start_portal || src.end_portal)
- if (start_portal)
- qdel(start_portal)
- start_portal = null
- if (end_portal)
- qdel(end_portal)
- end_portal = null
-
- message_host("command=ack")
- return
-
- if (recharging)
- message_host("command=nack&cause=recharge")
- return
-
- src.icon_state = "pad1"
- recharging = 1
- SPAWN_DBG(0)
-
- var/turf/turfcheck = doturfcheck(1)
- if(!istype(turfcheck))
- if (isnum(turfcheck))
- src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
- else
- src.message_host("command=nack&cause=badxyz")
- sleep(10)
- src.badreceive()
- else if(!is_allowed(turfcheck))
- src.message_host("command=nack&cause=interference")
- else
- message_host("command=ack")
- sleep(10)
- src.doubleportal(turfcheck)
- sleep(5)
-
- src.icon_state = "pad0"
- sleep(10)
-
- recharging = 0
-
- if ("scan")
- var/turf/scanTurf = doturfcheck(1)
- if(!scanTurf)
- message_host("command=nack&cause=badxyz")
- return
- else
- if (isnum(scanTurf))
- src.message_host("command=nack&cause=bad[scanTurf & 1 ? "x" : null][scanTurf & 2 ? "y" : null][scanTurf & 4 ? "z" : null]")
-
- else if(!istype(scanTurf, /turf/space))
- var/datum/gas_mixture/GM = scanTurf.return_air()
- var/burning = 0
- if(istype(scanTurf, /turf/simulated))
- var/turf/simulated/T = scanTurf
- if(T.active_hotspot)
- burning = 1
- message_host("command=scan_reply&o2=[GM.oxygen]&tox=[GM.toxins]&n2=[GM.nitrogen]&co2=[GM.carbon_dioxide]&temp=[GM.temperature]&pressure=[GM.return_pressure()][(burning)?("&burning=1"):(null)]")
- else
- message_host("command=scan_reply&cause=noatmos")
-
- return
-
- if("term_ping")
- if(target != src.host_id)
- return
- if(signal.data["data"] == "reply")
- src.post_status(target, "command","term_ping")
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- return
-
- if("term_disconnect")
- if(target == src.host_id)
- src.host_id = null
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- src.updateUsrDialog()
- return
-
- return
-
- process()
- if(status & (NOPOWER|BROKEN))
- if (start_portal || end_portal)
- qdel(start_portal)
- start_portal = null
- qdel(end_portal)
- end_portal = null
- badreceive()
-
- return
-
- use_power(200)
-
- if (start_portal || end_portal)
- use_power(50000) //Apparently this could run indefinitely on solar power. Fuck that. 25 000 -> 250 000
- if(prob(1))
- badreceive()
-
- if(!host_id || !link)
- return
-
- if(src.timeout == 0)
- src.post_status(host_id, "command","term_disconnect","data","timeout")
- src.host_id = null
- src.updateUsrDialog()
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- else
- src.timeout--
- if(src.timeout <= 5 && !src.timeout_alert)
- src.timeout_alert = 1
- src.post_status(src.host_id, "command","term_ping","data","reply")
-
- return
-
- proc/message_host(var/message, var/datum/computer/file/file)
- if (!src.host_id || !message)
- return
-
- if (session)
- message += "&session=[session]"
-
- if (file)
- src.post_file(src.host_id,"data",message, file)
- else
- src.post_status(src.host_id,"command","term_message","data",message)
-
- return
-
- proc/doturfcheck(var/notify_invalid)
- var/turf/realturf = null
- var/xisbad = (realx < 1 || realx > world.maxx) || (realx - round(realx) != 0) ? 1 : 0;
- var/yisbad = (realy < 1 || realy > world.maxy) || (realy - round(realy) != 0) ? 1 : 0;
- var/zisbad = (realz < 1 || realz > world.maxz) || (realz - round(realz) != 0) ? 1 : 0;
- if (!xisbad && !yisbad && !zisbad)
- realturf = locate(realx, realy, realz)
- else if (notify_invalid)
- realturf = 0
- realturf |= (xisbad * 1) | (yisbad * 2) | (zisbad * 4)
-
- return realturf
-
- proc/is_allowed(var/turf/T)
-
- for (var/atom in teleport_jammers)
- var/atom/A = atom
- if (get_dist(T,A) <= 5)
- if (istype(atom, /obj/machinery/telejam))
- var/obj/machinery/telejam/TJ = atom
- if (!TJ.active)
- continue
- var/r = get_dist(TJ, T)
- if (r > TJ.range)
- continue
- return 0
-
- if (get_dist(T,A) <= 4)
- if (istype(atom, /obj/item/device/flockblocker))
- var/obj/item/device/flockblocker/F = atom
- if (!F.active)
- continue
- var/r = get_dist(F, T)
- if (r > F.range)
- continue
- return 0
-
- for (var/obj/blob/nucleus/N in range(T, 4))
- return 0
-
-
- // first check the always allowed turfs from map landmarks
- if (T in telesci)
- return 1
-
- if ((istype(T.loc,/area) && T.loc:teleport_blocked) || isrestrictedz(T.z))
- return 0
-
- if (istype(T.loc, /area/shuttle/escape/station) && !T.canpass())
- return 0//forgive me pls
-
- return 1
-
- proc/send(var/turf/target)
- if (!target)
- return 1
-
- var/list/stuff = list()
- for(var/atom/movable/O as obj|mob in src.loc)
- if(O.anchored) continue
- if(O == src) continue
- stuff.Add(O)
- if (stuff.len)
- var/atom/movable/which = pick(stuff)
- if(ismob(which))
- logTheThing("station", usr, which, "sent %target% to [showCoords(target.x, target.y, target.z)] from [showCoords(src.x, src.y, src.z)] with a telepad")
- which.set_loc(target)
-
- showswirl(src.loc)
- leaveresidual(src.loc)
- showswirl(target)
- leaveresidual(target)
- use_power(1500)
- if(prob(2) && prob(2))
- src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
- XSUBTRACT = rand(0,100)
- YSUBTRACT = rand(0,100)
- ZSUBTRACT = rand(0,world.maxz)
- SPAWN_DBG(1 SECOND)
- processbadeffect(pick("flash","buzz","scatter","ignite","chill"))
-
- return 0
-
- proc/receive(var/turf/receiveturf)
- if (!receiveturf)
- //boutput(usr, "Unknown interference prevents teleportation from that location!")
- return 1
-
- var/list/stuff = list()
- for(var/atom/movable/O as obj|mob in receiveturf)
- if(O.anchored) continue
- stuff.Add(O)
- if (stuff.len)
- var/atom/movable/which = pick(stuff)
- if(ismob(which))
- logTheThing("station", usr, which, "received %target% from [showCoords(which.x, which.y, which.z)] to [showCoords(src.x, src.y, src.z)] with a telepad")
- which.set_loc(src.loc)
- showswirl(src.loc)
- leaveresidual(src.loc)
- showswirl(receiveturf)
- leaveresidual(receiveturf)
- use_power(1500)
- if(prob(2) && prob(2))
- src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
- XSUBTRACT = rand(0,100)
- YSUBTRACT = rand(0,100)
- ZSUBTRACT = rand(0,world.maxz)
- SPAWN_DBG(5 DECI SECONDS)
- processbadeffect(pick("flash","buzz","minorsummon","tinyfire","chill"))
-
- return 0
-
- proc/doubleportal(var/turf/target)
- if (!target)
- return 1
-
- var/list/send = list()
- var/list/receive = list()
- for(var/atom/movable/O as obj|mob in src.loc)
- if(O.anchored) continue
- send.Add(O)
- for(var/atom/movable/O as obj|mob in target)
- if(O.anchored) continue
- receive.Add(O)
- for(var/atom/movable/O in send)
- O.set_loc(target)
- if(ismob(O))
- logTheThing("station", usr, O, "sent %target% to [showCoords(target.x, target.y, target.z)] from [showCoords(src.x, src.y, src.z)] with a telepad")
-
- for(var/atom/movable/O in receive)
- if(ismob(O))
- logTheThing("station", usr, O, "received %target% from [showCoords(O.x, O.y, O.z)] to [showCoords(src.x, src.y, src.z)] with a telepad")
- O.set_loc(src.loc)
- showswirl(src.loc)
- showswirl(target)
- use_power(500000)
- if(prob(2))
- src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
- XSUBTRACT = rand(0,100)
- YSUBTRACT = rand(0,100)
- ZSUBTRACT = rand(0,world.maxz)
- SPAWN_DBG(1 SECOND)
- processbadeffect(pick("flash","buzz","scatter","ignite","chill"))
- if(prob(5) && !locate(/obj/dfissure_to) in get_step(src, EAST))
- new/obj/dfissure_to(get_step(src, EAST))
- else
- start_portal = makeportal(src.loc, target)
- if (start_portal)
- end_portal = makeportal(target, src.loc)
- logTheThing("station", usr, null, "created a portal to [log_loc(target)] at [log_loc(src.loc)] with a telepad")
-
- proc/makeportal(var/turf/newloc, var/turf/destination)
- var/obj/perm_portal/P = new /obj/perm_portal (newloc)
- P.target = destination
- return P
-
- proc/badsend()
- showswirl(src.loc)
-
- var/effect = ""
- if(prob(90)) //MINOR EFFECTS
- effect = pick("flash","buzz","scatter","ignite","chill")
- else if(prob(80)) //MEDIUM EFFECTS
- effect = pick("tempblind","minormutate","sorium","rads","fire","widescatter","brute")
- else //MAJOR EFFECTS
- effect = pick("gib","majormutate","mutatearea","fullscatter")
- logTheThing("station", usr, null, "sends the telepad at [log_loc(src)] on invalid coords, causing the [effect] effect.")
- processbadeffect(effect)
-
- proc/badreceive()
- showswirl(src.loc)
-
- var/effect = ""
- if(prob(80)) //MINOR EFFECTS
- effect = pick("flash","buzz","minorsummon","tinyfire","chill")
- else if(prob(80)) //MEDIUM EFFECTS
- effect = pick("mediumsummon","sorium","rads","fire","getrandom")
- else //MAJOR EFFECTS
- effect = pick("mutatearea","areascatter","majorsummon")
- logTheThing("station", usr, null, "receives the telepad at [log_loc(src)] on invalid coords, causing the [effect] effect.")
- processbadeffect(effect)
-
- proc/processbadeffect(var/effect)
- switch(effect)
- if("")
- return
- if("flash")
- for(var/mob/O in AIviewers(src, null)) O.show_message("A bright flash emnates from the [src]!", 1)
- playsound(src.loc, "sound/weapons/flashbang.ogg", 50, 1)
- for (var/mob/N in viewers(src, null))
- if (get_dist(N, src) <= 6)
- N.apply_flash(30, 5)
- if (N.client)
- shake_camera(N, 6, 4)
- return
- if("buzz")
- for(var/mob/O in AIviewers(src, null)) O.show_message("You hear a loud buzz coming from the [src]!", 1)
- playsound(src.loc, "sound/machines/buzz-sigh.ogg", 50, 1)
- return
- if("scatter") //stolen from hand tele, heh
- var/list/turfs = new
- var/turf/target = null
- for(var/turf/T in orange(5,src.loc))
- if(T.x>world.maxx-4 || T.x<4) continue
- if(T.y>world.maxy-4 || T.y<4) continue
- if (is_allowed(T))
- turfs += T
- if(turfs && turfs.len)
- for(var/atom/movable/O as obj|mob in src.loc)
- if(O.anchored) continue
- target = pick(turfs)
- if(target) O.set_loc(target)
- qdel(turfs)
- return
- if("ignite")
- for(var/mob/living/carbon/M in src.loc)
- M.update_burning(30)
- boutput(M, "You catch fire!")
- return
- if("chill")
- for(var/mob/living/carbon/M in src.loc)
- M.bodytemperature -= 100
- boutput(M, "You feel colder!")
- return
- if("tempblind")
- for(var/mob/living/carbon/M in src.loc)
- M.take_eye_damage(10, 1)
- boutput(M, "You can't see anything!")
- return
- if("minormutate")
- for(var/mob/living/carbon/M in src.loc)
- M:bioHolder:RandomEffect("bad")
- return
- if("sorium") // stolen from sorium, obviously
- explosion(src, src.loc, -1, -1, -1, 4)
- var/myturf = src.loc
- for(var/atom/movable/M in view(4, myturf))
- if(M.anchored) continue
- if(ismob(M)) if(hasvar(M,"weakened")) M:changeStatus("weakened", 80)
- if(ismob(M)) random_brute_damage(M, 20)
- var/dir_away = get_dir(myturf,M)
- var/turf/target = get_step(myturf,dir_away)
- M.throw_at(target, 10, 2)
- return
- if("rads")
- for(var/turf/T in view(5,src.loc))
- if(!T.reagents)
- var/datum/reagents/R = new/datum/reagents(1000)
- T.reagents = R
- R.my_atom = T
- T.reagents.add_reagent("radium", 20)
- for(var/mob/O in AIviewers(src, null)) O.show_message("The area surrounding the [src] begins to glow bright green!", 1)
- return
- if("fire")
- fireflash(src.loc, 6) // cogwerks - lowered from 8, too laggy
- for(var/mob/O in AIviewers(src, null)) O.show_message("A huge wave of fire explodes out from the [src]!", 1)
- return
- if("widescatter")
- var/list/turfs = new
- var/turf/target = null
- for(var/turf/T in orange(30,src.loc))
- if(T.x>world.maxx-4 || T.x<4) continue
- if(T.y>world.maxy-4 || T.y<4) continue
- if (is_allowed(T))
- turfs += T
- if(turfs && turfs.len)
- for(var/atom/movable/O as obj|mob in src.loc)
- if(O.anchored) continue
- target = pick(turfs)
- if(target) O.set_loc(target)
- qdel(turfs)
- return
- if("brute")
- for(var/mob/living/M in src.loc)
- M.TakeDamage("chest", rand(20,30), 0)
- boutput(M, "You feel like you're being pulled apart!")
- return
- if("gib")
- for(var/mob/living/M in src.loc)
- M.gib()
- return
- if("majormutate")
- for(var/mob/living/carbon/M in src.loc)
- M:bioHolder:RandomEffect("bad")
- M:bioHolder:RandomEffect("bad")
- M:bioHolder:RandomEffect("bad")
- M:bioHolder:RandomEffect("bad")
- M:bioHolder:RandomEffect("bad")
- return
- if("mutatearea")
- for(var/mob/living/carbon/M in orange(5,src.loc))
- M:bioHolder:RandomEffect("bad")
- for(var/mob/O in AIviewers(src, null)) O.show_message("A bright green pulse emnates from the [src]!", 1)
- return
- if("explosion")
- explosion(src, src.loc, 0, 0, 5, 10)
- return
- if("fullscatter")
- var/list/turfs = new
- var/turf/target = null
- for(var/turf/T in world)
- LAGCHECK(LAG_LOW)
- if(T.x>world.maxx-4 || T.x<4) continue
- if(T.y>world.maxy-4 || T.y<4) continue
- if (is_allowed(T))
- turfs += T
- if(turfs && turfs.len)
- for(var/atom/movable/O as obj|mob in src.loc)
- if(O.anchored) continue
- target = pick(turfs)
- if(target) O.set_loc(target)
- qdel(turfs)
- return
- if("minorsummon")
- var/summon = pick("pig","mouse","roach","rockworm")
- switch(summon)
- if("pig")
- var/obj/critter/pig/P = new /obj/critter/pig
- P.set_loc(src.loc)
- if("mouse")
- for(var/i=1,iThe area surrounding the [src] bursts into flame!", 1)
- return
- if("mediumsummon")
- var/summon = pick("maneater","killertomato","bee","golem","magiczombie","mimic")
- switch(summon)
- if("maneater")
- var/obj/critter/maneater/P = new /obj/critter/maneater
- P.set_loc(src.loc)
- if("killertomato")
- var/obj/critter/killertomato/P = new /obj/critter/killertomato
- P.set_loc(src.loc)
- if("bee")
- var/obj/critter/spacebee/P = new /obj/critter/spacebee
- P.set_loc(src.loc)
- if("golem")
- var/obj/critter/golem/P = new /obj/critter/golem
- P.set_loc(src.loc)
- if("magiczombie")
- var/obj/critter/magiczombie/P = new /obj/critter/magiczombie
- P.set_loc(src.loc)
- if("mimic")
- var/obj/critter/mimic/P = new /obj/critter/mimic
- P.set_loc(src.loc)
- //if("mimic2") // Not much of a mimic. Doesn't use the current toolbox sprite (Convair880).
- // var/obj/critter/mimic2/P = new /obj/critter/mimic2
- // P.set_loc(src.loc)
- return
- if("getrandom")
- var/turfs = list()
- for(var/turf/T in world)
- LAGCHECK(LAG_LOW)
- if(!contents) continue
- if(isrestrictedz(T.z)) continue
- turfs += T
- var/turf = pick(turfs)
- for(var/atom/movable/O as obj|mob in turf)
- O.set_loc(src.loc)
- return
- if("areascatter")
- var/list/turfs = new
- var/turf/target = null
- for(var/turf/T in orange(10,src.loc))
- if(T.x>world.maxx-4 || T.x<4) continue
- if(T.y>world.maxy-4 || T.y<4) continue
- if (is_allowed(T))
- turfs += T
- if (turfs && turfs.len)
- for(var/atom/movable/O as obj|mob in oview(src,5))
- if(O.anchored) continue
- target = pick(turfs)
- if(target) O.set_loc(target)
- qdel(turfs)
- return
- if("majorsummon")
- var/summon = pick("zombie","bear","syndicate","martian","lion","yeti","drone","ancient")
- switch(summon)
- if("maneater")
- var/obj/critter/zombie/P = new /obj/critter/zombie
- P.set_loc(src.loc)
- if("bear")
- var/obj/critter/bear/P = new /obj/critter/bear
- P.set_loc(src.loc)
- if("syndicate")
- var/mob/living/carbon/human/npc/syndicate/P = new /mob/living/carbon/human/npc/syndicate
- P.set_loc(src.loc)
- if("martian")
- var/obj/critter/martian/soldier/P = new /obj/critter/martian/soldier
- P.set_loc(src.loc)
- if("lion")
- var/obj/critter/lion/P = new /obj/critter/lion
- P.set_loc(src.loc)
- if("yeti")
- var/obj/critter/yeti/P = new /obj/critter/yeti
- P.set_loc(src.loc)
- if("drone")
- var/obj/critter/gunbot/drone/P = new /obj/critter/gunbot/drone
- P.set_loc(src.loc)
- if("ancient")
- var/obj/critter/ancient_thing/P = new /obj/critter/ancient_thing
- P.set_loc(src.loc)
- return
-
-
-/obj/machinery/networked/teleconsole
- icon = 'icons/obj/computer.dmi'
- icon_state = "s_teleport"
- name = "teleport computer"
- density = 1
- anchored = 1
- device_tag = "SRV_TERMINAL"
- timeout = 10
- mats = 14
- var/xtarget = 0
- var/ytarget = 0
- var/ztarget = 0
-
- var/list/bookmarks = new/list()
- var/max_bookmarks = 5
- var/allow_bookmarks = 1
- var/allow_scan = 1
- var/coord_update_flag = 1
-
- var/readout = " "
- var/datum/computer/file/record/user_data
- var/padNum = 1
-
- New()
- ..()
- SPAWN_DBG(5 DECI SECONDS)
- src.net_id = generate_net_id(src)
-
- if(!src.link)
- var/turf/T = get_turf(src)
- var/obj/machinery/power/data_terminal/test_link = locate() in T
- if(test_link && !test_link.is_valid_master(test_link.master))
- src.link = test_link
- src.link.master = src
-
- receive_signal(datum/signal/signal)
- if(status & (NOPOWER|BROKEN) || !src.link)
- return
-
- if(!signal || !src.net_id || signal.encryption)
- return
-
- if(signal.transmission_method != TRANSMISSION_WIRE)
- return
-
- var/target = signal.data["sender"]
-
- if(signal.data["address_1"] != src.net_id)
- if((signal.data["address_1"] == "ping") && ((signal.data["net"] == null) || ("[signal.data["net"]]" == "[src.net_number]")) && signal.data["sender"])
- SPAWN_DBG(5 DECI SECONDS)
- src.post_status(target, "command", "ping_reply", "device", src.device_tag, "netid", src.net_id, "net", "[net_number]")
-
- return
-
- var/sigcommand = lowertext(signal.data["command"])
- if(!sigcommand || !signal.data["sender"])
- return
-
- switch(sigcommand)
- if("term_connect") //Terminal interface stuff.
- if(target == src.host_id)
- src.host_id = null
- src.updateUsrDialog()
- SPAWN_DBG(3 DECI SECONDS)
- src.post_status(target, "command","term_disconnect")
- return
-
- if(src.host_id)
- return
-
- if (!istype(user_data))
- user_data = new
-
- user_data.fields["userid"] = "telepad"
- user_data.fields["access"] = "11"
-
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- src.host_id = target
- src.old_host_id = src.host_id
- if(signal.data["data"] != "noreply" && src.link)
- //src.post_status(target, "command","term_connect","data","noreply","device",src.device_tag)
- var/datum/signal/newsignal = get_free_signal()
- newsignal.source = src
- newsignal.transmission_method = TRANSMISSION_WIRE
- newsignal.data["command"] = "term_connect"
- newsignal.data["data"] = "noreply"
- newsignal.data["device"] = src.device_tag
-
- newsignal.data_file = user_data.copy_file()
-
- newsignal.data["address_1"] = target
- newsignal.data["sender"] = src.net_id
-
- src.link.post_signal(src, newsignal)
-
- src.updateUsrDialog(1)
- //SPAWN_DBG(2 DECI SECONDS) //Sign up with the driver (if a mainframe contacted us)
- // src.post_status(target,"command","term_message","data","command=register")
- return
-
- if("term_ping")
- if(target != src.host_id)
- return
- if(signal.data["data"] == "reply")
- src.post_status(target, "command","term_ping")
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- return
-
- if("term_message","term_file")
- var/message = signal.data["data"]
- if (message)
- message = replacetext(message, "|n", "
")
-
- src.readout = copytext(message,9,256)
-
- src.updateUsrDialog(1)
- return
-
- if("term_disconnect")
- if(target == src.host_id)
- src.host_id = null
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- src.updateUsrDialog()
- return
-
- return
-
- attack_hand(var/mob/user as mob)
- if (..(user))
- return
-
- var/dat = "Teleport Computer
"
- if (!host_id)
- dat += "NO CONNECTION TO HOST
Retry
"
- else
- dat += "[readout]
"
-
- dat += {""}
-
- dat += "Target Coordinates
"
- dat += "X: (<<)(<) [xtarget] (>)(>>)
"
- dat += "Y: (<<)(<) [ytarget] (>)(>>)
"
- dat += "Z: (<) [ztarget] (>)"
- dat += "
Send"
- dat += "
Receive"
-
- dat += "
Toggle Portal"
-
- if(allow_scan)
- dat += "
Scan"
-
- if(allow_bookmarks)
- dat += "
Add Bookmark"
-
- if(allow_bookmarks && bookmarks.len)
- dat += "
Bookmarks:"
- for (var/datum/teleporter_bookmark/b in bookmarks)
- dat += "
[b.name] ([b.x]/[b.y]/[b.z]) Restore Delete"
-
- dat += "
Reset Connection"
-
- if (src.panel_open)
- dat += "
Linked Pad Number: [src.padNum]
"
- dat += net_switch_html()
-
- user.machine = src
- user.Browse(dat, "window=t_computer;size=400x600")
- onclose(user, "t_computer")
- return
-
- attackby(obj/item/W as obj, mob/user as mob)
- if (isscrewingtool(W))
- playsound(src.loc, "sound/items/Screwdriver.ogg", 50, 1)
- src.panel_open = !src.panel_open
- boutput(user, "You [src.panel_open ? "unscrew" : "secure"] the cover.")
- src.updateUsrDialog()
- return
-
- else
- return ..()
-
-
- updateUsrDialog(var/updateReadout)
- var/list/nearby = viewers(1, src)
- for(var/mob/M in nearby)
- if ((M.client && M.machine == src))
- if (updateReadout)
- M << output(url_encode(src.readout), "t_computer.browser:updateReadout")
- else
- src.attack_hand(M)
-
- if (issilicon(usr))
- if (!(usr in nearby))
- if (usr.client && usr.machine==src)
- if (updateReadout)
- usr << output(url_encode(src.readout), "t_computer.browser:updateReadout")
- else
- src.attack_ai(usr)
-
- Topic(href, href_list)
- if (..(href, href_list))
- return
-
- usr.machine = src
- playsound(src.loc, 'sound/machines/keypress.ogg', 50, 1, 5)
-
- if (href_list["scan"])
- if (!host_id)
- boutput(usr, "Error: No host connection!")
- return
-
- if (coord_update_flag)
- coord_update_flag = 0
- message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
-
- message_host("command=teleman&args=scan")
- src.updateUsrDialog(1)
- return
-
- if (href_list["reconnect"])
- if ((host_id && href_list["reconnect"] != "2") || !old_host_id || !src.link)
- return
-
- if (href_list["reconnect"] == "2")
- host_id = null
-
- var/old = old_host_id
- old_host_id = null
- var/datum/signal/newsignal = get_free_signal()
- newsignal.source = src
- newsignal.transmission_method = TRANSMISSION_WIRE
- newsignal.data["command"] = "term_connect"
- newsignal.data["device"] = src.device_tag
-
- newsignal.data_file = user_data.copy_file()
-
- newsignal.data["address_1"] = old
- newsignal.data["sender"] = src.net_id
-
- src.link.post_signal(src, newsignal)
- SPAWN_DBG(1 SECOND)
- if (!old_host_id)
- old_host_id = old
-
- if (href_list["restorebookmark"])
- var/datum/teleporter_bookmark/bm = locate(href_list["restorebookmark"]) in bookmarks
- if(!bm) return
- xtarget = bm.x
- ytarget = bm.y
- ztarget = bm.z
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- if (href_list["deletebookmark"])
- var/datum/teleporter_bookmark/bm = locate(href_list["deletebookmark"]) in bookmarks
- if(!bm) return
- bookmarks.Remove(bm)
- src.updateUsrDialog()
- return
-
- if (href_list["addbookmark"])
- if(bookmarks.len >= max_bookmarks)
- boutput(usr, "Maximum number of Bookmarks reached.")
- return
- var/datum/teleporter_bookmark/bm = new
- var/title = input(usr,"Enter name:","Name","New Bookmark") as text
- title = copytext(adminscrub(title), 1, 128)
- if(!length(title)) return
- bm.name = title
- bm.x = xtarget
- bm.y = ytarget
- bm.z = ztarget
- bookmarks.Add(bm)
- src.updateUsrDialog()
- playsound(src.loc, "keyboard", 50, 1, 5)
- return
-
- if (href_list["setpad"])
- src.padNum = (src.padNum & 3) + 1
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- if (href_list["decreaseX"])
- var/change = text2num(href_list["decreaseX"])
- xtarget = min(max(0, xtarget-change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["increaseX"])
- var/change = text2num(href_list["increaseX"])
- xtarget = min(max(0, xtarget+change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["setX"])
- var/change = input(usr,"Target X:","Enter target X coordinate",xtarget) as num
- if(!isnum(change))
- return
- xtarget = min(max(0, change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["decreaseY"])
- var/change = text2num(href_list["decreaseY"])
- ytarget = min(max(0, ytarget-change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["increaseY"])
- var/change = text2num(href_list["increaseY"])
- ytarget = min(max(0, ytarget+change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["setY"])
- var/change = input(usr,"Target Y:","Enter target Y coordinate",ytarget) as num
- if(!isnum(change))
- return
- ytarget = min(max(0, change),500)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["decreaseZ"])
- var/change = text2num(href_list["decreaseZ"])
- ztarget = min(max(0, ztarget-change),14)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["increaseZ"])
- var/change = text2num(href_list["increaseZ"])
- ztarget = min(max(0, ztarget+change),14)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["setZ"])
- var/change = input(usr,"Target Z:","Enter target Z coordinate",ztarget) as num
- if(!isnum(change))
- return
- ztarget = min(max(0, change),14)
- coord_update_flag = 1
- src.updateUsrDialog()
- return
-
- else if (href_list["send"])
- if (!host_id)
- boutput(usr, "Error: No host connection!")
- return
-
- if (coord_update_flag)
- coord_update_flag = 0
- message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
-
- message_host("command=teleman&args=-p [padNum] send")
-
- return
-
- else if (href_list["receive"])
- if (!host_id)
- boutput(usr, "Error: No host connection!")
- return
-
- if (coord_update_flag)
- coord_update_flag = 0
- message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
-
- message_host("command=teleman&args=-p [padNum] receive")
-
- return
-
- else if (href_list["portal"])
- if (coord_update_flag)
- coord_update_flag = 0
- message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
-
- message_host("command=teleman&args=-p [padNum] portal toggle")
-
- return
-
- else
- usr.Browse(null, "window=t_computer")
- src.updateUsrDialog()
- return
-
- process()
- if(status & (NOPOWER|BROKEN))
- return
- use_power(200)
-
- if(!host_id || !link)
- return
-
- if(src.timeout == 0)
- src.post_status(host_id, "command","term_disconnect","data","timeout")
- src.host_id = null
- src.updateUsrDialog()
- src.timeout = initial(src.timeout)
- src.timeout_alert = 0
- else
- src.timeout--
- if(src.timeout <= 5 && !src.timeout_alert)
- src.timeout_alert = 1
- src.post_status(src.host_id, "command","term_ping","data","reply")
-
- return
-
- proc/message_host(var/message, var/datum/computer/file/file)
- if (!src.host_id || !message)
- return
-
- if (file)
- src.post_file(src.host_id,"data",message, file)
- else
- src.post_status(src.host_id,"command","term_message","data",message)
-
+/datum/computer/file/coords
+ name = "coordinates"
+ extension = "GPS"
+ var/destx = 0
+ var/desty = 0
+ var/destz = 0
+
+ var/origx = 0 //Only used for relaying stuff.
+ var/origy = 0 //Fun for people who can't spell.
+ var/origz = 0
+
+ var/can_cheat = 0 //Flag to ignore destination restrictions.
+
+var/telesci_modifiers_set = 0
+
+proc/is_teleportation_allowed(var/turf/T)
+ for (var/atom in teleport_jammers)
+ if (istype(atom, /obj/machinery/telejam))
+ var/obj/machinery/telejam/TJ = atom
+ if (!TJ.active)
+ continue
+ if(DIST_CHECK(TJ, T, TJ.range))
+ return 0
+ if (istype(atom, /obj/item/device/flockblocker))
+ var/obj/item/device/flockblocker/F = atom
+ if (!F.active)
+ continue
+ if(DIST_CHECK(F, T, F.range))
+ return 0
+
+ for (var/X in by_type[/obj/blob/nucleus])
+ var/obj/blob/nucleus/N = X
+ if(DIST_CHECK(N, T, 3))
+ return 0
+
+ // first check the always allowed turfs from map landmarks
+ if (T in telesci)
+ return 1
+
+ if ((istype(T.loc,/area) && T.loc:teleport_blocked) || isrestrictedz(T.z))
+ return 0
+
+ if (istype(T.loc, /area/shuttle/escape/station) && !T.canpass())
+ return 0//forgive me pls
+
+ return 1
+
+/obj/machinery/networked/telepad
+ icon = 'icons/obj/stationobjs.dmi'
+ icon_state = "pad0"
+ name = "teleport pad"
+ anchored = 1
+ density = 0
+ layer = FLOOR_EQUIP_LAYER1
+ mats = 16
+ timeout = 10
+ desc = "Stand on this to have your wildest dreams come true!"
+ device_tag = "PNET_S_TELEPAD"
+ var/recharging = 0
+ var/realx = 0
+ var/realy = 0
+ var/realz = 0
+ var/tmp/session = null
+ var/obj/perm_portal/start_portal
+ var/obj/perm_portal/end_portal
+ var/image/disconnectedImage
+
+ New()
+ ..()
+ if (!telesci_modifiers_set)
+ telesci_modifiers_set = 1
+ XMULTIPLY = pick(1,2,4) //If it is three, perfect precision is impossible because fractions will be recurring.
+ XSUBTRACT = rand(0,100)
+ YMULTIPLY = pick(1,2,4) // same as above
+ YSUBTRACT = rand(0,100)
+ ZSUBTRACT = rand(0,world.maxz)
+
+ disconnectedImage = image('icons/obj/stationobjs.dmi', "pad-noconnect")
+
+ SPAWN_DBG(0.5 SECONDS)
+ src.net_id = generate_net_id(src)
+
+ if(!src.link)
+ var/turf/T = get_turf(src)
+ var/obj/machinery/power/data_terminal/test_link = locate() in T
+ if(test_link && !test_link.is_valid_master(test_link.master))
+ src.link = test_link
+ src.link.master = src
+
+ ex_act()
+ return
+
+ examine()
+ set src in view()
+ ..()
+ if (!src.host_id)
+ boutput(usr, "The [src.name]'s \"disconnected from host\" light is flashing.")
+
+ attack_hand(mob/user as mob)
+ if(..())
+ return
+
+ user.machine = src
+
+ var/dat = "Telepad"
+
+ var/readout_color = "#000000"
+ var/readout = "ERROR"
+ if(src.host_id)
+ readout_color = "#33FF00"
+ readout = "OK CONNECTION"
+ else
+ readout_color = "#F80000"
+ readout = "NO CONNECTION"
+
+ dat += "Host Connection: "
+ dat += "
"
+
+ dat += "Reset Connection
"
+
+ if (src.panel_open)
+ dat += net_switch_html()
+
+ user.Browse(dat,"window=telepad;size=245x302")
+ onclose(user,"telepad")
+ return
+
+ Topic(href, href_list)
+ if(..())
+ return
+
+ usr.machine = src
+ if (href_list["reset"])
+ if(last_reset && (last_reset + NETWORK_MACHINE_RESET_DELAY >= world.time))
+ return
+
+ if(!host_id && !old_host_id)
+ return
+
+ src.last_reset = world.time
+ var/rem_host = src.host_id ? host_id : old_host_id
+ src.host_id = null
+ //src.old_host_id = null
+ src.post_status(rem_host, "command","term_disconnect")
+ SPAWN_DBG(0.5 SECONDS)
+ src.post_status(rem_host, "command","term_connect","device",src.device_tag)
+
+ src.updateUsrDialog()
+ return
+
+
+ src.add_fingerprint(usr)
+ return
+
+ updateUsrDialog()
+ ..()
+ if (src.host_id)
+ src.overlays.len = 0
+ else if (!src.overlays.len)
+ src.overlays += src.disconnectedImage
+
+ receive_signal(datum/signal/signal)
+ if(status & (NOPOWER|BROKEN) || !src.link)
+ return
+ if(!signal || !src.net_id || signal.encryption)
+ return
+
+ if(signal.transmission_method != TRANSMISSION_WIRE) //No radio for us thanks
+ return
+
+ var/target = signal.data["sender"]
+
+ if(signal.data["address_1"] != src.net_id)
+ if((signal.data["address_1"] == "ping") && ((signal.data["net"] == null) || ("[signal.data["net"]]" == "[src.net_number]")) && signal.data["sender"])
+ SPAWN_DBG(0.5 SECONDS)
+ src.post_status(target, "command", "ping_reply", "device", src.device_tag, "netid", src.net_id, "net", "[net_number]")
+
+ return
+
+ var/sigcommand = lowertext(signal.data["command"])
+ if(!sigcommand || !signal.data["sender"])
+ return
+
+ switch(sigcommand)
+ if("term_connect") //Terminal interface stuff.
+ if(target == src.host_id)
+ src.host_id = null
+ src.updateUsrDialog()
+ SPAWN_DBG(0.3 SECONDS)
+ src.post_status(target, "command","term_disconnect")
+ return
+
+ if(src.host_id)
+ return
+
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ src.host_id = target
+ src.old_host_id = target
+ if(signal.data["data"] != "noreply")
+ src.post_status(target, "command","term_connect","data","noreply","device",src.device_tag)
+ src.updateUsrDialog()
+ SPAWN_DBG(0.2 SECONDS) //Sign up with the driver (if a mainframe contacted us)
+ src.post_status(target,"command","term_message","data","command=register")
+ return
+
+ if("term_message","term_file")
+ if(target != src.host_id) //Huh, who is this?
+ return
+
+ var/list/data = params2list(signal.data["data"])
+ if(!data)
+ return
+
+ session = data["session"]
+
+ switch(data["command"])
+ if ("set_coords")
+ var/datum/computer/file/coords/coords = signal.data_file
+ if (!istype(coords))
+ message_host("command=nack")
+ return
+
+ src.realx = round( max(0, min(coords.destx, world.maxx+1)) )
+ src.realy = round( max(0, min(coords.desty, world.maxy+1)) )
+ src.realz = round( max(0, min(coords.destz, world.maxz+1)) )
+ signal.data_file = null
+ pool(coords)
+ message_host("command=ack")
+
+ if ("send")
+ if (recharging)
+ message_host("command=nack&cause=recharge")
+ return
+
+ src.icon_state = "pad1"
+ recharging = 1
+ SPAWN_DBG(0)
+
+ var/turf/turfcheck = doturfcheck(1)
+ if(!istype(turfcheck))
+ src.badsend()
+ if (isnum(turfcheck))
+ src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
+ else
+ src.message_host("command=nack&cause=badxyz")
+ else if(!is_teleportation_allowed(turfcheck))
+ src.message_host("command=nack&cause=interference")
+ else
+ message_host("command=ack")
+ sleep(10)
+ src.send(turfcheck)
+ sleep(5)
+
+ src.icon_state = "pad0"
+ sleep(10)
+
+ recharging = 0
+
+ if ("receive")
+ if (recharging)
+ message_host("command=nack&cause=recharge")
+ return
+
+ src.icon_state = "pad1"
+ recharging = 1
+ SPAWN_DBG(0)
+
+ var/turf/turfcheck = doturfcheck(1)
+ if(!istype(turfcheck))
+ if (isnum(turfcheck))
+ src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
+ else
+ src.message_host("command=nack&cause=badxyz")
+ sleep(10)
+ src.badreceive()
+ else if(!is_teleportation_allowed(turfcheck))
+ src.message_host("command=nack&cause=interference")
+ else
+ message_host("command=ack")
+ sleep(10)
+ src.receive(turfcheck)
+ sleep(5)
+
+ src.icon_state = "pad0"
+ sleep(10)
+
+ recharging = 0
+
+ if ("relay")
+ if (recharging)
+ message_host("command=nack&cause=recharge")
+ return
+
+ var/datum/computer/file/coords/coords = signal.data_file
+ if (!istype(coords))
+ message_host("command=nack")
+ return
+
+ var/original_realx = realx
+ var/original_realy = realy
+ var/original_realz = realz
+
+ realx = coords.origx
+ realy = coords.origy
+ realz = coords.origz
+
+
+ var/turf/sourceturf = doturfcheck(0)
+ realx = coords.destx
+ realy = coords.desty
+ realz = coords.destz
+
+ var/turf/endturf = doturfcheck(0)
+ recharging = 1
+ if (istype(sourceturf) && istype(endturf))
+ if (coords.can_cheat || (is_teleportation_allowed(endturf) && is_teleportation_allowed(sourceturf)))
+ src.receive(sourceturf)
+ SPAWN_DBG(0)
+ sleep(10)
+ recharging = 0
+ sleep(40)
+ src.send(endturf)
+ message_host("command=ack")
+
+ else
+ src.message_host("command=nack&cause=interference")
+ recharging = 0
+
+ else
+ src.message_host("command=nack&cause=badxyz")
+ recharging = 0
+
+ realx = original_realx
+ realy = original_realy
+ realz = original_realz
+
+ if ("portal")
+ if (src.start_portal || src.end_portal)
+ if (start_portal)
+ qdel(start_portal)
+ start_portal = null
+ if (end_portal)
+ qdel(end_portal)
+ end_portal = null
+
+ message_host("command=ack")
+ return
+
+ if (recharging)
+ message_host("command=nack&cause=recharge")
+ return
+
+ src.icon_state = "pad1"
+ recharging = 1
+ SPAWN_DBG(0)
+
+ var/turf/turfcheck = doturfcheck(1)
+ if(!istype(turfcheck))
+ if (isnum(turfcheck))
+ src.message_host("command=nack&cause=bad[turfcheck & 1 ? "x" : null][turfcheck & 2 ? "y" : null][turfcheck & 4 ? "z" : null]")
+ else
+ src.message_host("command=nack&cause=badxyz")
+ sleep(10)
+ src.badreceive()
+ else if(!is_teleportation_allowed(turfcheck))
+ src.message_host("command=nack&cause=interference")
+ else
+ message_host("command=ack")
+ sleep(10)
+ src.doubleportal(turfcheck)
+ sleep(5)
+
+ src.icon_state = "pad0"
+ sleep(10)
+
+ recharging = 0
+
+ if ("scan")
+ var/turf/scanTurf = doturfcheck(1)
+ if(!scanTurf)
+ message_host("command=nack&cause=badxyz")
+ return
+ else
+ if (isnum(scanTurf))
+ src.message_host("command=nack&cause=bad[scanTurf & 1 ? "x" : null][scanTurf & 2 ? "y" : null][scanTurf & 4 ? "z" : null]")
+
+ else if(!istype(scanTurf, /turf/space))
+ var/datum/gas_mixture/GM = scanTurf.return_air()
+ var/burning = 0
+ if(istype(scanTurf, /turf/simulated))
+ var/turf/simulated/T = scanTurf
+ if(T.active_hotspot)
+ burning = 1
+ message_host("command=scan_reply&o2=[GM.oxygen]&tox=[GM.toxins]&n2=[GM.nitrogen]&co2=[GM.carbon_dioxide]&temp=[GM.temperature]&pressure=[GM.return_pressure()][(burning)?("&burning=1"):(null)]")
+ else
+ message_host("command=scan_reply&cause=noatmos")
+
+ return
+
+ if("term_ping")
+ if(target != src.host_id)
+ return
+ if(signal.data["data"] == "reply")
+ src.post_status(target, "command","term_ping")
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ return
+
+ if("term_disconnect")
+ if(target == src.host_id)
+ src.host_id = null
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ src.updateUsrDialog()
+ return
+
+ return
+
+ process()
+ if(status & (NOPOWER|BROKEN))
+ if (start_portal || end_portal)
+ qdel(start_portal)
+ start_portal = null
+ qdel(end_portal)
+ end_portal = null
+ badreceive()
+
+ return
+
+ use_power(200)
+
+ if (start_portal || end_portal)
+ use_power(50000) //Apparently this could run indefinitely on solar power. Fuck that. 25 000 -> 250 000
+ if(prob(1))
+ badreceive()
+
+ if(!host_id || !link)
+ return
+
+ if(src.timeout == 0)
+ src.post_status(host_id, "command","term_disconnect","data","timeout")
+ src.host_id = null
+ src.updateUsrDialog()
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ else
+ src.timeout--
+ if(src.timeout <= 5 && !src.timeout_alert)
+ src.timeout_alert = 1
+ src.post_status(src.host_id, "command","term_ping","data","reply")
+
+ return
+
+ proc/message_host(var/message, var/datum/computer/file/file)
+ if (!src.host_id || !message)
+ return
+
+ if (session)
+ message += "&session=[session]"
+
+ if (file)
+ src.post_file(src.host_id,"data",message, file)
+ else
+ src.post_status(src.host_id,"command","term_message","data",message)
+
+ return
+
+ proc/doturfcheck(var/notify_invalid)
+ var/turf/realturf = null
+ var/xisbad = (realx < 1 || realx > world.maxx) || (realx - round(realx) != 0) ? 1 : 0;
+ var/yisbad = (realy < 1 || realy > world.maxy) || (realy - round(realy) != 0) ? 1 : 0;
+ var/zisbad = (realz < 1 || realz > world.maxz) || (realz - round(realz) != 0) ? 1 : 0;
+ if (!xisbad && !yisbad && !zisbad)
+ realturf = locate(realx, realy, realz)
+ else if (notify_invalid)
+ realturf = 0
+ realturf |= (xisbad * 1) | (yisbad * 2) | (zisbad * 4)
+
+ return realturf
+
+ proc/send(var/turf/target)
+ if (!target)
+ return 1
+
+ var/list/stuff = list()
+ for(var/atom/movable/O as obj|mob in src.loc)
+ if(O.anchored) continue
+ if(O == src) continue
+ stuff.Add(O)
+ if (stuff.len)
+ var/atom/movable/which = pick(stuff)
+ if(ismob(which))
+ logTheThing("station", usr, which, "sent %target% to [showCoords(target.x, target.y, target.z)] from [showCoords(src.x, src.y, src.z)] with a telepad")
+ which.set_loc(target)
+
+ showswirl(src.loc)
+ leaveresidual(src.loc)
+ showswirl(target)
+ leaveresidual(target)
+ use_power(1500)
+ if(prob(2) && prob(2))
+ src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
+ XSUBTRACT = rand(0,100)
+ YSUBTRACT = rand(0,100)
+ ZSUBTRACT = rand(0,world.maxz)
+ SPAWN_DBG(1 SECOND)
+ processbadeffect(pick("flash","buzz","scatter","ignite","chill"))
+
+ return 0
+
+ proc/receive(var/turf/receiveturf)
+ if (!receiveturf)
+ //boutput(usr, "Unknown interference prevents teleportation from that location!")
+ return 1
+
+ var/list/stuff = list()
+ for(var/atom/movable/O as obj|mob in receiveturf)
+ if(O.anchored) continue
+ stuff.Add(O)
+ if (stuff.len)
+ var/atom/movable/which = pick(stuff)
+ if(ismob(which))
+ logTheThing("station", usr, which, "received %target% from [showCoords(which.x, which.y, which.z)] to [showCoords(src.x, src.y, src.z)] with a telepad")
+ which.set_loc(src.loc)
+ showswirl(src.loc)
+ leaveresidual(src.loc)
+ showswirl(receiveturf)
+ leaveresidual(receiveturf)
+ use_power(1500)
+ if(prob(2) && prob(2))
+ src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
+ XSUBTRACT = rand(0,100)
+ YSUBTRACT = rand(0,100)
+ ZSUBTRACT = rand(0,world.maxz)
+ SPAWN_DBG(0.5 SECONDS)
+ processbadeffect(pick("flash","buzz","minorsummon","tinyfire","chill"))
+
+ return 0
+
+ proc/doubleportal(var/turf/target)
+ if (!target)
+ return 1
+
+ var/list/send = list()
+ var/list/receive = list()
+ for(var/atom/movable/O as obj|mob in src.loc)
+ if(O.anchored) continue
+ send.Add(O)
+ for(var/atom/movable/O as obj|mob in target)
+ if(O.anchored) continue
+ receive.Add(O)
+ for(var/atom/movable/O in send)
+ O.set_loc(target)
+ if(ismob(O))
+ logTheThing("station", usr, O, "sent %target% to [showCoords(target.x, target.y, target.z)] from [showCoords(src.x, src.y, src.z)] with a telepad")
+
+ for(var/atom/movable/O in receive)
+ if(ismob(O))
+ logTheThing("station", usr, O, "received %target% from [showCoords(O.x, O.y, O.z)] to [showCoords(src.x, src.y, src.z)] with a telepad")
+ O.set_loc(src.loc)
+ showswirl(src.loc)
+ showswirl(target)
+ use_power(500000)
+ if(prob(2))
+ src.visible_message("The console emits a loud pop and an acrid smell fills the air!")
+ XSUBTRACT = rand(0,100)
+ YSUBTRACT = rand(0,100)
+ ZSUBTRACT = rand(0,world.maxz)
+ SPAWN_DBG(1 SECOND)
+ processbadeffect(pick("flash","buzz","scatter","ignite","chill"))
+ if(prob(5) && !locate(/obj/dfissure_to) in get_step(src, EAST))
+ new/obj/dfissure_to(get_step(src, EAST))
+ else
+ start_portal = makeportal(src.loc, target)
+ if (start_portal)
+ end_portal = makeportal(target, src.loc)
+ logTheThing("station", usr, null, "created a portal to [log_loc(target)] at [log_loc(src.loc)] with a telepad")
+
+ proc/makeportal(var/turf/newloc, var/turf/destination)
+ var/obj/perm_portal/P = new /obj/perm_portal (newloc)
+ P.target = destination
+ return P
+
+ proc/badsend()
+ showswirl(src.loc)
+
+ var/effect = ""
+ if(prob(90)) //MINOR EFFECTS
+ effect = pick("flash","buzz","scatter","ignite","chill")
+ else if(prob(80)) //MEDIUM EFFECTS
+ effect = pick("tempblind","minormutate","sorium","rads","fire","widescatter","brute")
+ else //MAJOR EFFECTS
+ effect = pick("gib","majormutate","mutatearea","fullscatter")
+ logTheThing("station", usr, null, "sends the telepad at [log_loc(src)] on invalid coords, causing the [effect] effect.")
+ processbadeffect(effect)
+
+ proc/badreceive()
+ showswirl(src.loc)
+
+ var/effect = ""
+ if(prob(80)) //MINOR EFFECTS
+ effect = pick("flash","buzz","minorsummon","tinyfire","chill")
+ else if(prob(80)) //MEDIUM EFFECTS
+ effect = pick("mediumsummon","sorium","rads","fire","getrandom")
+ else //MAJOR EFFECTS
+ effect = pick("mutatearea","areascatter","majorsummon")
+ logTheThing("station", usr, null, "receives the telepad at [log_loc(src)] on invalid coords, causing the [effect] effect.")
+ processbadeffect(effect)
+
+ proc/processbadeffect(var/effect)
+ switch(effect)
+ if("")
+ return
+ if("flash")
+ for(var/mob/O in AIviewers(src, null)) O.show_message("A bright flash emnates from the [src]!", 1)
+ playsound(src.loc, "sound/weapons/flashbang.ogg", 50, 1)
+ for (var/mob/N in viewers(src, null))
+ if (get_dist(N, src) <= 6)
+ N.apply_flash(30, 5)
+ if (N.client)
+ shake_camera(N, 6, 4)
+ return
+ if("buzz")
+ for(var/mob/O in AIviewers(src, null)) O.show_message("You hear a loud buzz coming from the [src]!", 1)
+ playsound(src.loc, "sound/machines/buzz-sigh.ogg", 50, 1)
+ return
+ if("scatter") //stolen from hand tele, heh
+ var/list/turfs = new
+ var/turf/target = null
+ for(var/turf/T in orange(5,src.loc))
+ if(T.x>world.maxx-4 || T.x<4) continue
+ if(T.y>world.maxy-4 || T.y<4) continue
+ if (is_teleportation_allowed(T))
+ turfs += T
+ if(turfs && turfs.len)
+ for(var/atom/movable/O as obj|mob in src.loc)
+ if(O.anchored) continue
+ target = pick(turfs)
+ if(target) O.set_loc(target)
+ qdel(turfs)
+ return
+ if("ignite")
+ for(var/mob/living/carbon/M in src.loc)
+ M.update_burning(30)
+ boutput(M, "You catch fire!")
+ return
+ if("chill")
+ for(var/mob/living/carbon/M in src.loc)
+ M.bodytemperature -= 100
+ boutput(M, "You feel colder!")
+ return
+ if("tempblind")
+ for(var/mob/living/carbon/M in src.loc)
+ M.take_eye_damage(10, 1)
+ boutput(M, "You can't see anything!")
+ return
+ if("minormutate")
+ for(var/mob/living/carbon/M in src.loc)
+ M:bioHolder:RandomEffect("bad")
+ return
+ if("sorium") // stolen from sorium, obviously
+ explosion(src, src.loc, -1, -1, -1, 4)
+ var/myturf = src.loc
+ for(var/atom/movable/M in view(4, myturf))
+ if(M.anchored) continue
+ if(ismob(M)) if(hasvar(M,"weakened")) M:changeStatus("weakened", 80)
+ if(ismob(M)) random_brute_damage(M, 20)
+ var/dir_away = get_dir(myturf,M)
+ var/turf/target = get_step(myturf,dir_away)
+ M.throw_at(target, 10, 2)
+ return
+ if("rads")
+ for(var/turf/T in view(5,src.loc))
+ if(!T.reagents)
+ var/datum/reagents/R = new/datum/reagents(1000)
+ T.reagents = R
+ R.my_atom = T
+ T.reagents.add_reagent("radium", 20)
+ for(var/mob/O in AIviewers(src, null)) O.show_message("The area surrounding the [src] begins to glow bright green!", 1)
+ return
+ if("fire")
+ fireflash(src.loc, 6) // cogwerks - lowered from 8, too laggy
+ for(var/mob/O in AIviewers(src, null)) O.show_message("A huge wave of fire explodes out from the [src]!", 1)
+ return
+ if("widescatter")
+ var/list/turfs = new
+ var/turf/target = null
+ for(var/turf/T in orange(30,src.loc))
+ if(T.x>world.maxx-4 || T.x<4) continue
+ if(T.y>world.maxy-4 || T.y<4) continue
+ if (is_teleportation_allowed(T))
+ turfs += T
+ if(turfs && turfs.len)
+ for(var/atom/movable/O as obj|mob in src.loc)
+ if(O.anchored) continue
+ target = pick(turfs)
+ if(target) O.set_loc(target)
+ qdel(turfs)
+ return
+ if("brute")
+ for(var/mob/living/M in src.loc)
+ M.TakeDamage("chest", rand(20,30), 0)
+ boutput(M, "You feel like you're being pulled apart!")
+ return
+ if("gib")
+ for(var/mob/living/M in src.loc)
+ M.gib()
+ return
+ if("majormutate")
+ for(var/mob/living/carbon/M in src.loc)
+ M:bioHolder:RandomEffect("bad")
+ M:bioHolder:RandomEffect("bad")
+ M:bioHolder:RandomEffect("bad")
+ M:bioHolder:RandomEffect("bad")
+ M:bioHolder:RandomEffect("bad")
+ return
+ if("mutatearea")
+ for(var/mob/living/carbon/M in orange(5,src.loc))
+ M:bioHolder:RandomEffect("bad")
+ for(var/mob/O in AIviewers(src, null)) O.show_message("A bright green pulse emnates from the [src]!", 1)
+ return
+ if("explosion")
+ explosion(src, src.loc, 0, 0, 5, 10)
+ return
+ if("fullscatter")
+ var/list/turfs = new
+ var/turf/target = null
+ for(var/turf/T in world)
+ LAGCHECK(LAG_LOW)
+ if(T.x>world.maxx-4 || T.x<4) continue
+ if(T.y>world.maxy-4 || T.y<4) continue
+ if (is_teleportation_allowed(T))
+ turfs += T
+ if(turfs && turfs.len)
+ for(var/atom/movable/O as obj|mob in src.loc)
+ if(O.anchored) continue
+ target = pick(turfs)
+ if(target) O.set_loc(target)
+ qdel(turfs)
+ return
+ if("minorsummon")
+ var/summon = pick("pig","mouse","roach","rockworm")
+ switch(summon)
+ if("pig")
+ var/obj/critter/pig/P = new /obj/critter/pig
+ P.set_loc(src.loc)
+ if("mouse")
+ for(var/i=1,iThe area surrounding the [src] bursts into flame!", 1)
+ return
+ if("mediumsummon")
+ var/summon = pick("maneater","killertomato","bee","golem","magiczombie","mimic")
+ switch(summon)
+ if("maneater")
+ var/obj/critter/maneater/P = new /obj/critter/maneater
+ P.set_loc(src.loc)
+ if("killertomato")
+ var/obj/critter/killertomato/P = new /obj/critter/killertomato
+ P.set_loc(src.loc)
+ if("bee")
+ var/obj/critter/spacebee/P = new /obj/critter/spacebee
+ P.set_loc(src.loc)
+ if("golem")
+ var/obj/critter/golem/P = new /obj/critter/golem
+ P.set_loc(src.loc)
+ if("magiczombie")
+ var/obj/critter/magiczombie/P = new /obj/critter/magiczombie
+ P.set_loc(src.loc)
+ if("mimic")
+ var/obj/critter/mimic/P = new /obj/critter/mimic
+ P.set_loc(src.loc)
+ //if("mimic2") // Not much of a mimic. Doesn't use the current toolbox sprite (Convair880).
+ // var/obj/critter/mimic2/P = new /obj/critter/mimic2
+ // P.set_loc(src.loc)
+ return
+ if("getrandom")
+ var/turfs = list()
+ for(var/turf/T in world)
+ LAGCHECK(LAG_LOW)
+ if(!contents) continue
+ if(isrestrictedz(T.z)) continue
+ turfs += T
+ var/turf = pick(turfs)
+ for(var/atom/movable/O as obj|mob in turf)
+ O.set_loc(src.loc)
+ return
+ if("areascatter")
+ var/list/turfs = new
+ var/turf/target = null
+ for(var/turf/T in orange(10,src.loc))
+ if(T.x>world.maxx-4 || T.x<4) continue
+ if(T.y>world.maxy-4 || T.y<4) continue
+ if (is_teleportation_allowed(T))
+ turfs += T
+ if (turfs && turfs.len)
+ for(var/atom/movable/O as obj|mob in oview(src,5))
+ if(O.anchored) continue
+ target = pick(turfs)
+ if(target) O.set_loc(target)
+ qdel(turfs)
+ return
+ if("majorsummon")
+ var/summon = pick("zombie","bear","syndicate","martian","lion","yeti","drone","ancient")
+ switch(summon)
+ if("maneater")
+ var/obj/critter/zombie/P = new /obj/critter/zombie
+ P.set_loc(src.loc)
+ if("bear")
+ var/obj/critter/bear/P = new /obj/critter/bear
+ P.set_loc(src.loc)
+ if("syndicate")
+ var/mob/living/carbon/human/npc/syndicate/P = new /mob/living/carbon/human/npc/syndicate
+ P.set_loc(src.loc)
+ if("martian")
+ var/obj/critter/martian/soldier/P = new /obj/critter/martian/soldier
+ P.set_loc(src.loc)
+ if("lion")
+ var/obj/critter/lion/P = new /obj/critter/lion
+ P.set_loc(src.loc)
+ if("yeti")
+ var/obj/critter/yeti/P = new /obj/critter/yeti
+ P.set_loc(src.loc)
+ if("drone")
+ var/obj/critter/gunbot/drone/P = new /obj/critter/gunbot/drone
+ P.set_loc(src.loc)
+ if("ancient")
+ var/obj/critter/ancient_thing/P = new /obj/critter/ancient_thing
+ P.set_loc(src.loc)
+ return
+
+
+/obj/machinery/networked/teleconsole
+ icon = 'icons/obj/computer.dmi'
+ icon_state = "s_teleport"
+ name = "teleport computer"
+ density = 1
+ anchored = 1
+ device_tag = "SRV_TERMINAL"
+ timeout = 10
+ mats = 14
+ var/xtarget = 0
+ var/ytarget = 0
+ var/ztarget = 0
+
+ var/list/bookmarks = new/list()
+ var/max_bookmarks = 5
+ var/allow_bookmarks = 1
+ var/allow_scan = 1
+ var/coord_update_flag = 1
+
+ var/readout = " "
+ var/datum/computer/file/record/user_data
+ var/padNum = 1
+
+ New()
+ ..()
+ SPAWN_DBG(0.5 SECONDS)
+ src.net_id = generate_net_id(src)
+
+ if(!src.link)
+ var/turf/T = get_turf(src)
+ var/obj/machinery/power/data_terminal/test_link = locate() in T
+ if(test_link && !test_link.is_valid_master(test_link.master))
+ src.link = test_link
+ src.link.master = src
+
+ receive_signal(datum/signal/signal)
+ if(status & (NOPOWER|BROKEN) || !src.link)
+ return
+
+ if(!signal || !src.net_id || signal.encryption)
+ return
+
+ if(signal.transmission_method != TRANSMISSION_WIRE)
+ return
+
+ var/target = signal.data["sender"]
+
+ if(signal.data["address_1"] != src.net_id)
+ if((signal.data["address_1"] == "ping") && ((signal.data["net"] == null) || ("[signal.data["net"]]" == "[src.net_number]")) && signal.data["sender"])
+ SPAWN_DBG(0.5 SECONDS)
+ src.post_status(target, "command", "ping_reply", "device", src.device_tag, "netid", src.net_id, "net", "[net_number]")
+
+ return
+
+ var/sigcommand = lowertext(signal.data["command"])
+ if(!sigcommand || !signal.data["sender"])
+ return
+
+ switch(sigcommand)
+ if("term_connect") //Terminal interface stuff.
+ if(target == src.host_id)
+ src.host_id = null
+ src.updateUsrDialog()
+ SPAWN_DBG(0.3 SECONDS)
+ src.post_status(target, "command","term_disconnect")
+ return
+
+ if(src.host_id)
+ return
+
+ if (!istype(user_data))
+ user_data = new
+
+ user_data.fields["userid"] = "telepad"
+ user_data.fields["access"] = "11"
+
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ src.host_id = target
+ src.old_host_id = src.host_id
+ if(signal.data["data"] != "noreply" && src.link)
+ //src.post_status(target, "command","term_connect","data","noreply","device",src.device_tag)
+ var/datum/signal/newsignal = get_free_signal()
+ newsignal.source = src
+ newsignal.transmission_method = TRANSMISSION_WIRE
+ newsignal.data["command"] = "term_connect"
+ newsignal.data["data"] = "noreply"
+ newsignal.data["device"] = src.device_tag
+
+ newsignal.data_file = user_data.copy_file()
+
+ newsignal.data["address_1"] = target
+ newsignal.data["sender"] = src.net_id
+
+ src.link.post_signal(src, newsignal)
+
+ src.updateUsrDialog(1)
+ //SPAWN_DBG(0.2 SECONDS) //Sign up with the driver (if a mainframe contacted us)
+ // src.post_status(target,"command","term_message","data","command=register")
+ return
+
+ if("term_ping")
+ if(target != src.host_id)
+ return
+ if(signal.data["data"] == "reply")
+ src.post_status(target, "command","term_ping")
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ return
+
+ if("term_message","term_file")
+ var/message = signal.data["data"]
+ if (message)
+ message = replacetext(message, "|n", "
")
+
+ src.readout = copytext(message,9,256)
+
+ src.updateUsrDialog(1)
+ return
+
+ if("term_disconnect")
+ if(target == src.host_id)
+ src.host_id = null
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ src.updateUsrDialog()
+ return
+
+ return
+
+ attack_hand(var/mob/user as mob)
+ if (..(user))
+ return
+
+ var/dat = "Teleport Computer
"
+ if (!host_id)
+ dat += "NO CONNECTION TO HOST
Retry
"
+ else
+ dat += "[readout]
"
+
+ dat += {""}
+
+ dat += "Target Coordinates
"
+ dat += "X: (<<)(<) [xtarget] (>)(>>)
"
+ dat += "Y: (<<)(<) [ytarget] (>)(>>)
"
+ dat += "Z: (<) [ztarget] (>)"
+ dat += "
Send"
+ dat += "
Receive"
+
+ dat += "
Toggle Portal"
+
+ if(allow_scan)
+ dat += "
Scan"
+
+ if(allow_bookmarks)
+ dat += "
Add Bookmark"
+
+ if(allow_bookmarks && bookmarks.len)
+ dat += "
Bookmarks:"
+ for (var/datum/teleporter_bookmark/b in bookmarks)
+ dat += "
[b.name] ([b.x]/[b.y]/[b.z]) Restore Delete"
+
+ dat += "
Reset Connection"
+
+ if (src.panel_open)
+ dat += "
Linked Pad Number: [src.padNum]
"
+ dat += net_switch_html()
+
+ user.machine = src
+ user.Browse(dat, "window=t_computer;size=400x600")
+ onclose(user, "t_computer")
+ return
+
+ attackby(obj/item/W as obj, mob/user as mob)
+ if (isscrewingtool(W))
+ playsound(src.loc, "sound/items/Screwdriver.ogg", 50, 1)
+ src.panel_open = !src.panel_open
+ boutput(user, "You [src.panel_open ? "unscrew" : "secure"] the cover.")
+ src.updateUsrDialog()
+ return
+
+ else
+ return ..()
+
+
+ updateUsrDialog(var/updateReadout)
+ var/list/nearby = viewers(1, src)
+ for(var/mob/M in nearby)
+ if ((M.client && M.machine == src))
+ if (updateReadout)
+ M << output(url_encode(src.readout), "t_computer.browser:updateReadout")
+ else
+ src.attack_hand(M)
+
+ if (issilicon(usr))
+ if (!(usr in nearby))
+ if (usr.client && usr.machine==src)
+ if (updateReadout)
+ usr << output(url_encode(src.readout), "t_computer.browser:updateReadout")
+ else
+ src.attack_ai(usr)
+
+ Topic(href, href_list)
+ if (..(href, href_list))
+ return
+
+ usr.machine = src
+ playsound(src.loc, 'sound/machines/keypress.ogg', 50, 1, 5)
+
+ if (href_list["scan"])
+ if (!host_id)
+ boutput(usr, "Error: No host connection!")
+ return
+
+ if (coord_update_flag)
+ coord_update_flag = 0
+ message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
+
+ message_host("command=teleman&args=-p [padNum] scan")
+ src.updateUsrDialog(1)
+ return
+
+ if (href_list["reconnect"])
+ if ((host_id && href_list["reconnect"] != "2") || !old_host_id || !src.link)
+ return
+
+ if (href_list["reconnect"] == "2")
+ host_id = null
+
+ var/old = old_host_id
+ old_host_id = null
+ var/datum/signal/newsignal = get_free_signal()
+ newsignal.source = src
+ newsignal.transmission_method = TRANSMISSION_WIRE
+ newsignal.data["command"] = "term_connect"
+ newsignal.data["device"] = src.device_tag
+
+ newsignal.data_file = user_data.copy_file()
+
+ newsignal.data["address_1"] = old
+ newsignal.data["sender"] = src.net_id
+
+ src.link.post_signal(src, newsignal)
+ SPAWN_DBG(1 SECOND)
+ if (!old_host_id)
+ old_host_id = old
+
+ if (href_list["restorebookmark"])
+ var/datum/teleporter_bookmark/bm = locate(href_list["restorebookmark"]) in bookmarks
+ if(!bm) return
+ xtarget = bm.x
+ ytarget = bm.y
+ ztarget = bm.z
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ if (href_list["deletebookmark"])
+ var/datum/teleporter_bookmark/bm = locate(href_list["deletebookmark"]) in bookmarks
+ if(!bm) return
+ bookmarks.Remove(bm)
+ src.updateUsrDialog()
+ return
+
+ if (href_list["addbookmark"])
+ if(bookmarks.len >= max_bookmarks)
+ boutput(usr, "Maximum number of Bookmarks reached.")
+ return
+ var/datum/teleporter_bookmark/bm = new
+ var/title = input(usr,"Enter name:","Name","New Bookmark") as text
+ title = copytext(adminscrub(title), 1, 128)
+ if(!length(title)) return
+ bm.name = title
+ bm.x = xtarget
+ bm.y = ytarget
+ bm.z = ztarget
+ bookmarks.Add(bm)
+ src.updateUsrDialog()
+ playsound(src.loc, "keyboard", 50, 1, 5)
+ return
+
+ if (href_list["setpad"])
+ src.padNum = (src.padNum & 3) + 1
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ if (href_list["decreaseX"])
+ var/change = text2num(href_list["decreaseX"])
+ xtarget = min(max(0, xtarget-change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["increaseX"])
+ var/change = text2num(href_list["increaseX"])
+ xtarget = min(max(0, xtarget+change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["setX"])
+ var/change = input(usr,"Target X:","Enter target X coordinate",xtarget) as num
+ if(!isnum(change))
+ return
+ xtarget = min(max(0, change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["decreaseY"])
+ var/change = text2num(href_list["decreaseY"])
+ ytarget = min(max(0, ytarget-change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["increaseY"])
+ var/change = text2num(href_list["increaseY"])
+ ytarget = min(max(0, ytarget+change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["setY"])
+ var/change = input(usr,"Target Y:","Enter target Y coordinate",ytarget) as num
+ if(!isnum(change))
+ return
+ ytarget = min(max(0, change),500)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["decreaseZ"])
+ var/change = text2num(href_list["decreaseZ"])
+ ztarget = min(max(0, ztarget-change),14)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["increaseZ"])
+ var/change = text2num(href_list["increaseZ"])
+ ztarget = min(max(0, ztarget+change),14)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["setZ"])
+ var/change = input(usr,"Target Z:","Enter target Z coordinate",ztarget) as num
+ if(!isnum(change))
+ return
+ ztarget = min(max(0, change),14)
+ coord_update_flag = 1
+ src.updateUsrDialog()
+ return
+
+ else if (href_list["send"])
+ if (!host_id)
+ boutput(usr, "Error: No host connection!")
+ return
+
+ if (coord_update_flag)
+ coord_update_flag = 0
+ message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
+
+ message_host("command=teleman&args=-p [padNum] send")
+
+ return
+
+ else if (href_list["receive"])
+ if (!host_id)
+ boutput(usr, "Error: No host connection!")
+ return
+
+ if (coord_update_flag)
+ coord_update_flag = 0
+ message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
+
+ message_host("command=teleman&args=-p [padNum] receive")
+
+ return
+
+ else if (href_list["portal"])
+ if (coord_update_flag)
+ coord_update_flag = 0
+ message_host("command=teleman&args=-p [padNum] coords x=[xtarget] y=[ytarget] z=[ztarget]")
+
+ message_host("command=teleman&args=-p [padNum] portal toggle")
+
+ return
+
+ else
+ usr.Browse(null, "window=t_computer")
+ src.updateUsrDialog()
+ return
+
+ process()
+ if(status & (NOPOWER|BROKEN))
+ return
+ use_power(200)
+
+ if(!host_id || !link)
+ return
+
+ if(src.timeout == 0)
+ src.post_status(host_id, "command","term_disconnect","data","timeout")
+ src.host_id = null
+ src.updateUsrDialog()
+ src.timeout = initial(src.timeout)
+ src.timeout_alert = 0
+ else
+ src.timeout--
+ if(src.timeout <= 5 && !src.timeout_alert)
+ src.timeout_alert = 1
+ src.post_status(src.host_id, "command","term_ping","data","reply")
+
+ return
+
+ proc/message_host(var/message, var/datum/computer/file/file)
+ if (!src.host_id || !message)
+ return
+
+ if (file)
+ src.post_file(src.host_id,"data",message, file)
+ else
+ src.post_status(src.host_id,"command","term_message","data",message)
+
return
\ No newline at end of file