Skip to content

Commit

Permalink
Removes do_atom, do_after_mob and do_mob (also interaction key stuff) (
Browse files Browse the repository at this point in the history
…yogstation13#19813)

* removes do_after_mob and do_atom

* Ports TG do_after

* Convert a ton of do_mob to do_after

* Removes do_mob entirely

* Now breaks the compile 👍

* Goes over current do_afters and fixes problems I found

* Increases CPR speed

* you eat food faster too

* Fixes stripping mobs

* Revert "you eat food faster too"

This reverts commit abcca7e.

* Fixes accidental swapover

* Update horror.dm

* Update hecata.dm
  • Loading branch information
JohnFulpWillard authored Aug 20, 2023
1 parent a7fee19 commit 9640d15
Show file tree
Hide file tree
Showing 140 changed files with 494 additions and 552 deletions.
14 changes: 14 additions & 0 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,17 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204

/// 33554431 (2^24 - 1) is the maximum value our bitflags can reach.
#define MAX_BITFLAG_DIGITS 8

// timed_action_flags parameter for `/proc/do_after`
/// Can do the action even if mob moves location
#define IGNORE_USER_LOC_CHANGE (1<<0)
/// Can do the action even if the target moves location
#define IGNORE_TARGET_LOC_CHANGE (1<<1)
/// Can do the action even if the item is no longer being held
#define IGNORE_HELD_ITEM (1<<2)
/// Can do the action even if the mob is incapacitated (ex. handcuffed)
#define IGNORE_INCAPACITATED (1<<3)
/// Used to prevent important slowdowns from being abused by drugs like kronkaine
#define IGNORE_SLOWDOWNS (1<<4)

#define IGNORE_ALL (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED|IGNORE_SLOWDOWNS)
6 changes: 3 additions & 3 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,10 @@
//this should be in the ai defines, but out ai defines are actual ai, not simplemob ai
#define IS_DEAD_OR_INCAP(source) (source.incapacitated() || source.stat)

#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)

///Define for spawning megafauna instead of a mob for cave gen
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
Expand Down
198 changes: 41 additions & 157 deletions code/__HELPERS/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -269,64 +269,6 @@ GLOBAL_LIST_EMPTY(species_list)
else
return "unknown"


/mob/var/action_speed_modifier = 1 //Value to multiply action delays by //yogs start: fuck
/mob/var/action_speed_adjust = 0 //Value to add or remove to action delays //yogs end

/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null)
if(!user || !target)
return 0
var/user_loc = user.loc

if(target)
LAZYADD(user.do_afters, target)
LAZYADD(target.targeted_by, user)

var/drifting = 0
if(!user.Process_Spacemove(0) && user.inertia_dir)
drifting = 1

var/target_loc = target.loc

var/holding = user.get_active_held_item()
time = ((time + user.action_speed_adjust) * user.action_speed_modifier) //yogs: darkspawn
var/datum/progressbar/progbar
if (progress)
progbar = new(user, time, target)

var/endtime = world.time+time
var/starttime = world.time
. = 1
while (world.time < endtime)
stoplag(1)
if (progress)
progbar.update(world.time - starttime)
if(QDELETED(user) || QDELETED(target))
. = 0
break

if(target && !(target in user.do_afters))
. = FALSE
break

if(uninterruptible)
continue

if(drifting && !user.inertia_dir)
drifting = 0
user_loc = user.loc

if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || (extra_checks && !extra_checks.Invoke()))
. = 0
break
if (progress)
qdel(progbar)

if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)


//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
if(check_clicks && next_move > world.time)
Expand All @@ -341,139 +283,81 @@ GLOBAL_LIST_EMPTY(species_list)
checked_health["health"] = health
return ..()

/proc/do_after(mob/user, delay, atom/target = null, needhand = TRUE, progress = TRUE, datum/callback/extra_checks = null, stayStill = TRUE)
/**
* Timed action involving one mob user. Target is optional.
*
* 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, 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(!isnum(delay))
CRASH("do_after was passed a non-number delay: [delay || "null"].")

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
var/atom/target_loc = target?.loc

var/drifting = FALSE
if(!user.Process_Spacemove() && user.inertia_dir)
drifting = TRUE

var/holding = user.get_active_held_item()

var/holdingnull = TRUE //User's hand started out empty, check for an empty hand
if(holding)
holdingnull = FALSE //Users hand started holding something, check to see if it's still holding that

delay = ((delay + user.action_speed_adjust) * user.action_speed_modifier * user.do_after_coefficent()) //yogs: darkspawn
if(!(timed_action_flags & IGNORE_SLOWDOWNS))
delay *= user.action_speed_modifier * user.do_after_coefficent() //yogs: darkspawn

var/datum/progressbar/progbar
if (progress)
progbar = new(user, delay, target)
if(progress)
progbar = new(user, delay, target || user)

SEND_SIGNAL(user, COMSIG_DO_AFTER_BEGAN)

var/endtime = world.time + delay
var/starttime = world.time
. = TRUE
while (world.time < endtime)
stoplag(1)
if (progress)

if(!QDELETED(progbar))
progbar.update(world.time - starttime)

if(drifting && !user.inertia_dir)
drifting = FALSE
user_loc = user.loc

if(QDELETED(user) || user.stat || (!drifting && user.loc != user_loc && stayStill) || (extra_checks && !extra_checks.Invoke()))
if(QDELETED(user) \
|| (!(timed_action_flags & IGNORE_USER_LOC_CHANGE) && !drifting && user.loc != user_loc) \
|| (!(timed_action_flags & IGNORE_HELD_ITEM) && user.get_active_held_item() != holding) \
|| (!(timed_action_flags & IGNORE_INCAPACITATED) && HAS_TRAIT(user, TRAIT_INCAPACITATED)) \
|| (extra_checks && !extra_checks.Invoke()))
. = FALSE
break

if(isliving(user))
var/mob/living/L = user
if(L.IsStun() || L.IsParalyzed())
. = FALSE
break

if(!QDELETED(target_loc) && (QDELETED(target) || target_loc != target.loc))
if((user_loc != target_loc || target_loc != user) && !drifting && stayStill)
. = FALSE
break

if(target && !(target in user.do_afters))
if(target && (user != target) && \
(QDELETED(target) \
|| (!(timed_action_flags & IGNORE_TARGET_LOC_CHANGE) && target.loc != target_loc)))
. = FALSE
break

if(needhand)
//This might seem like an odd check, but you can still need a hand even when it's empty
//i.e the hand is used to pull some item/tool out of the construction
if(!holdingnull)
if(!holding)
. = FALSE
break
if(user.get_active_held_item() != holding)
. = FALSE
break
if (progress)
qdel(progbar)

if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)
if(!QDELETED(progbar))
progbar.end_progress()

/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
. = 1
return

/proc/do_after_mob(mob/user, list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks, required_mobility_flags = MOBILITY_STAND)
if(!user || !targets)
return 0
if(!islist(targets))
targets = list(targets)
var/user_loc = user.loc
if(interaction_key)
LAZYREMOVE(user.do_afters, interaction_key)
SEND_SIGNAL(user, COMSIG_DO_AFTER_ENDED)

var/drifting = 0
if(!user.Process_Spacemove(0) && user.inertia_dir)
drifting = 1

var/list/originalloc = list()
for(var/atom/target in targets)
originalloc[target] = target.loc

var/holding = user.get_active_held_item()
time = ((time + user.action_speed_adjust) * user.action_speed_modifier) //yogs: darkspawn
var/datum/progressbar/progbar
if(progress)
progbar = new(user, time, targets[1])

var/endtime = world.time + time
var/starttime = world.time
var/mob/living/L
if(isliving(user))
L = user
/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
. = 1
mainloop:
while(world.time < endtime)
stoplag(1)
if(progress)
progbar.update(world.time - starttime)
if(QDELETED(user) || !targets)
. = 0
break
if(uninterruptible)
continue

if(drifting && !user.inertia_dir)
drifting = 0
user_loc = user.loc

if(L && !CHECK_MULTIPLE_BITFIELDS(L.mobility_flags, required_mobility_flags))
. = 0
break

for(var/atom/target in targets)
if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || (extra_checks && !extra_checks.Invoke()))
. = 0
break mainloop
if(progbar)
qdel(progbar)

/proc/is_species(A, species_datum)
. = FALSE
Expand Down
38 changes: 0 additions & 38 deletions code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1290,44 +1290,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 = 30, uninterruptible = 0,datum/callback/extra_checks = null)
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))
. = 0
break
if(uninterruptible)
continue

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((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke()))
. = FALSE
break

// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
// If it ever becomes necesary to get a more performant REF(), this lies here in wait
// #define REF(thing) (thing && istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
Expand Down
3 changes: 0 additions & 3 deletions code/_onclick/hud/alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -716,9 +716,6 @@ so as to remain in compliance with the most up-to-date laws."
mymob?.client?.screen |= alert
return 1

/mob
var/list/alerts = list() // contains /atom/movable/screen/alert only // On /mob so clientless mobs will throw alerts properly

/atom/movable/screen/alert/Click(location, control, params)
if(!usr || !usr.client)
return
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
if(butchering && butchering.butchering_enabled)
to_chat(user, span_notice("You begin to butcher [src]..."))
playsound(loc, butchering.butcher_sound, 50, TRUE, -1)
if(do_mob(user, src, butchering.speed) && Adjacent(I))
if(do_after(user, butchering.speed, src) && Adjacent(I))
butchering.Butcher(user, src)
return TRUE
else if(I.is_sharp() && !butchering) //give sharp objects butchering functionality, for consistency
Expand Down
2 changes: 1 addition & 1 deletion code/datums/components/chasm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
if(!HAS_TRAIT(rod, TRAIT_WIELDED))
to_chat(user, span_warning("You need to wield the rod in both hands before you can fish in the chasm!"))
return
if(do_after(user, 3 SECONDS, src.parent))
if(do_after(user, 3 SECONDS, parent))
if(!HAS_TRAIT(rod, TRAIT_WIELDED))
return

Expand Down
Loading

0 comments on commit 9640d15

Please sign in to comment.