[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

🆑
fix: fixes a hard del with thrown items
/🆑

* Fixes throwing hard del

---------

Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-12-25 12:15:06 +00:00
committed by GitHub
co-authored by Bloop
parent cc270306ae
commit fd2e346683
14 changed files with 59 additions and 42 deletions
+11 -3
View File
@@ -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
+12 -10
View File
@@ -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!"))
+6 -4
View File
@@ -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)
+1 -1
View File
@@ -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)
+5 -5
View File
@@ -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)
+2 -1
View File
@@ -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 ..()
+6 -6
View File
@@ -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
..()
+1 -1
View File
@@ -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)
+2 -1
View File
@@ -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)
+2 -3
View File
@@ -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)
+2 -1
View File
@@ -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))
+2 -1
View File
@@ -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))
@@ -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)
+2 -1
View File
@@ -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()