mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-30 11:01:35 +00:00
* Refactors firestacks into status effects (#66573) This PR refactors firestacks into two status effects: fire_stacks, which behave like normal firestacks you have right now, and wet_stacks, which are your negative fire stacks right now. This allows for custom fires with custom behaviors and icons to be made. Some fire related is moved away from species(what the fuck was it even doing there) into these as well. Oh and I fixed the bug where monkeys on fire had a human fire overlay, why wasn't this fixed already, it's like ancient. Also changed some related proc names to be snake_case like everything should be. This allows for custom fire types with custom behaviours, like freezing freon fire or radioactive tritium fire. Removing vars from living and moving them to status effects for modularity is also good. Nothing to argue about since there's nothing player-facing * Hud Image Culling By Z Level: Theft edition (#65189) * makes hud images only apply by z level * makes some of the atom_hud procs have better names * fixes warning with the hud_user list and adds better documentation * better docs for hud_images * removes TODOs * docs for hud_list * adds support for linked z levels so mobs can see lower ones * fixes merge conflict and shittily makes only shocked airlocks get added * adds support for setting images in the hud as active and inactive * gets rid of unatomic spatial grid change * maybe i should actually try COMPILING my changes * fixes merge skew and makes it compile again * fixes huds refusing to remove from users who changed z level * improves z level and registration logic * fixes antag huds not appearing * Fixes antag huds not properly setting. We now use hud_list in init, so it needs to be set before the new call, not after. Not sure why the use of appearance key was split like this, but none else knows either so none can stop me * Ensures that hiding a basic appearance also hides the atom's active list too * Fixes antag huds going poof Ensures that remove_atom_from_hud will return false if the passed atom isn't managed by it This fixes antag huds disappearing randomly, since they assumed that if the parent call of remove_atom_from_hud returned true, we should delete ourselves. This is a safe assumption for them to make, since they should only ever have one atom. Does kinda bork if we call remove_atom_from_hud in a way that is unsure if the passed atom is actually in that list. We were forced into doing this by how atom huds use the qdeleting signal. * makes basic alternate_appearance's only update themselves when setting their hud image to active and makes them not add themselves to the global huds_by_category list * fixes mistake with hud_users list being set non associatively (bad) * as anything in bot path loops * Fixes merge skew problems * Makes bot paths non global This way they can show themselves to only the bot that "owns" them, ya feel me? * Fixes huds not showing up sometimes, cleans up some code Post Kapu's limb refactor, we were calling prepare_huds twice in a human init call chain. What was happening was this: call prepare_huds() // Human I gained a new hud image I set active hud icons to mirror it call prepare_huds() // Living I overwrote the new hud image I attempted to set active hud icons, which failed because it assumes this can never happen *cries* * Renames add_hud_to_atom to show_to My hope is this will make understanding hud code a bit easier, by tying the behavior to a "verb" more closely. Also renamed a few vars * remove_hud_from_mob -> hide_from * Nitpicks a few comments * Whoops/fuck/shit/damn it all/hhhhhhhhhhhh * Moves check down, improves stack trace a bit Co-authored-by: KylerAce <kylerlumpkin1@gmail.com> * small touch-up * this should do it Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: KylerAce <kylerlumpkin1@gmail.com>
472 lines
24 KiB
Plaintext
472 lines
24 KiB
Plaintext
// Admin Tab - Game Verbs
|
|
|
|
/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
|
|
set category = "Admin.Game"
|
|
set name = "Show Player Panel"
|
|
set desc="Edit player (respawn, ban, heal, etc)"
|
|
|
|
if(!check_rights())
|
|
return
|
|
|
|
log_admin("[key_name(usr)] checked the individual player panel for [key_name(M)][isobserver(usr)?"":" while in game"].")
|
|
|
|
if(!M)
|
|
to_chat(usr, span_warning("You seem to be selecting a mob that doesn't exist anymore."), confidential = TRUE)
|
|
return
|
|
|
|
var/body = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Options for [M.key]</title></head>"
|
|
body += "<body>Options panel for <b>[M]</b>"
|
|
if(M.client)
|
|
body += " played by <b>[M.client]</b> "
|
|
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];key=[M.key]'>[M.client.holder ? M.client.holder.rank_names() : "Player"]</A>\]"
|
|
if(CONFIG_GET(flag/use_exp_tracking))
|
|
body += "\[<A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(M)]'>" + M.client.get_exp_living(FALSE) + "</a>\]"
|
|
|
|
if(isnewplayer(M))
|
|
body += " <B>Hasn't Entered Game</B> "
|
|
else
|
|
body += " \[<A href='?_src_=holder;[HrefToken()];revive=[REF(M)]'>Heal</A>\] "
|
|
|
|
if(M.ckey)
|
|
body += "<br>\[<A href='?_src_=holder;[HrefToken()];ppbyckey=[M.ckey];ppbyckeyorigmob=[REF(M)]'>Find Updated Panel</A>\]"
|
|
|
|
if(M.client)
|
|
body += "<br>\[<b>First Seen:</b> [M.client.player_join_date]\]\[<b>Byond account registered on:</b> [M.client.account_join_date]\]"
|
|
body += "<br><br><b>CentCom Galactic Ban DB: </b> "
|
|
if(CONFIG_GET(string/centcom_ban_db))
|
|
body += "<a href='?_src_=holder;[HrefToken()];centcomlookup=[M.client.ckey]'>Search</a>"
|
|
else
|
|
body += "<i>Disabled</i>"
|
|
body += "<br><br><b>Show related accounts by:</b> "
|
|
body += "\[ <a href='?_src_=holder;[HrefToken()];showrelatedacc=cid;client=[REF(M.client)]'>CID</a> | "
|
|
body += "<a href='?_src_=holder;[HrefToken()];showrelatedacc=ip;client=[REF(M.client)]'>IP</a> \]"
|
|
var/full_version = "Unknown"
|
|
if(M.client.byond_version)
|
|
full_version = "[M.client.byond_version].[M.client.byond_build ? M.client.byond_build : "xxx"]"
|
|
body += "<br>\[<b>Byond version:</b> [full_version]\]<br>"
|
|
|
|
|
|
body += "<br><br>\[ "
|
|
body += "<a href='?_src_=vars;[HrefToken()];Vars=[REF(M)]'>VV</a> - "
|
|
if(M.mind)
|
|
body += "<a href='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>TP</a> - "
|
|
body += "<a href='?_src_=holder;[HrefToken()];skill=[REF(M)]'>SKILLS</a> - "
|
|
else
|
|
body += "<a href='?_src_=holder;[HrefToken()];initmind=[REF(M)]'>Init Mind</a> - "
|
|
if (iscyborg(M))
|
|
body += "<a href='?_src_=holder;[HrefToken()];borgpanel=[REF(M)]'>BP</a> - "
|
|
body += "<a href='?priv_msg=[M.ckey]'>PM</a> - "
|
|
body += "<a href='?_src_=holder;[HrefToken()];subtlemessage=[REF(M)]'>SM</a> - "
|
|
if (ishuman(M) && M.mind)
|
|
body += "<a href='?_src_=holder;[HrefToken()];HeadsetMessage=[REF(M)]'>HM</a> - "
|
|
body += "<a href='?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(M)]'>FLW</a> - "
|
|
//Default to client logs if available
|
|
var/source = LOGSRC_MOB
|
|
if(M.ckey)
|
|
source = LOGSRC_CKEY
|
|
body += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_src=[source]'>LOGS</a>\] <br>"
|
|
|
|
body += "<b>Mob type</b> = [M.type]<br><br>"
|
|
|
|
body += "<A href='?_src_=holder;[HrefToken()];boot2=[REF(M)]'>Kick</A> | "
|
|
if(M.client)
|
|
body += "<A href='?_src_=holder;[HrefToken()];newbankey=[M.key];newbanip=[M.client.address];newbancid=[M.client.computer_id]'>Ban</A> | "
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];newbankey=[M.key]'>Ban</A> | "
|
|
|
|
body += "<A href='?_src_=holder;[HrefToken()];showmessageckey=[M.ckey]'>Notes | Messages | Watchlist</A> | "
|
|
if(M.client)
|
|
body += "| <A href='?_src_=holder;[HrefToken()];sendtoprison=[REF(M)]'>Prison</A> | "
|
|
body += "\ <A href='?_src_=holder;[HrefToken()];sendbacktolobby=[REF(M)]'>Send back to Lobby</A> | "
|
|
var/muted = M.client.prefs.muted
|
|
body += "<br><b>Mute: </b> "
|
|
body += "\[<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_IC]'><font color='[(muted & MUTE_IC)?"red":"blue"]'>IC</font></a> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"blue"]'>OOC</font></a> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"blue"]'>PRAY</font></a> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"blue"]'>ADMINHELP</font></a> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"blue"]'>DEADCHAT</font></a>\]"
|
|
body += "(<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"blue"]'>toggle all</font></a>)"
|
|
|
|
body += "<br><br>"
|
|
body += "<A href='?_src_=holder;[HrefToken()];jumpto=[REF(M)]'><b>Jump to</b></A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];getmob=[REF(M)]'>Get</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];sendmob=[REF(M)]'>Send To</A>"
|
|
|
|
body += "<br><br>"
|
|
body += "<A href='?_src_=holder;[HrefToken()];traitor=[REF(M)]'>Traitor panel</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];narrateto=[REF(M)]'>Narrate to</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];subtlemessage=[REF(M)]'>Subtle message</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];playsoundto=[REF(M)]'>Play sound to</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];languagemenu=[REF(M)]'>Language Menu</A>"
|
|
|
|
if(M.client)
|
|
if(!isnewplayer(M))
|
|
body += "<br><br>"
|
|
body += "<b>Transformation:</b><br>"
|
|
if(isobserver(M))
|
|
body += "<b>Ghost</b> | "
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];simplemake=observer;mob=[REF(M)]'>Make Ghost</A> | "
|
|
|
|
if(ishuman(M) && !ismonkey(M))
|
|
body += "<b>Human</b> | "
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];simplemake=human;mob=[REF(M)]'>Make Human</A> | "
|
|
|
|
if(ismonkey(M))
|
|
body += "<b>Monkey</b> | "
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];simplemake=monkey;mob=[REF(M)]'>Make Monkey</A> | "
|
|
|
|
if(iscyborg(M))
|
|
body += "<b>Cyborg</b> | "
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];simplemake=robot;mob=[REF(M)]'>Make Cyborg</A> | "
|
|
|
|
if(isAI(M))
|
|
body += "<b>AI</b>"
|
|
else
|
|
body += "<A href='?_src_=holder;[HrefToken()];makeai=[REF(M)]'>Make AI</A>"
|
|
|
|
body += "<br><br>"
|
|
body += "<b>Other actions:</b>"
|
|
body += "<br>"
|
|
if(!isnewplayer(M))
|
|
body += "<A href='?_src_=holder;[HrefToken()];forcespeech=[REF(M)]'>Forcesay</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];tdome1=[REF(M)]'>Thunderdome 1</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];tdome2=[REF(M)]'>Thunderdome 2</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];tdomeadmin=[REF(M)]'>Thunderdome Admin</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];tdomeobserve=[REF(M)]'>Thunderdome Observer</A> | "
|
|
body += "<A href='?_src_=holder;[HrefToken()];admincommend=[REF(M)]'>Commend Behavior</A> | "
|
|
|
|
body += "<br>"
|
|
body += "</body></html>"
|
|
|
|
usr << browse(body, "window=adminplayeropts-[REF(M)];size=550x515")
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
|
|
set category = "Admin.Game"
|
|
set name = "Godmode"
|
|
if(!check_rights(R_ADMIN))
|
|
return
|
|
|
|
M.status_flags ^= GODMODE
|
|
to_chat(usr, span_adminnotice("Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"), confidential = TRUE)
|
|
|
|
log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
|
|
var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
|
|
message_admins(msg)
|
|
admin_ticket_log(M, msg)
|
|
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[M.status_flags & GODMODE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/*
|
|
If a guy was gibbed and you want to revive him, this is a good way to do so.
|
|
Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
|
|
Traitors and the like can also be revived with the previous role mostly intact.
|
|
/N */
|
|
/client/proc/respawn_character()
|
|
set category = "Admin.Game"
|
|
set name = "Respawn Character"
|
|
set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
|
|
if(!check_rights(R_ADMIN))
|
|
return
|
|
|
|
var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
|
|
if(!input)
|
|
return
|
|
|
|
var/mob/dead/observer/G_found
|
|
for(var/mob/dead/observer/G in GLOB.player_list)
|
|
if(G.ckey == input)
|
|
G_found = G
|
|
break
|
|
|
|
if(!G_found)//If a ghost was not found.
|
|
to_chat(usr, "<font color='red'>There is no active key like that in the game or the person is not currently a ghost.</font>", confidential = TRUE)
|
|
return
|
|
|
|
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
|
|
//check if they were a monkey
|
|
if(findtext(G_found.real_name,"monkey"))
|
|
if(tgui_alert(usr,"This character appears to have been a monkey. Would you like to respawn them as such?",,list("Yes","No"))=="Yes")
|
|
var/mob/living/carbon/human/species/monkey/new_monkey = new
|
|
SSjob.SendToLateJoin(new_monkey)
|
|
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
|
new_monkey.key = G_found.key
|
|
to_chat(new_monkey, "You have been fully respawned. Enjoy the game.", confidential = TRUE)
|
|
var/msg = span_adminnotice("[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy monkey.")
|
|
message_admins(msg)
|
|
admin_ticket_log(new_monkey, msg)
|
|
return //all done. The ghost is auto-deleted
|
|
|
|
|
|
//Ok, it's not a monkey. So, spawn a human.
|
|
var/mob/living/carbon/human/new_character = new//The mob being spawned.
|
|
SSjob.SendToLateJoin(new_character)
|
|
|
|
var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
|
|
if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
|
|
/*Try and locate a record for the person being respawned through GLOB.data_core.
|
|
This isn't an exact science but it does the trick more often than not.*/
|
|
var/id = md5("[G_found.real_name][G_found.mind.assigned_role.title]")
|
|
|
|
record_found = find_record("id", id, GLOB.data_core.locked)
|
|
|
|
if(record_found)//If they have a record we can determine a few things.
|
|
new_character.real_name = record_found.fields["name"]
|
|
new_character.gender = record_found.fields["gender"]
|
|
new_character.age = record_found.fields["age"]
|
|
new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], null, record_found.fields["name"], record_found.fields["blood_type"], new record_found.fields["species"], record_found.fields["features"])
|
|
else
|
|
new_character.randomize_human_appearance()
|
|
new_character.dna.update_dna_identity()
|
|
|
|
new_character.name = new_character.real_name
|
|
|
|
if(G_found.mind && !G_found.mind.active)
|
|
G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
|
else
|
|
new_character.mind_initialize()
|
|
if(is_unassigned_job(new_character.mind.assigned_role))
|
|
new_character.mind.set_assigned_role(SSjob.GetJobType(SSjob.overflow_role))
|
|
|
|
new_character.key = G_found.key
|
|
|
|
/*
|
|
The code below functions with the assumption that the mob is already a traitor if they have a special role.
|
|
So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
|
|
If they don't have a mind, they obviously don't have a special role.
|
|
*/
|
|
|
|
//Two variables to properly announce later on.
|
|
var/admin = key_name_admin(src)
|
|
var/player_key = G_found.key
|
|
|
|
//Now for special roles and equipment.
|
|
var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(/datum/antagonist/traitor)
|
|
if(traitordatum)
|
|
SSjob.EquipRank(new_character, new_character.mind.assigned_role, new_character.client)
|
|
new_character.mind.give_uplink(silent = TRUE, antag_datum = traitordatum)
|
|
|
|
switch(new_character.mind.special_role)
|
|
if(ROLE_WIZARD)
|
|
new_character.forceMove(pick(GLOB.wizardstart))
|
|
var/datum/antagonist/wizard/A = new_character.mind.has_antag_datum(/datum/antagonist/wizard,TRUE)
|
|
A.equip_wizard()
|
|
if(ROLE_SYNDICATE)
|
|
new_character.forceMove(pick(GLOB.nukeop_start))
|
|
var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)
|
|
N.equip_op()
|
|
if(ROLE_NINJA)
|
|
var/list/ninja_spawn = list()
|
|
for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list)
|
|
ninja_spawn += L
|
|
var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(/datum/antagonist/ninja)
|
|
ninjadatum.equip_space_ninja()
|
|
if(ninja_spawn.len)
|
|
new_character.forceMove(pick(ninja_spawn))
|
|
|
|
else//They may also be a cyborg or AI.
|
|
switch(new_character.mind.assigned_role.type)
|
|
if(/datum/job/cyborg)//More rigging to make em' work and check if they're traitor.
|
|
new_character = new_character.Robotize(TRUE)
|
|
if(/datum/job/ai)
|
|
new_character = new_character.AIize()
|
|
else
|
|
if(!traitordatum) // Already equipped there.
|
|
SSjob.EquipRank(new_character, new_character.mind.assigned_role, new_character.client)//Or we simply equip them.
|
|
|
|
//Announces the character on all the systems, based on the record.
|
|
if(!record_found && (new_character.mind.assigned_role.job_flags & JOB_CREW_MEMBER))
|
|
//Power to the user!
|
|
if(tgui_alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,list("No","Yes"))=="Yes")
|
|
GLOB.data_core.manifest_inject(new_character, src) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: GLOB.data_core.manifest_inject(new_character)
|
|
|
|
if(tgui_alert(new_character,"Would you like an active AI to announce this character?",,list("No","Yes"))=="Yes")
|
|
announce_arrival(new_character, new_character.mind.assigned_role.title)
|
|
|
|
var/msg = span_adminnotice("[admin] has respawned [player_key] as [new_character.real_name].")
|
|
message_admins(msg)
|
|
admin_ticket_log(new_character, msg)
|
|
|
|
to_chat(new_character, "You have been fully respawned. Enjoy the game.", confidential = TRUE)
|
|
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
return new_character
|
|
|
|
/client/proc/cmd_admin_list_open_jobs()
|
|
set category = "Admin.Game"
|
|
set name = "Manage Job Slots"
|
|
|
|
if(!check_rights(R_ADMIN))
|
|
return
|
|
holder.manage_free_slots()
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/manage_free_slots()
|
|
if(!check_rights())
|
|
return
|
|
var/datum/browser/browser = new(usr, "jobmanagement", "Manage Free Slots", 520)
|
|
var/list/dat = list()
|
|
var/count = 0
|
|
|
|
if(!SSjob.initialized)
|
|
tgui_alert(usr, "You cannot manage jobs before the job subsystem is initialized!")
|
|
return
|
|
|
|
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
|
|
dat += "<div class='notice red' style='font-size: 125%'>Lag Switch \"Disable non-observer late joining\" is ON. Only Observers may join!</div>"
|
|
|
|
dat += "<table>"
|
|
|
|
for(var/datum/job/job as anything in SSjob.joinable_occupations)
|
|
count++
|
|
var/J_title = html_encode(job.title)
|
|
var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
|
|
var/J_totPos = html_encode(job.total_positions)
|
|
dat += "<tr><td>[J_title]:</td> <td>[J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]"
|
|
|
|
dat += "</td>"
|
|
dat += "<td>"
|
|
if(job.total_positions >= 0)
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];customjobslot=[job.title]'>Custom</A> | "
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];addjobslot=[job.title]'>Add 1</A> | "
|
|
if(job.total_positions > job.current_positions)
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];removejobslot=[job.title]'>Remove</A> | "
|
|
else
|
|
dat += "Remove | "
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];unlimitjobslot=[job.title]'>Unlimit</A></td>"
|
|
else
|
|
dat += "<A href='?src=[REF(src)];[HrefToken()];limitjobslot=[job.title]'>Limit</A></td>"
|
|
|
|
browser.height = min(100 + count * 20, 650)
|
|
browser.set_content(dat.Join())
|
|
browser.open()
|
|
|
|
/client/proc/toggle_view_range()
|
|
set category = "Admin.Game"
|
|
set name = "Change View Range"
|
|
set desc = "switches between 1x and custom views"
|
|
|
|
if(view_size.getView() == view_size.default)
|
|
view_size.setTo(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,37) - 7)
|
|
else
|
|
view_size.resetToDefault(getScreenSize(prefs.read_preference(/datum/preference/toggle/widescreen)))
|
|
|
|
log_admin("[key_name(usr)] changed their view range to [view].")
|
|
//message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
|
|
|
|
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Change View Range", "[view]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/toggle_combo_hud()
|
|
set category = "Admin.Game"
|
|
set name = "Toggle Combo HUD"
|
|
set desc = "Toggles the Admin Combo HUD (antag, sci, med, eng)"
|
|
|
|
if(!check_rights(R_ADMIN))
|
|
return
|
|
|
|
if (combo_hud_enabled)
|
|
disable_combo_hud()
|
|
else
|
|
enable_combo_hud()
|
|
|
|
to_chat(usr, "You toggled your admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].", confidential = TRUE)
|
|
message_admins("[key_name_admin(usr)] toggled their admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].")
|
|
log_admin("[key_name(usr)] toggled their admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].")
|
|
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Combo HUD", "[combo_hud_enabled ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/client/proc/enable_combo_hud()
|
|
if (combo_hud_enabled)
|
|
return
|
|
|
|
combo_hud_enabled = TRUE
|
|
|
|
for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED))
|
|
var/datum/atom_hud/atom_hud = GLOB.huds[hudtype]
|
|
atom_hud.show_to(mob)
|
|
|
|
for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances)
|
|
antag_hud.show_to(mob)
|
|
|
|
mob.lighting_alpha = mob.default_lighting_alpha()
|
|
mob.update_sight()
|
|
|
|
/client/proc/disable_combo_hud()
|
|
if (!combo_hud_enabled)
|
|
return
|
|
|
|
combo_hud_enabled = FALSE
|
|
|
|
for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED))
|
|
var/datum/atom_hud/atom_hud = GLOB.huds[hudtype]
|
|
atom_hud.hide_from(mob)
|
|
|
|
for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances)
|
|
antag_hud.hide_from(mob)
|
|
|
|
mob.lighting_alpha = mob.default_lighting_alpha()
|
|
mob.update_sight()
|
|
|
|
/datum/admins/proc/show_traitor_panel(mob/target_mob in GLOB.mob_list)
|
|
set category = "Admin.Game"
|
|
set desc = "Edit mobs's memory and role"
|
|
set name = "Show Traitor Panel"
|
|
var/datum/mind/target_mind = target_mob.mind
|
|
if(!target_mind)
|
|
to_chat(usr, "This mob has no mind!", confidential = TRUE)
|
|
return
|
|
if(!istype(target_mob) && !istype(target_mind))
|
|
to_chat(usr, "This can only be used on instances of type /mob and /mind", confidential = TRUE)
|
|
return
|
|
target_mind.traitor_panel()
|
|
SSblackbox.record_feedback("tally", "admin_verb", 1, "Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
|
|
/datum/admins/proc/show_skill_panel(target)
|
|
set category = "Admin.Game"
|
|
set desc = "Edit mobs's experience and skill levels"
|
|
set name = "Show Skill Panel"
|
|
var/datum/mind/target_mind
|
|
if(ismob(target))
|
|
var/mob/target_mob = target
|
|
target_mind = target_mob.mind
|
|
else if (istype(target, /datum/mind))
|
|
target_mind = target
|
|
else
|
|
to_chat(usr, "This can only be used on instances of type /mob and /mind", confidential = TRUE)
|
|
return
|
|
var/datum/skill_panel/SP = new(usr, target_mind)
|
|
SP.ui_interact(usr)
|
|
|
|
/datum/admins/proc/show_lag_switch_panel()
|
|
set category = "Admin.Game"
|
|
set name = "Show Lag Switches"
|
|
set desc="Display the controls for drastic lag mitigation measures."
|
|
|
|
if(!SSlag_switch.initialized)
|
|
to_chat(usr, span_notice("The Lag Switch subsystem has not yet been initialized."))
|
|
return
|
|
if(!check_rights())
|
|
return
|
|
|
|
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Lag Switches</title></head><body><h2><B>Lag (Reduction) Switches</B></h2>")
|
|
dat += "Automatic Trigger: <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=TOGGLE_AUTO'><b>[SSlag_switch.auto_switch ? "On" : "Off"]</b></a><br/>"
|
|
dat += "Population Threshold: <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=NUM'><b>[SSlag_switch.trigger_pop]</b></a><br/>"
|
|
dat += "Slowmode Cooldown (toggle On/Off below): <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=SLOWCOOL'><b>[SSlag_switch.slowmode_cooldown/10] seconds</b></a><br/>"
|
|
dat += "<br/><b>SET ALL MEASURES: <a href='?_src_=holder;[HrefToken()];change_lag_switch=ALL_ON'>ON</a> | <a href='?_src_=holder;[HrefToken()];change_lag_switch=ALL_OFF'>OFF</a></b><br/>"
|
|
dat += "<br/>Disable ghosts zoom and t-ray verbs (except staff): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_GHOST_ZOOM_TRAY]'><b>[SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]</b></a><br/>"
|
|
dat += "Disable late joining: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_NON_OBSJOBS]'><b>[SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]</b></a><br/>"
|
|
dat += "<br/>============! MAD GHOSTS ZONE !============<br/>"
|
|
dat += "Disable deadmob keyLoop (except staff, informs dchat): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_DEAD_KEYLOOP]'><b>[SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]</b></a><br/>"
|
|
dat += "==========================================<br/>"
|
|
dat += "<br/><b>Measures below can be bypassed with a <abbr title='TRAIT_BYPASS_MEASURES'><u>special trait</u></abbr></b><br/>"
|
|
dat += "Slowmode say verb (informs world): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[SLOWMODE_SAY]'><b>[SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]</b></a><br/>"
|
|
dat += "Disable runechat: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_RUNECHAT]'><b>[SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to speaker</span><br/>"
|
|
dat += "Disable examine icons: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_USR_ICON2HTML]'><b>[SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to examiner</span><br/>"
|
|
dat += "Disable parallax: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_PARALLAX]'><b>[SSlag_switch.measures[DISABLE_PARALLAX] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to character</span><br />"
|
|
dat += "Disable footsteps: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_FOOTSTEPS]'><b>[SSlag_switch.measures[DISABLE_FOOTSTEPS] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to character</span><br />"
|
|
dat += "Disable character creator: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_CREATOR]'><b>[SSlag_switch.measures[DISABLE_CREATOR] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to all</span><br />" // SKRYAT EDIT ADDITION
|
|
dat += "</body></html>"
|
|
usr << browse(dat.Join(), "window=lag_switch_panel;size=420x480")
|