mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 05:30:05 +01:00
Admin Verb Datums MkIII | Now with functional command bar (#82511)
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
GENERAL_PROTECT_DATUM(/datum/controller/subsystem/admin_verbs)
|
||||
|
||||
SUBSYSTEM_DEF(admin_verbs)
|
||||
name = "Admin Verbs"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_ADMIN_VERBS
|
||||
/// A list of all admin verbs indexed by their type.
|
||||
var/list/datum/admin_verb/admin_verbs_by_type = list()
|
||||
/// A list of all admin verbs indexed by their visibility flag.
|
||||
var/list/list/datum/admin_verb/admin_verbs_by_visibility_flag = list()
|
||||
/// A map of all assosciated admins and their visibility flags.
|
||||
var/list/admin_visibility_flags = list()
|
||||
/// A list of all admins that are pending initialization of this SS.
|
||||
var/list/admins_pending_subsytem_init = list()
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/Initialize()
|
||||
setup_verb_list()
|
||||
process_pending_admins()
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/Recover()
|
||||
admin_verbs_by_type = SSadmin_verbs.admin_verbs_by_type
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/stat_entry(msg)
|
||||
return "[..()] | V: [length(admin_verbs_by_type)]"
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/process_pending_admins()
|
||||
var/list/pending_admins = admins_pending_subsytem_init
|
||||
admins_pending_subsytem_init = null
|
||||
for(var/admin_ckey in pending_admins)
|
||||
assosciate_admin(GLOB.directory[admin_ckey])
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/setup_verb_list()
|
||||
if(length(admin_verbs_by_type))
|
||||
CRASH("Attempting to setup admin verbs twice!")
|
||||
for(var/datum/admin_verb/verb_type as anything in subtypesof(/datum/admin_verb))
|
||||
var/datum/admin_verb/verb_singleton = new verb_type
|
||||
if(!verb_singleton.__avd_check_should_exist())
|
||||
qdel(verb_singleton, force = TRUE)
|
||||
continue
|
||||
|
||||
admin_verbs_by_type[verb_type] = verb_singleton
|
||||
if(verb_singleton.visibility_flag)
|
||||
if(!(verb_singleton.visibility_flag in admin_verbs_by_visibility_flag))
|
||||
admin_verbs_by_visibility_flag[verb_singleton.visibility_flag] = list()
|
||||
admin_verbs_by_visibility_flag[verb_singleton.visibility_flag] |= list(verb_singleton)
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/get_valid_verbs_for_admin(client/admin)
|
||||
if(isnull(admin.holder))
|
||||
CRASH("Why are we checking a non-admin for their valid... ahem... admin verbs?")
|
||||
|
||||
var/list/has_permission = list()
|
||||
for(var/permission_flag in GLOB.bitflags)
|
||||
if(admin.holder.check_for_rights(permission_flag))
|
||||
has_permission["[permission_flag]"] = TRUE
|
||||
|
||||
var/list/valid_verbs = list()
|
||||
for(var/datum/admin_verb/verb_type as anything in admin_verbs_by_type)
|
||||
var/datum/admin_verb/verb_singleton = admin_verbs_by_type[verb_type]
|
||||
if(!verify_visibility(admin, verb_singleton))
|
||||
continue
|
||||
|
||||
var/verb_permissions = verb_singleton.permissions
|
||||
if(verb_permissions == R_NONE)
|
||||
valid_verbs |= list(verb_singleton)
|
||||
else for(var/permission_flag in bitfield_to_list(verb_permissions))
|
||||
if(!has_permission["[permission_flag]"])
|
||||
continue
|
||||
valid_verbs |= list(verb_singleton)
|
||||
|
||||
return valid_verbs
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/verify_visibility(client/admin, datum/admin_verb/verb_singleton)
|
||||
var/needed_flag = verb_singleton.visibility_flag
|
||||
return !needed_flag || (needed_flag in admin_visibility_flags[admin.ckey])
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/update_visibility_flag(client/admin, flag, state)
|
||||
if(state)
|
||||
admin_visibility_flags[admin.ckey] |= list(flag)
|
||||
assosciate_admin(admin)
|
||||
return
|
||||
|
||||
admin_visibility_flags[admin.ckey] -= list(flag)
|
||||
// they lost the flag, iterate over verbs with that flag and yoink em
|
||||
for(var/datum/admin_verb/verb_singleton as anything in admin_verbs_by_visibility_flag[flag])
|
||||
verb_singleton.unassign_from_client(admin)
|
||||
admin.init_verbs()
|
||||
|
||||
/datum/controller/subsystem/admin_verbs/proc/dynamic_invoke_verb(client/admin, datum/admin_verb/verb_type, ...)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
message_admins("PERMISSION ELEVATION: [key_name_admin(admin)] attempted to dynamically invoke admin verb '[verb_type]'.")
|
||||
return
|
||||
|
||||
if(ismob(admin))
|
||||
var/mob/mob = admin
|
||||
admin = mob.client
|
||||
|
||||
if(!ispath(verb_type, /datum/admin_verb) || verb_type == /datum/admin_verb)
|
||||
CRASH("Attempted to dynamically invoke admin verb with invalid typepath '[verb_type]'.")
|
||||
if(isnull(admin.holder))
|
||||
CRASH("Attempted to dynamically invoke admin verb '[verb_type]' with a non-admin.")
|
||||
|
||||
var/list/verb_args = args.Copy()
|
||||
verb_args.Cut(2, 3)
|
||||
var/datum/admin_verb/verb_singleton = admin_verbs_by_type[verb_type] // this cannot be typed because we need to use `:`
|
||||
if(isnull(verb_singleton))
|
||||
CRASH("Attempted to dynamically invoke admin verb '[verb_type]' that doesn't exist.")
|
||||
|
||||
if(!admin.holder.check_for_rights(verb_singleton.permissions))
|
||||
to_chat(admin, span_adminnotice("You lack the permissions to do this."))
|
||||
return
|
||||
|
||||
var/old_usr = usr
|
||||
usr = admin.mob
|
||||
// THE MACRO ENSURES THIS EXISTS. IF IT EVER DOESNT EXIST SOMEONE DIDNT USE THE DAMN MACRO!
|
||||
verb_singleton.__avd_do_verb(arglist(verb_args))
|
||||
usr = old_usr
|
||||
SSblackbox.record_feedback("tally", "dynamic_admin_verb_invocation", 1, "[verb_type]")
|
||||
|
||||
/**
|
||||
* Assosciates and/or resyncs an admin with their accessible admin verbs.
|
||||
*/
|
||||
/datum/controller/subsystem/admin_verbs/proc/assosciate_admin(client/admin)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
|
||||
if(!isnull(admins_pending_subsytem_init)) // if the list exists we are still initializing
|
||||
to_chat(admin, span_big(span_green("Admin Verbs are still initializing. Please wait and you will be automatically assigned your verbs when it is complete.")))
|
||||
admins_pending_subsytem_init |= list(admin.ckey)
|
||||
return
|
||||
|
||||
// refresh their verbs
|
||||
admin_visibility_flags[admin.ckey] ||= list()
|
||||
for(var/datum/admin_verb/verb_singleton as anything in get_valid_verbs_for_admin(admin))
|
||||
verb_singleton.assign_to_client(admin)
|
||||
admin.init_verbs()
|
||||
|
||||
/**
|
||||
* Unassosciates an admin from their admin verbs.
|
||||
* Goes over all admin verbs because we don't know which ones are assigned to the admin's mob without a bunch of extra bookkeeping.
|
||||
* This might be a performance issue in the future if we have a lot of admin verbs.
|
||||
*/
|
||||
/datum/controller/subsystem/admin_verbs/proc/deassosciate_admin(client/admin)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
|
||||
UnregisterSignal(admin, COMSIG_CLIENT_MOB_LOGIN)
|
||||
for(var/datum/admin_verb/verb_type as anything in admin_verbs_by_type)
|
||||
admin_verbs_by_type[verb_type].unassign_from_client(admin)
|
||||
admin_visibility_flags -= list(admin.ckey)
|
||||
@@ -87,12 +87,9 @@ SUBSYSTEM_DEF(explosions)
|
||||
throwturf -= T
|
||||
held_throwturf -= T
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = tgui_alert(usr, "Use reactionary explosions?","Check Bomb Impact", list("Yes", "No"))
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
ADMIN_VERB(check_bomb_impacts, R_DEBUG, "Check Bomb Impact", "See what the effect of a bomb would be.", ADMIN_CATEGORY_DEBUG)
|
||||
var/newmode = tgui_alert(user, "Use reactionary explosions?","Check Bomb Impact", list("Yes", "No"))
|
||||
var/turf/epicenter = get_turf(user.mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
@@ -100,7 +97,7 @@ SUBSYSTEM_DEF(explosions)
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = tgui_input_list(usr, "Pick the bomb size", "Bomb Size?", choices)
|
||||
var/choice = tgui_input_list(user, "Pick the bomb size", "Bomb Size?", choices)
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
@@ -117,9 +114,9 @@ SUBSYSTEM_DEF(explosions)
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devastation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
dev = input(user, "Devastation range (Tiles):") as num
|
||||
heavy = input(user, "Heavy impact range (Tiles):") as num
|
||||
light = input(user, "Light impact range (Tiles):") as num
|
||||
|
||||
var/max_range = max(dev, heavy, light)
|
||||
var/x0 = epicenter.x
|
||||
|
||||
@@ -643,46 +643,38 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
|
||||
holodeck_templates[holo_template.template_id] = holo_template
|
||||
|
||||
//Manual loading of away missions.
|
||||
/client/proc/admin_away()
|
||||
set name = "Load Away Mission"
|
||||
set category = "Admin.Events"
|
||||
|
||||
if(!holder || !check_rights(R_FUN))
|
||||
return
|
||||
|
||||
|
||||
ADMIN_VERB(load_away_mission, R_FUN, "Load Away Mission", "Load a specific away mission for the station.", ADMIN_CATEGORY_EVENTS)
|
||||
if(!GLOB.the_gateway)
|
||||
if(tgui_alert(usr, "There's no home gateway on the station. You sure you want to continue ?", "Uh oh", list("Yes", "No")) != "Yes")
|
||||
if(tgui_alert(user, "There's no home gateway on the station. You sure you want to continue ?", "Uh oh", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
|
||||
var/list/possible_options = GLOB.potentialRandomZlevels + "Custom"
|
||||
var/away_name
|
||||
var/datum/space_level/away_level
|
||||
var/secret = FALSE
|
||||
if(tgui_alert(usr, "Do you want your mission secret? (This will prevent ghosts from looking at your map in any way other than through a living player's eyes.)", "Are you $$$ekret?", list("Yes", "No")) == "Yes")
|
||||
if(tgui_alert(user, "Do you want your mission secret? (This will prevent ghosts from looking at your map in any way other than through a living player's eyes.)", "Are you $$$ekret?", list("Yes", "No")) == "Yes")
|
||||
secret = TRUE
|
||||
var/answer = input("What kind?","Away") as null|anything in possible_options
|
||||
var/answer = input(user, "What kind?","Away") as null|anything in possible_options
|
||||
switch(answer)
|
||||
if("Custom")
|
||||
var/mapfile = input("Pick file:", "File") as null|file
|
||||
var/mapfile = input(user, "Pick file:", "File") as null|file
|
||||
if(!mapfile)
|
||||
return
|
||||
away_name = "[mapfile] custom"
|
||||
to_chat(usr,span_notice("Loading [away_name]..."))
|
||||
to_chat(user,span_notice("Loading [away_name]..."))
|
||||
var/datum/map_template/template = new(mapfile, "Away Mission")
|
||||
away_level = template.load_new_z(secret)
|
||||
else
|
||||
if(answer in GLOB.potentialRandomZlevels)
|
||||
away_name = answer
|
||||
to_chat(usr,span_notice("Loading [away_name]..."))
|
||||
to_chat(user,span_notice("Loading [away_name]..."))
|
||||
var/datum/map_template/template = new(away_name, "Away Mission")
|
||||
away_level = template.load_new_z(secret)
|
||||
else
|
||||
return
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has loaded [away_name] away mission.")
|
||||
log_admin("Admin [key_name(usr)] has loaded [away_name] away mission.")
|
||||
message_admins("Admin [key_name_admin(user)] has loaded [away_name] away mission.")
|
||||
log_admin("Admin [key_name(user)] has loaded [away_name] away mission.")
|
||||
if(!away_level)
|
||||
message_admins("Loading [away_name] failed!")
|
||||
return
|
||||
|
||||
@@ -86,15 +86,9 @@ SUBSYSTEM_DEF(weather)
|
||||
/datum/controller/subsystem/weather/proc/get_weather_by_type(type)
|
||||
return locate(type) in processing
|
||||
|
||||
/**
|
||||
* Calls end() on all current weather effects that are currently processing in the weather subsystem.
|
||||
*/
|
||||
/client/proc/stop_weather()
|
||||
set category = "Debug"
|
||||
set name = "Stop All Active Weather"
|
||||
|
||||
log_admin("[key_name(src)] stopped all currently active weather.")
|
||||
message_admins("[key_name_admin(src)] stopped all currently active weather.")
|
||||
ADMIN_VERB(stop_weather, R_DEBUG|R_ADMIN, "Stop All Active Weather", "Stop all currently active weather.", ADMIN_CATEGORY_DEBUG)
|
||||
log_admin("[key_name(user)] stopped all currently active weather.")
|
||||
message_admins("[key_name_admin(user)] stopped all currently active weather.")
|
||||
for(var/datum/weather/current_weather as anything in SSweather.processing)
|
||||
if(current_weather in SSweather.processing)
|
||||
current_weather.end()
|
||||
|
||||
Reference in New Issue
Block a user