mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
[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:
@@ -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
|
||||
|
||||
@@ -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!"))
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user