diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm index b836c811667..601f441c66d 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm @@ -23,9 +23,11 @@ #define COMSIG_MOVABLE_DRIFT_BLOCK_INPUT "movable_drift_block_input" #define DRIFT_ALLOW_INPUT (1<<0) ///from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum) -#define COMSIG_MOVABLE_IMPACT "movable_impact" +#define COMSIG_MOVABLE_PRE_IMPACT "movable_pre_impact" #define COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH (1<<0) //if true, flip if the impact will push what it hits #define COMPONENT_MOVABLE_IMPACT_NEVERMIND (1<<1) //return true if you destroyed whatever it was you're impacting and there won't be anything for hitby() to run on +///from base of atom/movable/throw_impact() after confirming a hit: (/atom/hit_atom, /datum/thrownthing/throwingdatum) +#define COMSIG_MOVABLE_IMPACT "movable_impact" ///from base of mob/living/hitby(): (mob/living/target, hit_zone, blocked, datum/thrownthing/throwingdatum) #define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" ///from /atom/movable/proc/buckle_mob(): (mob/living/M, force, check_loc, buckle_mob_flags) diff --git a/code/datums/components/on_hit_effect.dm b/code/datums/components/on_hit_effect.dm index 38610395248..50f31269f16 100644 --- a/code/datums/components/on_hit_effect.dm +++ b/code/datums/components/on_hit_effect.dm @@ -11,12 +11,15 @@ var/datum/callback/on_hit_callback ///callback optionally used for more checks var/datum/callback/extra_check_callback + ///optionally should we also apply the effect if thrown at something? + var/thrown_effect -/datum/component/on_hit_effect/Initialize(on_hit_callback, extra_check_callback) +/datum/component/on_hit_effect/Initialize(on_hit_callback, extra_check_callback, thrown_effect = FALSE) src.on_hit_callback = on_hit_callback src.extra_check_callback = extra_check_callback if(!(ismachinery(parent) || isstructure(parent) || isgun(parent) || isprojectilespell(parent) || isitem(parent) || isanimal_or_basicmob(parent) || isprojectile(parent))) return ELEMENT_INCOMPATIBLE + src.thrown_effect = thrown_effect /datum/component/on_hit_effect/Destroy(force, silent) on_hit_callback = null @@ -33,12 +36,16 @@ else if(isprojectile(parent)) RegisterSignal(parent, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(on_projectile_self_hit)) + if(thrown_effect) + RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, PROC_REF(on_thrown_hit)) + /datum/component/on_hit_effect/UnregisterFromParent() UnregisterSignal(parent, list( COMSIG_PROJECTILE_ON_HIT, COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_POST_ATTACKINGTARGET, COMSIG_PROJECTILE_SELF_ON_HIT, + COMSIG_MOVABLE_IMPACT, )) /datum/component/on_hit_effect/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) @@ -79,3 +86,9 @@ if(!extra_check_callback.Invoke(firer, target)) return on_hit_callback.Invoke(source, firer, target, body_zone) + +/datum/component/on_hit_effect/proc/on_thrown_hit(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum) + SIGNAL_HANDLER + if(extra_check_callback && !extra_check_callback.Invoke(source, hit_atom)) + return + on_hit_callback.Invoke(source, source, hit_atom, null) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index aefaa43d0b9..101425f54b2 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -54,11 +54,11 @@ /datum/component/tackler/RegisterWithParent() RegisterSignal(parent, COMSIG_MOB_CLICKON, PROC_REF(checkTackle)) - RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, PROC_REF(sack)) + RegisterSignal(parent, COMSIG_MOVABLE_PRE_IMPACT, PROC_REF(sack)) RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, PROC_REF(registerTackle)) /datum/component/tackler/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_MOB_CLICKON, COMSIG_MOVABLE_IMPACT, COMSIG_MOVABLE_MOVED, COMSIG_MOVABLE_POST_THROW)) + UnregisterSignal(parent, list(COMSIG_MOB_CLICKON, COMSIG_MOVABLE_PRE_IMPACT, COMSIG_MOVABLE_MOVED, COMSIG_MOVABLE_POST_THROW)) ///Store the thrownthing datum for later use /datum/component/tackler/proc/registerTackle(mob/living/carbon/user, datum/thrownthing/tackle) diff --git a/code/datums/elements/venomous.dm b/code/datums/elements/venomous.dm index b310e01bafc..ba4e088750c 100644 --- a/code/datums/elements/venomous.dm +++ b/code/datums/elements/venomous.dm @@ -8,14 +8,21 @@ argument_hash_start_idx = 2 ///Path of the reagent added var/poison_type + ///Details of how we inject our venom + var/injection_flags ///How much of the reagent added. if it's a list, it'll pick a range with the range being list(lower_value, upper_value) var/list/amount_added -/datum/element/venomous/Attach(datum/target, poison_type, amount_added) +/datum/element/venomous/Attach(datum/target, poison_type, amount_added, injection_flags = NONE, thrown_effect = FALSE) . = ..() src.poison_type = poison_type src.amount_added = amount_added - target.AddComponent(/datum/component/on_hit_effect, CALLBACK(src, PROC_REF(do_venom))) + src.injection_flags = injection_flags + target.AddComponent(\ + /datum/component/on_hit_effect,\ + on_hit_callback = CALLBACK(src, PROC_REF(do_venom)),\ + thrown_effect = thrown_effect,\ + ) /datum/element/venomous/Detach(datum/target) qdel(target.GetComponent(/datum/component/on_hit_effect)) @@ -26,6 +33,8 @@ return if(target.stat == DEAD) return + if(isliving(element_owner) && !target.try_inject(element_owner, hit_zone, injection_flags)) + return var/final_amount_added if(islist(amount_added)) final_amount_added = rand(amount_added[1], amount_added[2]) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index fe4b65950a6..eee03949a09 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1242,7 +1242,7 @@ /atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) set waitfor = FALSE var/hitpush = TRUE - var/impact_signal = SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) + var/impact_signal = SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_IMPACT, hit_atom, throwingdatum) if(impact_signal & COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH) hitpush = FALSE // hacky, tie this to something else or a proper workaround later @@ -1250,6 +1250,7 @@ return // in case a signal interceptor broke or deleted the thing before we could process our hit if(SEND_SIGNAL(hit_atom, COMSIG_ATOM_PREHITBY, src, throwingdatum) & COMSIG_HIT_PREVENTED) return + SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) return hit_atom.hitby(src, throwingdatum=throwingdatum, hitpush=hitpush) /atom/movable/hitby(atom/movable/hitting_atom, skipcatch, hitpush = TRUE, blocked, datum/thrownthing/throwingdatum) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 950bead3829..9fb200b30a2 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -772,10 +772,12 @@ /obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(QDELETED(hit_atom)) return - if(SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) & COMPONENT_MOVABLE_IMPACT_NEVERMIND) + if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_IMPACT, hit_atom, throwingdatum) & COMPONENT_MOVABLE_IMPACT_NEVERMIND) return if(SEND_SIGNAL(hit_atom, COMSIG_ATOM_PREHITBY, src, throwingdatum) & COMSIG_HIT_PREVENTED) return + + SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) if(get_temperature() && isliving(hit_atom)) var/mob/living/L = hit_atom L.ignite_mob() diff --git a/code/modules/mob/living/basic/clown/clown.dm b/code/modules/mob/living/basic/clown/clown.dm index 6c677e284dc..1a713ec04f8 100644 --- a/code/modules/mob/living/basic/clown/clown.dm +++ b/code/modules/mob/living/basic/clown/clown.dm @@ -112,7 +112,12 @@ var/static/list/injection_range if(!injection_range) injection_range = string_numbers_list(list(1, 5)) - AddElement(/datum/element/venomous, /datum/reagent/consumable/laughter, injection_range) + AddElement(\ + /datum/element/venomous,\ + /datum/reagent/consumable/laughter,\ + injection_range,\ + injection_flags = INJECT_CHECK_PENETRATE_THICK | INJECT_CHECK_IGNORE_SPECIES,\ + ) /mob/living/basic/clown/fleshclown name = "Fleshclown" @@ -288,7 +293,12 @@ var/static/list/injection_range if(!injection_range) injection_range = string_numbers_list(list(1, 5)) - AddElement(/datum/element/venomous, /datum/reagent/peaceborg/confuse, injection_range) + AddElement(\ + /datum/element/venomous,\ + /datum/reagent/peaceborg/confuse,\ + injection_range,\ + injection_flags = INJECT_CHECK_PENETRATE_THICK | INJECT_CHECK_IGNORE_SPECIES,\ + ) // I don't really know what a clown is using to inject people but let's assume it doesn't need to penetrate at all /mob/living/basic/clown/clownhulk/destroyer name = "The Destroyer" diff --git a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm index dfaff9f4efc..66c0d129962 100644 --- a/code/modules/mob/living/basic/farm_animals/bee/_bee.dm +++ b/code/modules/mob/living/basic/farm_animals/bee/_bee.dm @@ -192,11 +192,11 @@ if(!injection_range) injection_range = string_numbers_list(list(1, 5)) if(beegent) //clear the old since this one is going to have some new value - RemoveElement(/datum/element/venomous, beegent.type, injection_range) + RemoveElement(/datum/element/venomous, beegent.type, injection_range, thrown_effect = TRUE) beegent = toxin name = "[initial(name)] ([toxin.name])" real_name = name - AddElement(/datum/element/venomous, beegent.type, injection_range) + AddElement(/datum/element/venomous, beegent.type, injection_range, thrown_effect = TRUE) generate_bee_visuals() /mob/living/basic/bee/queen diff --git a/code/modules/mob/living/basic/farm_animals/cow/cow_moonicorn.dm b/code/modules/mob/living/basic/farm_animals/cow/cow_moonicorn.dm index f499859e19e..b3af3c59a12 100644 --- a/code/modules/mob/living/basic/farm_animals/cow/cow_moonicorn.dm +++ b/code/modules/mob/living/basic/farm_animals/cow/cow_moonicorn.dm @@ -24,7 +24,7 @@ /mob/living/basic/cow/moonicorn/Initialize(mapload) . = ..() - AddElement(/datum/element/venomous, /datum/reagent/pax, 5) + AddElement(/datum/element/venomous, /datum/reagent/pax, 5, injection_flags = INJECT_CHECK_PENETRATE_THICK | INJECT_CHECK_IGNORE_SPECIES) AddElement(/datum/element/movement_turf_changer, /turf/open/floor/grass/fairy) /mob/living/basic/cow/moonicorn/udder_component() diff --git a/code/modules/mob/living/basic/heretic/fire_shark.dm b/code/modules/mob/living/basic/heretic/fire_shark.dm index e1eba100845..c4106050bc2 100644 --- a/code/modules/mob/living/basic/heretic/fire_shark.dm +++ b/code/modules/mob/living/basic/heretic/fire_shark.dm @@ -26,7 +26,7 @@ . = ..() AddElement(/datum/element/death_gases, /datum/gas/plasma, 40) AddElement(/datum/element/simple_flying) - AddElement(/datum/element/venomous, /datum/reagent/phlogiston, 2) + AddElement(/datum/element/venomous, /datum/reagent/phlogiston, 2, injection_flags = INJECT_CHECK_PENETRATE_THICK) AddComponent(/datum/component/swarming) AddComponent(/datum/component/regenerator, outline_colour = COLOR_DARK_RED) ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) diff --git a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm index c16831f74a2..80e1768c90e 100644 --- a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm +++ b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm @@ -47,7 +47,7 @@ ADD_TRAIT(src, TRAIT_WEB_SURFER, INNATE_TRAIT) AddElement(/datum/element/cliff_walking) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) - AddElement(/datum/element/venomous, /datum/reagent/toxin/hunterspider, 5) + AddElement(/datum/element/venomous, /datum/reagent/toxin/hunterspider, 5, injection_flags = INJECT_CHECK_PENETRATE_THICK) AddElement(/datum/element/web_walker, /datum/movespeed_modifier/fast_web) AddElement(/datum/element/nerfed_pulling, GLOB.typecache_general_bad_things_to_easily_move) AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!") diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index 56f060ca3e2..d4264b4a126 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm @@ -19,6 +19,7 @@ melee_damage_upper = 25 gold_core_spawnable = HOSTILE_SPAWN ai_controller = /datum/ai_controller/basic_controller/giant_spider + bite_injection_flags = INJECT_CHECK_PENETRATE_THICK /// Actions to grant on Initialize var/list/innate_actions = null diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm index 6cd6275c10d..b9938631ec5 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -36,6 +36,8 @@ var/poison_type = /datum/reagent/toxin/hunterspider /// How much of a reagent the mob injects on attack var/poison_per_bite = 0 + /// How tough is our bite? + var/bite_injection_flags = NONE /// Multiplier to apply to web laying speed. Fractional numbers make it faster, because it's a multiplier. var/web_speed = 1 /// Type of webbing ability to learn. @@ -57,7 +59,7 @@ AddComponent(/datum/component/health_scaling_effects, min_health_slowdown = 1.5) if(poison_per_bite) - AddElement(/datum/element/venomous, poison_type, poison_per_bite) + AddElement(/datum/element/venomous, poison_type, poison_per_bite, injection_flags = bite_injection_flags) var/datum/action/cooldown/mob_cooldown/lay_web/webbing = new web_type(src) webbing.webbing_time *= web_speed diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm index 5ed1e44b709..f175dda0317 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -218,7 +218,7 @@ /obj/item/mod/module/weapon_recall/proc/set_weapon(obj/item/weapon) linked_weapon = weapon - RegisterSignal(linked_weapon, COMSIG_MOVABLE_IMPACT, PROC_REF(catch_weapon)) + RegisterSignal(linked_weapon, COMSIG_MOVABLE_PRE_IMPACT, PROC_REF(catch_weapon)) RegisterSignal(linked_weapon, COMSIG_QDELETING, PROC_REF(deleted_weapon)) /obj/item/mod/module/weapon_recall/proc/recall_weapon(caught = FALSE)