mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 15:17:01 +01:00
[MIRROR] Fixing embedding for projectiles. [MDB IGNORE] (#23217)
* Fixing embedding for projectiles. (#77674) So, the main issue was that the variables for the embed element wouldn't set when attached to a projectile but only on items for some insignificant reason, which means it'll spawn the shrapnel yes, but won't embed it since the chance is null/zero. I read the code over and over and over with the assumption that something like this wouldn't have been done, yet it was. As for the secondary issue, because of how embedding works, the casing types of arrows and harpoon aren't spawned when hitting a non-carbon or reaching their maximum range. So, I'm re-enabling the reusable arg/var for the caseless component of harpoons and arrows, and modifying the `projectile_drop` to not drop their payload if the embedding component would already do that, so we avoid duping. * Fixing embedding for projectiles. --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
This commit is contained in:
@@ -40,23 +40,23 @@
|
||||
RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(examined))
|
||||
RegisterSignal(target, COMSIG_EMBED_TRY_FORCE, PROC_REF(tryForceEmbed))
|
||||
RegisterSignal(target, COMSIG_ITEM_DISABLE_EMBED, PROC_REF(detachFromWeapon))
|
||||
if(!initialized)
|
||||
src.embed_chance = embed_chance
|
||||
src.fall_chance = fall_chance
|
||||
src.pain_chance = pain_chance
|
||||
src.pain_mult = pain_mult
|
||||
src.remove_pain_mult = remove_pain_mult
|
||||
src.rip_time = rip_time
|
||||
src.impact_pain_mult = impact_pain_mult
|
||||
src.ignore_throwspeed_threshold = ignore_throwspeed_threshold
|
||||
src.jostle_chance = jostle_chance
|
||||
src.jostle_pain_mult = jostle_pain_mult
|
||||
src.pain_stam_pct = pain_stam_pct
|
||||
initialized = TRUE
|
||||
else
|
||||
payload_type = projectile_payload
|
||||
RegisterSignal(target, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(checkEmbedProjectile))
|
||||
|
||||
if(!initialized)
|
||||
src.embed_chance = embed_chance
|
||||
src.fall_chance = fall_chance
|
||||
src.pain_chance = pain_chance
|
||||
src.pain_mult = pain_mult
|
||||
src.remove_pain_mult = remove_pain_mult
|
||||
src.rip_time = rip_time
|
||||
src.impact_pain_mult = impact_pain_mult
|
||||
src.ignore_throwspeed_threshold = ignore_throwspeed_threshold
|
||||
src.jostle_chance = jostle_chance
|
||||
src.jostle_pain_mult = jostle_pain_mult
|
||||
src.pain_stam_pct = pain_stam_pct
|
||||
initialized = TRUE
|
||||
|
||||
/datum/element/embed/Detach(obj/target)
|
||||
. = ..()
|
||||
@@ -136,24 +136,25 @@
|
||||
* That's awful, and it'll limit us to drop-deletable shrapnels in the worry of stuff like
|
||||
* arrows and harpoons being embeddable even when not let loose by their weapons.
|
||||
*/
|
||||
/datum/element/embed/proc/checkEmbedProjectile(obj/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone)
|
||||
/datum/element/embed/proc/checkEmbedProjectile(obj/projectile/source, atom/movable/firer, atom/hit, angle, hit_zone)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!iscarbon(hit) || HAS_TRAIT(hit, TRAIT_PIERCEIMMUNE))
|
||||
Detach(P)
|
||||
if(!source.can_embed_into(hit))
|
||||
Detach(source)
|
||||
return // we don't care
|
||||
|
||||
var/obj/item/payload = new payload_type(get_turf(hit))
|
||||
if(istype(payload, /obj/item/shrapnel/bullet))
|
||||
payload.name = P.name
|
||||
SEND_SIGNAL(P, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, payload)
|
||||
payload.name = source.name
|
||||
SEND_SIGNAL(source, COMSIG_PROJECTILE_ON_SPAWN_EMBEDDED, payload)
|
||||
var/mob/living/carbon/C = hit
|
||||
var/obj/item/bodypart/limb = C.get_bodypart(hit_zone)
|
||||
if(!limb)
|
||||
limb = C.get_bodypart()
|
||||
|
||||
tryForceEmbed(payload, limb)
|
||||
Detach(P)
|
||||
if(!tryForceEmbed(payload, limb))
|
||||
payload.failedEmbed()
|
||||
Detach(source)
|
||||
|
||||
/**
|
||||
* tryForceEmbed() is called here when we fire COMSIG_EMBED_TRY_FORCE from [/obj/item/proc/tryEmbed]. Mostly, this means we're a piece of shrapnel from a projectile that just impacted something, and we're trying to embed in it.
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
///A simple element that spawns an atom when the bullet hits an object or reaches the end of its range
|
||||
/**
|
||||
* A simple element that spawns an atom when the bullet hits an object or reaches the end of its range
|
||||
* If the projectile has embedding and it can embed into the target, then it won't spawn the drop,
|
||||
* since embedding the embed element already handles that.
|
||||
*/
|
||||
/datum/element/projectile_drop
|
||||
element_flags = ELEMENT_BESPOKE
|
||||
argument_hash_start_idx = 2
|
||||
@@ -9,7 +13,12 @@
|
||||
if(!isprojectile(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
src.drop_type = drop_type
|
||||
RegisterSignals(target, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PROJECTILE_SELF_ON_HIT), PROC_REF(spawn_drop))
|
||||
RegisterSignal(target, COMSIG_PROJECTILE_RANGE_OUT, PROC_REF(spawn_drop))
|
||||
RegisterSignal(target, COMSIG_PROJECTILE_SELF_ON_HIT, PROC_REF(spawn_drop_if_not_embeddable))
|
||||
|
||||
/datum/element/projectile_drop/Detach(datum/source)
|
||||
UnregisterSignal(source, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PROJECTILE_SELF_ON_HIT))
|
||||
return ..()
|
||||
|
||||
/datum/element/projectile_drop/proc/spawn_drop(obj/projectile/source)
|
||||
SIGNAL_HANDLER
|
||||
@@ -17,4 +26,11 @@
|
||||
var/atom/new_drop = new drop_type(turf)
|
||||
SEND_SIGNAL(source, COMSIG_PROJECTILE_ON_SPAWN_DROP, new_drop)
|
||||
//Just to be safe, knowing it won't be spawned multiple times.
|
||||
UnregisterSignal(source, list(COMSIG_PROJECTILE_RANGE_OUT, COMSIG_PROJECTILE_SELF_ON_HIT, COMSIG_QDELETING))
|
||||
Detach(source)
|
||||
|
||||
/datum/element/projectile_drop/proc/spawn_drop_if_not_embeddable(obj/projectile/source, atom/movable/firer, atom/hit, angle, hit_zone)
|
||||
SIGNAL_HANDLER
|
||||
if(source.can_embed_into(hit))
|
||||
Detach(source)
|
||||
return
|
||||
spawn_drop(source)
|
||||
|
||||
Reference in New Issue
Block a user