diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 034de38eeb..5365223c4d 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -46,6 +46,11 @@ #define COMSIG_CLIENT_KEY_DOWN "client_key_down" #define COMSIG_CLIENT_KEY_UP "client_key_up" +///from /datum/key_down(): (key, client/user) +#define COMSIG_DATUM_KEY_DOWN "datum_key_down" +///from /datum/key_up(): (key, client/user) +#define COMSIG_DATUM_KEY_UP "datum_key_up" + ///from /datum/controller/subsystem/radio/get_available_tcomm_zs(): (list/tcomms) #define COMSIG_SSRADIO_GET_AVAILABLE_TCOMMS_ZS "ssradio_get_available_tcomms_zs" @@ -298,6 +303,10 @@ #define COMSIG_MOVABLE_PRE_LAUNCH "movable_pre_launch" #define COMPONENT_LAUNCH_CANCEL (1<<0) +///from /atom/movable/launch_towards(): (datum/launch_metadata/LM) +#define COMSIG_MOVABLE_POST_LAUNCH "movable_post_launch" + #define COMPONENT_ABORT_COLLISION_CALLBACKS (1<<0) + // Return non-zero value to override original behaviour #define COMSIG_MOB_SCREECH_ACT "mob_screech_act" #define COMPONENT_SCREECH_ACT_CANCEL (1<<0) diff --git a/code/__DEFINES/keybinding.dm b/code/__DEFINES/keybinding.dm index 982fa8b417..6fedca7f15 100644 --- a/code/__DEFINES/keybinding.dm +++ b/code/__DEFINES/keybinding.dm @@ -55,6 +55,7 @@ #define COMSIG_KB_HUMAN_WEAPON_UNLOAD "keybinding_human_weapon_unload" #define COMSIG_KB_HUMAN_WEAPON_ATTACHMENT "keybinding_human_weapon_attachment" #define COMSIG_KB_HUMAN_WEAPON_ATTACHMENT_RAIL "keybinding_human_weapon_attachment_rail" +#define COMSIG_KB_HUMAN_PARRY "keybinding_human_parry" //Living #define COMSIG_KB_LIVING_RESIST_DOWN "keybinding_living_resist_down" diff --git a/code/datums/keybinding/human_combat.dm b/code/datums/keybinding/human_combat.dm index 8d3bad1bfb..9eff2ab017 100644 --- a/code/datums/keybinding/human_combat.dm +++ b/code/datums/keybinding/human_combat.dm @@ -1,13 +1,14 @@ /datum/keybinding/human/combat category = CATEGORY_HUMAN_COMBAT weight = WEIGHT_MOB + var/requires_gun = TRUE /datum/keybinding/human/combat/can_use(client/user) . = ..() if(!.) return var/mob/M = user.mob - return isgun(M.get_held_item()) + return !requires_gun || isgun(M.get_held_item()) /datum/keybinding/human/combat/field_strip_weapon hotkey_keys = list() @@ -169,3 +170,11 @@ var/obj/item/weapon/gun/G = H.get_held_item() G.activate_rail_attachment_verb() return TRUE + +/datum/keybinding/human/combat/parry + hotkey_keys = list("Space") + classic_keys = list() + name = "human_parry" + full_name = "Parry" + keybind_signal = COMSIG_KB_HUMAN_PARRY + requires_gun = FALSE diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index d8f13f8778..8a96ddfb89 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -46,7 +46,7 @@ singular_name = "medical gauze" desc = "Some sterile gauze to wrap around bloody stumps and lacerations." icon_state = "brutepack" - + stack_id = "bruise pack" /obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob) @@ -90,7 +90,7 @@ singular_name = "ointment" icon_state = "ointment" heal_burn = 1 - + stack_id = "ointment" /obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob) @@ -119,7 +119,7 @@ SPAN_HELPFUL("[user] salves the wounds on your [affecting.display_name]."), SPAN_NOTICE("[user] salves the wounds [possessive_their] [affecting.display_name].")) use(1) - playsound(user, 'sound/handling/ointment_spreading.ogg', 25, 1, 2) + playsound(user, 'sound/handling/ointment_spreading.ogg', 25, 1, 2) else if (H.can_be_operated_on()) //Checks if mob is lying down on table for surgery if (do_surgery(H,user,src)) @@ -128,57 +128,46 @@ to_chat(user, SPAN_NOTICE("The [affecting.display_name] is cut open, you'll need more than a bandage!")) -/obj/item/stack/medical/advanced/bruise_pack - name = "advanced trauma kit" - singular_name = "advanced trauma kit" - desc = "An advanced trauma kit for severe injuries." - icon_state = "traumakit" - heal_brute = 12 - - stack_id = "advanced bruise pack" +/obj/item/stack/medical/advanced/attack(mob/living/carbon/M, mob/user) + if(..()) + return TRUE + if(M.action_busy) + return + if (!istype(M, /mob/living/carbon/human)) + return -/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M, mob/user) - if(..()) - return 1 + var/mob/living/carbon/human/H = M + if((H.getBruteLoss() <= 0 || !heal_brute) && (H.getFireLoss() <= 0 || !heal_burn)) + to_chat(user, SPAN_WARNING("[M] is already at full health!")) + return - if (istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M + if(!do_after(user, 30, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY, M, INTERRUPT_MOVED, BUSY_ICON_MEDICAL)) + return - var/heal_amt = heal_brute - if(user.skills) - if(!skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC)) //untrained marines have a hard time using it - to_chat(user, SPAN_WARNING("You start fumbling with [src].")) - if(!do_after(user, 30, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY, M, INTERRUPT_MOVED, BUSY_ICON_MEDICAL)) - return - heal_amt = 3 //non optimal application means less healing + for(var/i in H.limbs) + var/obj/limb/affecting = i + affecting.remove_all_bleeding(TRUE, TRUE) - var/obj/limb/affecting = H.get_limb(user.zone_selected) - if(affecting.surgery_open_stage == 0) - var/bandaged = affecting.bandage() + var/possessive = "[user == M ? "your" : "[M]'s"]" + var/possessive_their = "[user == M ? "their" : "[M]'s"]" + user.affected_message(M, + SPAN_HELPFUL("You clean and seal the wounds on [possessive] limbs with bioglue."), + SPAN_HELPFUL("[user] cleans and seals the wounds on your limbs with bioglue."), + SPAN_NOTICE("[user] cleans and seals the wounds on [possessive_their] limbs with bioglue.")) + H.heal_overall_damage(heal_brute, heal_burn, TRUE) + use(1) - if(!bandaged) - to_chat(user, SPAN_WARNING("The wounds on [M]'s [affecting.display_name] have already been treated.")) - return 1 - else - var/possessive = "[user == M ? "your" : "[M]'s"]" - var/possessive_their = "[user == M ? "their" : "[M]'s"]" - user.affected_message(M, - SPAN_HELPFUL("You clean and seal the wounds on [possessive] [affecting.display_name] with bioglue."), - SPAN_HELPFUL("[user] cleans and seals the wounds on your [affecting.display_name] with bioglue."), - SPAN_NOTICE("[user] cleans and seals the wounds on [possessive_their] [affecting.display_name] with bioglue.")) - if(bandaged) - H.apply_damage(-heal_amt, BRUTE, affecting) - use(1) - else - if(H.can_be_operated_on()) //Checks if mob is lying down on table for surgery - if(do_surgery(H, user, src)) - return - else - to_chat(user, SPAN_NOTICE("The [affecting.display_name] is cut open, you'll need more than a bandage!")) +/obj/item/stack/medical/advanced/bruise_pack + name = "advanced trauma kit" + singular_name = "advanced trauma kit" + desc = "An advanced trauma kit for severe injuries." + icon_state = "traumakit" + heal_brute = 12 + stack_id = "advanced bruise pack" /obj/item/stack/medical/advanced/bruise_pack/tajaran name = "\improper S'rendarr's Hand leaf" singular_name = "S'rendarr's Hand leaf" @@ -203,47 +192,8 @@ desc = "An advanced treatment kit for severe burns." icon_state = "burnkit" heal_burn = 12 - - stack_id = "advanced burn kit" - -/obj/item/stack/medical/advanced/ointment/attack(mob/living/carbon/M as mob, mob/user as mob) - if(..()) - return 1 - - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - - var/heal_amt = heal_burn - if(user.skills) - if(!skillcheck(user, SKILL_MEDICAL, SKILL_MEDICAL_MEDIC)) //untrained marines have a hard time using it - to_chat(user, SPAN_WARNING("You start fumbling with [src].")) - if(!do_after(user, 30, INTERRUPT_NO_NEEDHAND, BUSY_ICON_FRIENDLY, M, INTERRUPT_MOVED, BUSY_ICON_MEDICAL)) - return - heal_amt = 3 //non optimal application means less healing - - var/obj/limb/affecting = H.get_limb(user.zone_selected) - - if(affecting.surgery_open_stage == 0) - if(!affecting.salve()) - to_chat(user, SPAN_WARNING("The wounds on [M]'s [affecting.display_name] have already been salved.")) - return 1 - else - var/possessive = "[user == M ? "your" : "[M]'s"]" - var/possessive_their = "[user == M ? "their" : "[M]'s"]" - user.affected_message(M, - SPAN_HELPFUL("You cover the wounds on [possessive] [affecting.display_name] with regenerative membrane."), - SPAN_HELPFUL("[user] covers the wounds on your [affecting.display_name] with regenerative membrane."), - SPAN_NOTICE("[user] covers the wounds on [possessive_their] [affecting.display_name] with regenerative membrane.")) - - H.apply_damage(-heal_amt, BURN, affecting) - use(1) - else - if(H.can_be_operated_on()) //Checks if mob is lying down on table for surgery - if(do_surgery(H,user,src)) - return - else - to_chat(user, SPAN_NOTICE("The [affecting.display_name] is cut open, you'll need more than a bandage!")) + stack_id = "advanced burn kit" /obj/item/stack/medical/splint name = "medical splints" singular_name = "medical splint" @@ -300,4 +250,4 @@ if(affecting.apply_splints(src, user, M, indestructible_splints)) // Referenced in external organ helpers. use(1) - playsound(user, 'sound/handling/splint1.ogg', 25, 1, 2) \ No newline at end of file + playsound(user, 'sound/handling/splint1.ogg', 25, 1, 2) diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm index f36a3256e5..bed7e8c333 100644 --- a/code/modules/keybindings/setup.dm +++ b/code/modules/keybindings/setup.dm @@ -1,8 +1,10 @@ // Set a client's focus to an object and override these procs on that object to let it handle keypresses /datum/proc/key_down(key, client/user) // Called when a key is pressed down initially + SEND_SIGNAL(src, COMSIG_DATUM_KEY_DOWN, key, user) return /datum/proc/key_up(key, client/user) // Called when a key is released + SEND_SIGNAL(src, COMSIG_DATUM_KEY_UP, key, user) return /datum/proc/keyLoop(client/user) // Called once every frame set waitfor = FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm index 002136db0d..6f47216e8e 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm @@ -161,9 +161,10 @@ var/freeze_time = 5 // 5 for runners, 15 for lurkers var/freeze_timer_id = TIMER_ID_NULL // Timer to cancel the end freeze if it can be cancelled earlier - var/windup = FALSE // Is there a do_after before we pounce? - var/windup_duration = 20 // How long to wind up, if applicable + var/windup = TRUE // Is there a do_after before we pounce? + var/windup_duration = 0.5 SECONDS // How long to wind up, if applicable var/windup_interruptable = TRUE // Can the windup be interrupted? + var/windup_interrupt_flags = INTERRUPT_INCAPACITATED var/can_be_shield_blocked = FALSE // Some legacy stuff, self explanatory var/should_destroy_objects = FALSE // Only used for ravager charge @@ -174,6 +175,9 @@ var/list/pounce_callbacks = null // Specific callbacks to invoke when a pounce lands on an atom of a specific type // (note that if a collided atom does not match any of the key types, defaults to the appropriate X_launch_collision proc) + var/successful_parry = FALSE + var/atom/current_pounce_target + /datum/action/xeno_action/activable/pounce/New() . = ..() initialize_pounce_pass_flags() 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 9c20aa8a0a..39cb11bb05 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -283,13 +283,17 @@ apply_cooldown() + cleanup_pounce_target() + current_pounce_target = A + RegisterSignal(A, COMSIG_KB_HUMAN_PARRY, .proc/handle_parry) + if (windup) if (!windup_interruptable) X.frozen = TRUE X.anchored = TRUE X.update_canmove() - if (!do_after(X, windup_duration, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) + if (!do_after(X, windup_duration, windup_interrupt_flags, BUSY_ICON_HOSTILE)) to_chat(X, SPAN_XENODANGER("You cancel your [ability_name]!")) if (!windup_interruptable) X.frozen = 0 @@ -316,6 +320,9 @@ LM.spin = FALSE LM.pass_flags = pounce_pass_flags LM.collision_callbacks = pounce_callbacks + LM.ignore_collision_behaviour = successful_parry + RegisterSignal(A, COMSIG_PARENT_QDELETING, .proc/cleanup_pounce_target) + RegisterSignal(owner, COMSIG_MOVABLE_POST_LAUNCH, .proc/handle_finish_launch, TRUE) X.launch_towards(LM) //Victim, distance, speed @@ -324,6 +331,57 @@ return +/datum/action/xeno_action/activable/pounce/proc/handle_finish_launch() + SIGNAL_HANDLER + var/parried = successful_parry + var/mob/living/carbon/human/H = current_pounce_target + + cleanup_pounce_target() + if(!H || !parried) + return + if(H.get_active_hand() && H.Adjacent(owner)) + INVOKE_ASYNC(H, /mob.proc/do_click, owner, list()) + var/turf/valid_turf + var/direction_between = get_dir(owner, H) + for(var/dir in GLOB.cardinals) + if(dir & direction_between) + continue + + var/turf/T = get_step(H, dir) + if(LinkBlocked(H, get_turf(H), T, list(H))) + continue + + valid_turf = T + break + + if(valid_turf) + var/turf/prev_turf = get_turf(H) + H.Move(valid_turf, get_dir(H, valid_turf)) + owner.Move(prev_turf, get_dir(owner, prev_turf)) + return COMPONENT_ABORT_COLLISION_CALLBACKS + +/datum/action/xeno_action/activable/pounce/proc/cleanup_pounce_target() + SIGNAL_HANDLER + if(!current_pounce_target) + return + successful_parry = FALSE + UnregisterSignal(current_pounce_target, list( + COMSIG_KB_HUMAN_PARRY, + COMSIG_PARENT_QDELETING + )) + current_pounce_target = null + +/datum/action/xeno_action/activable/pounce/proc/handle_parry(var/mob/living/carbon/human/H) + SIGNAL_HANDLER + if(!owner) + return + + successful_parry = TRUE + if(owner.launch_metadata) + owner.launch_metadata.ignore_collision_behaviour = TRUE + UnregisterSignal(H, COMSIG_KB_HUMAN_PARRY) + return COMPONENT_KB_ACTIVATED + // Massive, customizable spray_acid /datum/action/xeno_action/activable/spray_acid/use_ability(atom/A) var/mob/living/carbon/Xenomorph/X = owner diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_abilities.dm index 8ebdcf55b0..b44eb742ba 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_abilities.dm @@ -32,6 +32,8 @@ plasma_cost = 25 // Pounce config + + windup = FALSE distance = 5 knockdown = FALSE // Should we knock down the target? slash = FALSE // Do we slash upon reception? diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_abilities.dm index 1238bf42c3..b54977b5de 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_abilities.dm @@ -30,7 +30,7 @@ // Warrior Lunge -/datum/action/xeno_action/activable/lunge +/datum/action/xeno_action/activable/pounce/lunge name = "Lunge" action_icon_state = "lunge" ability_name = "lunge" @@ -38,9 +38,13 @@ action_type = XENO_ACTION_CLICK ability_primacy = XENO_PRIMARY_ACTION_2 xeno_cooldown = 100 - + plasma_cost = 0 + // Configurables - var/grab_range = 6 + distance = 6 + knockdown = FALSE + freeze_self = FALSE + var/click_miss_cooldown = 15 var/twitch_message_cooldown = 0 //apparently this is necessary for a tiny code that makes the lunge message on cooldown not be spammable, doesn't need to be big so 5 will do. diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm index 8926e0bace..2f7a79884c 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm @@ -1,4 +1,4 @@ -/datum/action/xeno_action/activable/lunge/use_ability(atom/A) +/datum/action/xeno_action/activable/pounce/lunge/use_ability(atom/A) var/mob/living/carbon/Xenomorph/X = owner if (!action_cooldown_check()) @@ -7,16 +7,10 @@ twitch_message_cooldown = world.time + 5 SECONDS return //this gives a little feedback on why your lunge didn't hit other than the lunge button going grey. Plus, it might spook marines that almost got lunged if they know why the message appeared, and extra spookiness is always good. - if (!A) - return - if (!isturf(X.loc)) to_chat(X, SPAN_XENOWARNING("You can't lunge from here!")) return - if (!X.check_state() || X.agility) - return - if(X.can_not_harm(A) || !ismob(A)) apply_cooldown_override(click_miss_cooldown) return @@ -25,15 +19,7 @@ if(H.stat == DEAD) return - if (!check_and_use_plasma_owner()) - return - - apply_cooldown() - ..() - - X.visible_message(SPAN_XENOWARNING("\The [X] lunges towards [H]!"), SPAN_XENOWARNING("You lunge at [H]!")) - - X.throw_atom(get_step_towards(A, X), grab_range, SPEED_FAST, X) + . = ..() if (X.Adjacent(H)) X.start_pulling(H,1) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm index d23fa913db..d0f28971e9 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm @@ -188,7 +188,7 @@ if(clear) var/datum/action/xeno_action/A = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce/lurker) - A.use_ability_async(get_turf(current_target)) + A.use_ability_async(current_target) SSxeno_pathfinding.stop_calculating_path(src) //stop_calculating_path() current_path = null diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm index b0c4d62138..faf67c5c43 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm @@ -79,6 +79,7 @@ if(pulling && can_move_and_apply_move_delay()) Move(get_step(loc, pull_direction), pull_direction) + current_path = null else if(!(src in view(world.view, current_target))) travelling_turf = get_turf(current_target) @@ -104,7 +105,7 @@ if(clear) var/datum/action/xeno_action/A = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce) - A.use_ability_async(get_turf(current_target)) + A.use_ability_async(current_target) SSxeno_pathfinding.stop_calculating_path(src) //stop_calculating_path() current_path = null diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm index a19abb6c8f..03d17b3fdd 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm @@ -45,7 +45,7 @@ /datum/action/xeno_action/onclick/regurgitate, /datum/action/xeno_action/watch_xeno, /datum/action/xeno_action/activable/warrior_punch, - /datum/action/xeno_action/activable/lunge, + /datum/action/xeno_action/activable/pounce/lunge, /datum/action/xeno_action/activable/fling, ) @@ -78,6 +78,7 @@ GLOBAL_LIST_INIT(warrior_target_limbs, list( if(pulling && can_move_and_apply_move_delay()) Move(get_step(loc, turn(dir, 180)), turn(dir, 180)) + current_path = null else var/turf/T = get_turf(current_target) if(get_dist(src, current_target) <= 1) @@ -107,7 +108,7 @@ GLOBAL_LIST_INIT(warrior_target_limbs, list( remove_temp_pass_flags(PASS_OVER_THROW_MOB) if(clear) - var/datum/action/xeno_action/A = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/lunge) + var/datum/action/xeno_action/A = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce/lunge) A.use_ability_async(current_target) SSxeno_pathfinding.stop_calculating_path(src) //stop_calculating_path() diff --git a/code/modules/mob/living/carbon/xenomorph/mutators/strains/warrior/boxer.dm b/code/modules/mob/living/carbon/xenomorph/mutators/strains/warrior/boxer.dm index ee3e4b6b41..b59e531875 100644 --- a/code/modules/mob/living/carbon/xenomorph/mutators/strains/warrior/boxer.dm +++ b/code/modules/mob/living/carbon/xenomorph/mutators/strains/warrior/boxer.dm @@ -6,7 +6,7 @@ caste_whitelist = list(XENO_CASTE_WARRIOR) mutator_actions_to_remove = list( /datum/action/xeno_action/activable/fling, - /datum/action/xeno_action/activable/lunge, + /datum/action/xeno_action/activable/pounce/lunge, ) mutator_actions_to_add = list( /datum/action/xeno_action/activable/jab, diff --git a/code/modules/movement/launching/launching.dm b/code/modules/movement/launching/launching.dm index ce8392b51a..644f7bfd67 100644 --- a/code/modules/movement/launching/launching.dm +++ b/code/modules/movement/launching/launching.dm @@ -2,6 +2,7 @@ // Parameters var/pass_flags = NO_FLAGS // Pass flags to add temporarily var/call_all = FALSE // Whether to perform all callback calls or none of them + var/ignore_collision_behaviour = FALSE var/atom/target var/range @@ -53,6 +54,11 @@ if (isnull(launch_metadata)) CRASH("launch_impact called without any stored metadata") + if(launch_metadata.ignore_collision_behaviour) + throwing = FALSE + rebounding = FALSE + return + var/list/collision_callbacks = launch_metadata.get_collision_callbacks(hit_atom) if (islist(collision_callbacks)) for(var/datum/callback/CB in collision_callbacks) @@ -180,8 +186,10 @@ break sleep(delay) + var/result = SEND_SIGNAL(src, COMSIG_MOVABLE_POST_LAUNCH, LM) + //done throwing, either because it hit something or it finished moving - if ((isobj(src) || ismob(src)) && throwing && !early_exit) + if (!(result & COMPONENT_ABORT_COLLISION_CALLBACKS) && (isobj(src) || ismob(src)) && throwing && !early_exit) var/turf/T = get_turf(src) if(!istype(T)) return