From 9e7a98cefb968c700d8ba807af8fad865727bd51 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Thu, 15 Jan 2026 12:33:23 -0500 Subject: [PATCH] refactor user verb sources (#31411) --- code/__HELPERS/mob_helpers.dm | 36 + code/modules/admin/admin_verbs.dm | 676 ++++++----- code/modules/admin/event_verbs.dm | 689 +++++++++++ code/modules/admin/misc_admin_procs.dm | 510 -------- code/modules/admin/outfits.dm | 3 - code/modules/admin/server_verbs.dm | 197 +++ code/modules/admin/spawn_verbs.dm | 347 ++++++ code/modules/admin/verbs/antag-ooc.dm | 13 - code/modules/admin/verbs/custom_event.dm | 34 - .../admin/verbs/{debug.dm => debug_verbs.dm} | 250 ++-- code/modules/admin/verbs/modify_traits.dm | 43 + code/modules/admin/verbs/one_click_antag.dm | 4 - code/modules/admin/verbs/ooc_channel_verbs.dm | 64 + code/modules/admin/verbs/player_panel_verb.dm | 216 ++++ code/modules/admin/verbs/randomverbs.dm | 1067 ----------------- code/modules/economy/economy_admin.dm | 4 - code/modules/events/event_procs.dm | 11 - code/modules/response_team/ert.dm | 15 - paradise.dme | 11 +- 19 files changed, 2092 insertions(+), 2098 deletions(-) create mode 100644 code/modules/admin/event_verbs.dm create mode 100644 code/modules/admin/server_verbs.dm create mode 100644 code/modules/admin/spawn_verbs.dm delete mode 100644 code/modules/admin/verbs/antag-ooc.dm delete mode 100644 code/modules/admin/verbs/custom_event.dm rename code/modules/admin/verbs/{debug.dm => debug_verbs.dm} (78%) create mode 100644 code/modules/admin/verbs/modify_traits.dm create mode 100644 code/modules/admin/verbs/ooc_channel_verbs.dm create mode 100644 code/modules/admin/verbs/player_panel_verb.dm delete mode 100644 code/modules/admin/verbs/randomverbs.dm diff --git a/code/__HELPERS/mob_helpers.dm b/code/__HELPERS/mob_helpers.dm index 54857c16aa9..0c1a0900cd3 100644 --- a/code/__HELPERS/mob_helpers.dm +++ b/code/__HELPERS/mob_helpers.dm @@ -824,3 +824,39 @@ GLOBAL_LIST_EMPTY(do_after_once_tracker) if(bypass_warning && length(limbs)) CRASH("limbs is empty and the chest is blacklisted. this may not be intended!") return (((chest_blacklisted && !base_zone) || even_weights) ? pickweight(limbs) : ran_zone(base_zone, base_probability, limbs)) + +/proc/create_xeno(ckey, mob/user) + if(!ckey) + var/list/candidates = list() + for(var/mob/M in GLOB.player_list) + if(M.stat != DEAD) + continue //we are not dead! + if(!(ROLE_ALIEN in M.client.prefs.be_special)) + continue //we don't want to be an alium + if(jobban_isbanned(M, ROLE_ALIEN) || jobban_isbanned(M, ROLE_SYNDICATE)) + continue //we are jobbanned + if(M.client.is_afk()) + continue //we are afk + if(M.mind && M.mind.current && M.mind.current.stat != DEAD) + continue //we have a live body we are tied to + candidates += M.ckey + if(length(candidates)) + ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates + else + to_chat(user, "Error: create_xeno(): no suitable candidates.") + if(!istext(ckey)) return 0 + + var/alien_caste = input(user, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva") + var/obj/effect/landmark/spawn_here = length(GLOB.xeno_spawn) ? pick(GLOB.xeno_spawn) : pick(GLOB.latejoin) + var/mob/living/carbon/alien/new_xeno + switch(alien_caste) + if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen/large(spawn_here) + if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) + if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) + if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) + if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here) + else return 0 + + new_xeno.ckey = ckey + message_admins(SPAN_NOTICE("[key_name_admin(user)] has spawned [ckey] as a filthy xeno [alien_caste]."), 1) + return 1 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 597c1a0af66..5b2884e06e9 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -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("[mob.control_object.name] 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, "Stopped logging hrefs") - else - GLOB.configuration.logging.href_logging = TRUE - to_chat(client, "Started logging hrefs") - 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]: [length(zlevel_turf_indexes["[key]"])] Interesting Turfs")) - - 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 += "
" - ui_dat += "" - // 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 += "" - - 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
" + else + msg += "[key_name_mentor(C.mob)]: [C.player_age] days old
" + + 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
" + else + msg += "[key_name_mentor(C.mob)]: [client_hours] living + ghost hours
" + + 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, "Error: cmd_admin_mute: You don't have permission to do this.") + return + if(!M.client) + to_chat(usr, "Error: cmd_admin_mute: This mob doesn't have a client tied to it.") + 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 (Free job slots)")) + for(var/datum/job/job in SSjobs.occupations) + to_chat(client, "[job.title]: [job.current_positions] / \ + [job.total_positions == -1 ? "UNLIMITED" : job.total_positions] \ + ([job.total_positions == -1 ? "UNLIMITED" : job.total_positions - job.current_positions])") + if(job.total_positions != -1) // Only count position that isn't unlimited + currentpositiontally += job.current_positions + totalpositiontally += job.total_positions + to_chat(client, "Currently filled job slots (Excluding unlimited): [currentpositiontally] / [totalpositiontally] ([totalpositiontally - currentpositiontally])") + 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 = "SSD & AFK Report" + msg += "SSD Players:
" + msg += "" + 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 = "" + job_string + "" + role_string = "-" + obj_count = 0 + obj_string = "" + if(H.mind) + if(H.mind.special_role) + role_string = "[H.mind.special_role]" + 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 = "
Obj Target" + msg += "" + msg += "" + if(istype(H.loc, /obj/machinery/cryopod)) + msg += "" + else + msg += "" + msg += "" + msg += "
KeyReal NameJobMins SSDSpecial RoleAreaPPNCryo
[key_string][H.real_name][job_string][mins_ssd][role_string][obj_string][get_area(H)][ADMIN_PP(H,"PP")]De-SpawnCryo

" + + /* ======== AFK Section ========= */ + msg += "AFK Players:
" + msg += "" + 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 = "" + job_string + "" + role_string = "-" + obj_count = 0 + obj_string = "" + if(H.mind) + if(H.mind.special_role) + role_string = "[H.mind.special_role]" + 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 = "
Obj Target" + msg += "" + msg += "" + if(istype(H.loc, /obj/machinery/cryopod)) + msg += "" + else + msg += "" + msg += "" + msg += "
KeyReal NameJobMins AFKSpecial RoleAreaPPNCryo
[key_string][H.real_name][job_string][mins_afk][role_string][obj_string][get_area(H)][ADMIN_PP(H,"PP")]De-SpawnCryo
" + client << browse(msg, "window=Player_ssd_afk_check;size=600x300") diff --git a/code/modules/admin/event_verbs.dm b/code/modules/admin/event_verbs.dm new file mode 100644 index 00000000000..ff7a3d1190b --- /dev/null +++ b/code/modules/admin/event_verbs.dm @@ -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, "Error: Start Now: Game has already started.") + 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("[mob.control_object.name] 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, "The AI job is no longer chooseable.") + else + to_chat(world, "The AI job is chooseable now.") + 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, "

Custom Event

") + to_chat(world, "

A custom event is starting. OOC Info:

") + to_chat(world, SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]")) + to_chat(world, "
") + +// 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("
"))) + return + + custom_event_information += "

Custom Event

" + custom_event_information += "

A custom event is taking place. OOC Info:

" + custom_event_information += SPAN_ALERT("[html_encode(GLOB.custom_event_msg)]") + to_chat(src, chat_box_regular(custom_event_information.Join("
"))) + +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 Enabled.")) + 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 Disabled.")) + 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("") + for(var/datum/station_goal/S in SSticker.mode.station_goals) + dat += "[S.name][S.completed ? " (C)" : ""] - Announce | Remove" + dat += "" + dat += "Add New Goal" + dat += "" + dat += "Secondary goals" + 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] - Announce | Remove | Mark complete | Reset progress" + dat += "Add New Secondary Goal" + + usr << browse(dat.Join("
"), "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("Admin [client.key] has forced the players to have completely random identities!")) + + to_chat(client, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") + + 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, "You hear a voice in your head... [msg]") + + 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]
"), 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]
"), 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, "Incoming priority transmission from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] [input]") + SEND_SOUND(H, 'sound/effects/headset_message.ogg') diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm index 781fd47ea2b..30ec9194a06 100644 --- a/code/modules/admin/misc_admin_procs.dm +++ b/code/modules/admin/misc_admin_procs.dm @@ -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 = "Options for [our_key]" - body += "Options panel for [M]" - if(M.client) - body += " played by [M.client] " - if(check_rights(R_PERMISSIONS, FALSE)) - body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\] " - 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 += "\[" + M.client.get_exp_type(EXP_TYPE_CREW) + " as [EXP_TYPE_CREW]\]" - body += "
BYOND account registration date: [M.client.byondacc_date || "ERROR"] [M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "" : ""]([M.client.byondacc_age] days old)[M.client.byondacc_age <= GLOB.configuration.general.byond_account_age_threshold ? "" : ""]" - body += "
BYOND client version: [M.client.byond_version].[M.client.byond_build]" - body += "
Global Ban DB Lookup: [GLOB.configuration.url.centcom_ban_db_url ? "Lookup" : "Disabled"]" - body += "
Check for client modification" - - body += "
" - - if(isnewplayer(M)) - body += " Hasn't Entered Game " - else - body += " \[Heal\] " - - - body += "

\[ " - body += "LOGS - " - body += "VV - " - body += "[ADMIN_TP(M,"TP")] - " - if(M.client) - body += "PM - " - body += "[ADMIN_SM(M,"SM")] - " - if(ishuman(M) && M.mind) - body += "HM - " - body += "[admin_jump_link(M)] - " - body += "SEND ALERT\]
" - body += "Mob type: [M.type]
" - if(M.client) - if(length(M.client.related_accounts_cid)) - body += "Related accounts by CID: [jointext(M.client.related_accounts_cid, " - ")]
" - if(length(M.client.related_accounts_ip)) - body += "Related accounts by IP: [jointext(M.client.related_accounts_ip, " - ")]

" - - if(M.ckey) - body += "Enabled AntagHUD: [M.has_ahudded() ? "TRUE" : "false"]
" - body += "Roundstart observer: [M.is_roundstart_observer() ? "true" : "false"]
" - body += "Kick | " - body += "Ban | " - body += "Jobban | " - body += "Notes | " - if(GLOB.configuration.url.forum_playerinfo_url) - body += "WebInfo | " - if(M.client) - if(M.client.watchlisted) - body += "Remove from Watchlist | " - body += "Edit Watchlist Reason " - else - body += "Add to Watchlist " - - body += "| Prison | " - body += "\ Send back to Lobby | " - body += "\ Erase Flavor Text | " - body += "\ Use Random Name | " - body += {"
Mute: - \[IC | - OOC | - PRAY | - ADMINHELP | - DEADCHAT | - EMOTE] - (toggle all) - "} - - 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 = " (Eye)" - body += {"

- Jump to[jumptoeye] | - Get | - Send To -

- [check_rights(R_ADMIN,0) ? "[ADMIN_TP(M,"Traitor panel")] | " : "" ] - Narrate to | - [ADMIN_SM(M,"Subtle message")] - "} - - if(check_rights(R_EVENT, 0)) - body += {" | Bless | Smite"} - - if(isLivingSSD(M)) - if(istype(M.loc, /obj/machinery/cryopod)) - body += {" | De-Spawn "} - else - body += {" | Cryo "} - - if(M.client) - if(!isnewplayer(M)) - body += "

" - body += "Transformation:" - body += "
" - - //Monkey - if(issmall(M)) - body += "Monkeyized | " - else - body += "Monkeyize | " - - //Corgi - if(iscorgi(M)) - body += "Corgized | " - else - body += "Corgize | " - - //AI / Cyborg - if(is_ai(M)) - body += "Is an AI " - else if(ishuman(M)) - body += {"Make AI | - Make Robot | - Make Alien | - Make Slime | - Make Superhero | - "} - - //Simple Animals - if(isanimal_or_basicmob(M)) - body += "Re-Animalize | " - else - body += "Animalize | " - - if(isobserver(M)) - body += "Re-incarnate | " - - if(ispAI(M)) - body += "Is a pAI " - else - body += "Make pAI | " - - // DNA2 - Admin Hax - if(M.dna && iscarbon(M)) - body += "

" - body += "DNA Blocks:
" - var/bname - for(var/block in 1 to DNA_SE_LENGTH) - if(((block-1)%5)==0) - body += "" - bname = GLOB.assigned_blocks[block] - body += "" - body += "
 12345
[block-1]" - if(bname) - var/bstate=M.dna.GetSEState(block) - var/bcolor="[(bstate)?"#006600":"#ff0000"]" - body += "[bname][block]" - else - body += "[block]" - body+="
" - - body += {"

- Rudimentary transformation:
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.

- Observer | - \[ Alien: Drone, - Hunter, - Queen, - Sentinel, - Larva \] - Human - \[ slime: Baby, - Adult \] - Monkey | - Cyborg | - Cat | - Runtime | - Corgi | - Ian | - Crab | - Coffee | - \[ Construct: Armoured , - Builder , - Wraith \] - Shade - "} - - if(M.client) - body += {"

- Other actions: -
- Forcesay | - Admin Room | - Thunderdome 1 | - Thunderdome 2 | - Thunderdome Admin | - Thunderdome Observer | - Stop Syndicate Jail Timer | - Start Syndicate Jail Timer | - Release now from Syndicate Jail | - "} - - body += {"
- - "} - - 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("[input]")) - 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", "
") // required since we're putting it in a

tag - to_chat(world, chat_box_notice(SPAN_NOTICE("[client.holder.fakekey ? "Administrator" : client.key] Announces:

[message]

"))) - 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, "The LOOC channel has been globally enabled!") - else - to_chat(world, "The LOOC channel has been globally disabled!") - 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, "Deadchat has been globally enabled!", MESSAGE_TYPE_DEADCHAT) - else - to_chat(world, "Deadchat has been globally disabled!", 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, "Error: Start Now: Game has already started.") - 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, "New players may no longer enter the game.") - else - to_chat(world, "New players may now enter the game.") - 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, "The AI job is no longer chooseable.") - else - to_chat(world, "The AI job is chooseable now.") - 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, "You may now respawn.") - else - to_chat(world, "You may no longer respawn") - 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, "The game start has been delayed.") - 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, "The game will start soon.") - 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, "Guests may no longer enter the game.") - else - to_chat(world, "Guests may now enter the game.") - 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() diff --git a/code/modules/admin/outfits.dm b/code/modules/admin/outfits.dm index bdb0a12ee17..ad5c7681326 100644 --- a/code/modules/admin/outfits.dm +++ b/code/modules/admin/outfits.dm @@ -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("