mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* asset cache cdn * Fix cdn rsc (#52886) I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0. * Add warning about https to the external rsc config (#53367) today in hostchat we discovered that most of the servers who tried to do cdn the .rsc, had unknown issues because they had used https:// urls. Byond can't into https. like 5 servers had failed to get this to work because of that pitfall, so im gonna add a warning to the config. * tchat * tgchat compile * fixes * Merge pull request #53011 from stylemistake/tgui-chat-fix-asay tgchat: Fix asay * chat color * logging * webstorage * compile TGUI * actually like compiles on the DM side * Update chat-dark.scss * Update chat-light.scss * Update resources.txt * Update tgui-panel.bundle.css * Colors * compile * s * s * Ports Gamers TGChat so we can edit it. - NOT LIVE TGCHAT BRANCH (#10226) * asset cache cdn * Fix cdn rsc (#52886) I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0. * Add warning about https to the external rsc config (#53367) today in hostchat we discovered that most of the servers who tried to do cdn the .rsc, had unknown issues because they had used https:// urls. Byond can't into https. like 5 servers had failed to get this to work because of that pitfall, so im gonna add a warning to the config. * tchat * tgchat compile * fixes * Merge pull request #53011 from stylemistake/tgui-chat-fix-asay tgchat: Fix asay * chat color * logging * webstorage * compile TGUI * actually like compiles on the DM side * Update chat-dark.scss * Update chat-light.scss * Update resources.txt * Update tgui-panel.bundle.css * Colors * compile * s * s Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com> Co-authored-by: Aleksej Komarov <stylemistake@gmail.com> Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com> Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com> Co-authored-by: TheSmallBlue <ilanmori@hotmail.com> * Fixes Replay Chat * Update to_chat.dm * Update chat.dm * Update demo.dm * yarn berry * yarn berry compile * Update resources.txt * Update config/resources.txt * Update resources.txt * Attempt at fixing reconnect. * Lets try fix it again * oops * THROW THE SINK AT IT * ree * Makes Travis work again thank you jamie * Fixes snowflake images * Update security.dm * Updates TGChat Test Merge (#10307) * asset cache cdn * Fix cdn rsc (#52886) I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0. * Add warning about https to the external rsc config (#53367) today in hostchat we discovered that most of the servers who tried to do cdn the .rsc, had unknown issues because they had used https:// urls. Byond can't into https. like 5 servers had failed to get this to work because of that pitfall, so im gonna add a warning to the config. * tchat * tgchat compile * fixes * Merge pull request #53011 from stylemistake/tgui-chat-fix-asay tgchat: Fix asay * chat color * logging * webstorage * compile TGUI * actually like compiles on the DM side * Update chat-dark.scss * Update chat-light.scss * Update resources.txt * Update tgui-panel.bundle.css * Colors * compile * s * s * Ports Gamers TGChat so we can edit it. - NOT LIVE TGCHAT BRANCH (#10226) * asset cache cdn * Fix cdn rsc (#52886) I was converting this to use length so it didn't have to care if the list existed or not, and forgot to remove the .len. this broke cdn .rsc files because length(num) returns 0. * Add warning about https to the external rsc config (#53367) today in hostchat we discovered that most of the servers who tried to do cdn the .rsc, had unknown issues because they had used https:// urls. Byond can't into https. like 5 servers had failed to get this to work because of that pitfall, so im gonna add a warning to the config. * tchat * tgchat compile * fixes * Merge pull request #53011 from stylemistake/tgui-chat-fix-asay tgchat: Fix asay * chat color * logging * webstorage * compile TGUI * actually like compiles on the DM side * Update chat-dark.scss * Update chat-light.scss * Update resources.txt * Update tgui-panel.bundle.css * Colors * compile * s * s Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com> Co-authored-by: Aleksej Komarov <stylemistake@gmail.com> Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com> Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com> Co-authored-by: TheSmallBlue <ilanmori@hotmail.com> * Fixes Replay Chat * Update to_chat.dm * Update chat.dm * Update demo.dm * yarn berry * yarn berry compile * Update resources.txt * Update config/resources.txt * Update resources.txt * Attempt at fixing reconnect. * Lets try fix it again * oops * THROW THE SINK AT IT * ree * Makes Travis work again thank you jamie * Fixes snowflake images * Update security.dm Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com> Co-authored-by: Aleksej Komarov <stylemistake@gmail.com> Co-authored-by: TheGamerdk <5618080+TheGamerdk@users.noreply.github.com> Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com> Co-authored-by: TheSmallBlue <ilanmori@hotmail.com> Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> * Fixes * Undo Kitchen Sink * Fucking 7 Hours. * status panel * stat panel fixes * fixes * stat panel stuff * Stat panel finish * Compile, oops * Update server_maint.dm * Update world.dm * Update interface.dm * tgui compile * Update subsystems.dm * fix statpanel deleting whole admin tab (#54211) fix: adminhelping no longer removes entire admin tab fix: end of round no longer removes entire admin tab * Update skin.dmf * verbs? Co-authored-by: Kyle Spier-Swenson <kyleshome@gmail.com> Co-authored-by: Aleksej Komarov <stylemistake@gmail.com> Co-authored-by: skoglol <33292112+kriskog@users.noreply.github.com> Co-authored-by: TheSmallBlue <ilanmori@hotmail.com> Co-authored-by: Jamie D <993128+JamieD1@users.noreply.github.com> Co-authored-by: alexkar598 <25136265+alexkar598@users.noreply.github.com> Co-authored-by: Couls <coul422@gmail.com> Co-authored-by: Tad Hardesty <tad@platymuus.com> Co-authored-by: Bobbahbrown <bobbahbrown@gmail.com>
379 lines
13 KiB
Plaintext
379 lines
13 KiB
Plaintext
//- Are all the floors with or without air, as they should be? (regular or airless)
|
|
//- Does the area have an APC?
|
|
//- Does the area have an Air Alarm?
|
|
//- Does the area have a Request Console?
|
|
//- Does the area have lights?
|
|
//- Does the area have a light switch?
|
|
//- Does the area have enough intercoms?
|
|
//- Does the area have enough security cameras? (Use the 'Camera Range Display' verb under Debug)
|
|
//- Is the area connected to the scrubbers air loop?
|
|
//- Is the area connected to the vent air loop? (vent pumps)
|
|
//- Is everything wired properly?
|
|
//- Does the area have a fire alarm and firedoors?
|
|
//- Do all pod doors work properly?
|
|
//- Are accesses set properly on doors, pod buttons, etc.
|
|
//- Are all items placed properly? (not below vents, scrubbers, tables)
|
|
//- Does the disposal system work properly from all the disposal units in this room and all the units, the pipes of which pass through this room?
|
|
//- Check for any misplaced or stacked piece of pipe (air and disposal)
|
|
//- Check for any misplaced or stacked piece of wire
|
|
//- Identify how hard it is to break into the area and where the weak points are
|
|
//- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels.
|
|
|
|
GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
|
|
/client/proc/camera_view, //-errorage
|
|
/client/proc/sec_camera_report, //-errorage
|
|
/client/proc/intercom_view, //-errorage
|
|
/client/proc/air_status, //Air things
|
|
/client/proc/Cell, //More air things
|
|
/client/proc/atmosscan, //check plumbing
|
|
/client/proc/powerdebug, //check power
|
|
/client/proc/count_objects_on_z_level,
|
|
/client/proc/count_objects_all,
|
|
/client/proc/cmd_assume_direct_control, //-errorage
|
|
/client/proc/startSinglo,
|
|
/client/proc/set_server_fps, //allows you to set the ticklag.
|
|
/client/proc/cmd_admin_grantfullaccess,
|
|
/client/proc/cmd_admin_areatest_all,
|
|
/client/proc/cmd_admin_areatest_station,
|
|
#ifdef TESTING
|
|
/client/proc/see_dirty_varedits,
|
|
#endif
|
|
/client/proc/cmd_admin_test_atmos_controllers,
|
|
/datum/admins/proc/show_traitor_panel,
|
|
/client/proc/disable_communication,
|
|
/client/proc/cmd_show_at_list,
|
|
/client/proc/cmd_show_at_markers,
|
|
/client/proc/manipulate_organs,
|
|
/client/proc/start_line_profiling,
|
|
/client/proc/stop_line_profiling,
|
|
/client/proc/show_line_profiling,
|
|
/client/proc/create_mapping_job_icons,
|
|
/client/proc/debug_z_levels,
|
|
/client/proc/place_ruin
|
|
))
|
|
GLOBAL_PROTECT(admin_verbs_debug_mapping)
|
|
|
|
/obj/effect/debugging/mapfix_marker
|
|
name = "map fix marker"
|
|
icon = 'icons/mob/screen_gen.dmi'
|
|
icon_state = "mapfixmarker"
|
|
desc = "I am a mappers mistake."
|
|
|
|
/obj/effect/debugging/marker
|
|
icon = 'icons/turf/areas.dmi'
|
|
icon_state = "yellow"
|
|
|
|
/obj/effect/debugging/marker/Move()
|
|
return 0
|
|
|
|
/client/proc/camera_view()
|
|
set category = "Mapping"
|
|
set name = "Camera Range Display"
|
|
|
|
var/on = FALSE
|
|
for(var/turf/T in world)
|
|
if(T.maptext)
|
|
on = TRUE
|
|
T.maptext = null
|
|
|
|
if(!on)
|
|
var/list/seen = list()
|
|
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
|
for(var/turf/T in C.can_see())
|
|
seen[T]++
|
|
for(var/turf/T in seen)
|
|
T.maptext = "[seen[T]]"
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range")
|
|
|
|
#ifdef TESTING
|
|
GLOBAL_LIST_EMPTY(dirty_vars)
|
|
|
|
/client/proc/see_dirty_varedits()
|
|
set category = "Mapping"
|
|
set name = "Dirty Varedits"
|
|
|
|
var/list/dat = list()
|
|
dat += "<h3>Abandon all hope ye who enter here</h3><br><br>"
|
|
for(var/thing in GLOB.dirty_vars)
|
|
dat += "[thing]<br>"
|
|
CHECK_TICK
|
|
var/datum/browser/popup = new(usr, "dirty_vars", "Dirty Varedits", 900, 750)
|
|
popup.set_content(dat.Join())
|
|
popup.open()
|
|
#endif
|
|
|
|
/client/proc/sec_camera_report()
|
|
set category = "Mapping"
|
|
set name = "Camera Report"
|
|
|
|
if(!Master)
|
|
alert(usr,"Master_controller not found.","Sec Camera Report")
|
|
return 0
|
|
|
|
var/list/obj/machinery/camera/CL = list()
|
|
|
|
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
|
CL += C
|
|
|
|
var/output = {"<HTML><HEAD><meta charset='UTF-8'></HEAD><BODY><B>Camera Abnormalities Report</B><HR>
|
|
<B>The following abnormalities have been detected. The ones in red need immediate attention: Some of those in black may be intentional.</B><BR><ul>"}
|
|
|
|
for(var/obj/machinery/camera/C1 in CL)
|
|
for(var/obj/machinery/camera/C2 in CL)
|
|
if(C1 != C2)
|
|
if(C1.c_tag == C2.c_tag)
|
|
output += "<li><font color='red'>c_tag match for cameras at [ADMIN_VERBOSEJMP(C1)] and [ADMIN_VERBOSEJMP(C2)] - c_tag is [C1.c_tag]</font></li>"
|
|
if(C1.loc == C2.loc && C1.dir == C2.dir && C1.pixel_x == C2.pixel_x && C1.pixel_y == C2.pixel_y)
|
|
output += "<li><font color='red'>FULLY overlapping cameras at [ADMIN_VERBOSEJMP(C1)] Networks: [json_encode(C1.network)] and [json_encode(C2.network)]</font></li>"
|
|
if(C1.loc == C2.loc)
|
|
output += "<li>Overlapping cameras at [ADMIN_VERBOSEJMP(C1)] Networks: [json_encode(C1.network)] and [json_encode(C2.network)]</li>"
|
|
var/turf/T = get_step(C1,turn(C1.dir,180))
|
|
if(!T || !isturf(T) || !T.density )
|
|
if(!(locate(/obj/structure/grille) in T))
|
|
var/window_check = 0
|
|
for(var/obj/structure/window/W in T)
|
|
if (W.dir == turn(C1.dir,180) || (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST)) )
|
|
window_check = 1
|
|
break
|
|
if(!window_check)
|
|
output += "<li><font color='red'>Camera not connected to wall at [ADMIN_VERBOSEJMP(C1)] Network: [json_encode(C1.network)]</font></li>"
|
|
|
|
output += "</ul></BODY></HTML>"
|
|
usr << browse(output,"window=airreport;size=1000x500")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/intercom_view()
|
|
set category = "Mapping"
|
|
set name = "Intercom Range Display"
|
|
|
|
var/static/intercom_range_display_status = FALSE
|
|
intercom_range_display_status = !intercom_range_display_status //blame cyberboss if this breaks something
|
|
|
|
for(var/obj/effect/debugging/marker/M in world)
|
|
qdel(M)
|
|
|
|
if(intercom_range_display_status)
|
|
for(var/obj/item/radio/intercom/I in world)
|
|
for(var/turf/T in orange(7,I))
|
|
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
|
|
if (!(F in view(7,I.loc)))
|
|
qdel(F)
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/cmd_show_at_list()
|
|
set category = "Mapping"
|
|
set name = "Show roundstart AT list"
|
|
set desc = "Displays a list of active turfs coordinates at roundstart"
|
|
|
|
var/dat = {"<HTML><HEAD><meta charset='UTF-8'></HEAD><BODY>
|
|
<b>Coordinate list of Active Turfs at Roundstart</b>
|
|
<br>Real-time Active Turfs list you can see in Air Subsystem at active_turfs var<br>"}
|
|
|
|
for(var/t in GLOB.active_turfs_startlist)
|
|
var/turf/T = t
|
|
dat += "[ADMIN_VERBOSEJMP(T)]\n"
|
|
dat += "<br>"
|
|
|
|
dat += "</BODY></HTML>"
|
|
|
|
usr << browse(dat, "window=at_list")
|
|
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Roundstart Active Turfs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/cmd_show_at_markers()
|
|
set category = "Mapping"
|
|
set name = "Show roundstart AT markers"
|
|
set desc = "Places a marker on all active-at-roundstart turfs"
|
|
|
|
var/count = 0
|
|
for(var/obj/effect/abstract/marker/at/AT in GLOB.all_abstract_markers)
|
|
qdel(AT)
|
|
count++
|
|
|
|
if(count)
|
|
to_chat(usr, "[count] AT markers removed.", confidential=TRUE)
|
|
else
|
|
for(var/t in GLOB.active_turfs_startlist)
|
|
new /obj/effect/abstract/marker/at(t)
|
|
count++
|
|
to_chat(usr, "[count] AT markers placed.", confidential=TRUE)
|
|
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Roundstart Active Turf Markers")
|
|
|
|
/client/proc/enable_debug_verbs()
|
|
set category = "Debug"
|
|
set name = "Debug verbs - Enable"
|
|
if(!check_rights(R_DEBUG))
|
|
return
|
|
remove_verb(src, /client/proc/enable_debug_verbs)
|
|
add_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/disable_debug_verbs()
|
|
set category = "Debug"
|
|
set name = "Debug verbs - Disable"
|
|
remove_verb(src, list(/client/proc/disable_debug_verbs, GLOB.admin_verbs_debug_mapping))
|
|
add_verb(src, /client/proc/enable_debug_verbs)
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/count_objects_on_z_level()
|
|
set category = "Mapping"
|
|
set name = "Count Objects On Level"
|
|
var/level = input("Which z-level?","Level?") as text
|
|
if(!level)
|
|
return
|
|
var/num_level = text2num(level)
|
|
if(!num_level)
|
|
return
|
|
if(!isnum(num_level))
|
|
return
|
|
|
|
var/type_text = input("Which type path?","Path?") as text
|
|
if(!type_text)
|
|
return
|
|
var/type_path = text2path(type_text)
|
|
if(!type_path)
|
|
return
|
|
|
|
var/count = 0
|
|
|
|
var/list/atom/atom_list = list()
|
|
|
|
for(var/atom/A in world)
|
|
if(istype(A,type_path))
|
|
var/atom/B = A
|
|
while(!(isturf(B.loc)))
|
|
if(B && B.loc)
|
|
B = B.loc
|
|
else
|
|
break
|
|
if(B)
|
|
if(B.z == num_level)
|
|
count++
|
|
atom_list += A
|
|
|
|
to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level]")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects Zlevel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/count_objects_all()
|
|
set category = "Mapping"
|
|
set name = "Count Objects All"
|
|
|
|
var/type_text = input("Which type path?","") as text
|
|
if(!type_text)
|
|
return
|
|
var/type_path = text2path(type_text)
|
|
if(!type_path)
|
|
return
|
|
|
|
var/count = 0
|
|
|
|
for(var/atom/A in world)
|
|
if(istype(A,type_path))
|
|
count++
|
|
|
|
to_chat(world, "There are [count] objects of type [type_path] in the game world")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
|
|
//This proc is intended to detect lag problems relating to communication procs
|
|
GLOBAL_VAR_INIT(say_disabled, FALSE)
|
|
/client/proc/disable_communication()
|
|
set category = "Mapping"
|
|
set name = "Disable all communication verbs"
|
|
|
|
GLOB.say_disabled = !GLOB.say_disabled
|
|
if(GLOB.say_disabled)
|
|
message_admins("[key] used 'Disable all communication verbs', killing all communication methods.")
|
|
else
|
|
message_admins("[key] used 'Disable all communication verbs', restoring all communication methods.")
|
|
|
|
//This generates the icon states for job starting location landmarks.
|
|
/client/proc/create_mapping_job_icons()
|
|
set name = "Generate job landmarks icons"
|
|
set category = "Mapping"
|
|
var/icon/final = icon()
|
|
var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted
|
|
D.setDir(SOUTH)
|
|
for(var/job in subtypesof(/datum/job))
|
|
var/datum/job/JB = new job
|
|
switch(JB.title)
|
|
if("AI")
|
|
final.Insert(icon('icons/mob/ai.dmi', "ai", SOUTH, 1), "AI")
|
|
if("Cyborg")
|
|
final.Insert(icon('icons/mob/robots.dmi', "robot", SOUTH, 1), "Cyborg")
|
|
else
|
|
for(var/obj/item/I in D)
|
|
qdel(I)
|
|
randomize_human(D)
|
|
JB.equip(D, TRUE, FALSE)
|
|
COMPILE_OVERLAYS(D)
|
|
var/icon/I = icon(getFlatIcon(D), frame = 1)
|
|
final.Insert(I, JB.title)
|
|
qdel(D)
|
|
//Also add the x
|
|
for(var/x_number in 1 to 4)
|
|
final.Insert(icon('icons/mob/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]")
|
|
fcopy(final, "icons/mob/landmarks.dmi")
|
|
|
|
/client/proc/debug_z_levels()
|
|
set name = "Debug Z-Levels"
|
|
set category = "Mapping"
|
|
|
|
var/list/z_list = SSmapping.z_list
|
|
var/list/messages = list()
|
|
messages += "<b>World</b>: [world.maxx] x [world.maxy] x [world.maxz]<br>"
|
|
|
|
var/list/linked_levels = list()
|
|
var/min_x = INFINITY
|
|
var/min_y = INFINITY
|
|
var/max_x = -INFINITY
|
|
var/max_y = -INFINITY
|
|
|
|
for(var/z in 1 to max(world.maxz, z_list.len))
|
|
if (z > z_list.len)
|
|
messages += "<b>[z]</b>: Unmanaged (out of bounds)<br>"
|
|
continue
|
|
var/datum/space_level/S = z_list[z]
|
|
if (!S)
|
|
messages += "<b>[z]</b>: Unmanaged (null)<br>"
|
|
continue
|
|
var/linkage
|
|
switch (S.linkage)
|
|
if (UNAFFECTED)
|
|
linkage = "no linkage"
|
|
if (SELFLOOPING)
|
|
linkage = "self-looping"
|
|
if (CROSSLINKED)
|
|
linkage = "linked at ([S.xi], [S.yi])"
|
|
linked_levels += S
|
|
min_x = min(min_x, S.xi)
|
|
min_y = min(min_y, S.yi)
|
|
max_x = max(max_x, S.xi)
|
|
max_y = max(max_y, S.yi)
|
|
else
|
|
linkage = "unknown linkage '[S.linkage]'"
|
|
|
|
messages += "<b>[z]</b>: [S.name], [linkage], traits: [json_encode(S.traits)]<br>"
|
|
if (S.z_value != z)
|
|
messages += "-- z_value is [S.z_value], should be [z]<br>"
|
|
if (S.name == initial(S.name))
|
|
messages += "-- name not set<br>"
|
|
if (z > world.maxz)
|
|
messages += "-- exceeds max z"
|
|
|
|
var/grid[max_x - min_x + 1][max_y - min_y + 1]
|
|
for(var/datum/space_level/S in linked_levels)
|
|
grid[S.xi - min_x + 1][S.yi - min_y + 1] = S.z_value
|
|
|
|
messages += "<table border='1'>"
|
|
for(var/y in max_y to min_y step -1)
|
|
var/list/part = list()
|
|
for(var/x in min_x to max_x)
|
|
part += "[grid[x - min_x + 1][y - min_y + 1]]"
|
|
messages += "<tr><td>[part.Join("</td><td>")]</td></tr>"
|
|
messages += "</table>"
|
|
|
|
to_chat(src, messages.Join(""), confidential=TRUE)
|