From ef9c90d512a62ac9d6446c70815caf5dbc0ce57a Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Tue, 16 Nov 2021 20:26:38 +0100 Subject: [PATCH] embeds, unarmed and wounds --- code/datums/components/pellet_cloud.dm | 12 ++++++------ code/datums/elements/embed.dm | 6 ++++-- code/game/objects/items/shields.dm | 26 ++++++++++++++++---------- code/modules/projectiles/projectile.dm | 2 +- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm index f88b9e1869..dcc806d991 100644 --- a/code/datums/components/pellet_cloud.dm +++ b/code/datums/components/pellet_cloud.dm @@ -198,7 +198,7 @@ break ///One of our pellets hit something, record what it was and check if we're done (terminated == num_pellets) -/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone) +/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone, blocked) pellets -= P terminated++ hits++ @@ -208,14 +208,14 @@ hit_part = hit_carbon.get_bodypart(hit_zone) if(hit_part) target = hit_part - if(P.wound_bonus != CANT_WOUND) // handle wounding + if(P.wound_bonus != CANT_WOUND && (blocked < 100)) // handle wounding // unfortunately, due to how pellet clouds handle finalizing only after every pellet is accounted for, that also means there might be a short delay in dealing wounds if one pellet goes wide // while buckshot may reach a target or miss it all in one tick, we also have to account for possible ricochets that may take a bit longer to hit the target if(isnull(wound_info_by_part[hit_part])) wound_info_by_part[hit_part] = list(0, 0, 0) - wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] += P.damage // these account for decay - wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] += P.wound_bonus - wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] += P.bare_wound_bonus + wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] += (P.damage * ((100 - blocked) * 0.01))// these account for decay and now block + wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS] = max(wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS], P.wound_bonus) + wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS] = max(wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS], P.bare_wound_bonus) P.wound_bonus = CANT_WOUND // actual wounding will be handled aggregate targets_hit[target]++ @@ -259,7 +259,7 @@ var/num_hits = targets_hit[target] UnregisterSignal(target, COMSIG_PARENT_QDELETING) var/obj/item/bodypart/hit_part - if(isbodypart(target)) + if(isbodypart(target) && wound_info_by_part[hit_part]) hit_part = target target = hit_part.owner var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE] diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 876414330f..4a9044b6e1 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -168,11 +168,13 @@ * If we hit a valid target (carbon or closed turf), we create the shrapnel_type object and immediately call tryEmbed() on it, targeting what we impacted. That will lead * it to call tryForceEmbed() on its own embed element (it's out of our hands here, our projectile is done), where it will run through all the checks it needs to. */ -/datum/element/embed/proc/checkEmbedProjectile(obj/item/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone) +/datum/element/embed/proc/checkEmbedProjectile(obj/item/projectile/P, atom/movable/firer, atom/hit, angle, hit_zone, blocked) if(!iscarbon(hit)) Detach(P) return // we don't care - + if(blocked >= 100) + Detach(P) //fully blocked, no embedding for us. + return var/obj/item/payload = new payload_type(get_turf(hit)) if(istype(payload, /obj/item/shrapnel/bullet)) payload.name = P.name diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 8432a8b73e..36559d14be 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -247,22 +247,28 @@ var/final_damage = damage if(attack_type & ATTACK_TYPE_MELEE) - var/obj/hittingthing = object - if(hittingthing.damtype == BURN) - if((shield_flags & SHIELD_ENERGY_WEAK)) - final_damage *= 2 - else if((shield_flags & SHIELD_ENERGY_STRONG)) - final_damage *= 0.5 + if(istype(object, /obj)) //Assumption: non-object attackers are a meleeing mob. Therefore: Assuming physical attack in this case. + var/obj/hittingthing = object + if(hittingthing.damtype == BURN) + if((shield_flags & SHIELD_ENERGY_WEAK)) + final_damage *= 2 + else if((shield_flags & SHIELD_ENERGY_STRONG)) + final_damage *= 0.5 - if(hittingthing.damtype == BRUTE) + if(hittingthing.damtype == BRUTE) + if((shield_flags & SHIELD_KINETIC_WEAK)) + final_damage *= 2 + else if((shield_flags & SHIELD_KINETIC_STRONG)) + final_damage *= 0.5 + + if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY) + final_damage = 0 + else if((shield_flags & SHIELD_KINETIC_WEAK)) final_damage *= 2 else if((shield_flags & SHIELD_KINETIC_STRONG)) final_damage *= 0.5 - if(hittingthing.damtype == STAMINA || hittingthing.damtype == TOX || hittingthing.damtype == CLONE || hittingthing.damtype == BRAIN || hittingthing.damtype == OXY) - final_damage = 0 - if(attack_type & ATTACK_TYPE_PROJECTILE) var/obj/item/projectile/shootingthing = object if(is_energy_reflectable_projectile(shootingthing)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 07fc4bf9de..8d467c9901 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -215,7 +215,7 @@ if(isliving(target)) var/mob/living/L = target hit_limb = L.check_limb_hit(def_zone) - SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb) + SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb, blocked) var/turf/target_loca = get_turf(target) var/hitx