diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8962230946c8..d37c9185fa6d 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -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" diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index b5848786c698..289dd6952cda 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -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) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm index 35024d7304af..b05000cc4588 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm @@ -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) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm index 63051a94efa9..73ce0fc41b63 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_abilities.dm @@ -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) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm index 34a9a4833fec..67c92a0efda7 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm @@ -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 @@ -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 ..() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 74a46a30e9ba..fa60187b6fab 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -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() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm index 1a0205862480..f55676f96921 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm @@ -191,7 +191,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 ..() @@ -508,7 +508,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)) diff --git a/code/modules/movement/launching/launching.dm b/code/modules/movement/launching/launching.dm index 96db667fe2ff..f72a7c773490 100644 --- a/code/modules/movement/launching/launching.dm +++ b/code/modules/movement/launching/launching.dm @@ -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) @@ -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