renders storage objects independently per user (#14545)

* sigh

* sigh

* override

* hah..

* kinda working

* done
This commit is contained in:
silicons
2021-04-13 07:16:21 -06:00
committed by GitHub
parent 62bebf1261
commit ef2482c6b0
6 changed files with 94 additions and 96 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } }
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
#define LAZYOR(L, I) if(!L) { L = list(); } L |= I;
#define LAZYFIND(L, V) L ? L.Find(V) : 0
#define LAZYFIND(L, V) (L ? L.Find(V) : 0)
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null)
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
#define LAZYLEN(L) length(L)
+47 -9
View File
@@ -85,21 +85,16 @@
makeItemInactive()
/obj/screen/storage/volumetric_box/proc/makeItemInactive()
if(!our_item)
return
our_item.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
our_item.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
return
/obj/screen/storage/volumetric_box/proc/makeItemActive()
if(!our_item)
return
our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
return
/obj/screen/storage/volumetric_box/center
icon_state = "stored_continue"
var/obj/screen/storage/volumetric_edge/stored_left/left
var/obj/screen/storage/volumetric_edge/stored_right/right
var/obj/screen/storage/item_holder/holder
var/pixel_size
/obj/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item)
@@ -110,6 +105,9 @@
/obj/screen/storage/volumetric_box/center/Destroy()
QDEL_NULL(left)
QDEL_NULL(right)
vis_contents.Cut()
if(holder)
QDEL_NULL(holder)
return ..()
/obj/screen/storage/volumetric_box/center/proc/on_screen_objects()
@@ -123,13 +121,36 @@
return
pixel_size = pixels
cut_overlays()
vis_contents.Cut()
//our icon size is 32 pixels.
transform = matrix((pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE, 0, 0, 0, 1, 0)
var/multiplier = (pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE
transform = matrix(multiplier, 0, 0, 0, 1, 0)
if(our_item)
if(holder)
qdel(holder)
holder = new(null, src, our_item)
holder.transform = matrix(1 / multiplier, 0, 0, 0, 1, 0)
holder.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
holder.appearance_flags &= ~RESET_TRANSFORM
makeItemInactive()
vis_contents += holder
left.pixel_x = -((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) - VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
right.pixel_x = ((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) + VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
add_overlay(left)
add_overlay(right)
/obj/screen/storage/volumetric_box/center/makeItemInactive()
if(!holder)
return
holder.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
holder.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
/obj/screen/storage/volumetric_box/center/makeItemActive()
if(!holder)
return
holder.our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
holder.our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
/obj/screen/storage/volumetric_edge
layer = VOLUMETRIC_STORAGE_BOX_LAYER
plane = VOLUMETRIC_STORAGE_BOX_PLANE
@@ -157,3 +178,20 @@
/obj/screen/storage/volumetric_edge/stored_right
icon_state = "stored_end"
appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM
/obj/screen/storage/item_holder
var/obj/item/our_item
vis_flags = NONE
/obj/screen/storage/item_holder/Initialize(mapload, new_master, obj/item/I)
. = ..()
our_item = I
vis_contents += I
/obj/screen/storage/item_holder/Destroy()
vis_contents.Cut()
our_item = null
return ..()
/obj/screen/storage/item_holder/Click(location, control, params)
return our_item.Click(location, control, params)
+12 -31
View File
@@ -47,18 +47,8 @@
var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
/// "legacy"/default view mode's storage "boxes"
var/obj/screen/storage/boxes/ui_boxes
/// New volumetric storage display mode's left side
var/obj/screen/storage/left/ui_left
/// New volumetric storage display mode's center 'blocks'
var/obj/screen/storage/continuous/ui_continuous
/// The close button, used in all modes. Frames right side in volumetric mode.
var/obj/screen/storage/close/ui_close
/// Associative list of list(item = screen object) for volumetric storage item screen blocks
var/list/ui_item_blocks
var/current_maxscreensize
/// Ui objects by person. mob = list(objects)
var/list/ui_by_mob = list()
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -125,18 +115,16 @@
/datum/component/storage/Destroy()
close_all()
QDEL_NULL(ui_boxes)
QDEL_NULL(ui_close)
QDEL_NULL(ui_continuous)
QDEL_NULL(ui_left)
// DO NOT USE QDEL_LIST_ASSOC.
if(ui_item_blocks)
for(var/i in ui_item_blocks)
qdel(ui_item_blocks[i]) //qdel the screen object not the item
ui_item_blocks.Cut()
wipe_ui_objects()
LAZYCLEARLIST(is_using)
return ..()
/datum/component/storage/proc/wipe_ui_objects()
for(var/i in ui_by_mob)
var/list/objects = ui_by_mob[i]
QDEL_LIST(objects)
ui_by_mob.Cut()
/datum/component/storage/PreTransfer()
update_actions()
@@ -351,13 +339,6 @@
return master._removal_reset(thing)
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
if(LAZYACCESS(ui_item_blocks, thing))
var/obj/screen/storage/volumetric_box/center/C = ui_item_blocks[thing]
for(var/i in can_see_contents()) //runtimes result if mobs can access post deletion.
var/mob/M = i
M.client?.screen -= C.on_screen_objects()
ui_item_blocks -= thing
qdel(C)
_removal_reset(thing) // THIS NEEDS TO HAPPEN AFTER SO LAYERING DOESN'T BREAK!
refresh_mob_views()
@@ -467,14 +448,14 @@
return
A.add_fingerprint(M)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, ghost = FALSE)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
var/atom/A = parent
if(!istype(M))
return FALSE
A.add_fingerprint(M)
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
ui_show(M, !ghost)
ui_show(M)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -596,7 +577,7 @@
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
return user_show_to_mob(M, TRUE, TRUE)
return user_show_to_mob(M, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
return user_show_to_mob(showto, force)
+32 -53
View File
@@ -7,7 +7,7 @@
if(QDELETED(I))
continue
if(!.[I.type])
.[I.type] = new /datum/numbered_display(I, 1)
.[I.type] = new /datum/numbered_display(I, 1, src)
else
var/datum/numbered_display/ND = .[I.type]
ND.number++
@@ -20,6 +20,8 @@
. = list()
var/list/accessible_contents = accessible_items()
var/adjusted_contents = length(accessible_contents)
var/obj/screen/storage/close/ui_close
var/obj/screen/storage/boxes/ui_boxes
//Numbered contents display
var/list/datum/numbered_display/numbered_contents
@@ -60,12 +62,13 @@
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]"
var/obj/screen/storage/item_holder/D = new(null, src, O)
D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
O.maptext = ""
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
. += O
. += D
cx++
if(cx - screen_start_x >= columns)
cx = screen_start_x
@@ -78,6 +81,9 @@
*/
/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
. = list()
var/obj/screen/storage/left/ui_left
var/obj/screen/storage/continuous/ui_continuous
var/obj/screen/storage/close/ui_close
// Generate ui_item_blocks for missing ones and render+orient.
var/list/atom/contents = accessible_items()
@@ -128,14 +134,10 @@
var/first = TRUE
var/row = 1
LAZYINITLIST(ui_item_blocks)
for(var/i in percentage_by_item)
I = i
var/percent = percentage_by_item[I]
if(!ui_item_blocks[I])
ui_item_blocks[I] = new /obj/screen/storage/volumetric_box/center(null, src, I)
var/obj/screen/storage/volumetric_box/center/B = ui_item_blocks[I]
var/obj/screen/storage/volumetric_box/center/B = new /obj/screen/storage/volumetric_box/center(null, src, I)
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
var/addrow = FALSE
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
@@ -143,25 +145,17 @@
addrow = TRUE
// now that we have pixels_to_use, place our thing and add it to the returned list.
B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]"
B.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]"
// add the used pixels to pixel after we place the object
current_pixel += pixels_to_use + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING)
first = FALSE //apply padding to everything after this
// set various things
B.set_pixel_size(pixels_to_use)
B.layer = VOLUMETRIC_STORAGE_BOX_LAYER
B.plane = VOLUMETRIC_STORAGE_BOX_PLANE
B.name = I.name
I.mouse_opacity = MOUSE_OPACITY_ICON
I.maptext = ""
I.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
I.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
// finally add our things.
. += B.on_screen_objects()
. += I
// go up a row if needed
if(addrow)
@@ -185,18 +179,19 @@
/**
* Shows our UI to a mob.
*/
/datum/component/storage/proc/ui_show(mob/M, set_screen_size = TRUE)
/datum/component/storage/proc/ui_show(mob/M)
if(!M.client)
return FALSE
if(ui_by_mob[M] || LAZYFIND(is_using, M))
// something went horribly wrong
// hide first
ui_hide(M)
var/list/cview = getviewsize(M.client.view)
// in tiles
var/maxallowedscreensize = cview[1]-8
if(set_screen_size)
current_maxscreensize = maxallowedscreensize
else if(current_maxscreensize)
maxallowedscreensize = current_maxscreensize
// we got screen size, register signal
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout, override = TRUE)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/on_logout, override = TRUE)
if(M.active_storage != src)
if(M.active_storage)
M.active_storage.ui_hide(M)
@@ -204,10 +199,14 @@
LAZYOR(is_using, M)
if(!M.client?.prefs?.no_tetris_storage && volumetric_ui())
//new volumetric ui bay-style
M.client.screen |= orient2hud_volumetric(M, maxallowedscreensize)
var/list/objects = orient2hud_volumetric(M, maxallowedscreensize)
M.client.screen |= objects
ui_by_mob[M] = objects
else
//old ui
M.client.screen |= orient2hud_legacy(M, maxallowedscreensize)
var/list/objects = orient2hud_legacy(M, maxallowedscreensize)
M.client.screen |= objects
ui_by_mob[M] = objects
return TRUE
/**
@@ -236,8 +235,10 @@
/datum/component/storage/proc/ui_hide(mob/M)
if(!M.client)
return TRUE
UnregisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT)
M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide(M)
UnregisterSignal(M, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_CLIENT_LOGOUT))
M.client.screen -= ui_by_mob[M]
var/list/objects = ui_by_mob[M]
QDEL_LIST(objects)
if(M.active_storage == src)
M.active_storage = null
LAZYREMOVE(is_using, M)
@@ -250,48 +251,26 @@
var/atom/real_location = real_location()
return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_ITEMS) && !display_numerical_stacking
/**
* Gets the ui item objects to ui_hide.
*/
/datum/component/storage/proc/get_ui_item_objects_hide(mob/M)
if(!volumetric_ui() || M.client?.prefs?.no_tetris_storage)
var/atom/real_location = real_location()
return real_location.contents
else
. = list()
for(var/i in ui_item_blocks)
// get both the box and the item
. += ui_item_blocks[i]
. += i
/**
* Gets our ui_boxes, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_boxes()
if(!ui_boxes)
ui_boxes = new(null, src)
return ui_boxes
return new /obj/screen/storage/boxes(null, src)
/**
* Gets our ui_left, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_left()
if(!ui_left)
ui_left = new(null, src)
return ui_left
return new /obj/screen/storage/left(null, src)
/**
* Gets our ui_close, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_close()
if(!ui_close)
ui_close = new(null, src)
return ui_close
return new /obj/screen/storage/close(null, src)
/**
* Gets our ui_continuous, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_continuous()
if(!ui_continuous)
ui_continuous = new(null, src)
return ui_continuous
return new /obj/screen/storage/continuous(null, src)
+2 -2
View File
@@ -3,8 +3,8 @@
var/obj/item/sample_object
var/number
/datum/numbered_display/New(obj/item/sample, _number = 1)
/datum/numbered_display/New(obj/item/sample, _number = 1, datum/component/storage/parent)
if(!istype(sample))
qdel(src)
sample_object = sample
sample_object = new /obj/screen/storage/item_holder(null, parent, sample)
number = _number