refactor user verb sources (#31411)

This commit is contained in:
warriorstar-orion
2026-01-15 12:33:23 -05:00
committed by GitHub
parent 0ab708ff61
commit 9e7a98cefb
19 changed files with 2092 additions and 2098 deletions
+403 -273
View File
@@ -25,6 +25,47 @@ USER_VERB(hide_verbs, R_NONE, "Adminverbs - Hide All", "Hide most of your admin
to_chat(src, SPAN_INTERFACE("All of your adminverbs are now visible."))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Admin Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_drop_everything(mob/M as mob in GLOB.mob_list)
set name = "\[Admin\] Drop Everything"
if(!check_rights(R_DEBUG|R_ADMIN))
return
var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
if(confirm != "Yes")
return
for(var/obj/item/W in M)
M.drop_item_to_ground(W)
log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(imprison, R_ADMIN, "Prison", "Send a mob to prison.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list)
if(ismob(M))
if(is_ai(M))
alert(client, "The AI can't be sent to prison you jerk!", null, null, null, null)
return
//strip their stuff before they teleport into a cell :downs:
for(var/obj/item/W in M)
M.drop_item_to_ground(W)
//teleport person to cell
if(isliving(M))
var/mob/living/L = M
L.Paralyse(10 SECONDS)
sleep(5) //so they black out before warping
M.loc = pick(GLOB.prisonwarp)
if(ishuman(M))
var/mob/living/carbon/human/prisoner = M
prisoner.equip_to_slot_or_del(new /obj/item/clothing/under/color/orange(prisoner), ITEM_SLOT_JUMPSUIT)
prisoner.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(prisoner), ITEM_SLOT_SHOES)
spawn(50)
to_chat(M, SPAN_WARNING("You have been sent to the prison station!"))
log_admin("[key_name(client)] sent [key_name(M)] to the prison station.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] sent [key_name_admin(M)] to the prison station."), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/mentor_ghost()
var/is_mentor = check_rights(R_MENTOR, FALSE)
var/is_full_admin = check_rights(R_ADMIN|R_MOD, FALSE)
@@ -275,129 +316,6 @@ USER_VERB(big_brother, R_PERMISSIONS, "Big Brother Mode", "Enables Big Brother m
log_admin("[key_name(client)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]", TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Big Brother Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(drop_bomb, R_EVENT, "Drop Bomb", "Cause an explosion of varying strength at your location.", VERB_CATEGORY_EVENT)
var/turf/epicenter = client.mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/choice = tgui_input_list(client, "What size explosion would you like to produce?", "Drop Bomb", choices)
switch(choice)
if(null)
return 0
if("Small Bomb")
explosion(epicenter, 1, 2, 3, 3, cause = "[client.ckey]: Drop Bomb command")
if("Medium Bomb")
explosion(epicenter, 2, 3, 4, 4, cause = "[client.ckey]: Drop Bomb command")
if("Big Bomb")
explosion(epicenter, 3, 5, 7, 5, cause = "[client.ckey]: Drop Bomb command")
if("Custom Bomb")
var/devastation_range = tgui_input_number(client, "Devastation range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(devastation_range))
return
var/heavy_impact_range = tgui_input_number(client, "Heavy impact range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(heavy_impact_range))
return
var/light_impact_range = tgui_input_number(client, "Light impact range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(light_impact_range))
return
var/flash_range = tgui_input_number(client, "Flash range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(flash_range))
return
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, 1, 1, cause = "[client.ckey]: Drop Bomb command")
log_admin("[key_name(client)] created an admin explosion at [epicenter.loc]")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] created an admin explosion at [epicenter.loc]"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(give_spell, R_EVENT, "Give Spell", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T)
var/list/spell_list = list()
var/type_length = length("/datum/spell") + 2
for(var/A in GLOB.spells)
spell_list[copytext("[A]", type_length)] = A
var/datum/spell/S = input(client, "Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list
if(!S)
return
S = spell_list[S]
if(T.mind)
T.mind.AddSpell(new S)
else
T.AddSpell(new S)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] gave [key_name(T)] the spell [S].")
message_admins("[key_name_admin(client)] gave [key_name(T)] the spell [S].", 1)
USER_VERB(give_disease, R_EVENT, "Give Disease", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T)
var/datum/disease/given_disease = null
if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes")
given_disease = AdminCreateVirus(client)
else
given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases)
if(!given_disease)
return
if(!istype(given_disease, /datum/disease/advance))
given_disease = new given_disease
T.ForceContractDisease(given_disease)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Disease") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] gave [key_name(T)] the disease [given_disease].")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] gave [key_name(T)] the disease [given_disease]."))
USER_VERB(disease_outbreak, R_EVENT, "Disease Outbreak", "Creates a disease and infects a random player with it.", VERB_CATEGORY_EVENT)
var/datum/disease/given_disease = null
if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes")
given_disease = AdminCreateVirus(client)
else
given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases)
if(!given_disease)
return
if(!istype(given_disease, /datum/disease/advance))
given_disease = new given_disease
for(var/thing in shuffle(GLOB.human_list))
var/mob/living/carbon/human/H = thing
if(H.stat == DEAD || !is_station_level(H.z))
continue
if(!H.HasDisease(given_disease))
H.ForceContractDisease(given_disease)
break
if(istype(given_disease, /datum/disease/advance))
var/datum/disease/advance/given_advanced_disease = given_disease
var/list/name_symptoms = list()
for(var/datum/symptom/S in given_advanced_disease.symptoms)
name_symptoms += S.name
message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_advanced_disease.name]! It has these symptoms: [english_list(name_symptoms)] and these base stats [english_map(given_advanced_disease.base_properties)]")
else
message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_disease.name]!")
USER_CONTEXT_MENU(make_sound, R_EVENT, "\[Admin\] Make Sound", obj/O in view())
if(O)
var/message = clean_input("What do you want the message to be?", "Make Sound", user = client)
if(!message)
return
for(var/mob/V in hearers(O))
V.show_message(admin_pencode_to_html(message), 2)
log_admin("[key_name(client)] made [O] at [O.x], [O.y], [O.z] make a sound")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [O] at [O.x], [O.y], [O.z] make a sound"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_build_mode_self, R_EVENT, "Toggle Build Mode Self", "Toggle Build Mode on yourself.", VERB_CATEGORY_EVENT)
if(client.mob)
togglebuildmode(client.mob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(object_talk, R_EVENT, "oSay", "Display a message to everyone who can hear the target", VERB_CATEGORY_EVENT, msg as text)
var/mob/living/mob = client.mob
if(mob.control_object)
if(!msg)
return
for(var/mob/V in hearers(mob.control_object))
V.show_message("<b>[mob.control_object.name]</b> says: \"" + msg + "\"", 2)
log_admin("[key_name(client)] used oSay on [mob.control_object]: [msg]")
message_admins("[key_name_admin(client)] used oSay on [mob.control_object]: [msg]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "oSay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(deadmin_self, R_ADMIN|R_MENTOR, "De-admin self", "De-admin yourself.", VERB_CATEGORY_ADMIN)
log_admin("[key_name(client)] deadmined themself.")
message_admins("[key_name_admin(client)] deadmined themself.")
@@ -405,19 +323,6 @@ USER_VERB(deadmin_self, R_ADMIN|R_MENTOR, "De-admin self", "De-admin yourself.",
to_chat(client, SPAN_INTERFACE("You are now a normal player."))
SSblackbox.record_feedback("tally", "admin_verb", 1, "De-admin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_log_hrefs, R_SERVER, "Toggle href logging", "Toggle href logging", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
// Why would we ever turn this off?
if(GLOB.configuration.logging.href_logging)
GLOB.configuration.logging.href_logging = FALSE
to_chat(client, "<b>Stopped logging hrefs</b>")
else
GLOB.configuration.logging.href_logging = TRUE
to_chat(client, "<b>Started logging hrefs</b>")
USER_VERB(check_ai_laws, R_ADMIN, "Check AI Laws", "Output AI laws.", VERB_CATEGORY_ADMIN)
client.holder.output_ai_laws()
@@ -430,52 +335,6 @@ USER_VERB(open_law_manager, R_ADMIN, "Manage Silicon Laws", "Open the law manage
log_and_message_admins("has opened [S]'s law manager.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Silicon Laws") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(change_human_appearance, R_EVENT, "\[Admin\] C.M.A. - Admin", mob/living/carbon/human/H in GLOB.mob_list)
if(!istype(H))
if(isbrain(H))
var/mob/living/brain/B = H
if(istype(B.container, /obj/item/mmi/robotic_brain/positronic))
var/obj/item/mmi/robotic_brain/positronic/C = B.container
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
if(ishuman(P.owner))
H = P.owner
else
return
else
return
if(client.holder)
log_and_message_admins("is altering the appearance of [H].")
H.change_appearance(APPEARANCE_ALL, client.mob, client.mob, check_species_whitelist = 0)
SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Admin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(change_human_appearance_self, R_EVENT, "\[Admin\] C.M.A. - Self",mob/living/carbon/human/H in GLOB.mob_list)
if(!istype(H))
if(isbrain(H))
var/mob/living/brain/B = H
if(istype(B.container, /obj/item/mmi/robotic_brain/positronic))
var/obj/item/mmi/robotic_brain/positronic/C = B.container
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
if(ishuman(P.owner))
H = P.owner
else
return
else
return
if(!H.client)
to_chat(client, "Only mobs with clients can alter their own appearance.")
return
switch(alert(client, "Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
if("Yes")
log_and_message_admins("has allowed [H] to change [H.p_their()] appearance, without whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
if("No")
log_and_message_admins("has allowed [H] to change [H.p_their()] appearance, with whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(free_job_slot, R_ADMIN, "Free Job Slot", "Frees a station job role.", VERB_CATEGORY_ADMIN)
var/list/jobs = list()
for(var/datum/job/J in SSjobs.occupations)
@@ -545,102 +404,11 @@ USER_VERB(send_alert_message, R_ADMIN, "Send Alert Message", "Sends a large noti
log_admin("[key_name(client)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".")
message_admins("[key_name(client)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".")
USER_VERB(debug_statpanel, R_DEBUG, "Debug Stat Panel", "Toggles local debug of the stat panel", VERB_CATEGORY_DEBUG)
client.stat_panel.send_message("create_debug")
USER_VERB(profile_code, R_DEBUG|R_VIEWRUNTIMES, "Profile Code", "View code profiler", VERB_CATEGORY_DEBUG)
winset(client, null, "command=.profile")
USER_VERB(export_character, R_ADMIN, "Export Character DMI/JSON", "Saves character DMI and JSON to data directory.", VERB_CATEGORY_ADMIN)
if(ishuman(client.mob))
var/mob/living/carbon/human/H = client.mob
H.export_dmi_json()
USER_VERB(raw_gas_scan, R_DEBUG|R_VIEWRUNTIMES, "Raw Gas Scan", "Scans your current tile, including LINDA data not normally displayed.", VERB_CATEGORY_DEBUG)
atmos_scan(client.mob, get_turf(client.mob), silent = TRUE, milla_turf_details = TRUE)
USER_VERB(find_interesting_turf, R_DEBUG|R_VIEWRUNTIMES, "Interesting Turf", \
"Teleports you to a random Interesting Turf from MILLA", VERB_CATEGORY_DEBUG)
if(!isobserver(client.mob))
to_chat(client.mob, SPAN_WARNING("You must be an observer to do this!"))
return
var/list/interesting_tile = get_random_interesting_tile()
if(!length(interesting_tile))
to_chat(client, SPAN_NOTICE("There are no interesting turfs. How interesting!"))
return
var/turf/T = interesting_tile[MILLA_INDEX_TURF]
var/mob/dead/observer/O = client.mob
admin_forcemove(O, T)
O.manual_follow(T)
USER_VERB(visualize_interesting_turfs, R_DEBUG|R_VIEWRUNTIMES, "Visualize Interesting Turfs", "Shows all the Interesting Turfs from MILLA", VERB_CATEGORY_DEBUG)
if(SSair.interesting_tile_count > 500)
// This can potentially iterate through a list thats 20k things long. Give ample warning to the user
if(tgui_alert(client, "WARNING: There are [SSair.interesting_tile_count] Interesting Turfs. This process will be lag intensive and should only be used if the atmos controller \
is screaming bloody murder. Are you sure you with to continue", "WARNING", list("I am sure", "Nope")) != "I am sure")
return
else
if(tgui_alert(client, "Visualizing turfs may cause server to lag. Are you sure?", "Warning", list("Yes", "No")) != "Yes")
return
var/display_turfs_overlay = FALSE
if(tgui_alert(client, "Would you like to have all interesting turfs have a client side overlay applied as well?", "Optional", list("Yes", "No")) == "Yes")
display_turfs_overlay = TRUE
message_admins("[key_name_admin(client)] is visualizing interesting atmos turfs. Server may lag.")
var/list/zlevel_turf_indexes = list()
var/list/coords = get_interesting_atmos_tiles()
if(!length(coords))
to_chat(client, SPAN_NOTICE("There are no interesting turfs. How interesting!"))
return
while(length(coords))
var/offset = length(coords) - MILLA_INTERESTING_TILE_SIZE
var/turf/T = coords[offset + MILLA_INDEX_TURF]
coords.len -= MILLA_INTERESTING_TILE_SIZE
// ENSURE YOU USE STRING NUMBERS HERE, THIS IS A DICTIONARY KEY NOT AN INDEX!!!
if(!zlevel_turf_indexes["[T.z]"])
zlevel_turf_indexes["[T.z]"] = list()
zlevel_turf_indexes["[T.z]"] |= T
if(display_turfs_overlay)
client.images += image('icons/effects/alphacolors.dmi', T, "red")
CHECK_TICK
// Sort the keys
zlevel_turf_indexes = sortAssoc(zlevel_turf_indexes)
for(var/key in zlevel_turf_indexes)
to_chat(client, SPAN_NOTICE("Z[key]: <b>[length(zlevel_turf_indexes["[key]"])] Interesting Turfs</b>"))
var/z_to_view = tgui_input_number(client, "A list of z-levels their ITs has appeared in chat. Please enter a Z to visualize. Enter 0 or close the window to cancel", "Selection", 0)
if(!z_to_view)
return
// Do not combine these
var/list/ui_dat = list()
var/list/turf_markers = list()
var/datum/browser/vis = new(client, "atvis", "Interesting Turfs (Z[z_to_view])", 300, 315)
ui_dat += "<center><canvas width=\"255px\" height=\"255px\" id=\"atmos\"></canvas></center>"
ui_dat += "<script>e=document.getElementById(\"atmos\");c=e.getContext('2d');c.fillStyle='#ffffff';c.fillRect(0,0,255,255);function s(x,y){var p=c.createImageData(1,1);p.data\[0]=255;p.data\[1]=0;p.data\[2]=0;p.data\[3]=255;c.putImageData(p,(x-1),255-Math.abs(y-1));}</script>"
// Now generate the other list
for(var/x in zlevel_turf_indexes["[z_to_view]"])
var/turf/T = x
turf_markers += "s([T.x],[T.y]);"
CHECK_TICK
ui_dat += "<script>[turf_markers.Join("")]</script>"
vis.set_content(ui_dat.Join(""))
vis.open(FALSE)
USER_VERB(create_rnd_restore_disk, R_ADMIN, "Create RnD Backup Restore Disk", "Create RnD Backup Restore Disk", VERB_CATEGORY_EVENT)
var/list/targets = list()
@@ -681,3 +449,365 @@ USER_VERB(create_rnd_restore_disk, R_ADMIN, "Create RnD Backup Restore Disk", "C
var/mob/dead/observer/A = client.mob
A.manual_follow(target)
USER_VERB(check_new_players, R_MENTOR|R_MOD|R_ADMIN, "Check New Players", "Perform a player account age check.", VERB_CATEGORY_ADMIN)
var/age = input(client, "Show accounts younger then ____ days", "Age check") as num|null
var/playtime_hours = input(client, "Show accounts with less than ____ hours", "Playtime check") as num|null
if(isnull(age))
age = -1
if(isnull(playtime_hours))
playtime_hours = -1
if(age <= 0 && playtime_hours <= 0)
return
var/missing_ages = 0
var/msg = ""
var/is_admin = check_rights(R_ADMIN, 0)
for(var/client/C in GLOB.clients)
if(C?.holder?.fakekey && !check_rights(R_ADMIN, FALSE))
continue // Skip those in stealth mode if an admin isnt viewing the panel
if(!isnum(C.player_age))
missing_ages = 1
continue
if(C.player_age < age)
if(is_admin)
msg += "[key_name_admin(C.mob)]: [C.player_age] days old<br>"
else
msg += "[key_name_mentor(C.mob)]: [C.player_age] days old<br>"
var/client_hours = C.get_exp_type_num(EXP_TYPE_LIVING) + C.get_exp_type_num(EXP_TYPE_GHOST)
client_hours /= 60 // minutes to hours
if(client_hours < playtime_hours)
if(is_admin)
msg += "[key_name_admin(C.mob)]: [client_hours] living + ghost hours<br>"
else
msg += "[key_name_mentor(C.mob)]: [client_hours] living + ghost hours<br>"
if(missing_ages)
to_chat(client, "Some accounts did not have proper ages set in their clients. This function requires database to be present")
if(msg != "")
client << browse(msg, "window=Player_age_check")
else
to_chat(client, "No matches for that age range found.")
USER_VERB_VISIBILITY(show_traitor_panel, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(show_traitor_panel, R_ADMIN|R_MOD, "Show Traitor Panel", "Edit mob's memory and role", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list)
if(!istype(M))
to_chat(client, "This can only be used on instances of type /mob")
return
if(!M.mind)
to_chat(client, "This mob has no mind!")
return
M.mind.edit_memory()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(player_notes, R_ADMIN|R_MOD, "Player Notes", "Open Player Notes panel.", VERB_CATEGORY_ADMIN)
show_note()
USER_VERB(player_notes_target, R_ADMIN|R_MOD, "Show Player Notes", "Show Player Notes panel for a given ckey.", VERB_CATEGORY_ADMIN, key as text)
show_note(key)
USER_VERB(vpn_whitelist, R_BAN, "VPN Ckey Whitelist", "Modify ckey's presence on VPN whitelist", VERB_CATEGORY_ADMIN)
var/key = stripped_input(client, "Enter ckey to add/remove, or leave blank to cancel:", "VPN Whitelist add/remove", max_length=32)
if(key)
GLOB.ipintel_manager.vpn_whitelist_panel(key)
USER_VERB(godmode, R_ADMIN, "Godmode", "Toggles godmode on a mob.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list)
M.status_flags ^= GODMODE
to_chat(client, SPAN_NOTICE("Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"))
log_admin("[key_name(client)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
message_admins("[key_name_admin(client)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Godmode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
if(automute)
if(!GLOB.configuration.general.enable_auto_mute)
return
else
if(!usr || !usr.client)
return
if(!check_rights(R_ADMIN|R_MOD))
to_chat(usr, "<font color='red'>Error: cmd_admin_mute: You don't have permission to do this.</font>")
return
if(!M.client)
to_chat(usr, "<font color='red'>Error: cmd_admin_mute: This mob doesn't have a client tied to it.</font>")
if(!M.client)
return
var/muteunmute
var/mute_string
switch(mute_type)
if(MUTE_IC)
mute_string = "IC (say and emote)"
if(MUTE_OOC)
mute_string = "OOC"
if(MUTE_PRAY)
mute_string = "pray"
if(MUTE_ADMINHELP)
mute_string = "adminhelp, admin PM and ASAY"
if(MUTE_DEADCHAT)
mute_string = "deadchat and DSAY"
if(MUTE_EMOTE)
mute_string = "emote"
if(MUTE_ALL)
mute_string = "everything"
else
return
if(automute)
muteunmute = "auto-muted"
force_add_mute(M.client.ckey, mute_type)
log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(M)] from [mute_string]")
message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
to_chat(M, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Automute") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
toggle_mute(M.client.ckey, mute_type)
if(check_mute(M.client.ckey, mute_type))
muteunmute = "muted"
else
muteunmute = "unmuted"
log_admin("[key_name(usr)] has [muteunmute] [key_name(M)] from [mute_string]")
message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(M)] from [mute_string].", 1)
to_chat(M, "You have been [muteunmute] from [mute_string].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mute") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(admin_rejuvenate, R_REJUVINATE, "\[Admin\] Rejuvenate", mob/living/M as mob in GLOB.mob_list)
if(!istype(M))
alert(client, "Cannot revive a ghost")
return
M.revive()
log_admin("[key_name(client)] healed / revived [key_name(M)]")
message_admins(SPAN_WARNING("Admin [key_name_admin(client)] healed / revived [key_name_admin(M)]!"), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvenate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(admin_delete, R_ADMIN, "\[Admin\] Delete", atom/A as obj|mob|turf in view())
client.admin_delete(A)
/client/proc/admin_delete(datum/D)
if(istype(D) && !D.can_vv_delete())
to_chat(src, "[D] rejected your deletion")
return
var/atom/A = D
var/coords = istype(A) ? "at ([A.x], [A.y], [A.z])" : ""
if(alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [D] [coords]")
message_admins("[key_name_admin(usr)] deleted [D] [coords]", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ChangeTurf(T.baseturf)
else
qdel(D)
USER_VERB(list_open_jobs, R_ADMIN, "List free slots", "List available station jobs.", VERB_CATEGORY_ADMIN)
if(SSjobs)
var/currentpositiontally
var/totalpositiontally
to_chat(client, SPAN_NOTICE("Job Name: Filled job slot / Total job slots <b>(Free job slots)</b>"))
for(var/datum/job/job in SSjobs.occupations)
to_chat(client, "<span class='notice'>[job.title]: [job.current_positions] / \
[job.total_positions == -1 ? "<b>UNLIMITED</b>" : job.total_positions] \
<b>([job.total_positions == -1 ? "UNLIMITED" : job.total_positions - job.current_positions])</b></span>")
if(job.total_positions != -1) // Only count position that isn't unlimited
currentpositiontally += job.current_positions
totalpositiontally += job.total_positions
to_chat(client, "<b>Currently filled job slots (Excluding unlimited): [currentpositiontally] / [totalpositiontally] ([totalpositiontally - currentpositiontally])</b>")
SSblackbox.record_feedback("tally", "admin_verb", 1, "List Free Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(admin_check_contents, R_ADMIN, "\[Admin\] Check Contents", mob/living/M as mob)
var/list/L = M.get_contents()
for(var/t in L)
to_chat(client, "[t]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_view_range, R_ADMIN, "Change View Range", "Change tile view range.", VERB_CATEGORY_ADMIN)
if(client.view == world.view)
client.view = input(client, "Select view range:", "View Range", world.view) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)
else
client.view = world.view
log_admin("[key_name(client)] changed their view range to [client.view].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Change View Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(call_shuttle, R_ADMIN, "Call Shuttle", "Calls the shuttle.", VERB_CATEGORY_ADMIN)
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
return
var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
if(alert(client, "Set Shuttle Recallable (Select Yes unless you know what this does)", "Recallable?", "Yes", "No") == "Yes")
SSshuttle.emergency.canRecall = TRUE
else
SSshuttle.emergency.canRecall = FALSE
if(SSsecurity_level.get_current_level_as_number() >= SEC_LEVEL_RED)
SSshuttle.emergency.request(coefficient = 0.5, redAlert = TRUE)
else
SSshuttle.emergency.request()
log_admin("[key_name(client)] admin-called the emergency shuttle.")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] admin-called the emergency shuttle."))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(cancel_shuttle, R_ADMIN, "Cancel Shuttle", "Cancels the shuttle.", VERB_CATEGORY_ADMIN)
if(alert(client, "You sure?", "Confirm", "Yes", "No") != "Yes") return
if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED)
return
if(!SSshuttle.emergency.canRecall)
if(alert(client, "Shuttle is currently set to be nonrecallable. Recalling may break things. Respect Recall Status?", "Override Recall Status?", "Yes", "No") == "Yes")
return
else
var/keepStatus = alert(client, "Maintain recall status on future shuttle calls?", "Maintain Status?", "Yes", "No") == "Yes" //Keeps or drops recallability
SSshuttle.emergency.canRecall = TRUE // must be true for cancel proc to work
SSshuttle.emergency.cancel(byCC = TRUE)
if(keepStatus)
SSshuttle.emergency.canRecall = FALSE // restores original status
else
SSshuttle.emergency.cancel(byCC = TRUE)
log_admin("[key_name(client)] admin-recalled the emergency shuttle.")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] admin-recalled the emergency shuttle."))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(deny_shuttle, R_ADMIN, "Toggle Deny Shuttle", "Toggles crew shuttle calling-ability.", VERB_CATEGORY_ADMIN)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "The game hasn't started yet!")
return
var/alert = alert(client, "Do you want to ALLOW or DENY shuttle calls?", "Toggle Deny Shuttle", "Allow", "Deny", "Cancel")
if(alert == "Cancel")
return
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deny Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(alert == "Allow")
if(!length(SSshuttle.hostile_environments))
to_chat(client, SPAN_NOTICE("No hostile environments found, cleared for takeoff!"))
return
if(alert(client, "[english_list(SSshuttle.hostile_environments)] is currently blocking the shuttle call, do you want to clear them?", "Toggle Deny Shuttle", "Yes", "No") == "Yes")
SSshuttle.hostile_environments.Cut()
var/log = "[key_name(client)] has cleared all hostile environments, allowing the shuttle to be called."
log_admin(log)
message_admins(log)
return
SSshuttle.registerHostileEnvironment(client) // wow, a client blocking the shuttle
log_and_message_admins("has denied the shuttle to be called.")
USER_VERB(open_attack_log, R_ADMIN, "Attack Log", "Prints the attack log.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list)
to_chat(client, SPAN_DANGER("Attack Log for [M]"))
for(var/t in M.attack_log_old)
to_chat(client, t)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Attack Log") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(reset_telecoms, R_ADMIN, "Reset NTTC Configuration", "Resets NTTC to the default configuration.", VERB_CATEGORY_ADMIN)
var/confirm = alert(client, "You sure you want to reset NTTC?", "Confirm", "Yes", "No")
if(confirm != "Yes")
return
for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines)
C.nttc.reset()
log_admin("[key_name(client)] reset NTTC scripts.")
message_admins("[key_name_admin(client)] reset NTTC scripts.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reset NTTC Configuration") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(list_ssds_afks, R_ADMIN, "List SSDs and AFKs", "List SSDs and AFK players", VERB_CATEGORY_ADMIN)
/* ======== SSD Section ========= */
var/msg = "<html><meta charset='utf-8'><head><title>SSD & AFK Report</title></head><body>"
msg += "SSD Players:<br><TABLE border='1'>"
msg += "<tr><td><b>Key</b></td><td><b>Real Name</b></td><td><b>Job</b></td><td><b>Mins SSD</b></td><td><b>Special Role</b></td><td><b>Area</b></td><td><b>PPN</b></td><td><b>Cryo</b></td></tr>"
var/mins_ssd
var/job_string
var/key_string
var/role_string
var/obj_count = 0
var/obj_string = ""
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(!isLivingSSD(H))
continue
mins_ssd = round((world.time - H.last_logout) / 600)
if(H.job)
job_string = H.job
else
job_string = "-"
key_string = H.key
if(job_string in GLOB.command_positions)
job_string = "<U>" + job_string + "</U>"
role_string = "-"
obj_count = 0
obj_string = ""
if(H.mind)
if(H.mind.special_role)
role_string = "<U>[H.mind.special_role]</U>"
if(!H.key && H.mind.key)
key_string = H.mind.key
for(var/datum/objective/O in GLOB.all_objectives)
if(O.target == H.mind)
obj_count++
if(obj_count > 0)
obj_string = "<BR><U>Obj Target</U>"
msg += "<TR><TD>[key_string]</TD><TD>[H.real_name]</TD><TD>[job_string]</TD><TD>[mins_ssd]</TD><TD>[role_string][obj_string]</TD>"
msg += "<TD>[get_area(H)]</TD><TD>[ADMIN_PP(H,"PP")]</TD>"
if(istype(H.loc, /obj/machinery/cryopod))
msg += "<TD><A href='byond://?_src_=holder;cryossd=[H.UID()]'>De-Spawn</A></TD>"
else
msg += "<TD><A href='byond://?_src_=holder;cryossd=[H.UID()]'>Cryo</A></TD>"
msg += "</TR>"
msg += "</TABLE><br></BODY></HTML>"
/* ======== AFK Section ========= */
msg += "AFK Players:<BR><TABLE border='1'>"
msg += "<TR><TD><B>Key</B></TD><TD><B>Real Name</B></TD><TD><B>Job</B></TD><TD><B>Mins AFK</B></TD><TD><B>Special Role</B></TD><TD><B>Area</B></TD><TD><B>PPN</B></TD><TD><B>Cryo</B></TD></TR>"
var/mins_afk
for(var/thing in GLOB.human_list)
var/mob/living/carbon/human/H = thing
if(H.client == null || H.stat == DEAD) // No clientless or dead
continue
mins_afk = round(H.client.inactivity / 600)
if(mins_afk < 5)
continue
if(H.job)
job_string = H.job
else
job_string = "-"
key_string = H.key
if(job_string in GLOB.command_positions)
job_string = "<U>" + job_string + "</U>"
role_string = "-"
obj_count = 0
obj_string = ""
if(H.mind)
if(H.mind.special_role)
role_string = "<U>[H.mind.special_role]</U>"
if(!H.key && H.mind.key)
key_string = H.mind.key
for(var/datum/objective/O in GLOB.all_objectives)
if(O.target == H.mind)
obj_count++
if(obj_count > 0)
obj_string = "<BR><U>Obj Target</U>"
msg += "<TR><TD>[key_string]</TD><TD>[H.real_name]</TD><TD>[job_string]</TD><TD>[mins_afk]</TD><TD>[role_string][obj_string]</TD>"
msg += "<TD>[get_area(H)]</TD><TD>[ADMIN_PP(H,"PP")]</TD>"
if(istype(H.loc, /obj/machinery/cryopod))
msg += "<TD><A href='byond://?_src_=holder;cryossd=[H.UID()];cryoafk=1'>De-Spawn</A></TD>"
else
msg += "<TD><A href='byond://?_src_=holder;cryossd=[H.UID()];cryoafk=1'>Cryo</A></TD>"
msg += "</TR>"
msg += "</TABLE></BODY></HTML>"
client << browse(msg, "window=Player_ssd_afk_check;size=600x300")
+689
View File
@@ -0,0 +1,689 @@
USER_VERB_VISIBILITY(trigger_event, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(trigger_event, R_EVENT, "Trigger Event", "Trigger Event", VERB_CATEGORY_EVENT, event_type in SSevents.allEvents)
if(ispath(event_type))
new event_type(new /datum/event_meta(EVENT_LEVEL_MAJOR))
message_admins("[key_name_admin(client)] has triggered an event. ([event_type])", 1)
USER_VERB(event_manager_panel, R_EVENT, "Event Manager Panel", "Event Manager Panel", VERB_CATEGORY_EVENT)
if(SSevents)
SSevents.Interact(client)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Event Manager") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(start_server_now, R_SERVER, "Start Now", "Start the round RIGHT NOW", VERB_CATEGORY_SERVER)
if(SSticker.current_state < GAME_STATE_STARTUP)
alert(client, "Unable to start the game as it is not set up.")
return
if(!SSticker.ticker_going)
alert(client, "Remove the round-start delay first.")
return
if(GLOB.configuration.general.start_now_confirmation)
if(alert(client, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes")
return
if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP)
SSticker.force_start = TRUE
log_admin("[client.key] has started the game.")
var/msg = ""
if(SSticker.current_state == GAME_STATE_STARTUP)
msg = " (The server is still setting up, but the round will be started as soon as possible.)"
message_admins(SPAN_DARKMBLUE("[client.key] has started the game.[msg]"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Start Game") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return 1
else
to_chat(client, "<font color='red'>Error: Start Now: Game has already started.</font>")
return
USER_VERB(drop_bomb, R_EVENT, "Drop Bomb", "Cause an explosion of varying strength at your location.", VERB_CATEGORY_EVENT)
var/turf/epicenter = client.mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/choice = tgui_input_list(client, "What size explosion would you like to produce?", "Drop Bomb", choices)
switch(choice)
if(null)
return 0
if("Small Bomb")
explosion(epicenter, 1, 2, 3, 3, cause = "[client.ckey]: Drop Bomb command")
if("Medium Bomb")
explosion(epicenter, 2, 3, 4, 4, cause = "[client.ckey]: Drop Bomb command")
if("Big Bomb")
explosion(epicenter, 3, 5, 7, 5, cause = "[client.ckey]: Drop Bomb command")
if("Custom Bomb")
var/devastation_range = tgui_input_number(client, "Devastation range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(devastation_range))
return
var/heavy_impact_range = tgui_input_number(client, "Heavy impact range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(heavy_impact_range))
return
var/light_impact_range = tgui_input_number(client, "Light impact range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(light_impact_range))
return
var/flash_range = tgui_input_number(client, "Flash range (in tiles):", "Custom Bomb", max_value = 255)
if(isnull(flash_range))
return
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, 1, 1, cause = "[client.ckey]: Drop Bomb command")
log_admin("[key_name(client)] created an admin explosion at [epicenter.loc]")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] created an admin explosion at [epicenter.loc]"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(give_spell, R_EVENT, "Give Spell", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T)
var/list/spell_list = list()
var/type_length = length("/datum/spell") + 2
for(var/A in GLOB.spells)
spell_list[copytext("[A]", type_length)] = A
var/datum/spell/S = input(client, "Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list
if(!S)
return
S = spell_list[S]
if(T.mind)
T.mind.AddSpell(new S)
else
T.AddSpell(new S)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] gave [key_name(T)] the spell [S].")
message_admins("[key_name_admin(client)] gave [key_name(T)] the spell [S].", 1)
USER_VERB(give_disease, R_EVENT, "Give Disease", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T)
var/datum/disease/given_disease = null
if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes")
given_disease = AdminCreateVirus(client)
else
given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases)
if(!given_disease)
return
if(!istype(given_disease, /datum/disease/advance))
given_disease = new given_disease
T.ForceContractDisease(given_disease)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Disease") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] gave [key_name(T)] the disease [given_disease].")
message_admins(SPAN_ADMINNOTICE("[key_name_admin(client)] gave [key_name(T)] the disease [given_disease]."))
USER_VERB(disease_outbreak, R_EVENT, "Disease Outbreak", "Creates a disease and infects a random player with it.", VERB_CATEGORY_EVENT)
var/datum/disease/given_disease = null
if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes")
given_disease = AdminCreateVirus(client)
else
given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases)
if(!given_disease)
return
if(!istype(given_disease, /datum/disease/advance))
given_disease = new given_disease
for(var/thing in shuffle(GLOB.human_list))
var/mob/living/carbon/human/H = thing
if(H.stat == DEAD || !is_station_level(H.z))
continue
if(!H.HasDisease(given_disease))
H.ForceContractDisease(given_disease)
break
if(istype(given_disease, /datum/disease/advance))
var/datum/disease/advance/given_advanced_disease = given_disease
var/list/name_symptoms = list()
for(var/datum/symptom/S in given_advanced_disease.symptoms)
name_symptoms += S.name
message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_advanced_disease.name]! It has these symptoms: [english_list(name_symptoms)] and these base stats [english_map(given_advanced_disease.base_properties)]")
else
message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_disease.name]!")
USER_CONTEXT_MENU(make_sound, R_EVENT, "\[Admin\] Make Sound", obj/O in view())
if(O)
var/message = clean_input("What do you want the message to be?", "Make Sound", user = client)
if(!message)
return
for(var/mob/V in hearers(O))
V.show_message(admin_pencode_to_html(message), 2)
log_admin("[key_name(client)] made [O] at [O.x], [O.y], [O.z] make a sound")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [O] at [O.x], [O.y], [O.z] make a sound"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_build_mode_self, R_EVENT, "Toggle Build Mode Self", "Toggle Build Mode on yourself.", VERB_CATEGORY_EVENT)
if(client.mob)
togglebuildmode(client.mob)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(object_talk, R_EVENT, "oSay", "Display a message to everyone who can hear the target", VERB_CATEGORY_EVENT, msg as text)
var/mob/living/mob = client.mob
if(mob.control_object)
if(!msg)
return
for(var/mob/V in hearers(mob.control_object))
V.show_message("<b>[mob.control_object.name]</b> says: \"" + msg + "\"", 2)
log_admin("[key_name(client)] used oSay on [mob.control_object]: [msg]")
message_admins("[key_name_admin(client)] used oSay on [mob.control_object]: [msg]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "oSay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(change_human_appearance, R_EVENT, "\[Admin\] C.M.A. - Admin", mob/living/carbon/human/H in GLOB.mob_list)
if(!istype(H))
if(isbrain(H))
var/mob/living/brain/B = H
if(istype(B.container, /obj/item/mmi/robotic_brain/positronic))
var/obj/item/mmi/robotic_brain/positronic/C = B.container
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
if(ishuman(P.owner))
H = P.owner
else
return
else
return
if(client.holder)
log_and_message_admins("is altering the appearance of [H].")
H.change_appearance(APPEARANCE_ALL, client.mob, client.mob, check_species_whitelist = 0)
SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Admin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(change_human_appearance_self, R_EVENT, "\[Admin\] C.M.A. - Self",mob/living/carbon/human/H in GLOB.mob_list)
if(!istype(H))
if(isbrain(H))
var/mob/living/brain/B = H
if(istype(B.container, /obj/item/mmi/robotic_brain/positronic))
var/obj/item/mmi/robotic_brain/positronic/C = B.container
var/obj/item/organ/internal/brain/mmi_holder/posibrain/P = C.loc
if(ishuman(P.owner))
H = P.owner
else
return
else
return
if(!H.client)
to_chat(client, "Only mobs with clients can alter their own appearance.")
return
switch(alert(client, "Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
if("Yes")
log_and_message_admins("has allowed [H] to change [H.p_their()] appearance, without whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
if("No")
log_and_message_admins("has allowed [H] to change [H.p_their()] appearance, with whitelisting of races.")
H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ai_role, R_EVENT, "Toggle AI", "People can't be AI", VERB_CATEGORY_EVENT)
GLOB.configuration.jobs.allow_ai = !(GLOB.configuration.jobs.allow_ai)
if(!GLOB.configuration.jobs.allow_ai)
to_chat(world, "<B>The AI job is no longer chooseable.</B>")
else
to_chat(world, "<B>The AI job is chooseable now.</B>")
message_admins("[key_name_admin(client)] toggled AI allowed.")
log_admin("[key_name(client)] toggled AI allowed.")
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle AI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(change_custom_event, R_EVENT, "Change Custom Event", "Set a custom event.", VERB_CATEGORY_EVENT)
var/input = input(client, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", GLOB.custom_event_msg) as message|null
if(!input || input == "")
GLOB.custom_event_msg = null
log_admin("[key_name(client)] has cleared the custom event text.")
message_admins("[key_name_admin(client)] has cleared the custom event text.")
return
log_admin("[key_name(client)] has changed the custom event text.")
message_admins("[key_name_admin(client)] has changed the custom event text.")
GLOB.custom_event_msg = input
to_chat(world, "<h1 class='alert'>Custom Event</h1>")
to_chat(world, "<h2 class='alert'>A custom event is starting. OOC Info:</h2>")
to_chat(world, SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]"))
to_chat(world, "<br>")
// normal verb for players to view info
/client/verb/cmd_view_custom_event()
set category = "OOC"
set name = "Custom Event Info"
var/list/custom_event_information = list()
if(!GLOB.custom_event_msg || GLOB.custom_event_msg == "")
custom_event_information += "There currently is no known custom event taking place."
custom_event_information += "Keep in mind: it is possible that an admin has not properly set this."
to_chat(src, chat_box_regular(custom_event_information.Join("<br>")))
return
custom_event_information += "<h1 class='alert'>Custom Event</h1>"
custom_event_information += "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>"
custom_event_information += SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]")
to_chat(src, chat_box_regular(custom_event_information.Join("<br>")))
USER_VERB(toggle_ert_calling, R_EVENT, "Toggle ERT", "Toggle the station's ability to call a response team.", VERB_CATEGORY_EVENT)
if(SSticker.mode.ert_disabled)
SSticker.mode.ert_disabled = FALSE
to_chat(client, SPAN_NOTICE("ERT has been <b>Enabled</b>."))
log_admin("Admin [key_name(client)] has enabled ERT calling.")
message_admins("Admin [key_name_admin(client)] has enabled ERT calling.", 1)
else
SSticker.mode.ert_disabled = TRUE
to_chat(client, SPAN_WARNING("ERT has been <b>Disabled</b>."))
log_admin("Admin [key_name(client)] has disabled ERT calling.")
message_admins("Admin [key_name_admin(client)] has disabled ERT calling.", 1)
USER_VERB(show_tip, R_EVENT, "Show Custom Tip", \
"Sends a tip (that you specify) to all players. After all, you're the experienced player here.", \
VERB_CATEGORY_EVENT)
var/input = input(client, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null
if(!input)
return
if(SSticker.current_state < GAME_STATE_PREGAME)
return
SSticker.selected_tip = input
// If we've already tipped, then send it straight away.
if(SSticker.tipped)
SSticker.send_tip_of_the_round()
message_admins("[key_name_admin(client)] sent a custom Tip of the round.")
log_admin("[key_name(client)] sent \"[input]\" as the Tip of the Round.")
return
message_admins("[key_name_admin(client)] set the Tip of the round to \"[html_encode(SSticker.selected_tip)]\".")
log_admin("[key_name(client)] sent \"[input]\" as the Tip of the Round.")
USER_VERB(modify_goals, R_EVENT, "Modify Station Goals", "Modify station goals.", VERB_CATEGORY_EVENT)
client.holder.modify_goals()
/datum/admins/proc/modify_goals()
if(SSticker.current_state < GAME_STATE_PLAYING)
to_chat(usr, SPAN_WARNING("This verb can only be used if the round has started."))
return
var/list/dat = list("<!DOCTYPE html>")
for(var/datum/station_goal/S in SSticker.mode.station_goals)
dat += "[S.name][S.completed ? " (C)" : ""] - <a href='byond://?src=[S.UID()];announce=1'>Announce</a> | <a href='byond://?src=[S.UID()];remove=1'>Remove</a>"
dat += ""
dat += "<a href='byond://?src=[UID()];add_station_goal=1'>Add New Goal</a>"
dat += ""
dat += "<b>Secondary goals</b>"
for(var/datum/station_goal/secondary/SG in SSticker.mode.secondary_goals)
dat += "[SG.admin_desc][SG.completed ? " (C)" : ""] for [SG.requester_name || SG.department] - <a href='byond://?src=[SG.UID()];announce=1'>Announce</a> | <a href='byond://?src=[SG.UID()];remove=1'>Remove</a> | <a href='byond://?src=[SG.UID()];mark_complete=1'>Mark complete</a> | <a href='byond://?src=[SG.UID()];reset_progress=1'>Reset progress</a>"
dat += "<a href='byond://?src=[UID()];add_secondary_goal=1'>Add New Secondary Goal</a>"
usr << browse(dat.Join("<br>"), "window=goals;size=400x400")
USER_VERB(toggle_random_events, R_SERVER|R_EVENT, "Toggle random events on/off", \
"Toggles random events such as meteors, black holes, blob (but not space dust) on/off", \
VERB_CATEGORY_EVENT)
if(tgui_alert(client, "[GLOB.configuration.event.enable_random_events ? "Disable" : "Enable"] random events?", "Confirm", list("Yes", "No")) != "Yes")
return
if(!GLOB.configuration.event.enable_random_events)
GLOB.configuration.event.enable_random_events = TRUE
to_chat(client, "Random events enabled")
message_admins("Admin [key_name_admin(client)] has enabled random events.")
else
GLOB.configuration.event.enable_random_events = FALSE
to_chat(client, "Random events disabled")
message_admins("Admin [key_name_admin(client)] has disabled random events.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Random Events") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(everyone_random, R_SERVER|R_EVENT, "Make Everyone Random", \
"Make everyone have a random appearance. You can only use this before rounds!", \
VERB_CATEGORY_EVENT)
if(SSticker && SSticker.mode)
to_chat(client, "Nope you can't do this, the game's already started. This only works before rounds!")
return
if(SSticker.random_players)
SSticker.random_players = 0
message_admins("Admin [key_name_admin(client)] has disabled \"Everyone is Special\" mode.", 1)
to_chat(client, "Disabled.")
return
var/notifyplayers = alert(client, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel")
if(notifyplayers == "Cancel")
return
log_admin("Admin [key_name(client)] has forced the players to have random appearances.")
message_admins("Admin [key_name_admin(client)] has forced the players to have random appearances.", 1)
if(notifyplayers == "Yes")
to_chat(world, SPAN_NOTICE("<b>Admin [client.key] has forced the players to have completely random identities!</b>"))
to_chat(client, "<i>Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet</i>.")
SSticker.random_players = 1
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(admin_explosion, R_DEBUG|R_EVENT, "Explosion", "Create a custom explosion.", VERB_CATEGORY_EVENT, atom/O as obj|mob|turf in view())
var/devastation = input(client, "Range of total devastation. -1 to none", "Input") as num|null
if(devastation == null) return
var/heavy = input(client, "Range of heavy impact. -1 to none", "Input") as num|null
if(heavy == null) return
var/light = input(client, "Range of light impact. -1 to none", "Input") as num|null
if(light == null) return
var/flash = input(client, "Range of flash. -1 to none", "Input") as num|null
if(flash == null) return
var/flames = input(client, "Range of flames. -1 to none", "Input") as num|null
if(flames == null) return
if((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1))
if((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20))
if(alert(client, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
return
explosion(O, devastation, heavy, light, flash, null, null,flames, cause = "[client.ckey]: Explosion command")
log_admin("[key_name(client)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(client)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
SSblackbox.record_feedback("tally", "admin_verb", 1, "EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
return
USER_VERB(admin_emp, R_DEBUG|R_EVENT, "EM Pulse", "Cause an electromagnetic pulse.", VERB_CATEGORY_EVENT, atom/O as obj|mob|turf in view())
var/heavy = input(client, "Range of heavy pulse.", "Input") as num|null
if(heavy == null) return
var/light = input(client, "Range of light pulse.", "Input") as num|null
if(light == null) return
if(heavy || light)
empulse(O, heavy, light)
log_admin("[key_name(client)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])")
message_admins("[key_name_admin(client)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
else
return
USER_VERB(gib_mob, R_ADMIN|R_EVENT, "Gib", "Gibs a chosen mob.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list)
var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
//Due to the delay here its easy for something to have happened to the mob
if(!M) return
log_admin("[key_name(client)] has gibbed [key_name(M)]")
message_admins("[key_name_admin(client)] has gibbed [key_name_admin(M)]", 1)
if(isobserver(M))
gibs(M.loc)
return
M.gib()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(gib_self, R_ADMIN|R_EVENT, "Gibself", "Gibself.", VERB_CATEGORY_EVENT)
var/mob/mob = client.mob
var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
if(isobserver(mob)) // so they don't spam gibs everywhere
return
else
mob.gib()
log_admin("[key_name(client)] used gibself.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] used gibself."), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Gibself") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_ghosts(notify = 0, what = 2)
// what = 1, return ghosts ass list.
// what = 2, return mob list
var/list/mobs = list()
var/list/ghosts = list()
var/list/sortmob = sortAtom(GLOB.mob_list) // get the mob list.
var/any=0
for(var/mob/dead/observer/M in sortmob)
mobs.Add(M) //filter it where it's only ghosts
any = 1 //if no ghosts show up, any will just be 0
if(!any)
if(notify)
to_chat(src, "There doesn't appear to be any ghosts for you to select.")
return
for(var/mob/M in mobs)
var/name = M.name
ghosts[name] = M //get the name of the mob for the popup list
if(what==1)
return ghosts
else
return mobs
USER_VERB(add_freeform_ai_law, R_EVENT, "Add Custom AI law", "Add custom AI law.", VERB_CATEGORY_EVENT)
var/input = clean_input("Please enter anything you want the AI to do. Anything. Serious.", "What?", "", user = client)
if(!input)
return
log_admin("Admin [key_name(client)] has added a new AI law - [input]")
message_admins("Admin [key_name_admin(client)] has added a new AI law - [input]")
var/show_log = alert(client, "Show ion message?", "Message", "Yes", "No")
var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
new /datum/event/ion_storm(botEmagChance = 0, announceEvent = announce_ion_laws, ionMessage = input)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(create_centcom_report, R_SERVER|R_EVENT, "Create Communications Report", "Send an IC announcement to the game world.", VERB_CATEGORY_EVENT)
//the stuff on the list is |"report type" = "report title"|, if that makes any sense
var/list/MsgType = list("Central Command Report" = "Nanotrasen Update",
"Syndicate Communique" = "Syndicate Message",
"Space Wizard Federation Message" = "Sorcerous Message",
"Enemy Communications" = "Unknown Message",
"Custom" = "Cryptic Message")
var/list/MsgSound = list("Beep" = 'sound/misc/notice2.ogg',
"Enemy Communications Intercepted" = 'sound/AI/intercept.ogg',
"New Command Report Created" = 'sound/AI/commandreport.ogg')
var/type = input(client, "Pick a type of report to send", "Report Type", "") as anything in MsgType
if(type == "Custom")
type = clean_input("What would you like the report type to be?", "Report Type", "Encrypted Transmission", user = client)
var/subtitle = input(client, "Pick a title for the report.", "Title", MsgType[type]) as text|null
if(!subtitle)
return
var/message = input(client, "Please enter anything you want. Anything. Serious.", "What's the message?") as message|null
if(!message)
return
switch(alert(client, "Should this be announced to the general population?", null,"Yes","No", "Cancel"))
if("Yes")
var/beepsound = input(client, "What sound should the announcement make?", "Announcement Sound", "") as anything in MsgSound
var/should_translate = alert(client, "Should it be auto-translated for all human mobs?", "Translation", "Yes", "No")
if(should_translate != "Yes")
should_translate = null // We can just do it like this since force_translation just needs any value to not be false/null
GLOB.major_announcement.Announce(
message,
new_title = type,
new_subtitle = subtitle,
new_sound = MsgSound[beepsound],
force_translation = should_translate
)
print_command_report(message, subtitle)
if("No")
//same thing as the blob stuff - it's not public, so it's classified, dammit
GLOB.command_announcer.autosay("A classified message has been printed out at all communication consoles.")
print_command_report(message, "Classified: [subtitle]")
else
return
log_admin("[key_name(client)] has created a communications report: [message]")
message_admins("[key_name_admin(client)] has created a communications report", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Comms Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(add_random_ai_law, R_EVENT, "Add Random AI Law", "Add a random law to the AI.", VERB_CATEGORY_EVENT)
var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
log_admin("[key_name(client)] has added a random AI law.")
message_admins("[key_name_admin(client)] has added a random AI law.")
var/show_log = alert(client, "Show ion message?", "Message", "Yes", "No")
var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
new /datum/event/ion_storm(botEmagChance = 0, announceEvent = announce_ion_laws)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Random AI Law")
USER_CONTEXT_MENU(subtle_message, R_EVENT, "\[Admin\] Subtle Message", mob/M as mob in GLOB.mob_list)
if(!ismob(M))
return
var/msg = clean_input("Message:", "Subtle PM to [M.key]", user = client)
if(!msg)
return
msg = admin_pencode_to_html(msg)
if(client.holder)
to_chat(M, "<b>You hear a voice in your head... <i>[msg]</i></b>")
log_admin("SubtlePM: [key_name(client)] -> [key_name(M)] : [msg]")
message_admins(SPAN_BOLDNOTICE("Subtle Message: [key_name_admin(client)] -> [key_name_admin(M)] : [msg]"), 1)
M.create_log(MISC_LOG, "Subtle Message: [msg]", "From: [key_name_admin(client)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(economy_panel, R_EVENT, "Economy Panel", "Open the economy panel.", VERB_CATEGORY_EVENT)
var/datum/ui_module/economy_manager/E = new()
E.ui_interact(client.mob)
USER_VERB(dispatch_ert, R_EVENT, "Dispatch CentComm Response Team", \
"Send an CentComm response team to the station.", \
VERB_CATEGORY_EVENT)
if(SSticker.current_state < GAME_STATE_PLAYING)
to_chat(client, SPAN_WARNING("The game hasn't started yet!"))
return
if(SSticker.current_state == GAME_STATE_PREGAME)
to_chat(client, SPAN_WARNING("The round hasn't started yet!"))
return
var/datum/ui_module/ert_manager/E = new()
E.ui_interact(client.mob)
USER_VERB_VISIBILITY(grant_full_access, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(grant_full_access, R_EVENT, "Grant Full Access", "Gives mob all-access.", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.wear_id)
var/obj/item/card/id/id = H.wear_id
if(istype(H.wear_id, /obj/item/pda))
var/obj/item/pda/pda = H.wear_id
id = pda.id
id.icon_state = "gold"
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
else
var/obj/item/card/id/id = new/obj/item/card/id(M)
id.icon_state = "gold"
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
id.registered_name = H.real_name
id.assignment = "Captain"
id.name = "[id.registered_name]'s ID Card ([id.assignment])"
H.equip_to_slot_or_del(id, ITEM_SLOT_ID)
H.update_inv_wear_id()
else
alert(client, "Invalid mob")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Grant Full Access") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] has granted [M.key] full access.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] has granted [M.key] full access."), 1)
USER_VERB(outfit_manager, R_EVENT, "Outfit Manager", "Opens the outfit manager.", VERB_CATEGORY_EVENT)
client.holder.outfit_manager(client.mob)
USER_CONTEXT_MENU(select_equipment, R_EVENT, "\[Admin\] Select equipment", mob/living/carbon/human/M in GLOB.human_list)
if(!ishuman(M) && !isobserver(M))
alert(client, "Invalid mob")
return
var/dresscode = client.robust_dress_shop()
if(!dresscode)
return
var/delete_pocket
var/mob/living/carbon/human/H
if(isobserver(M))
H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE)
else
H = M
if(H.l_store || H.r_store || H.s_store) //saves a lot of time for admins and coders alike
if(alert(client, "Should the items in their pockets be dropped? Selecting \"No\" will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
delete_pocket = TRUE
for(var/obj/item/I in H.get_equipped_items(delete_pocket))
qdel(I)
if(dresscode != "Naked")
H.equipOutfit(dresscode)
H.regenerate_icons()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins(SPAN_NOTICE("[key_name_admin(client)] changed the equipment of [key_name_admin(M)] to [dresscode]."), 1)
USER_VERB(one_click_antag, R_SERVER|R_EVENT, "Create Antagonist", "Auto-create an antagonist of your choice", VERB_CATEGORY_EVENT)
if(client.holder)
client.holder.one_click_antag()
USER_VERB(global_narrate, R_SERVER|R_EVENT, "Global Narrate", "Narrate text to the whole game world.", VERB_CATEGORY_EVENT)
var/msg = clean_input("Message:", "Enter the text you wish to appear to everyone:", user = client)
if(!msg)
return
msg = admin_pencode_to_html(msg)
to_chat(world, "[msg]")
log_admin("GlobalNarrate: [key_name(client)] : [msg]")
message_admins(SPAN_BOLDNOTICE("GlobalNarrate: [key_name_admin(client)]: [msg]<BR>"), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Global Narrate")
USER_CONTEXT_MENU(direct_narrate, R_SERVER|R_EVENT, "\[Admin\] Direct Narrate", mob/M)
if(!M)
M = input(client, "Direct narrate to who?", "Active Players") as null|anything in get_mob_with_client_list()
if(!M)
return
var/msg = clean_input("Message:", "Enter the text you wish to appear to your target:", user = client)
if(!msg)
return
msg = admin_pencode_to_html(msg)
to_chat(M, msg)
log_admin("DirectNarrate: [key_name(client)] to ([key_name(M)]): [msg]")
message_admins(SPAN_BOLDNOTICE("Direct Narrate: [key_name_admin(client)] to ([key_name_admin(M)]): [msg]<br>"), 1)
M.create_log(MISC_LOG, "Direct Narrate: [msg]", "From: [key_name_admin(client)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_CONTEXT_MENU(headset_message, R_SERVER|R_EVENT, "\[Admin\] Headset Message", mob/M in GLOB.mob_list)
client.admin_headset_message(M)
/client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null)
var/mob/living/carbon/human/H = M
if(!check_rights(R_EVENT))
return
if(!istype(H))
to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human")
return
if(!istype(H.l_ear, /obj/item/radio/headset) && !istype(H.r_ear, /obj/item/radio/headset))
to_chat(usr, "The person you are trying to contact is not wearing a headset")
return
if(!sender)
sender = input("Who is the message from?", "Sender") as null|anything in list("Centcomm", "Syndicate")
if(!sender)
return
message_admins("[key_name_admin(src)] has started answering [key_name_admin(H)]'s [sender] request.")
var/input = clean_input("Please enter a message to reply to [key_name(H)] via their headset.", "Outgoing message from [sender]", "")
if(!input)
message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.")
return
log_admin("[key_name(src)] replied to [key_name(H)]'s [sender] message with the message [input].")
message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"")
H.create_log(MISC_LOG, "Headset Message: [input]", "From: [key_name_admin(src)]")
to_chat(H, "<span class = 'specialnotice bold'>Incoming priority transmission from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"]</span><span class = 'specialnotice'> [input]</span>")
SEND_SOUND(H, 'sound/effects/headset_message.ogg')
-510
View File
@@ -70,236 +70,8 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE)
///////////////////////////////////////////////////////////////////////////////////////////////Panels
USER_CONTEXT_MENU(show_player_panel, R_ADMIN|R_MOD, "\[Admin\] Show Player Panel", mob/M)
if(!M)
to_chat(client, "You seem to be selecting a mob that doesn't exist anymore.")
return
var/our_key = M.key
if(M.client && M.client.holder)
if(M.client.holder.fakekey && M.client.holder.big_brother)
our_key = M.client.holder.fakekey
var/mob_uid = M.UID()
var/body = "<html><meta charset='UTF-8'><head><title>Options for [our_key]</title></head>"
body += "<body>Options panel for <b>[M]</b>"
if(M.client)
body += " played by <b>[M.client]</b> "
if(check_rights(R_PERMISSIONS, FALSE))
body += "\[<A href='byond://?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\] "
else if(M.client.holder && M.client.holder.fakekey && M.client.holder.big_brother)
body += "\[Player\] "
else
body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\] "
body += "\[<A href='byond://?_src_=holder;getplaytimewindow=[mob_uid]'>" + M.client.get_exp_type(EXP_TYPE_CREW) + " as [EXP_TYPE_CREW]</a>\]"
body += "<br>BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "<b>" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "</b>" : ""]"
body += "<br>BYOND client version: [M.client.byond_version].[M.client.byond_build]"
body += "<br>Global Ban DB Lookup: [GLOB.configuration.url.centcom_ban_db_url ? "<a href='byond://?_src_=holder;open_ccbdb=[M.client.ckey]'>Lookup</a>" : "<i>Disabled</i>"]"
body += "<br><a href='byond://?_src_=holder;clientmodcheck=[M.client.UID()]'>Check for client modification</a>"
body += "<br>"
if(isnewplayer(M))
body += " <B>Hasn't Entered Game</B> "
else
body += " \[<A href='byond://?_src_=holder;revive=[mob_uid]'>Heal</A>\] "
body += "<br><br>\[ "
body += "<a href='byond://?_src_=holder;open_logging_view=[mob_uid];'>LOGS</a> - "
body += "<a href='byond://?_src_=vars;Vars=[mob_uid]'>VV</a> - "
body += "[ADMIN_TP(M,"TP")] - "
if(M.client)
body += "<a href='byond://?src=[usr.UID()];priv_msg=[M.client.ckey]'>PM</a> - "
body += "[ADMIN_SM(M,"SM")] - "
if(ishuman(M) && M.mind)
body += "<a href='byond://?_src_=holder;HeadsetMessage=[mob_uid]'>HM</a> - "
body += "[admin_jump_link(M)] - "
body += "<a href='byond://?_src_=holder;adminalert=[mob_uid]'>SEND ALERT</a>\]</b><br>"
body += "<b>Mob type:</b> [M.type]<br>"
if(M.client)
if(length(M.client.related_accounts_cid))
body += "<b>Related accounts by CID:</b> [jointext(M.client.related_accounts_cid, " - ")]<br>"
if(length(M.client.related_accounts_ip))
body += "<b>Related accounts by IP:</b> [jointext(M.client.related_accounts_ip, " - ")]<br><br>"
if(M.ckey)
body += "<b>Enabled AntagHUD</b>: [M.has_ahudded() ? "<b><font color='red'>TRUE</font></b>" : "false"]<br>"
body += "<b>Roundstart observer</b>: [M.is_roundstart_observer() ? "<b>true</b>" : "false"]<br>"
body += "<A href='byond://?_src_=holder;boot2=[mob_uid]'>Kick</A> | "
body += "<A href='byond://?_src_=holder;newban=[mob_uid];dbbanaddckey=[M.ckey]'>Ban</A> | "
body += "<A href='byond://?_src_=holder;jobban2=[mob_uid];dbbanaddckey=[M.ckey]'>Jobban</A> | "
body += "<A href='byond://?_src_=holder;shownoteckey=[M.ckey]'>Notes</A> | "
if(GLOB.configuration.url.forum_playerinfo_url)
body += "<A href='byond://?_src_=holder;webtools=[M.ckey]'>WebInfo</A> | "
if(M.client)
if(M.client.watchlisted)
body += "<A href='byond://?_src_=holder;watchremove=[M.ckey]'>Remove from Watchlist</A> | "
body += "<A href='byond://?_src_=holder;watchedit=[M.ckey]'>Edit Watchlist Reason</A> "
else
body += "<A href='byond://?_src_=holder;watchadd=[M.ckey]'>Add to Watchlist</A> "
body += "| <A href='byond://?_src_=holder;sendtoprison=[mob_uid]'>Prison</A> | "
body += "\ <A href='byond://?_src_=holder;sendbacktolobby=[mob_uid]'>Send back to Lobby</A> | "
body += "\ <A href='byond://?_src_=holder;eraseflavortext=[mob_uid]'>Erase Flavor Text</A> | "
body += "\ <A href='byond://?_src_=holder;userandomname=[mob_uid]'>Use Random Name</A> | "
body += {"<br><b>Mute: </b>
\[<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_IC]'><font color='[check_mute(M.client.ckey, MUTE_IC) ? "red" : "#6685f5"]'>IC</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_OOC]'><font color='[check_mute(M.client.ckey, MUTE_OOC) ? "red" : "#6685f5"]'>OOC</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_PRAY]'><font color='[check_mute(M.client.ckey, MUTE_PRAY) ? "red" : "#6685f5"]'>PRAY</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_ADMINHELP]'><font color='[check_mute(M.client.ckey, MUTE_ADMINHELP) ? "red" : "#6685f5"]'>ADMINHELP</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_DEADCHAT]'><font color='[check_mute(M.client.ckey, MUTE_DEADCHAT) ?" red" : "#6685f5"]'>DEADCHAT</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_EMOTE]'><font color='[check_mute(M.client.ckey, MUTE_EMOTE) ?" red" : "#6685f5"]'>EMOTE</font></a>]
(<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_ALL]'><font color='[check_mute(M.client.ckey, MUTE_ALL) ? "red" : "#6685f5"]'>toggle all</font></a>)
"}
var/jumptoeye = ""
if(is_ai(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
jumptoeye = " <b>(<A href='byond://?_src_=holder;jumpto=[A.eyeobj.UID()]'>Eye</A>)</b>"
body += {"<br><br>
<A href='byond://?_src_=holder;jumpto=[mob_uid]'><b>Jump to</b></A>[jumptoeye] |
<A href='byond://?_src_=holder;getmob=[mob_uid]'>Get</A> |
<A href='byond://?_src_=holder;sendmob=[mob_uid]'>Send To</A>
<br><br>
[check_rights(R_ADMIN,0) ? "[ADMIN_TP(M,"Traitor panel")] | " : "" ]
<A href='byond://?_src_=holder;narrateto=[mob_uid]'>Narrate to</A> |
[ADMIN_SM(M,"Subtle message")]
"}
if(check_rights(R_EVENT, 0))
body += {" | <A href='byond://?_src_=holder;Bless=[mob_uid]'>Bless</A> | <A href='byond://?_src_=holder;Smite=[mob_uid]'>Smite</A>"}
if(isLivingSSD(M))
if(istype(M.loc, /obj/machinery/cryopod))
body += {" | <A href='byond://?_src_=holder;cryossd=[mob_uid]'>De-Spawn</A> "}
else
body += {" | <A href='byond://?_src_=holder;cryossd=[mob_uid]'>Cryo</A> "}
if(M.client)
if(!isnewplayer(M))
body += "<br><br>"
body += "<b>Transformation:</b>"
body += "<br>"
//Monkey
if(issmall(M))
body += "<B>Monkeyized</B> | "
else
body += "<A href='byond://?_src_=holder;monkeyone=[mob_uid]'>Monkeyize</A> | "
//Corgi
if(iscorgi(M))
body += "<B>Corgized</B> | "
else
body += "<A href='byond://?_src_=holder;corgione=[mob_uid]'>Corgize</A> | "
//AI / Cyborg
if(is_ai(M))
body += "<B>Is an AI</B> "
else if(ishuman(M))
body += {"<A href='byond://?_src_=holder;makeai=[mob_uid]'>Make AI</A> |
<A href='byond://?_src_=holder;makerobot=[mob_uid]'>Make Robot</A> |
<A href='byond://?_src_=holder;makealien=[mob_uid]'>Make Alien</A> |
<A href='byond://?_src_=holder;makeslime=[mob_uid]'>Make Slime</A> |
<A href='byond://?_src_=holder;makesuper=[mob_uid]'>Make Superhero</A> |
"}
//Simple Animals
if(isanimal_or_basicmob(M))
body += "<A href='byond://?_src_=holder;makeanimal=[mob_uid]'>Re-Animalize</A> | "
else
body += "<A href='byond://?_src_=holder;makeanimal=[mob_uid]'>Animalize</A> | "
if(isobserver(M))
body += "<A href='byond://?_src_=holder;incarn_ghost=[mob_uid]'>Re-incarnate</a> | "
if(ispAI(M))
body += "<B>Is a pAI</B> "
else
body += "<A href='byond://?_src_=holder;makePAI=[mob_uid]'>Make pAI</A> | "
// DNA2 - Admin Hax
if(M.dna && iscarbon(M))
body += "<br><br>"
body += "<b>DNA Blocks:</b><br><table border='0'><tr><th>&nbsp;</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th>"
var/bname
for(var/block in 1 to DNA_SE_LENGTH)
if(((block-1)%5)==0)
body += "</tr><tr><th>[block-1]</th>"
bname = GLOB.assigned_blocks[block]
body += "<td>"
if(bname)
var/bstate=M.dna.GetSEState(block)
var/bcolor="[(bstate)?"#006600":"#ff0000"]"
body += "<A href='byond://?_src_=holder;togmutate=[mob_uid];block=[block]' style='color:[bcolor];'>[bname]</A><sub>[block]</sub>"
else
body += "[block]"
body+="</td>"
body += "</tr></table>"
body += {"<br><br>
<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>
<A href='byond://?_src_=holder;simplemake=observer;mob=[mob_uid]'>Observer</A> |
\[ Alien: <A href='byond://?_src_=holder;simplemake=drone;mob=[mob_uid]'>Drone</A>,
<A href='byond://?_src_=holder;simplemake=hunter;mob=[mob_uid]'>Hunter</A>,
<A href='byond://?_src_=holder;simplemake=queen;mob=[mob_uid]'>Queen</A>,
<A href='byond://?_src_=holder;simplemake=sentinel;mob=[mob_uid]'>Sentinel</A>,
<A href='byond://?_src_=holder;simplemake=larva;mob=[mob_uid]'>Larva</A> \]
<A href='byond://?_src_=holder;simplemake=human;mob=[mob_uid]'>Human</A>
\[ slime: <A href='byond://?_src_=holder;simplemake=slime;mob=[mob_uid]'>Baby</A>,
<A href='byond://?_src_=holder;simplemake=adultslime;mob=[mob_uid]'>Adult</A> \]
<A href='byond://?_src_=holder;simplemake=monkey;mob=[mob_uid]'>Monkey</A> |
<A href='byond://?_src_=holder;simplemake=robot;mob=[mob_uid]'>Cyborg</A> |
<A href='byond://?_src_=holder;simplemake=cat;mob=[mob_uid]'>Cat</A> |
<A href='byond://?_src_=holder;simplemake=runtime;mob=[mob_uid]'>Runtime</A> |
<A href='byond://?_src_=holder;simplemake=corgi;mob=[mob_uid]'>Corgi</A> |
<A href='byond://?_src_=holder;simplemake=ian;mob=[mob_uid]'>Ian</A> |
<A href='byond://?_src_=holder;simplemake=crab;mob=[mob_uid]'>Crab</A> |
<A href='byond://?_src_=holder;simplemake=coffee;mob=[mob_uid]'>Coffee</A> |
\[ Construct: <A href='byond://?_src_=holder;simplemake=constructarmoured;mob=[mob_uid]'>Armoured</A> ,
<A href='byond://?_src_=holder;simplemake=constructbuilder;mob=[mob_uid]'>Builder</A> ,
<A href='byond://?_src_=holder;simplemake=constructwraith;mob=[mob_uid]'>Wraith</A> \]
<A href='byond://?_src_=holder;simplemake=shade;mob=[mob_uid]'>Shade</A>
"}
if(M.client)
body += {"<br><br>
<b>Other actions:</b>
<br>
<A href='byond://?_src_=holder;forcespeech=[mob_uid]'>Forcesay</A> |
<A href='byond://?_src_=holder;aroomwarp=[mob_uid]'>Admin Room</A> |
<A href='byond://?_src_=holder;tdome1=[mob_uid]'>Thunderdome 1</A> |
<A href='byond://?_src_=holder;tdome2=[mob_uid]'>Thunderdome 2</A> |
<A href='byond://?_src_=holder;tdomeadmin=[mob_uid]'>Thunderdome Admin</A> |
<A href='byond://?_src_=holder;tdomeobserve=[mob_uid]'>Thunderdome Observer</A> |
<A href='byond://?_src_=holder;contractor_stop=[mob_uid]'>Stop Syndicate Jail Timer</A> |
<A href='byond://?_src_=holder;contractor_start=[mob_uid]'>Start Syndicate Jail Timer</A> |
<A href='byond://?_src_=holder;contractor_release=[mob_uid]'>Release now from Syndicate Jail</A> |
"}
body += {"<br>
</body></html>
"}
client << browse(body, "window=adminplayeropts;size=550x615")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
#define PLAYER_NOTES_ENTRIES_PER_PAGE 50
USER_VERB(player_notes, R_ADMIN|R_MOD, "Player Notes", "Open Player Notes panel.", VERB_CATEGORY_ADMIN)
show_note()
USER_VERB(player_notes_target, R_ADMIN|R_MOD, "Show Player Notes", "Show Player Notes panel for a given ckey.", VERB_CATEGORY_ADMIN, key as text)
show_note(key)
USER_VERB(vpn_whitelist, R_BAN, "VPN Ckey Whitelist", "Modify ckey's presence on VPN whitelist", VERB_CATEGORY_ADMIN)
var/key = stripped_input(client, "Enter ckey to add/remove, or leave blank to cancel:", "VPN Whitelist add/remove", max_length=32)
if(key)
GLOB.ipintel_manager.vpn_whitelist_panel(key)
/datum/admins/proc/Game()
if(!check_rights(R_ADMIN))
return
@@ -325,217 +97,6 @@ USER_VERB(vpn_whitelist, R_BAN, "VPN Ckey Whitelist", "Modify ckey's presence on
onclose(usr, "game_panel")
return
/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
//i.e. buttons/verbs
USER_VERB(restart_server, R_SERVER, "Restart", "Restarts the world.", VERB_CATEGORY_SERVER)
// Give an extra popup if they are rebooting a live server
var/is_live_server = TRUE
if(client.is_connecting_from_localhost())
is_live_server = FALSE
var/list/options = list("Regular Restart", "Hard Restart")
if(world.TgsAvailable()) // TGS lets you kill the process entirely
options += "Terminate Process (Kill and restart DD)"
var/result = input(client, "Select reboot method", "World Reboot", options[1]) as null|anything in options
if(result && is_live_server)
if(alert(client, "WARNING: THIS IS A LIVE SERVER, NOT A LOCAL TEST SERVER. DO YOU STILL WANT TO RESTART","This server is live","Restart","Cancel") != "Restart")
return FALSE
if(result)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/init_by = "Initiated by [client.holder.fakekey ? "Admin" : client.key]."
switch(result)
if("Regular Restart")
var/delay = input(client, "What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null
if(!delay)
return FALSE
// These are pasted each time so that they dont false send if reboot is cancelled
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
SSticker.delay_end = FALSE // We arent delayed anymore
SSticker.reboot_helper(init_by, "admin reboot - by [client.key] [client.holder.fakekey ? "(stealth)" : ""]", delay * 10)
if("Hard Restart")
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
world.Reboot(fast_track = TRUE)
if("Terminate Process (Kill and restart DD)")
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
world.TgsEndProcess() // Just nuke the entire process if we are royally fucked
USER_VERB(end_round, R_SERVER, "End Round", \
"Instantly ends the round and brings up the scoreboard, in the same way that wizards dying do.", \
VERB_CATEGORY_SERVER)
var/input = sanitize(copytext_char(input(client, "What text should players see announcing the round end? Input nothing to cancel.", "Specify Announcement Text", "Shift Has Ended!"), 1, MAX_MESSAGE_LEN))
if(!input)
return
if(SSticker.force_ending)
return
message_admins("[key_name_admin(client)] has admin ended the round with message: '[input]'")
log_admin("[key_name(client)] has admin ended the round with message: '[input]'")
SSticker.force_ending = TRUE
SSticker.record_biohazard_results()
to_chat(world, SPAN_WARNING("<big><b>[input]</b></big>"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
SSticker.mode_result = "admin ended"
USER_VERB(announce, R_ADMIN, "Announce", "Announce your desires to the world", VERB_CATEGORY_ADMIN)
var/message = input(client, "Global message to send:", "Admin Announce", null) as message|null
if(message)
if(!check_rights_client(R_SERVER, 0, client))
message = adminscrub(message,500)
message = replacetext(message, "\n", "<br>") // required since we're putting it in a <p> tag
to_chat(world, chat_box_notice(SPAN_NOTICE("<b>[client.holder.fakekey ? "Administrator" : client.key] Announces:</b><br><br><p>[message]</p>")))
log_admin("Announce: [key_name(client)] : [message]")
for(var/client/clients_to_alert in GLOB.clients)
window_flash(clients_to_alert)
if(clients_to_alert.prefs?.sound & SOUND_ADMINHELP)
SEND_SOUND(clients_to_alert, sound('sound/misc/server_alert.ogg'))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ooc, R_ADMIN, "Toggle OOC", "Globally Toggles OOC", VERB_CATEGORY_SERVER)
toggle_ooc()
log_and_message_admins("toggled OOC.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_looc, R_ADMIN, "Toggle LOOC", "Globally Toggles LOOC", VERB_CATEGORY_SERVER)
GLOB.looc_enabled = !(GLOB.looc_enabled)
if(GLOB.looc_enabled)
to_chat(world, "<B>The LOOC channel has been globally enabled!</B>")
else
to_chat(world, "<B>The LOOC channel has been globally disabled!</B>")
log_and_message_admins("toggled LOOC.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle LOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_dsay, R_ADMIN, "Toggle DSAY", "Globally Toggles DSAY", VERB_CATEGORY_SERVER)
GLOB.dsay_enabled = !(GLOB.dsay_enabled)
if(GLOB.dsay_enabled)
to_chat(world, "<b>Deadchat has been globally enabled!</b>", MESSAGE_TYPE_DEADCHAT)
else
to_chat(world, "<b>Deadchat has been globally disabled!</b>", MESSAGE_TYPE_DEADCHAT)
log_admin("[key_name(client)] toggled deadchat.")
message_admins("[key_name_admin(client)] toggled deadchat.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deadchat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ooc_dead, R_ADMIN, "Toggle Dead OOC", "Toggle Dead OOC.", VERB_CATEGORY_SERVER)
GLOB.dooc_enabled = !(GLOB.dooc_enabled)
log_admin("[key_name(client)] toggled Dead OOC.")
message_admins("[key_name_admin(client)] toggled Dead OOC.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Dead OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_emoji, R_ADMIN, "Toggle OOC Emoji", "Toggle OOC Emoji", VERB_CATEGORY_SERVER)
GLOB.configuration.general.enable_ooc_emoji = !(GLOB.configuration.general.enable_ooc_emoji)
log_admin("[key_name(client)] toggled OOC Emoji.")
message_admins("[key_name_admin(client)] toggled OOC Emoji.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC Emoji")
USER_VERB(start_server_now, R_SERVER, "Start Now", "Start the round RIGHT NOW", VERB_CATEGORY_SERVER)
if(SSticker.current_state < GAME_STATE_STARTUP)
alert(client, "Unable to start the game as it is not set up.")
return
if(!SSticker.ticker_going)
alert(client, "Remove the round-start delay first.")
return
if(GLOB.configuration.general.start_now_confirmation)
if(alert(client, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes")
return
if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP)
SSticker.force_start = TRUE
log_admin("[client.key] has started the game.")
var/msg = ""
if(SSticker.current_state == GAME_STATE_STARTUP)
msg = " (The server is still setting up, but the round will be started as soon as possible.)"
message_admins(SPAN_DARKMBLUE("[client.key] has started the game.[msg]"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Start Game") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return 1
else
to_chat(client, "<font color='red'>Error: Start Now: Game has already started.</font>")
return
USER_VERB(toggle_enter, R_SERVER, "Toggle Entering", "People can't enter", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.enter_allowed = !GLOB.enter_allowed
if(!GLOB.enter_allowed)
to_chat(world, "<B>New players may no longer enter the game.</B>")
else
to_chat(world, "<B>New players may now enter the game.</B>")
log_admin("[key_name(client)] toggled new player game entering.")
message_admins("[key_name_admin(client)] toggled new player game entering.", 1)
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Entering") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ai_role, R_EVENT, "Toggle AI", "People can't be AI", VERB_CATEGORY_EVENT)
GLOB.configuration.jobs.allow_ai = !(GLOB.configuration.jobs.allow_ai)
if(!GLOB.configuration.jobs.allow_ai)
to_chat(world, "<B>The AI job is no longer chooseable.</B>")
else
to_chat(world, "<B>The AI job is chooseable now.</B>")
message_admins("[key_name_admin(client)] toggled AI allowed.")
log_admin("[key_name(client)] toggled AI allowed.")
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle AI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_respawn, R_SERVER, "Toggle Respawn", "Toggle the ability for players to respawn.", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.configuration.general.respawn_enabled = !(GLOB.configuration.general.respawn_enabled)
if(GLOB.configuration.general.respawn_enabled)
to_chat(world, "<B>You may now respawn.</B>")
else
to_chat(world, "<B>You may no longer respawn</B>")
message_admins("[key_name_admin(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].", 1)
log_admin("[key_name(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].")
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Respawn") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(delay_game, R_SERVER, "Delay", "Delay the game start/end", VERB_CATEGORY_SERVER)
if(SSticker.current_state < GAME_STATE_STARTUP)
alert(client, "Slow down a moment, let the ticker start first!")
return
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
if(SSblackbox)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(SSticker.current_state > GAME_STATE_PREGAME)
SSticker.delay_end = !SSticker.delay_end
log_admin("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
message_admins("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1)
if(SSticker.delay_end)
SSticker.real_reboot_time = 0 // Immediately show the "Admin delayed round end" message
return //alert("Round end delayed", null, null, null, null, null)
if(SSticker.ticker_going)
SSticker.ticker_going = FALSE
SSticker.delay_end = TRUE
to_chat(world, "<b>The game start has been delayed.</b>")
log_admin("[key_name(client)] delayed the game.")
else
SSticker.ticker_going = TRUE
SSticker.round_start_time = world.time + SSticker.pregame_timeleft
to_chat(world, "<b>The game will start soon.</b>")
log_admin("[key_name(client)] removed the delay.")
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
/**
@@ -617,77 +178,6 @@ USER_VERB(delay_game, R_SERVER, "Delay", "Delay the game start/end", VERB_CATEGO
return ""
USER_VERB(spawn_atom, R_SPAWN, "Spawn", \
"Spawn an atom. Append a period to the text in order to exclude subtypes of paths matching the input.", \
VERB_CATEGORY_DEBUG, object as text)
if(!object)
return
var/list/types = typesof(/atom)
var/list/matches = list()
var/include_subtypes = TRUE
if(copytext(object, -1) == ".")
include_subtypes = FALSE
object = copytext(object, 1, -1)
if(include_subtypes)
for(var/path in types)
if(findtext("[path]", object))
matches += path
else
var/needle_length = length(object)
for(var/path in types)
if(copytext("[path]", -needle_length) == object)
matches += path
if(length(matches)==0)
return
var/chosen
if(length(matches)==1)
chosen = matches[1]
else
chosen = tgui_input_list(client, "Select an Atom Type", "Spawn Atom", matches)
if(!chosen)
return
if(ispath(chosen,/turf))
var/turf/T = get_turf(client.mob.loc)
T.ChangeTurf(chosen)
else
var/atom/A = new chosen(client.mob.loc)
A.admin_spawned = TRUE
log_admin("[key_name(client)] spawned [chosen] at ([client.mob.x],[client.mob.y],[client.mob.z])")
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!
USER_VERB_VISIBILITY(show_traitor_panel, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(show_traitor_panel, R_ADMIN|R_MOD, "Show Traitor Panel", "Edit mob's memory and role", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list)
if(!istype(M))
to_chat(client, "This can only be used on instances of type /mob")
return
if(!M.mind)
to_chat(client, "This mob has no mind!")
return
M.mind.edit_memory()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_guests, R_SERVER, "Toggle Guests", "Guests can't enter", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.configuration.general.guest_ban = !(GLOB.configuration.general.guest_ban)
if(GLOB.configuration.general.guest_ban)
to_chat(world, "<B>Guests may no longer enter the game.</B>")
else
to_chat(world, "<B>Guests may now enter the game.</B>")
log_admin("[key_name(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed."), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Guests") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws()
var/ai_number = 0
var/list/messages = list()
-3
View File
@@ -1,8 +1,5 @@
GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
USER_VERB(outfit_manager, R_EVENT, "Outfit Manager", "Opens the outfit manager.", VERB_CATEGORY_EVENT)
client.holder.outfit_manager(client.mob)
/datum/admins/proc/outfit_manager(mob/admin)
var/list/dat = list("<!DOCTYPE html><ul>")
for(var/datum/outfit/O in GLOB.custom_outfits)
+197
View File
@@ -0,0 +1,197 @@
USER_VERB(toggle_enter, R_SERVER, "Toggle Entering", "People can't enter", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.enter_allowed = !GLOB.enter_allowed
if(!GLOB.enter_allowed)
to_chat(world, "<B>New players may no longer enter the game.</B>")
else
to_chat(world, "<B>New players may now enter the game.</B>")
log_admin("[key_name(client)] toggled new player game entering.")
message_admins("[key_name_admin(client)] toggled new player game entering.", 1)
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Entering") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_respawn, R_SERVER, "Toggle Respawn", "Toggle the ability for players to respawn.", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.configuration.general.respawn_enabled = !(GLOB.configuration.general.respawn_enabled)
if(GLOB.configuration.general.respawn_enabled)
to_chat(world, "<B>You may now respawn.</B>")
else
to_chat(world, "<B>You may no longer respawn</B>")
message_admins("[key_name_admin(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].", 1)
log_admin("[key_name(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].")
world.update_status()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Respawn") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(delay_game, R_SERVER, "Delay", "Delay the game start/end", VERB_CATEGORY_SERVER)
if(SSticker.current_state < GAME_STATE_STARTUP)
alert(client, "Slow down a moment, let the ticker start first!")
return
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
if(SSblackbox)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(SSticker.current_state > GAME_STATE_PREGAME)
SSticker.delay_end = !SSticker.delay_end
log_admin("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
message_admins("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1)
if(SSticker.delay_end)
SSticker.real_reboot_time = 0 // Immediately show the "Admin delayed round end" message
return //alert("Round end delayed", null, null, null, null, null)
if(SSticker.ticker_going)
SSticker.ticker_going = FALSE
SSticker.delay_end = TRUE
to_chat(world, "<b>The game start has been delayed.</b>")
log_admin("[key_name(client)] delayed the game.")
else
SSticker.ticker_going = TRUE
SSticker.round_start_time = world.time + SSticker.pregame_timeleft
to_chat(world, "<b>The game will start soon.</b>")
log_admin("[key_name(client)] removed the delay.")
USER_VERB(end_round, R_SERVER, "End Round", \
"Instantly ends the round and brings up the scoreboard, in the same way that wizards dying do.", \
VERB_CATEGORY_SERVER)
var/input = sanitize(copytext_char(input(client, "What text should players see announcing the round end? Input nothing to cancel.", "Specify Announcement Text", "Shift Has Ended!"), 1, MAX_MESSAGE_LEN))
if(!input)
return
if(SSticker.force_ending)
return
message_admins("[key_name_admin(client)] has admin ended the round with message: '[input]'")
log_admin("[key_name(client)] has admin ended the round with message: '[input]'")
SSticker.force_ending = TRUE
SSticker.record_biohazard_results()
to_chat(world, SPAN_WARNING("<big><b>[input]</b></big>"))
SSblackbox.record_feedback("tally", "admin_verb", 1, "End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
SSticker.mode_result = "admin ended"
USER_VERB(restart_server, R_SERVER, "Restart", "Restarts the world.", VERB_CATEGORY_SERVER)
// Give an extra popup if they are rebooting a live server
var/is_live_server = TRUE
if(client.is_connecting_from_localhost())
is_live_server = FALSE
var/list/options = list("Regular Restart", "Hard Restart")
if(world.TgsAvailable()) // TGS lets you kill the process entirely
options += "Terminate Process (Kill and restart DD)"
var/result = input(client, "Select reboot method", "World Reboot", options[1]) as null|anything in options
if(result && is_live_server)
if(alert(client, "WARNING: THIS IS A LIVE SERVER, NOT A LOCAL TEST SERVER. DO YOU STILL WANT TO RESTART","This server is live","Restart","Cancel") != "Restart")
return FALSE
if(result)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/init_by = "Initiated by [client.holder.fakekey ? "Admin" : client.key]."
switch(result)
if("Regular Restart")
var/delay = input(client, "What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null
if(!delay)
return FALSE
// These are pasted each time so that they dont false send if reboot is cancelled
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
SSticker.delay_end = FALSE // We arent delayed anymore
SSticker.reboot_helper(init_by, "admin reboot - by [client.key] [client.holder.fakekey ? "(stealth)" : ""]", delay * 10)
if("Hard Restart")
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
world.Reboot(fast_track = TRUE)
if("Terminate Process (Kill and restart DD)")
message_admins("[key_name_admin(client)] has initiated a server restart of type [result]")
log_admin("[key_name(client)] has initiated a server restart of type [result]")
world.TgsEndProcess() // Just nuke the entire process if we are royally fucked
USER_VERB(toggle_log_hrefs, R_SERVER, "Toggle href logging", "Toggle href logging", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
// Why would we ever turn this off?
if(GLOB.configuration.logging.href_logging)
GLOB.configuration.logging.href_logging = FALSE
to_chat(client, "<b>Stopped logging hrefs</b>")
else
GLOB.configuration.logging.href_logging = TRUE
to_chat(client, "<b>Started logging hrefs</b>")
USER_VERB(toggle_antaghug_restrictions, R_SERVER, "Toggle antagHUD Restrictions", \
"Restricts players that have used antagHUD from being able to join this round.", \
VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
var/action=""
if(GLOB.configuration.general.restrict_antag_hud_rejoin)
for(var/mob/dead/observer/g in client.get_ghosts())
to_chat(g, SPAN_BOLDNOTICE("The administrator has lifted restrictions on joining the round if you use AntagHUD"))
action = "lifted restrictions"
GLOB.configuration.general.restrict_antag_hud_rejoin = FALSE
to_chat(client, SPAN_BOLDNOTICE("AntagHUD restrictions have been lifted"))
else
for(var/mob/dead/observer/g in client.get_ghosts())
to_chat(g, SPAN_DANGER("The administrator has placed restrictions on joining the round if you use AntagHUD"))
to_chat(g, SPAN_DANGER("Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions."))
g.antagHUD = FALSE
GLOB.antag_hud_users -= g.ckey
action = "placed restrictions"
GLOB.configuration.general.restrict_antag_hud_rejoin = TRUE
to_chat(client, SPAN_DANGER("AntagHUD restrictions have been enabled"))
log_admin("[key_name(client)] has [action] on joining the round if they use AntagHUD")
message_admins("Admin [key_name_admin(client)] has [action] on joining the round if they use AntagHUD", 1)
USER_VERB(toggle_antaghud_use, R_SERVER, "Toggle antagHUD usage", "Toggles antagHUD usage for observers", VERB_CATEGORY_SERVER)
var/action=""
if(GLOB.configuration.general.allow_antag_hud)
GLOB.antag_hud_users.Cut()
for(var/mob/dead/observer/g in client.get_ghosts())
if(g.antagHUD)
g.antagHUD = FALSE // Disable it on those that have it enabled
to_chat(g, SPAN_DANGER("The Administrators have disabled AntagHUD."))
GLOB.configuration.general.allow_antag_hud = FALSE
to_chat(client, SPAN_DANGER("AntagHUD usage has been disabled"))
action = "disabled"
else
for(var/mob/dead/observer/g in client.get_ghosts())
if(!g.client.holder) // Add the verb back for all non-admin ghosts
to_chat(g, SPAN_BOLDNOTICE("The Administrators have enabled AntagHUD."))// Notify all observers they can now use AntagHUD
GLOB.configuration.general.allow_antag_hud = TRUE
action = "enabled"
to_chat(client, SPAN_BOLDNOTICE("AntagHUD usage has been enabled"))
log_admin("[key_name(client)] has [action] antagHUD usage for observers")
message_admins("Admin [key_name_admin(client)] has [action] antagHUD usage for observers", 1)
USER_VERB(toggle_guests, R_SERVER, "Toggle Guests", "Guests can't enter", VERB_CATEGORY_SERVER)
if(!client.is_connecting_from_localhost())
if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes")
return
GLOB.configuration.general.guest_ban = !(GLOB.configuration.general.guest_ban)
if(GLOB.configuration.general.guest_ban)
to_chat(world, "<B>Guests may no longer enter the game.</B>")
else
to_chat(world, "<B>Guests may now enter the game.</B>")
log_admin("[key_name(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed."), 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Guests") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+347
View File
@@ -0,0 +1,347 @@
USER_VERB(create_crate, R_SPAWN, "Create Crate", \
"Spawn a crate from a supplypack datum. Append a period to the text in order to exclude subtypes of paths matching the input.", \
VERB_CATEGORY_EVENT,
object as text)
var/list/types = SSeconomy.supply_packs
var/list/matches = list()
var/include_subtypes = TRUE
if(copytext(object, -1) == ".")
include_subtypes = FALSE
object = copytext(object, 1, -1)
if(include_subtypes)
for(var/path in types)
if(findtext("[path]", object))
matches += path
else
var/needle_length = length(object)
for(var/path in types)
if(copytext("[path]", -needle_length) == object)
matches += path
if(!length(matches))
return
var/chosen = input(client, "Select a supply crate type", "Create Crate", matches[1]) as null|anything in matches
if(!chosen)
return
var/datum/supply_packs/the_pack = new chosen()
var/spawn_location = get_turf(client.mob)
if(!spawn_location)
return
var/obj/structure/closet/crate/crate = the_pack.create_package(spawn_location)
crate.admin_spawned = TRUE
for(var/atom/A in crate.contents)
A.admin_spawned = TRUE
qdel(the_pack)
log_admin("[key_name(client)] created a '[chosen]' crate at ([COORD(client.mob)])")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Crate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/// If a guy was gibbed and you want to revive him, this is a good way to do so.
/// Works kind of like entering the game with a new character. Character
/// receives a new mind if they didn't have one. Traitors and the like can also
/// be revived with the previous role mostly intact.
USER_VERB(respawn_character, R_SPAWN, "Respawn Character", \
"Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into.", \
VERB_CATEGORY_EVENT)
var/input = ckey(input(client, "Please specify which key will be respawned.", "Key", ""))
if(!input)
return
var/mob/dead/observer/G_found
for(var/mob/dead/observer/G in GLOB.player_list)
if(G.ckey == input)
G_found = G
break
if(!G_found)//If a ghost was not found.
to_chat(client, "<font color='red'>There is no active key like that in the game or the person is not currently a ghost.</font>")
return
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
//Check if they were an alien
if(G_found.mind.assigned_role=="Alien")
if(alert(client, "This character appears to have been an alien. Would you like to respawn them as such?", null,"Yes","No")=="Yes")
var/turf/T
if(length(GLOB.xeno_spawn)) T = pick(GLOB.xeno_spawn)
else T = pick(GLOB.latejoin)
var/mob/living/carbon/alien/new_xeno
switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen(T)
else//If we don't know what special role they have, for whatever reason, or they're a larva.
create_xeno(G_found.ckey)
return
//Now to give them their mind back.
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_xeno.key = G_found.key
to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] has respawned [new_xeno.key] as a filthy xeno."), 1)
return //all done. The ghost is auto-deleted
var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned.
var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
/*Try and locate a record for the person being respawned through data_core.
This isn't an exact science but it does the trick more often than not.*/
var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
for(var/datum/data/record/t in GLOB.data_core.locked)
if(t.fields["id"]==id)
record_found = t//We shall now reference the record.
break
if(record_found)//If they have a record we can determine a few things.
new_character.real_name = record_found.fields["name"]
new_character.change_gender(record_found.fields["sex"])
new_character.age = record_found.fields["age"]
new_character.dna.blood_type = record_found.fields["blood_type"]
else
// We make a random character
new_character.change_gender(pick(MALE,FEMALE))
var/datum/character_save/S = new
S.randomise()
S.real_name = G_found.real_name
S.copy_to(new_character)
if(!new_character.real_name)
new_character.real_name = random_name(new_character.gender)
new_character.name = new_character.real_name
if(G_found.mind && !G_found.mind.active)
G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_character.mind.special_verbs = list()
else
new_character.mind_initialize()
if(!new_character.mind.assigned_role) new_character.mind.assigned_role = "Assistant" //If they somehow got a null assigned role.
//DNA
if(record_found)//Pull up their name from database records if they did have a mind.
new_character.dna = new()//Let's first give them a new DNA.
new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity.
// I HATE BYOND. HATE. HATE. - N3X
var/list/newSE= record_found.fields["enzymes"]
var/list/newUI = record_found.fields["identity"]
new_character.dna.SE = newSE.Copy() //This is the default of enzymes so I think it's safe to go with.
new_character.dna.UpdateSE()
new_character.UpdateAppearance(newUI.Copy())//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch.
else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile.
new_character.dna.ready_dna(new_character)
new_character.key = G_found.key
/*
The code below functions with the assumption that the mob is already a traitor if they have a special role.
So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
If they don't have a mind, they obviously don't have a special role.
*/
//Now for special roles and equipment.
switch(new_character.mind.special_role)
if("traitor")
if(new_character.mind.has_antag_datum(/datum/antagonist/traitor))
var/datum/antagonist/traitor/T = new_character.mind.has_antag_datum(/datum/antagonist/traitor)
T.give_uplink()
else
new_character.mind.add_antag_datum(/datum/antagonist/traitor)
if("Wizard")
new_character.forceMove(pick(GLOB.wizardstart))
//ticker.mode.learn_basic_spells(new_character)
var/datum/antagonist/wizard/wizard = new_character.mind.has_antag_datum(/datum/antagonist/wizard)
if(istype(wizard))
wizard.equip_wizard()
if("Syndicate")
var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
if(synd_spawn)
new_character.loc = get_turf(synd_spawn)
call(TYPE_PROC_REF(/datum/game_mode, equip_syndicate))(new_character)
if("Deathsquad Commando")//Leaves them at late-join spawn.
new_character.equip_deathsquad_commando()
new_character.update_action_buttons_icon()
else//They may also be a cyborg or AI.
switch(new_character.mind.assigned_role)
if("Cyborg")//More rigging to make em' work and check if they're traitor.
new_character = new_character.Robotize()
if(new_character.mind.special_role=="traitor")
new_character.mind.add_antag_datum(/datum/antagonist/traitor)
if("AI")
new_character = new_character.AIize()
var/mob/living/silicon/ai/ai_character = new_character
ai_character.moveToAILandmark()
if(new_character.mind.special_role=="traitor")
new_character.mind.add_antag_datum(/datum/antagonist/traitor)
//Add aliens.
else
SSjobs.AssignRank(new_character, new_character.mind.assigned_role, FALSE)
SSjobs.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
//Announces the character on all the systems, based on the record.
if(!issilicon(new_character))//If they are not a cyborg/AI.
if(!record_found && new_character.mind.assigned_role != new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. Offstation special characters announced anyway.
//Power to the user!
if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?", null,"No","Yes")=="Yes")
GLOB.data_core.manifest_inject(new_character)
if(alert(new_character,"Would you like an active AI to announce this character?", null,"No","Yes")=="Yes")
call(TYPE_PROC_REF(/mob/new_player, AnnounceArrival))(new_character, new_character.mind.assigned_role)
message_admins(SPAN_NOTICE("[key_name_admin(client)] has respawned [key_name_admin(G_found)] as [new_character.real_name]."), 1)
to_chat(new_character, "You have been fully respawned. Enjoy the game.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return new_character
USER_VERB(spawn_atom, R_SPAWN, "Spawn", \
"Spawn an atom. Append a period to the text in order to exclude subtypes of paths matching the input.", \
VERB_CATEGORY_DEBUG, object as text)
if(!object)
return
var/list/types = typesof(/atom)
var/list/matches = list()
var/include_subtypes = TRUE
if(copytext(object, -1) == ".")
include_subtypes = FALSE
object = copytext(object, 1, -1)
if(include_subtypes)
for(var/path in types)
if(findtext("[path]", object))
matches += path
else
var/needle_length = length(object)
for(var/path in types)
if(copytext("[path]", -needle_length) == object)
matches += path
if(length(matches)==0)
return
var/chosen
if(length(matches)==1)
chosen = matches[1]
else
chosen = tgui_input_list(client, "Select an Atom Type", "Spawn Atom", matches)
if(!chosen)
return
if(ispath(chosen,/turf))
var/turf/T = get_turf(client.mob.loc)
T.ChangeTurf(chosen)
else
var/atom/A = new chosen(client.mob.loc)
A.admin_spawned = TRUE
log_admin("[key_name(client)] spawned [chosen] at ([client.mob.x],[client.mob.y],[client.mob.z])")
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!
USER_VERB(admin_robotize, R_SPAWN, "Make Robot", "Turn the target into a borg.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has robotized [M.key].")
spawn(10)
M:Robotize()
else
alert(client, "Invalid mob")
USER_VERB(admin_animalize, R_SPAWN, "Make Simple Animal", "Turn the target into a simple animal.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(!M)
alert(client, "That mob doesn't seem to exist, close the panel and try again.")
return
if(isnewplayer(M))
alert(client, "The mob must not be a new_player.")
return
log_admin("[key_name(client)] has animalized [M.key].")
spawn(10)
M.Animalize()
USER_VERB(admin_make_pai, R_SPAWN, "Make pAI", "Specify a location to spawn a pAI device, then specify a key to play that pAI", VERB_CATEGORY_EVENT, turf/T in GLOB.mob_list)
var/list/available = list()
for(var/mob/C in GLOB.mob_list)
if(C.key)
available.Add(C)
var/mob/choice = input(client, "Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
if(!isobserver(choice))
var/confirm = input(client, "[choice.key] isn't ghosting right now. Are you sure you want to yank [choice.p_them()] out of [choice.p_their()] body and place [choice.p_them()] in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
var/obj/item/paicard/card = new(T)
var/mob/living/silicon/pai/pai = new(card)
var/raw_name = clean_input("Enter your pAI name:", "pAI Name", "Personal AI", choice, user = client)
var/new_name = reject_bad_name(raw_name, 1)
if(new_name)
pai.name = new_name
pai.real_name = new_name
else
to_chat(client, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
pai.real_name = pai.name
pai.key = choice.key
card.setPersonality(pai)
for(var/datum/pai_save/candidate in GLOB.paiController.pai_candidates)
if(candidate.owner.ckey == choice.ckey)
GLOB.paiController.pai_candidates.Remove(candidate)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(admin_alienize, R_SPAWN, "Make Alien", "Turn the target mob into an alien.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has alienized [M.key].")
spawn(10)
M:Alienize()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Alien") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] made [key_name(M)] into an alien.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into an alien."), 1)
else
alert(client, "Invalid mob")
USER_VERB(admin_slimezie, R_SPAWN, "Make slime", "Turn the target mob into a slime.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has slimeized [M.key].")
spawn(10)
M:slimeize()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Slime") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] made [key_name(M)] into a slime.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into a slime."), 1)
else
alert(client, "Invalid mob")
USER_VERB(admin_super, R_SPAWN, "Make Superhero", "Turn the target mob into a superhero.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
var/type = input(client, "Pick the Superhero","Superhero") as null|anything in GLOB.all_superheroes
var/datum/superheroes/S = GLOB.all_superheroes[type]
if(S)
S.create(M)
log_admin("[key_name(client)] has turned [M.key] into a Superhero.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into a Superhero."), 1)
else
alert(client, "Invalid mob")
-13
View File
@@ -1,13 +0,0 @@
USER_VERB(aooc, R_ADMIN, "AOOC", "Antagonist OOC", VERB_CATEGORY_OOC, msg as text)
msg = sanitize(msg)
if(!msg) return
var/display_name = client.key
if(client.holder && client.holder.fakekey)
display_name = client.holder.fakekey
for(var/mob/M in GLOB.mob_list)
if((M.mind && M.mind.special_role && M.client) || (M.client && M.client.holder && (M.client.holder.rights & R_ADMIN)))
to_chat(M, "<font color='#960018'>[SPAN_OOC("[SPAN_PREFIX("AOOC:")] <EM>[display_name]:</EM> [SPAN_MESSAGE("[msg]")]")]</font>")
log_aooc(msg, client)
-34
View File
@@ -1,34 +0,0 @@
USER_VERB(change_custom_event, R_EVENT, "Change Custom Event", "Set a custom event.", VERB_CATEGORY_EVENT)
var/input = input(client, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", GLOB.custom_event_msg) as message|null
if(!input || input == "")
GLOB.custom_event_msg = null
log_admin("[key_name(client)] has cleared the custom event text.")
message_admins("[key_name_admin(client)] has cleared the custom event text.")
return
log_admin("[key_name(client)] has changed the custom event text.")
message_admins("[key_name_admin(client)] has changed the custom event text.")
GLOB.custom_event_msg = input
to_chat(world, "<h1 class='alert'>Custom Event</h1>")
to_chat(world, "<h2 class='alert'>A custom event is starting. OOC Info:</h2>")
to_chat(world, SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]"))
to_chat(world, "<br>")
// normal verb for players to view info
/client/verb/cmd_view_custom_event()
set category = "OOC"
set name = "Custom Event Info"
var/list/custom_event_information = list()
if(!GLOB.custom_event_msg || GLOB.custom_event_msg == "")
custom_event_information += "There currently is no known custom event taking place."
custom_event_information += "Keep in mind: it is possible that an admin has not properly set this."
to_chat(src, chat_box_regular(custom_event_information.Join("<br>")))
return
custom_event_information += "<h1 class='alert'>Custom Event</h1>"
custom_event_information += "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>"
custom_event_information += SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]")
to_chat(src, chat_box_regular(custom_event_information.Join("<br>")))
@@ -216,106 +216,6 @@ USER_VERB(air_status, R_DEBUG, "Air Status in Location", "Print out the local ai
usr.show_message(t, 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status (Location)") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(admin_robotize, R_SPAWN, "Make Robot", "Turn the target into a borg.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has robotized [M.key].")
spawn(10)
M:Robotize()
else
alert(client, "Invalid mob")
USER_VERB(admin_animalize, R_SPAWN, "Make Simple Animal", "Turn the target into a simple animal.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(!M)
alert(client, "That mob doesn't seem to exist, close the panel and try again.")
return
if(isnewplayer(M))
alert(client, "The mob must not be a new_player.")
return
log_admin("[key_name(client)] has animalized [M.key].")
spawn(10)
M.Animalize()
USER_VERB(admin_make_pai, R_SPAWN, "Make pAI", "Specify a location to spawn a pAI device, then specify a key to play that pAI", VERB_CATEGORY_EVENT, turf/T in GLOB.mob_list)
var/list/available = list()
for(var/mob/C in GLOB.mob_list)
if(C.key)
available.Add(C)
var/mob/choice = input(client, "Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
if(!isobserver(choice))
var/confirm = input(client, "[choice.key] isn't ghosting right now. Are you sure you want to yank [choice.p_them()] out of [choice.p_their()] body and place [choice.p_them()] in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
var/obj/item/paicard/card = new(T)
var/mob/living/silicon/pai/pai = new(card)
var/raw_name = clean_input("Enter your pAI name:", "pAI Name", "Personal AI", choice, user = client)
var/new_name = reject_bad_name(raw_name, 1)
if(new_name)
pai.name = new_name
pai.real_name = new_name
else
to_chat(client, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
pai.real_name = pai.name
pai.key = choice.key
card.setPersonality(pai)
for(var/datum/pai_save/candidate in GLOB.paiController.pai_candidates)
if(candidate.owner.ckey == choice.ckey)
GLOB.paiController.pai_candidates.Remove(candidate)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make pAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(admin_alienize, R_SPAWN, "Make Alien", "Turn the target mob into an alien.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has alienized [M.key].")
spawn(10)
M:Alienize()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Alien") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] made [key_name(M)] into an alien.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into an alien."), 1)
else
alert(client, "Invalid mob")
USER_VERB(admin_slimezie, R_SPAWN, "Make slime", "Turn the target mob into a slime.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
log_admin("[key_name(client)] has slimeized [M.key].")
spawn(10)
M:slimeize()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Slime") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] made [key_name(M)] into a slime.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into a slime."), 1)
else
alert(client, "Invalid mob")
USER_VERB(admin_super, R_SPAWN, "Make Superhero", "Turn the target mob into a superhero.", VERB_CATEGORY_EVENT, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
var/type = input(client, "Pick the Superhero","Superhero") as null|anything in GLOB.all_superheroes
var/datum/superheroes/S = GLOB.all_superheroes[type]
if(S)
S.create(M)
log_admin("[key_name(client)] has turned [M.key] into a Superhero.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] made [key_name(M)] into a Superhero."), 1)
else
alert(client, "Invalid mob")
USER_VERB(delete_singulo, R_DEBUG, "Del Singulo / Tesla", "Delete all singularities and tesla balls.", VERB_CATEGORY_DEBUG)
//This gets a confirmation check because it's way easier to accidentally hit this and delete things than it is with qdel-all
var/confirm = alert(client, "This will delete ALL Singularities and Tesla orbs except for any that are on away mission z-levels or the centcomm z-level. Are you sure you want to delete them?", "Confirm Panic Button", "Yes", "No")
@@ -337,35 +237,6 @@ USER_VERB(make_powernets, R_DEBUG, "Make Powernets", "Remake all powernets.", VE
message_admins("[key_name_admin(client)] has remade the powernets. makepowernets() called.", 0)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Powernets") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB_VISIBILITY(grant_full_access, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(grant_full_access, R_EVENT, "Grant Full Access", "Gives mob all-access.", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list)
if(SSticker.current_state < GAME_STATE_PLAYING)
alert(client, "Wait until the game starts")
return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.wear_id)
var/obj/item/card/id/id = H.wear_id
if(istype(H.wear_id, /obj/item/pda))
var/obj/item/pda/pda = H.wear_id
id = pda.id
id.icon_state = "gold"
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
else
var/obj/item/card/id/id = new/obj/item/card/id(M)
id.icon_state = "gold"
id:access = get_all_accesses()+get_all_centcom_access()+get_all_syndicate_access()
id.registered_name = H.real_name
id.assignment = "Captain"
id.name = "[id.registered_name]'s ID Card ([id.assignment])"
H.equip_to_slot_or_del(id, ITEM_SLOT_ID)
H.update_inv_wear_id()
else
alert(client, "Invalid mob")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Grant Full Access") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] has granted [M.key] full access.")
message_admins(SPAN_NOTICE("[key_name_admin(client)] has granted [M.key] full access."), 1)
USER_VERB_VISIBILITY(assume_direct_control, VERB_VISIBILITY_FLAG_MOREDEBUG)
USER_VERB(assume_direct_control, R_ADMIN|R_DEBUG, "Assume direct control", "Direct intervention", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list)
if(M.ckey)
@@ -493,37 +364,6 @@ USER_VERB(mapping_area_test, R_DEBUG, "Test areas", "Run mapping area test", VER
for(var/areatype in areas_without_camera)
to_chat(world, "* [areatype]")
USER_CONTEXT_MENU(select_equipment, R_EVENT, "\[Admin\] Select equipment", mob/living/carbon/human/M in GLOB.human_list)
if(!ishuman(M) && !isobserver(M))
alert(client, "Invalid mob")
return
var/dresscode = client.robust_dress_shop()
if(!dresscode)
return
var/delete_pocket
var/mob/living/carbon/human/H
if(isobserver(M))
H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE)
else
H = M
if(H.l_store || H.r_store || H.s_store) //saves a lot of time for admins and coders alike
if(alert(client, "Should the items in their pockets be dropped? Selecting \"No\" will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
delete_pocket = TRUE
for(var/obj/item/I in H.get_equipped_items(delete_pocket))
qdel(I)
if(dresscode != "Naked")
H.equipOutfit(dresscode)
H.regenerate_icons()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(client)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins(SPAN_NOTICE("[key_name_admin(client)] changed the equipment of [key_name_admin(M)] to [dresscode]."), 1)
/client/proc/robust_dress_shop(list/potential_minds)
var/list/special_outfits = list(
"Naked",
@@ -787,3 +627,93 @@ USER_VERB(view_bug_reports, R_DEBUG|R_VIEWRUNTIMES|R_ADMIN, "View Bug Reports",
return
form.ui_interact(client.mob)
USER_VERB(debug_statpanel, R_DEBUG, "Debug Stat Panel", "Toggles local debug of the stat panel", VERB_CATEGORY_DEBUG)
client.stat_panel.send_message("create_debug")
USER_VERB(profile_code, R_DEBUG|R_VIEWRUNTIMES, "Profile Code", "View code profiler", VERB_CATEGORY_DEBUG)
winset(client, null, "command=.profile")
USER_VERB(raw_gas_scan, R_DEBUG|R_VIEWRUNTIMES, "Raw Gas Scan", "Scans your current tile, including LINDA data not normally displayed.", VERB_CATEGORY_DEBUG)
atmos_scan(client.mob, get_turf(client.mob), silent = TRUE, milla_turf_details = TRUE)
USER_VERB(find_interesting_turf, R_DEBUG|R_VIEWRUNTIMES, "Interesting Turf", \
"Teleports you to a random Interesting Turf from MILLA", VERB_CATEGORY_DEBUG)
if(!isobserver(client.mob))
to_chat(client.mob, SPAN_WARNING("You must be an observer to do this!"))
return
var/list/interesting_tile = get_random_interesting_tile()
if(!length(interesting_tile))
to_chat(client, SPAN_NOTICE("There are no interesting turfs. How interesting!"))
return
var/turf/T = interesting_tile[MILLA_INDEX_TURF]
var/mob/dead/observer/O = client.mob
admin_forcemove(O, T)
O.manual_follow(T)
USER_VERB(visualize_interesting_turfs, R_DEBUG|R_VIEWRUNTIMES, "Visualize Interesting Turfs", "Shows all the Interesting Turfs from MILLA", VERB_CATEGORY_DEBUG)
if(SSair.interesting_tile_count > 500)
// This can potentially iterate through a list thats 20k things long. Give ample warning to the user
if(tgui_alert(client, "WARNING: There are [SSair.interesting_tile_count] Interesting Turfs. This process will be lag intensive and should only be used if the atmos controller \
is screaming bloody murder. Are you sure you with to continue", "WARNING", list("I am sure", "Nope")) != "I am sure")
return
else
if(tgui_alert(client, "Visualizing turfs may cause server to lag. Are you sure?", "Warning", list("Yes", "No")) != "Yes")
return
var/display_turfs_overlay = FALSE
if(tgui_alert(client, "Would you like to have all interesting turfs have a client side overlay applied as well?", "Optional", list("Yes", "No")) == "Yes")
display_turfs_overlay = TRUE
message_admins("[key_name_admin(client)] is visualizing interesting atmos turfs. Server may lag.")
var/list/zlevel_turf_indexes = list()
var/list/coords = get_interesting_atmos_tiles()
if(!length(coords))
to_chat(client, SPAN_NOTICE("There are no interesting turfs. How interesting!"))
return
while(length(coords))
var/offset = length(coords) - MILLA_INTERESTING_TILE_SIZE
var/turf/T = coords[offset + MILLA_INDEX_TURF]
coords.len -= MILLA_INTERESTING_TILE_SIZE
// ENSURE YOU USE STRING NUMBERS HERE, THIS IS A DICTIONARY KEY NOT AN INDEX!!!
if(!zlevel_turf_indexes["[T.z]"])
zlevel_turf_indexes["[T.z]"] = list()
zlevel_turf_indexes["[T.z]"] |= T
if(display_turfs_overlay)
client.images += image('icons/effects/alphacolors.dmi', T, "red")
CHECK_TICK
// Sort the keys
zlevel_turf_indexes = sortAssoc(zlevel_turf_indexes)
for(var/key in zlevel_turf_indexes)
to_chat(client, SPAN_NOTICE("Z[key]: <b>[length(zlevel_turf_indexes["[key]"])] Interesting Turfs</b>"))
var/z_to_view = tgui_input_number(client, "A list of z-levels their ITs has appeared in chat. Please enter a Z to visualize. Enter 0 or close the window to cancel", "Selection", 0)
if(!z_to_view)
return
// Do not combine these
var/list/ui_dat = list()
var/list/turf_markers = list()
var/datum/browser/vis = new(client, "atvis", "Interesting Turfs (Z[z_to_view])", 300, 315)
ui_dat += "<center><canvas width=\"255px\" height=\"255px\" id=\"atmos\"></canvas></center>"
ui_dat += "<script>e=document.getElementById(\"atmos\");c=e.getContext('2d');c.fillStyle='#ffffff';c.fillRect(0,0,255,255);function s(x,y){var p=c.createImageData(1,1);p.data\[0]=255;p.data\[1]=0;p.data\[2]=0;p.data\[3]=255;c.putImageData(p,(x-1),255-Math.abs(y-1));}</script>"
// Now generate the other list
for(var/x in zlevel_turf_indexes["[z_to_view]"])
var/turf/T = x
turf_markers += "s([T.x],[T.y]);"
CHECK_TICK
ui_dat += "<script>[turf_markers.Join("")]</script>"
vis.set_content(ui_dat.Join(""))
vis.open(FALSE)
+43
View File
@@ -0,0 +1,43 @@
/// Allow admin to add or remove traits of datum
/datum/admins/proc/modify_traits(datum/D)
if(!D)
return
var/add_or_remove = tgui_input_list(usr, "Add or Remove Trait?", "Modify Trait", list("Add","Remove"))
if(!add_or_remove)
return
var/list/availible_traits = list()
switch(add_or_remove)
if("Add")
for(var/key in GLOB.traits_by_type)
if(istype(D, key))
availible_traits += GLOB.traits_by_type[key]
if("Remove")
if(!GLOB.trait_name_map)
GLOB.trait_name_map = generate_trait_name_map()
for(var/trait in D.status_traits)
var/name = GLOB.trait_name_map[trait] || trait
availible_traits[name] = trait
var/chosen_trait = tgui_input_list(usr, "Select trait to modify.", "Traits", availible_traits)
if(!chosen_trait)
return
chosen_trait = availible_traits[chosen_trait]
var/source = "adminabuse"
switch(add_or_remove)
if("Add") //Not doing source choosing here intentionally to make this bit faster to use, you can always vv it.
ADD_TRAIT(D, chosen_trait, source)
if("Remove")
var/specific = tgui_input_list(usr, "All or from a specific source?", "Add or Remove Trait", list("All","Specific"))
if(!specific)
return
switch(specific)
if("All")
source = null
if("Specific")
source = tgui_input_list(usr, "Source to be removed?", "Add or Remove Trait", D.status_traits[chosen_trait])
if(!source)
return
REMOVE_TRAIT(D, chosen_trait, source)
@@ -1,7 +1,3 @@
USER_VERB(one_click_antag, R_SERVER|R_EVENT, "Create Antagonist", "Auto-create an antagonist of your choice", VERB_CATEGORY_EVENT)
if(client.holder)
client.holder.one_click_antag()
/datum/admins/proc/one_click_antag()
var/dat = {"<B>One-click Antagonist</B><br>
@@ -0,0 +1,64 @@
USER_VERB(aooc, R_ADMIN, "AOOC", "Antagonist OOC", VERB_CATEGORY_OOC, msg as text)
msg = sanitize(msg)
if(!msg) return
var/display_name = client.key
if(client.holder && client.holder.fakekey)
display_name = client.holder.fakekey
for(var/mob/M in GLOB.mob_list)
if((M.mind && M.mind.special_role && M.client) || (M.client && M.client.holder && (M.client.holder.rights & R_ADMIN)))
to_chat(M, "<font color='#960018'>[SPAN_OOC("[SPAN_PREFIX("AOOC:")] <EM>[display_name]:</EM> [SPAN_MESSAGE("[msg]")]")]</font>")
log_aooc(msg, client)
USER_VERB(announce, R_ADMIN, "Announce", "Announce your desires to the world", VERB_CATEGORY_ADMIN)
var/message = input(client, "Global message to send:", "Admin Announce", null) as message|null
if(message)
if(!check_rights_client(R_SERVER, 0, client))
message = adminscrub(message,500)
message = replacetext(message, "\n", "<br>") // required since we're putting it in a <p> tag
to_chat(world, chat_box_notice(SPAN_NOTICE("<b>[client.holder.fakekey ? "Administrator" : client.key] Announces:</b><br><br><p>[message]</p>")))
log_admin("Announce: [key_name(client)] : [message]")
for(var/client/clients_to_alert in GLOB.clients)
window_flash(clients_to_alert)
if(clients_to_alert.prefs?.sound & SOUND_ADMINHELP)
SEND_SOUND(clients_to_alert, sound('sound/misc/server_alert.ogg'))
SSblackbox.record_feedback("tally", "admin_verb", 1, "Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ooc, R_ADMIN, "Toggle OOC", "Globally Toggles OOC", VERB_CATEGORY_SERVER)
toggle_ooc()
log_and_message_admins("toggled OOC.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_looc, R_ADMIN, "Toggle LOOC", "Globally Toggles LOOC", VERB_CATEGORY_SERVER)
GLOB.looc_enabled = !(GLOB.looc_enabled)
if(GLOB.looc_enabled)
to_chat(world, "<B>The LOOC channel has been globally enabled!</B>")
else
to_chat(world, "<B>The LOOC channel has been globally disabled!</B>")
log_and_message_admins("toggled LOOC.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle LOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_dsay, R_ADMIN, "Toggle DSAY", "Globally Toggles DSAY", VERB_CATEGORY_SERVER)
GLOB.dsay_enabled = !(GLOB.dsay_enabled)
if(GLOB.dsay_enabled)
to_chat(world, "<b>Deadchat has been globally enabled!</b>", MESSAGE_TYPE_DEADCHAT)
else
to_chat(world, "<b>Deadchat has been globally disabled!</b>", MESSAGE_TYPE_DEADCHAT)
log_admin("[key_name(client)] toggled deadchat.")
message_admins("[key_name_admin(client)] toggled deadchat.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deadchat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_ooc_dead, R_ADMIN, "Toggle Dead OOC", "Toggle Dead OOC.", VERB_CATEGORY_SERVER)
GLOB.dooc_enabled = !(GLOB.dooc_enabled)
log_admin("[key_name(client)] toggled Dead OOC.")
message_admins("[key_name_admin(client)] toggled Dead OOC.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Dead OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
USER_VERB(toggle_emoji, R_ADMIN, "Toggle OOC Emoji", "Toggle OOC Emoji", VERB_CATEGORY_SERVER)
GLOB.configuration.general.enable_ooc_emoji = !(GLOB.configuration.general.enable_ooc_emoji)
log_admin("[key_name(client)] toggled OOC Emoji.")
message_admins("[key_name_admin(client)] toggled OOC Emoji.", 1)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC Emoji")
@@ -0,0 +1,216 @@
USER_CONTEXT_MENU(show_player_panel, R_ADMIN|R_MOD, "\[Admin\] Show Player Panel", mob/M)
if(!M)
to_chat(client, "You seem to be selecting a mob that doesn't exist anymore.")
return
var/our_key = M.key
if(M.client && M.client.holder)
if(M.client.holder.fakekey && M.client.holder.big_brother)
our_key = M.client.holder.fakekey
var/mob_uid = M.UID()
var/body = "<html><meta charset='UTF-8'><head><title>Options for [our_key]</title></head>"
body += "<body>Options panel for <b>[M]</b>"
if(M.client)
body += " played by <b>[M.client]</b> "
if(check_rights(R_PERMISSIONS, FALSE))
body += "\[<A href='byond://?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\] "
else if(M.client.holder && M.client.holder.fakekey && M.client.holder.big_brother)
body += "\[Player\] "
else
body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\] "
body += "\[<A href='byond://?_src_=holder;getplaytimewindow=[mob_uid]'>" + M.client.get_exp_type(EXP_TYPE_CREW) + " as [EXP_TYPE_CREW]</a>\]"
body += "<br>BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "<b>" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "</b>" : ""]"
body += "<br>BYOND client version: [M.client.byond_version].[M.client.byond_build]"
body += "<br>Global Ban DB Lookup: [GLOB.configuration.url.centcom_ban_db_url ? "<a href='byond://?_src_=holder;open_ccbdb=[M.client.ckey]'>Lookup</a>" : "<i>Disabled</i>"]"
body += "<br><a href='byond://?_src_=holder;clientmodcheck=[M.client.UID()]'>Check for client modification</a>"
body += "<br>"
if(isnewplayer(M))
body += " <B>Hasn't Entered Game</B> "
else
body += " \[<A href='byond://?_src_=holder;revive=[mob_uid]'>Heal</A>\] "
body += "<br><br>\[ "
body += "<a href='byond://?_src_=holder;open_logging_view=[mob_uid];'>LOGS</a> - "
body += "<a href='byond://?_src_=vars;Vars=[mob_uid]'>VV</a> - "
body += "[ADMIN_TP(M,"TP")] - "
if(M.client)
body += "<a href='byond://?src=[usr.UID()];priv_msg=[M.client.ckey]'>PM</a> - "
body += "[ADMIN_SM(M,"SM")] - "
if(ishuman(M) && M.mind)
body += "<a href='byond://?_src_=holder;HeadsetMessage=[mob_uid]'>HM</a> - "
body += "[admin_jump_link(M)] - "
body += "<a href='byond://?_src_=holder;adminalert=[mob_uid]'>SEND ALERT</a>\]</b><br>"
body += "<b>Mob type:</b> [M.type]<br>"
if(M.client)
if(length(M.client.related_accounts_cid))
body += "<b>Related accounts by CID:</b> [jointext(M.client.related_accounts_cid, " - ")]<br>"
if(length(M.client.related_accounts_ip))
body += "<b>Related accounts by IP:</b> [jointext(M.client.related_accounts_ip, " - ")]<br><br>"
if(M.ckey)
body += "<b>Enabled AntagHUD</b>: [M.has_ahudded() ? "<b><font color='red'>TRUE</font></b>" : "false"]<br>"
body += "<b>Roundstart observer</b>: [M.is_roundstart_observer() ? "<b>true</b>" : "false"]<br>"
body += "<A href='byond://?_src_=holder;boot2=[mob_uid]'>Kick</A> | "
body += "<A href='byond://?_src_=holder;newban=[mob_uid];dbbanaddckey=[M.ckey]'>Ban</A> | "
body += "<A href='byond://?_src_=holder;jobban2=[mob_uid];dbbanaddckey=[M.ckey]'>Jobban</A> | "
body += "<A href='byond://?_src_=holder;shownoteckey=[M.ckey]'>Notes</A> | "
if(GLOB.configuration.url.forum_playerinfo_url)
body += "<A href='byond://?_src_=holder;webtools=[M.ckey]'>WebInfo</A> | "
if(M.client)
if(M.client.watchlisted)
body += "<A href='byond://?_src_=holder;watchremove=[M.ckey]'>Remove from Watchlist</A> | "
body += "<A href='byond://?_src_=holder;watchedit=[M.ckey]'>Edit Watchlist Reason</A> "
else
body += "<A href='byond://?_src_=holder;watchadd=[M.ckey]'>Add to Watchlist</A> "
body += "| <A href='byond://?_src_=holder;sendtoprison=[mob_uid]'>Prison</A> | "
body += "\ <A href='byond://?_src_=holder;sendbacktolobby=[mob_uid]'>Send back to Lobby</A> | "
body += "\ <A href='byond://?_src_=holder;eraseflavortext=[mob_uid]'>Erase Flavor Text</A> | "
body += "\ <A href='byond://?_src_=holder;userandomname=[mob_uid]'>Use Random Name</A> | "
body += {"<br><b>Mute: </b>
\[<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_IC]'><font color='[check_mute(M.client.ckey, MUTE_IC) ? "red" : "#6685f5"]'>IC</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_OOC]'><font color='[check_mute(M.client.ckey, MUTE_OOC) ? "red" : "#6685f5"]'>OOC</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_PRAY]'><font color='[check_mute(M.client.ckey, MUTE_PRAY) ? "red" : "#6685f5"]'>PRAY</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_ADMINHELP]'><font color='[check_mute(M.client.ckey, MUTE_ADMINHELP) ? "red" : "#6685f5"]'>ADMINHELP</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_DEADCHAT]'><font color='[check_mute(M.client.ckey, MUTE_DEADCHAT) ?" red" : "#6685f5"]'>DEADCHAT</font></a> |
<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_EMOTE]'><font color='[check_mute(M.client.ckey, MUTE_EMOTE) ?" red" : "#6685f5"]'>EMOTE</font></a>]
(<A href='byond://?_src_=holder;mute=[mob_uid];mute_type=[MUTE_ALL]'><font color='[check_mute(M.client.ckey, MUTE_ALL) ? "red" : "#6685f5"]'>toggle all</font></a>)
"}
var/jumptoeye = ""
if(is_ai(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
jumptoeye = " <b>(<A href='byond://?_src_=holder;jumpto=[A.eyeobj.UID()]'>Eye</A>)</b>"
body += {"<br><br>
<A href='byond://?_src_=holder;jumpto=[mob_uid]'><b>Jump to</b></A>[jumptoeye] |
<A href='byond://?_src_=holder;getmob=[mob_uid]'>Get</A> |
<A href='byond://?_src_=holder;sendmob=[mob_uid]'>Send To</A>
<br><br>
[check_rights(R_ADMIN,0) ? "[ADMIN_TP(M,"Traitor panel")] | " : "" ]
<A href='byond://?_src_=holder;narrateto=[mob_uid]'>Narrate to</A> |
[ADMIN_SM(M,"Subtle message")]
"}
if(check_rights(R_EVENT, 0))
body += {" | <A href='byond://?_src_=holder;Bless=[mob_uid]'>Bless</A> | <A href='byond://?_src_=holder;Smite=[mob_uid]'>Smite</A>"}
if(isLivingSSD(M))
if(istype(M.loc, /obj/machinery/cryopod))
body += {" | <A href='byond://?_src_=holder;cryossd=[mob_uid]'>De-Spawn</A> "}
else
body += {" | <A href='byond://?_src_=holder;cryossd=[mob_uid]'>Cryo</A> "}
if(M.client)
if(!isnewplayer(M))
body += "<br><br>"
body += "<b>Transformation:</b>"
body += "<br>"
//Monkey
if(issmall(M))
body += "<B>Monkeyized</B> | "
else
body += "<A href='byond://?_src_=holder;monkeyone=[mob_uid]'>Monkeyize</A> | "
//Corgi
if(iscorgi(M))
body += "<B>Corgized</B> | "
else
body += "<A href='byond://?_src_=holder;corgione=[mob_uid]'>Corgize</A> | "
//AI / Cyborg
if(is_ai(M))
body += "<B>Is an AI</B> "
else if(ishuman(M))
body += {"<A href='byond://?_src_=holder;makeai=[mob_uid]'>Make AI</A> |
<A href='byond://?_src_=holder;makerobot=[mob_uid]'>Make Robot</A> |
<A href='byond://?_src_=holder;makealien=[mob_uid]'>Make Alien</A> |
<A href='byond://?_src_=holder;makeslime=[mob_uid]'>Make Slime</A> |
<A href='byond://?_src_=holder;makesuper=[mob_uid]'>Make Superhero</A> |
"}
//Simple Animals
if(isanimal_or_basicmob(M))
body += "<A href='byond://?_src_=holder;makeanimal=[mob_uid]'>Re-Animalize</A> | "
else
body += "<A href='byond://?_src_=holder;makeanimal=[mob_uid]'>Animalize</A> | "
if(isobserver(M))
body += "<A href='byond://?_src_=holder;incarn_ghost=[mob_uid]'>Re-incarnate</a> | "
if(ispAI(M))
body += "<B>Is a pAI</B> "
else
body += "<A href='byond://?_src_=holder;makePAI=[mob_uid]'>Make pAI</A> | "
// DNA2 - Admin Hax
if(M.dna && iscarbon(M))
body += "<br><br>"
body += "<b>DNA Blocks:</b><br><table border='0'><tr><th>&nbsp;</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th>"
var/bname
for(var/block in 1 to DNA_SE_LENGTH)
if(((block-1)%5)==0)
body += "</tr><tr><th>[block-1]</th>"
bname = GLOB.assigned_blocks[block]
body += "<td>"
if(bname)
var/bstate=M.dna.GetSEState(block)
var/bcolor="[(bstate)?"#006600":"#ff0000"]"
body += "<A href='byond://?_src_=holder;togmutate=[mob_uid];block=[block]' style='color:[bcolor];'>[bname]</A><sub>[block]</sub>"
else
body += "[block]"
body+="</td>"
body += "</tr></table>"
body += {"<br><br>
<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>
<A href='byond://?_src_=holder;simplemake=observer;mob=[mob_uid]'>Observer</A> |
\[ Alien: <A href='byond://?_src_=holder;simplemake=drone;mob=[mob_uid]'>Drone</A>,
<A href='byond://?_src_=holder;simplemake=hunter;mob=[mob_uid]'>Hunter</A>,
<A href='byond://?_src_=holder;simplemake=queen;mob=[mob_uid]'>Queen</A>,
<A href='byond://?_src_=holder;simplemake=sentinel;mob=[mob_uid]'>Sentinel</A>,
<A href='byond://?_src_=holder;simplemake=larva;mob=[mob_uid]'>Larva</A> \]
<A href='byond://?_src_=holder;simplemake=human;mob=[mob_uid]'>Human</A>
\[ slime: <A href='byond://?_src_=holder;simplemake=slime;mob=[mob_uid]'>Baby</A>,
<A href='byond://?_src_=holder;simplemake=adultslime;mob=[mob_uid]'>Adult</A> \]
<A href='byond://?_src_=holder;simplemake=monkey;mob=[mob_uid]'>Monkey</A> |
<A href='byond://?_src_=holder;simplemake=robot;mob=[mob_uid]'>Cyborg</A> |
<A href='byond://?_src_=holder;simplemake=cat;mob=[mob_uid]'>Cat</A> |
<A href='byond://?_src_=holder;simplemake=runtime;mob=[mob_uid]'>Runtime</A> |
<A href='byond://?_src_=holder;simplemake=corgi;mob=[mob_uid]'>Corgi</A> |
<A href='byond://?_src_=holder;simplemake=ian;mob=[mob_uid]'>Ian</A> |
<A href='byond://?_src_=holder;simplemake=crab;mob=[mob_uid]'>Crab</A> |
<A href='byond://?_src_=holder;simplemake=coffee;mob=[mob_uid]'>Coffee</A> |
\[ Construct: <A href='byond://?_src_=holder;simplemake=constructarmoured;mob=[mob_uid]'>Armoured</A> ,
<A href='byond://?_src_=holder;simplemake=constructbuilder;mob=[mob_uid]'>Builder</A> ,
<A href='byond://?_src_=holder;simplemake=constructwraith;mob=[mob_uid]'>Wraith</A> \]
<A href='byond://?_src_=holder;simplemake=shade;mob=[mob_uid]'>Shade</A>
"}
if(M.client)
body += {"<br><br>
<b>Other actions:</b>
<br>
<A href='byond://?_src_=holder;forcespeech=[mob_uid]'>Forcesay</A> |
<A href='byond://?_src_=holder;aroomwarp=[mob_uid]'>Admin Room</A> |
<A href='byond://?_src_=holder;tdome1=[mob_uid]'>Thunderdome 1</A> |
<A href='byond://?_src_=holder;tdome2=[mob_uid]'>Thunderdome 2</A> |
<A href='byond://?_src_=holder;tdomeadmin=[mob_uid]'>Thunderdome Admin</A> |
<A href='byond://?_src_=holder;tdomeobserve=[mob_uid]'>Thunderdome Observer</A> |
<A href='byond://?_src_=holder;contractor_stop=[mob_uid]'>Stop Syndicate Jail Timer</A> |
<A href='byond://?_src_=holder;contractor_start=[mob_uid]'>Start Syndicate Jail Timer</A> |
<A href='byond://?_src_=holder;contractor_release=[mob_uid]'>Release now from Syndicate Jail</A> |
"}
body += {"<br>
</body></html>
"}
client << browse(body, "window=adminplayeropts;size=550x615")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
File diff suppressed because it is too large Load Diff