diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index a53db2764de..13d91141c5d 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -24,3 +24,55 @@ #define VV_VISIBLE_ATOM "Visible Atom" #define VV_INSIDE_VISIBLE_ATOM "Inside a Visible Atom" #define VV_VISIBLE_TURF "Visible Turf" + +// VV href keys +#define VV_HK_TARGET "target" + +// /datum +#define VV_HK_PROC_CALL "proc_call" +#define VV_HK_MARK_OBJECT "mark_object" +#define VV_HK_DELETE "delete" +#define VV_HK_MODIFY_TRAITS "traitmod" +#define VV_HK_JUMP_TO "jump_to" +#define VV_HK_TRAITMOD "traitmod" +#define VV_HK_ADDCOMPONENT "addcomponent" +#define VV_HK_REMOVECOMPONENT "removecomponent" +#define VV_HK_MASSREMOVECOMPONENT "massremovecomponent" + +// /atom +#define VV_HK_MANIPULATE_COLOR_MATRIX "manipcolours" +#define VV_HK_ADDREAGENT "addreagent" +#define VV_HK_EDITREAGENTS "editreagents" +#define VV_HK_EXPLODE "explode" +#define VV_HK_EMP "emp" + +// /obj +#define VV_HK_DELALL "delall" +#define VV_HK_MAKESPEEDY "makespeedy" +#define VV_HK_MAKENORMALSPEED "makenormalspeed" +#define VV_HK_MODIFYARMOR "modifyarmor" + +// /mob +#define VV_HK_MOB_PLAYER_PANEL "mob_player_panel" +#define VV_HK_GIVE_SPELL "give_spell" +#define VV_HK_GIVEMARTIALART "givemartialart" +#define VV_HK_GIVE_DISEASE "give_disease" +#define VV_HK_GODMODE "godmode" +#define VV_HK_BUILD_MODE "build_mode" +#define VV_HK_MAKE_SKELETON "make_skeleton" +#define VV_HK_HALLUCINATE "hallucinate" +#define VV_HK_DIRECT_CONTROL "direct_control" +#define VV_HK_OFFER_CONTROL "offer_control" +#define VV_HK_DROP_EVERYTHING "drop_everything" +#define VV_HK_REGENERATEICONS "regenerateicons" +#define VV_HK_ADDLANGUAGE "addlanguage" +#define VV_HK_REMLANGUAGE "remlanguage" +#define VV_HK_ADDORGAN "addorgan" +#define VV_HK_REMORGAN "remorgan" +#define VV_HK_ADDVERB "addverb" +#define VV_HK_REMVERB "remverb" +#define VV_HK_GIB "gib" + +#define GET_VV_TARGET locateUID(href_list[VV_HK_TARGET]) + +#define VV_DROPDOWN_OPTION(href_key, name) . += "" diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index f341062de18..9896ec71369 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -81,27 +81,61 @@ //please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down //add seperaters by doing . += "---" /datum/proc/vv_get_dropdown() + SHOULD_CALL_PARENT(TRUE) + + . = list() + + VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION(VV_HK_PROC_CALL, "Call Proc") + VV_DROPDOWN_OPTION(VV_HK_MARK_OBJECT, "Mark Object") + VV_DROPDOWN_OPTION(VV_HK_JUMP_TO, "Jump to Object") + VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete") + VV_DROPDOWN_OPTION(VV_HK_TRAITMOD, "Modify Traits") + VV_DROPDOWN_OPTION(VV_HK_ADDCOMPONENT, "Add Component/Element") + VV_DROPDOWN_OPTION(VV_HK_REMOVECOMPONENT, "Remove Component/Element") + VV_DROPDOWN_OPTION(VV_HK_MASSREMOVECOMPONENT, "Mass Remove Component/Element") + VV_DROPDOWN_OPTION("", "---") + +/** + * This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks! + * href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables! + * This proc is for "high level" actions like admin heal/set species/etc/etc. The low level debugging things should go in admin/view_variables/topic_basic.dm in case this runtimes. + */ +/datum/proc/vv_do_topic(list/href_list) + if(!usr || !usr.client || !usr.client.holder || !check_rights(R_VAREDIT)) + return FALSE //This is VV, not to be called by anything else. + if(href_list[VV_HK_MODIFY_TRAITS]) + usr.client.holder.modify_traits(src) + + return TRUE + +/datum/proc/vv_get_header() . = list() - . += "---" - .["Call Proc"] = "byond://?_src_=vars;proc_call=[UID()]" - .["Mark Object"] = "byond://?_src_=vars;mark_object=[UID()]" - .["Jump to Object"] = "byond://?_src_=vars;jump_to=[UID()]" - .["Delete"] = "byond://?_src_=vars;delete=[UID()]" - .["Modify Traits"] = "byond://?_src_=vars;traitmod=[UID()]" - .["Add Component/Element"] = "byond://?_src_=vars;addcomponent=[UID()]" - .["Remove Component/Element"] = "byond://?_src_=vars;removecomponent=[UID()]" - .["Mass Remove Component/Element"] = "byond://?_src_=vars;massremovecomponent=[UID()]" - . += "---" /client/vv_get_dropdown() - . = list() - .["Manipulate Colour Matrix"] = "byond://?_src_=vars;manipcolours=[UID()]" - . += "---" - .["Call Proc"] = "byond://?_src_=vars;proc_call=[UID()]" - .["Mark Object"] = "byond://?_src_=vars;mark_object=[UID()]" - .["Delete"] = "byond://?_src_=vars;delete=[UID()]" - .["Modify Traits"] = "byond://?_src_=vars;traitmod=[UID()]" - . += "---" + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_MANIPULATE_COLOR_MATRIX, "Manipulate Color Matrix") + VV_DROPDOWN_OPTION("", "---") + VV_DROPDOWN_OPTION(VV_HK_PROC_CALL, "Call Proc") + VV_DROPDOWN_OPTION(VV_HK_MARK_OBJECT, "Mark Object") + VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete") + VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRAITS, "Modify Traits") + VV_DROPDOWN_OPTION("", "---") + +/client/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list[VV_HK_MANIPULATE_COLOR_MATRIX]) + if(!check_rights(R_DEBUG)) + return + + message_admins("[key_name_admin(usr)] is manipulating the colour matrix for [src]") + var/datum/ui_module/colour_matrix_tester/CMT = new(target=src) + CMT.ui_interact(usr) /client/proc/debug_variables(datum/D in world) set name = "\[Admin\] View Variables" @@ -150,34 +184,7 @@ if(sprite) sprite_text = "" - - var/list/atomsnowflake = list() - if(isatom(D)) - var/atom/A = D - if(isliving(A)) - var/mob/living/L = A - atomsnowflake += "[L]" - if(L.dir) - atomsnowflake += "
<< [dir2text(L.dir)] >>" - atomsnowflake += {" -
[L.ckey ? L.ckey : "No ckey"] / [L.real_name ? L.real_name : "No real name"] -
- BRUTE:[L.getBruteLoss()] - FIRE:[L.getFireLoss()] - TOXIN:[L.getToxLoss()] - OXY:[L.getOxyLoss()] - CLONE:[L.getCloneLoss()] - BRAIN:[L.getBrainLoss()] - STAMINA:[L.getStaminaLoss()] - - "} - else - atomsnowflake += "[A]" - if(A.dir) - atomsnowflake += "
<< [dir2text(A.dir)] >>" - else - atomsnowflake += "[D]" - + var/list/header = islist ? list("/list") : D.vv_get_header() var/formatted_type = "[type]" if(length(formatted_type) > 25) @@ -205,7 +212,7 @@ varedited_line += "
Var Edited" - var/dropdownoptions = list() + var/list/dropdownoptions = list() if(islist) dropdownoptions = list( "---", @@ -218,16 +225,6 @@ else dropdownoptions = D.vv_get_dropdown() - - var/list/dropdownoptions_html = list() - for(var/name in dropdownoptions) - var/link = dropdownoptions[name] - if(link) - dropdownoptions_html += "" - else - dropdownoptions_html += "" - - var/list/names = list() if(!islist) for(var/V in D.vars) @@ -395,7 +392,7 @@ [sprite_text]
- [atomsnowflake.Join()] + [header.Join()]
@@ -416,7 +413,7 @@ onmouseclick="this.focus()" style="background-color:#ffffff"> - [dropdownoptions_html.Join()] + [dropdownoptions.Join()] @@ -599,838 +596,19 @@ if(href_list["Vars"]) debug_variables(locateUID(href_list["Vars"])) - //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). - else if(href_list["rename"]) - if(!check_rights(R_ADMIN)) return + var/target = GET_VV_TARGET + vv_core_topics(target, href_list, href) + if(isdatum(target)) + var/datum/D = target + D.vv_do_topic(href_list) - var/mob/M = locateUID(href_list["rename"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - var/new_name = reject_bad_name(sanitize(copytext_char(input(usr, "What would you like to name this mob?", "Input a name", M.real_name) as text|null, 1, MAX_NAME_LEN)), allow_numbers = TRUE) - if(!new_name || !M) return - - message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") - M.rename_character(M.real_name, new_name) - href_list["datumrefresh"] = href_list["rename"] - - else if(href_list["varnameedit"] && href_list["datumedit"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locateUID(href_list["datumedit"]) - if(!istype(D,/datum) && !isclient(D)) - to_chat(usr, "This can only be used on instances of types /client or /datum") - return - - modify_variables(D, href_list["varnameedit"], 1) - - else if(href_list["togbit"]) - if(!check_rights(R_VAREDIT)) return - - var/atom/D = locateUID(href_list["subject"]) - if(!istype(D,/datum) && !isclient(D)) - to_chat(usr, "This can only be used on instances of types /client or /datum") - return - if(!(href_list["var"] in D.vars)) - to_chat(usr, "Unable to find variable specified.") - return - var/value = D.vars[href_list["var"]] - value ^= 1 << text2num(href_list["togbit"]) - - D.vars[href_list["var"]] = value - - else if(href_list["varnamechange"] && href_list["datumchange"]) - if(!check_rights(R_VAREDIT)) return - - var/D = locateUID(href_list["datumchange"]) - if(!istype(D,/datum) && !isclient(D)) - to_chat(usr, "This can only be used on instances of types /client or /datum") - return - - modify_variables(D, href_list["varnamechange"], 0) - - else if(href_list["varnamemass"] && href_list["datummass"]) - if(!check_rights(R_VAREDIT)) return - - var/atom/A = locateUID(href_list["datummass"]) - if(!istype(A)) - to_chat(usr, "This can only be used on instances of type /atom") - return - - cmd_mass_modify_object_variables(A, href_list["varnamemass"]) - - - else if(href_list["mob_player_panel"]) - if(!check_rights(R_ADMIN|R_MOD)) return - - var/mob/M = locateUID(href_list["mob_player_panel"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.holder.show_player_panel(M) - href_list["datumrefresh"] = href_list["mob_player_panel"] - - else if(href_list["give_spell"]) - if(!check_rights(R_SERVER|R_EVENT)) return - - var/mob/M = locateUID(href_list["give_spell"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.give_spell(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["givemartialart"]) - if(!check_rights(R_SERVER|R_EVENT)) return - - var/mob/living/carbon/C = locateUID(href_list["givemartialart"]) - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/list/artpaths = subtypesof(/datum/martial_art) - var/list/artnames = list() - for(var/i in artpaths) - var/datum/martial_art/M = i - artnames[initial(M.name)] = M - - var/result = input(usr, "Choose the martial art to teach", "JUDO CHOP") as null|anything in artnames - if(!usr) - return - if(QDELETED(C)) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - var/chosenart = artnames[result] - var/datum/martial_art/MA = new chosenart - MA.teach(C) - - href_list["datumrefresh"] = href_list["givemartialart"] - - else if(href_list["give_disease"]) - if(!check_rights(R_SERVER|R_EVENT)) return - - var/mob/M = locateUID(href_list["give_disease"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.give_disease(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["godmode"]) - if(!check_rights(R_EVENT)) return - - var/mob/M = locateUID(href_list["godmode"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.cmd_admin_godmode(M) - href_list["datumrefresh"] = href_list["godmode"] - - else if(href_list["gib"]) - if(!check_rights(R_ADMIN|R_EVENT)) return - - var/mob/M = locateUID(href_list["gib"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.cmd_admin_gib(M) - - else if(href_list["build_mode"]) - if(!check_rights(R_BUILDMODE)) return - - var/mob/M = locateUID(href_list["build_mode"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - togglebuildmode(M) - href_list["datumrefresh"] = href_list["build_mode"] - - else if(href_list["drop_everything"]) - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/mob/M = locateUID(href_list["drop_everything"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - if(usr.client) - usr.client.cmd_admin_drop_everything(M) - - else if(href_list["direct_control"]) - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/mob/M = locateUID(href_list["direct_control"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - if(usr.client) - usr.client.cmd_assume_direct_control(M) - - else if(href_list["make_skeleton"]) - if(!check_rights(R_SERVER|R_EVENT)) return - - var/mob/living/carbon/human/H = locateUID(href_list["make_skeleton"]) - if(!istype(H)) - to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") - return - - var/confirm = alert("Are you sure you want to turn this mob into a skeleton?","Confirm Skeleton Transformation","Yes","No") - if(confirm != "Yes") - return - - H.makeSkeleton() - message_admins("[key_name(usr)] has turned [key_name(H)] into a skeleton") - log_admin("[key_name_admin(usr)] has turned [key_name_admin(H)] into a skeleton") - href_list["datumrefresh"] = href_list["make_skeleton"] - - else if(href_list["hallucinate"]) - if(!check_rights(R_SERVER | R_EVENT)) - return - - var/mob/living/carbon/human/C = locateUID(href_list["hallucinate"]) - if(!istype(C)) - to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human") - return - - var/haltype = tgui_input_list(usr, "Select Hallucination Type", "Hallucinate", (subtypesof(/obj/effect/hallucination) + subtypesof(/datum/hallucination_manager))) - if(!haltype) - return - C.invoke_hallucination(haltype) - message_admins("[key_name(usr)] has given [key_name(C)] the [haltype] hallucination") - log_admin("[key_name_admin(usr)] has given [key_name_admin(C)] the [haltype] hallucination") - href_list["datumrefresh"] = href_list["hallucinate"] - - else if(href_list["offer_control"]) - if(!check_rights(R_ADMIN)) return - - var/mob/M = locateUID(href_list["offer_control"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - offer_control(M) - - else if(href_list["delete"]) - if(!check_rights(R_DEBUG, 0)) - return - - var/datum/D = locateUID(href_list["delete"]) - if(!D) - to_chat(usr, "Unable to locate item!") - admin_delete(D) - href_list["datumrefresh"] = href_list["delete"] - - else if(href_list["delall"]) - if(!check_rights(R_DEBUG|R_SERVER)) return - - var/obj/O = locateUID(href_list["delall"]) - if(!isobj(O)) - to_chat(usr, "This can only be used on instances of type /obj") - return - - var/action_type = alert("Strict type ([O.type]) or type and all subtypes?", null,"Strict type","Type and subtypes","Cancel") - if(action_type == "Cancel" || !action_type) - return - - if(alert("Are you really sure you want to delete all objects of type [O.type]?", null,"Yes","No") != "Yes") - return - - if(alert("Second confirmation required. Delete?", null,"Yes","No") != "Yes") - return - - var/O_type = O.type - switch(action_type) - if("Strict type") - var/i = 0 - for(var/obj/Obj in world) - if(Obj.type == O_type) - i++ - qdel(Obj) - if(!i) - to_chat(usr, "No objects of this type exist") - return - log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)") - message_admins("[key_name_admin(usr)] deleted all objects of type [O_type] ([i] objects deleted)") - if("Type and subtypes") - var/i = 0 - for(var/obj/Obj in world) - if(istype(Obj,O_type)) - i++ - qdel(Obj) - if(!i) - to_chat(usr, "No objects of this type exist") - return - log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") - message_admins("[key_name_admin(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") - - else if(href_list["makespeedy"]) - if(!check_rights(R_DEBUG|R_ADMIN)) - return - var/obj/A = locateUID(href_list["makespeedy"]) - if(!istype(A)) - return - A.var_edited = TRUE - A.makeSpeedProcess() - log_admin("[key_name(usr)] has made [A] speed process") - message_admins("[key_name(usr)] has made [A] speed process") - return TRUE - - else if(href_list["makenormalspeed"]) - if(!check_rights(R_DEBUG|R_ADMIN)) - return - var/obj/A = locateUID(href_list["makenormalspeed"]) - if(!istype(A)) - return - A.var_edited = TRUE - A.makeNormalProcess() - log_admin("[key_name(usr)] has made [A] process normally") - message_admins("[key_name(usr)] has made [A] process normally") - return TRUE - - else if(href_list["modifyarmor"]) - if(!check_rights(R_DEBUG|R_ADMIN)) - return - var/obj/A = locateUID(href_list["modifyarmor"]) - if(!istype(A)) - return - A.var_edited = TRUE - var/list/armorlist = A.armor.getList() - var/list/displaylist - - var/result - do - displaylist = list() - for(var/key in armorlist) - displaylist += "[key] = [armorlist[key]]" - result = input(usr, "Select an armor type to modify..", "Modify armor") as null|anything in displaylist + "(ADD ALL)" + "(SET ALL)" + "(DONE)" - - if(result == "(DONE)") - break - else if(result == "(ADD ALL)" || result == "(SET ALL)") - var/new_amount = input(usr, result == "(ADD ALL)" ? "Enter armor to add to all types:" : "Enter new armor value for all types:", "Modify all types") as num|null - if(isnull(new_amount)) - continue - var/proper_amount = text2num(new_amount) - if(isnull(proper_amount)) - continue - for(var/key in armorlist) - armorlist[key] = (result == "(ADD ALL)" ? armorlist[key] : 0) + proper_amount - else if(result) - var/list/fields = splittext(result, " = ") - if(length(fields) != 2) - continue - var/type = fields[1] - if(isnull(armorlist[type])) - continue - var/new_amount = input(usr, "Enter new armor value for [type]:", "Modify [type]") as num|null - if(isnull(new_amount)) - continue - var/proper_amount = text2num(new_amount) - if(isnull(proper_amount)) - continue - armorlist[type] = proper_amount - while(result) - - if(!result || !A) - return TRUE - - A.armor = A.armor.setRating(armorlist[MELEE], armorlist[BULLET], armorlist[LASER], armorlist[ENERGY], armorlist[BOMB], armorlist[RAD], armorlist[FIRE], armorlist[ACID], armorlist[MAGIC]) - - log_admin("[key_name(usr)] modified the armor on [A] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]") - message_admins("[key_name(usr)] modified the armor on [A] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]") - return TRUE - - else if(href_list["addreagent"]) /* Made on /TG/, credit to them. */ - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/atom/A = locateUID(href_list["addreagent"]) - - if(!A.reagents) - var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num - if(amount) - A.create_reagents(amount) - - if(A.reagents) - var/chosen_id - var/list/reagent_options = sortAssoc(GLOB.chemical_reagents_list) - switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) - if("Enter ID") - var/valid_id - while(!valid_id) - chosen_id = stripped_input(usr, "Enter the ID of the reagent you want to add.") - if(!chosen_id) //Get me out of here! - break - for(var/ID in reagent_options) - if(ID == chosen_id) - valid_id = 1 - if(!valid_id) - to_chat(usr, "A reagent with that ID doesn't exist!") - if("Choose ID") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_options - if(chosen_id) - var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num - if(amount) - A.reagents.add_reagent(chosen_id, amount) - log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") - message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") - - else if(href_list["editreagents"]) - if(!check_rights(R_DEBUG|R_ADMIN)) - return - - var/atom/A = locateUID(href_list["editreagents"]) - - try_open_reagent_editor(A) - - else if(href_list["explode"]) - if(!check_rights(R_DEBUG|R_EVENT)) return - - var/atom/A = locateUID(href_list["explode"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") - return - - src.cmd_admin_explosion(A) - href_list["datumrefresh"] = href_list["explode"] - - else if(href_list["emp"]) - if(!check_rights(R_DEBUG|R_EVENT)) return - - var/atom/A = locateUID(href_list["emp"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") - return - - src.cmd_admin_emp(A) - href_list["datumrefresh"] = href_list["emp"] - - else if(href_list["mark_object"]) - if(!check_rights(0)) return - - var/datum/D = locateUID(href_list["mark_object"]) - if(!istype(D)) - to_chat(usr, "This can only be done to instances of type /datum") - return - - src.holder.marked_datum = D - href_list["datumrefresh"] = href_list["mark_object"] - - else if(href_list["proc_call"]) - if(!check_rights(R_PROCCALL)) - return - - var/T = locateUID(href_list["proc_call"]) - - if(T) - callproc_datum(T) - - else if(href_list["jump_to"]) - if(!check_rights(R_ADMIN)) - return - - var/atom/A = locateUID(href_list["jump_to"]) - var/turf/T = get_turf(A) - if(T) - usr.client.jumptoturf(T) - href_list["datumrefresh"] = href_list["jump_to"] - - - else if(href_list["rotatedatum"]) - if(!check_rights(R_DEBUG|R_ADMIN)) return - - var/atom/A = locateUID(href_list["rotatedatum"]) - if(!istype(A)) - to_chat(usr, "This can only be done to instances of type /atom") - return - - switch(href_list["rotatedir"]) - if("right") A.dir = turn(A.dir, -45) - if("left") A.dir = turn(A.dir, 45) - - message_admins("[key_name_admin(usr)] has rotated \the [A]") - log_admin("[key_name(usr)] has rotated \the [A]") - href_list["datumrefresh"] = href_list["rotatedatum"] - - else if(href_list["addlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locateUID(href_list["addlanguage"]) - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob") - return - - var/new_language = input("Please choose a language to add.","Language",null) as null|anything in GLOB.all_languages - - if(!new_language) - return - - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(H.add_language(new_language, TRUE)) - to_chat(usr, "Added [new_language] to [H].") - message_admins("[key_name_admin(usr)] has given [key_name_admin(H)] the language [new_language]") - log_admin("[key_name(usr)] has given [key_name(H)] the language [new_language]") - else - to_chat(usr, "Mob already knows that language.") - - else if(href_list["remlanguage"]) - if(!check_rights(R_SPAWN)) return - - var/mob/H = locateUID(href_list["remlanguage"]) - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob") - return - - if(!length(H.languages)) - to_chat(usr, "This mob knows no languages.") - return - - var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages - - if(!rem_language) - return - - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(H.remove_language(rem_language.name, TRUE)) - to_chat(usr, "Removed [rem_language] from [H].") - message_admins("[key_name_admin(usr)] has removed language [rem_language] from [key_name_admin(H)]") - log_admin("[key_name(usr)] has removed language [rem_language] from [key_name(H)]") - else - to_chat(usr, "Mob doesn't know that language.") - - else if(href_list["addverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/living/H = locateUID(href_list["addverb"]) - - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living") - return - var/list/possibleverbs = list() - possibleverbs += "Cancel" // One for the top... - possibleverbs += typesof(/mob/proc,/mob/verb,/mob/living/proc,/mob/living/verb) - switch(H.type) - if(/mob/living/carbon/human) - possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc) - if(/mob/living/silicon/robot) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb) - if(/mob/living/silicon/ai) - possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb) - possibleverbs -= H.verbs - possibleverbs += "Cancel" // ...And one for the bottom - - var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - if(!verb || verb == "Cancel") - return - else - add_verb(H, verb) - message_admins("[key_name_admin(usr)] has given [key_name_admin(H)] the verb [verb]") - log_admin("[key_name(usr)] has given [key_name(H)] the verb [verb]") - - else if(href_list["remverb"]) - if(!check_rights(R_DEBUG)) return - - var/mob/H = locateUID(href_list["remverb"]) - - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob") - return - var/verb = input("Please choose a verb to remove.","Verbs",null) as null|anything in H.verbs - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - if(!verb) - return - else - remove_verb(H, verb) - message_admins("[key_name_admin(usr)] has removed verb [verb] from [key_name_admin(H)]") - log_admin("[key_name(usr)] has removed verb [verb] from [key_name(H)]") - - else if(href_list["addorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locateUID(href_list["addorgan"]) - if(!istype(M)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/new_organ = tgui_input_list(usr, "Please choose an organ to add.", "Organ", subtypesof(/obj/item/organ)) - if(!new_organ) - return - - if(!M) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(locateUID(new_organ) in M.internal_organs) - to_chat(usr, "Mob already has that organ.") - return - var/obj/item/organ/internal/organ = new new_organ - organ.insert(M) - message_admins("[key_name_admin(usr)] has given [key_name_admin(M)] the organ [new_organ]") - log_admin("[key_name(usr)] has given [key_name(M)] the organ [new_organ]") - - else if(href_list["remorgan"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/M = locateUID(href_list["remorgan"]) - if(!istype(M)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/obj/item/organ/internal/rem_organ = tgui_input_list(usr, "Please choose an organ to remove.", "Organ", M.internal_organs) - - if(!M) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(!(rem_organ in M.internal_organs)) - to_chat(usr, "Mob does not have that organ.") - return - - to_chat(usr, "Removed [rem_organ] from [M].") - rem_organ.remove(M) - message_admins("[key_name_admin(usr)] has removed the organ [rem_organ] from [key_name_admin(M)]") - log_admin("[key_name(usr)] has removed the organ [rem_organ] from [key_name(M)]") - qdel(rem_organ) - - else if(href_list["regenerateicons"]) - if(!check_rights(0)) return - - var/mob/M = locateUID(href_list["regenerateicons"]) - if(!ismob(M)) - to_chat(usr, "This can only be done to instances of type /mob") - return - M.regenerate_icons() - - else if(href_list["adjustDamage"] && href_list["mobToDamage"]) - if(!check_rights(R_DEBUG|R_ADMIN|R_EVENT)) return - - var/mob/living/L = locateUID(href_list["mobToDamage"]) - if(!istype(L)) return - - var/Text = href_list["adjustDamage"] - - var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num - - if(!L) - to_chat(usr, "Mob doesn't exist anymore") - return - - switch(Text) - if("brute") - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.adjustBruteLoss(amount, robotic = TRUE) - else - L.adjustBruteLoss(amount) - if("fire") - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.adjustFireLoss(amount, robotic = TRUE) - else - L.adjustFireLoss(amount) - if("toxin") - L.adjustToxLoss(amount) - if("oxygen") - L.adjustOxyLoss(amount) - if("brain") - L.adjustBrainLoss(amount) - if("clone") - L.adjustCloneLoss(amount) - if("stamina") - L.adjustStaminaLoss(amount) - else - to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]") - return - - if(amount != 0) - log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]") - message_admins("[key_name_admin(usr)] dealt [amount] amount of [Text] damage to [L]") - href_list["datumrefresh"] = href_list["mobToDamage"] - - else if(href_list["traitmod"]) - if(!check_rights(NONE)) - return - var/datum/A = locateUID(href_list["traitmod"]) - if(!istype(A)) - return - holder.modify_traits(A) - - if(href_list["addcomponent"]) - if(!check_rights(NONE)) - return - var/datum/target = locateUID(href_list["addcomponent"]) - if(!target) - return - var/list/names = list() - var/list/componentsubtypes = sortList(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc)) - names += "---Components---" - names += componentsubtypes - names += "---Elements---" - names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc)) - - var/result = tgui_input_list(usr, "Choose a component/element to add", "Add Component", names) - if(isnull(result)) - return - if(!usr || result == "---Components---" || result == "---Elements---") - return - - if(QDELETED(src)) - to_chat(usr, "That thing doesn't exist anymore!", confidential = TRUE) - return - - var/list/lst = get_callproc_args() - if(!lst) - return - - var/datumname = "error" - lst.Insert(1, result) - if(result in componentsubtypes) - datumname = "component" - target._AddComponent(lst) - else - datumname = "element" - target._AddElement(lst) - log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(target)].") - message_admins("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(target)].") - if(href_list["removecomponent"] || href_list["massremovecomponent"]) - if(!check_rights(NONE)) - return - var/datum/target = href_list["removecomponent"] ? locateUID(href_list["removecomponent"]) : locateUID(href_list["massremovecomponent"]) - if(!target) - return - var/mass_remove = href_list["massremovecomponent"] - var/list/components = target.datum_components.Copy() - var/list/names = list() - names += "---Components---" - if(length(components)) - names += sortList(components, GLOBAL_PROC_REF(cmp_typepaths_asc)) - names += "---Elements---" - // We have to list every element here because there is no way to know what element is on this object without doing some sort of hack. - names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc)) - var/path = tgui_input_list(usr, "Choose a component/element to remove. All elements listed here may not be on the datum.", "Remove element", names) - if(isnull(path)) - return - if(!usr || path == "---Components---" || path == "---Elements---") - return - if(QDELETED(src)) - to_chat(usr, "That thing doesn't exist anymore!") - return - var/list/targets_to_remove_from = list(target) - if(mass_remove) - var/method = vv_subtype_prompt(target.type) - targets_to_remove_from = get_all_of_type(target.type, method) - - if(alert(usr, "Are you sure you want to mass-delete [path] on [target.type]?", "Mass Remove Confirmation", "Yes", "No") == "No") - return - - var/list/ele_list = list() - if(ispath(path, /datum/element)) - ele_list = get_callproc_args() - ele_list.Insert(1, path) - for(var/datum/target_to_remove_from as anything in targets_to_remove_from) - if(ispath(path, /datum/element)) - target._RemoveElement(ele_list) - else - var/list/components_actual = target_to_remove_from.GetComponents(path) - for(var/to_delete in components_actual) - qdel(to_delete) - - message_admins("[key_name_admin(usr)] has [mass_remove ? "mass" : ""] removed [path] component from [mass_remove ? target.type : key_name_admin(target)].") + // Refresh the VV if something asked us to if(href_list["datumrefresh"]) var/datum/DAT = locateUID(href_list["datumrefresh"]) if(!istype(DAT, /datum) && !isclient(DAT)) return src.debug_variables(DAT) - if(href_list["manipcolours"]) - if(!check_rights(R_DEBUG)) - return - - var/datum/target = locateUID(href_list["manipcolours"]) - if(!(isatom(target) || isclient(target))) - to_chat(usr, "This can only be used on atoms and clients") - return - - message_admins("[key_name_admin(usr)] is manipulating the colour matrix for [target]") - var/datum/ui_module/colour_matrix_tester/CMT = new(target=target) - CMT.ui_interact(usr) - - if(href_list["grantdeadchatcontrol"]) - if(!check_rights(R_EVENT)) - return - - var/atom/movable/A = locateUID(href_list["grantdeadchatcontrol"]) - if(!istype(A)) - return - - if(!GLOB.dsay_enabled) - // TODO verify what happens when deadchat is muted - to_chat(usr, "Deadchat is globally muted, un-mute deadchat before enabling this.") - return - - if(A.GetComponent(/datum/component/deadchat_control)) - to_chat(usr, "[A] is already under deadchat control!") - return - - var/control_mode = input(usr, "Please select the control mode","Deadchat Control", null) as null|anything in list("democracy", "anarchy") - - var/selected_mode - switch(control_mode) - if("democracy") - selected_mode = DEADCHAT_DEMOCRACY_MODE - if("anarchy") - selected_mode = DEADCHAT_ANARCHY_MODE - else - return - - var/cooldown = input(usr, "Please enter a cooldown time in seconds. For democracy, it's the time between actions (must be greater than zero). For anarchy, it's the time between each user's actions, or -1 for no cooldown.", "Cooldown", null) as null|num - if(isnull(cooldown) || (cooldown == -1 && selected_mode == DEADCHAT_DEMOCRACY_MODE)) - return - if(cooldown < 0 && selected_mode == DEADCHAT_DEMOCRACY_MODE) - to_chat(usr, "The cooldown for democracy mode must be greater than zero.") - return - if(cooldown == -1) - cooldown = 0 - else - cooldown = cooldown SECONDS - - A.deadchat_plays(selected_mode, cooldown) - message_admins("[key_name_admin(usr)] provided deadchat control to [A].") - - if(href_list["removedeadchatcontrol"]) - if(!check_rights(R_EVENT)) - return - - var/atom/movable/A = locateUID(href_list["removedeadchatcontrol"]) - if(!istype(A)) - return - - if(!A.GetComponent(/datum/component/deadchat_control)) - to_chat(usr, "[A] is not currently under deadchat control!") - return - - A.stop_deadchat_plays() - message_admins("[key_name_admin(usr)] removed deadchat control from [A].") - /client/proc/view_var_Topic_list(href, href_list, hsrc) if(href_list["VarsList"]) debug_variables(locate(href_list["VarsList"])) diff --git a/code/datums/vv_core_topics.dm b/code/datums/vv_core_topics.dm new file mode 100644 index 00000000000..b7b5e9ec96c --- /dev/null +++ b/code/datums/vv_core_topics.dm @@ -0,0 +1,136 @@ +/// Core topics are VV topics which should work even if the code responsible +/// for processing vv topics for that datum is runtiming. They're kept separately +/// from [/datum/proc/vv_do_topic] for that reason. +/client/proc/vv_core_topics(datum/target, href_list) + if(href_list[VV_HK_JUMP_TO]) + if(!check_rights(R_ADMIN)) + return + + var/turf/T = get_turf(target) + if(T) + jumptoturf(T) + href_list["datumrefresh"] = target.UID() + if(href_list["varnameedit"] && href_list["datumedit"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locateUID(href_list["datumedit"]) + if(!istype(D,/datum) && !isclient(D)) + to_chat(usr, "This can only be used on instances of types /client or /datum.") + return + + modify_variables(D, href_list["varnameedit"], 1) + if(href_list["varnamechange"] && href_list["datumchange"]) + if(!check_rights(R_VAREDIT)) return + + var/D = locateUID(href_list["datumchange"]) + if(!istype(D,/datum) && !isclient(D)) + to_chat(usr, "This can only be used on instances of types /client or /datum.") + return + + modify_variables(D, href_list["varnamechange"], 0) + if(href_list["varnamemass"] && href_list["datummass"]) + if(!check_rights(R_VAREDIT)) return + + var/atom/A = locateUID(href_list["datummass"]) + if(!istype(A)) + to_chat(usr, "This can only be used on instances of type /atom.") + return + + cmd_mass_modify_object_variables(A, href_list["varnamemass"]) + if(href_list[VV_HK_DELETE]) + if(!check_rights(R_DEBUG, 0)) + return + + admin_delete(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_MARK_OBJECT]) + if(!check_rights(0)) return + + if(!istype(target)) + to_chat(usr, "This can only be done to instances of type /datum.") + return + + src.holder.marked_datum = target + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_PROC_CALL]) + if(!check_rights(R_PROCCALL)) + return + + if(target) + callproc_datum(target) + if(href_list[VV_HK_ADDCOMPONENT]) + if(!check_rights(NONE)) + return + + var/list/names = list() + var/list/componentsubtypes = sortList(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc)) + names += "---Components---" + names += componentsubtypes + names += "---Elements---" + names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc)) + + var/result = tgui_input_list(usr, "Choose a component/element to add", "Add Component", names) + if(isnull(result)) + return + if(!usr || result == "---Components---" || result == "---Elements---") + return + + if(QDELETED(src)) + to_chat(usr, "That thing doesn't exist anymore!", confidential = TRUE) + return + + var/list/lst = get_callproc_args() + if(!lst) + return + + var/datumname = "error" + lst.Insert(1, result) + if(result in componentsubtypes) + datumname = "component" + target._AddComponent(lst) + else + datumname = "element" + target._AddElement(lst) + log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(target)].") + message_admins("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(target)].") + if(href_list[VV_HK_REMOVECOMPONENT] || href_list[VV_HK_MASSREMOVECOMPONENT]) + if(!check_rights(NONE)) + return + var/mass_remove = href_list[VV_HK_MASSREMOVECOMPONENT] + var/list/components = target.datum_components.Copy() + var/list/names = list() + names += "---Components---" + if(length(components)) + names += sortList(components, GLOBAL_PROC_REF(cmp_typepaths_asc)) + names += "---Elements---" + // We have to list every element here because there is no way to know what element is on this object without doing some sort of hack. + names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc)) + var/path = tgui_input_list(usr, "Choose a component/element to remove. All elements listed here may not be on the datum.", "Remove element", names) + if(isnull(path)) + return + if(!usr || path == "---Components---" || path == "---Elements---") + return + if(QDELETED(src)) + to_chat(usr, "That thing doesn't exist anymore!") + return + var/list/targets_to_remove_from = list(target) + if(mass_remove) + var/method = vv_subtype_prompt(target.type) + targets_to_remove_from = get_all_of_type(target.type, method) + + if(tgui_alert(usr, "Are you sure you want to mass-delete [path] on [target.type]?", "Mass Remove Confirmation", list("Yes", "No")) != "Yes") + return + + var/list/ele_list = list() + if(ispath(path, /datum/element)) + ele_list = get_callproc_args() + ele_list.Insert(1, path) + for(var/datum/target_to_remove_from as anything in targets_to_remove_from) + if(ispath(path, /datum/element)) + target._RemoveElement(ele_list) + else + var/list/components_actual = target_to_remove_from.GetComponents(path) + for(var/to_delete in components_actual) + qdel(to_delete) + + message_admins("[key_name_admin(usr)] has [mass_remove ? "mass" : ""] removed [path] component from [mass_remove ? target.type : key_name_admin(target)].") diff --git a/code/game/atom_vv.dm b/code/game/atom_vv.dm new file mode 100644 index 00000000000..d3feb00216d --- /dev/null +++ b/code/game/atom_vv.dm @@ -0,0 +1,99 @@ +/atom/vv_edit_var(var_name, var_value) + . = ..() + switch(var_name) + if("light_power", "light_range", "light_color") + update_light() + if("color") + add_atom_colour(color, ADMIN_COLOUR_PRIORITY) + +/atom/vv_get_dropdown() + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_MANIPULATE_COLOR_MATRIX, "Manipulate Colour Matrix") + var/turf/curturf = get_turf(src) + if(curturf) + . += "" + VV_DROPDOWN_OPTION(VV_HK_ADDREAGENT, "Add reagent") + VV_DROPDOWN_OPTION(VV_HK_EDITREAGENTS, "Edit reagents") + VV_DROPDOWN_OPTION(VV_HK_EXPLODE, "Trigger explosion") + VV_DROPDOWN_OPTION(VV_HK_EMP, "Trigger EM pulse") + +/atom/vv_get_header() + . = ..() + . += "[src]" + if(dir) + . += "
<< [dir2text(dir)] >>" + +/atom/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list["rotatedatum"]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + switch(href_list["rotatedir"]) + if("right") dir = turn(dir, -45) + if("left") dir = turn(dir, 45) + + message_admins("[key_name_admin(usr)] has rotated \the [src]") + log_admin("[key_name(usr)] has rotated \the [src]") + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_EXPLODE]) + if(!check_rights(R_DEBUG|R_EVENT)) + return + + usr.client.cmd_admin_explosion(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_EMP]) + if(!check_rights(R_DEBUG|R_EVENT)) + return + + usr.client.cmd_admin_emp(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_ADDREAGENT]) /* Made on /TG/, credit to them. */ + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + if(!reagents) + var/amount = input(usr, "Specify the reagent size of [src]", "Set Reagent Size", 50) as num + if(amount) + create_reagents(amount) + + if(reagents) + var/chosen_id + var/list/reagent_options = sortAssoc(GLOB.chemical_reagents_list) + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + chosen_id = stripped_input(usr, "Enter the ID of the reagent you want to add.") + if(!chosen_id) //Get me out of here! + break + for(var/ID in reagent_options) + if(ID == chosen_id) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_options + if(chosen_id) + var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", reagents.maximum_volume) as num + if(amount) + reagents.add_reagent(chosen_id, amount) + log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [src]") + message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to \the [src]") + if(href_list[VV_HK_EDITREAGENTS]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + usr.client.try_open_reagent_editor(src) + if(href_list[VV_HK_MANIPULATE_COLOR_MATRIX]) + if(!check_rights(R_DEBUG)) + return + + message_admins("[key_name_admin(usr)] is manipulating the colour matrix for [src]") + var/datum/ui_module/colour_matrix_tester/CMT = new(target=src) + CMT.ui_interact(usr) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c0cb695e5e5..31df2551846 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -505,7 +505,7 @@ * * Arguments: * - updates: A set of bitflags dictating what should be updated. Defaults to [ALL] - * + * * Supported bitflags: UPDATE_NAME, UPDATE_DESC, UPDATE_ICON */ /atom/proc/update_appearance(updates=ALL) @@ -540,7 +540,7 @@ * * Arguments: * - updates: A set of bitflags dictating what should be updated. Defaults to [ALL] - * + * * Supported bitflags: UPDATE_ICON_STATE, UPDATE_OVERLAYS */ /atom/proc/update_icon(updates=ALL) @@ -1258,25 +1258,6 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/speech_bubble(bubble_state = "", bubble_loc = src, list/bubble_recipients = list()) return -/atom/vv_edit_var(var_name, var_value) - . = ..() - switch(var_name) - if("light_power", "light_range", "light_color") - update_light() - if("color") - add_atom_colour(color, ADMIN_COLOUR_PRIORITY) - -/atom/vv_get_dropdown() - . = ..() - .["Manipulate Colour Matrix"] = "byond://?_src_=vars;manipcolours=[UID()]" - var/turf/curturf = get_turf(src) - if(curturf) - .["Jump to turf"] = "byond://?_src_=holder;adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]" - .["Add reagent"] = "byond://?_src_=vars;addreagent=[UID()]" - .["Edit reagents"] = "byond://?_src_=vars;editreagents=[UID()]" - .["Trigger explosion"] = "byond://?_src_=vars;explode=[UID()]" - .["Trigger EM pulse"] = "byond://?_src_=vars;emp=[UID()]" - /atom/proc/AllowDrop() return FALSE diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 609b1a30234..5890ac77d51 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -961,14 +961,6 @@ /atom/movable/proc/stop_deadchat_plays() DeleteComponent(/datum/component/deadchat_control) -/atom/movable/vv_get_dropdown() - . = ..() - if(!GetComponent(/datum/component/deadchat_control)) - .["Give deadchat control"] = "byond://?_src_=vars;grantdeadchatcontrol=[UID()]" - else - .["Remove deadchat control"] = "byond://?_src_=vars;removedeadchatcontrol=[UID()]" - - //Update the screentip to reflect what we're hovering over /atom/movable/MouseEntered(location, control, params) if(invisibility > usr.see_invisible) diff --git a/code/game/movable_vv.dm b/code/game/movable_vv.dm new file mode 100644 index 00000000000..0762a4e9e63 --- /dev/null +++ b/code/game/movable_vv.dm @@ -0,0 +1,67 @@ +#define VV_HK_GIVE_DEADCHAT_CONTROL "grantdeadchatcontrol" +#define VV_HK_REMOVE_DEADCHAT_CONTROL "removedeadchatcontrol" + +/atom/movable/vv_get_dropdown() + . = ..() + if(!GetComponent(/datum/component/deadchat_control)) + VV_DROPDOWN_OPTION(VV_HK_GIVE_DEADCHAT_CONTROL, "Give deadchat control") + else + VV_DROPDOWN_OPTION(VV_HK_REMOVE_DEADCHAT_CONTROL, "Remove deadchat control") + +/atom/movable/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list[VV_HK_GIVE_DEADCHAT_CONTROL]) + if(!check_rights(R_EVENT)) + return + + if(!GLOB.dsay_enabled) + // TODO verify what happens when deadchat is muted + to_chat(usr, "Deadchat is globally muted, un-mute deadchat before enabling this.") + return + + if(GetComponent(/datum/component/deadchat_control)) + to_chat(usr, "[src] is already under deadchat control!") + return + + var/control_mode = tgui_input_list(usr, "Please select the control mode", "Deadchat Control", list("Democracy", "Anarchy")) + + var/selected_mode + switch(control_mode) + if("Democracy") + selected_mode = DEADCHAT_DEMOCRACY_MODE + if("Anarchy") + selected_mode = DEADCHAT_ANARCHY_MODE + else + return + + var/cooldown = tgui_input_number(usr, "Please enter a cooldown time in seconds. For Democracy, it's the time between actions (must be greater than zero). For Anarchy, it's the time between each user's actions, or -1 for no cooldown.", "Cooldown") + if(isnull(cooldown) || (cooldown == -1 && selected_mode == DEADCHAT_DEMOCRACY_MODE)) + return + if(cooldown < 0 && selected_mode == DEADCHAT_DEMOCRACY_MODE) + to_chat(usr, "The cooldown for Democracy mode must be greater than zero.") + return + if(cooldown == -1) + cooldown = 0 + else + cooldown = cooldown SECONDS + + deadchat_plays(selected_mode, cooldown) + message_admins("[key_name_admin(usr)] provided deadchat control to [src].") + + if(href_list[VV_HK_REMOVE_DEADCHAT_CONTROL]) + if(!check_rights(R_EVENT)) + return + + if(!GetComponent(/datum/component/deadchat_control)) + to_chat(usr, "[src] is not currently under deadchat control!") + return + + stop_deadchat_plays() + message_admins("[key_name_admin(usr)] removed deadchat control from [src].") + +#undef VV_HK_GIVE_DEADCHAT_CONTROL +#undef VV_HK_REMOVE_DEADCHAT_CONTROL diff --git a/code/game/objects/obj_vv.dm b/code/game/objects/obj_vv.dm new file mode 100644 index 00000000000..c492a24843d --- /dev/null +++ b/code/game/objects/obj_vv.dm @@ -0,0 +1,120 @@ +/obj/vv_get_dropdown() + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_DELALL, "Delete all of type") + if(!speed_process) + VV_DROPDOWN_OPTION(VV_HK_MAKESPEEDY, "Make speed process") + else + VV_DROPDOWN_OPTION(VV_HK_MAKENORMALSPEED, "Make normal process") + VV_DROPDOWN_OPTION(VV_HK_MODIFYARMOR, "Modify armor values") + +/obj/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list[VV_HK_DELALL]) + if(!check_rights(R_DEBUG|R_SERVER)) + return + + var/action_type = tgui_alert(usr, "Strict type ([type]) or type and all subtypes?", "Select", list("Strict type", "Type and Subtypes", "Cancel")) + if(action_type == "Cancel" || !action_type) + return + + if(tgui_alert(usr, "Are you really sure you want to delete all objects of type [type]?", "Confirm", list("Yes", "No")) != "Yes") + return + + if(tgui_alert("Second confirmation required. Delete?", "Confirm", list("Yes", "No")) != "Yes") + return + + var/O_type = type + switch(action_type) + if("Strict type") + var/i = 0 + for(var/obj/Obj in world) + if(Obj.type == O_type) + i++ + qdel(Obj) + if(!i) + to_chat(usr, "No objects of this type exist.") + return + log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)") + message_admins("[key_name_admin(usr)] deleted all objects of type [O_type] ([i] objects deleted)") + if("Type and Subtypes") + var/i = 0 + for(var/obj/Obj in world) + if(istype(Obj, O_type)) + i++ + qdel(Obj) + if(!i) + to_chat(usr, "No objects of this type exist.") + return + log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") + message_admins("[key_name_admin(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)") + + if(href_list[VV_HK_MAKESPEEDY]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + var_edited = TRUE + makeSpeedProcess() + log_admin("[key_name(usr)] has made [src] speed process") + message_admins("[key_name(usr)] has made [src] speed process") + if(href_list[VV_HK_MAKENORMALSPEED]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + var_edited = TRUE + makeNormalProcess() + log_admin("[key_name(usr)] has made [src] process normally") + message_admins("[key_name(usr)] has made [src] process normally") + if(href_list[VV_HK_MODIFYARMOR]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + var_edited = TRUE + var/list/armorlist = armor.getList() + var/list/displaylist + + var/result + do + displaylist = list() + for(var/key in armorlist) + displaylist += "[key] = [armorlist[key]]" + result = input(usr, "Select an armor type to modify..", "Modify armor") as null|anything in displaylist + "(ADD ALL)" + "(SET ALL)" + "(DONE)" + + if(result == "(DONE)") + break + else if(result == "(ADD ALL)" || result == "(SET ALL)") + var/new_amount = tgui_input_number(usr, result == "(ADD ALL)" ? "Enter armor to add to all types:" : "Enter new armor value for all types:", "Modify all types") + if(isnull(new_amount)) + continue + var/proper_amount = text2num(new_amount) + if(isnull(proper_amount)) + continue + for(var/key in armorlist) + armorlist[key] = (result == "(ADD ALL)" ? armorlist[key] : 0) + proper_amount + else if(result) + var/list/fields = splittext(result, " = ") + if(length(fields) != 2) + continue + var/type = fields[1] + if(isnull(armorlist[type])) + continue + var/new_amount = tgui_input_number(usr, "Enter new armor value for [type]:", "Modify [type]") + if(isnull(new_amount)) + continue + var/proper_amount = text2num(new_amount) + if(isnull(proper_amount)) + continue + armorlist[type] = proper_amount + while(result) + + if(!result || !QDELETED(src)) + return TRUE + + armor = armor.setRating(armorlist[MELEE], armorlist[BULLET], armorlist[LASER], armorlist[ENERGY], armorlist[BOMB], armorlist[RAD], armorlist[FIRE], armorlist[ACID], armorlist[MAGIC]) + + log_admin("[key_name(usr)] modified the armor on [src] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]") + message_admins("[key_name(usr)] modified the armor on [src] to: melee = [armorlist[MELEE]], bullet = [armorlist[BULLET]], laser = [armorlist[LASER]], energy = [armorlist[ENERGY]], bomb = [armorlist[BOMB]], rad = [armorlist[RAD]], fire = [armorlist[FIRE]], acid = [armorlist[ACID]], magic = [armorlist[MAGIC]]") diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 66661d0d0d4..56535a23a42 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -236,15 +236,6 @@ START_PROCESSING(SSobj, src) STOP_PROCESSING(SSfastprocess, src) -/obj/vv_get_dropdown() - . = ..() - .["Delete all of type"] = "byond://?_src_=vars;delall=[UID()]" - if(!speed_process) - .["Make speed process"] = "byond://?_src_=vars;makespeedy=[UID()]" - else - .["Make normal process"] = "byond://?_src_=vars;makenormalspeed=[UID()]" - .["Modify armor values"] = "byond://?_src_=vars;modifyarmor=[UID()]" - /obj/proc/check_uplink_validity() return TRUE diff --git a/code/modules/mob/living/carbon/carbon_procs.dm b/code/modules/mob/living/carbon/carbon_procs.dm index 544f7337b19..25b9887143f 100644 --- a/code/modules/mob/living/carbon/carbon_procs.dm +++ b/code/modules/mob/living/carbon/carbon_procs.dm @@ -1454,3 +1454,78 @@ so that different stomachs can handle things in different ways VB*/ /mob/living/carbon/proc/get_thermal_protection() // Xenos got nothin return 0 + +/mob/living/carbon/vv_get_dropdown() + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_GIVEMARTIALART, "Give Martial Art") + VV_DROPDOWN_OPTION(VV_HK_ADDORGAN, "Add Organ") + VV_DROPDOWN_OPTION(VV_HK_REMORGAN, "Remove Organ") + +/mob/living/carbon/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list[VV_HK_GIVEMARTIALART]) + if(!check_rights(R_SERVER|R_EVENT)) + return + + var/list/artpaths = subtypesof(/datum/martial_art) + var/list/artnames = list() + for(var/i in artpaths) + var/datum/martial_art/M = i + artnames[initial(M.name)] = M + + var/result = tgui_input_list(usr, "Choose the martial art to teach", "JUDO CHOP", artnames) + if(!usr) + return + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + if(result) + var/chosenart = artnames[result] + var/datum/martial_art/MA = new chosenart + MA.teach(src) + + href_list["datumrefresh"] = UID() + else if(href_list[VV_HK_ADDORGAN]) + if(!check_rights(R_SPAWN)) + return + + var/new_organ = tgui_input_list(usr, "Please choose an organ to add.", "Organ", subtypesof(/obj/item/organ)) + if(!new_organ) + return + + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + if(locateUID(new_organ) in internal_organs) + to_chat(usr, "Mob already has that organ.") + return + var/obj/item/organ/internal/organ = new new_organ + organ.insert(src) + message_admins("[key_name_admin(usr)] has given [key_name_admin(src)] the organ [new_organ]") + log_admin("[key_name(usr)] has given [key_name(src)] the organ [new_organ]") + + else if(href_list[VV_HK_REMORGAN]) + if(!check_rights(R_SPAWN)) return + + var/obj/item/organ/internal/rem_organ = tgui_input_list(usr, "Please choose an organ to remove.", "Organ", internal_organs) + + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + if(!(rem_organ in internal_organs)) + to_chat(usr, "Mob does not have that organ.") + return + + to_chat(usr, "Removed [rem_organ] from [src].") + rem_organ.remove(src) + message_admins("[key_name_admin(usr)] has removed the organ [rem_organ] from [key_name_admin(src)]") + log_admin("[key_name(usr)] has removed the organ [rem_organ] from [key_name(src)]") + qdel(rem_organ) diff --git a/code/modules/mob/living/carbon/human/human_vv.dm b/code/modules/mob/living/carbon/human/human_vv.dm new file mode 100644 index 00000000000..9592dc2e963 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human_vv.dm @@ -0,0 +1,35 @@ +/mob/living/carbon/human/vv_get_dropdown() + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_MAKE_SKELETON, "Make 2spooky") + VV_DROPDOWN_OPTION(VV_HK_HALLUCINATE, "Hallucinate") + +/mob/living/carbon/human/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list[VV_HK_MAKE_SKELETON]) + if(!check_rights(R_SERVER|R_EVENT)) + return + + if(tgui_alert(usr, "Are you sure you want to turn this mob into a skeleton?", "Confirm Skeleton Transformation", list("Yes", "No")) != "Yes") + return + + makeSkeleton() + message_admins("[key_name(usr)] has turned [key_name(src)] into a skeleton") + log_admin("[key_name_admin(usr)] has turned [key_name_admin(src)] into a skeleton") + href_list["datumrefresh"] = UID() + + if(href_list[VV_HK_HALLUCINATE]) + if(!check_rights(R_SERVER | R_EVENT)) + return + + var/haltype = tgui_input_list(usr, "Select Hallucination Type", "Hallucinate", (subtypesof(/obj/effect/hallucination) + subtypesof(/datum/hallucination_manager))) + if(!haltype) + return + invoke_hallucination(haltype) + message_admins("[key_name(usr)] has given [key_name(src)] the [haltype] hallucination") + log_admin("[key_name_admin(usr)] has given [key_name_admin(src)] the [haltype] hallucination") + href_list["datumrefresh"] = UID() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fed9832c338..4a83de3e4d5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1152,6 +1152,68 @@ if(A.light_range > 0) A.extinguish_light(force) +/mob/living/vv_get_header() + . = ..() + . += {" +
+ BRUTE:[getBruteLoss()] + FIRE:[getFireLoss()] + TOXIN:[getToxLoss()] + OXY:[getOxyLoss()] + CLONE:[getCloneLoss()] + BRAIN:[getBrainLoss()] + STAMINA:[getStaminaLoss()] + + "} + +/mob/living/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + if(href_list["adjustDamage"]) + if(!check_rights(R_DEBUG|R_ADMIN|R_EVENT)) return + + var/Text = href_list["adjustDamage"] + var/amount = tgui_input_number(usr, "Deal how much damage to mob? (Negative values here heal)", "Adjust [Text]loss") + + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + switch(Text) + if("brute") + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.adjustBruteLoss(amount, robotic = TRUE) + else + adjustBruteLoss(amount) + if("fire") + if(ishuman(src)) + var/mob/living/carbon/human/H = src + H.adjustFireLoss(amount, robotic = TRUE) + else + adjustFireLoss(amount) + if("toxin") + adjustToxLoss(amount) + if("oxygen") + adjustOxyLoss(amount) + if("brain") + adjustBrainLoss(amount) + if("clone") + adjustCloneLoss(amount) + if("stamina") + adjustStaminaLoss(amount) + else + to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[src]") + return + + if(amount != 0) + log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [src]") + message_admins("[key_name_admin(usr)] dealt [amount] amount of [Text] damage to [src]") + href_list["datumrefresh"] = UID() + /mob/living/vv_edit_var(var_name, var_value) switch(var_name) if("stat") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index e37d3851545..affbb0a34b3 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1294,34 +1294,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ target += new_log -/mob/vv_get_dropdown() - . = ..() - .["Show player panel"] = "byond://?_src_=vars;mob_player_panel=[UID()]" - - .["Give Spell"] = "byond://?_src_=vars;give_spell=[UID()]" - .["Give Martial Art"] = "byond://?_src_=vars;givemartialart=[UID()]" - .["Give Disease"] = "byond://?_src_=vars;give_disease=[UID()]" - .["Toggle Godmode"] = "byond://?_src_=vars;godmode=[UID()]" - .["Toggle Build Mode"] = "byond://?_src_=vars;build_mode=[UID()]" - - .["Make 2spooky"] = "byond://?_src_=vars;make_skeleton=[UID()]" - .["Hallucinate"] = "byond://?_src_=vars;hallucinate=[UID()]" - - .["Assume Direct Control"] = "byond://?_src_=vars;direct_control=[UID()]" - .["Offer Control to Ghosts"] = "byond://?_src_=vars;offer_control=[UID()]" - .["Drop Everything"] = "byond://?_src_=vars;drop_everything=[UID()]" - - .["Regenerate Icons"] = "byond://?_src_=vars;regenerateicons=[UID()]" - .["Add Language"] = "byond://?_src_=vars;addlanguage=[UID()]" - .["Remove Language"] = "byond://?_src_=vars;remlanguage=[UID()]" - .["Add Organ"] = "byond://?_src_=vars;addorgan=[UID()]" - .["Remove Organ"] = "byond://?_src_=vars;remorgan=[UID()]" - - .["Add Verb"] = "byond://?_src_=vars;addverb=[UID()]" - .["Remove Verb"] = "byond://?_src_=vars;remverb=[UID()]" - - .["Gib"] = "byond://?_src_=vars;gib=[UID()]" - ///Can this mob resist (default FALSE) /mob/proc/can_resist() return FALSE //overridden in living.dm diff --git a/code/modules/mob/mob_vv.dm b/code/modules/mob/mob_vv.dm new file mode 100644 index 00000000000..5610695825a --- /dev/null +++ b/code/modules/mob/mob_vv.dm @@ -0,0 +1,180 @@ +/mob/vv_get_header() + . = ..() + . += "
[ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"]" + +/mob/vv_get_dropdown() + . = ..() + + VV_DROPDOWN_OPTION(VV_HK_MOB_PLAYER_PANEL, "Show player panel") + VV_DROPDOWN_OPTION(VV_HK_GIVE_SPELL, "Give Spell") + VV_DROPDOWN_OPTION(VV_HK_GIVE_DISEASE, "Give Disease") + VV_DROPDOWN_OPTION(VV_HK_GODMODE, "Toggle Godmode") + VV_DROPDOWN_OPTION(VV_HK_BUILD_MODE, "Toggle Build Mode") + VV_DROPDOWN_OPTION(VV_HK_DIRECT_CONTROL, "Assume Direct Control") + VV_DROPDOWN_OPTION(VV_HK_OFFER_CONTROL, "Offer Control to Ghosts") + VV_DROPDOWN_OPTION(VV_HK_DROP_EVERYTHING, "Drop Everything") + VV_DROPDOWN_OPTION(VV_HK_REGENERATEICONS, "Regenerate Icons") + VV_DROPDOWN_OPTION(VV_HK_ADDLANGUAGE, "Add Language") + VV_DROPDOWN_OPTION(VV_HK_REMLANGUAGE, "Remove Language") + VV_DROPDOWN_OPTION(VV_HK_ADDVERB, "Add Verb") + VV_DROPDOWN_OPTION(VV_HK_REMVERB, "Remove Verb") + VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib") + +/mob/vv_do_topic(list/href_list) + . = ..() + + if(!.) + return + + //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). + if(href_list["rename"]) + if(!check_rights(R_ADMIN)) + return + + var/new_name = reject_bad_name(sanitize(copytext_char(input(usr, "What would you like to name this mob?", "Input a name", real_name) as text|null, 1, MAX_NAME_LEN)), allow_numbers = TRUE) + if(!new_name || QDELETED(src)) + return + + message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(src)] to [new_name].") + rename_character(real_name, new_name) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_MOB_PLAYER_PANEL]) + if(!check_rights(R_ADMIN|R_MOD)) + return + + usr.client.holder.show_player_panel(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_GIVE_SPELL]) + if(!check_rights(R_SERVER|R_EVENT)) + return + + usr.client.give_spell(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_GIVE_DISEASE]) + if(!check_rights(R_SERVER|R_EVENT)) + return + + usr.client.give_disease(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_GODMODE]) + if(!check_rights(R_EVENT)) + return + + usr.client.cmd_admin_godmode(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_GIB]) + if(!check_rights(R_ADMIN|R_EVENT)) + return + + usr.client.cmd_admin_gib(src) + if(href_list[VV_HK_BUILD_MODE]) + if(!check_rights(R_BUILDMODE)) + return + + togglebuildmode(src) + href_list["datumrefresh"] = UID() + if(href_list[VV_HK_DROP_EVERYTHING]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + if(usr.client) + usr.client.cmd_admin_drop_everything(src) + if(href_list[VV_HK_DIRECT_CONTROL]) + if(!check_rights(R_DEBUG|R_ADMIN)) + return + + if(usr.client) + usr.client.cmd_assume_direct_control(src) + if(href_list[VV_HK_OFFER_CONTROL]) + if(!check_rights(R_ADMIN)) + return + + offer_control(src) + if(href_list[VV_HK_REGENERATEICONS]) + if(!check_rights(0)) + return + + regenerate_icons() + if(href_list[VV_HK_ADDLANGUAGE]) + if(!check_rights(R_SPAWN)) + return + + var/new_language = tgui_input_list(usr, "Please choose a language to add.", "Language", GLOB.all_languages) + + if(!new_language) + return + + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + if(add_language(new_language, TRUE)) + to_chat(usr, "Added [new_language] to [src].") + message_admins("[key_name_admin(usr)] has given [key_name_admin(src)] the language [new_language]") + log_admin("[key_name(usr)] has given [key_name(src)] the language [new_language]") + else + to_chat(usr, "Mob already knows that language.") + if(href_list[VV_HK_REMLANGUAGE]) + if(!check_rights(R_SPAWN)) + return + + if(!length(languages)) + to_chat(usr, "This mob knows no languages.") + return + + var/datum/language/rem_language = tgui_input_list(usr, "Please choose a language to remove.", "Language", src.languages) + + if(!rem_language) + return + + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + + if(remove_language(rem_language.name, TRUE)) + to_chat(usr, "Removed [rem_language] from [src].") + message_admins("[key_name_admin(usr)] has removed language [rem_language] from [key_name_admin(src)]") + log_admin("[key_name(usr)] has removed language [rem_language] from [key_name(src)]") + else + to_chat(usr, "Mob doesn't know that language.") + if(href_list[VV_HK_ADDVERB]) + if(!check_rights(R_DEBUG)) + return + + var/list/possibleverbs = list() + possibleverbs += "Cancel" // One for the top... + possibleverbs += typesof(/mob/proc, /mob/verb, /mob/living/proc, /mob/living/verb) + switch(type) // Horrid + if(/mob/living/carbon/human) + possibleverbs += typesof(/mob/living/carbon/proc, /mob/living/carbon/verb, /mob/living/carbon/human/verb, /mob/living/carbon/human/proc) + if(/mob/living/silicon/robot) + possibleverbs += typesof(/mob/living/silicon/proc, /mob/living/silicon/robot/proc, /mob/living/silicon/robot/verb) + if(/mob/living/silicon/ai) + possibleverbs += typesof(/mob/living/silicon/proc, /mob/living/silicon/ai/proc, /mob/living/silicon/ai/verb) + possibleverbs -= verbs + possibleverbs += "Cancel" // ...And one for the bottom + + var/verb = input("Select a verb!", "Verbs",null) as anything in possibleverbs + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + if(!verb || verb == "Cancel") + return + else + add_verb(src, verb) + message_admins("[key_name_admin(usr)] has given [key_name_admin(src)] the verb [verb]") + log_admin("[key_name(usr)] has given [key_name(src)] the verb [verb]") + if(href_list[VV_HK_REMVERB]) + if(!check_rights(R_DEBUG)) + return + + var/verb = tgui_input_list(usr, "Please choose a verb to remove.", "Verbs", src.verbs) + if(QDELETED(src)) + to_chat(usr, "Mob doesn't exist anymore.") + return + if(!verb) + return + else + remove_verb(src, verb) + message_admins("[key_name_admin(usr)] has removed verb [verb] from [key_name_admin(src)]") + log_admin("[key_name(usr)] has removed verb [verb] from [key_name(src)]") diff --git a/paradise.dme b/paradise.dme index 5a18e18b41b..ed3cb27b1fb 100644 --- a/paradise.dme +++ b/paradise.dme @@ -443,6 +443,7 @@ #include "code\datums\tgs_event_handler.dm" #include "code\datums\verb_callbacks.dm" #include "code\datums\vision_override.dm" +#include "code\datums\vv_core_topics.dm" #include "code\datums\actions\action.dm" #include "code\datums\actions\generic_action.dm" #include "code\datums\actions\innate_action.dm" @@ -796,9 +797,11 @@ #include "code\defines\procs\radio_procs.dm" #include "code\defines\procs\records.dm" #include "code\game\alternate_appearance.dm" +#include "code\game\atom_vv.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" #include "code\game\data_huds.dm" +#include "code\game\movable_vv.dm" #include "code\game\shuttle_engines.dm" #include "code\game\sound.dm" #include "code\game\world.dm" @@ -1097,6 +1100,7 @@ #include "code\game\objects\items.dm" #include "code\game\objects\mail.dm" #include "code\game\objects\obj_defense.dm" +#include "code\game\objects\obj_vv.dm" #include "code\game\objects\objs.dm" #include "code\game\objects\structures.dm" #include "code\game\objects\effects\alien_acid.dm" @@ -2349,6 +2353,7 @@ #include "code\modules\mob\mob_update_icons_base.dm" #include "code\modules\mob\mob_update_status_base.dm" #include "code\modules\mob\mob_vars.dm" +#include "code\modules\mob\mob_vv.dm" #include "code\modules\mob\transform_procs.dm" #include "code\modules\mob\typing_indicator.dm" #include "code\modules\mob\camera\camera_mob.dm" @@ -2464,6 +2469,7 @@ #include "code\modules\mob\living\carbon\human\human_stripping.dm" #include "code\modules\mob\living\carbon\human\human_update_icons.dm" #include "code\modules\mob\living\carbon\human\human_update_status.dm" +#include "code\modules\mob\living\carbon\human\human_vv.dm" #include "code\modules\mob\living\carbon\human\npcs.dm" #include "code\modules\mob\living\carbon\human\physiology.dm" #include "code\modules\mob\living\carbon\human\species\_species.dm"