diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index 2683922820..6acc667f2d 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -19,8 +19,8 @@ #define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} -#define START_PROCESSING(Processor, Datum) if (!Datum.is_processing) {Datum.is_processing = TRUE;Processor.processing += Datum} -#define STOP_PROCESSING(Processor, Datum) Datum.is_processing = FALSE;Processor.processing -= Datum +#define START_PROCESSING(Processor, Datum) if (!(Datum.datum_flags & DF_ISPROCESSING)) {Datum.datum_flags |= DF_ISPROCESSING;Processor.processing += Datum} +#define STOP_PROCESSING(Processor, Datum) Datum.datum_flags &= ~DF_ISPROCESSING;Processor.processing -= Datum //! SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier) diff --git a/code/__defines/_tick.dm b/code/__defines/_tick.dm index 8384c509d7..ae3c70db1d 100644 --- a/code/__defines/_tick.dm +++ b/code/__defines/_tick.dm @@ -10,3 +10,5 @@ #define TICK_CHECK_HIGH_PRIORITY ( TICK_USAGE > 95 ) #define CHECK_TICK_HIGH_PRIORITY ( TICK_CHECK_HIGH_PRIORITY? stoplag() : 0 ) + +#define UNTIL(X) while(!(X)) stoplag() diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 27b1afcc1c..b9417d2a86 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -1,6 +1,5 @@ -/* - These defines are specific to the atom/flags_1 bitmask -*/ +//MARK ALL FLAG CHANGES IN _globals/bitfields.dm! +//All flags should go in here if possible. #define ALL (~0) //For convenience. #define NONE 0 @@ -17,3 +16,4 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 // datum_flags #define DF_VAR_EDITED (1<<0) #define DF_ISPROCESSING (1<<1) + diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index d77b5cf297..95d4929acb 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -106,26 +106,15 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret #define ATMOS_DEFAULT_VOLUME_MIXER 200 // L. #define ATMOS_DEFAULT_VOLUME_PIPE 70 // L. +//wIP - PORT ALL OF THESE TO SUBSYSTEMS AND GET RID OF THE WHOLE LIST PROCESS THING // Fancy-pants START/STOP_PROCESSING() macros that lets us custom define what the list is. #define START_PROCESSING_IN_LIST(DATUM, LIST) \ -if (DATUM.is_processing) {\ - if(DATUM.is_processing != #LIST)\ - {\ - crash_with("Failed to start processing. [log_info_line(DATUM)] is already being processed by [DATUM.is_processing] but queue attempt occured on [#LIST]."); \ - }\ -} else {\ - DATUM.is_processing = #LIST;\ +if (!(DATUM.datum_flags & DF_ISPROCESSING)) {\ LIST += DATUM;\ + DATUM.datum_flags |= DF_ISPROCESSING\ } -#define STOP_PROCESSING_IN_LIST(DATUM, LIST) \ -if(DATUM.is_processing) {\ - if(LIST.Remove(DATUM)) {\ - DATUM.is_processing = null;\ - } else {\ - crash_with("Failed to stop processing. [log_info_line(DATUM)] is being processed by [is_processing] and not found in SSmachines.[#LIST]"); \ - }\ -} +#define STOP_PROCESSING_IN_LIST(DATUM, LIST) LIST.Remove(DATUM);DATUM.datum_flags &= ~DF_ISPROCESSING // Note - I would prefer these be defined machines.dm, but some are used prior in file order. ~Leshana #define START_MACHINE_PROCESSING(Datum) START_PROCESSING_IN_LIST(Datum, global.processing_machines) diff --git a/code/__defines/vv.dm b/code/__defines/vv.dm index 025b65d158..b7b54b0b57 100644 --- a/code/__defines/vv.dm +++ b/code/__defines/vv.dm @@ -20,6 +20,13 @@ #define VV_MARKED_DATUM "Marked Datum" #define VV_BITFIELD "Bitfield" +#define VV_MSG_MARKED "
Marked Object" +#define VV_MSG_EDITED "
Var Edited" +#define VV_MSG_DELETED "
Deleted" + +#define VV_NORMAL_LIST_NO_EXPAND_THRESHOLD 50 +#define VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD 150 + //Helpers for vv_get_dropdown() #define VV_DROPDOWN_OPTION(href_key, name) . += "" diff --git a/code/_global_vars/bitfields.dm b/code/_global_vars/bitfields.dm new file mode 100644 index 0000000000..891c50ce88 --- /dev/null +++ b/code/_global_vars/bitfields.dm @@ -0,0 +1,7 @@ +GLOBAL_LIST_INIT(bitfields, list( + "datum_flags" = list( + "DF_VAR_EDITED" = DF_VAR_EDITED, + "DF_ISPROCESSING" = DF_ISPROCESSING + ) + +)) diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 855aa9c138..b4d9f39a7f 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -753,3 +753,9 @@ proc/dd_sortedTextList(list/incoming) for(var/i = 1 to l.len) if(islist(.[i])) .[i] = .(.[i]) + +//Return a list with no duplicate entries +/proc/uniqueList(list/L) + . = list() + for(var/i in L) + . |= i diff --git a/code/_helpers/type2type.dm b/code/_helpers/type2type.dm index 0316e1d186..55dad2242f 100644 --- a/code/_helpers/type2type.dm +++ b/code/_helpers/type2type.dm @@ -242,3 +242,34 @@ /proc/isLeap(y) return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + +//Takes a string and a datum +//The string is well, obviously the string being checked +//The datum is used as a source for var names, to check validity +//Otherwise every single word could technically be a variable! +/proc/string2listofvars(var/t_string, var/datum/var_source) + if(!t_string || !var_source) + return list() + + . = list() + + var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check + if(var_found) + //Find var names + + // "A dog said hi [name]!" + // splittext() --> list("A dog said hi ","name]!" + // jointext() --> "A dog said hi name]!" + // splittext() --> list("A","dog","said","hi","name]!") + + t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios + var/list/list_value = splittext(t_string,"\[") + var/intermediate_stage = jointext(list_value, null) + + list_value = splittext(intermediate_stage," ") + for(var/value in list_value) + if(findtext(value,"]")) + value = splittext(value,"]") //"name]!" --> list("name","!") + for(var/A in value) + if(var_source.vars.Find(A)) + . += A diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 2073f7970e..72a289a622 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1441,3 +1441,92 @@ var/mob/dview/dview_mob = new return #define NAMEOF(datum, X) (#X || ##datum.##X) + +/proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) + if (value == FALSE) //nothing should be calling us with a number, so this is safe + value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text + if (isnull(value)) + return + value = trim(value) + if(!isnull(value) && value != "") + matches = filter_fancy_list(matches, value) + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select a type", "Pick Type", matches[1]) as null|anything in matches + if(!chosen) + return + chosen = matches[chosen] + return chosen + +/proc/get_fancy_list_of_atom_types() + var/static/list/pre_generated_list + if (!pre_generated_list) //init + pre_generated_list = make_types_fancy(typesof(/atom)) + return pre_generated_list + +/proc/get_fancy_list_of_datum_types() + var/static/list/pre_generated_list + if (!pre_generated_list) //init + pre_generated_list = make_types_fancy(sortList(typesof(/datum) - typesof(/atom))) + return pre_generated_list + +/proc/filter_fancy_list(list/L, filter as text) + var/list/matches = new + for(var/key in L) + var/value = L[key] + if(findtext("[key]", filter) || findtext("[value]", filter)) + matches[key] = value + return matches + +/proc/make_types_fancy(var/list/types) + if (ispath(types)) + types = list(types) + . = list() + for(var/type in types) + var/typename = "[type]" + var/static/list/TYPES_SHORTCUTS = list( + /obj/effect/decal/cleanable = "CLEANABLE", + /obj/item/device/radio/headset = "HEADSET", + /obj/item/clothing/head/helmet/space = "SPESSHELMET", + /obj/item/weapon/book/manual = "MANUAL", + /obj/item/weapon/reagent_containers/food/drinks = "DRINK", //longest paths comes first + /obj/item/weapon/reagent_containers/food = "FOOD", + /obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS", + /obj/machinery/atmospherics = "ATMOS_MECH", + /obj/machinery/portable_atmospherics = "PORT_ATMOS", + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK", + /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", + /obj/item/organ = "ORGAN", + /obj/item = "ITEM", + /obj/machinery = "MACHINERY", + /obj/effect = "EFFECT", + /obj = "O", + /datum = "D", + /turf/simulated/wall = "S-WALL", + /turf/simulated/floor = "S-FLOOR", + /turf/simulated = "SIMULATED", + /turf/unsimulated/wall = "US-WALL", + /turf/unsimulated/floor = "US-FLOOR", + /turf/unsimulated = "UNSIMULATED", + /turf = "T", + /mob/living/carbon = "CARBON", + /mob/living/simple_mob = "SIMPLE", + /mob/living = "LIVING", + /mob = "M" + ) + for (var/tn in TYPES_SHORTCUTS) + if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ ) + typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/")) + break + .[typename] = type + +/proc/IsValidSrc(datum/D) + if(istype(D)) + return !QDELETED(D) + return FALSE diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index fa7b917194..56a9244347 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -38,8 +38,10 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) stat("Globals:", statclick.update("Edit")) -/datum/controller/global_vars/VV_hidden() - return ..() + gvars_datum_protected_varlist +/datum/controller/global_vars/vv_edit_var(var_name, var_value) + if(gvars_datum_protected_varlist[var_name]) + return FALSE + return ..() /datum/controller/global_vars/Initialize(var/exclude_these) gvars_datum_init_order = list() diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index 4cba70a981..4525175393 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -109,7 +109,7 @@ SUBSYSTEM_DEF(machines) else global.pipe_networks.Remove(PN) if(!QDELETED(PN)) - PN.is_processing = null + DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -127,7 +127,7 @@ SUBSYSTEM_DEF(machines) else global.processing_machines.Remove(M) if(!QDELETED(M)) - M.is_processing = null + DISABLE_BITFIELD(M.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -144,7 +144,7 @@ SUBSYSTEM_DEF(machines) else global.powernets.Remove(PN) if(!QDELETED(PN)) - PN.is_processing = null + DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return @@ -160,7 +160,7 @@ SUBSYSTEM_DEF(machines) current_run.len-- if(!I.pwr_drain(wait)) // 0 = Process Kill, remove from processing list. global.processing_power_items.Remove(I) - I.is_processing = null + DISABLE_BITFIELD(I.datum_flags, DF_ISPROCESSING) if(MC_TICK_CHECK) return diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 577698532e..ea2f4feec2 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -105,6 +105,10 @@ "} /datum/browser/proc/open(var/use_onclose = 1) + if(isnull(window_id)) //null check because this can potentially nuke goonchat + WARNING("Browser [title] tried to open with a null ID") + to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!") + return var/window_size = "" if (width && height) window_size = "size=[width]x[height];" @@ -112,9 +116,6 @@ if (use_onclose) onclose(user, window_id, ref) -/datum/browser/proc/close() - user << browse(null, "window=[window_id]") - // This will allow you to show an icon in the browse window // This is added to mob so that it can be used without a reference to the browser object // There is probably a better place for this... @@ -157,12 +158,12 @@ //world << "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]" - // the on-close client verb // called when a browser popup window is closed after registering with proc/onclose() // if a valid atom reference is supplied, call the atom's Topic() with "close=1" // otherwise, just reset the client mob's machine var. // + /client/verb/windowclose(var/atomref as text) set hidden = 1 // hide this verb from the user's panel set name = ".windowclose" // no autocomplete on cmd line @@ -182,3 +183,198 @@ //world << "[src] was [src.mob.machine], setting to null" src.mob.unset_machine() return + +/datum/browser/proc/close() + if(!isnull(window_id))//null check because this can potentially nuke goonchat + user << browse(null, "window=[window_id]") + else + WARNING("Browser [title] tried to close with a null ID") + +/datum/browser/modal/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000) + if (!User) + return + + var/output = {"
[Message]

+
+ [Button1]"} + + if (Button2) + output += {"[Button2]"} + + if (Button3) + output += {"[Button3]"} + + output += {"
"} + + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/alert/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + opentime = 0 + close() + +//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) +/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!User) + User = usr + switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)) + if (1) + return Button1 + if (2) + return Button2 + if (3) + return Button3 + +//Same shit, but it returns the button number, could at some point support unlimited button amounts. +/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) + A.open() + A.wait() + if (A.selectedbutton) + return A.selectedbutton + +/datum/browser/modal + var/opentime = 0 + var/timeout + var/selectedbutton = 0 + var/stealfocus + +/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000) + ..() + stealfocus = StealFocus + if (!StealFocus) + window_options += "focus=false;" + timeout = Timeout + + +/datum/browser/modal/close() + .=..() + opentime = 0 + +/datum/browser/modal/open() + set waitfor = 0 + opentime = world.time + + if (stealfocus) + . = ..(use_onclose = 1) + else + var/focusedwindow = winget(user, null, "focus") + . = ..(use_onclose = 1) + + //waits for the window to show up client side before attempting to un-focus it + //winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping + for (var/i in 1 to 10) + if (user && winexists(user, window_id)) + if (focusedwindow) + winset(user, focusedwindow, "focus=true") + else + winset(user, "mapwindow", "focus=true") + break + if (timeout) + addtimer(CALLBACK(src, .proc/close), timeout) + +/datum/browser/modal/proc/wait() + while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) + stoplag(1) + +/datum/browser/modal/listpicker + var/valueslist = list() + +/datum/browser/modal/listpicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/values,inputtype="checkbox", width, height, slidecolor) + if (!User) + return + + var/output = {"
+ "} + + if (Button2) + output += {""} + + if (Button3) + output += {""} + + output += {"
"} + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/listpicker/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + for (var/item in href_list) + switch(item) + if ("close", "button", "src") + continue + else + valueslist[item] = href_list[item] + opentime = 0 + close() + +/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor) + A.open() + A.wait() + if (A.selectedbutton) + return list("button" = A.selectedbutton, "values" = A.valueslist) + +/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) + if (!User || !(bitfield in GLOB.bitfields)) + return + var/list/pickerlist = list() + for (var/i in GLOB.bitfields[bitfield]) + var/can_edit = 1 + if(!isnull(allowed_edit_list) && !(allowed_edit_list & GLOB.bitfields[bitfield][i])) + can_edit = 0 + if (current_value & GLOB.bitfields[bitfield][i]) + pickerlist += list(list("checked" = 1, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + else + pickerlist += list(list("checked" = 0, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = pickerlist, width = nwidth, height = nheight, slidecolor = nslidecolor) + if (islist(result)) + if (result["button"] == 2) // If the user pressed the cancel button + return + . = 0 + for (var/flag in result["values"]) + . |= GLOB.bitfields[bitfield][flag] + else + return diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index ad3702dfce..d08860e7db 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,10 +1,3 @@ -#define VV_MSG_MARKED "
Marked Object" -#define VV_MSG_EDITED "
Var Edited" -#define VV_MSG_DELETED "
Deleted" - -#define VV_NORMAL_LIST_NO_EXPAND_THRESHOLD 50 -#define VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD 150 - /datum/proc/CanProcCall(procname) return TRUE @@ -37,12 +30,12 @@ //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! /datum/proc/vv_do_topic(list/href_list) - if(!usr || !usr.holder) + if(!usr || !usr.client.holder) return //This is VV, not to be called by anything else. IF_VV_OPTION(VV_HK_EXPOSE) if(!check_rights(R_ADMIN, FALSE)) return - var/value = vv_get_value(VV_CLIENT) + var/value = usr.client.vv_get_value(VV_CLIENT) if (value["class"] != VV_CLIENT) return var/client/C = value["value"] @@ -51,28 +44,25 @@ var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No") if (prompt != "Yes" || !usr.client) return - message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]") to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") C.debug_variables(src) IF_VV_OPTION(VV_HK_DELETE) if(!check_rights(R_DEBUG)) return - usr.admin_delete(src) + usr.client.admin_delete(src) if (isturf(src)) // show the turf that took its place - usr.debug_variables(src) + usr.client.debug_variables(src) IF_VV_OPTION(VV_HK_MARK) - if(usr.holder.marked_datum) - usr.vv_update_display(usr.holder.marked_datum, "marked", "") - usr.holder.marked_datum = D - usr.vv_update_display(D, "marked", VV_MSG_MARKED) + usr.client.mark_datum(src) IF_VV_OPTION(VV_HK_CALLPROC) - usr.callproc_datum(T) + usr.client.callproc_datum(src) -/datum/proc/get_view_variables_header() +/datum/proc/vv_get_header() . = list() if("name" in vars) - . += "[name]
" + . += "[vars["name"]]
" . += "[type]" /datum/proc/on_reagent_change(changetype) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index befeeac45c..fee50f41e2 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -97,9 +97,6 @@ return 0 return -1 -/atom/proc/on_reagent_change() - return - /atom/proc/Bumped(AM as mob|obj) return @@ -538,15 +535,15 @@ IF_VV_OPTION(VV_HK_ATOM_EXPLODE) if(!check_rights(R_DEBUG|R_FUN)) return - usr.cmd_admin_explosion(src) + usr.client.cmd_admin_explosion(src) href_list["datumrefresh"] = "\ref[src]" IF_VV_OPTION(VV_HK_ATOM_EMP) if(!check_rights(R_DEBUG|R_FUN)) return - usr.cmd_admin_emp(src) + usr.client.cmd_admin_emp(src) href_list["datumrefresh"] = "\ref[src]" -/atom/get_view_variables_header() +/atom/vv_get_header() . = ..() . += {" [src] diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 8c2d8e70fd..a24f2868da 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -54,7 +54,7 @@ color = girder_material.icon_colour if(girder_material.products_need_process()) //Am I radioactive or some other? Process me! START_PROCESSING(SSobj, src) - else if(is_processing) //If I happened to be radioactive or s.o. previously, and am not now, stop processing. + else if(datum_flags & DF_ISPROCESSING) //If I happened to be radioactive or s.o. previously, and am not now, stop processing. STOP_PROCESSING(SSobj, src) /obj/structure/girder/get_material() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 28b73818e5..2a4641e76a 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -6,6 +6,7 @@ var/list/admin_verbs_default = list( /client/proc/hide_verbs, //hides all our adminverbs, /client/proc/hide_most_verbs, //hides all our hideable adminverbs, /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, + /client/proc/mark_datum_mapview, //Lets us mark datums. /client/proc/cmd_check_new_players, //allows us to see every new player // /client/proc/check_antagonists, //shows all antags, // /client/proc/cmd_mod_say, @@ -211,7 +212,7 @@ var/list/admin_verbs_debug = list( /client/proc/show_plant_genes, /client/proc/enable_debug_verbs, /client/proc/callproc, - /client/proc/callproc_target, + /client/proc/callproc_datum, /client/proc/SDQL2_query, /client/proc/Jump, /client/proc/jumptomob, @@ -229,7 +230,7 @@ var/list/admin_verbs_debug = list( var/list/admin_verbs_paranoid_debug = list( /client/proc/callproc, - /client/proc/callproc_target, + /client/proc/callproc_datum, /client/proc/debug_controller ) @@ -297,7 +298,7 @@ var/list/admin_verbs_hideable = list( /client/proc/restart_controller, /client/proc/cmd_admin_list_open_jobs, /client/proc/callproc, - /client/proc/callproc_target, + /client/proc/callproc_datum, /client/proc/Debug2, /client/proc/reload_admins, /client/proc/kill_air, @@ -365,7 +366,7 @@ var/list/admin_verbs_event_manager = list( /proc/possess, /proc/release, /client/proc/callproc, - /client/proc/callproc_target, + /client/proc/callproc_datum, /client/proc/debug_controller, /client/proc/show_gm_status, /datum/admins/proc/change_weather, diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index df7937d2c5..129429598c 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -1,152 +1,203 @@ - /client/proc/callproc() set category = "Debug" set name = "Advanced ProcCall" + set waitfor = 0 - if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return + if(!check_rights(R_DEBUG)) + return - var/target = null + var/datum/target = null var/targetselected = 0 - - switch(alert("Proc owned by something?",, "Yes", "No", "Cancel")) - if("Yes") - targetselected=1 - switch(input("Proc owned by...", "Owner", null) as null|anything in list("Obj", "Mob", "Area or Turf", "Client")) - if("Obj") - target = input("Select target:", "Target") as null|obj in world - if("Mob") - target = input("Select target:", "Target", usr) as null|mob in world - if("Area or Turf") - target = input("Select target:", "Target", get_turf(usr)) as null|area|turf in world - if("Client") - target = input("Select target:", "Target", usr.client) as null|anything in GLOB.clients - else - return - if(!target) - usr << "Proc call cancelled." - return - if("Cancel") - return - if("No") - ; // do nothing - - callproc_targetpicked(targetselected, target) - -/client/proc/callproc_target(atom/A in world) - set category = "Debug" - set name = "Advanced ProcCall Target" - - if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return - - callproc_targetpicked(1, A) - -/client/proc/callproc_targetpicked(hastarget, datum/target) - - // this needs checking again here because VV's 'Call Proc' option directly calls this proc with the target datum - if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return - var/returnval = null - var/procname = input("Proc name", "Proc") as null|text - if(!procname) return - - if(hastarget) - if(!target) - usr << "Your callproc target no longer exists." - return - if(!hascall(target, procname)) - usr << "\The [target] has no call [procname]()" - return - - var/list/arguments = list() - var/done = 0 - var/current = null - - while(!done) - if(hastarget && !target) - usr << "Your callproc target no longer exists." - return - switch(input("Type of [arguments.len+1]\th variable", "argument [arguments.len+1]") as null|anything in list( - "finished", "null", "text", "num", "type", "obj reference", "mob reference", - "area/turf reference", "icon", "file", "client", "mob's area", "marked datum")) - if(null) + switch(alert("Proc owned by something?",,"Yes","No")) + if("Yes") + targetselected = 1 + var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT)) + if (!value["class"] || !value["value"]) return + target = value["value"] + if("No") + target = null + targetselected = 0 - if("finished") - done = 1 + var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null + if(!procname) + return - if("null") - current = null + //hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib") + var/testname = procname + if(targetselected) + //Find one of the 3 possible ways they could have written /proc/PROCNAME + if(findtext(procname, "/proc/")) + testname = replacetext(procname, "/proc/", "") + else if(findtext(procname, "/proc")) + testname = replacetext(procname, "/proc", "") + else if(findtext(procname, "proc/")) + testname = replacetext(procname, "proc/", "") + //Clear out any parenthesis if they're a dummy + testname = replacetext(testname, "()", "") - if("text") - current = input("Enter text for [arguments.len+1]\th argument") as null|text - if(isnull(current)) return - - if("num") - current = input("Enter number for [arguments.len+1]\th argument") as null|num - if(isnull(current)) return - - if("type") - current = input("Select type for [arguments.len+1]\th argument") as null|anything in typesof(/obj, /mob, /area, /turf) - if(isnull(current)) return - - if("obj reference") - current = input("Select object for [arguments.len+1]\th argument") as null|obj in world - if(isnull(current)) return - - if("mob reference") - current = input("Select mob for [arguments.len+1]\th argument") as null|mob in world - if(isnull(current)) return - - if("area/turf reference") - current = input("Select area/turf for [arguments.len+1]\th argument") as null|area|turf in world - if(isnull(current)) return - - if("icon") - current = input("Provide icon for [arguments.len+1]\th argument") as null|icon - if(isnull(current)) return - - if("client") - current = input("Select client for [arguments.len+1]\th argument") as null|anything in GLOB.clients - if(isnull(current)) return - - if("mob's area") - var/mob/M = input("Select mob to take area for [arguments.len+1]\th argument") as null|mob in world - if(!M) return - current = get_area(M) - if(!current) - switch(alert("\The [M] appears to not have an area; do you want to pass null instead?",, "Yes", "Cancel")) - if("Yes") - ; // do nothing - if("Cancel") - return - - if("marked datum") - current = holder.marked_datum - if(!current) - switch(alert("You do not currently have a marked datum; do you want to pass null instead?",, "Yes", "Cancel")) - if("Yes") - ; // do nothing - if("Cancel") - return - if(!done) - arguments += current - - if(hastarget) - if(!target) - usr << "Your callproc target no longer exists." - return - log_admin("[key_name(src)] called [target]'s [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].") - if(arguments.len) - returnval = call(target, procname)(arglist(arguments)) - else - returnval = call(target, procname)() + if(targetselected && !hascall(target,testname)) + to_chat(usr, "Error: callproc(): type [target.type] has no proc named [procname].") + return else - log_admin("[key_name(src)] called [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].") - returnval = call(procname)(arglist(arguments)) + var/procpath = text2path(procname) + if (!procpath) + to_chat(usr, "Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + return + var/list/lst = get_callproc_args() + if(!lst) + return - usr << "[procname]() returned: [isnull(returnval) ? "null" : returnval]" + if(targetselected) + if(!target) + to_chat(usr, "Error: callproc(): owner of proc no longer exists.") + return + var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + log_admin(msg) + message_admins(msg) + admin_ticket_log(target, msg) + returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc + else + //this currently has no hascall protection. wasn't able to get it working. + log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") + message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") + returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc + . = get_callproc_returnval(returnval, procname) + if(.) + to_chat(usr, .) feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +GLOBAL_VAR(AdminProcCaller) +GLOBAL_PROTECT(AdminProcCaller) +GLOBAL_VAR_INIT(AdminProcCallCount, 0) +GLOBAL_PROTECT(AdminProcCallCount) +GLOBAL_VAR(LastAdminCalledTargetRef) +GLOBAL_PROTECT(LastAdminCalledTargetRef) +GLOBAL_VAR(LastAdminCalledTarget) +GLOBAL_PROTECT(LastAdminCalledTarget) +GLOBAL_VAR(LastAdminCalledProc) +GLOBAL_PROTECT(LastAdminCalledProc) +GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention) +GLOBAL_PROTECT(AdminProcCallSpamPrevention) + +/proc/WrapAdminProcCall(datum/target, procname, list/arguments) + if(target && procname == "Del") + to_chat(usr, "Calling Del() is not allowed") + return + + if(target != GLOBAL_PROC && !target.CanProcCall(procname)) + to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!") + return + var/current_caller = GLOB.AdminProcCaller + var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller + if(!ckey) + CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") + if(current_caller && current_caller != ckey) + if(!GLOB.AdminProcCallSpamPrevention[ckey]) + to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") + GLOB.AdminProcCallSpamPrevention[ckey] = TRUE + UNTIL(!GLOB.AdminProcCaller) + to_chat(usr, "Running your proc") + GLOB.AdminProcCallSpamPrevention -= ckey + else + UNTIL(!GLOB.AdminProcCaller) + GLOB.LastAdminCalledProc = procname + if(target != GLOBAL_PROC) + GLOB.LastAdminCalledTargetRef = "\ref[target]" + GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you + ++GLOB.AdminProcCallCount + . = world.WrapAdminProcCall(target, procname, arguments) + if(--GLOB.AdminProcCallCount == 0) + GLOB.AdminProcCaller = null + +//adv proc call this, ya nerds +/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) + if(target == GLOBAL_PROC) + return call(procname)(arglist(arguments)) + else if(target != world) + return call(target, procname)(arglist(arguments)) + else + log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]") + +/proc/IsAdminAdvancedProcCall() +#ifdef TESTING + return FALSE +#else + return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey +#endif + +/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) + set category = "Debug" + set name = "Atom ProcCall" + set waitfor = 0 + + if(!check_rights(R_DEBUG)) + return + + var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null + if(!procname) + return + if(!hascall(A,procname)) + to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].") + return + var/list/lst = get_callproc_args() + if(!lst) + return + + if(!A || !IsValidSrc(A)) + to_chat(usr, "Error: callproc_datum(): owner of proc no longer exists.") + return + log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") + var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + message_admins(msg) + admin_ticket_log(A, msg) + feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc + . = get_callproc_returnval(returnval,procname) + if(.) + to_chat(usr, .) + +/client/proc/get_callproc_args() + var/argnum = input("Number of arguments","Number:",0) as num|null + if(isnull(argnum)) + return + + . = list() + var/list/named_args = list() + while(argnum--) + var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null + var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) + if (!value["class"]) + return + if(named_arg) + named_args[named_arg] = value["value"] + else + . += value["value"] + if(LAZYLEN(named_args)) + . += named_args + +/client/proc/get_callproc_returnval(returnval,procname) + . = "" + if(islist(returnval)) + var/list/returnedlist = returnval + . = "" + if(returnedlist.len) + var/assoc_check = returnedlist[1] + if(istext(assoc_check) && (returnedlist[assoc_check] != null)) + . += "[procname] returned an associative list:" + for(var/key in returnedlist) + . += "\n[key] = [returnedlist[key]]" + + else + . += "[procname] returned a list:" + for(var/elem in returnedlist) + . += "\n[elem]" + else + . = "[procname] returned an empty list" + . += "" + + else + . = "[procname] returned: [!isnull(returnval) ? returnval : "null"]" diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index f6a67a22d5..114808d3d3 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -101,7 +101,18 @@ NOTE: It checks usr by default. Supply the "user" argument if you wish to check usr << "Error: Cannot proceed. They have more or equal rights to us." return 0 +/client/proc/mark_datum(datum/D) + if(!holder) + return + if(holder.marked_datum) + vv_update_display(holder.marked_datum, "marked", "") + holder.marked_datum = D + vv_update_display(D, "marked", VV_MSG_MARKED) +/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view)) + set category = "Debug" + set name = "Mark Object" + mark_datum(D) /client/proc/deadmin() if(holder) diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm deleted file mode 100644 index 09178d650e..0000000000 --- a/code/modules/admin/verbs/massmodvar.dm +++ /dev/null @@ -1,375 +0,0 @@ -/client/proc/cmd_mass_modify_object_variables(atom/A, var/var_name) - set category = "Debug" - set name = "Mass Edit Variables" - set desc="(target) Edit all instances of a target item's variables" - - var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms) - - if(!check_rights(R_VAREDIT)) return - - if(A && A.type) - if(typesof(A.type)) - switch(input("Strict object type detection?") as null|anything in list("Strictly this type","This type and subtypes", "Cancel")) - if("Strictly this type") - method = 0 - if("This type and subtypes") - method = 1 - if("Cancel") - return - if(null) - return - - src.massmodify_variables(A, var_name, method) - feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/client/proc/massmodify_variables(var/atom/O, var/var_name = "", var/method = 0) - if(!check_rights(R_VAREDIT)) return - - var/list/locked = list("vars", "key", "ckey", "client") - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - usr << "It is forbidden to edit this object's variables." - return - - var/list/names = list() - for (var/V in O.vars) - names += V - - names = sortList(names) - - var/variable = "" - - if(!var_name) - variable = input("Which var?","Var") as null|anything in names - else - variable = var_name - - if(!variable) return - var/default - var/var_value = O.vars[variable] - var/dir - - if(variable == "holder" || (variable in locked)) - if(!check_rights(R_DEBUG)) return - - if(isnull(var_value)) - usr << "Unable to determine variable type." - - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [var_value]" - if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - if(dir) - usr << "If a direction, direction is: [dir]" - - var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","icon","file","edit referenced object","restore to default") - - if(!class) - return - - var/original_name - - if (!istype(O, /atom)) - original_name = "\ref[O] ([O])" - else - original_name = O:name - - switch(class) - - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("edit referenced object") - return .(O.vars[variable]) - - if("text") - var/new_value = input("Enter new text:","Text",O.vars[variable]) as text|null//todo: sanitize ??? - if(new_value == null) return - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("num") - var/new_value = input("Enter new number:","Num",\ - O.vars[variable]) as num|null - if(new_value == null) return - - if(variable=="light_range") - O.set_light(new_value) - else - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - if(variable=="light_range") - M.set_light(new_value) - else - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - if(variable=="light_range") - A.set_light(new_value) - else - A.vars[variable] = O.vars[variable] - - if("type") - var/new_value - new_value = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("file") - var/new_value = input("Pick file:","File",O.vars[variable]) as null|file - if(new_value == null) return - O.vars[variable] = new_value - - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O.type, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O.type, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - if("icon") - var/new_value = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(new_value == null) return - O.vars[variable] = new_value - if(method) - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if ( istype(M , O.type) ) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if ( istype(A , O.type) ) - A.vars[variable] = O.vars[variable] - - else - if(istype(O, /mob)) - for(var/mob/M in mob_list) - if (M.type == O.type) - M.vars[variable] = O.vars[variable] - - else if(istype(O, /obj)) - for(var/obj/A in world) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - else if(istype(O, /turf)) - for(var/turf/A in turfs) - if (A.type == O.type) - A.vars[variable] = O.vars[variable] - - log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm deleted file mode 100644 index ecd26e9b56..0000000000 --- a/code/modules/admin/verbs/modifyvariables.dm +++ /dev/null @@ -1,591 +0,0 @@ -var/list/forbidden_varedit_object_types = list( - /datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea, - /obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering, - /datum/feedback_variable //Prevents people messing with feedback gathering, - ) - -var/list/VVlocked = list("vars", "client", "virus", "viruses", "cuffed", "last_eaten", "unlock_content", "bound_x", "bound_y", "step_x", "step_y", "force_ending", "queued_priority") -var/list/VVicon_edit_lock = list("icon", "icon_state", "overlays", "underlays") -var/list/VVckey_edit = list("key", "ckey") - -/* -/client/proc/cmd_modify_object_variables(obj/O as obj|mob|turf|area in world) - set category = "Debug" - set name = "Edit Variables" - set desc="(target) Edit a target item's variables" - src.modify_variables(O) - feedback_add_details("admin_verb","EDITV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -*/ - -/client/proc/cmd_modify_ticker_variables() - set category = "Debug" - set name = "Edit Ticker Variables" - - if (ticker == null) - src << "Game hasn't started yet." - else - src.modify_variables(ticker) - feedback_add_details("admin_verb","ETV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/mod_list_add_ass() //haha - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/var_value = null - - switch(class) - - if("text") - var_value = input("Enter new text:","Text") as null|text - - if("num") - var_value = input("Enter new number:","Num") as null|num - - if("type") - var_value = input("Enter type:","Type") as null|anything in typesof(/obj,/mob,/area,/turf) - - if("reference") - var_value = input("Select reference:","Reference") as null|mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as null|mob in world - - if("file") - var_value = input("Pick file:","File") as null|file - - if("icon") - var_value = input("Pick icon:","Icon") as null|icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return - - return var_value - - -/client/proc/mod_list_add(var/list/L, atom/O, original_name, objectvar) - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type") as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/var_value = null - - switch(class) - - if("text") - var_value = input("Enter new text:","Text") as text - - if("num") - var_value = input("Enter new number:","Num") as num - - if("type") - var_value = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - - if("reference") - var_value = input("Select reference:","Reference") as mob|obj|turf|area in world - - if("mob reference") - var_value = input("Select reference:","Reference") as mob in world - - if("file") - var_value = input("Pick file:","File") as file - - if("icon") - var_value = input("Pick icon:","Icon") as icon - - if("marked datum") - var_value = holder.marked_datum - - if(!var_value) return - - switch(alert("Would you like to associate a var with the list entry?",,"Yes","No")) - if("Yes") - L += var_value - L[var_value] = mod_list_add_ass() //haha - if("No") - L += var_value - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: ADDED=[var_value]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") - message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]") - -/client/proc/mod_list(var/list/L, atom/O, original_name, objectvar) - if(!check_rights(R_VAREDIT)) return - if(!istype(L,/list)) src << "Not a List." - - if(L.len > 1000) - var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort") - if(confirm != "Continue") - return - - var/assoc = 0 - if(L.len > 0) - var/a = L[1] - if(istext(a) && L[a] != null) - assoc = 1 //This is pretty weak test but i can't think of anything else - usr << "List appears to be associative." - - var/list/names = null - if(!assoc) - names = sortList(L) - - var/variable - var/assoc_key - if(assoc) - variable = input("Which var?","Var") as null|anything in L + "(ADD VAR)" - else - variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" - - if(variable == "(ADD VAR)") - mod_list_add(L, O, original_name, objectvar) - return - - if(assoc) - assoc_key = variable - variable = L[assoc_key] - - if(!assoc && !variable || assoc && !assoc_key) - return - - var/default - - var/dir - - if(variable in VVlocked) - if(!check_rights(R_DEBUG)) return - if(variable in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(variable in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - if(isnull(variable)) - usr << "Unable to determine variable type." - - else if(isnum(variable)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(variable)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(variable)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(variable)) - usr << "Variable appears to be ICON." - variable = "\icon[variable]" - default = "icon" - - else if(istype(variable,/atom) || istype(variable,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(variable,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(variable,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [variable]" - if(dir) - switch(variable) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - - if(dir) - usr << "If a direction, direction is: [dir]" - - var/class = "text" - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])", "DELETE FROM LIST") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default", "DELETE FROM LIST") - - if(!class) - return - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - var/original_var - if(assoc) - original_var = L[assoc_key] - else - original_var = L[L.Find(variable)] - - var/new_var - switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet. - - if("list") - mod_list(variable, O, original_name, objectvar) - - if("restore to default") - new_var = initial(variable) - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("edit referenced object") - modify_variables(variable) - - if("DELETE FROM LIST") - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[variable]")]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]") - message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[variable]") - L -= variable - return - - if("text") - new_var = input("Enter new text:","Text") as text - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("num") - new_var = input("Enter new number:","Num") as num - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("type") - new_var = input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf) - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("reference") - new_var = input("Select reference:","Reference") as mob|obj|turf|area in world - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("mob reference") - new_var = input("Select reference:","Reference") as mob in world - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("file") - new_var = input("Pick file:","File") as file - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("icon") - new_var = input("Pick icon:","Icon") as icon - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - if("marked datum") - new_var = holder.marked_datum - if(assoc) - L[assoc_key] = new_var - else - L[L.Find(variable)] = new_var - - world.log << "### ListVarEdit by [src]: [O.type] [objectvar]: [original_var]=[new_var]" - log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]") - message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]") - -/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - if(!check_rights(R_VAREDIT)) return - - for(var/p in forbidden_varedit_object_types) - if( istype(O,p) ) - usr << "It is forbidden to edit this object's variables." - return - - if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key")) - usr << "You cannot edit ckeys on client objects." - return - - var/class - var/variable - var/var_value - - if(param_var_name) - if(!param_var_name in O.vars) - src << "A variable with this name ([param_var_name]) doesn't exist in this atom ([O])" - return - - if(param_var_name in VVlocked) - if(!check_rights(R_DEBUG)) return - if(param_var_name in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(param_var_name in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - variable = param_var_name - - var_value = O.vars[variable] - - if(autodetect_class) - if(isnull(var_value)) - usr << "Unable to determine variable type." - class = null - autodetect_class = null - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - class = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - class = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - class = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - class = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - class = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - class = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - class = "cancel" - - else - usr << "Variable appears to be FILE." - class = "file" - - else - - var/list/names = list() - for (var/V in O.vars) - names += V - - names = sortList(names) - - variable = input("Which var?","Var") as null|anything in names - if(!variable) return - var_value = O.vars[variable] - - if(variable in VVlocked) - if(!check_rights(R_DEBUG)) return - if(variable in VVckey_edit) - if(!check_rights(R_SPAWN|R_DEBUG)) return - if(variable in VVicon_edit_lock) - if(!check_rights(R_FUN|R_DEBUG)) return - - if(!autodetect_class) - - var/dir - var/default - if(isnull(var_value)) - usr << "Unable to determine variable type." - - else if(isnum(var_value)) - usr << "Variable appears to be NUM." - default = "num" - dir = 1 - - else if(istext(var_value)) - usr << "Variable appears to be TEXT." - default = "text" - - else if(isloc(var_value)) - usr << "Variable appears to be REFERENCE." - default = "reference" - - else if(isicon(var_value)) - usr << "Variable appears to be ICON." - var_value = "\icon[var_value]" - default = "icon" - - else if(istype(var_value,/atom) || istype(var_value,/datum)) - usr << "Variable appears to be TYPE." - default = "type" - - else if(istype(var_value,/list)) - usr << "Variable appears to be LIST." - default = "list" - - else if(istype(var_value,/client)) - usr << "Variable appears to be CLIENT." - default = "cancel" - - else - usr << "Variable appears to be FILE." - default = "file" - - usr << "Variable contains: [var_value]" - if(dir) - switch(var_value) - if(1) - dir = "NORTH" - if(2) - dir = "SOUTH" - if(4) - dir = "EAST" - if(8) - dir = "WEST" - if(5) - dir = "NORTHEAST" - if(6) - dir = "SOUTHEAST" - if(9) - dir = "NORTHWEST" - if(10) - dir = "SOUTHWEST" - else - dir = null - if(dir) - usr << "If a direction, direction is: [dir]" - - if(src.holder && src.holder.marked_datum) - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default","marked datum ([holder.marked_datum.type])") - else - class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", - "num","type","reference","mob reference", "icon","file","list","edit referenced object","restore to default") - - if(!class) - return - - var/original_name - - if (!istype(O, /atom)) - original_name = "\ref[O] ([O])" - else - original_name = O:name - - if(holder.marked_datum && class == "marked datum ([holder.marked_datum.type])") - class = "marked datum" - - switch(class) - - if("list") - mod_list(O.vars[variable], O, original_name, variable) - return - - if("restore to default") - O.vars[variable] = initial(O.vars[variable]) - - if("edit referenced object") - return .(O.vars[variable]) - - if("text") - var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|text - if(var_new==null) return - O.vars[variable] = var_new - - if("num") - if(variable=="light_range") - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - O.set_light(var_new) - else if(variable=="stat") - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new == null) return - if((O.vars[variable] == 2) && (var_new < 2))//Bringing the dead back to life - dead_mob_list -= O - living_mob_list += O - if((O.vars[variable] < 2) && (var_new == 2))//Kill he - living_mob_list -= O - dead_mob_list += O - O.vars[variable] = var_new - else - var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num - if(var_new==null) return - O.vars[variable] = var_new - - if("type") - var/var_new = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf) - if(var_new==null) return - O.vars[variable] = var_new - - if("reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob|obj|turf|area in world - if(var_new==null) return - O.vars[variable] = var_new - - if("mob reference") - var/var_new = input("Select reference:","Reference",O.vars[variable]) as null|mob in world - if(var_new==null) return - O.vars[variable] = var_new - - if("file") - var/var_new = input("Pick file:","File",O.vars[variable]) as null|file - if(var_new==null) return - O.vars[variable] = var_new - - if("icon") - var/var_new = input("Pick icon:","Icon",O.vars[variable]) as null|icon - if(var_new==null) return - O.vars[variable] = var_new - - if("marked datum") - O.vars[variable] = holder.marked_datum - - world.log << "### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]" - log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]") - message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 338ae0acf7..3f7908c1a8 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -593,12 +593,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if (!holder) src << "Only administrators may use this command." return - - if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes") - log_admin("[key_name(usr)] deleted [O] at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] deleted [O] at ([O.x],[O.y],[O.z])", 1) - feedback_add_details("admin_verb","DEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - qdel(O) + admin_delete(O) /client/proc/cmd_admin_list_open_jobs() set category = "Admin" diff --git a/code/modules/admin/view_variables/admin_delete.dm b/code/modules/admin/view_variables/admin_delete.dm new file mode 100644 index 0000000000..53a54786a9 --- /dev/null +++ b/code/modules/admin/view_variables/admin_delete.dm @@ -0,0 +1,24 @@ +/client/proc/admin_delete(datum/D) + var/atom/A = D + var/coords = "" + var/jmp_coords = "" + if(istype(A)) + var/turf/T = get_turf(A) + if(T) + coords = "at [COORD(T)]" + jmp_coords = "at [ADMIN_COORDJMP(T)]" + else + jmp_coords = coords = "in nullspace" + + if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes") + log_admin("[key_name(usr)] deleted [D] [coords]") + message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]") + feedback_add_details("admin_verb","ADEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /*if(isturf(D)) //Polaris doesn't support baseturfs yet. + var/turf/T = D + T.ScrapeAway() + else*/ + vv_update_display(D, "deleted", VV_MSG_DELETED) + qdel(D) + if(!QDELETED(D)) + vv_update_display(D, "deleted", "") diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index 620da27318..bcf097f813 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -8,9 +8,9 @@ name = DA[name] //name is really the index until this line else value = DA[name] - header = "
  • (E) (C) (-) " + header = "
  • (E) (C) (-) " else - header = "
  • (E) (C) (M) " + header = "
  • (E) (C) (M) " else header = "
  • " @@ -25,7 +25,7 @@ #ifdef VARSICON var/icon/I = new/icon(value) var/rnd = rand(1,10000) - var/rname = "tmp[REF(I)][rnd].png" + var/rname = "tmp\ref[I][rnd].png" usr << browse_rsc(I, rname) item = "[VV_HTML_ENCODE(name)] = ([value]) " #else @@ -38,9 +38,9 @@ else if (istype(value, /datum)) var/datum/D = value if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. - item = "[VV_HTML_ENCODE(name)] [REF(value)] = [D] [D.type]" + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" else - item = "[VV_HTML_ENCODE(name)] [REF(value)] = [D.type]" + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" else if (islist(value)) var/list/L = value @@ -58,9 +58,9 @@ items += debug_variable(key, val, level + 1, sanitize = sanitize) - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" else - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" else if (name in GLOB.bitfields) var/list/flags = list() diff --git a/code/modules/admin/view_variables/mass_edit_variables.dm b/code/modules/admin/view_variables/mass_edit_variables.dm index ba199350e3..7374759e8c 100644 --- a/code/modules/admin/view_variables/mass_edit_variables.dm +++ b/code/modules/admin/view_variables/mass_edit_variables.dm @@ -12,7 +12,7 @@ method = vv_subtype_prompt(A.type) src.massmodify_variables(A, var_name, method) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Edit Variables") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + feedback_add_details("admin_verb","MVV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/massmodify_variables(datum/O, var_name = "", method = 0) if(!check_rights(R_VAREDIT)) @@ -205,19 +205,19 @@ typecache = typecacheof(typecache) . = list() if (ispath(T, /mob)) - for(var/mob/thing in GLOB.mob_list) + for(var/mob/thing in mob_list) if (typecache[thing.type]) . += thing CHECK_TICK else if (ispath(T, /obj/machinery/door)) - for(var/obj/machinery/door/thing in GLOB.airlocks) + for(var/obj/machinery/door/thing in world) if (typecache[thing.type]) . += thing CHECK_TICK else if (ispath(T, /obj/machinery)) - for(var/obj/machinery/thing in GLOB.machines) + for(var/obj/machinery/thing in machines) if (typecache[thing.type]) . += thing CHECK_TICK diff --git a/code/modules/admin/view_variables/modify_variables.dm b/code/modules/admin/view_variables/modify_variables.dm index a7e88675f3..8e3838d2c7 100644 --- a/code/modules/admin/view_variables/modify_variables.dm +++ b/code/modules/admin/view_variables/modify_variables.dm @@ -62,7 +62,7 @@ GLOBAL_PROTECT(VVpixelmovement) if (!lentext(shorttype)) shorttype = "/" - .["[D]([shorttype])[REF(D)]#[i]"] = D + .["[D]([shorttype])\ref[D]#[i]"] = D /client/proc/mod_list_add_ass(atom/O) //hehe @@ -308,11 +308,6 @@ GLOBAL_PROTECT(VVpixelmovement) var_value = O.vars[variable] if(!vv_varname_lockcheck(variable)) return - if(istype(O, /datum/armor)) - var/prompt = alert(src, "Editing this var changes this value on potentially thousands of items that share the same combination of armor values. If you want to edit the armor of just one item, use the \"Modify armor values\" dropdown item", "DANGER", "ABORT ", "Continue", " ABORT") - if (prompt != "Continue") - return - var/default = vv_get_class(variable, var_value) @@ -376,7 +371,6 @@ GLOBAL_PROTECT(VVpixelmovement) to_chat(src, "Your edit was rejected by the object.") return vv_update_display(O, "varedited", VV_MSG_EDITED) - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args) log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]") log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]") var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]" diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index b1706bda77..35cff902d8 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -506,14 +506,14 @@ if (!C) return var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No") - if (prompt != "Yes" || !client) + if (prompt != "Yes") return if(!thing) to_chat(usr, "The object you tried to expose to [C] no longer exists (GC'd)") return message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]") - to_chat(C, "[client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") + to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") C.debug_variables(thing) if(href_list["datumrefresh"]) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm index d2c0f061be..43b77a7ee7 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin/view_variables/view_variables.dm @@ -16,7 +16,7 @@ return var/title = "" - var/refid = REF(D) + var/refid = "\ref[D]" var/icon/sprite var/hash @@ -34,7 +34,7 @@ hash = md5(hash + AT.icon_state) src << browse_rsc(sprite, "vv[hash].png") - title = "[D] ([REF(D)]) = [type]" + title = "[D] (\ref[D]) = [type]" var/formatted_type = replacetext("[type]", "/", "/") var/sprite_text @@ -336,4 +336,4 @@ datumrefresh=[refid]'>Refresh src << browse(html, "window=variables[refid];size=475x650") /client/proc/vv_update_display(datum/D, span, content) - src << output("[span]:[content]", "variables[REF(D)].browser:replace_span") + src << output("[span]:[content]", "variables\ref[D].browser:replace_span") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c1e05a1852..a8ff7a1205 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1275,7 +1275,7 @@ default behaviour is: /mob/living/proc/needs_to_breathe() return !isSynthetic() -/mob/living/get_view_variables_header() +/mob/living/vv_get_header() . = ..() . += {" [src] diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm index 06a3d3ba7b..75fb5fff2a 100644 --- a/code/modules/research/message_server.dm +++ b/code/modules/research/message_server.dm @@ -324,9 +324,13 @@ var/obj/machinery/blackbox_recorder/blackbox feedback_set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set. -/obj/machinery/blackbox_recorder/vv_edit_var() - var/obj/O = /obj //hacky as fuck kill me - if(var_name in (vars - initial(O.vars))) +/obj/machinery/blackbox_recorder/vv_edit_var(var_name, var_value) + var/static/list/blocked_vars //hacky as fuck kill me + if(!blocked_vars) + var/obj/machinery/M = new + var/list/parent_vars = M.vars.Copy() + blocked_vars = vars.Copy() - parent_vars + if(var_name in blocked_vars) return FALSE return ..() diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm index dc10bc85f9..e2821db1a9 100644 --- a/code/modules/virus2/admin.dm +++ b/code/modules/virus2/admin.dm @@ -15,7 +15,7 @@ return 1 -/datum/disease2/disease/get_view_variables_header() +/datum/disease2/disease/vv_get_header() . = list() for(var/datum/disease2/effectholder/E in effects) . += "[E.stage]: [E.effect.name]" diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm index 00eb61b79b..c5eb9b35ac 100644 --- a/code/modules/xenoarcheaology/tools/tools.dm +++ b/code/modules/xenoarcheaology/tools/tools.dm @@ -254,7 +254,7 @@ if(prob(scan_ticks * 10)) spawn(0) set background = 1 - if(is_processing) + if(datum_flags & DF_ISPROCESSING) //scan radios in the world to try and find one var/cur_dist = 999 for(var/obj/item/device/radio/beacon/R in all_beacons) diff --git a/polaris.dme b/polaris.dme index 8b97ef0d2c..14b0a796ee 100644 --- a/polaris.dme +++ b/polaris.dme @@ -69,6 +69,7 @@ #include "code\_compatibility\509\JSON Writer.dm" #include "code\_compatibility\509\text.dm" #include "code\_compatibility\509\type2type.dm" +#include "code\_global_vars\bitfields.dm" #include "code\_global_vars\misc.dm" #include "code\_global_vars\mobs.dm" #include "code\_global_vars\sensitive.dm" @@ -1286,8 +1287,6 @@ #include "code\modules\admin\verbs\lightning_strike.dm" #include "code\modules\admin\verbs\map_template_loadverb.dm" #include "code\modules\admin\verbs\mapping.dm" -#include "code\modules\admin\verbs\massmodvar.dm" -#include "code\modules\admin\verbs\modifyvariables.dm" #include "code\modules\admin\verbs\panicbunker.dm" #include "code\modules\admin\verbs\playsound.dm" #include "code\modules\admin\verbs\possess.dm" @@ -1300,6 +1299,7 @@ #include "code\modules\admin\verbs\SDQL2\SDQL_2.dm" #include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm" #include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm" +#include "code\modules\admin\view_variables\admin_delete.dm" #include "code\modules\admin\view_variables\debug_variables.dm" #include "code\modules\admin\view_variables\get_variables.dm" #include "code\modules\admin\view_variables\helpers_deprecated.dm"