mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 07:46:20 +00:00
## About The Pull Request Tanks while used as internals gives a progress bar to show how full they are, starting from the pressure when first starting to get used, when we expect the player to know how much is in the tank, and ticking down as it gets used. Alternative to this could be using the initial pressure, but then it would remain at 100% for quite a while when you put more than it starts off with. This replaces the stat panel entry for them, this is a part of https://hackmd.io/443_dE5lRWeEAp9bjGcKYw  ## Why It's Good For The Game Adds a visual indicator to tell people how much air they've used since toggling the tank's internals which is much better than the previous' random numbers in stat panel. ## Changelog 🆑 qol: internal tanks gives a progress bar when you toggle them, allowing you to see how much you've consumed so far. /🆑
159 lines
5.0 KiB
Plaintext
159 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, starting_amount)
|
|
. = ..()
|
|
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))
|
|
|
|
if(starting_amount)
|
|
update(starting_amount)
|
|
|
|
/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
|