mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-10 17:04:36 +00:00
[MIRROR] Progress bars & cleaning particles will centre on the tile occupied by large icon objects [MDB IGNORE] (#23394)
* Progress bars & cleaning particles will centre on the tile occupied by large icon objects (#77940) ## About The Pull Request Do_after bars always draw based on the top-left corner of the targetted atom, for atoms with sprites that are larger than 32x32 this gives them a weird offset instead of being centred, which bugs me. I have tried my best to figure out a way to reverse this which does not interfere with atoms which use pixel_x/pixel_y to visually appear to be on a different tile. ## Why It's Good For The Game Before:  he hates how you missed him completely 😦 After:  now you're cleaning his feet 🙂 ## Changelog 🆑 image: progress bars and cleaning particles are now centered on the tile occupied by the target, if it is a big sprite /🆑 * Progress bars & cleaning particles will centre on the tile occupied by large icon objects --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
@@ -323,3 +323,15 @@ rough example of the "cone" made by the 3 dirs checked
|
|||||||
if(!storage_datum)
|
if(!storage_datum)
|
||||||
return
|
return
|
||||||
. += storage_datum.real_location?.resolve()
|
. += storage_datum.real_location?.resolve()
|
||||||
|
|
||||||
|
/// Returns an x and y value require to reverse the transformations made to center an oversized icon
|
||||||
|
/atom/proc/get_oversized_icon_offsets()
|
||||||
|
if (pixel_x == 0 && pixel_y == 0)
|
||||||
|
return list("x" = 0, "y" = 0)
|
||||||
|
var/list/icon_dimensions = get_icon_dimensions(icon)
|
||||||
|
var/icon_width = icon_dimensions["width"]
|
||||||
|
var/icon_height = icon_dimensions["height"]
|
||||||
|
return list(
|
||||||
|
"x" = icon_width > world.icon_size && pixel_x != 0 ? (icon_width - world.icon_size) * 0.5 : 0,
|
||||||
|
"y" = icon_height > world.icon_size && pixel_y != 0 ? (icon_height - world.icon_size) * 0.5 : 0,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1461,3 +1461,10 @@ GLOBAL_LIST_EMPTY(transformation_animation_objects)
|
|||||||
else
|
else
|
||||||
bound_width = world.icon_size
|
bound_width = world.icon_size
|
||||||
bound_height = size * world.icon_size
|
bound_height = size * world.icon_size
|
||||||
|
|
||||||
|
/// Returns a list containing the width and height of an icon file
|
||||||
|
/proc/get_icon_dimensions(icon_path)
|
||||||
|
if (isnull(GLOB.icon_dimensions[icon_path]))
|
||||||
|
var/icon/my_icon = icon(icon_path)
|
||||||
|
GLOB.icon_dimensions[icon_path] = list("width" = my_icon.Width(), "height" = my_icon.Height())
|
||||||
|
return GLOB.icon_dimensions[icon_path]
|
||||||
|
|||||||
@@ -232,9 +232,9 @@ Turf and target are separate in case you want to teleport some distance from a t
|
|||||||
var/pixel_y_offset = checked_atom.pixel_y + atom_matrix.get_y_shift()
|
var/pixel_y_offset = checked_atom.pixel_y + atom_matrix.get_y_shift()
|
||||||
|
|
||||||
//Irregular objects
|
//Irregular objects
|
||||||
var/icon/checked_atom_icon = icon(checked_atom.icon, checked_atom.icon_state)
|
var/list/icon_dimensions = get_icon_dimensions(checked_atom.icon)
|
||||||
var/checked_atom_icon_height = checked_atom_icon.Height()
|
var/checked_atom_icon_height = icon_dimensions["width"]
|
||||||
var/checked_atom_icon_width = checked_atom_icon.Width()
|
var/checked_atom_icon_width = icon_dimensions["height"]
|
||||||
if(checked_atom_icon_height != world.icon_size || checked_atom_icon_width != world.icon_size)
|
if(checked_atom_icon_height != world.icon_size || checked_atom_icon_width != world.icon_size)
|
||||||
pixel_x_offset += ((checked_atom_icon_width / world.icon_size) - 1) * (world.icon_size * 0.5)
|
pixel_x_offset += ((checked_atom_icon_width / world.icon_size) - 1) * (world.icon_size * 0.5)
|
||||||
pixel_y_offset += ((checked_atom_icon_height / world.icon_size) - 1) * (world.icon_size * 0.5)
|
pixel_y_offset += ((checked_atom_icon_height / world.icon_size) - 1) * (world.icon_size * 0.5)
|
||||||
|
|||||||
2
code/_globalvars/lists/icons.dm
Normal file
2
code/_globalvars/lists/icons.dm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/// Cache of the width and height of icon files, to avoid repeating the same expensive operation
|
||||||
|
GLOBAL_LIST_EMPTY(icon_dimensions)
|
||||||
@@ -98,6 +98,11 @@
|
|||||||
RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(cleaning_target_moved))
|
RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(cleaning_target_moved))
|
||||||
var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, GAME_PLANE)
|
var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, GAME_PLANE)
|
||||||
var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, ABOVE_GAME_PLANE)
|
var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, ABOVE_GAME_PLANE)
|
||||||
|
var/list/icon_offsets = target.get_oversized_icon_offsets()
|
||||||
|
low_bubble.pixel_x = icon_offsets["x"]
|
||||||
|
low_bubble.pixel_y = icon_offsets["y"]
|
||||||
|
high_bubble.pixel_x = icon_offsets["x"]
|
||||||
|
high_bubble.pixel_y = icon_offsets["y"]
|
||||||
if(target.plane > low_bubble.plane) //check if the higher overlay is necessary
|
if(target.plane > low_bubble.plane) //check if the higher overlay is necessary
|
||||||
target.add_overlay(high_bubble)
|
target.add_overlay(high_bubble)
|
||||||
else if(target.plane == low_bubble.plane)
|
else if(target.plane == low_bubble.plane)
|
||||||
|
|||||||
@@ -139,9 +139,9 @@
|
|||||||
* without otherwise affecting other movables with identical overlays.
|
* without otherwise affecting other movables with identical overlays.
|
||||||
*/
|
*/
|
||||||
/datum/element/immerse/proc/add_immerse_overlay(atom/movable/movable)
|
/datum/element/immerse/proc/add_immerse_overlay(atom/movable/movable)
|
||||||
var/icon/movable_icon = icon(movable.icon)
|
var/list/icon_dimensions = get_icon_dimensions(movable.icon)
|
||||||
var/width = movable_icon.Width() || world.icon_size
|
var/width = icon_dimensions["width"] || world.icon_size
|
||||||
var/height = movable_icon.Height() || world.icon_size
|
var/height = icon_dimensions["height"] || world.icon_size
|
||||||
|
|
||||||
var/is_below_water = movable.layer < WATER_LEVEL_LAYER ? "underwater-" : ""
|
var/is_below_water = movable.layer < WATER_LEVEL_LAYER ? "underwater-" : ""
|
||||||
|
|
||||||
|
|||||||
@@ -193,9 +193,9 @@
|
|||||||
|
|
||||||
/// Reads layer configurations to take out some useful overall information
|
/// Reads layer configurations to take out some useful overall information
|
||||||
/datum/greyscale_config/proc/ReadMetadata()
|
/datum/greyscale_config/proc/ReadMetadata()
|
||||||
var/icon/source = icon(icon_file)
|
var/list/icon_dimensions = get_icon_dimensions(icon_file)
|
||||||
height = source.Height()
|
height = icon_dimensions["width"]
|
||||||
width = source.Width()
|
width = icon_dimensions["height"]
|
||||||
|
|
||||||
var/list/datum/greyscale_layer/all_layers = list()
|
var/list/datum/greyscale_layer/all_layers = list()
|
||||||
for(var/state in icon_states)
|
for(var/state in icon_states)
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
var/listindex = 0
|
var/listindex = 0
|
||||||
///The type of our last value for bar_loc, for debugging
|
///The type of our last value for bar_loc, for debugging
|
||||||
var/location_type
|
var/location_type
|
||||||
|
///Where to draw the progress bar above the icon
|
||||||
|
var/offset_y
|
||||||
|
|
||||||
/datum/progressbar/New(mob/User, goal_number, atom/target)
|
/datum/progressbar/New(mob/User, goal_number, atom/target)
|
||||||
. = ..()
|
. = ..()
|
||||||
@@ -36,7 +38,12 @@
|
|||||||
goal = goal_number
|
goal = goal_number
|
||||||
bar_loc = target
|
bar_loc = target
|
||||||
location_type = bar_loc.type
|
location_type = bar_loc.type
|
||||||
bar = image('icons/effects/progressbar.dmi', bar_loc, "prog_bar_0")
|
|
||||||
|
var/list/icon_offsets = target.get_oversized_icon_offsets()
|
||||||
|
var/offset_x = icon_offsets["x"]
|
||||||
|
offset_y = icon_offsets["y"]
|
||||||
|
|
||||||
|
bar = image('icons/effects/progressbar.dmi', bar_loc, "prog_bar_0", pixel_x = offset_x)
|
||||||
SET_PLANE_EXPLICIT(bar, ABOVE_HUD_PLANE, User)
|
SET_PLANE_EXPLICIT(bar, ABOVE_HUD_PLANE, User)
|
||||||
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||||
user = User
|
user = User
|
||||||
@@ -62,8 +69,8 @@
|
|||||||
continue
|
continue
|
||||||
progress_bar.listindex--
|
progress_bar.listindex--
|
||||||
|
|
||||||
progress_bar.bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1))
|
progress_bar.bar.pixel_y = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1))
|
||||||
var/dist_to_travel = 32 + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT
|
var/dist_to_travel = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT
|
||||||
animate(progress_bar.bar, pixel_y = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
animate(progress_bar.bar, pixel_y = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
||||||
|
|
||||||
LAZYREMOVEASSOC(user.progressbars, bar_loc, src)
|
LAZYREMOVEASSOC(user.progressbars, bar_loc, src)
|
||||||
@@ -118,7 +125,7 @@
|
|||||||
bar.pixel_y = 0
|
bar.pixel_y = 0
|
||||||
bar.alpha = 0
|
bar.alpha = 0
|
||||||
user_client.images += bar
|
user_client.images += bar
|
||||||
animate(bar, pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
animate(bar, pixel_y = world.icon_size + offset_y + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
||||||
|
|
||||||
|
|
||||||
///Updates the progress bar image visually.
|
///Updates the progress bar image visually.
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
/mob/living/simple_animal/revenant/ranged_secondary_attack(atom/target, modifiers)
|
/mob/living/simple_animal/revenant/ranged_secondary_attack(atom/target, modifiers)
|
||||||
if(revealed || notransform || inhibited || !Adjacent(target) || !incorporeal_move_check(target))
|
if(revealed || notransform || inhibited || !Adjacent(target) || !incorporeal_move_check(target))
|
||||||
return
|
return
|
||||||
var/icon/I = icon(target.icon,target.icon_state,target.dir)
|
|
||||||
var/orbitsize = (I.Width()+I.Height())*0.5
|
var/list/icon_dimensions = get_icon_dimensions(target.icon)
|
||||||
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
|
var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5
|
||||||
|
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
|
||||||
orbit(target, orbitsize)
|
orbit(target, orbitsize)
|
||||||
|
|
||||||
//Harvest; activated by clicking the target, will try to drain their essence.
|
//Harvest; activated by clicking the target, will try to drain their essence.
|
||||||
|
|||||||
@@ -478,8 +478,8 @@ Moving interrupts
|
|||||||
user.balloon_alert(user, "no sculpt target!")
|
user.balloon_alert(user, "no sculpt target!")
|
||||||
return FALSE
|
return FALSE
|
||||||
//No big icon things
|
//No big icon things
|
||||||
var/icon/thing_icon = icon(target.icon, target.icon_state)
|
var/list/icon_dimensions = get_icon_dimensions(target.icon)
|
||||||
if(thing_icon.Height() != world.icon_size || thing_icon.Width() != world.icon_size)
|
if(icon_dimensions["width"] != world.icon_size || icon_dimensions["height"] != world.icon_size)
|
||||||
user.balloon_alert(user, "sculpt target is too big!")
|
user.balloon_alert(user, "sculpt target is too big!")
|
||||||
return FALSE
|
return FALSE
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|||||||
@@ -136,10 +136,10 @@
|
|||||||
|
|
||||||
// Scale the preview if it's bigger than one tile
|
// Scale the preview if it's bigger than one tile
|
||||||
var/mutable_appearance/preview_overlay = new(typepath)
|
var/mutable_appearance/preview_overlay = new(typepath)
|
||||||
var/icon/size_check = icon(initial(typepath.icon), icon_state = initial(typepath.icon_state))
|
var/list/icon_dimensions = get_icon_dimensions(initial(typepath.icon))
|
||||||
|
var/width = icon_dimensions["width"]
|
||||||
|
var/height = icon_dimensions["height"]
|
||||||
var/scale = 1
|
var/scale = 1
|
||||||
var/width = size_check.Width()
|
|
||||||
var/height = size_check.Height()
|
|
||||||
if(width > world.icon_size || height > world.icon_size)
|
if(width > world.icon_size || height > world.icon_size)
|
||||||
if(width >= height)
|
if(width >= height)
|
||||||
scale = world.icon_size / width
|
scale = world.icon_size / width
|
||||||
|
|||||||
@@ -148,11 +148,10 @@
|
|||||||
for (var/atom/movable/ingredient as anything in ingredients)
|
for (var/atom/movable/ingredient as anything in ingredients)
|
||||||
var/image/ingredient_overlay = image(ingredient, src)
|
var/image/ingredient_overlay = image(ingredient, src)
|
||||||
|
|
||||||
var/icon/ingredient_icon = icon(ingredient.icon, ingredient.icon_state)
|
var/list/icon_dimensions = get_icon_dimensions(ingredient.icon)
|
||||||
|
|
||||||
ingredient_overlay.transform = ingredient_overlay.transform.Scale(
|
ingredient_overlay.transform = ingredient_overlay.transform.Scale(
|
||||||
MICROWAVE_INGREDIENT_OVERLAY_SIZE / ingredient_icon.Width(),
|
MICROWAVE_INGREDIENT_OVERLAY_SIZE / icon_dimensions["width"],
|
||||||
MICROWAVE_INGREDIENT_OVERLAY_SIZE / ingredient_icon.Height(),
|
MICROWAVE_INGREDIENT_OVERLAY_SIZE / icon_dimensions["height"],
|
||||||
)
|
)
|
||||||
|
|
||||||
ingredient_overlay.pixel_y = -4
|
ingredient_overlay.pixel_y = -4
|
||||||
|
|||||||
@@ -502,9 +502,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
|||||||
if (!istype(target) || (is_secret_level(target.z) && !client?.holder))
|
if (!istype(target) || (is_secret_level(target.z) && !client?.holder))
|
||||||
return
|
return
|
||||||
|
|
||||||
var/icon/I = icon(target.icon,target.icon_state,target.dir)
|
var/list/icon_dimensions = get_icon_dimensions(target.icon)
|
||||||
|
var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5
|
||||||
var/orbitsize = (I.Width()+I.Height())*0.5
|
|
||||||
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
|
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
|
||||||
|
|
||||||
var/rot_seg
|
var/rot_seg
|
||||||
|
|||||||
@@ -354,8 +354,8 @@ Difficulty: Extremely Hard
|
|||||||
if(!owner.stat)
|
if(!owner.stat)
|
||||||
to_chat(owner, span_userdanger("You become frozen in a cube!"))
|
to_chat(owner, span_userdanger("You become frozen in a cube!"))
|
||||||
cube = icon('icons/effects/freeze.dmi', "ice_cube")
|
cube = icon('icons/effects/freeze.dmi', "ice_cube")
|
||||||
var/icon/size_check = icon(owner.icon, owner.icon_state)
|
var/list/icon_dimensions = get_icon_dimensions(owner.icon)
|
||||||
cube.Scale(size_check.Width(), size_check.Height())
|
cube.Scale(icon_dimensions["width"], icon_dimensions["height"])
|
||||||
owner.add_overlay(cube)
|
owner.add_overlay(cube)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
|||||||
@@ -146,11 +146,10 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
miniball.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
|
miniball.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
|
||||||
var/icon/I = icon(icon, icon_state,dir)
|
var/list/icon_dimensions = get_icon_dimensions(icon)
|
||||||
|
|
||||||
var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8)
|
var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * pick(0.4, 0.5, 0.6, 0.7, 0.8)
|
||||||
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
|
orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25)
|
||||||
|
|
||||||
miniball.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36))
|
miniball.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36))
|
||||||
|
|
||||||
/obj/energy_ball/Bump(atom/A)
|
/obj/energy_ball/Bump(atom/A)
|
||||||
|
|||||||
@@ -574,6 +574,7 @@
|
|||||||
#include "code\_globalvars\lists\client.dm"
|
#include "code\_globalvars\lists\client.dm"
|
||||||
#include "code\_globalvars\lists\color.dm"
|
#include "code\_globalvars\lists\color.dm"
|
||||||
#include "code\_globalvars\lists\flavor_misc.dm"
|
#include "code\_globalvars\lists\flavor_misc.dm"
|
||||||
|
#include "code\_globalvars\lists\icons.dm"
|
||||||
#include "code\_globalvars\lists\keybindings.dm"
|
#include "code\_globalvars\lists\keybindings.dm"
|
||||||
#include "code\_globalvars\lists\maintenance_loot.dm"
|
#include "code\_globalvars\lists\maintenance_loot.dm"
|
||||||
#include "code\_globalvars\lists\mapping.dm"
|
#include "code\_globalvars\lists\mapping.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user