mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-20 22:16:51 +00:00
## About The Pull Request
516 requires float layered overlays to be using pixel_w and pixel_z
instead of pixel_x and pixel_y respectively, unless we want
visual/layering errors. This makes sense, as w,z are for visual effects
only. Sadly seems we were not entirely consistent in this, and many
things seem to have been using x,y incorrectly.
This hopefully fixes that, and thus also fixes layering issues. Complete
1:1 compatibility not guaranteed.
I did the lazy way suggested to me by SmArtKar to speed it up (Runtiming
inside apply_overlays), and this is still included in the PR to flash
out possible issues in a TM (Plus I will need someone to grep the
runtimes for me after the TM period to make sure nothing was missed).
After this is done I'll remove all these extra checks.
Lints will probably be failing for a bit, got to wait for [this
update](4b77cd487d)
to them to make it into release. Or just unlint the lines, though that's
probably gonna produce code debt
## Why It's Good For The Game
Fixes this massive 516 mess, hopefully.
closes #90281
## Changelog
🆑
refactor: Changed many of our use cases for pixel_x and pixel_y
correctly into pixel_w and pixel_z, fixing layering issues in the
process.
/🆑
---------
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: SmArtKar <master.of.bagets@gmail.com>
157 lines
5.0 KiB
Plaintext
157 lines
5.0 KiB
Plaintext
#define PROGRESSBAR_HEIGHT 6
|
|
#define PROGRESSBAR_ANIMATION_TIME 5
|
|
|
|
/datum/progressbar
|
|
///The progress bar visual element.
|
|
var/image/bar
|
|
///The target where this progress bar is applied and where it is shown.
|
|
var/atom/bar_loc
|
|
///The mob whose client sees the progress bar.
|
|
var/mob/user
|
|
///The client seeing the progress bar.
|
|
var/client/user_client
|
|
///Effectively the number of steps the progress bar will need to do before reaching completion.
|
|
var/goal = 1
|
|
///Control check to see if the progress was interrupted before reaching its goal.
|
|
var/last_progress = 0
|
|
///Variable to ensure smooth visual stacking on multiple progress bars.
|
|
var/listindex = 0
|
|
///The type of our last value for bar_loc, for debugging
|
|
var/location_type
|
|
///Where to draw the progress bar above the icon
|
|
var/offset_y
|
|
|
|
/datum/progressbar/New(mob/User, goal_number, atom/target)
|
|
. = ..()
|
|
if (!istype(target))
|
|
stack_trace("Invalid target [target] passed in")
|
|
qdel(src)
|
|
return
|
|
if(QDELETED(User) || !istype(User))
|
|
stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] user")
|
|
qdel(src)
|
|
return
|
|
if(!isnum(goal_number))
|
|
stack_trace("/datum/progressbar created with [isnull(User) ? "null" : "invalid"] goal_number")
|
|
qdel(src)
|
|
return
|
|
goal = goal_number
|
|
bar_loc = target
|
|
location_type = bar_loc.type
|
|
|
|
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)
|
|
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
|
user = User
|
|
|
|
LAZYADDASSOCLIST(user.progressbars, bar_loc, src)
|
|
var/list/bars = user.progressbars[bar_loc]
|
|
listindex = bars.len
|
|
|
|
if(user.client)
|
|
user_client = user.client
|
|
add_prog_bar_image_to_client()
|
|
|
|
RegisterSignal(user, COMSIG_QDELETING, PROC_REF(on_user_delete))
|
|
RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(clean_user_client))
|
|
RegisterSignal(user, COMSIG_MOB_LOGIN, PROC_REF(on_user_login))
|
|
|
|
|
|
/datum/progressbar/Destroy()
|
|
if(user)
|
|
for(var/pb in user.progressbars[bar_loc])
|
|
var/datum/progressbar/progress_bar = pb
|
|
if(progress_bar == src || progress_bar.listindex <= listindex)
|
|
continue
|
|
progress_bar.listindex--
|
|
|
|
progress_bar.bar.pixel_z = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1))
|
|
var/dist_to_travel = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (progress_bar.listindex - 1)) - PROGRESSBAR_HEIGHT
|
|
animate(progress_bar.bar, pixel_z = dist_to_travel, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
|
|
|
LAZYREMOVEASSOC(user.progressbars, bar_loc, src)
|
|
user = null
|
|
|
|
if(user_client)
|
|
clean_user_client()
|
|
|
|
bar_loc = null
|
|
bar = null
|
|
|
|
return ..()
|
|
|
|
|
|
///Called right before the user's Destroy()
|
|
/datum/progressbar/proc/on_user_delete(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
user.progressbars = null //We can simply nuke the list and stop worrying about updating other prog bars if the user itself is gone.
|
|
user = null
|
|
qdel(src)
|
|
|
|
|
|
///Removes the progress bar image from the user_client and nulls the variable, if it exists.
|
|
/datum/progressbar/proc/clean_user_client(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!user_client) //Disconnected, already gone.
|
|
return
|
|
user_client.images -= bar
|
|
user_client = null
|
|
|
|
|
|
///Called by user's Login(), it transfers the progress bar image to the new client.
|
|
/datum/progressbar/proc/on_user_login(datum/source)
|
|
SIGNAL_HANDLER
|
|
|
|
if(user_client)
|
|
if(user_client == user.client) //If this was not client handling I'd condemn this sanity check. But clients are fickle things.
|
|
return
|
|
clean_user_client()
|
|
if(!user.client) //Clients can vanish at any time, the bastards.
|
|
return
|
|
user_client = user.client
|
|
add_prog_bar_image_to_client()
|
|
|
|
|
|
///Adds a smoothly-appearing progress bar image to the player's screen.
|
|
/datum/progressbar/proc/add_prog_bar_image_to_client()
|
|
bar.pixel_z = 0
|
|
bar.alpha = 0
|
|
user_client.images += bar
|
|
animate(bar, pixel_z = ICON_SIZE_Y + offset_y + (PROGRESSBAR_HEIGHT * (listindex - 1)), alpha = 255, time = PROGRESSBAR_ANIMATION_TIME, easing = SINE_EASING)
|
|
|
|
|
|
///Updates the progress bar image visually.
|
|
/datum/progressbar/proc/update(progress)
|
|
progress = clamp(progress, 0, goal)
|
|
if(progress == last_progress)
|
|
return
|
|
last_progress = progress
|
|
bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]"
|
|
|
|
|
|
///Called on progress end, be it successful or a failure. Wraps up things to delete the datum and bar.
|
|
/datum/progressbar/proc/end_progress()
|
|
if(last_progress != goal)
|
|
bar.icon_state = "[bar.icon_state]_fail"
|
|
|
|
animate(bar, alpha = 0, time = PROGRESSBAR_ANIMATION_TIME)
|
|
|
|
QDEL_IN(src, PROGRESSBAR_ANIMATION_TIME)
|
|
|
|
///Progress bars are very generic, and what hangs a ref to them depends heavily on the context in which they're used
|
|
///So let's make hunting harddels easier yeah?
|
|
/datum/progressbar/dump_harddel_info()
|
|
if(harddel_deets_dumped)
|
|
return
|
|
harddel_deets_dumped = TRUE
|
|
return "Owner's type: [location_type]"
|
|
|
|
#undef PROGRESSBAR_ANIMATION_TIME
|
|
#undef PROGRESSBAR_HEIGHT
|