From 3a0491d3b4849e689628528d6432ab8d4f20ed0b Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Mon, 7 Dec 2020 22:46:59 +0100 Subject: [PATCH] [MIRROR] Small do-after refactor (#2074) * Small do-after refactor (#55172) This is an alternative to the PR Ryll made, it does some things similar e.g. the default limit of 1 interaction per target for a person, however, it refactors do_afters to support overrides for max interaction counts and unique sources. For example, stripping uses the item being stripped as the source, allowing you to strip multiple items, but not the same item multiple times. I've also fixed most other edge-cases this could cause where balance would be affected, but feel free to point out any I might've missed, this'll probably require some longer-term testmerging. * Small do-after refactor Co-authored-by: Qustinnus --- code/__DEFINES/do_afters.dm | 4 ++ code/__DEFINES/misc.dm | 11 ++- code/__DEFINES/mobs.dm | 6 +- code/__HELPERS/mobs.dm | 67 ++++++++++--------- code/__HELPERS/unsorted.dm | 41 ------------ code/datums/components/butchering.dm | 2 +- code/datums/elements/art.dm | 2 +- code/datums/wounds/_wounds.dm | 2 +- code/datums/wounds/slash.dm | 2 +- code/game/atoms.dm | 7 -- code/game/objects/items/RPD.dm | 2 +- .../items/stacks/sheets/sheet_types.dm | 3 +- code/game/objects/structures/loom.dm | 8 +-- code/modules/clothing/shoes/_shoes.dm | 6 +- code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/mob/living/living.dm | 4 +- .../mob/living/simple_animal/bot/medbot.dm | 2 +- code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_defines.dm | 2 +- .../reagents/reagent_containers/hypospray.dm | 4 +- code/modules/surgery/surgery_step.dm | 4 +- .../mecha/equipment/mecha_equipment.dm | 4 +- .../mecha/equipment/tools/mining_tools.dm | 11 +-- tgstation.dme | 1 + 24 files changed, 81 insertions(+), 118 deletions(-) create mode 100644 code/__DEFINES/do_afters.dm diff --git a/code/__DEFINES/do_afters.dm b/code/__DEFINES/do_afters.dm new file mode 100644 index 00000000000..456cf940400 --- /dev/null +++ b/code/__DEFINES/do_afters.dm @@ -0,0 +1,4 @@ +#define DOAFTER_SOURCE_SURGERY "doafter_surgery" +#define DOAFTER_SOURCE_MECHADRILL "doafter_mechadrill" +#define DOAFTER_SOURCE_SURVIVALPEN "doafter_survivalpen" +#define DOAFTER_SOURCE_GETTING_UP "doafter_gettingup" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 2186f226d06..d6f110b0d38 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -535,9 +535,8 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE))) #define NO_BUCKLE_LYING -1 -// timed_action_flags parameter for `/proc/do_atom`, `/proc/do_after_mob`, `/proc/do_mob` and `/proc/do_after` -#define IGNORE_TARGET_IN_DOAFTERS (1<<0) -#define IGNORE_USER_LOC_CHANGE (1<<1) -#define IGNORE_TARGET_LOC_CHANGE (1<<2) -#define IGNORE_HELD_ITEM (1<<3) -#define IGNORE_INCAPACITATED (1<<4) +// timed_action_flags parameter for `/proc/do_after_mob`, `/proc/do_mob` and `/proc/do_after` +#define IGNORE_USER_LOC_CHANGE (1<<0) +#define IGNORE_TARGET_LOC_CHANGE (1<<1) +#define IGNORE_HELD_ITEM (1<<2) +#define IGNORE_INCAPACITATED (1<<3) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 306b4724401..d407fbd5458 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -361,7 +361,11 @@ #define DEFIB_REVIVABLE_STATES (DEFIB_FAIL_NO_HEART | DEFIB_FAIL_FAILING_HEART | DEFIB_FAIL_HUSK | DEFIB_FAIL_TISSUE_DAMAGE | DEFIB_FAIL_FAILING_BRAIN | DEFIB_POSSIBLE) #define SLEEP_CHECK_DEATH(X) sleep(X); if(QDELETED(src) || stat == DEAD) return; -#define INTERACTING_WITH(X, Y) (Y in X.do_afters) + +#define DOING_INTERACTION(user, interaction_key) (LAZYACCESS(user.do_afters, interaction_key)) +#define DOING_INTERACTION_LIMIT(user, interaction_key, max_interaction_count) ((LAZYACCESS(user.do_afters, interaction_key) || 0) >= max_interaction_count) +#define DOING_INTERACTION_WITH_TARGET(user, target) (LAZYACCESS(user.do_afters, target)) +#define DOING_INTERACTION_WITH_TARGET_LIMIT(user, target, max_interaction_count) ((LAZYACCESS(user.do_afters, target) || 0) >= max_interaction_count) /// If you examine the same atom twice in this timeframe, we call examine_more() instead of examine() #define EXAMINE_MORE_TIME 1 SECONDS diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 03c82024a6d..104c9610f2e 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -177,8 +177,8 @@ GLOBAL_LIST_EMPTY(species_list) return "unknown" -///Timed action involving two mobs, the user and the target. -/proc/do_mob(mob/user, mob/target, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks) +///Timed action involving two mobs, the user and the target. interaction_key is the assoc key under which the do_after is capped under, and the max interaction count is how many of this interaction you can do at once. +/proc/do_mob(mob/user, mob/target, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1) if(!user || !target) return FALSE var/user_loc = user.loc @@ -189,8 +189,14 @@ GLOBAL_LIST_EMPTY(species_list) var/target_loc = target.loc - LAZYADD(user.do_afters, target) - LAZYADD(target.targeted_by, user) + if(!interaction_key && target) + interaction_key = target //Use the direct ref to the target + if(interaction_key) //Do we have a interaction_key now? + var/current_interaction_count = LAZYACCESS(user.do_afters, interaction_key) || 0 + if(current_interaction_count >= max_interact_count) //We are at our peak + return + LAZYSET(user.do_afters, interaction_key, current_interaction_count + 1) + var/holding = user.get_active_held_item() var/datum/progressbar/progbar if (progress) @@ -214,7 +220,6 @@ GLOBAL_LIST_EMPTY(species_list) if( QDELETED(user) || QDELETED(target) \ - || (!(timed_action_flags & IGNORE_TARGET_IN_DOAFTERS) && !(target in user.do_afters)) \ || (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \ || (!(timed_action_flags & IGNORE_TARGET_LOC_CHANGE) && target.loc != target_loc) \ || (!(timed_action_flags & IGNORE_HELD_ITEM) && user.get_active_held_item() != holding) \ @@ -227,9 +232,8 @@ GLOBAL_LIST_EMPTY(species_list) if(!QDELETED(progbar)) progbar.end_progress() - if(!QDELETED(target)) - LAZYREMOVE(user.do_afters, target) - LAZYREMOVE(target.targeted_by, user) + if(interaction_key) + LAZYREMOVE(user.do_afters, interaction_key) //some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action @@ -252,17 +256,22 @@ GLOBAL_LIST_EMPTY(species_list) * * Checks that `user` does not move, change hands, get stunned, etc. for the * given `delay`. Returns `TRUE` on success or `FALSE` on failure. + * Interaction_key is the assoc key under which the do_after is capped, with max_interact_count being the cap. Interaction key will default to target if not set. */ -/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks) +/proc/do_after(mob/user, delay, atom/target, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1) if(!user) return FALSE var/atom/target_loc = null if(target && !isturf(target)) target_loc = target.loc - if(target) - LAZYADD(user.do_afters, target) - LAZYADD(target.targeted_by, user) + if(!interaction_key && target) + interaction_key = target //Use the direct ref to the target + if(interaction_key) //Do we have a interaction_key now? + var/current_interaction_count = LAZYACCESS(user.do_afters, interaction_key) || 0 + if(current_interaction_count >= max_interact_count) //We are at our peak + return + LAZYSET(user.do_afters, interaction_key, current_interaction_count + 1) var/atom/user_loc = user.loc @@ -311,20 +320,15 @@ GLOBAL_LIST_EMPTY(species_list) . = FALSE break - if(target && !(timed_action_flags & IGNORE_TARGET_IN_DOAFTERS) && !(target in user.do_afters)) - . = FALSE - break - if(!QDELETED(progbar)) progbar.end_progress() - if(!QDELETED(target)) - LAZYREMOVE(user.do_afters, target) - LAZYREMOVE(target.targeted_by, user) + if(interaction_key) + LAZYREMOVE(user.do_afters, interaction_key) -///Timed action involving at least one mob user and a list of targets. -/proc/do_after_mob(mob/user, list/targets, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks) +///Timed action involving at least one mob user and a list of targets. interaction_key is the assoc key under which the do_after is capped under, and the max interaction count is how many of this interaction you can do at once. +/proc/do_after_mob(mob/user, list/targets, time = 3 SECONDS, timed_action_flags = NONE, progress = TRUE, datum/callback/extra_checks, interaction_key, max_interact_count = 1) if(!user) return FALSE if(!islist(targets)) @@ -340,10 +344,17 @@ GLOBAL_LIST_EMPTY(species_list) drifting = TRUE var/list/originalloc = list() + for(var/atom/target in targets) originalloc[target] = target.loc - LAZYADD(user.do_afters, target) - LAZYADD(target.targeted_by, user) + + if(interaction_key) + var/current_interaction_count = LAZYACCESS(user.do_afters, interaction_key) || 0 + if(current_interaction_count >= max_interact_count) //We are at our peak + to_chat(user, "You can't do this at the moment!") + return + LAZYSET(user.do_afters, interaction_key, current_interaction_count + 1) + var/holding = user.get_active_held_item() var/datum/progressbar/progbar @@ -390,12 +401,8 @@ GLOBAL_LIST_EMPTY(species_list) if(!QDELETED(progbar)) progbar.end_progress() - for(var/thing in targets) - var/atom/target = thing - if(!QDELETED(target)) - LAZYREMOVE(user.do_afters, target) - LAZYREMOVE(target.targeted_by, user) - + if(interaction_key) + LAZYREMOVE(user.do_afters, interaction_key) /proc/is_species(A, species_datum) . = FALSE @@ -452,7 +459,7 @@ GLOBAL_LIST_EMPTY(species_list) return spawned_mobs -// Displays a message in deadchat, sent by source. Source is not linkified, message is, to avoid stuff like character names to be linkified. +// Displays a message in deadchat, sent by source. source is not linkified, message is, to avoid stuff like character names to be linkified. // Automatically gives the class deadsay to the whole message (message + source) /proc/deadchat_broadcast(message, source=null, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR) message = "[source][message]" diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ce3046280f6..0ff99cc3d60 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1255,47 +1255,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) temp = ((temp + (temp>>3))&29127) % 63 //070707 return temp -//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar -/proc/do_atom(atom/movable/user, atom/movable/target, time = 3 SECONDS, timed_action_flags = NONE, datum/callback/extra_checks) - if(!user || !target) - return TRUE - var/user_loc = user.loc - - var/drifting = FALSE - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = TRUE - - var/target_drifting = FALSE - if(!target.Process_Spacemove(0) && target.inertia_dir) - target_drifting = TRUE - - var/target_loc = target.loc - - var/endtime = world.time+time - . = TRUE - while (world.time < endtime) - stoplag(1) - - if(QDELETED(user) || QDELETED(target)) - . = FALSE - break - - if(drifting && !user.inertia_dir) - drifting = FALSE - user_loc = user.loc - - if(target_drifting && !target.inertia_dir) - target_drifting = FALSE - target_loc = target.loc - - if( - (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \ - || (!(timed_action_flags& IGNORE_TARGET_LOC_CHANGE) && !target_drifting && target.loc != target_loc) \ - || (extra_checks && !extra_checks.Invoke()) \ - ) - . = FALSE - break - //returns a GUID like identifier (using a mostly made up record format) //guids are not on their own suitable for access or security tokens, as most of their bits are predictable. // (But may make a nice salt to one) diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 0d3c84ae0ce..70f13376639 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -49,7 +49,7 @@ Butcher(user, M) /datum/component/butchering/proc/startNeckSlice(obj/item/source, mob/living/carbon/human/H, mob/living/user) - if(INTERACTING_WITH(user, H)) + if(DOING_INTERACTION_WITH_TARGET(user, H)) to_chat(user, "You're already interacting with [H]!") return diff --git a/code/datums/elements/art.dm b/code/datums/elements/art.dm index 54048c0126d..87f827c21f1 100644 --- a/code/datums/elements/art.dm +++ b/code/datums/elements/art.dm @@ -38,7 +38,7 @@ /datum/element/art/proc/on_examine(atom/source, mob/user, list/examine_texts) SIGNAL_HANDLER - if(!INTERACTING_WITH(user, source)) + if(!DOING_INTERACTION_WITH_TARGET(user, source)) INVOKE_ASYNC(src, .proc/appraise, source, user) //Do not sleep the proc. /datum/element/art/proc/appraise(atom/source, mob/user) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 340650c09aa..1fe723f779c 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -283,7 +283,7 @@ return FALSE // now that we've determined we have a valid attempt at treating, we can stomp on their dreams if we're already interacting with the patient or if their part is obscured - if(INTERACTING_WITH(user, victim)) + if(DOING_INTERACTION_WITH_TARGET(user, victim)) to_chat(user, "You're already interacting with [victim]!") return TRUE diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index d24facedc2a..0f091cb95ec 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -145,7 +145,7 @@ /datum/wound/slash/try_handling(mob/living/carbon/human/user) if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB || !isfelinid(user) || !victim.can_inject(user, TRUE)) return FALSE - if(INTERACTING_WITH(user, victim)) + if(DOING_INTERACTION_WITH_TARGET(user, victim)) to_chat(user, "You're already interacting with [victim]!") return if(user.is_mouth_covered()) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 34a47332f96..90aa43059fc 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -90,8 +90,6 @@ var/list/alternate_appearances - ///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy() - var/list/targeted_by /// Last appearance of the atom for demo saving purposes var/image/demo_last_appearance @@ -279,11 +277,6 @@ LAZYCLEARLIST(overlays) - for(var/i in targeted_by) - var/mob/M = i - LAZYREMOVE(M.do_afters, src) - - targeted_by = null QDEL_NULL(light) if(smoothing_flags & SMOOTH_QUEUED) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 7b40b96292c..6b8da326d90 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -386,7 +386,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/queued_p_flipped = p_flipped //Unwrench pipe before we build one over/paint it, but only if we're not already running a do_after on it already to prevent a potential runtime. - if((mode & DESTROY_MODE) && (upgrade_flags & RPD_UPGRADE_UNWRENCH) && istype(attack_target, /obj/machinery/atmospherics) && !(attack_target in user.do_afters)) + if((mode & DESTROY_MODE) && (upgrade_flags & RPD_UPGRADE_UNWRENCH) && istype(attack_target, /obj/machinery/atmospherics) && !(DOING_INTERACTION_WITH_TARGET(user, attack_target))) attack_target = attack_target.wrench_act(user, src) if(!isatom(attack_target)) CRASH("When attempting to call [A.type].wrench_act(), received the following non-atom return value: [attack_target]") diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a139f89a5b6..e984901a698 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -395,7 +395,7 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ force = 0 throwforce = 0 merge_type = /obj/item/stack/sheet/cotton - var/pull_effort = 30 + var/pull_effort = 10 var/loom_result = /obj/item/stack/sheet/cloth grind_results = list(/datum/reagent/cellulose = 20) @@ -405,7 +405,6 @@ GLOBAL_LIST_INIT(durathread_recipes, list ( \ singular_name = "raw durathread ball" icon_state = "sheet-durathreadraw" merge_type = /obj/item/stack/sheet/cotton/durathread - pull_effort = 70 loom_result = /obj/item/stack/sheet/durathread grind_results = list() diff --git a/code/game/objects/structures/loom.dm b/code/game/objects/structures/loom.dm index 28ff5a8de73..e2c3b890991 100644 --- a/code/game/objects/structures/loom.dm +++ b/code/game/objects/structures/loom.dm @@ -31,11 +31,9 @@ user.show_message("You need at least [FABRIC_PER_SHEET] units of fabric before using this.", MSG_VISUAL) return FALSE user.show_message("You start weaving \the [W.name] through the loom..", MSG_VISUAL) - if(W.use_tool(src, user, W.pull_effort)) - if(W.amount >= FABRIC_PER_SHEET) - new W.loom_result(drop_location()) - W.use(FABRIC_PER_SHEET) - user.show_message("You weave \the [W.name] into a workable fabric.", MSG_VISUAL) + while(W.use_tool(src, user, W.pull_effort) && W.use(FABRIC_PER_SHEET)) + new W.loom_result(drop_location()) + user.show_message("You weave \the [W.name] into a workable fabric.", MSG_VISUAL) return TRUE #undef FABRIC_PER_SHEET diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index 68af6bacf78..296b715c650 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -141,7 +141,7 @@ return if(user == loc && tied != SHOES_TIED) // if they're our own shoes, go tie-wards - if(INTERACTING_WITH(user, our_guy)) + if(DOING_INTERACTION_WITH_TARGET(user, our_guy)) to_chat(user, "You're already interacting with [src]!") return user.visible_message("[user] begins [tied ? "unknotting" : "tying"] the laces of [user.p_their()] [src.name].", "You begin [tied ? "unknotting" : "tying"] the laces of your [src.name]...") @@ -161,7 +161,7 @@ if(tied == SHOES_KNOTTED) to_chat(user, "The laces on [loc]'s [src.name] are already a hopelessly tangled mess!") return - if(INTERACTING_WITH(user, our_guy)) + if(DOING_INTERACTION_WITH_TARGET(user, our_guy)) to_chat(user, "You're already interacting with [src]!") return @@ -247,7 +247,7 @@ /obj/item/clothing/shoes/attack_self(mob/user) . = ..() - if(INTERACTING_WITH(user, src)) + if(DOING_INTERACTION_WITH_TARGET(user, src)) to_chat(user, "You're already interacting with [src]!") return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c1b661db374..c0f4a19ac18 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -646,7 +646,7 @@ do CHECK_DNA_AND_SPECIES(target) - if (INTERACTING_WITH(src, target)) + if (DOING_INTERACTION_WITH_TARGET(src,target)) return FALSE if (target.stat == DEAD || HAS_TRAIT(target, TRAIT_FAKEDEATH)) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bbcaf307eae..50168b3b8a5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -525,7 +525,7 @@ /mob/living/proc/get_up(instant = FALSE) set waitfor = FALSE - if(!instant && !do_mob(src, src, 1 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, /mob/living/proc/rest_checks_callback))) + if(!instant && !do_mob(src, src, 1 SECONDS, timed_action_flags = (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM), extra_checks = CALLBACK(src, /mob/living/proc/rest_checks_callback), interaction_key = DOAFTER_SOURCE_GETTING_UP)) return if(resting || body_position == STANDING_UP || HAS_TRAIT(src, TRAIT_FLOORED)) return @@ -985,7 +985,7 @@ who.log_message("[key_name(who)] is being stripped of [what] by [key_name(src)]", LOG_ATTACK, color="red") log_message("[key_name(who)] is being stripped of [what] by [key_name(src)]", LOG_ATTACK, color="red", log_globally=FALSE) what.add_fingerprint(src) - if(do_mob(src, who, what.strip_delay)) + if(do_mob(src, who, what.strip_delay, interaction_key = what)) if(what && Adjacent(who)) if(islist(where)) var/list/L = where diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index ba201216052..25818a18019 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -450,7 +450,7 @@ return TRUE /mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H) - if(INTERACTING_WITH(H, src)) + if(DOING_INTERACTION_WITH_TARGET(H, src)) to_chat(H, "You're already interacting with [src].") return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 820659b3a1d..550e57e4051 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -494,7 +494,7 @@ return FALSE //you can only queue up one examine on something at a time - if(examined_thing in do_afters) + if(DOING_INTERACTION_WITH_TARGET(src, examined_thing)) return FALSE to_chat(src, "You start feeling around for something...") diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index cbaea918645..40c10f1f5df 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -196,7 +196,7 @@ ///List of progress bars this mob is currently seeing for actions var/list/progressbars = null //for stacking do_after bars - ///For storing what do_after's someone has, in case we want to restrict them to only one of a certain do_after at a time + ///For storing what do_after's someone has, key = string, value = amount of interactions of that type happening. var/list/do_afters ///Allows a datum to intercept all click calls this mob is the source of diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index cfab7fc9bb3..9c5c5b0a9cc 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -231,12 +231,12 @@ amount_per_transfer_from_this = initial(amount_per_transfer_from_this) return ..() - if(M in user.do_afters) + if(DOING_INTERACTION(user, DOAFTER_SOURCE_SURVIVALPEN)) to_chat(user,"You are too busy to use \the [src]!") return to_chat(user,"You start manually releasing the low-pressure gauge...") - if(!do_mob(user, M, 10 SECONDS)) + if(!do_mob(user, M, 10 SECONDS, interaction_key = DOAFTER_SOURCE_SURVIVALPEN)) return amount_per_transfer_from_this = initial(amount_per_transfer_from_this) * 0.5 diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index af653e74d82..3a15bc500d0 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -61,8 +61,6 @@ /datum/surgery_step/proc/initiate(mob/living/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) // Only followers of Asclepius have the ability to use Healing Touch and perform miracle feats of surgery. // Prevents people from performing multiple simultaneous surgeries unless they're holding a Rod of Asclepius. - if(LAZYLEN(user.do_afters) && !user.has_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH)) - return surgery.step_in_progress = TRUE var/speed_mod = 1 @@ -92,7 +90,7 @@ var/was_sleeping = (target.stat != DEAD && target.IsSleeping()) - if(do_after(user, modded_time, target = target)) + if(do_after(user, modded_time, target = target, interaction_key = user.has_status_effect(STATUS_EFFECT_HIPPOCRATIC_OATH) ? target : DOAFTER_SOURCE_SURGERY)) //If we have the hippocratic oath, we can perform one surgery on each target, otherwise we can only do one surgery in total. var/chem_check_result = chem_check(target) if((prob(100-fail_prob) || (iscyborg(user) && !silicons_obey_prob)) && chem_check_result && !try_to_fail) diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm index f58db78715e..c6382b5cc15 100644 --- a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm +++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm @@ -96,12 +96,12 @@ chassis.use_power(energy_drain) return TRUE -/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target, mob/user) +/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target, mob/user, interaction_key) if(!chassis) return var/C = chassis.loc chassis.use_power(energy_drain) - . = do_after(user, equip_cooldown, target=target) + . = do_after(user, equip_cooldown, target=target, interaction_key = interaction_key) if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) return FALSE diff --git a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm index 4f2e47fb3cf..86ac78f68cd 100644 --- a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm @@ -40,12 +40,13 @@ if(target_obj.resistance_flags & (UNACIDABLE | INDESTRUCTIBLE)) return - target.visible_message("[chassis] starts to drill [target].", \ - "[chassis] starts to drill [target]...", \ - "You hear drilling.") - // You can't drill harder by clicking more. - if(!(target in source.do_afters) && do_after_cooldown(target, source)) + if(!DOING_INTERACTION_WITH_TARGET(source, target) && do_after_cooldown(target, source, DOAFTER_SOURCE_MECHADRILL)) + + target.visible_message("[chassis] starts to drill [target].", \ + "[chassis] starts to drill [target]...", \ + "You hear drilling.") + log_message("Started drilling [target]", LOG_MECHA) // Drilling a turf is a one-and-done procedure. if(isturf(target)) diff --git a/tgstation.dme b/tgstation.dme index effecf33d8e..df8c7fc0865 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -45,6 +45,7 @@ #include "code\__DEFINES\cult.dm" #include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\DNA.dm" +#include "code\__DEFINES\do_afters.dm" #include "code\__DEFINES\dye_keys.dm" #include "code\__DEFINES\economy.dm" #include "code\__DEFINES\events.dm"