mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
Adds a new admin verb, Mass Modify Traits (#93767)
## About The Pull Request Adds a verb, Mass Modify Traits, which allows an admin to apply or remove a specific trait from all living mobs. This lets you do things like give all mobs the `TRAIT_NOBREATHING`, or making all mobs able to fly. <img width="345" height="138" alt="JvkEnGMkQI" src="https://github.com/user-attachments/assets/fad89db3-a1a5-42d7-ae54-67ca7ba92301" /> You can specify only cliented mobs, as well as the trait source for removals. <details><summary>results</summary>  </details> ## Why It's Good For The Game More tools for admins to get creative with is always a good thing, I think! The trait system uses macros so it's difficult to use SQL to mass-apply, so here's an easy verb for it instead. ## Changelog 🆑 admin: added new admin verb, 'Mass Modify Traits', which can be used to add or remove a trait to/from every living mob. /🆑 --------- Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
This commit is contained in:
@@ -125,7 +125,7 @@ ADMIN_VERB(cmd_admin_check_player_exp, R_ADMIN, "Player Playtime", "View player
|
||||
return
|
||||
chosen_trait = available_traits[chosen_trait]
|
||||
|
||||
var/source = "adminabuse"
|
||||
var/source = TRAIT_ADMIN_GRANTED
|
||||
switch(add_or_remove)
|
||||
if("Add") //Not doing source choosing here intentionally to make this bit faster to use, you can always vv it.
|
||||
if(GLOB.movement_type_trait_to_flag[chosen_trait]) //include the required element.
|
||||
|
||||
@@ -165,6 +165,96 @@ ADMIN_VERB(polymorph_all, R_ADMIN, "Polymorph All", "Applies the effects of the
|
||||
|
||||
message_admins("Mass polymorph started by [who_did_it] is complete.")
|
||||
|
||||
/// Allow admin to mass add or remove a trait across all mobs
|
||||
ADMIN_VERB(mass_modify_traits, R_FUN, "Mass Modify Traits", "Adds or removes a trait from every mob.", ADMIN_CATEGORY_FUN)
|
||||
|
||||
var/choice = tgui_alert(user, "Add or Remove Trait?", "Mass Add/Remove Trait", list("Add", "Remove"))
|
||||
if(isnull(choice))
|
||||
return
|
||||
var/is_add = (choice == "Add")
|
||||
var/lower_choice = LOWER_TEXT(choice)
|
||||
|
||||
// Build list of valid traits that can be applied to mobs
|
||||
var/list/available_traits = list()
|
||||
for(var/key in GLOB.admin_visible_traits)
|
||||
if(ispath(/mob, key)) // so we get atom and atom/movable traits too, which doing (istype(key, /mob)) would skip
|
||||
available_traits += GLOB.admin_visible_traits[key]
|
||||
if(!length(available_traits))
|
||||
return
|
||||
|
||||
available_traits = sort_list(available_traits, GLOBAL_PROC_REF(cmp_typepaths_asc)) // sort alphabetically
|
||||
|
||||
var/mob_trait = tgui_input_list(user, "Select a trait to [lower_choice].", "Mass [choice] Trait", available_traits)
|
||||
if(isnull(mob_trait))
|
||||
return
|
||||
mob_trait = available_traits[mob_trait]
|
||||
|
||||
var/target_scope = tgui_alert(user, "[choice] [lower_choice == "add" ? "to" : "from"] all mobs, or only cliented ones?", "Scope", list("All", "Cliented"))
|
||||
if(!target_scope)
|
||||
return
|
||||
var/cliented_only = (target_scope == "Cliented")
|
||||
|
||||
// So we get readable trait name to display in the uis
|
||||
if(!GLOB.admin_trait_name_map)
|
||||
GLOB.admin_trait_name_map = generate_admin_trait_name_map()
|
||||
var/trait_name = GLOB.admin_trait_name_map[mob_trait] || mob_trait
|
||||
|
||||
// Ask for confirmation first
|
||||
var/action_word = is_add ? "to" : "from"
|
||||
var/confirm = tgui_alert(
|
||||
user,
|
||||
"Please confirm you want to [lower_choice] [trait_name] [action_word] every [cliented_only ? "cliented" : ""] mob?",
|
||||
"Confirm Mass [choice] Trait",
|
||||
list("Yes", "No")
|
||||
)
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
|
||||
// Perform operation
|
||||
var/affected = 0
|
||||
if(is_add) // Adding trait
|
||||
var/needs_movetype = GLOB.movement_type_trait_to_flag[mob_trait]
|
||||
for(var/mob/mob_to_modify as anything in GLOB.alive_mob_list)
|
||||
if(cliented_only && !mob_to_modify.client)
|
||||
continue
|
||||
if(needs_movetype)
|
||||
mob_to_modify.AddElement(/datum/element/movetype_handler)
|
||||
ADD_TRAIT(mob_to_modify, mob_trait, TRAIT_ADMIN_GRANTED)
|
||||
affected++
|
||||
|
||||
else // Removing trait
|
||||
var/source = null
|
||||
var/remove_mode = tgui_alert(user, "Remove from specific source?", "Mass Remove Trait", list("All", "Admin-Granted Traits", "Specific"))
|
||||
if(isnull(remove_mode))
|
||||
return
|
||||
|
||||
switch(remove_mode)
|
||||
if("Admin-Granted Traits") source = TRAIT_ADMIN_GRANTED
|
||||
if("Specific")
|
||||
source = LOWER_TEXT(tgui_input_text(user, "Enter source", "Mass Remove Trait", max_length = MAX_NAME_LEN))
|
||||
if(isnull(source))
|
||||
return
|
||||
|
||||
for(var/mob/mob_to_modify as anything in GLOB.alive_mob_list)
|
||||
if(cliented_only && !mob_to_modify.client)
|
||||
continue
|
||||
REMOVE_TRAIT(mob_to_modify, mob_trait, source)
|
||||
affected++
|
||||
|
||||
if(affected)
|
||||
var/plural = affected == 1 ? "mob" : "mobs"
|
||||
var/log_msg = "[key_name_admin(user)] mass [lower_choice][is_add ? "ed" : "d"] [trait_name] [action_word] [affected] [plural]."
|
||||
message_admins(log_msg)
|
||||
log_admin(log_msg)
|
||||
|
||||
/// Returns only traits that apply to mobs
|
||||
/proc/get_mob_admin_traits()
|
||||
var/list/out = list()
|
||||
for(var/key in GLOB.admin_visible_traits)
|
||||
if(ispath(key, /mob)) // key is a mob type or subtype
|
||||
out += GLOB.admin_visible_traits[key]
|
||||
return out
|
||||
|
||||
ADMIN_VERB_AND_CONTEXT_MENU(admin_smite, R_ADMIN|R_FUN, "Smite", "Smite a player with divine power.", ADMIN_CATEGORY_FUN, mob/living/target in world)
|
||||
var/punishment = tgui_input_list(user, "Choose a punishment", "DIVINE SMITING", GLOB.smites)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user