From fd2e34668320d30eea3daa0bb800b40c0b2553dd Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Mon, 25 Dec 2023 13:15:06 +0100 Subject: [PATCH] [MIRROR] Fixes throwing hard del [MDB IGNORE] (#25846) * Fixes throwing hard del (#80551) ## About The Pull Request Fixes https://github.com/tgstation/tgstation/issues/80472 ## Why It's Good For The Game Less CI failures ## Changelog :cl: fix: fixes a hard del with thrown items /:cl: * Fixes throwing hard del --------- Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> --- code/controllers/subsystem/throwing.dm | 14 +++++++++--- code/datums/components/boomerang.dm | 22 ++++++++++--------- code/datums/components/pet_commands/fetch.dm | 10 +++++---- code/datums/components/tackle.dm | 2 +- code/game/objects/items/theft_tools.dm | 10 ++++----- code/game/objects/items/toys.dm | 3 ++- code/modules/antagonists/cult/cult_items.dm | 12 +++++----- code/modules/basketball/hoop.dm | 2 +- code/modules/cards/cards.dm | 3 ++- code/modules/cards/deck/deck.dm | 5 ++--- code/modules/mob/living/carbon/carbon.dm | 3 ++- code/modules/mob/living/living_movement.dm | 3 ++- .../reagent_containers/cups/drinks.dm | 9 ++++---- code/modules/recycling/disposal/bin.dm | 3 ++- 14 files changed, 59 insertions(+), 42 deletions(-) diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 60c8ecbf84c..b391200d6cf 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -58,7 +58,7 @@ SUBSYSTEM_DEF(throwing) ///Turfs to travel per tick var/speed ///If a mob is the one who has thrown the object, then it's moved here. This can be null and must be null checked before trying to use it. - var/mob/thrower + var/datum/weakref/thrower ///A variable that helps in describing objects thrown at an angle, if it should be moved diagonally first or last. var/diagonals_first ///Set to TRUE if the throw is exclusively diagonal (45 Degree angle throws for example) @@ -101,7 +101,8 @@ SUBSYSTEM_DEF(throwing) src.init_dir = init_dir src.maxrange = maxrange src.speed = speed - src.thrower = thrower + if(thrower) + src.thrower = WEAKREF(thrower) src.diagonals_first = diagonals_first src.force = force src.gentle = gentle @@ -124,6 +125,12 @@ SUBSYSTEM_DEF(throwing) qdel(src) +/// Returns the mob thrower, or null +/datum/thrownthing/proc/get_thrower() + . = thrower?.resolve() + if(isnull(.)) + thrower = null + /datum/thrownthing/proc/tick() var/atom/movable/AM = thrownthing if (!isturf(AM.loc) || !AM.throwing) @@ -135,10 +142,11 @@ SUBSYSTEM_DEF(throwing) return var/atom/movable/actual_target = initial_target?.resolve() + var/mob/mob_thrower = get_thrower() if(dist_travelled) //to catch sneaky things moving on our tile while we slept for(var/atom/movable/obstacle as anything in get_turf(thrownthing)) - if (obstacle == thrownthing || (obstacle == thrower && !ismob(thrownthing))) + if (obstacle == thrownthing || (obstacle == mob_thrower && !ismob(thrownthing))) continue if(ismob(obstacle) && thrownthing.pass_flags & PASSMOB && (obstacle != actual_target)) continue diff --git a/code/datums/components/boomerang.dm b/code/datums/components/boomerang.dm index 751013d7116..8b35f171c28 100644 --- a/code/datums/components/boomerang.dm +++ b/code/datums/components/boomerang.dm @@ -37,12 +37,13 @@ * * thrown_thing: The thrownthing datum from the parent object's latest throw. Updates thrown_boomerang. * * spin: Carry over from POST_THROW, the speed of rotation on the boomerang when thrown. */ -/datum/component/boomerang/proc/prepare_throw(datum/source, datum/thrownthing/thrown_thing, spin) +/datum/component/boomerang/proc/prepare_throw(datum/source, datum/thrownthing/throwingdatum, spin) SIGNAL_HANDLER - if(thrower_easy_catch_enabled && thrown_thing?.thrower) - if(iscarbon(thrown_thing.thrower)) - var/mob/living/carbon/Carbon = thrown_thing.thrower - Carbon.throw_mode_on(THROW_MODE_TOGGLE) + var/mob/thrower = throwingdatum?.get_thrower() + if(thrower_easy_catch_enabled && thrower) + if(iscarbon(thrower)) + var/mob/living/carbon/carbon_mob = thrower + carbon_mob.throw_mode_on(THROW_MODE_TOGGLE) return /** @@ -63,24 +64,25 @@ * * source: Datum src from original signal call. * * throwing_datum: The thrownthing datum that originally impacted the object, that we use to build the new throwing datum for the rebound. */ -/datum/component/boomerang/proc/return_missed_throw(datum/source, datum/thrownthing/throwing_datum) +/datum/component/boomerang/proc/return_missed_throw(datum/source, datum/thrownthing/throwingdatum) SIGNAL_HANDLER if(!COOLDOWN_FINISHED(src, last_boomerang_throw)) return var/obj/item/true_parent = parent - aerodynamic_swing(throwing_datum, true_parent) + aerodynamic_swing(throwingdatum, true_parent) /** * Proc that triggers when the thrown boomerang has been fully thrown, rethrowing the boomerang back to the thrower, and producing visible feedback. * * throwing_datum: The thrownthing datum that originally impacted the object, that we use to build the new throwing datum for the rebound. * * hit_atom: The atom that has been hit by the boomerang'd object. */ -/datum/component/boomerang/proc/aerodynamic_swing(datum/thrownthing/throwing_datum, obj/item/true_parent) +/datum/component/boomerang/proc/aerodynamic_swing(datum/thrownthing/throwingdatum, obj/item/true_parent) var/mob/thrown_by = true_parent.thrownby?.resolve() if(thrown_by) - addtimer(CALLBACK(true_parent, TYPE_PROC_REF(/atom/movable, throw_at), thrown_by, boomerang_throw_range, throwing_datum.speed, null, TRUE), 1) + addtimer(CALLBACK(true_parent, TYPE_PROC_REF(/atom/movable, throw_at), thrown_by, boomerang_throw_range, throwingdatum.speed, null, TRUE), 1) COOLDOWN_START(src, last_boomerang_throw, BOOMERANG_REBOUND_INTERVAL) - true_parent.visible_message(span_danger("[true_parent] is flying back at [throwing_datum.thrower]!"), \ + var/mob/thrower = throwingdatum?.get_thrower() + true_parent.visible_message(span_danger("[true_parent] is flying back at [thrower]!"), \ span_danger("You see [true_parent] fly back at you!"), \ span_hear("You hear an aerodynamic woosh!")) diff --git a/code/datums/components/pet_commands/fetch.dm b/code/datums/components/pet_commands/fetch.dm index fa0b3193a44..9a42c485d5c 100644 --- a/code/datums/components/pet_commands/fetch.dm +++ b/code/datums/components/pet_commands/fetch.dm @@ -57,7 +57,7 @@ RegisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED, PROC_REF(listen_throw_land)) /// A throw we were listening to has finished, see if it's in range for us to try grabbing it -/datum/pet_command/point_targeting/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwing_datum) +/datum/pet_command/point_targeting/fetch/proc/listen_throw_land(obj/item/thrown_thing, datum/thrownthing/throwingdatum) SIGNAL_HANDLER UnregisterSignal(thrown_thing, COMSIG_MOVABLE_THROW_LANDED) @@ -69,9 +69,11 @@ if (!can_see(parent, thrown_thing, length = sense_radius)) return - try_activate_command(throwing_datum.thrower) - set_command_target(parent, thrown_thing) - parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, throwing_datum.thrower) + var/mob/thrower = throwingdatum?.get_thrower() + if(thrower) + try_activate_command(thrower) + set_command_target(parent, thrown_thing) + parent.ai_controller.set_blackboard_key(BB_FETCH_DELIVER_TO, thrower) // Don't try and fetch turfs or anchored objects if someone points at them /datum/pet_command/point_targeting/fetch/look_for_target(mob/living/pointing_friend, obj/item/pointed_atom) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index c05277c136f..d89c028c584 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -65,7 +65,7 @@ SIGNAL_HANDLER tackle_ref = WEAKREF(tackle) - tackle.thrower = user + tackle.thrower = WEAKREF(user) ///See if we can tackle or not. If we can, leap! /datum/component/tackler/proc/checkTackle(mob/living/carbon/user, atom/clicked_atom, list/modifiers) diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index 8b7ff362046..e695dedbca3 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -189,11 +189,11 @@ var/mob/living/victim = hit_atom if(victim.incorporeal_move || victim.status_flags & GODMODE) //try to keep this in sync with supermatter's consume fail conditions return ..() - if(throwingdatum?.thrower) - var/mob/user = throwingdatum.thrower - log_combat(throwingdatum?.thrower, hit_atom, "consumed", src) - message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)], thrown by [key_name_admin(user)].") - investigate_log("has consumed [key_name(victim)], thrown by [key_name(user)]", INVESTIGATE_ENGINE) + var/mob/thrower = throwingdatum?.get_thrower() + if(thrower) + log_combat(thrower, hit_atom, "consumed", src) + message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)], thrown by [key_name_admin(thrower)].") + investigate_log("has consumed [key_name(victim)], thrown by [key_name(thrower)]", INVESTIGATE_ENGINE) else message_admins("[src] has consumed [key_name_admin(victim)] [ADMIN_JMP(src)] via throw impact.") investigate_log("has consumed [key_name(victim)] via throw impact.", INVESTIGATE_ENGINE) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 18d65f2d8b6..c91f6eb6c44 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -135,7 +135,8 @@ return ..() /obj/item/toy/balloon/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) - if(ismonkey(throwingdatum.thrower) && istype(AM, /obj/item/ammo_casing/foam_dart)) + var/mob/thrower = throwingdatum?.get_thrower() + if(ismonkey(thrower) && istype(AM, /obj/item/ammo_casing/foam_dart)) pop_balloon(monkey_pop = TRUE) else return ..() diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 944aa45e377..f99f2db9e79 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -1023,8 +1023,7 @@ Striking a noncultist, however, will tear their flesh."} return FALSE /obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - var/turf/T = get_turf(hit_atom) - var/datum/thrownthing/D = throwingdatum + var/turf/impact_turf = get_turf(hit_atom) if(isliving(hit_atom)) var/mob/living/target = hit_atom @@ -1037,13 +1036,14 @@ Striking a noncultist, however, will tear their flesh."} return if(!..()) target.Paralyze(30) - if(D?.thrower) - for(var/mob/living/Next in orange(2, T)) + var/mob/thrower = throwingdatum?.get_thrower() + if(thrower) + for(var/mob/living/Next in orange(2, impact_turf)) if(!Next.density || IS_CULTIST(Next)) continue - throw_at(Next, 3, 1, D.thrower) + throw_at(Next, 3, 1, thrower) return - throw_at(D.thrower, 7, 1, null) + throw_at(thrower, 7, 1, null) else ..() diff --git a/code/modules/basketball/hoop.dm b/code/modules/basketball/hoop.dm index 32699de1dc9..f356fc52315 100644 --- a/code/modules/basketball/hoop.dm +++ b/code/modules/basketball/hoop.dm @@ -152,7 +152,7 @@ var/score_chance = throw_range_success[distance] var/obj/structure/hoop/backboard = throwingdatum.initial_target?.resolve() var/click_on_hoop = TRUE - var/mob/living/thrower = throwingdatum.thrower + var/mob/living/thrower = throwingdatum?.get_thrower() // aim penalty for not clicking directly on the hoop when shooting if(!istype(backboard) || backboard != src) diff --git a/code/modules/cards/cards.dm b/code/modules/cards/cards.dm index fb84b2d9789..5cd17a53515 100644 --- a/code/modules/cards/cards.dm +++ b/code/modules/cards/cards.dm @@ -27,7 +27,8 @@ if(. || !istype(target)) // was it caught or is the target not a living mob return . - if(!throwingdatum?.thrower) // if a mob didn't throw it (need two people to play 52 pickup) + var/mob/thrower = throwingdatum?.get_thrower() + if(!thrower) // if a mob didn't throw it (need two people to play 52 pickup) return if(count_cards() == 0) diff --git a/code/modules/cards/deck/deck.dm b/code/modules/cards/deck/deck.dm index 632b01d509d..6a199bec4d7 100644 --- a/code/modules/cards/deck/deck.dm +++ b/code/modules/cards/deck/deck.dm @@ -188,11 +188,10 @@ if(. || !istype(target)) // was it caught or is the target not a living mob return . - if(!throwingdatum?.thrower) // if a mob didn't throw it (need two people to play 52 pickup) + var/mob/living/thrower = throwingdatum?.get_thrower() + if(!thrower) // if a mob didn't throw it (need two people to play 52 pickup) return - var/mob/living/thrower = throwingdatum.thrower - target.visible_message(span_warning("[target] is forced to play 52 card pickup!"), span_warning("You are forced to play 52 card pickup.")) target.add_mood_event("lost_52_card_pickup", /datum/mood_event/lost_52_card_pickup) thrower.add_mood_event("won_52_card_pickup", /datum/mood_event/won_52_card_pickup) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 58ed42b61f5..1c3fcbc41c1 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -50,7 +50,8 @@ var/hurt = TRUE var/extra_speed = 0 var/oof_noise = FALSE //We smacked something with denisty, so play a noise - if(throwingdatum.thrower != src) + var/mob/thrower = throwingdatum?.get_thrower() + if(thrower != src) extra_speed = min(max(0, throwingdatum.speed - initial(throw_speed)), CARBON_MAX_IMPACT_SPEED_BONUS) if(istype(throwingdatum)) diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index f694e685cf0..79cb96c90c3 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -60,7 +60,8 @@ if(.) return if(mover.throwing) - return (!density || (body_position == LYING_DOWN) || (mover.throwing.thrower == src && !ismob(mover))) + var/mob/thrower = mover.throwing.get_thrower() + return (!density || (body_position == LYING_DOWN) || (thrower == src && !ismob(mover))) if(buckled == mover) return TRUE if(ismob(mover) && (mover in buckled_mobs)) diff --git a/code/modules/reagents/reagent_containers/cups/drinks.dm b/code/modules/reagents/reagent_containers/cups/drinks.dm index f8948ae6eea..12a3d023c72 100644 --- a/code/modules/reagents/reagent_containers/cups/drinks.dm +++ b/code/modules/reagents/reagent_containers/cups/drinks.dm @@ -15,7 +15,8 @@ /obj/item/reagent_containers/cup/glass/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum, do_splash = TRUE) . = ..() if(!.) //if the bottle wasn't caught - smash(hit_atom, throwingdatum?.thrower, TRUE) + var/mob/thrower = throwingdatum?.get_thrower() + smash(hit_atom, thrower, TRUE) /obj/item/reagent_containers/cup/glass/proc/smash(atom/target, mob/thrower, ranged = FALSE, break_top = FALSE) if(!isGlass) @@ -314,9 +315,9 @@ return if(prob(flip_chance)) // landed upright src.visible_message(span_notice("[src] lands upright!")) - if(throwingdatum.thrower) - var/mob/living/living_thrower = throwingdatum.thrower - living_thrower.add_mood_event("bottle_flip", /datum/mood_event/bottle_flip) + var/mob/living/thrower = throwingdatum?.get_thrower() + if(thrower) + thrower.add_mood_event("bottle_flip", /datum/mood_event/bottle_flip) else // landed on it's side animate(src, transform = matrix(prob(50)? 90 : -90, MATRIX_ROTATE), time = 3, loop = 0) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 123d81501fa..66c1e073e2b 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -386,7 +386,8 @@ /obj/machinery/disposal/bin/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if(isitem(AM) && AM.CanEnterDisposals()) - if((throwingdatum.thrower && HAS_TRAIT(throwingdatum.thrower, TRAIT_THROWINGARM)) || prob(75)) + var/mob/thrower = throwingdatum?.get_thrower() + if((thrower && HAS_TRAIT(thrower, TRAIT_THROWINGARM)) || prob(75)) AM.forceMove(src) visible_message(span_notice("[AM] lands in [src].")) update_appearance()