From 80ec8ac200861545972a92c10832226c8f46d68a Mon Sep 17 00:00:00 2001 From: Atermonera Date: Sat, 1 Feb 2020 14:59:37 -0800 Subject: [PATCH] Merge pull request #6656 from Amunak/countable-lists Prettifies closet contents list with (newly added) countable variant of english_list --- code/_helpers/_lists.dm | 65 ++++++++++++++++++- .../structures/crates_lockers/closets.dm | 13 ++-- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/code/_helpers/_lists.dm b/code/_helpers/_lists.dm index 1eb8ac54560..bc6b46ea186 100644 --- a/code/_helpers/_lists.dm +++ b/code/_helpers/_lists.dm @@ -5,18 +5,79 @@ * Sorting */ +// Determiner constants +#define DET_NONE 0x00; +#define DET_DEFINITE 0x01; // the +#define DET_INDEFINITE 0x02; // a, an, some +#define DET_AUTO 0x04; + /* * Misc */ //Returns a list in plain english as a string -/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) +/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "") + // this proc cannot be merged with counting_english_list to maintain compatibility + // with shoddy use of this proc for code logic and for cases that require original order switch(input.len) if(0) return nothing_text if(1) return "[input[1]]" if(2) return "[input[1]][and_text][input[2]]" else return "[jointext(input, comma_text, 1, -1)][final_comma_text][and_text][input[input.len]]" +//Returns a newline-separated list that counts equal-ish items, outputting count and item names, optionally with icons and specific determiners +/proc/counting_english_list(var/list/input, output_icons = TRUE, determiners = DET_NONE, nothing_text = "nothing", line_prefix = "\t", first_item_prefix = "\n", last_item_suffix = "\n", and_text = "\n", comma_text = "\n", final_comma_text = "") + var/list/counts = list() // counted input items + var/list/items = list() // actual objects for later reference (for icons and formatting) + + // count items + for(var/item in input) + var/name = "[item]" // index items by name; usually works fairly well for loose equality + if(name in counts) + counts[name]++ + else + counts[name] = 1 + items.Add(item) + + // assemble the output list + var/list/out = list() + var/i = 0 + for(var/item in items) + var/name = "[item]" + var/count = counts[name] + var/item_str = line_prefix + if(count > 1) + item_str += "[count]x " + + if(isatom(item)) + // atoms/items/objects can be pretty and whatnot + var/atom/A = item + if(output_icons && isicon(A.icon) && !ismob(A)) // mobs tend to have unusable icons + item_str += "\icon[A] " + switch(determiners) + if(DET_NONE) item_str += A.name + if(DET_DEFINITE) item_str += "\the [A]" + if(DET_INDEFINITE) item_str += "\a [A]" + else item_str += name + else + // non-atoms use plain string conversion + item_str += name + + if(i == 0) + item_str = first_item_prefix + item_str + if(i == items.len - 1) + item_str = item_str + last_item_suffix + + out.Add(item_str) + i++ + + // finally return the list using regular english_list builder + return english_list(out, nothing_text, and_text, comma_text, final_comma_text) + +//A "preset" for counting_english_list that displays the list "inline" (comma separated) +/proc/inline_counting_english_list(var/list/input, output_icons = TRUE, determiners = DET_NONE, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "", line_prefix = "", first_item_prefix = "", last_item_suffix = "") + return counting_english_list(input, output_icons, determiners, nothing_text, and_text, comma_text, final_comma_text) + //Returns list element or null. Should prevent "index out of bounds" error. proc/listgetindex(var/list/list,index) if(istype(list) && list.len) @@ -762,4 +823,4 @@ proc/dd_sortedTextList(list/incoming) /proc/popleft(list/L) if(L.len) . = L[1] - L.Cut(1,2) + L.Cut(1,2) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 95d38c4473d..b75e3de6ed1 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -58,7 +58,7 @@ update_icon() /obj/structure/closet/examine(mob/user) - if(..(user, 1) && !opened) + if(!src.opened && (..(user, 1) || isobserver(user))) var/content_size = 0 for(var/obj/item/I in src.contents) if(!I.anchored) @@ -74,6 +74,9 @@ else to_chat(user, "It is full.") + if(!src.opened && isobserver(user)) + to_chat(user, "It contains: [counting_english_list(contents)]") + /obj/structure/closet/CanPass(atom/movable/mover, turf/target) if(wall_mounted) return TRUE @@ -360,12 +363,6 @@ if(!src.toggle()) to_chat(usr, "It won't budge!") -/obj/structure/closet/attack_ghost(mob/ghost) - if(ghost.client && ghost.client.inquisitive_ghost) - ghost.examinate(src) - if (!src.opened) - to_chat(ghost, "It contains: [english_list(contents)].") - /obj/structure/closet/verb/verb_toggleopen() set src in oview(1) set category = "Object" @@ -474,4 +471,4 @@ return dump_contents() spawn(1) qdel(src) - return 1 \ No newline at end of file + return 1