mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 16:18:01 +01:00
Ports the 'modern' player panel from Nova/Splurt (#4586)
## About The Pull Request Ports https://github.com/NovaSector/NovaSector/pull/5923 which was a port of https://github.com/SPLURT-Station/S.P.L.U.R.T-tg/pull/9 the new menu can be accessed via a toggle in the admin preferences in game options. To see what it looks like, see the attached video in Proof of Testing It also adds a new verb, `Toggle-Admin-TGUI` which can be found in the debug tab and will toggle ***EVERYONE'S*** UI preference to old TGUI it also reverts the player panel to the old one in case you have the preference enabled and are unable to access the preferences menu. ## Why It's Good For The Game It makes things easier on the staff members to find buttons, plus it is 100% optional. ## Proof Of Testing See the video below. <details> <summary>Screenshots/Videos</summary> https://github.com/user-attachments/assets/4098bc35-95e1-4ae5-91dd-27cb2564c350 </details> ## Changelog 🆑 admin: Ported a new, toggleable, player panel from NovaSector/SPLURT admin: Adds a new verb in the debug panel: Toggle Admin TGUI /🆑 --------- Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
This commit is contained in:
@@ -8,6 +8,14 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_ADMIN, "Show Player Panel", mo
|
||||
to_chat(user, span_warning("You seem to be selecting a mob that doesn't exist anymore."), confidential = TRUE)
|
||||
return
|
||||
|
||||
// BUBBER EDIT ADDITION START
|
||||
if(user.prefs.read_preference(/datum/preference/toggle/use_tgui_player_panel) && !GLOB.tgui_fallback_enabled)
|
||||
if(isnull(player.mob_panel))
|
||||
player.create_player_panel()
|
||||
player.mob_panel.ui_interact(user.mob)
|
||||
return
|
||||
// BUBBER EDIT ADDITION END
|
||||
|
||||
var/body = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Options for [player.key]</title></head>"
|
||||
body += "<body>Options panel for <b>[player]</b>"
|
||||
if(player.client)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/// If true, TGUI will use the old fallback UI instead of the default TGUI interface.
|
||||
GLOBAL_VAR(tgui_fallback_enabled)
|
||||
@@ -0,0 +1,540 @@
|
||||
GLOBAL_LIST_INIT(mute_bits, list(
|
||||
list(name = "IC", bitflag = MUTE_IC),
|
||||
list(name = "OOC", bitflag = MUTE_OOC),
|
||||
list(name = "LOOC", bitflag = MUTE_LOOC),
|
||||
list(name = "Pray", bitflag = MUTE_PRAY),
|
||||
list(name = "Ahelp", bitflag = MUTE_ADMINHELP),
|
||||
list(name = "Deadchat", bitflag = MUTE_DEADCHAT)
|
||||
))
|
||||
|
||||
GLOBAL_DATUM_INIT(admin_state, /datum/ui_state/admin_state, new)
|
||||
|
||||
/datum/ui_state/admin_state/can_use_topic(src_object, mob/user)
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
return UI_INTERACTIVE
|
||||
return UI_CLOSE
|
||||
|
||||
GLOBAL_LIST_INIT(pp_limbs, list(
|
||||
"Head" = BODY_ZONE_HEAD,
|
||||
"Left leg" = BODY_ZONE_L_LEG,
|
||||
"Right leg" = BODY_ZONE_R_LEG,
|
||||
"Left arm" = BODY_ZONE_L_ARM,
|
||||
"Right arm" = BODY_ZONE_R_ARM
|
||||
))
|
||||
|
||||
/datum/player_panel
|
||||
var/mob/target_mob
|
||||
var/client/target_client
|
||||
|
||||
/datum/player_panel/New(mob/target)
|
||||
. = ..()
|
||||
target_mob = target
|
||||
|
||||
/datum/player_panel/Destroy(force, ...)
|
||||
target_mob = null
|
||||
target_client = null
|
||||
|
||||
SStgui.close_uis(src)
|
||||
return ..()
|
||||
|
||||
/datum/player_panel/ui_interact(mob/user, datum/tgui/ui)
|
||||
if(!target_mob)
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if (!ui)
|
||||
ui = new(user, src, "PlayerPanel", "[target_mob.real_name] Player Panel")
|
||||
ui.open()
|
||||
|
||||
/datum/player_panel/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/player_panel/ui_data(mob/user)
|
||||
. = list()
|
||||
.["mob_name"] = target_mob.real_name
|
||||
.["mob_type"] = target_mob.type
|
||||
.["admin_mob_type"] = user.client?.mob.type
|
||||
.["godmode"] = HAS_TRAIT(user, TRAIT_GODMODE)
|
||||
|
||||
var/mob/living/living_mob = target_mob
|
||||
if (istype(living_mob))
|
||||
.["is_frozen"] = living_mob.admin_frozen
|
||||
.["is_slept"] = living_mob.admin_sleeping
|
||||
.["mob_scale"] = living_mob.current_size
|
||||
|
||||
if(target_mob.client)
|
||||
target_client = target_mob.client
|
||||
.["client_ckey"] = target_client.ckey
|
||||
.["client_muted"] = target_client.prefs.muted
|
||||
.["client_rank"] = target_client.holder ? target_client.holder.ranks : "Player"
|
||||
else
|
||||
target_client = null
|
||||
.["client_ckey"] = null
|
||||
|
||||
if (target_mob.ckey)
|
||||
.["last_ckey"] = copytext(target_mob.ckey, 2)
|
||||
|
||||
/datum/player_panel/ui_static_data()
|
||||
. = list()
|
||||
|
||||
.["transformables"] = GLOB.pp_transformables
|
||||
.["glob_limbs"] = GLOB.pp_limbs
|
||||
.["glob_mute_bits"] = GLOB.mute_bits
|
||||
.["current_time"] = time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")
|
||||
|
||||
if(target_client)
|
||||
var/byond_version = "Unknown"
|
||||
if(target_client.byond_version)
|
||||
byond_version = "[target_client.byond_version].[target_client.byond_build ? target_client.byond_build : "xxx"]"
|
||||
.["data_byond_version"] = byond_version
|
||||
.["data_player_join_date"] = target_client.player_join_date
|
||||
.["data_account_join_date"] = target_client.account_join_date
|
||||
.["data_related_cid"] = target_client.related_accounts_cid
|
||||
.["data_related_ip"] = target_client.related_accounts_ip
|
||||
/* // Find relevant PR maybe?
|
||||
var/datum/player_details/deets = GLOB.player_details[target_client.ckey]
|
||||
.["data_old_names"] = deets.get_played_names() || null
|
||||
*/
|
||||
var/list/player_ranks = list()
|
||||
if(SSplayer_ranks.is_donator(target_client, admin_bypass = FALSE))
|
||||
player_ranks += "Donator"
|
||||
if(SSplayer_ranks.is_mentor(target_client, admin_bypass = FALSE))
|
||||
player_ranks += "Mentor"
|
||||
if(SSplayer_ranks.is_vetted(target_client, admin_bypass = FALSE))
|
||||
player_ranks += "Vetted"
|
||||
.["ranks"] = length(player_ranks) ? player_ranks.Join(", ") : null
|
||||
|
||||
if(CONFIG_GET(flag/use_exp_tracking))
|
||||
.["playtimes_enabled"] = TRUE
|
||||
.["playtime"] = target_mob.client.get_exp_living()
|
||||
|
||||
/datum/player_panel/ui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
|
||||
var/mob/admin_mob = ui.user
|
||||
var/client/admin_client = admin_mob.client
|
||||
|
||||
if(. || !check_rights_for(admin_client, R_ADMIN))
|
||||
message_admins(span_adminhelp("WARNING: NON-ADMIN [ADMIN_LOOKUPFLW(admin_mob)] ATTEMPTED TO ACCESS ADMIN PANEL. NOTIFY Casper3044."))
|
||||
to_chat(admin_client, "Error: you are not an admin!")
|
||||
return
|
||||
|
||||
switch(action)
|
||||
// If this mob used to be player controlled but isn't anymore, this action will open the player panel for the mob that player is now controlling.
|
||||
if ("open_latest_panel")
|
||||
if (target_mob.client || !target_mob.ckey)
|
||||
return
|
||||
|
||||
// Remove '@' from the start of the ckey.
|
||||
var/ckey = copytext(target_mob.ckey, 2)
|
||||
var/mob/latest_mob = get_mob_by_ckey(ckey)
|
||||
|
||||
if(!latest_mob)
|
||||
to_chat(admin_client, span_warning("That ckey is not controlling a mob."))
|
||||
return
|
||||
|
||||
if(target_mob == latest_mob)
|
||||
return
|
||||
|
||||
to_chat(admin_client, span_notice("New mob found for player: [target_mob.ckey] ([latest_mob])."))
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/show_player_panel, latest_mob)
|
||||
|
||||
/// Edits player Rank
|
||||
if ("edit_rank")
|
||||
if (!target_mob.client?.ckey)
|
||||
return
|
||||
|
||||
var/list/context = list()
|
||||
|
||||
context["key"] = target_mob.client.ckey
|
||||
|
||||
if (GLOB.admin_datums[target_mob.client.ckey] || GLOB.deadmins[target_mob.client.ckey])
|
||||
context["editrights"] = "rank"
|
||||
else
|
||||
context["editrights"] = "add"
|
||||
|
||||
admin_client.holder.edit_rights_topic(context)
|
||||
|
||||
/// Opens the view variables list
|
||||
if ("access_variables")
|
||||
admin_client.debug_variables(target_mob)
|
||||
|
||||
/// Sees selected player/client playtime
|
||||
if ("access_playtimes")
|
||||
if (target_mob.client)
|
||||
admin_client.holder.cmd_show_exp_panel(target_mob.client)
|
||||
|
||||
/// Privately messages player
|
||||
if ("private_message")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/cmd_admin_pm_context, target_mob)
|
||||
|
||||
/// Subtly messages selected mob (requires target to have a headset)
|
||||
if ("subtle_message")
|
||||
var/list/subtle_message_options = list("Voice in head", RADIO_CHANNEL_CENTCOM, RADIO_CHANNEL_SYNDICATE)
|
||||
var/sender = tgui_input_list(admin_client, "Choose the method of subtle messaging", "Subtle Message", subtle_message_options)
|
||||
if (!sender)
|
||||
return
|
||||
|
||||
var/msg = input("Contents of the message", text("Subtle PM to [target_mob.key]")) as text
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
if (sender == "Voice in head")
|
||||
to_chat(target_mob, "<i>You hear a voice in your head... <b>[msg]</i></b>")
|
||||
else
|
||||
var/mob/living/carbon/human/selected_mob = target_mob
|
||||
|
||||
if(!istype(selected_mob))
|
||||
to_chat(admin_client, "The person you are trying to contact is not human. Unsent message: [msg]")
|
||||
return
|
||||
|
||||
if(!istype(selected_mob.ears, /obj/item/radio/headset))
|
||||
to_chat(admin_client, "The person you are trying to contact is not wearing a headset. Unsent message: [msg]")
|
||||
return
|
||||
|
||||
to_chat(selected_mob, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == RADIO_CHANNEL_SYNDICATE ? "your benefactor" : "Central Command"]. Message as follows[sender == RADIO_CHANNEL_SYNDICATE ? ", agent." : ":"] <span class='bold'>[msg].</span> Message ends.\"")
|
||||
|
||||
|
||||
log_admin("SubtlePM ([sender]): [key_name(admin_client)] -> [key_name(target_mob)] : [msg]")
|
||||
msg = span_adminnotice("<b> SubtleMessage ([sender]): [key_name_admin(admin_client)] -> [key_name_admin(target_mob)] :</b> [msg]")
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target_mob, msg)
|
||||
|
||||
/// Forces a name change on selected player
|
||||
if ("set_name")
|
||||
target_mob.vv_auto_rename(params["name"])
|
||||
|
||||
/// Admin heals
|
||||
if ("heal")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/cmd_admin_rejuvenate, target_mob)
|
||||
|
||||
/// Forces selected player/client into ghost, disconnecting them from mob.
|
||||
if ("ghost")
|
||||
if(target_mob.client)
|
||||
log_admin("[key_name(admin_client)] ejected [key_name(target_mob)] from their body.")
|
||||
message_admins("[key_name_admin(admin_client)] ejected [key_name_admin(target_mob)] from their body.")
|
||||
to_chat(target_mob, span_danger("An admin has ejected you from your body."))
|
||||
target_mob.ghostize(FALSE)
|
||||
|
||||
/// offers control to ghosts for selected mob/body
|
||||
if ("offer_control")
|
||||
offer_control(target_mob)
|
||||
|
||||
/// Steals control from selected client's body
|
||||
if ("take_control")
|
||||
// Disassociates observer mind from the body mind
|
||||
if(target_mob.client)
|
||||
target_mob.ghostize(FALSE)
|
||||
else
|
||||
for(var/mob/dead/observer/ghost in GLOB.dead_mob_list)
|
||||
if(target_mob.mind == ghost.mind)
|
||||
ghost.mind = null
|
||||
|
||||
target_mob.ckey = admin_mob.ckey
|
||||
qdel(admin_mob)
|
||||
|
||||
message_admins(span_adminnotice("[key_name_admin(admin_client)] took control of [target_mob]."))
|
||||
log_admin("[key_name(admin_client)] took control of [target_mob].")
|
||||
addtimer(CALLBACK(target_mob.mob_panel, TYPE_PROC_REF(/datum, ui_interact), target_mob), 0.1 SECONDS)
|
||||
|
||||
/// Smites selected Client/Target
|
||||
if ("smite")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/admin_smite, target_mob)
|
||||
|
||||
/// Brings selected Client/target
|
||||
if ("bring")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/get_mob, target_mob)
|
||||
|
||||
/// Orbits arround selected Target
|
||||
if ("orbit")
|
||||
if(!isobserver(admin_mob))
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/admin_ghost)
|
||||
var/mob/dead/observer/satellite = admin_client.mob
|
||||
satellite.ManualFollow(target_mob)
|
||||
|
||||
/// Jumps to selected mob
|
||||
if ("jump_to")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/jump_to_mob, target_mob)
|
||||
|
||||
/// Forces the selected mob/client to stop moving
|
||||
if ("freeze")
|
||||
var/mob/living/living_mob = target_mob
|
||||
if (istype(living_mob))
|
||||
living_mob.toggle_admin_freeze(admin_client)
|
||||
|
||||
/// Forces slected mob/client to sleep
|
||||
if ("sleep")
|
||||
var/mob/living/living_mob = target_mob
|
||||
if (istype(living_mob))
|
||||
living_mob.toggle_admin_sleep(admin_client)
|
||||
|
||||
/// Yeets target client to the lobby (only works on ghosts)
|
||||
if ("lobby")
|
||||
if(!isobserver(target_mob))
|
||||
to_chat(admin_client, span_notice("You can only send ghost players back to the Lobby."))
|
||||
return
|
||||
|
||||
if(!target_mob.client)
|
||||
to_chat(admin_client, span_warning("[target_mob] doesn't seem to have an active client."))
|
||||
return
|
||||
|
||||
log_admin("[key_name(admin_client)] has sent [key_name(target_mob)] back to the Lobby.")
|
||||
message_admins("[key_name(admin_client)] has sent [key_name(target_mob)] back to the Lobby.")
|
||||
|
||||
var/mob/dead/new_player/new_connected_player = new()
|
||||
new_connected_player.ckey = target_mob.ckey
|
||||
qdel(target_mob)
|
||||
|
||||
/// Selects admin equipmeent via Equipment UI on the selected player/mob
|
||||
if ("select_equipment")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/select_equipment, target_mob)
|
||||
|
||||
/// Forces selecteed client to drop all their stuff (SPREAD YOUR SHIT)
|
||||
if ("strip")
|
||||
for(var/obj/item/begone_items in target_mob)
|
||||
target_mob.dropItemToGround(begone_items, TRUE) //The TRUE forces all items to drop, since this is an admin undress.
|
||||
|
||||
/// Forces selected client into cryo storage
|
||||
if ("cryo")
|
||||
target_mob.vv_send_cryo()
|
||||
|
||||
/// Forces selected client to say things against their will
|
||||
if ("force_say")
|
||||
target_mob.say(params["to_say"], forced="admin")
|
||||
|
||||
/// Forces selected client to emote against their will
|
||||
if ("force_emote")
|
||||
if (params["to_emote"])
|
||||
QUEUE_OR_CALL_VERB_FOR(VERB_CALLBACK(target_mob, TYPE_PROC_REF(/mob, emote), "me", EMOTE_VISIBLE|EMOTE_AUDIBLE, params["to_emote"], TRUE), SSspeech_controller)
|
||||
|
||||
/// Sends the offender to SUPERJAIL known as SPACE PRISON (admin prison)
|
||||
if ("prison")
|
||||
if(isAI(target_mob))
|
||||
to_chat(admin_client, "This cannot be used on instances of type /mob/living/silicon/ai.")
|
||||
return
|
||||
|
||||
target_mob.forceMove(pick(GLOB.prisonwarp))
|
||||
to_chat(target_mob, span_userdanger("You have been sent to Prison!"))
|
||||
|
||||
log_admin("[key_name(admin_client)] has sent [key_name(target_mob)] to Prison!")
|
||||
message_admins("[key_name_admin(admin_client)] has sent [key_name_admin(target_mob)] to Prison!")
|
||||
|
||||
/// Boots the offending client from the server
|
||||
if ("kick")
|
||||
if(!check_if_greater_rights_than(target_client))
|
||||
to_chat(admin_client, span_danger("Error: They have more rights than you do."), confidential = TRUE)
|
||||
return
|
||||
if(tgui_alert(admin_mob, "Kick [key_name(target_mob)]?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
if(!target_mob)
|
||||
to_chat(admin_client, span_danger("Error: [target_mob] no longer exists!"), confidential = TRUE)
|
||||
return
|
||||
if(!target_client)
|
||||
to_chat(admin_client, span_danger("Error: [target_mob] no longer has a client!"), confidential = TRUE)
|
||||
return
|
||||
to_chat(target_mob, span_danger("You have been kicked from the server by [admin_client.holder.fakekey ? "an Administrator" : "[admin_client.key]"]."), confidential = TRUE)
|
||||
log_admin("[key_name(admin_client)] kicked [key_name(target_mob)].")
|
||||
message_admins(span_adminnotice("[key_name_admin(admin_client)] kicked [key_name_admin(target_mob)]."))
|
||||
qdel(target_client)
|
||||
|
||||
/// Bans target
|
||||
if ("ban")
|
||||
var/player_key = target_mob.key
|
||||
var/player_ip = target_mob.client.address
|
||||
var/player_cid = target_mob.client.computer_id
|
||||
admin_client.holder.ban_panel(player_key, player_ip, player_cid)
|
||||
|
||||
/// Stickbans target
|
||||
if ("sticky_ban")
|
||||
var/list/ban_settings = list()
|
||||
if(target_mob.client)
|
||||
ban_settings["ckey"] = target_mob.ckey
|
||||
admin_client.holder.stickyban("add", ban_settings)
|
||||
|
||||
/// Opens selected target's Notes
|
||||
if ("notes")
|
||||
if (target_mob.client)
|
||||
browse_messages(target_ckey = ckey(target_mob.ckey))
|
||||
|
||||
/// Opens selected target's logs
|
||||
if ("logs")
|
||||
var/source = target_mob.client ? LOGSRC_CKEY : LOGSRC_MOB
|
||||
show_individual_logging_panel(target_mob, source)
|
||||
|
||||
/// Just mutes
|
||||
if ("mute")
|
||||
if(!target_mob.client)
|
||||
return
|
||||
|
||||
target_mob.client.prefs.muted = text2num(params["mute_flag"])
|
||||
log_admin("[key_name(admin_client)] set the mute flags for [key_name(target_mob)] to [target_mob.client.prefs.muted].")
|
||||
|
||||
/// MUTES EVERYBODY (NO ONE GETS TALKING STICK!!!)
|
||||
if ("mute_all")
|
||||
if(!target_mob.client)
|
||||
return
|
||||
|
||||
for(var/bit in GLOB.mute_bits)
|
||||
target_mob.client.prefs.muted |= bit["bitflag"]
|
||||
|
||||
log_admin("[key_name(admin_client)] mass-muted [key_name(target_mob)].")
|
||||
|
||||
/// Unmutes EVERYBODY
|
||||
if ("unmute_all")
|
||||
if(!target_mob.client)
|
||||
return
|
||||
|
||||
for(var/bit in GLOB.mute_bits)
|
||||
target_mob.client.prefs.muted &= ~bit["bitflag"]
|
||||
|
||||
log_admin("[key_name(admin_client)] mass-unmuted [key_name(target_mob)].")
|
||||
|
||||
/// Looks for related account data to the selected mob
|
||||
if ("related_accounts")
|
||||
if(target_mob.client)
|
||||
var/related_accounts
|
||||
if (params["related_thing"] == "CID")
|
||||
related_accounts = target_mob.client.related_accounts_cid
|
||||
else
|
||||
related_accounts = target_mob.client.related_accounts_ip
|
||||
|
||||
related_accounts = splittext(related_accounts, ", ")
|
||||
|
||||
var/list/dat = list("Related accounts by [params["related_thing"]]:")
|
||||
dat += related_accounts
|
||||
admin_client << browse(dat.Join("<br>"), "window=related_[target_mob.client];size=420x300")
|
||||
|
||||
/// Transforms the selected mob
|
||||
if ("transform")
|
||||
var/choice = params["newType"]
|
||||
if (choice == "/mob/living")
|
||||
choice = tgui_input_list(admin_client, "What should this mob transform into", "Mob Transform", subtypesof(choice))
|
||||
if (!choice)
|
||||
return
|
||||
|
||||
admin_client.holder.transform_mob(target_mob, admin_mob, choice, params["newTypeName"])
|
||||
|
||||
/// Gives targeted mob GOD (its only invulnerability)
|
||||
if ("toggle_godmode")
|
||||
admin_client.cmd_admin_godmode(target_mob)
|
||||
|
||||
/// Gives targeted mob spells (shadow wizard money gang)
|
||||
if ("spell")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/give_spell, target_mob)
|
||||
|
||||
/// Gives targeted mob quirks
|
||||
if ("martial_art")
|
||||
admin_client.teach_martial_art(target_mob)
|
||||
|
||||
/// Sets targeted mob's quirks
|
||||
if ("quirk")
|
||||
admin_client.toggle_quirk(target_mob)
|
||||
|
||||
/// Sets targeted mob's species
|
||||
if ("species")
|
||||
admin_client.set_species(target_mob)
|
||||
|
||||
/// Delimbs targeted mob (SNAAAAAAAAAAKE!!!!)
|
||||
if ("limb")
|
||||
if(!params["limbs"] || !ishuman(target_mob))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/punished_mob = target_mob
|
||||
|
||||
for(var/limb in params["limbs"])
|
||||
if (!limb)
|
||||
continue
|
||||
|
||||
if (params["delimb_mode"])
|
||||
var/obj/item/bodypart/targeted_limb = punished_mob.get_bodypart(limb)
|
||||
if (!targeted_limb)
|
||||
continue
|
||||
targeted_limb.dismember()
|
||||
playsound(punished_mob, 'sound/effects/bamf.ogg', 70)
|
||||
else
|
||||
punished_mob.regenerate_limb(limb)
|
||||
|
||||
/// Assigns selected olayer/client's scale
|
||||
if ("scale")
|
||||
var/mob/living/local_mob_data = target_mob
|
||||
if(!isnull(params["new_scale"]) && istype(local_mob_data))
|
||||
local_mob_data.vv_edit_var("current_size", params["new_scale"])
|
||||
|
||||
/// Explodes the selected player with assigned power and blasts (for the funny of course!)
|
||||
if ("explode")
|
||||
var/power = text2num(params["power"])
|
||||
var/emp_mode = text2num(params["emp_mode"])
|
||||
|
||||
|
||||
var/turf/target_turf = get_turf(admin_mob)
|
||||
message_admins("[ADMIN_LOOKUPFLW(admin_client)] created an admin [emp_mode ? "EMP" : "explosion"] at [ADMIN_VERBOSEJMP(target_turf)].")
|
||||
log_admin("[key_name(admin_client)] created an admin [emp_mode ? "EMP" : "explosion"] at [admin_mob.loc].")
|
||||
|
||||
if (emp_mode)
|
||||
empulse(admin_mob, power, power / 2, TRUE)
|
||||
else
|
||||
explosion(admin_mob, power / 3, power / 2, power, power, ignorecap = TRUE)
|
||||
|
||||
/// Narrates typed texxt to the selected client's chatboxx
|
||||
if ("narrate")
|
||||
var/list/raw_styles = params["classes"]
|
||||
|
||||
var/styles = ""
|
||||
for(var/style in raw_styles)
|
||||
styles += "[style]:[raw_styles[style]];"
|
||||
|
||||
if (params["mode_global"])
|
||||
to_chat(world, "<span style='[styles]'>[params["message"]]</span>")
|
||||
log_admin("GlobalNarrate: [key_name(admin_client)] : [params["message"]]")
|
||||
message_admins(span_adminnotice("[key_name_admin(admin_client)] Sent a global narrate"))
|
||||
else
|
||||
for(var/mob/individual_mob in view(params["range"], admin_mob))
|
||||
to_chat(individual_mob, "<span style='[styles]'>[params["message"]]</span>")
|
||||
|
||||
log_admin("LocalNarrate: [key_name(admin_client)] at [AREACOORD(admin_mob)]: [params["message"]]")
|
||||
message_admins(span_adminnotice("<b> LocalNarrate: [key_name_admin(admin_client)] at [ADMIN_VERBOSEJMP(admin_mob)]:</b> [params["message"]]<BR>"))
|
||||
|
||||
/// Opens languages panel for the selected player/client
|
||||
if ("languages")
|
||||
var/datum/language_holder/selected_character = target_mob.get_language_holder()
|
||||
selected_character.open_language_menu(admin_mob)
|
||||
|
||||
/// Opens the Traitor Panel for the selected player/client
|
||||
if ("traitor_panel")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/show_traitor_panel, target_mob)
|
||||
|
||||
/// Opens the selected player/client's skills panel
|
||||
if ("skill_panel")
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/show_skill_panel, target_mob)
|
||||
|
||||
/// Forces a commendation to selected client/player
|
||||
if ("commend")
|
||||
if(!target_mob.ckey)
|
||||
to_chat(admin_client, span_warning("This mob either no longer exists or no longer is being controlled by someone!"))
|
||||
return
|
||||
|
||||
switch(tgui_alert(admin_mob, "Would you like the effects to apply immediately or at the end of the round? Applying them now will make it clear it was an admin commendation.", "<3?", list("Apply now", "Apply at round end", "Cancel")))
|
||||
if("Apply now")
|
||||
target_mob.receive_heart(admin_mob, instant = TRUE)
|
||||
if("Apply at round end")
|
||||
target_mob.receive_heart(admin_mob)
|
||||
|
||||
/// Plays a selected sound to target client
|
||||
if ("play_sound_to")
|
||||
var/sound_file = input("", "Select a sound file",) as null|sound
|
||||
|
||||
if(sound_file && target_mob)
|
||||
SSadmin_verbs.dynamic_invoke_verb(admin_client, /datum/admin_verb/play_direct_mob_sound, sound_file, target_mob)
|
||||
|
||||
/// Applies selected client's quirks
|
||||
if ("apply_client_quirks")
|
||||
var/mob/living/carbon/human/specified_humanoid = target_mob
|
||||
if(!istype(specified_humanoid))
|
||||
to_chat(admin_client, "this can only be used on instances of type /mob/living/carbon/human.", confidential = TRUE)
|
||||
return
|
||||
if(!specified_humanoid.client)
|
||||
to_chat(admin_client, "[specified_humanoid] has no client!", confidential = TRUE)
|
||||
return
|
||||
SSquirks.AssignQuirks(specified_humanoid, specified_humanoid.client)
|
||||
log_admin("[key_name(admin_client)] applied client quirks to [key_name(specified_humanoid)].")
|
||||
message_admins(span_adminnotice("[key_name_admin(admin_client)] applied client quirks to [key_name_admin(specified_humanoid)]."))
|
||||
@@ -0,0 +1,127 @@
|
||||
// Stuff that helps the TGUI player panel transform section to work
|
||||
|
||||
GLOBAL_LIST_INIT(pp_transformables, list(
|
||||
list(
|
||||
name = "Common",
|
||||
color = "",
|
||||
types = list(
|
||||
list(
|
||||
name = "Human",
|
||||
key = /mob/living/carbon/human
|
||||
),
|
||||
list(
|
||||
name = "Monkey",
|
||||
key = /mob/living/carbon/human/species/monkey
|
||||
),
|
||||
list(
|
||||
name = "Cyborg",
|
||||
key = /mob/living/silicon/robot
|
||||
)
|
||||
)
|
||||
),
|
||||
list(
|
||||
name = "Xenomorph",
|
||||
color = "purple",
|
||||
types = list(
|
||||
list(
|
||||
name = "Larva",
|
||||
key = /mob/living/carbon/alien/larva
|
||||
),
|
||||
list(
|
||||
name = "Drone",
|
||||
key = /mob/living/carbon/alien/adult/drone
|
||||
),
|
||||
list(
|
||||
name = "Hunter",
|
||||
key = /mob/living/carbon/alien/adult/hunter
|
||||
),
|
||||
list(
|
||||
name = "Sentinel",
|
||||
key = /mob/living/carbon/alien/adult/sentinel
|
||||
),
|
||||
list(
|
||||
name = "Praetorian",
|
||||
key = /mob/living/carbon/alien/adult/royal/praetorian
|
||||
),
|
||||
list(
|
||||
name = "Queen",
|
||||
key = /mob/living/carbon/alien/adult/royal/queen
|
||||
)
|
||||
)
|
||||
),
|
||||
list(
|
||||
name = "Lavaland",
|
||||
color = "orange",
|
||||
types = list(
|
||||
list(
|
||||
name = "Goliath",
|
||||
key = /mob/living/basic/mining/goliath
|
||||
),
|
||||
list(
|
||||
name = "Legion",
|
||||
key = /mob/living/simple_animal/hostile/megafauna/legion/small
|
||||
),
|
||||
list(
|
||||
name = "Blood-Drunk Miner",
|
||||
key = /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner
|
||||
),
|
||||
list(
|
||||
name = "Gladiator",
|
||||
key = /mob/living/simple_animal/hostile/megafauna/gladiator
|
||||
),
|
||||
list(
|
||||
name = "Dragon",
|
||||
key = /mob/living/simple_animal/hostile/megafauna/dragon
|
||||
),
|
||||
list(
|
||||
name = "Legion Hivelord",
|
||||
key = /mob/living/simple_animal/hostile/asteroid/elite/legionnaire
|
||||
)
|
||||
)
|
||||
),
|
||||
list(
|
||||
name = "Cultist",
|
||||
color = "violet",
|
||||
types = list(
|
||||
list(
|
||||
name = "Shade",
|
||||
key = /mob/living/basic/shade
|
||||
),
|
||||
list(
|
||||
name = "Artificer",
|
||||
key = /mob/living/basic/construct/artificer
|
||||
),
|
||||
list(
|
||||
name = "Wraith",
|
||||
key = /mob/living/basic/construct/wraith
|
||||
),
|
||||
list(
|
||||
name = "Juggernaut",
|
||||
key = /mob/living/basic/construct/juggernaut
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
// selected_mob: Mob to change
|
||||
// new_type: Path of new type e.g: /mob/living/carbon/alien/humanoid/drone
|
||||
// new_type_name (optional): Name of the new type (used in logging): e.g: "Drone"
|
||||
/datum/admins/proc/transform_mob(mob/selected_mob, mob/admin_mob, new_type, new_type_name)
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ismob(selected_mob))
|
||||
to_chat(usr, "This can only be used on instances of type /mob.")
|
||||
return
|
||||
|
||||
if (!new_type_name)
|
||||
new_type_name = new_type
|
||||
|
||||
log_admin("[key_name(usr)] transformed [key_name(selected_mob)] into a [new_type_name].")
|
||||
message_admins(span_adminnotice("[key_name_admin(usr)] transformed [key_name_admin(selected_mob)] into a [new_type_name]."))
|
||||
|
||||
var/mob/new_mob = selected_mob.change_mob_type(new_type, delete_old_mob = TRUE)
|
||||
|
||||
if (selected_mob == admin_mob)
|
||||
admin_mob = new_mob
|
||||
addtimer(CALLBACK(new_mob.mob_panel, PROC_REF(ui_interact), admin_mob), 0.1 SECONDS)
|
||||
@@ -97,3 +97,20 @@ ADMIN_VERB(find_nullspaced_objects, R_DEBUG, "Find Nullspaced Objects", "Popup a
|
||||
|
||||
var/title = "<h1>List of all objects with a loc of null:</h1><br>"
|
||||
user << browse(HTML_SKELETON_TITLE(title, "[jointext(strings, "<br>")]"), "window=maintenace_report")
|
||||
|
||||
ADMIN_VERB(toggle_tgui_fallback, R_DEBUG, "Toggle Old TGUI Globally", "ONLY use this in the case of TGUI being broken. This will toggle it for everyone.", ADMIN_CATEGORY_DEBUG)
|
||||
if(isnull(GLOB.tgui_fallback_enabled))
|
||||
GLOB.tgui_fallback_enabled = FALSE
|
||||
|
||||
GLOB.tgui_fallback_enabled = !GLOB.tgui_fallback_enabled
|
||||
|
||||
if(GLOB.tgui_fallback_enabled)
|
||||
log_admin("[key_name(usr)] enabled old UI globally.")
|
||||
message_admins("Old UI has been ENABLED globally.")
|
||||
for(var/client/connected_clients in GLOB.clients)
|
||||
winset(connected_clients, "output_selector.legacy_output_selector", "left=output_legacy")
|
||||
else
|
||||
log_admin("[key_name(usr)] disabled old UI globally.")
|
||||
message_admins("Old UI has been DISABLED globally.")
|
||||
for(var/client/connected_clients in GLOB.clients)
|
||||
winset(connected_clients, "output_selector.output", "left=output")
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
//// Toggles Selected quirks on selected mobs
|
||||
/client/proc/toggle_quirk(mob/living/carbon/human/selected_mob)
|
||||
if (!istype(selected_mob))
|
||||
to_chat(usr, "This can only be used on /mob/living/carbon/human.")
|
||||
return
|
||||
|
||||
var/list/options = list("Clear"="Clear")
|
||||
for(var/quirk_variable in subtypesof(/datum/quirk))
|
||||
var/datum/quirk/applicable_quirk = quirk_variable
|
||||
var/quirk_name = initial(applicable_quirk.name)
|
||||
options[selected_mob.has_quirk(applicable_quirk) ? "[quirk_name] (Remove)" : "[quirk_name] (Add)"] = applicable_quirk
|
||||
|
||||
var/result = tgui_input_list(usr, "Choose quirk to add/remove", "Mob Quirks", options)
|
||||
|
||||
if(QDELETED(selected_mob))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(result)
|
||||
if(result == "Clear")
|
||||
for(var/datum/quirk/selected_quirk in selected_mob.quirks)
|
||||
selected_mob.remove_quirk(selected_quirk.type)
|
||||
else
|
||||
var/toggle_quirk = options[result]
|
||||
if(selected_mob.has_quirk(toggle_quirk))
|
||||
selected_mob.remove_quirk(toggle_quirk)
|
||||
else
|
||||
selected_mob.add_quirk(toggle_quirk,TRUE)
|
||||
|
||||
//// "Teaches" Martial arts to the selected mob
|
||||
/client/proc/teach_martial_art(mob/living/carbon/selected_mob)
|
||||
if (!istype(selected_mob))
|
||||
to_chat(usr, "This can only be used on /mob/living/carbon.")
|
||||
return
|
||||
|
||||
var/list/art_paths = subtypesof(/datum/martial_art)
|
||||
var/list/art_names = list()
|
||||
for(var/martial_art_skill in art_paths)
|
||||
var/datum/martial_art/martial_skill = martial_art_skill
|
||||
art_names[initial(martial_skill.name)] = martial_skill
|
||||
var/result = tgui_input_list(usr, "Choose the martial art to teach", "JUDO CHOP", art_names)
|
||||
if(isnull(result))
|
||||
return
|
||||
|
||||
if(QDELETED(selected_mob))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(result)
|
||||
var/chosen_art = art_names[result]
|
||||
var/datum/martial_art/martial_skill = new chosen_art
|
||||
martial_skill.teach(selected_mob)
|
||||
log_admin("[key_name(usr)] has taught [martial_skill] to [key_name(selected_mob)].")
|
||||
message_admins(span_notice("[key_name_admin(usr)] has taught [martial_skill] to [key_name_admin(selected_mob)]."))
|
||||
|
||||
//// Sets species of the selected client
|
||||
/client/proc/set_species(mob/living/carbon/human/selected_mob)
|
||||
if (istype(selected_mob))
|
||||
var/result = tgui_input_list(usr, "Choose a new species","Species", GLOB.species_list)
|
||||
if(QDELETED(selected_mob))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(result)
|
||||
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [selected_mob] to [result]")
|
||||
selected_mob.set_species(GLOB.species_list[result])
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/preference/toggle/use_tgui_player_panel
|
||||
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
|
||||
savefile_key = "use_tgui_player_panel"
|
||||
savefile_identifier = PREFERENCE_PLAYER
|
||||
default_value = FALSE
|
||||
|
||||
/datum/preference/toggle/use_tgui_player_panel/is_accessible(datum/preferences/preferences)
|
||||
if (!..(preferences))
|
||||
return FALSE
|
||||
|
||||
return is_admin(preferences.parent)
|
||||
@@ -2,3 +2,31 @@
|
||||
. = ..()
|
||||
AddComponent(/datum/component/status_indicator)
|
||||
*/
|
||||
|
||||
/// Toggle admin frozen
|
||||
/mob/living/proc/toggle_admin_freeze(client/admin)
|
||||
admin_frozen = !admin_frozen
|
||||
|
||||
if(admin_frozen)
|
||||
SetStun(INFINITY, ignore_canstun = TRUE)
|
||||
else
|
||||
SetStun(0, ignore_canstun = TRUE)
|
||||
|
||||
if(client && admin)
|
||||
to_chat(src, span_userdanger("An admin has [!admin_frozen ? "un" : ""]frozen you."))
|
||||
log_admin("[key_name(admin)] toggled admin-freeze on [key_name(src)].")
|
||||
message_admins("[key_name_admin(admin)] toggled admin-freeze on [key_name_admin(src)].")
|
||||
|
||||
/// Toggle admin sleeping
|
||||
/mob/living/proc/toggle_admin_sleep(client/admin)
|
||||
admin_sleeping = !admin_sleeping
|
||||
|
||||
if(admin_sleeping)
|
||||
SetSleeping(INFINITY)
|
||||
else
|
||||
SetSleeping(0)
|
||||
|
||||
if(client && admin)
|
||||
to_chat(src, span_userdanger("An admin has [!admin_sleeping ? "un": ""]slept you."))
|
||||
log_admin("[key_name(admin)] toggled admin-sleep on [key_name(src)].")
|
||||
message_admins("[key_name_admin(admin)] toggled admin-sleep on [key_name_admin(src)].")
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/mob/living
|
||||
/// Player Panel Code
|
||||
var/admin_frozen = FALSE
|
||||
var/admin_sleeping = FALSE
|
||||
@@ -0,0 +1,14 @@
|
||||
/// Player Panel Proc calling for new player panel creation
|
||||
/mob/proc/create_player_panel()
|
||||
if(mob_panel)
|
||||
QDEL_NULL(mob_panel)
|
||||
|
||||
mob_panel = new(src)
|
||||
|
||||
/mob/Initialize()
|
||||
. = ..()
|
||||
create_player_panel()
|
||||
|
||||
/mob/Destroy()
|
||||
QDEL_NULL(mob_panel)
|
||||
return ..()
|
||||
@@ -0,0 +1,3 @@
|
||||
/mob
|
||||
// Admin player panel for this mob
|
||||
var/datum/player_panel/mob_panel
|
||||
@@ -8840,6 +8840,7 @@
|
||||
#include "modular_zubbers\code\__DEFINES\span.dm"
|
||||
#include "modular_zubbers\code\__DEFINES\techweb_nodes.dm"
|
||||
#include "modular_zubbers\code\__DEFINES\traits.dm"
|
||||
#include "modular_zubbers\code\_globalvars\tgui_fallback.dm"
|
||||
#include "modular_zubbers\code\_globalvars\lists\_maintenance_loot.dm"
|
||||
#include "modular_zubbers\code\_globalvars\lists\maintenance_loot_common.dm"
|
||||
#include "modular_zubbers\code\_globalvars\lists\maintenance_loot_oddity.dm"
|
||||
@@ -9106,6 +9107,8 @@
|
||||
#include "modular_zubbers\code\game\turfs\open\sand.dm"
|
||||
#include "modular_zubbers\code\jobs\mining\voucher_sets.dm"
|
||||
#include "modular_zubbers\code\modules\_defines.dm"
|
||||
#include "modular_zubbers\code\modules\admin\player_panel.dm"
|
||||
#include "modular_zubbers\code\modules\admin\transform.dm"
|
||||
#include "modular_zubbers\code\modules\admin\smites\pie.dm"
|
||||
#include "modular_zubbers\code\modules\admin\verbs\admin.dm"
|
||||
#include "modular_zubbers\code\modules\admin\verbs\debug.dm"
|
||||
@@ -9233,11 +9236,13 @@
|
||||
#include "modular_zubbers\code\modules\changeling_zombies\virus.dm"
|
||||
#include "modular_zubbers\code\modules\character_preview_background\character_preview_background.dm"
|
||||
#include "modular_zubbers\code\modules\client\client_color.dm"
|
||||
#include "modular_zubbers\code\modules\client\client_procs.dm"
|
||||
#include "modular_zubbers\code\modules\client\preferences.dm"
|
||||
#include "modular_zubbers\code\modules\client\ssd.dm"
|
||||
#include "modular_zubbers\code\modules\client\autopunctuation\preferences.dm"
|
||||
#include "modular_zubbers\code\modules\client\flavor_text\flavor_text.dm"
|
||||
#include "modular_zubbers\code\modules\client\preferences\permanent_limp.dm"
|
||||
#include "modular_zubbers\code\modules\client\preferences\player_panel.dm"
|
||||
#include "modular_zubbers\code\modules\client\preferences\sounds.dm"
|
||||
#include "modular_zubbers\code\modules\client\verbs\character_directory.dm"
|
||||
#include "modular_zubbers\code\modules\clothing\_job.dm"
|
||||
@@ -9449,6 +9454,8 @@
|
||||
#include "modular_zubbers\code\modules\mkultra\reaction.dm"
|
||||
#include "modular_zubbers\code\modules\mkultra\reagent.dm"
|
||||
#include "modular_zubbers\code\modules\mkultra\vocal_cords.dm"
|
||||
#include "modular_zubbers\code\modules\mob\mob.dm"
|
||||
#include "modular_zubbers\code\modules\mob\mob_defines.dm"
|
||||
#include "modular_zubbers\code\modules\mob\dead\new_player\sprite_accessories.dm"
|
||||
#include "modular_zubbers\code\modules\mob\dead\new_player\body_markings\body_marking_gloss.dm"
|
||||
#include "modular_zubbers\code\modules\mob\dead\new_player\body_markings\body_markings.dm"
|
||||
@@ -9467,6 +9474,7 @@
|
||||
#include "modular_zubbers\code\modules\mob\living\emote.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\examine.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\living.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\living_defines.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\basic\guardian\guardian_types\holoparasite_timestop.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\basic\lightgeist\lightgeist.dm"
|
||||
#include "modular_zubbers\code\modules\mob\living\basic\moonstation\cazador.dm"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+9
@@ -6,6 +6,15 @@ import {
|
||||
} from '../base';
|
||||
import { FeatureDropdownInput } from '../dropdowns';
|
||||
|
||||
// BUBBER EDIT ADDITION START
|
||||
export const use_tgui_player_panel: FeatureToggle = {
|
||||
name: 'Use modern player panel',
|
||||
category: 'ADMIN',
|
||||
description: 'Whether to use the new TGUI player panel or the old HTML one.',
|
||||
component: CheckboxInput,
|
||||
};
|
||||
// BUBBER EDIT ADDITION END
|
||||
|
||||
export const asaycolor: Feature<string> = {
|
||||
name: 'Admin chat color',
|
||||
category: 'ADMIN',
|
||||
|
||||
Reference in New Issue
Block a user