From 5c53314ee362dd3e7fe9d742533a70c05b5a96da Mon Sep 17 00:00:00 2001
From: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Date: Wed, 8 Apr 2020 00:57:09 -0700
Subject: [PATCH] cancel
---
code/__DEFINES/storage.dm | 4 +-
code/_onclick/hud/screen_objects/storage.dm | 10 ++
code/datums/components/storage/storage.dm | 2 +
code/datums/components/storage/ui.dm | 135 ++++++++++++--------
4 files changed, 95 insertions(+), 56 deletions(-)
diff --git a/code/__DEFINES/storage.dm b/code/__DEFINES/storage.dm
index 27bf502252..56fa599dc3 100644
--- a/code/__DEFINES/storage.dm
+++ b/code/__DEFINES/storage.dm
@@ -29,6 +29,8 @@
// UI defines
/// Minimum pixels an item must have in volumetric scaled storage UI
-#define MINIMUM_PIXELS_PER_ITEM 5
+#define MINIMUM_PIXELS_PER_ITEM 4
+/// The size of the volumetric scaled storage UI's volumetric boxes that's rendered behind items.
+#define VOLUMETRIC_STORAGE_BOX_SIZE 8
/// Maximum number of objects that will be allowed to be displayed using the volumetric display system. Arbitrary number to prevent server lockups.
#define MAXIMUM_VOLUMETRIC_ITEMS 256
diff --git a/code/_onclick/hud/screen_objects/storage.dm b/code/_onclick/hud/screen_objects/storage.dm
index 5e78ba45e0..56d921472c 100644
--- a/code/_onclick/hud/screen_objects/storage.dm
+++ b/code/_onclick/hud/screen_objects/storage.dm
@@ -39,3 +39,13 @@
var/datum/component/storage/S = master
S.hide_from(usr)
return TRUE
+
+/obj/screen/storage/volumetric_box
+ var/obj/item/our_item
+
+/obj/screen/storage/volumetric_box/Initialize(mapload, new_master, our_item)
+ src.our_item = our_item
+ return ..()
+
+/obj/screen/storage/volumetric_box/Click(location, control, params)
+ return our_item.Click(location, control, params)
diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm
index c3ac3c48a8..8f053961e5 100644
--- a/code/datums/components/storage/storage.dm
+++ b/code/datums/components/storage/storage.dm
@@ -360,6 +360,8 @@
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
_removal_reset(thing)
+ qdel(ui_item_blocks[thing])
+ ui_item_blocks -= thing
refresh_mob_views()
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
diff --git a/code/datums/components/storage/ui.dm b/code/datums/components/storage/ui.dm
index f73aff43ec..b014ef9dd1 100644
--- a/code/datums/components/storage/ui.dm
+++ b/code/datums/components/storage/ui.dm
@@ -72,73 +72,98 @@
break
/**
- * Orients all objects in .. volumetric mode.
+ * Orients all objects in .. volumetric mode. Does not support numerical display!
*/
/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
. = list()
- var/list/accessible_contents = accessible_items()
- var/adjusted_contents = length(accessible_contents)
- //Numbered contents display
- var/list/datum/numbered_display/numbered_contents
- if(display_numerical_stacking)
- numbered_contents = _process_numerical_display()
- adjusted_contents = numbered_contents.len
+ // Generate ui_item_blocks for missing ones and render+orient.
+ var/list/atom/contents = accessible_items()
- var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns)
- var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows)
+ var/horizontal_pixels = maxcolumns * world.icon_size
+ // do the check for fallback for when someone has too much gamer gear
+ if((MINIMUM_PIXELS_PER_ITEMS * length(contents)) > horizontal_pixels)
+ to_chat(user, "[parent] was showed to you in legacy mode due to your items overrunning the three row limit! Consider not carrying too much or bugging a maintainer to raise this limit!")
+ return orient2hud_legacy(user, maxcolumns)
+ // after this point we are sure we can somehow fit all items with 8 pixels or more into our one row.
- // First, continuous section.
- ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
+
+ // sigh. two loops.
+ var/total = max_volume
+
+ var/used = 0
+
+ var/list/volume_by_item = list()
+ var/list/percentage_by_item = list()
+ var/list/percentages = list()
+ // define outside for less lag
+ var/obj/item/I
+ var/volume
+ for(var/obj/item/I in contents)
+ volume = I.get_volume()
+ used += volume_by_item[I] = volume
+ percentages += percentage_by_item[I] = volume
+ // ugh
+ var/min_percent = min(percentages)
+
+ var/percentage_metric = max(min_percent,
+
+ var/pixels_needed = (100 / min_percent) * MINIMUM_PIXELS_PER_ITEM
+
+ var/overrunning = pixels_needed > maximum_horizontal_pixels
+
+ var/row = 1
+ var/pixel = 0
+
+ for(var/i in volume_by_item)
+ I = i
+ if(!ui_item_blocks[I])
+ ui_item_blocks[I] = new /obj/screen/storage(null, src, I)
+ var/obj/screen/storage/volumetric_box/B = ui_item_blocks[I]
+
+ . += B
+ var/pixels_to_use
+ if(!overrunning)
+ pixels_to_use = CEILING(min_percent / percentage_by_item[i], MINIMUM_PIXELS_PER_ITEM)
+ else
+ pixels_to_use = MINIMUM_PIXELS_PER_ITEM //not enough room to display everything ughh
+
+ // now that we have pixels_to_use, place our thing and add it to the returned list.
+
+ // uh oh, increment row or clamp.
+ if((horizontal_pixels - pixel) < pixels_to_use)
+ if(!pixels_to_use)
+ row++
+ else
+ pixels_to_use = (horizontal_pixels - pixel)
+ // now, scale the thing
+ var/multiply = pixels_to_use / MINIMUM_PIXELS_PER_ITEM
+ B.transform = matrix(multiply, 0, 0, 0, 1, 0)
+ // unfortunately since scaling means expand-from-center.. ugh..
+ var/px_add = 0
+ if(multiply > 1)
+ px_add = (pixels_to_use - MINIMUM_PIXELS_PER_ITEM) * 0.5
+ // not handling multiply < 1, that should never happen.
+ // now, screenloc the thing.
+ var/xshift = FLOOR(pixel / icon_size, 1)
+ var/px = pixel % world.icon_Size
+ B.screen_loc = "[screen_start_x + xshift]:[px],[screen_start_y+rows-1]:[screen_pixel_y]"
+ pixels += px
+ if(pixels >= horizontal_pixels)
+ row++
+ . += B
+
+ // Then, continuous section.
+ ui_continuous.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]"
. += ui_continuous
// Then, left and right.
ui_left.screen_loc = "[screen_start_x]:[screen_pixel_x - 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x]:[screen_pixel_x - 2],[screen_start_y+rows-1]:[screen_pixel_y]"
. += ui_left
- ui_right.screen_loc = "[screen_start_x+columns-1]:[screen_pixel_x + 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x+columns-1]:[screen_pixel_x + 2],[screen_start_y+rows-1]:[screen_pixel_y]"
+ ui_right.screen_loc = "[screen_start_x+maxcolumns-1]:[screen_pixel_x + 2],[screen_start_y]:[screen_pixel_y] to [screen_start_x+maxcolumns-1]:[screen_pixel_x + 2],[screen_start_y+rows-1]:[screen_pixel_y]"
. += ui_right
// Then, closer.
- closer.screen_loc = "[screen_start_x + columns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
+ closer.screen_loc = "[screen_start_x + maxcolumns]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]"
. += ui_closer
- // Generate ui_item_blocks for missing ones.
-
-
-
-
-
-
- var/cx = screen_start_x
- var/cy = screen_start_y
- if(islist(numerical_display_contents))
- for(var/type in numerical_display_contents)
- var/datum/numbered_display/ND = numerical_display_contents[type]
- ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE
- ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
- ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]"
- ND.sample_object.layer = ABOVE_HUD_LAYER
- ND.sample_object.plane = ABOVE_HUD_PLANE
- . += ND.sample_object
- cx++
- if(cx - screen_start_x >= columns)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
- else
- for(var/obj/O in accessible_items())
- if(QDELETED(O))
- continue
- O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
- O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
- O.maptext = ""
- O.layer = ABOVE_HUD_LAYER
- O.plane = ABOVE_HUD_PLANE
- . += O
- cx++
- if(cx - screen_start_x >= columns)
- cx = screen_start_x
- cy++
- if(cy - screen_start_y >= rows)
- break
/**
* Shows our UI to a mob.
@@ -204,7 +229,7 @@
*/
/datum/component/storage/proc/volumetric_ui()
var/atom/real_location = real_location()
- return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_OBJECTS)
+ return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_OBJECTS) && !display_numeric_stacking
/**
* Gets the ui item objects to ui_hide.