Skip to content

Commit

Permalink
Xeno Throwing Refactor, prevents canceling mob throws by moving (#5175)
Browse files Browse the repository at this point in the history
# About the pull request

<!-- Remove this text and explain what the purpose of your PR is.

Mention if you have tested your changes. If you changed a map, make sure
you used the mapmerge tool.
If this is an Issue Correction, you can type "Fixes Issue #169420" to
link the PR to the corresponding Issue number #169420.

Remember: something that is self-evident to you might not be to others.
Explain your rationale fully, even if you feel it goes without saying.
-->

This refactors xeno throw procs to be less of a pain to work with, and
introduces automatic immobilizing during some xeno throws. They end
after the throw using throw callbacks.

This is important because if you are not immobilized during the throw,
you can just move and step from your current location, canceling it -
mostly visible on flings and vanguard cleave

Xeno throws that apply a stun would already prevent moving.

Because they were only used by Xeno Pounce and Crusher Tumble, i don't
know how robust the callbacks are. It's worth Testmerging.

# Explain why it's good for the game
More reliable throws, throw procs which are easier to work with for new
contributors by baking in the immobilization


# Testing Photographs and Procedure
Done baseline testing with things such as Runner Pounce and Vanguard
Cleave. Not all abiltiies are affected because they used different
handlers, such as Warrior Fling.


# Changelog
:cl:
fix: Some Xeno throws now immobilize their targets, ensuring they do not
walk out of the toss mid-flight.
/:cl:
  • Loading branch information
fira committed Dec 13, 2023
1 parent a5e196b commit 7cf4464
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 45 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ GLOBAL_LIST(trait_name_map)
#define TRAIT_SOURCE_XENO_ACTION_CHARGE "t_s_xeno_action_charge"
///Status trait coming from a xeno nest
#define XENO_NEST_TRAIT "xeno_nest"
///Status trait from a generic throw by xeno abilities
#define XENO_THROW_TRAIT "xeno_throw_trait"
//-- structure traits --
///Status trait coming from being flipped or unflipped.
#define TRAIT_SOURCE_FLIP_TABLE "t_s_flip_table"
Expand Down
29 changes: 29 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -712,3 +712,32 @@

/mob/living/carbon/xenomorph/lying_angle_on_lying_down(new_lying_angle)
return // Do not rotate xenos around on the floor, their sprite is already top-down'ish

/**
* Helper procedure for throwing other carbon based mobs around
* Pretty much a wrapper to [/atom/movable/proc/throw_atom] with extra handling
*
* * target - the target carbon mob that will be thrown
* * direction - the direction the target will be thrown toward, or if null, infered from relative position with target
* * distance - the total distance the throw will be made for
* * speed - throw_atom relative speed of the throw, check [SPEED_AVERAGE] for details
* * shake_camera - whether to shake the thrown mob camera on throw
* * immobilize - if TRUE the mob will be immobilized during the throw, ensuring it doesn't move and break it
*/
/mob/living/carbon/xenomorph/proc/throw_carbon(mob/living/carbon/target, direction, distance, speed = SPEED_VERY_FAST, shake_camera = TRUE, immobilize = TRUE)
if(!direction)
direction = get_dir(src, target)
var/turf/target_destination = get_ranged_target_turf(target, direction, distance)

var/list/end_throw_callbacks
if(immobilize)
end_throw_callbacks = list(CALLBACK(src, PROC_REF(throw_carbon_end), target))
ADD_TRAIT(target, TRAIT_IMMOBILIZED, XENO_THROW_TRAIT)

target.throw_atom(target_destination, distance, speed, src, spin = TRUE, end_throw_callbacks = end_throw_callbacks)
if(shake_camera)
shake_camera(target, 10, 1)

/// Handler callback to reset immobilization status after a successful [/mob/living/carbon/xenomorph/proc/throw_carbon]
/mob/living/carbon/xenomorph/proc/throw_carbon_end(mob/living/carbon/target)
REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, XENO_THROW_TRAIT)
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,6 @@
T.update_xeno_hostile_hud()
to_chat(H, SPAN_XENOHIGHDANGER("You can move again!"))

/proc/xeno_throw_human(mob/living/carbon/H, mob/living/carbon/xenomorph/X, direction, distance, shake_camera = TRUE)
if (!istype(H) || !istype(X) || !direction || !distance)
return

var/turf/T = get_turf(H)
var/turf/temp = get_turf(H)
for (var/x in 0 to distance)
temp = get_step(T, direction)
if (!temp)
break
T = temp

H.throw_atom(T, distance, SPEED_VERY_FAST, X, TRUE)
if(!shake_camera)
return
shake_camera(H, 10, 1)

/mob/living/carbon/xenomorph/proc/zoom_in()
if(stat || resting)
if(is_zoomed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
Mob.apply_damage(15,BRUTE)
if(ishuman(Mob))
var/mob/living/carbon/human/Human = Mob
xeno_throw_human(Human, Xeno, get_dir(Xeno, Human), 1)
Xeno.throw_carbon(Human, distance = 1)
Human.apply_effect(1, WEAKEN)
else
Mob.apply_effect(1, WEAKEN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
X.visible_message(SPAN_XENODANGER("[X] overruns [H], brutally trampling them underfoot!"), SPAN_XENODANGER("You brutalize [H] as you crush them underfoot!"))

H.apply_armoured_damage(get_xeno_damage_slash(H, direct_hit_damage), ARMOR_MELEE, BRUTE)
xeno_throw_human(H, X, X.dir, 3)
X.throw_carbon(H, X.dir, 3)

H.last_damage_data = create_cause_data(X.caste_type, X)
return
Expand Down Expand Up @@ -302,17 +302,11 @@
playsound(Xeno,"alien_tail_swipe", 50, 1)

Xeno.use_plasma(plasma_cost)
var/datum/launch_metadata/LM = new()
LM.target = get_step(get_step(Xeno, target_dir), target_dir)
LM.range = target_dist
LM.speed = SPEED_FAST
LM.thrower = Xeno
LM.spin = FALSE
LM.pass_flags = PASS_CRUSHER_CHARGE
LM.collision_callbacks = list(/mob/living/carbon/human = CALLBACK(src, PROC_REF(handle_mob_collision)))
LM.end_throw_callbacks = list(CALLBACK(src, PROC_REF(on_end_throw), start_charging))

Xeno.launch_towards(LM)

var/target = get_step(get_step(Xeno, target_dir), target_dir)
var/list/collision_callbacks = list(/mob/living/carbon/human = CALLBACK(src, PROC_REF(handle_mob_collision)))
var/list/end_throw_callbacks = list(CALLBACK(src, PROC_REF(on_end_throw), start_charging))
Xeno.throw_atom(target, target_dist, SPEED_FAST, pass_flags = PASS_CRUSHER_CHARGE, end_throw_callbacks = end_throw_callbacks, collision_callbacks = collision_callbacks)

apply_cooldown()
return ..()
Original file line number Diff line number Diff line change
Expand Up @@ -433,18 +433,7 @@
pre_pounce_effects()

X.pounce_distance = get_dist(X, A)

var/datum/launch_metadata/LM = new()
LM.target = A
LM.range = distance
LM.speed = throw_speed
LM.thrower = X
LM.spin = FALSE
LM.pass_flags = pounce_pass_flags
LM.collision_callbacks = pounce_callbacks

X.launch_towards(LM)

X.throw_atom(A, distance, throw_speed, X, pass_flags = pounce_pass_flags, collision_callbacks = pounce_callbacks)
X.update_icons()

additional_effects_always()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
fling_distance *= 0.1
vanguard_user.visible_message(SPAN_XENODANGER("[vanguard_user] deals [target_atom] a massive blow, sending them flying!"), SPAN_XENOHIGHDANGER("You deal [target_atom] a massive blow, sending them flying!"))
vanguard_user.flick_attack_overlay(target_carbon, "slam")
xeno_throw_human(target_carbon, vanguard_user, get_dir(vanguard_user, target_atom), fling_distance)
vanguard_user.throw_carbon(target_atom, null, fling_distance)

apply_cooldown()
return ..()
Expand Down Expand Up @@ -509,7 +509,7 @@
if(H.mob_size >= MOB_SIZE_BIG)
continue

xeno_throw_human(H, X, facing, fling_dist)
X.throw_carbon(H, facing, fling_dist)

H.apply_effect(get_xeno_stun_duration(H, 0.5), WEAKEN)
new /datum/effects/xeno_slow(H, X, ttl = get_xeno_stun_duration(H, 25))
Expand Down
6 changes: 5 additions & 1 deletion code/modules/movement/launching/launching.dm
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
return TRUE

// Proc for throwing items (should only really be used for throw)
/atom/movable/proc/throw_atom(atom/target, range, speed = 0, atom/thrower, spin, launch_type = NORMAL_LAUNCH, pass_flags = NO_FLAGS)
/atom/movable/proc/throw_atom(atom/target, range, speed = 0, atom/thrower, spin, launch_type = NORMAL_LAUNCH, pass_flags = NO_FLAGS, list/end_throw_callbacks, list/collision_callbacks)
var/temp_pass_flags = pass_flags
switch (launch_type)
if (NORMAL_LAUNCH)
Expand All @@ -135,6 +135,10 @@
LM.speed = speed
LM.thrower = thrower
LM.spin = spin
if(end_throw_callbacks)
LM.end_throw_callbacks = end_throw_callbacks
if(collision_callbacks)
LM.collision_callbacks = collision_callbacks

if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_LAUNCH, LM) & COMPONENT_LAUNCH_CANCEL)
return
Expand Down

0 comments on commit 7cf4464

Please sign in to comment.