Merge remote-tracking branch 'origin/master' into TGUI-4
This commit is contained in:
@@ -67,7 +67,7 @@
|
||||
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD, wound_bonus=CANT_WOUND) // easy tiger, we'll get to that in a sec
|
||||
var/obj/item/bodypart/slit_throat = H.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(slit_throat)
|
||||
var/datum/wound/brute/cut/critical/screaming_through_a_slit_throat = new
|
||||
var/datum/wound/slash/critical/screaming_through_a_slit_throat = new
|
||||
screaming_through_a_slit_throat.apply_wound(slit_throat)
|
||||
H.apply_status_effect(/datum/status_effect/neck_slice)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/datum/component/embedded
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
var/obj/item/bodypart/limb
|
||||
@@ -139,30 +138,36 @@
|
||||
limb.embedded_objects |= weapon // on the inside... on the inside...
|
||||
weapon.forceMove(victim)
|
||||
RegisterSignal(weapon, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING), .proc/byeItemCarbon)
|
||||
|
||||
var/damage = 0
|
||||
if(harmful)
|
||||
victim.visible_message("<span class='danger'>[weapon] embeds itself in [victim]'s [limb.name]!</span>",ignored_mobs=victim)
|
||||
to_chat(victim, "<span class='userdanger'>[weapon] embeds itself in your [limb.name]!</span>")
|
||||
victim.throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
|
||||
playsound(victim,'sound/weapons/bladeslice.ogg', 40)
|
||||
weapon.add_mob_blood(victim)//it embedded itself in you, of course it's bloody!
|
||||
var/damage = weapon.w_class * impact_pain_mult
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus=-30, sharpness = TRUE)
|
||||
damage = weapon.w_class * impact_pain_mult
|
||||
SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
|
||||
else
|
||||
victim.visible_message("<span class='danger'>[weapon] sticks itself to [victim]'s [limb.name]!</span>",ignored_mobs=victim)
|
||||
to_chat(victim, "<span class='userdanger'>[weapon] sticks itself to your [limb.name]!</span>")
|
||||
|
||||
if(damage > 0)
|
||||
var/armor = victim.run_armor_check(limb.body_zone, "melee", "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration)
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, blocked=armor, sharpness = weapon.get_sharpness())
|
||||
|
||||
/// Called every time a carbon with a harmful embed moves, rolling a chance for the item to cause pain. The chance is halved if the carbon is crawling or walking.
|
||||
/datum/component/embedded/proc/jostleCheck()
|
||||
var/mob/living/carbon/victim = parent
|
||||
|
||||
var/chance = jostle_chance
|
||||
var/damage = weapon.w_class * pain_mult
|
||||
var/pain_chance_current = jostle_chance
|
||||
if(victim.m_intent == MOVE_INTENT_WALK || !(victim.mobility_flags & MOBILITY_STAND))
|
||||
chance *= 0.5
|
||||
pain_chance_current *= 0.5
|
||||
|
||||
if(harmful && prob(chance))
|
||||
var/damage = weapon.w_class * jostle_pain_mult
|
||||
if(pain_stam_pct && IS_STAMCRIT(victim)) //if it's a less-lethal embed, give them a break if they're already stamcritted
|
||||
pain_chance_current *= 0.2
|
||||
damage *= 0.5
|
||||
if(harmful && prob(pain_chance_current))
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND)
|
||||
to_chat(victim, "<span class='userdanger'>[weapon] embedded in your [limb.name] jostles and stings!</span>")
|
||||
|
||||
@@ -199,7 +204,7 @@
|
||||
|
||||
if(harmful)
|
||||
var/damage = weapon.w_class * remove_pain_mult
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, sharpness=TRUE) //It hurts to rip it out, get surgery you dingus.
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND) //It hurts to rip it out, get surgery you dingus.
|
||||
victim.emote("scream")
|
||||
victim.visible_message("<span class='notice'>[victim] successfully rips [weapon] out of [victim.p_their()] [limb.name]!</span>", "<span class='notice'>You successfully remove [weapon] from your [limb.name].</span>")
|
||||
else
|
||||
@@ -279,11 +284,13 @@
|
||||
limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, wound_bonus = CANT_WOUND)
|
||||
to_chat(victim, "<span class='userdanger'>[weapon] embedded in your [limb.name] hurts!</span>")
|
||||
|
||||
if(prob(fall_chance))
|
||||
var/fall_chance_current = fall_chance
|
||||
if(victim.mobility_flags & ~MOBILITY_STAND)
|
||||
fall_chance_current *= 0.2
|
||||
|
||||
if(prob(fall_chance_current))
|
||||
fallOutCarbon()
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
//////////////TURF PROCS////////////////
|
||||
////////////////////////////////////////
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// the following defines are used for [/datum/component/pellet_cloud/var/list/wound_info_by_part] to store the damage, wound_bonus, and bw_bonus for each bodypart hit
|
||||
#define CLOUD_POSITION_DAMAGE 1
|
||||
#define CLOUD_POSITION_W_BONUS 2
|
||||
#define CLOUD_POSITION_BW_BONUS 3
|
||||
|
||||
/*
|
||||
* This component is used when you want to create a bunch of shrapnel or projectiles (say, shrapnel from a fragmentation grenade, or buckshot from a shotgun) from a central point,
|
||||
* without necessarily printing a separate message for every single impact. This component should be instantiated right when you need it (like the moment of firing), then activated
|
||||
@@ -29,7 +34,10 @@
|
||||
var/list/pellets = list()
|
||||
/// An associated list with the atom hit as the key and how many pellets they've eaten for the value, for printing aggregate messages
|
||||
var/list/targets_hit = list()
|
||||
/// For grenades, any /mob/living's the grenade is moved onto, see [/datum/component/pellet_cloud/proc/handle_martyrs()]
|
||||
|
||||
/// Another associated list for hit bodyparts on carbons so we can track how much wounding potential we have for each bodypart
|
||||
var/list/wound_info_by_part = list()
|
||||
/// For grenades, any /mob/living's the grenade is moved onto, see [/datum/component/pellet_cloud/proc/handle_martyrs]
|
||||
var/list/bodies
|
||||
/// For grenades, tracking people who die covering a grenade for achievement purposes, see [/datum/component/pellet_cloud/proc/handle_martyrs()]
|
||||
var/list/purple_hearts
|
||||
@@ -64,6 +72,7 @@
|
||||
/datum/component/pellet_cloud/Destroy(force, silent)
|
||||
purple_hearts = null
|
||||
pellets = null
|
||||
wound_info_by_part = null
|
||||
targets_hit = null
|
||||
bodies = null
|
||||
return ..()
|
||||
@@ -187,10 +196,26 @@
|
||||
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)
|
||||
/datum/component/pellet_cloud/proc/pellet_hit(obj/item/projectile/P, atom/movable/firer, atom/target, Angle, hit_zone)
|
||||
pellets -= P
|
||||
terminated++
|
||||
hits++
|
||||
var/obj/item/bodypart/hit_part
|
||||
if(iscarbon(target) && hit_zone)
|
||||
var/mob/living/carbon/hit_carbon = target
|
||||
hit_part = hit_carbon.get_bodypart(hit_zone)
|
||||
if(hit_part)
|
||||
target = hit_part
|
||||
if(P.wound_bonus != CANT_WOUND) // 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
|
||||
P.wound_bonus = CANT_WOUND // actual wounding will be handled aggregate
|
||||
|
||||
targets_hit[target]++
|
||||
if(targets_hit[target] == 1)
|
||||
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/on_target_qdel, override=TRUE)
|
||||
@@ -231,13 +256,23 @@
|
||||
for(var/atom/target in targets_hit)
|
||||
var/num_hits = targets_hit[target]
|
||||
UnregisterSignal(target, COMSIG_PARENT_QDELETING)
|
||||
if(num_hits > 1)
|
||||
target.visible_message("<span class='danger'>[target] is hit by [num_hits] [proj_name]s!</span>", null, null, COMBAT_MESSAGE_RANGE, target)
|
||||
to_chat(target, "<span class='userdanger'>You're hit by [num_hits] [proj_name]s!</span>")
|
||||
else
|
||||
target.visible_message("<span class='danger'>[target] is hit by a [proj_name]!</span>", null, null, COMBAT_MESSAGE_RANGE, target)
|
||||
to_chat(target, "<span class='userdanger'>You're hit by a [proj_name]!</span>")
|
||||
var/obj/item/bodypart/hit_part
|
||||
if(isbodypart(target))
|
||||
hit_part = target
|
||||
target = hit_part.owner
|
||||
var/damage_dealt = wound_info_by_part[hit_part][CLOUD_POSITION_DAMAGE]
|
||||
var/w_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_W_BONUS]
|
||||
var/bw_bonus = wound_info_by_part[hit_part][CLOUD_POSITION_BW_BONUS]
|
||||
var/wound_type = (initial(P.damage_type) == BRUTE) ? WOUND_BLUNT : WOUND_BURN // sharpness is handled in the wound rolling
|
||||
wound_info_by_part[hit_part] = null
|
||||
hit_part.painless_wound_roll(wound_type, damage_dealt, w_bonus, bw_bonus, initial(P.sharpness))
|
||||
|
||||
if(num_hits > 1)
|
||||
target.visible_message("<span class='danger'>[target] is hit by [num_hits] [proj_name]s[hit_part ? " in the [hit_part.name]" : ""]!</span>", null, null, COMBAT_MESSAGE_RANGE, target)
|
||||
to_chat(target, "<span class='userdanger'>You're hit by [num_hits] [proj_name]s[hit_part ? " in the [hit_part.name]" : ""]!</span>")
|
||||
else
|
||||
target.visible_message("<span class='danger'>[target] is hit by a [proj_name][hit_part ? " in the [hit_part.name]" : ""]!</span>", null, null, COMBAT_MESSAGE_RANGE, target)
|
||||
to_chat(target, "<span class='userdanger'>You're hit by a [proj_name][hit_part ? " in the [hit_part.name]" : ""]!</span>")
|
||||
UnregisterSignal(parent, COMSIG_PARENT_PREQDELETED)
|
||||
if(queued_delete)
|
||||
qdel(parent)
|
||||
@@ -281,3 +316,7 @@
|
||||
targets_hit -= target
|
||||
bodies -= target
|
||||
purple_hearts -= target
|
||||
|
||||
#undef CLOUD_POSITION_DAMAGE
|
||||
#undef CLOUD_POSITION_W_BONUS
|
||||
#undef CLOUD_POSITION_BW_BONUS
|
||||
|
||||
Reference in New Issue
Block a user