diff --git a/code/__DEFINES/_bitfields.dm b/code/__DEFINES/_bitfields.dm index 19a962fbffe..4bf587c7101 100644 --- a/code/__DEFINES/_bitfields.dm +++ b/code/__DEFINES/_bitfields.dm @@ -1,4 +1,8 @@ -#define DEFINE_BITFIELD(_variable, _flags) /datum/bitfield/##_variable { \ +#define DEFINE_BITFIELD(_variable, _flags) \ +/* Important note: This exists to throw a compile time warning if more then one bitfield with the same name is defined */ \ +/* This is required to avoid dupes in vv, and any consumers of our bitfield metainfo procs */ \ +GLOBAL_REAL_VAR(_bitfield_##_variable); \ +/datum/bitfield/##_variable { \ flags = ##_flags; \ variable = #_variable; \ } diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 1a813cb1aad..b159fc201ee 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -16,6 +16,17 @@ GLOBAL_LIST_INIT(bitfields, generate_bitfields()) bitfields[bitfield.variable] = bitfield.flags return bitfields +/// Returns an associative list of bitflag name -> number for all valid bitflags in the passed in field +/proc/get_valid_bitflags(var_name) + return GLOB.bitfields[var_name] || list() + +/proc/get_random_bitflag(var_name) + var/list/flags = get_valid_bitflags(var_name) + if(!length(flags)) + return + var/name = pick(flags) + return flags[name] + DEFINE_BITFIELD(admin_flags, list( "ADMIN" = R_ADMIN, "AUTOLOGIN" = R_AUTOADMIN, diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 8027a2438f2..bff7b9f3cb7 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -312,25 +312,25 @@ if (A.selectedbutton) return list("button" = A.selectedbutton, "values" = A.valueslist) -/proc/input_bitfield(mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) - if (!User || !(bitfield in GLOB.bitfields)) +/proc/input_bitfield(mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_flags = ALL) + var/list/bitflags = get_valid_bitflags(bitfield) + if (!User || !length(bitflags)) 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) + var/list/picker_list = list() + for (var/bit_name in bitflags) + var/bit_value = bitflags[bit_name] + // TRUE/FALSE cast, sorry :) + var/can_edit = !!(allowed_edit_flags & bit_value) + var/flag_set = !!(current_value & bit_value) + picker_list += list(list("checked" = flag_set, "value" = bit_value, "name" = bit_name, "allowed_edit" = can_edit)) + + var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = picker_list, 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] + . = NONE + for (var/flag_name in result["values"]) + . |= bitflags[flag_name] else return diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index a4a4c525167..f0ffe85aa2d 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -471,7 +471,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm admin_holder.rank_flags(), 350, 590, - allowed_edit_list = usr.client.holder.can_edit_rights_flags(), + allowed_edit_flags = usr.client.holder.can_edit_rights_flags(), ) admin_holder.disassociate() diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index b776f1b5d79..34b34369299 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -86,21 +86,21 @@ items += debug_variable(key, val, level + 1, sanitize = sanitize) return "/list ([list_value.len])" - else - return "/list ([list_value.len])" + return "/list ([list_value.len])" - if(name in GLOB.bitfields) - var/list/flags = list() - for (var/i in GLOB.bitfields[name]) - if (value & GLOB.bitfields[name][i]) - flags += i - if(length(flags)) - return "[VV_HTML_ENCODE(jointext(flags, ", "))]" - else - return "NONE" - else + // if it's a number, is it a bitflag? + var/list/valid_bitflags = get_valid_bitflags(name) + if(!length(valid_bitflags)) return "[VV_HTML_ENCODE(value)]" + var/list/flags = list() + for (var/bit_name in valid_bitflags) + if (value & valid_bitflags[bit_name]) + flags += bit_name + if(length(flags)) + return "[VV_HTML_ENCODE(flags.Join(", "))]" + return "NONE" + /datum/proc/debug_variable_value(name, level, datum/owner, sanitize, display_flags) if("[src]" != "[type]") // If we have a name var, let's use it. return "[src] [type] [REF(src)]" diff --git a/code/modules/admin/view_variables/get_variables.dm b/code/modules/admin/view_variables/get_variables.dm index d493831da67..34bcc07b5c2 100644 --- a/code/modules/admin/view_variables/get_variables.dm +++ b/code/modules/admin/view_variables/get_variables.dm @@ -3,7 +3,7 @@ . = VV_NULL else if(isnum(var_value)) - if(var_name in GLOB.bitfields) + if(length(get_valid_bitflags(var_name))) . = VV_BITFIELD else . = VV_NUM diff --git a/code/modules/admin/view_variables/modify_variables.dm b/code/modules/admin/view_variables/modify_variables.dm index d8255f8b397..13b3a2aa398 100644 --- a/code/modules/admin/view_variables/modify_variables.dm +++ b/code/modules/admin/view_variables/modify_variables.dm @@ -65,7 +65,6 @@ GLOBAL_PROTECT(VVpixelmovement) .["[D]([shorttype])[REF(D)]#[i]"] = D /client/proc/mod_list_add_ass(atom/O) //hehe - var/list/L = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT)) var/class = L["class"] if (!class)