mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-16 20:52:33 +00:00
Done using this command sed -Ei 's/(\s*\S+)\s*\t+/\1 /g' code/**/*.dm We have countless examples in the codebase with this style gone wrong, and defines and such being on hideously different levels of indentation. Fixing this to keep the alignment involves tainting the blames of code your PR doesn't need to be touching at all. And ultimately, it's hideous. There are some files that this sed makes uglier. I can fix these when they are pointed out, but I believe this is ultimately for the greater good of readability. I'm more concerned with if any strings relied on this. Hi codeowners! Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
275 lines
7.6 KiB
Plaintext
275 lines
7.6 KiB
Plaintext
/client/proc/cmd_mass_modify_object_variables(atom/A, 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 items)
|
|
|
|
if(tgui_alert(src, "Are you sure you'd like to mass-modify every instance of the [var_name] variable? This can break everything if you do not know what you are doing.", "Slow down, chief!", list("Yes", "No")) != "Yes")
|
|
return
|
|
|
|
if(!check_rights(R_VAREDIT))
|
|
return
|
|
|
|
if(A?.type)
|
|
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!
|
|
|
|
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
|
|
if(!check_rights(R_VAREDIT))
|
|
return
|
|
if(!istype(O))
|
|
return
|
|
|
|
var/variable = ""
|
|
if(!var_name)
|
|
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
|
|
else
|
|
variable = var_name
|
|
|
|
if(!variable || !O.can_vv_get(variable))
|
|
return
|
|
var/default
|
|
var/var_value = O.vars[variable]
|
|
|
|
if(variable in GLOB.VVckey_edit)
|
|
to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.", confidential = TRUE)
|
|
return
|
|
if(variable in GLOB.VVlocked)
|
|
if(!check_rights(R_DEBUG))
|
|
return
|
|
if(variable in GLOB.VVicon_edit_lock)
|
|
if(!check_rights(R_FUN|R_DEBUG))
|
|
return
|
|
if(variable in GLOB.VVpixelmovement)
|
|
if(!check_rights(R_DEBUG))
|
|
return
|
|
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
|
|
if (prompt != "Continue")
|
|
return
|
|
|
|
default = vv_get_class(variable, var_value)
|
|
|
|
if(isnull(default))
|
|
to_chat(src, "Unable to determine variable type.", confidential = TRUE)
|
|
else
|
|
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.", confidential = TRUE)
|
|
|
|
to_chat(src, "Variable contains: [var_value]", confidential = TRUE)
|
|
|
|
if(default == VV_NUM)
|
|
var/dir_text = ""
|
|
if(var_value > 0 && var_value < 16)
|
|
if(var_value & 1)
|
|
dir_text += "NORTH"
|
|
if(var_value & 2)
|
|
dir_text += "SOUTH"
|
|
if(var_value & 4)
|
|
dir_text += "EAST"
|
|
if(var_value & 8)
|
|
dir_text += "WEST"
|
|
|
|
if(dir_text)
|
|
to_chat(src, "If a direction, direction is: [dir_text]", confidential = TRUE)
|
|
|
|
var/value = vv_get_value(default_class = default)
|
|
var/new_value = value["value"]
|
|
var/class = value["class"]
|
|
|
|
if(!class || !new_value == null && class != VV_NULL)
|
|
return
|
|
|
|
if (class == VV_MESSAGE)
|
|
class = VV_TEXT
|
|
|
|
if (value["type"])
|
|
class = VV_NEW_TYPE
|
|
|
|
var/original_name = "[O]"
|
|
|
|
var/rejected = 0
|
|
var/accepted = 0
|
|
|
|
switch(class)
|
|
if(VV_RESTORE_DEFAULT)
|
|
to_chat(src, "Finding items...", confidential = TRUE)
|
|
var/list/items = get_all_of_type(O.type, method)
|
|
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
|
for(var/thing in items)
|
|
if (!thing)
|
|
continue
|
|
var/datum/D = thing
|
|
if (D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
|
|
accepted++
|
|
else
|
|
rejected++
|
|
CHECK_TICK
|
|
|
|
if(VV_TEXT)
|
|
var/list/varsvars = vv_parse_text(O, new_value)
|
|
var/pre_processing = new_value
|
|
var/unique
|
|
if (varsvars?.len)
|
|
unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same")
|
|
if(unique == "Unique")
|
|
unique = TRUE
|
|
else
|
|
unique = FALSE
|
|
for(var/V in varsvars)
|
|
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
|
|
|
|
to_chat(src, "Finding items...", confidential = TRUE)
|
|
var/list/items = get_all_of_type(O.type, method)
|
|
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
|
for(var/thing in items)
|
|
if (!thing)
|
|
continue
|
|
var/datum/D = thing
|
|
if(unique)
|
|
new_value = pre_processing
|
|
for(var/V in varsvars)
|
|
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
|
|
|
|
if (D.vv_edit_var(variable, new_value) != FALSE)
|
|
accepted++
|
|
else
|
|
rejected++
|
|
CHECK_TICK
|
|
|
|
if (VV_NEW_TYPE)
|
|
var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel")
|
|
if (many == "Cancel")
|
|
return
|
|
if (many == "Many")
|
|
many = TRUE
|
|
else
|
|
many = FALSE
|
|
|
|
var/type = value["type"]
|
|
to_chat(src, "Finding items...", confidential = TRUE)
|
|
var/list/items = get_all_of_type(O.type, method)
|
|
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
|
for(var/thing in items)
|
|
if (!thing)
|
|
continue
|
|
var/datum/D = thing
|
|
if(many && !new_value)
|
|
new_value = new type()
|
|
|
|
if (D.vv_edit_var(variable, new_value) != FALSE)
|
|
accepted++
|
|
else
|
|
rejected++
|
|
new_value = null
|
|
CHECK_TICK
|
|
|
|
else
|
|
to_chat(src, "Finding items...", confidential = TRUE)
|
|
var/list/items = get_all_of_type(O.type, method)
|
|
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
|
for(var/thing in items)
|
|
if (!thing)
|
|
continue
|
|
var/datum/D = thing
|
|
if (D.vv_edit_var(variable, new_value) != FALSE)
|
|
accepted++
|
|
else
|
|
rejected++
|
|
CHECK_TICK
|
|
|
|
|
|
var/count = rejected+accepted
|
|
if (!count)
|
|
to_chat(src, "No objects found", confidential = TRUE)
|
|
return
|
|
if (!accepted)
|
|
to_chat(src, "Every object rejected your edit", confidential = TRUE)
|
|
return
|
|
if (rejected)
|
|
to_chat(src, "[rejected] out of [count] objects rejected your edit", confidential = TRUE)
|
|
|
|
log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])")
|
|
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
|
|
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
|
|
|
|
//not using global lists as vv is a debug function and debug functions should rely on as less things as possible.
|
|
/proc/get_all_of_type(T, subtypes = TRUE)
|
|
var/list/typecache = list()
|
|
typecache[T] = 1
|
|
if (subtypes)
|
|
typecache = typecacheof(typecache)
|
|
. = list()
|
|
if (ispath(T, /mob))
|
|
for(var/mob/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /obj/machinery/door))
|
|
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 world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /obj/item))
|
|
for(var/obj/item/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /obj))
|
|
for(var/obj/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /atom/movable))
|
|
for(var/atom/movable/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /turf))
|
|
for(var/turf/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /atom))
|
|
for(var/atom/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /client))
|
|
for(var/client/thing in GLOB.clients)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else if (ispath(T, /datum))
|
|
for(var/datum/thing)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|
|
|
|
else
|
|
for(var/datum/thing in world)
|
|
if (typecache[thing.type])
|
|
. += thing
|
|
CHECK_TICK
|