mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-27 10:02:12 +00:00
* Moves spawners and decals to a different init/delete scheme Rather then fully creating and then immediately deleting these things, we instead do the bare minimum. This is faster, if in theory more fragile. We should be safe since any errors should be caught in compile since this is very close to a "static" action. It does mean these atoms cannot use signals, etc. * Potentially saves init time, mostly cleans up a silly pattern We use sleeps and INVOKE_ASYNC to ensure that handing back turfs doesn't block a space reservation, but this by nature consumes up to the threshold and a bit more of whatever working block we were in. This is silly. Should just be a subsystem, so I made it one, with support for awaiting its finish if you want to * Optimizes garbage/proc/Queue slightly Queue takes about 1.6 seconds to process 26k items right now. The MASSIVE majority of this time is spent on using \ref This is because \ref returns a string, and that string requires being inserted into the global cache of strings we store What I'm doing is caching the result of ANY \ref on the datum it's applied to. This ensures previous uses will never decay from the string tree. This saves about 0.2 seconds of init
231 lines
9.0 KiB
Plaintext
231 lines
9.0 KiB
Plaintext
////////////////////////////////
|
|
/proc/message_admins(msg)
|
|
msg = "<span class=\"admin\"><span class=\"prefix\">ADMIN LOG:</span> <span class=\"message\">[msg]</span></span>"
|
|
to_chat(GLOB.admins,
|
|
type = MESSAGE_TYPE_ADMINLOG,
|
|
html = msg,
|
|
confidential = TRUE)
|
|
|
|
/proc/relay_msg_admins(msg)
|
|
msg = "<span class=\"admin\"><span class=\"prefix\">RELAY:</span> <span class=\"message\">[msg]</span></span>"
|
|
to_chat(GLOB.admins,
|
|
type = MESSAGE_TYPE_ADMINLOG,
|
|
html = msg,
|
|
confidential = TRUE)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////Panels
|
|
|
|
/datum/admins/proc/Game()
|
|
if(!check_rights(0))
|
|
return
|
|
|
|
var/dat = "<center><B>Game Panel</B></center><hr>"
|
|
if(SSticker.current_state <= GAME_STATE_PREGAME)
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];f_dynamic_roundstart=1'>(Force Roundstart Rulesets)</A><br>"
|
|
if (GLOB.dynamic_forced_roundstart_ruleset.len > 0)
|
|
for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset)
|
|
dat += {"<A href='?src=[REF(src)];[HrefToken()];f_dynamic_roundstart_remove=[text_ref(rule)]'>-> [rule.name] <-</A><br>"}
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];f_dynamic_roundstart_clear=1'>(Clear Rulesets)</A><br>"
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];f_dynamic_options=1'>(Dynamic mode options)</A><br>"
|
|
dat += "<hr/>"
|
|
if(SSticker.IsRoundInProgress())
|
|
dat += "<a href='?src=[REF(src)];[HrefToken()];gamemode_panel=1'>(Game Mode Panel)</a><BR>"
|
|
dat += {"
|
|
<BR>
|
|
<A href='?src=[REF(src)];[HrefToken()];create_object=1'>Create Object</A><br>
|
|
<A href='?src=[REF(src)];[HrefToken()];quick_create_object=1'>Quick Create Object</A><br>
|
|
<A href='?src=[REF(src)];[HrefToken()];create_turf=1'>Create Turf</A><br>
|
|
<A href='?src=[REF(src)];[HrefToken()];create_mob=1'>Create Mob</A><br>
|
|
"}
|
|
|
|
if(marked_datum && istype(marked_datum, /atom))
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];dupe_marked_datum=1'>Duplicate Marked Datum</A><br>"
|
|
|
|
usr << browse(dat, "window=admin2;size=240x280")
|
|
return
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
|
|
|
|
/datum/admins/proc/spawn_atom(object as text)
|
|
set category = "Debug"
|
|
set desc = "(atom path) Spawn an atom"
|
|
set name = "Spawn"
|
|
|
|
if(!check_rights(R_SPAWN) || !object)
|
|
return
|
|
|
|
var/list/preparsed = splittext(object,":")
|
|
var/path = preparsed[1]
|
|
var/amount = 1
|
|
if(preparsed.len > 1)
|
|
amount = clamp(text2num(preparsed[2]),1,ADMIN_SPAWN_CAP)
|
|
|
|
var/chosen = pick_closest_path(path)
|
|
if(!chosen)
|
|
return
|
|
var/turf/T = get_turf(usr)
|
|
|
|
if(ispath(chosen, /turf))
|
|
T.ChangeTurf(chosen)
|
|
else
|
|
for(var/i in 1 to amount)
|
|
var/atom/A = new chosen(T)
|
|
A.flags_1 |= ADMIN_SPAWNED_1
|
|
|
|
log_admin("[key_name(usr)] spawned [amount] x [chosen] at [AREACOORD(usr)]")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/podspawn_atom(object as text)
|
|
set category = "Debug"
|
|
set desc = "(atom path) Spawn an atom via supply drop"
|
|
set name = "Podspawn"
|
|
|
|
if(!check_rights(R_SPAWN))
|
|
return
|
|
|
|
var/chosen = pick_closest_path(object)
|
|
if(!chosen)
|
|
return
|
|
var/turf/target_turf = get_turf(usr)
|
|
|
|
if(ispath(chosen, /turf))
|
|
target_turf.ChangeTurf(chosen)
|
|
else
|
|
var/obj/structure/closet/supplypod/pod = podspawn(list(
|
|
"target" = target_turf,
|
|
"path" = /obj/structure/closet/supplypod/centcompod,
|
|
))
|
|
//we need to set the admin spawn flag for the spawned items so we do it outside of the podspawn proc
|
|
var/atom/A = new chosen(pod)
|
|
A.flags_1 |= ADMIN_SPAWNED_1
|
|
|
|
log_admin("[key_name(usr)] pod-spawned [chosen] at [AREACOORD(usr)]")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/spawn_cargo(object as text)
|
|
set category = "Debug"
|
|
set desc = "(atom path) Spawn a cargo crate"
|
|
set name = "Spawn Cargo"
|
|
|
|
if(!check_rights(R_SPAWN))
|
|
return
|
|
|
|
var/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/datum/supply_pack)))
|
|
if(!chosen)
|
|
return
|
|
var/datum/supply_pack/S = new chosen
|
|
S.admin_spawned = TRUE
|
|
S.generate(get_turf(usr))
|
|
|
|
log_admin("[key_name(usr)] spawned cargo pack [chosen] at [AREACOORD(usr)]")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Cargo") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/toggletintedweldhelmets()
|
|
set category = "Debug"
|
|
set desc="Reduces view range when wearing welding helmets"
|
|
set name="Toggle tinted welding helmes"
|
|
GLOB.tinted_weldhelh = !( GLOB.tinted_weldhelh )
|
|
if (GLOB.tinted_weldhelh)
|
|
to_chat(world, "<B>The tinted_weldhelh has been enabled!</B>", confidential = TRUE)
|
|
else
|
|
to_chat(world, "<B>The tinted_weldhelh has been disabled!</B>", confidential = TRUE)
|
|
log_admin("[key_name(usr)] toggled tinted_weldhelh.")
|
|
message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.")
|
|
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Tinted Welding Helmets", "[GLOB.tinted_weldhelh ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/dynamic_mode_options(mob/user)
|
|
var/dat = {"
|
|
<center><B><h2>Dynamic Mode Options</h2></B></center><hr>
|
|
<br/>
|
|
<h3>Common options</h3>
|
|
<i>All these options can be changed midround.</i> <br/>
|
|
<br/>
|
|
<b>Force extended:</b> - Option is <a href='?src=[REF(src)];[HrefToken()];f_dynamic_force_extended=1'> <b>[GLOB.dynamic_forced_extended ? "ON" : "OFF"]</a></b>.
|
|
<br/>This will force the round to be extended. No rulesets will be drafted. <br/>
|
|
<br/>
|
|
<b>No stacking:</b> - Option is <a href='?src=[REF(src)];[HrefToken()];f_dynamic_no_stacking=1'> <b>[GLOB.dynamic_no_stacking ? "ON" : "OFF"]</b></a>.
|
|
<br/>Unless the threat goes above [GLOB.dynamic_stacking_limit], only one "round-ender" ruleset will be drafted. <br/>
|
|
<br/>
|
|
<b>Forced threat level:</b> Current value : <a href='?src=[REF(src)];[HrefToken()];f_dynamic_forced_threat=1'><b>[GLOB.dynamic_forced_threat_level]</b></a>.
|
|
<br/>The value threat is set to if it is higher than -1.<br/>
|
|
<br/>
|
|
<br/>
|
|
<b>Stacking threeshold:</b> Current value : <a href='?src=[REF(src)];[HrefToken()];f_dynamic_stacking_limit=1'><b>[GLOB.dynamic_stacking_limit]</b></a>.
|
|
<br/>The threshold at which "round-ender" rulesets will stack. A value higher than 100 ensure this never happens. <br/>
|
|
"}
|
|
|
|
user << browse(dat, "window=dyn_mode_options;size=900x650")
|
|
|
|
/datum/admins/proc/create_or_modify_area()
|
|
set category = "Debug"
|
|
set name = "Create or modify area"
|
|
create_area(usr)
|
|
|
|
//Kicks all the clients currently in the lobby. The second parameter (kick_only_afk) determins if an is_afk() check is ran, or if all clients are kicked
|
|
//defaults to kicking everyone (afk + non afk clients in the lobby)
|
|
//returns a list of ckeys of the kicked clients
|
|
/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
|
|
var/list/kicked_client_names = list()
|
|
for(var/client/C in GLOB.clients)
|
|
if(isnewplayer(C.mob))
|
|
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
|
|
continue
|
|
if(message)
|
|
to_chat(C, message, confidential = TRUE)
|
|
kicked_client_names.Add("[C.key]")
|
|
qdel(C)
|
|
return kicked_client_names
|
|
|
|
//returns TRUE to let the dragdrop code know we are trapping this event
|
|
//returns FALSE if we don't plan to trap the event
|
|
/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, mob/tomob)
|
|
|
|
//this is the exact two check rights checks required to edit a ckey with vv.
|
|
if (!check_rights(R_VAREDIT,0) || !check_rights(R_SPAWN|R_DEBUG,0))
|
|
return FALSE
|
|
|
|
if (!frommob.ckey)
|
|
return FALSE
|
|
|
|
var/question = ""
|
|
if (tomob.ckey)
|
|
question = "This mob already has a user ([tomob.key]) in control of it! "
|
|
question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
|
|
|
|
var/ask = tgui_alert(usr, question, "Place ghost in control of mob?", list("Yes", "No"))
|
|
if (ask != "Yes")
|
|
return TRUE
|
|
|
|
if (!frommob || !tomob) //make sure the mobs don't go away while we waited for a response
|
|
return TRUE
|
|
|
|
// Disassociates observer mind from the body mind
|
|
if(tomob.client)
|
|
tomob.ghostize(FALSE)
|
|
else
|
|
for(var/mob/dead/observer/ghost in GLOB.dead_mob_list)
|
|
if(tomob.mind == ghost.mind)
|
|
ghost.mind = null
|
|
|
|
message_admins(span_adminnotice("[key_name_admin(usr)] has put [frommob.key] in control of [tomob.name]."))
|
|
log_admin("[key_name(usr)] stuffed [frommob.key] into [tomob.name].")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag Control")
|
|
|
|
tomob.key = frommob.key
|
|
tomob.client?.init_verbs()
|
|
qdel(frommob)
|
|
|
|
return TRUE
|
|
|
|
/client/proc/adminGreet(logout)
|
|
if(SSticker.HasRoundStarted())
|
|
var/string
|
|
if(logout && CONFIG_GET(flag/announce_admin_logout))
|
|
string = pick(
|
|
"Admin logout: [key_name(src)]")
|
|
else if(!logout && CONFIG_GET(flag/announce_admin_login) && (prefs.toggles & ANNOUNCE_LOGIN))
|
|
string = pick(
|
|
"Admin login: [key_name(src)]")
|
|
if(string)
|
|
message_admins("[string]")
|