|
10 | 10 | var/mob/user |
11 | 11 | ///The client seeing the progress bar. |
12 | 12 | var/client/user_client |
| 13 | + ///Extra checks for whether to stop the progress. |
| 14 | + var/datum/callback/extra_checks |
13 | 15 | ///Effectively the number of steps the progress bar will need to do before reaching completion. |
14 | 16 | var/goal = 1 |
15 | 17 | ///Control check to see if the progress was interrupted before reaching its goal. |
16 | 18 | var/last_progress = 0 |
17 | 19 | ///Variable to ensure smooth visual stacking on multiple progress bars. |
18 | 20 | var/listindex = 0 |
| 21 | + ///Whether progress has already been ended. |
| 22 | + var/progress_ended = FALSE |
19 | 23 |
|
20 | 24 |
|
21 | | -/datum/progressbar/New(mob/User, goal_number, atom/target) |
| 25 | +/datum/progressbar/New(mob/User, goal_number, atom/target, timed_action_flags = NONE) |
22 | 26 | . = ..() |
23 | 27 | if (!istype(target)) |
24 | 28 | stack_trace("Invalid target [target] passed in") |
|
50 | 54 | RegisterSignal(user, COMSIG_QDELETING, PROC_REF(on_user_delete)) |
51 | 55 | RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(clean_user_client)) |
52 | 56 | RegisterSignal(user, COMSIG_MOB_LOGIN, PROC_REF(on_user_login)) |
| 57 | + if(!(timed_action_flags & IGNORE_USER_LOC_CHANGE)) |
| 58 | + RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) |
| 59 | + var/obj/mecha/mech = user.loc |
| 60 | + if(ismecha(user.loc) && user == mech.occupant) |
| 61 | + RegisterSignal(mech, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) |
| 62 | + if(!(timed_action_flags & IGNORE_TARGET_LOC_CHANGE)) |
| 63 | + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) |
| 64 | + if(!(timed_action_flags & IGNORE_HELD_ITEM)) |
| 65 | + var/obj/item/held = user.get_active_held_item() |
| 66 | + if(held) |
| 67 | + RegisterSignal(held, COMSIG_ITEM_EQUIPPED, PROC_REF(end_progress)) |
| 68 | + RegisterSignal(held, COMSIG_ITEM_DROPPED, PROC_REF(end_progress)) |
| 69 | + else |
| 70 | + RegisterSignal(user, COMSIG_MOB_PICKUP_ITEM, PROC_REF(end_progress)) |
| 71 | + RegisterSignal(user, COMSIG_MOB_SWAPPING_HANDS, PROC_REF(end_progress)) |
| 72 | + if(!(timed_action_flags & IGNORE_INCAPACITATED)) |
| 73 | + RegisterSignal(user, SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), PROC_REF(end_progress)) |
53 | 74 |
|
54 | 75 |
|
55 | 76 | /datum/progressbar/Destroy() |
|
121 | 142 |
|
122 | 143 | ///Updates the progress bar image visually. |
123 | 144 | /datum/progressbar/proc/update(progress) |
| 145 | + if(progress_ended) |
| 146 | + return FALSE |
124 | 147 | progress = clamp(progress, 0, goal) |
125 | 148 | if(progress == last_progress) |
126 | | - return |
| 149 | + return FALSE |
127 | 150 | last_progress = progress |
| 151 | + if(extra_checks && !extra_checks.Invoke()) |
| 152 | + return FALSE |
128 | 153 | bar.icon_state = "prog_bar_[round(((progress / goal) * 100), 5)]" |
| 154 | + return TRUE |
129 | 155 |
|
130 | 156 |
|
131 | 157 | ///Called on progress end, be it successful or a failure. Wraps up things to delete the datum and bar. |
132 | 158 | /datum/progressbar/proc/end_progress() |
| 159 | + if(progress_ended) |
| 160 | + return |
| 161 | + progress_ended = TRUE |
| 162 | + |
133 | 163 | if(last_progress != goal) |
134 | 164 | bar.icon_state = "[bar.icon_state]_fail" |
135 | 165 |
|
136 | 166 | animate(bar, alpha = 0, time = PROGRESSBAR_ANIMATION_TIME) |
137 | 167 |
|
138 | 168 | QDEL_IN(src, PROGRESSBAR_ANIMATION_TIME) |
139 | 169 |
|
| 170 | +/datum/progressbar/proc/on_moved(atom/movable/mover, atom/old_loc, movement_dir, forced, list/old_locs, momentum_change, interrupting) |
| 171 | + SIGNAL_HANDLER |
| 172 | + if(!interrupting) |
| 173 | + return |
| 174 | + if(!mover.Process_Spacemove() && mover.inertia_dir) |
| 175 | + return |
| 176 | + INVOKE_ASYNC(src, PROC_REF(end_progress)) |
140 | 177 |
|
141 | 178 | #undef PROGRESSBAR_ANIMATION_TIME |
142 | 179 | #undef PROGRESSBAR_HEIGHT |
0 commit comments