diff --git a/code/__DEFINES/dcs/signals/signals_spell.dm b/code/__DEFINES/dcs/signals/signals_spell.dm index 4d2c7d2993f..92bbc206162 100644 --- a/code/__DEFINES/dcs/signals/signals_spell.dm +++ b/code/__DEFINES/dcs/signals/signals_spell.dm @@ -33,7 +33,7 @@ // Spell type signals // Pointed projectiles -/// Sent from /datum/action/cooldown/spell/pointed/projectile/on_cast_hit: (atom/hit, atom/firer, obj/projectile/source) +/// Sent from /datum/action/cooldown/spell/pointed/projectile/on_cast_hit: (atom/firer, atom/target, atom/hit, angle, hit_limb) #define COMSIG_SPELL_PROJECTILE_HIT "spell_projectile_hit" // AOE spells diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 43466bf71b7..39c462c012c 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -271,3 +271,5 @@ GLOBAL_LIST_INIT(book_types, typecacheof(list( #define is_security_officer_job(job_type) (istype(job_type, /datum/job/security_officer)) #define is_research_director_job(job_type) (istype(job_type, /datum/job/research_director)) #define is_unassigned_job(job_type) (istype(job_type, /datum/job/unassigned)) + +#define isprojectilespell(thing) (istype(thing, /datum/action/cooldown/spell/pointed/projectile)) diff --git a/code/datums/components/igniter.dm b/code/datums/components/igniter.dm index 7371942296e..1d2b34a9334 100644 --- a/code/datums/components/igniter.dm +++ b/code/datums/components/igniter.dm @@ -3,14 +3,14 @@ var/fire_type /datum/component/igniter/Initialize(fire_stacks = 1, fire_type = /datum/status_effect/fire_handler/fire_stacks) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) + if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent) && !isprojectilespell(parent)) return COMPONENT_INCOMPATIBLE src.fire_stacks = fire_stacks src.fire_type = fire_type /datum/component/igniter/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc + if(ismachinery(parent) || isstructure(parent) || isgun(parent) || isprojectilespell(parent)) // turrets, etc RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) else if(isitem(parent)) RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) @@ -34,7 +34,7 @@ return do_igniter(target) -/datum/component/igniter/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) +/datum/component/igniter/proc/projectile_hit(datum/fired_from, atom/movable/firer, atom/target, Angle) SIGNAL_HANDLER do_igniter(target) diff --git a/code/datums/components/mirv.dm b/code/datums/components/mirv.dm index 198a9336f24..8d22972ae8e 100644 --- a/code/datums/components/mirv.dm +++ b/code/datums/components/mirv.dm @@ -4,7 +4,7 @@ var/override_projectile_range /datum/component/mirv/Initialize(projectile_type, radius=1, override_projectile_range) - if(!isgun(parent) && !ismachinery(parent) && !isstructure(parent) && !isgrenade(parent)) + if(!isgun(parent) && !ismachinery(parent) && !isstructure(parent) && !isgrenade(parent) && !isprojectilespell(parent)) return COMPONENT_INCOMPATIBLE src.projectile_type = projectile_type @@ -15,13 +15,13 @@ parent.AddComponent(/datum/component/pellet_cloud, projectile_type=projectile_type) /datum/component/mirv/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc + if(ismachinery(parent) || isstructure(parent) || isgun(parent) || isprojectilespell(parent)) // turrets, etc RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) /datum/component/mirv/UnregisterFromParent() UnregisterSignal(parent, list(COMSIG_PROJECTILE_ON_HIT)) -/datum/component/mirv/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) +/datum/component/mirv/proc/projectile_hit(datum/fired_from, atom/movable/firer, atom/target, Angle) SIGNAL_HANDLER INVOKE_ASYNC(src, .proc/do_shrapnel, firer, target) diff --git a/code/datums/components/summoning.dm b/code/datums/components/summoning.dm index bceaf0897e7..b15fa075635 100644 --- a/code/datums/components/summoning.dm +++ b/code/datums/components/summoning.dm @@ -11,7 +11,7 @@ var/list/spawned_mobs = list() /datum/component/summoning/Initialize(mob_types, spawn_chance=100, max_mobs=3, spawn_delay=100, spawn_text="appears out of nowhere", spawn_sound='sound/magic/summon_magic.ogg', faction) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) + if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent) && !isprojectilespell(parent)) return COMPONENT_INCOMPATIBLE src.mob_types = mob_types @@ -23,7 +23,7 @@ src.faction = faction /datum/component/summoning/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc + if(ismachinery(parent) || isstructure(parent) || isgun(parent) || isprojectilespell(parent)) // turrets, etc RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) else if(isitem(parent)) RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) @@ -47,7 +47,7 @@ return do_spawn_mob(get_turf(target), attacker) -/datum/component/summoning/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) +/datum/component/summoning/proc/projectile_hit(datum/fired_from, atom/movable/firer, atom/target, Angle) SIGNAL_HANDLER do_spawn_mob(get_turf(target), firer) diff --git a/code/datums/elements/knockback.dm b/code/datums/elements/knockback.dm index ba132e7b235..af5cb3e0a36 100644 --- a/code/datums/elements/knockback.dm +++ b/code/datums/elements/knockback.dm @@ -12,7 +12,7 @@ /datum/element/knockback/Attach(datum/target, throw_distance = 1, throw_anchored = FALSE, throw_gentle = FALSE) . = ..() - if(ismachinery(target) || isstructure(target) || isgun(target)) // turrets, etc + if(ismachinery(target) || isstructure(target) || isgun(target) || isprojectilespell(target)) // turrets, etc RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) else if(isitem(target)) RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) @@ -45,7 +45,7 @@ do_knockback(target, attacker, get_dir(attacker, target)) /// triggered after a projectile hits something -/datum/element/knockback/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) +/datum/element/knockback/proc/projectile_hit(datum/fired_from, atom/movable/firer, atom/target, Angle) SIGNAL_HANDLER do_knockback(target, null, angle2dir(Angle)) diff --git a/code/datums/elements/lifesteal.dm b/code/datums/elements/lifesteal.dm index db3d008cd07..e793ea5d37c 100644 --- a/code/datums/elements/lifesteal.dm +++ b/code/datums/elements/lifesteal.dm @@ -11,7 +11,7 @@ /datum/element/lifesteal/Attach(datum/target, flat_heal) . = ..() - if(isgun(target)) + if(ismachinery(target) || isstructure(target) || isgun(target) || isprojectilespell(target)) RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) else if(isitem(target)) RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) @@ -40,7 +40,7 @@ return do_lifesteal(attacker, target) -/datum/element/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) +/datum/element/lifesteal/proc/projectile_hit(datum/fired_from, atom/movable/firer, atom/target, Angle) SIGNAL_HANDLER do_lifesteal(firer, target) diff --git a/code/datums/elements/light_eater.dm b/code/datums/elements/light_eater.dm index 0eb59bbc850..11c80f933d4 100644 --- a/code/datums/elements/light_eater.dm +++ b/code/datums/elements/light_eater.dm @@ -9,14 +9,20 @@ /datum/element/light_eater/Attach(datum/target) if(isatom(target)) if(ismovable(target)) + if(ismachinery(target) || isstructure(target)) + RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/on_projectile_hit) RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/on_throw_impact) if(isitem(target)) + if(isgun(target)) + RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/on_projectile_hit) RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, .proc/on_afterattack) RegisterSignal(target, COMSIG_ITEM_HIT_REACT, .proc/on_hit_reaction) else if(isprojectile(target)) - RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/on_projectile_hit) + RegisterSignal(target, COMSIG_PROJECTILE_SELF_ON_HIT, .proc/on_projectile_self_hit) else if(istype(target, /datum/reagent)) RegisterSignal(target, COMSIG_REAGENT_EXPOSE_ATOM, .proc/on_expose_atom) + else if(isprojectilespell(target)) + RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/on_projectile_hit) else return ELEMENT_INCOMPATIBLE @@ -137,6 +143,20 @@ eat_lights(hitby, source) return NONE +/** + * Called when a produced projectile strikes a target atom + * + * Arguments: + * - [source][/datum]: The thing that created the projectile + * - [firer][/atom/movable]: The movable atom that fired the projectile + * - [target][/atom]: The atom that was struck by the projectile + * - angle: The angle the target was struck at + */ +/datum/element/light_eater/proc/on_projectile_hit(datum/source, atom/movable/firer, atom/target, angle) + SIGNAL_HANDLER + eat_lights(target, source) + return NONE + /** * Called when a source projectile strikes a target atom * @@ -145,8 +165,9 @@ * - [firer][/atom/movable]: The movable atom that fired the projectile * - [target][/atom]: The atom that was struck by the projectile * - angle: The angle the target was struck at + * - hit_limb: The limb that was hit, if the target was a carbon */ -/datum/element/light_eater/proc/on_projectile_hit(obj/projectile/source, atom/movable/firer, atom/target, angle) +/datum/element/light_eater/proc/on_projectile_self_hit(obj/projectile/source, atom/movable/firer, atom/target, angle, hit_limb) SIGNAL_HANDLER eat_lights(target, source) return NONE diff --git a/code/datums/elements/venomous.dm b/code/datums/elements/venomous.dm index 0062c78d568..e2ca79ef08a 100644 --- a/code/datums/elements/venomous.dm +++ b/code/datums/elements/venomous.dm @@ -14,7 +14,7 @@ /datum/element/venomous/Attach(datum/target, poison_type, amount_added) . = ..() - if(isgun(target)) + if(ismachinery(target) || isstructure(target) || isgun(target) || isprojectilespell(target)) RegisterSignal(target, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) else if(isitem(target)) RegisterSignal(target, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) diff --git a/code/game/objects/structures/deployable_turret.dm b/code/game/objects/structures/deployable_turret.dm index 4a265d882be..16c28d41355 100644 --- a/code/game/objects/structures/deployable_turret.dm +++ b/code/game/objects/structures/deployable_turret.dm @@ -196,6 +196,8 @@ var/obj/projectile/projectile_to_fire = new projectile_type playsound(src, firesound, 75, TRUE) projectile_to_fire.preparePixelProjectile(target, targets_from) + projectile_to_fire.firer = user + projectile_to_fire.fired_from = src projectile_to_fire.fire() /obj/machinery/deployable_turret/ultimate // Admin-only proof of concept for autoclicker automatics diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a0fdba798c4..89562d1efd5 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -22,7 +22,7 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF var/def_zone = "" //Aiming at var/atom/movable/firer = null//Who shot it - var/atom/fired_from = null // the atom that the projectile was fired from (gun, turret) + var/datum/fired_from = null // the thing that the projectile was fired from (gun, turret, spell) var/suppressed = FALSE //Attack message var/yo = null var/xo = null diff --git a/code/modules/spells/spell_types/pointed/_pointed.dm b/code/modules/spells/spell_types/pointed/_pointed.dm index 4f5bbf2349e..3a3856390b6 100644 --- a/code/modules/spells/spell_types/pointed/_pointed.dm +++ b/code/modules/spells/spell_types/pointed/_pointed.dm @@ -165,9 +165,9 @@ /datum/action/cooldown/spell/pointed/projectile/proc/ready_projectile(obj/projectile/to_fire, atom/target, mob/user, iteration) to_fire.firer = owner - to_fire.fired_from = get_turf(owner) + to_fire.fired_from = src to_fire.preparePixelProjectile(target, owner) - RegisterSignal(to_fire, COMSIG_PROJECTILE_ON_HIT, .proc/on_cast_hit) + RegisterSignal(to_fire, COMSIG_PROJECTILE_SELF_ON_HIT, .proc/on_cast_hit) if(istype(to_fire, /obj/projectile/magic)) var/obj/projectile/magic/magic_to_fire = to_fire @@ -175,7 +175,7 @@ /// Signal proc for whenever the projectile we fire hits someone. /// Pretty much relays to the spell when the projectile actually hits something. -/datum/action/cooldown/spell/pointed/projectile/proc/on_cast_hit(atom/source, mob/firer, atom/hit, angle) +/datum/action/cooldown/spell/pointed/projectile/proc/on_cast_hit(datum/source, mob/firer, atom/target, angle, hit_limb) SIGNAL_HANDLER - SEND_SIGNAL(src, COMSIG_SPELL_PROJECTILE_HIT, hit, firer, source) + SEND_SIGNAL(src, COMSIG_SPELL_PROJECTILE_HIT, source, firer, target, angle, hit_limb)