Merge remote-tracking branch 'tgstation/master' into upstream-6-2-2026

This commit is contained in:
shayoki
2026-06-03 01:23:54 -05:00
1259 changed files with 50763 additions and 28726 deletions
+1 -1
View File
@@ -311,7 +311,7 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo
var/datum/feed_comment/new_feed_comment = new /datum/feed_comment
new_feed_comment.author = "Centcom Official"
new_feed_comment.body = comment_text
new_feed_comment.time_stamp = station_time_timestamp()
new_feed_comment.time_stamp = round_timestamp()
current_message.comments += new_feed_comment
GLOB.news_network.last_action ++
usr.log_message("(as an admin) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT)
+2 -1
View File
@@ -315,7 +315,7 @@ ADMIN_VERB(respawn_character, R_ADMIN, "Respawn Character", "Respawn a player th
if(record_found)//If they have a record we can determine a few things.
new_character.real_name = record_found.name
new_character.gender = LOWER_TEXT(record_found.gender)
new_character.gender = record_found.gender
new_character.age = record_found.age
var/datum/dna/found_dna = record_found.locked_dna
new_character.hardset_dna(found_dna.unique_identity, found_dna.mutation_index, null, record_found.name, record_found.blood_type, new record_found.species_type, found_dna.features)
@@ -514,6 +514,7 @@ ADMIN_VERB(lag_switch_panel, R_ADMIN, "Show Lag Switches", "Display the controls
dat += "<br/><b>Measures below can be bypassed with a <abbr title='TRAIT_BYPASS_MEASURES'><u>special trait</u></abbr></b><br/>"
dat += "Slowmode say verb (informs world): <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[SLOWMODE_SAY]'><b>[SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]</b></a><br/>"
dat += "Disable runechat: <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_RUNECHAT]'><b>[SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to speaker</span><br/>"
dat += "Disable dead runechat: <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_DEAD_RUNECHAT]'><b>[SSlag_switch.measures[DISABLE_DEAD_RUNECHAT] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to speaker</span><br/>"
dat += "Disable examine icons: <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_USR_ICON2HTML]'><b>[SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to examiner</span><br/>"
dat += "Disable parallax: <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_PARALLAX]'><b>[SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to character</span><br />"
dat += "Disable footsteps: <a href='byond://?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_FOOTSTEPS]'><b>[SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to character</span><br />"
+7 -7
View File
@@ -291,7 +291,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
"PLAYERS" = player_count,
"ROUND STATE" = round_state,
"ROUND ID" = GLOB.round_id,
"ROUND TIME" = ROUND_TIME(),
"ROUND TIME" = round_timestamp(),
"MESSAGE" = message,
"ADMINS" = admin_text,
)
@@ -377,9 +377,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
heard_by_no_admins = FALSE
send2adminchat(initiator_ckey, "Ticket #[id]: Answered by [key_name(usr)]")
ticket_interactions += "[time_stamp()]: [formatted_message]"
ticket_interactions += "[server_timestamp()]: [formatted_message]"
if (!isnull(player_message))
player_interactions += "[time_stamp()]: [player_message]"
player_interactions += "[server_timestamp()]: [player_message]"
//Removes the ahelp verb and returns it after 2 minutes
/datum/admin_help/proc/TimeoutVerb()
@@ -610,9 +610,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
dat += "[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]"
if(state != AHELP_ACTIVE)
dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]"
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
dat += "<br><br>Opened at: [round_timestamp(wtime = opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
if(closed_at)
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
dat += "<br>Closed at: [round_timestamp(wtime = closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
dat += "<br><br>"
if(initiator)
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
@@ -725,9 +725,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
else
dat += "UNKNOWN</b>"
dat += "\n[FOURSPACES]<A href='byond://?_src_=usr;player_ticket_panel=1'>Refresh</A>"
dat += "<br><br>Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
dat += "<br><br>Opened at: [round_timestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
if(closed_at)
dat += "<br>Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
dat += "<br>Closed at: [round_timestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
dat += "<br><br>"
dat += "<br><b>Log:</b><br><br>"
for (var/interaction in player_interactions)
@@ -0,0 +1,243 @@
/// Allows developers to see a breakdown of an atom or a specific target and edit some of the values
/datum/appearance_debugger
var/datum/admins/owner
/// Currently debugged atom or mutable appearance, hence /datum
var/datum/debug_target
/// A list of copies of the currently debugged appearance and its children for access from the UI
var/list/mutable_appearance/appearance_copies
/// Assoc list of ref -> appearance as to prevent refreshing of dynamic appearances
var/list/mutable_appearance/appearance_cache
/// Mapview used to display the hovered over appearance
var/atom/movable/screen/map_view/proxy_view_hover
/// Mapview used to display the selected appearance
var/atom/movable/screen/map_view/proxy_view_selected
/// Assoc list of ref -> list of atoms to be displayed in said ref atom's vis_contents
var/list/atom/movable/fake_vis
/// Should we display a popup that the appearance in-game has updated?
var/update_warning = FALSE
/datum/appearance_debugger/New(datum/admins/owner)
src.owner = owner
proxy_view_hover = new()
proxy_view_hover.generate_view("appearance_debugger_[REF(owner)]_proxy_hover")
proxy_view_selected = new()
proxy_view_selected.generate_view("appearance_debugger_[REF(owner)]_proxy_selected")
/datum/appearance_debugger/Destroy()
if (owner)
owner.appearance_debug = null
owner = null
if (fake_vis)
for (var/ref_id in fake_vis)
var/list/all_fakes = fake_vis[ref_id]
QDEL_LIST(all_fakes)
fake_vis.Cut()
QDEL_NULL(proxy_view_hover)
QDEL_NULL(proxy_view_selected)
return ..()
/datum/appearance_debugger/proc/get_appearance_data(atom/appearance_owner)
var/mutable_appearance/target = appearance_owner
if (isatom(appearance_owner))
target = appearance_cache["[REF(appearance_owner)]"] || new /mutable_appearance(appearance_owner.appearance)
appearance_cache["[REF(appearance_owner)]"] = target
if (!fake_vis["[REF(appearance_owner)]"] && (ismovable(appearance_owner) || isturf(appearance_owner)))
var/atom/movable/as_movable = appearance_owner
var/list/false_vis_contents = list()
fake_vis["[REF(appearance_owner)]"] = false_vis_contents
for (var/atom/something in (isturf(as_movable) ? (as_movable.vis_contents + as_movable.contents) : as_movable.vis_contents))
var/atom/movable/mimic = new()
mimic.appearance = new /mutable_appearance(something.appearance)
false_vis_contents += mimic
var/list/data = list(
"type" = isatom(appearance_owner) ? "atom" : (isimage(appearance_owner) ? "image" : "appearance"),
"alpha" = target.alpha,
"flags" = target.appearance_flags,
"blend_mode" = target.blend_mode,
"color" = target.color,
"dir" = target.dir,
"icon" = length("[target.icon]") ? "[target.icon]" : null,
"icon_state" = target.icon_state,
"invisibility" = target.invisibility,
"layer" = target.layer,
"name" = target.name,
"maptext" = target.maptext,
"maptext_width" = target.maptext_width,
"maptext_height" = target.maptext_height,
"maptext_x" = target.maptext_x,
"maptext_y" = target.maptext_y,
"mouse_opacity" = target.mouse_opacity,
"pixel_x" = target.pixel_x,
"pixel_y" = target.pixel_y,
"pixel_w" = target.pixel_w,
"pixel_z" = target.pixel_z,
"plane" = target.plane,
"plane_true" = PLANE_TO_TRUE(target.plane),
"render_source" = target.render_source,
"render_target" = target.render_target,
"screen_loc" = target.screen_loc,
)
if (!(target in appearance_copies))
appearance_copies += target
data["id"] = length(appearance_copies)
else
data["id"] = appearance_copies.Find(target)
var/list/filter_data = list()
for (var/list/our_filter as anything in target.filter_data)
filter_data += list(our_filter)
data["filters"] = filter_data
var/list/underlay_data = list()
for (var/mutable_appearance/underlay as anything in target.underlays)
underlay_data += list(get_appearance_data(underlay))
data["underlays"] = underlay_data
var/list/overlay_data = list()
for (var/mutable_appearance/overlay as anything in target.overlays)
overlay_data += list(get_appearance_data(overlay))
data["overlays"] = overlay_data
// Display previews if it is either an instance icon or a file and we have icon_state set
if ((isicon(target.icon) && !isfile(target.icon)) || (target.icon && target.icon_state))
var/icon/used_icon = icon(target.icon, target.icon_state, (isimage(target) && target.dir) ? target.dir : SOUTH, frame = 1)
if (istext(target.color))
used_icon.Blend(target.color, ICON_MULTIPLY)
data["embed_icon"] = icon2base64(used_icon)
data["transform"] = list(target.transform.a, target.transform.b, target.transform.c, target.transform.d, target.transform.e, target.transform.f)
// Turfs aren't movables but they still can have vis_flags/contents so lets just count them as such
if (ismovable(appearance_owner) || isturf(appearance_owner))
var/atom/movable/as_movable = appearance_owner
data["vis_flags"] = as_movable.vis_flags
// Maybe should be cached but I'm too lazy and don't think this'll matter enough
var/list/vis_data = list()
// Turfs also inherit their contents as vis_contents
for (var/atom/vis_thing as anything in isturf(as_movable) ? (as_movable.vis_contents + as_movable.contents) : as_movable.vis_contents)
vis_data += list(get_appearance_data(vis_thing))
data["vis_contents"] = vis_data
// Handle all dynamically modified layers
if (target.layer > FLOOR_EMISSIVE_START_LAYER && target.layer < FLOOR_EMISSIVE_END_LAYER)
data["layer_text_override"] = "FLOOR_EMISSIVE_LAYER (+[target.layer - FLOOR_EMISSIVE_START_LAYER])"
else if (target.layer > GAS_PIPE_HIDDEN_LAYER && target.layer < GAS_PIPE_HIDDEN_LAYER + 0.006)
data["layer_text_override"] = "GAS_PIPE_HIDDEN_LAYER (+[target.layer - GAS_PIPE_HIDDEN_LAYER])"
else if (target.layer > GAS_PIPE_VISIBLE_LAYER && target.layer < GAS_PIPE_VISIBLE_LAYER + 0.006)
data["layer_text_override"] = "GAS_PIPE_VISIBLE_LAYER (+[target.layer - GAS_PIPE_VISIBLE_LAYER])"
else if (target.layer > PLUMBING_PIPE_VISIBILE_LAYER && target.layer < PLUMBING_PIPE_VISIBILE_LAYER + (FIFTH_DUCT_LAYER * 2 / 3333))
data["layer_text_override"] = "PLUMBING_PIPE_VISIBILE_LAYER (+[target.layer - PLUMBING_PIPE_VISIBILE_LAYER])"
return data
/datum/appearance_debugger/ui_data(mob/user)
return list(
"updateWarning" = update_warning,
)
/datum/appearance_debugger/ui_static_data(mob/user)
return list(
"mainAppearance" = get_appearance_data(debug_target),
"planeToText" = GLOB.admin_readable_planes,
"layerToText" = GLOB.admin_readable_layers,
"flagsToText" = get_valid_bitflags("appearance_flags"),
"visToText" = get_valid_bitflags("vis_flags"),
"blendToText" = GLOB.blend_names,
"mapRefHover" = proxy_view_hover.assigned_map,
"mapRefSelected" = proxy_view_selected.assigned_map,
)
/datum/appearance_debugger/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
switch(action)
if("swapMapViewHover")
var/appearance_id = text2num(params["id"])
proxy_view_hover.appearance = appearance_copies[appearance_id]
for (var/atom/movable/something as anything in proxy_view_hover.vis_contents)
proxy_view_hover.vis_contents -= something
for (var/ref_id in appearance_cache)
if (appearance_copies[appearance_id] != appearance_cache[ref_id])
continue
if (fake_vis[ref_id])
proxy_view_hover.vis_contents |= fake_vis[ref_id]
// Needs screenloc to be set since we're setting the appearance and carrying over target's screenloc
proxy_view_hover.set_position(1, 1)
if("swapMapViewSelected")
var/appearance_id = text2num(params["id"])
proxy_view_selected.appearance = appearance_copies[appearance_id]
for (var/atom/movable/something as anything in proxy_view_selected.vis_contents)
proxy_view_selected.vis_contents -= something
for (var/ref_id in appearance_cache)
if (appearance_copies[appearance_id] != appearance_cache[ref_id])
continue
if (fake_vis[ref_id])
proxy_view_selected.vis_contents |= fake_vis[ref_id]
proxy_view_selected.set_position(1, 1)
if("refreshAppearance")
update_warning = FALSE
appearance_copies = list()
appearance_cache = list()
for (var/ref_id in fake_vis)
var/list/all_fakes = fake_vis[ref_id]
QDEL_LIST(all_fakes)
fake_vis = list()
update_static_data_for_all_viewers()
if("vvAppearance")
if (!check_rights(R_VAREDIT))
return
var/appearance_id = text2num(params["id"])
usr.client.debug_variables(appearance_copies[appearance_id])
/datum/appearance_debugger/ui_assets(mob/user)
return list(get_asset_datum(/datum/asset/simple/plane_background))
/datum/appearance_debugger/ui_state(mob/user)
return ADMIN_STATE(R_DEBUG)
/datum/appearance_debugger/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AppearanceDebug")
ui.open()
proxy_view_hover.display_to(user, ui.window)
proxy_view_selected.display_to(user, ui.window)
/datum/appearance_debugger/ui_close(mob/user)
. = ..()
// Reset appearances when the UI is closed
proxy_view_hover.appearance = new /mutable_appearance()
proxy_view_selected.appearance = new /mutable_appearance()
proxy_view_hover.vis_contents.Cut()
proxy_view_selected.vis_contents.Cut()
if (isatom(debug_target))
UnregisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE)
/datum/appearance_debugger/proc/set_target(mutable_appearance/new_target)
if (isatom(debug_target))
UnregisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE)
update_warning = FALSE
// Can be an atom!
debug_target = new_target
if (isatom(debug_target))
RegisterSignal(debug_target, COMSIG_ATOM_UPDATE_APPEARANCE, PROC_REF(warn_update))
appearance_copies = list()
appearance_cache = list()
for (var/ref_id in fake_vis)
var/list/all_fakes = fake_vis[ref_id]
QDEL_LIST(all_fakes)
fake_vis = list()
update_static_data_for_all_viewers()
/datum/appearance_debugger/proc/warn_update()
SIGNAL_HANDLER
update_warning = TRUE
+2 -14
View File
@@ -103,22 +103,10 @@ GLOBAL_DATUM_INIT(pathfind_dude, /obj/pathfind_guy, new())
return
/datum/action/innate/path_debug/proc/render_path(list/turf/draw_list)
if(!length(draw_list))
return list()
var/list/image/turf_images = list()
// Render everything but the first and last
for(var/i in 1 to (length(draw_list) - 1))
var/turf/problem_child = draw_list[i]
var/turf/next = draw_list[i + 1]
turf_images += render_turf(problem_child, get_dir(problem_child, next))
return turf_images
return SSpathfinder.render_path_images(draw_list)
/datum/action/innate/path_debug/proc/render_turf(turf/draw, direction)
var/image/arrow = image('icons/turf/debug.dmi', draw, "arrow", PATH_ARROW_DEBUG_LAYER, direction)
SET_PLANE_EXPLICIT(arrow, BALLOON_CHAT_PLANE, draw)
return arrow
return SSpathfinder.render_path_arrow(draw, direction)
/datum/action/innate/path_debug/jps
name = "JPS Test"
+19 -20
View File
@@ -1,51 +1,50 @@
/mob/verb/pray(msg as text)
set category = "IC"
set name = "Pray"
/mob/verb/pray(message as text)
set name = VERB_PRAY
if(GLOB.say_disabled) //This is here to try to identify lag problems
to_chat(usr, span_danger("Speech is currently admin-disabled."), confidential = TRUE)
to_chat(src, span_danger("Speech is currently admin-disabled."), confidential = TRUE)
return
msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN)
if(!msg)
message = copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)
if(!message)
return
log_prayer("[src.key]/([src.name]): [msg]")
if(usr.client)
if(usr.client.prefs.muted & MUTE_PRAY)
to_chat(usr, span_danger("You cannot pray (muted)."), confidential = TRUE)
log_prayer("[src.key]/([src.name]): [message]")
if(src.client)
if(src.client.prefs.muted & MUTE_PRAY)
to_chat(src, span_danger("You cannot pray (muted)."), confidential = TRUE)
return
if(src.client.handle_spam_prevention(msg,MUTE_PRAY))
if(src.client.handle_spam_prevention(message, MUTE_PRAY))
return
var/mutable_appearance/cross = mutable_appearance('icons/obj/storage/book.dmi', "bible")
var/font_color = "purple"
var/prayer_type = "PRAYER"
var/deity
if(usr.job == JOB_CHAPLAIN)
if(src.job == JOB_CHAPLAIN)
cross.icon_state = "kingyellow"
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
if(GLOB.deity)
deity = GLOB.deity
else if(IS_CULTIST(usr))
else if(IS_CULTIST(src))
cross.icon_state = "tome"
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = "Nar'Sie"
else if(isliving(usr))
var/mob/living/L = usr
else if(isliving(src))
var/mob/living/L = src
if(HAS_TRAIT(L, TRAIT_SPIRITUAL))
cross.icon_state = "holylight"
font_color = "blue"
prayer_type = "SPIRITUAL PRAYER"
var/msg_tmp = msg
GLOB.requests.pray(usr.client, msg, usr.job == JOB_CHAPLAIN)
msg = span_adminnotice("[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [span_linkify(msg)]")
var/msg_tmp = message
GLOB.requests.pray(src.client, message, src.job == JOB_CHAPLAIN)
message = span_adminnotice("[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [span_linkify(message)]")
for(var/client/C in GLOB.admins)
if(get_chat_toggles(C) & CHAT_PRAYER)
to_chat(C, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE)
to_chat(usr, span_info("You pray to the gods: \"[msg_tmp]\""), confidential = TRUE)
to_chat(C, message, type = MESSAGE_TYPE_PRAYER, confidential = TRUE)
to_chat(src, span_info("You pray to the gods: \"[msg_tmp]\""), confidential = TRUE)
BLACKBOX_LOG_ADMIN_VERB("Prayer")
+21 -15
View File
@@ -163,21 +163,6 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w
log_admin("[key_name(holder)] reset the station name.")
message_admins(span_adminnotice("[key_name_admin(holder)] reset the station name."))
priority_announce("[command_name()] has renamed the station to \"[new_name]\".")
if("night_shift_set")
var/val = tgui_alert(holder, "What do you want to set night shift to? This will override the automatic system until set to automatic again.", "Night Shift", list("On", "Off", "Automatic"))
switch(val)
if("Automatic")
if(CONFIG_GET(flag/enable_night_shifts))
SSnightshift.can_fire = TRUE
SSnightshift.fire()
else
SSnightshift.update_nightshift(active = FALSE, announce = TRUE, forced = TRUE)
if("On")
SSnightshift.can_fire = FALSE
SSnightshift.update_nightshift(active = TRUE, announce = TRUE, forced = TRUE)
if("Off")
SSnightshift.can_fire = FALSE
SSnightshift.update_nightshift(active = FALSE, announce = TRUE, forced = TRUE)
if("moveferry")
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send CentCom Ferry"))
if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away"))
@@ -703,6 +688,27 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w
return
return
if("meteormode")
if(!is_funmin)
return
if(GLOB.meteor_mode)
QDEL_NULL(GLOB.meteor_mode)
message_admins("[key_name_admin(holder)] disabled meteor mode.")
return TRUE
GLOB.meteor_mode = new()
var/start_when = tgui_input_number(usr, "Meteors will start in (this many seconds):", "Meteor Mode: Start", (5 MINUTES) / 10, (24 HOURS) / 10, 0)
var/ramp_speed = tgui_input_number(usr, "Meteors will worsen every (this many seconds):", "Meteor Mode: Intensity", (5 MINUTES) / 10, (24 HOURS) / 10, (30 SECONDS) / 10)
if(!is_funmin) // deadminnied?
QDEL_NULL(GLOB.meteor_mode)
return TRUE
GLOB.meteor_mode.meteordelay = world.time + (start_when * 10)
GLOB.meteor_mode.rampupdelta = ramp_speed / 60
GLOB.meteor_mode.start_meteor()
message_admins("[key_name_admin(holder)] enabled meteor mode. \
Meteors will start [start_when ? "in [DisplayTimeText(start_when * 10)]" : "immediately"], and will worsen every [DisplayTimeText(ramp_speed * 10)].")
return TRUE
if("fix_gravity")
if(!is_funmin)
return
+1 -1
View File
@@ -11,7 +11,7 @@ GLOBAL_DATUM_INIT(sprite_auditor, /datum/sprite_auditor, new)
"name" = author.real_name,
"ckey" = author.ckey,
"appearance" = icon_appearance,
"timestamp" = gameTimestamp(),
"timestamp" = round_timestamp(),
)))
SStgui.update_uis(src)