From 6baa6801d3113be7edf9f16e9436e6e1fb283441 Mon Sep 17 00:00:00 2001 From: Lucy Date: Fri, 27 Feb 2026 11:53:10 -0500 Subject: [PATCH 1/2] allows separating items from numerical stacking in storage via labels/colors/etc --- code/__HELPERS/_lists.dm | 39 +++++++++++++++++++ .../code/datums/components/storage/ui.dm | 11 ++++++ .../master_files/code/game/objects/items.dm | 20 ++++++++++ modular_pentest/~pentest.dme | 2 + 4 files changed, 72 insertions(+) create mode 100644 modular_pentest/master_files/code/datums/components/storage/ui.dm create mode 100644 modular_pentest/master_files/code/game/objects/items.dm diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index c1277615e73..3c1bd14d4be 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -163,6 +163,45 @@ };\ } while(FALSE) +#define SORT_FIRST_INDEX(list) (list[1]) +#define SORT_PRIORITY_INDEX(list) (list["priority"]) +#define SORT_COMPARE_DIRECTLY(thing) (thing) +#define SORT_VAR_NO_TYPE(varname) var/varname +/**** + * Even more custom binary search sorted insert, using defines instead of vars + * INPUT: Item to be inserted + * LIST: List to insert INPUT into + * TYPECONT: A define setting the var to the typepath of the contents of the list + * COMPARE: The item to compare against, usualy the same as INPUT + * COMPARISON: A define that takes an item to compare as input, and returns their comparable value + * COMPTYPE: How should the list be compared? Either COMPARE_KEY or COMPARE_VALUE. + */ +#define BINARY_INSERT_DEFINE(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \ + do {\ + var/list/__BIN_LIST = LIST;\ + var/__BIN_CTTL = length(__BIN_LIST);\ + if(!__BIN_CTTL) {\ + __BIN_LIST += INPUT;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + ##TYPECONT(__BIN_ITEM);\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = COMPTYPE;\ + if(##COMPARISON(__BIN_ITEM) <= ##COMPARISON(COMPARE)) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + };\ + __BIN_ITEM = COMPTYPE;\ + __BIN_MID = ##COMPARISON(__BIN_ITEM) > ##COMPARISON(COMPARE) ? __BIN_MID : __BIN_MID + 1;\ + __BIN_LIST.Insert(__BIN_MID, INPUT);\ + };\ + } while(FALSE) + //Returns a list in plain english as a string /proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) var/total = length(input) diff --git a/modular_pentest/master_files/code/datums/components/storage/ui.dm b/modular_pentest/master_files/code/datums/components/storage/ui.dm new file mode 100644 index 00000000000..2ad0a336804 --- /dev/null +++ b/modular_pentest/master_files/code/datums/components/storage/ui.dm @@ -0,0 +1,11 @@ +/datum/component/storage/_process_numerical_display() + . = list() + for(var/obj/item/item in accessible_items()) + if(QDELING(item)) + continue + var/id = item.numerical_display_id() + if(!.[id]) + .[id] = new /datum/numbered_display(item, 1, src) + else + var/datum/numbered_display/display = .[id] + display.number++ diff --git a/modular_pentest/master_files/code/game/objects/items.dm b/modular_pentest/master_files/code/game/objects/items.dm new file mode 100644 index 00000000000..eb4114699a7 --- /dev/null +++ b/modular_pentest/master_files/code/game/objects/items.dm @@ -0,0 +1,20 @@ +/// Returns the "ID" used for grouping items together in numerical displays. +/obj/item/proc/numerical_display_id() + . = "[type]" + // adding a label separates them + var/datum/component/label/label = GetComponent(/datum/component/label) + if(label) + . += "-[label.label_name]" + // spray painting colors also separates them, if there is no label + else if(length(atom_colours) >= WASHABLE_COLOUR_PRIORITY && atom_colours[WASHABLE_COLOUR_PRIORITY]) + . += "-[atom_colours[WASHABLE_COLOUR_PRIORITY]]" + +// for beakers/bottles/etc, also group by what reagents they have +/obj/item/reagent_containers/numerical_display_id() + . = ..() + var/list/reagent_names = list() + // sort them first so that it's consistent no matter what order we inserted the reagents in + for(var/datum/reagent/reagent as anything in reagents.reagent_list) + BINARY_INSERT_DEFINE(reagent.name, reagent_names, SORT_VAR_NO_TYPE, reagent.name, SORT_COMPARE_DIRECTLY, COMPARE_KEY) + if(length(reagent_names)) + . += "+" + jointext(reagent_names, "+") diff --git a/modular_pentest/~pentest.dme b/modular_pentest/~pentest.dme index 71ad2f78f25..c6dbd22e923 100644 --- a/modular_pentest/~pentest.dme +++ b/modular_pentest/~pentest.dme @@ -23,6 +23,7 @@ #include "master_files\code\datums\dog_fashion.dm" #include "master_files\code\datums\holocall.dm" #include "master_files\code\datums\brain_damage\phobia.dm" +#include "master_files\code\datums\components\storage\ui.dm" #include "master_files\code\datums\components\slippery.dm" #include "master_files\code\datums\components\soulstoned.dm" #include "master_files\code\datums\components\crafting\recipes\misc.dm" @@ -42,6 +43,7 @@ #include "master_files\code\game\mecha\mech_fabricator.dm" #include "master_files\code\game\mecha\equipment\tools\mech_fabricator.dm" #include "master_files\code\game\objects\AI_modules.dm" +#include "master_files\code\game\objects\items.dm" #include "master_files\code\game\objects\effects\decals\turfdecal\flooring_decals.dm" #include "master_files\code\game\objects\effects\spawners\random\food_or_drink.dm" #include "master_files\code\game\objects\items\dna_injector.dm" From 11458fa3b7479146ad11eac8f645daa963647f6a Mon Sep 17 00:00:00 2001 From: Lucy Date: Fri, 27 Feb 2026 11:59:06 -0500 Subject: [PATCH 2/2] small optimization prolly --- modular_pentest/master_files/code/game/objects/items.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modular_pentest/master_files/code/game/objects/items.dm b/modular_pentest/master_files/code/game/objects/items.dm index eb4114699a7..7d6681b792b 100644 --- a/modular_pentest/master_files/code/game/objects/items.dm +++ b/modular_pentest/master_files/code/game/objects/items.dm @@ -6,8 +6,10 @@ if(label) . += "-[label.label_name]" // spray painting colors also separates them, if there is no label - else if(length(atom_colours) >= WASHABLE_COLOUR_PRIORITY && atom_colours[WASHABLE_COLOUR_PRIORITY]) - . += "-[atom_colours[WASHABLE_COLOUR_PRIORITY]]" + else if(length(atom_colours) >= WASHABLE_COLOUR_PRIORITY) + var/painted_color = atom_colours[WASHABLE_COLOUR_PRIORITY] + if(painted_color) + . += "-[painted_color]" // for beakers/bottles/etc, also group by what reagents they have /obj/item/reagent_containers/numerical_display_id()