section 2

This commit is contained in:
timothyteakettle
2020-07-24 23:44:57 +01:00
parent 7fb55a02a5
commit 8360bb1a7f
44 changed files with 760 additions and 99 deletions
+206 -47
View File
@@ -86,12 +86,12 @@
/// A hat won't cover your face, but a shirt covering your chest will cover your... you know, chest
var/scars_covered_by_clothes = TRUE
/// Descriptions for the locations on the limb for scars to be assigned, just cosmetic
var/list/specific_locations = list("general area")
/// So we know if we need to scream if this limb hits max damage
var/last_maxed
/// How much generic bleedstacks we have on this bodypart
var/generic_bleedstacks
/// If we have a gauze wrapping currently applied (not including splints)
var/obj/item/stack/current_gauze
/obj/item/bodypart/examine(mob/user)
. = ..()
@@ -151,8 +151,20 @@
var/turf/T = get_turf(src)
if(status != BODYPART_ROBOTIC)
playsound(T, 'sound/misc/splort.ogg', 50, 1, -1)
for(var/obj/item/I in src)
I.forceMove(T)
if(current_gauze)
QDEL_NULL(current_gauze)
for(var/obj/item/organ/drop_organ in get_organs())
drop_organ.transfer_to_limb(src, owner)
///since organs aren't actually stored in the bodypart themselves while attached to a person, we have to query the owner for what we should have
/obj/item/bodypart/proc/get_organs()
if(!owner)
return
. = list()
for(var/i in owner.internal_organs) //internal organs inside the dismembered limb are dropped.
var/obj/item/organ/organ_check = i
if(check_zone(organ_check.zone) == body_zone)
. += organ_check
/obj/item/bodypart/proc/consider_processing()
if(stamina_dam > DAMAGE_PRECISION)
@@ -192,16 +204,64 @@
if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around
burn *= 1.2
var/wounding_type = (brute > burn ? WOUND_BRUTE : WOUND_BURN)
/*
// START WOUND HANDLING
*/
// what kind of wounds we're gonna roll for, take the greater between brute and burn, then if it's brute, we subdivide based on sharpness
var/wounding_type = (brute > burn ? WOUND_BLUNT : WOUND_BURN)
var/wounding_dmg = max(brute, burn)
if(wounding_type == WOUND_BRUTE && sharpness)
wounding_type = WOUND_SHARP
// i know this is effectively the same check as above but i don't know if those can null the damage by rounding and want to be safe
if(owner && wounding_dmg > 4 && wound_bonus != CANT_WOUND)
// if you want to make tox wounds or some other type, this will need to be expanded and made more modular
// handle all our wounding stuff
var/mangled_state = get_mangled_state()
var/bio_state = owner.get_biological_state()
var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
if(wounding_type == WOUND_BLUNT)
if(sharpness == SHARP_EDGED)
wounding_type = WOUND_SLASH
else if(sharpness == SHARP_POINTY)
wounding_type = WOUND_PIERCE
//Handling for bone only/flesh only(none right now)/flesh and bone targets
switch(bio_state)
// if we're bone only, all cutting attacks go straight to the bone
if(BIO_JUST_BONE)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.5)
else if(wounding_type == WOUND_PIERCE)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.75)
if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
// note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday)
// standard humanoids
if(BIO_FLESH_BONE)
// if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
// So a big sharp weapon is still all you need to destroy a limb
if(mangled_state == BODYPART_MANGLED_FLESH && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area
if(wounding_type == WOUND_PIERCE && !easy_dismember)
wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
wounding_type = WOUND_BLUNT
else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
// now we have our wounding_type and are ready to carry on with wounds and dealing the actual damage
if(owner && wounding_dmg >= WOUND_MINIMUM_DAMAGE && wound_bonus != CANT_WOUND)
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
for(var/i in wounds)
var/datum/wound/iter_wound = i
iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus)
/*
// END WOUND HANDLING
*/
//back to our regularly scheduled program, we now actually apply damage if there's room below limb damage cap
var/can_inflict = max_damage - get_damage()
var/total_damage = brute + burn
@@ -213,10 +273,6 @@
if(can_inflict <= 0)
return FALSE
for(var/i in wounds)
var/datum/wound/W = i
W.receive_damage(wounding_type, wounding_dmg, wound_bonus)
brute_dam += brute
burn_dam += burn
@@ -236,14 +292,58 @@
update_disabled()
return update_bodypart_damage_state()
/// Allows us to roll for and apply a wound without actually dealing damage. Used for aggregate wounding power with pellet clouds
/obj/item/bodypart/proc/painless_wound_roll(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus, sharpness=SHARP_NONE)
if(!owner || phantom_wounding_dmg <= WOUND_MINIMUM_DAMAGE || wound_bonus == CANT_WOUND)
return
var/mangled_state = get_mangled_state()
var/bio_state = owner.get_biological_state()
var/easy_dismember = HAS_TRAIT(owner, TRAIT_EASYDISMEMBER) // if we have easydismember, we don't reduce damage when redirecting damage to different types (slashing weapons on mangled/skinless limbs attack at 100% instead of 50%)
if(wounding_type == WOUND_BLUNT)
if(sharpness == SHARP_EDGED)
wounding_type = WOUND_SLASH
else if(sharpness == SHARP_POINTY)
wounding_type = WOUND_PIERCE
//Handling for bone only/flesh only(none right now)/flesh and bone targets
switch(bio_state)
// if we're bone only, all cutting attacks go straight to the bone
if(BIO_JUST_BONE)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
phantom_wounding_dmg *= (easy_dismember ? 1 : 0.5)
else if(wounding_type == WOUND_PIERCE)
wounding_type = WOUND_BLUNT
phantom_wounding_dmg *= (easy_dismember ? 1 : 0.75)
if((mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
return
// note that there's no handling for BIO_JUST_FLESH since we don't have any that are that right now (slimepeople maybe someday)
// standard humanoids
if(BIO_FLESH_BONE)
// if we've already mangled the skin (critical slash or piercing wound), then the bone is exposed, and we can damage it with sharp weapons at a reduced rate
// So a big sharp weapon is still all you need to destroy a limb
if(mangled_state == BODYPART_MANGLED_FLESH && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
phantom_wounding_dmg *= 0.5 // edged weapons pass along 50% of their wounding damage to the bone since the power is spread out over a larger area
if(wounding_type == WOUND_PIERCE && !easy_dismember)
phantom_wounding_dmg *= 0.75 // piercing weapons pass along 75% of their wounding damage to the bone since it's more concentrated
wounding_type = WOUND_BLUNT
else if(mangled_state == BODYPART_MANGLED_BOTH && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
return
check_wounding(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus)
/**
* check_wounding() is where we handle rolling for, selecting, and applying a wound if we meet the criteria
*
* We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [check_wounding_mods()], then go down the list from most severe to least severe wounds in that category.
* We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [/obj/item/bodypart/proc/check_wounding_mods], then go down the list from most severe to least severe wounds in that category.
* We can promote a wound from a lesser to a higher severity this way, but we give up if we have a wound of the given type and fail to roll a higher severity, so no sidegrades/downgrades
*
* Arguments:
* * woundtype- Either WOUND_SHARP, WOUND_BRUTE, or WOUND_BURN based on the attack type.
* * woundtype- Either WOUND_BLUNT, WOUND_SLASH, WOUND_PIERCE, or WOUND_BURN based on the attack type.
* * damage- How much damage is tied to this attack, since wounding potential scales with damage in an attack (see: WOUND_DAMAGE_EXPONENT)
* * wound_bonus- The wound_bonus of an attack
* * bare_wound_bonus- The bare_wound_bonus of an attack
@@ -252,19 +352,24 @@
// actually roll wounds if applicable
if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE))
damage *= 1.5
else
damage = min(damage, WOUND_MAX_CONSIDERED_DAMAGE)
var/base_roll = rand(1, round(damage ** WOUND_DAMAGE_EXPONENT))
var/injury_roll = base_roll
injury_roll += check_woundings_mods(woundtype, damage, wound_bonus, bare_wound_bonus)
var/list/wounds_checking
var/list/wounds_checking = GLOB.global_wound_types[woundtype]
switch(woundtype)
if(WOUND_SHARP)
wounds_checking = WOUND_LIST_SLASH
if(WOUND_BRUTE)
wounds_checking = WOUND_LIST_BLUNT
if(WOUND_BURN)
wounds_checking = WOUND_LIST_BURN
// quick re-check to see if bare_wound_bonus applies, for the benefit of log_wound(), see about getting the check from check_woundings_mods() somehow
if(ishuman(owner))
var/mob/living/carbon/human/human_wearer = owner
var/list/clothing = human_wearer.clothingonpart(src)
for(var/i in clothing)
var/obj/item/clothing/clothes_check = i
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
if(clothes_check.armor.getRating("wound"))
bare_wound_bonus = 0
break
//cycle through the wounds of the relevant category from the most severe down
for(var/PW in wounds_checking)
@@ -279,21 +384,22 @@
replaced_wound = existing_wound
if(initial(possible_wound.threshold_minimum) < injury_roll)
var/datum/wound/new_wound
if(replaced_wound)
var/datum/wound/new_wound = replaced_wound.replace_wound(possible_wound)
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
new_wound = replaced_wound.replace_wound(possible_wound)
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll) // dismembering wounds are logged in the apply_wound() for loss wounds since they delete themselves immediately, these will be immediately returned
else
var/datum/wound/new_wound = new possible_wound
new_wound = new possible_wound
new_wound.apply_wound(src)
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
return
return new_wound
// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart
/obj/item/bodypart/proc/force_wound_upwards(specific_woundtype, smited = FALSE)
var/datum/wound/potential_wound = specific_woundtype
for(var/i in wounds)
var/datum/wound/existing_wound = i
if(existing_wound.type in (initial(potential_wound.wound_type)))
if(existing_wound.wound_type == initial(potential_wound.wound_type))
if(existing_wound.severity < initial(potential_wound.severity)) // we only try if the existing one is inferior to the one we're trying to force
existing_wound.replace_wound(potential_wound, smited)
return
@@ -301,12 +407,20 @@
var/datum/wound/new_wound = new potential_wound
new_wound.apply_wound(src, smited = smited)
/**
* check_wounding_mods() is where we handle the various modifiers of a wound roll
*
* A short list of things we consider: any armor a human target may be wearing, and if they have no wound armor on the limb, if we have a bare_wound_bonus to apply, plus the plain wound_bonus
* We also flick through all of the wounds we currently have on this limb and add their threshold penalties, so that having lots of bad wounds makes you more liable to get hurt worse
* Lastly, we add the inherent wound_resistance variable the bodypart has (heads and chests are slightly harder to wound), and a small bonus if the limb is already disabled
*
* Arguments:
* * It's the same ones on [receive_damage]
*/
/obj/item/bodypart/proc/check_woundings_mods(wounding_type, damage, wound_bonus, bare_wound_bonus)
var/armor_ablation = 0
var/injury_mod = 0
//var/bwb = 0
if(owner && ishuman(owner))
var/mob/living/carbon/human/H = owner
var/list/clothing = H.clothingonpart(src)
@@ -314,7 +428,7 @@
var/obj/item/clothing/C = c
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
armor_ablation += C.armor.getRating("wound")
if(wounding_type == WOUND_SHARP)
if(wounding_type == WOUND_SLASH)
C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration)
else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage()
C.take_damage_zone(body_zone, damage, BURN, armour_penetration)
@@ -330,7 +444,7 @@
injury_mod += W.threshold_penalty
var/part_mod = -wound_resistance
if(is_disabled())
if(get_damage(TRUE) >= max_damage)
part_mod += disabled_wound_penalty
injury_mod += part_mod
@@ -383,11 +497,11 @@
return BODYPART_DISABLED_WOUND
if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER))
. = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled
if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0%
if(get_damage(TRUE) >= max_damage * (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) ? 0.6 : 1)) //Easy limb disable disables the limb at 40% health instead of 0%
if(!last_maxed)
owner.emote("scream")
last_maxed = TRUE
if(!is_organic_limb())
if(!is_organic_limb() || stamina_dam >= max_damage)
return BODYPART_DISABLED_DAMAGE
else if(disabled && (get_damage(TRUE) <= (max_damage * 0.8))) // reenabled at 80% now instead of 50% as of wounds update
last_maxed = FALSE
@@ -741,17 +855,29 @@
/obj/item/bodypart/proc/get_wound_type(checking_type)
if(isnull(wounds))
return
for(var/thing in wounds)
var/datum/wound/W = thing
if(istype(W, checking_type))
return W
for(var/i in wounds)
if(istype(i, checking_type))
return i
/// very rough start for updating efficiency and other stats on a body part whenever a wound is gained/lost
/obj/item/bodypart/proc/update_wounds()
/**
* update_wounds() is called whenever a wound is gained or lost on this bodypart, as well as if there's a change of some kind on a bone wound possibly changing disabled status
*
* Covers tabulating the damage multipliers we have from wounds (burn specifically), as well as deleting our gauze wrapping if we don't have any wounds that can use bandaging
*
* Arguments:
* * replaced- If true, this is being called from the remove_wound() of a wound that's being replaced, so the bandage that already existed is still relevant, but the new wound hasn't been added yet
*/
/obj/item/bodypart/proc/update_wounds(replaced = FALSE)
var/dam_mul = 1 //initial(wound_damage_multiplier)
// we can only have one wound per type, but remember there's multiple types
for(var/datum/wound/W in wounds)
dam_mul *= W.damage_mulitplier_penalty
// we can (normally) only have one wound per type, but remember there's multiple types (smites like :B:loodless can generate multiple cuts on a limb)
for(var/i in wounds)
var/datum/wound/iter_wound = i
dam_mul *= iter_wound.damage_mulitplier_penalty
if(!LAZYLEN(wounds) && current_gauze && !replaced)
owner.visible_message("<span class='notice'>\The [current_gauze] on [owner]'s [name] fall away.</span>", "<span class='notice'>The [current_gauze] on your [name] fall away.</span>")
QDEL_NULL(current_gauze)
wound_damage_multiplier = dam_mul
update_disabled()
@@ -761,8 +887,6 @@
var/bleed_rate = 0
if(generic_bleedstacks > 0)
bleed_rate++
if(brute_dam >= 40)
bleed_rate += (brute_dam * 0.008)
//We want an accurate reading of .len
listclearnulls(embedded_objects)
@@ -773,5 +897,40 @@
for(var/thing in wounds)
var/datum/wound/W = thing
bleed_rate += W.blood_flow
if(owner.mobility_flags & ~MOBILITY_STAND)
bleed_rate *= 0.75
return bleed_rate
/**
* apply_gauze() is used to- well, apply gauze to a bodypart
*
* As of the Wounds 2 PR, all bleeding is now bodypart based rather than the old bleedstacks system, and 90% of standard bleeding comes from flesh wounds (the exception is embedded weapons).
* The same way bleeding is totaled up by bodyparts, gauze now applies to all wounds on the same part. Thus, having a slash wound, a pierce wound, and a broken bone wound would have the gauze
* applying blood staunching to the first two wounds, while also acting as a sling for the third one. Once enough blood has been absorbed or all wounds with the ACCEPTS_GAUZE flag have been cleared,
* the gauze falls off.
*
* Arguments:
* * gauze- Just the gauze stack we're taking a sheet from to apply here
*/
/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze)
if(!istype(gauze) || !gauze.absorption_capacity)
return
QDEL_NULL(current_gauze)
current_gauze = new gauze.type(src, 1)
gauze.use(1)
/**
* seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
*
* The passed amount of seepage is deducted from the bandage's absorption capacity, and if we reach a negative absorption capacity, the bandages fall off and we're left with nothing.
*
* Arguments:
* * seep_amt - How much absorption capacity we're removing from our current bandages (think, how much blood or pus are we soaking up this tick?)
*/
/obj/item/bodypart/proc/seep_gauze(seep_amt = 0)
if(!current_gauze)
return
current_gauze.absorption_capacity -= seep_amt
if(current_gauze.absorption_capacity < 0)
owner.visible_message("<span class='danger'>\The [current_gauze] on [owner]'s [name] fall away in rags.</span>", "<span class='warning'>\The [current_gauze] on your [name] fall away in rags.</span>", vision_distance=COMBAT_MESSAGE_RANGE)
QDEL_NULL(current_gauze)
@@ -4,7 +4,7 @@
return TRUE
//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE)
/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE)
if(!owner)
return FALSE
var/mob/living/carbon/C = owner
@@ -16,7 +16,8 @@
return FALSE
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
if(!silent)
C.visible_message("<span class='danger'><B>[C]'s [name] is violently dismembered!</B></span>")
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
drop_limb()
@@ -30,6 +31,7 @@
burn()
return TRUE
add_mob_blood(C)
C.bleed(rand(20, 40))
var/direction = pick(GLOB.cardinals)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -80,8 +82,6 @@
if(organ_spilled)
C.visible_message("<span class='danger'><B>[C]'s internal organs spill out onto the floor!</B></span>")
//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
/obj/item/bodypart/proc/drop_limb(special, dismembered)
if(!owner)
@@ -153,7 +153,52 @@
forceMove(Tsec)
/**
* get_mangled_state() is relevant for flesh and bone bodyparts, and returns whether this bodypart has mangled skin, mangled bone, or both (or neither i guess)
*
* Dismemberment for flesh and bone requires the victim to have the skin on their bodypart destroyed (either a critical cut or piercing wound), and at least a hairline fracture
* (severe bone), at which point we can start rolling for dismembering. The attack must also deal at least 10 damage, and must be a brute attack of some kind (sorry for now, cakehat, maybe later)
*
* Returns: BODYPART_MANGLED_NONE if we're fine, BODYPART_MANGLED_FLESH if our skin is broken, BODYPART_MANGLED_BONE if our bone is broken, or BODYPART_MANGLED_BOTH if both are broken and we're up for dismembering
*/
/obj/item/bodypart/proc/get_mangled_state()
. = BODYPART_MANGLED_NONE
for(var/i in wounds)
var/datum/wound/iter_wound = i
if((iter_wound.wound_flags & MANGLES_BONE))
. |= BODYPART_MANGLED_BONE
if((iter_wound.wound_flags & MANGLES_FLESH))
. |= BODYPART_MANGLED_FLESH
/**
* try_dismember() is used, once we've confirmed that a flesh and bone bodypart has both the skin and bone mangled, to actually roll for it
*
* Mangling is described in the above proc, [/obj/item/bodypart/proc/get_mangled_state()]. This simply makes the roll for whether we actually dismember or not
* using how damaged the limb already is, and how much damage this blow was for. If we have a critical bone wound instead of just a severe, we add +10% to the roll.
* Lastly, we choose which kind of dismember we want based on the wounding type we hit with. Note we don't care about all the normal mods or armor for this
*
* Arguments:
* * wounding_type: Either WOUND_BLUNT, WOUND_SLASH, or WOUND_PIERCE, basically only matters for the dismember message
* * wounding_dmg: The damage of the strike that prompted this roll, higher damage = higher chance
* * wound_bonus: Not actually used right now, but maybe someday
* * bare_wound_bonus: ditto above
*/
/obj/item/bodypart/proc/try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
if(wounding_dmg < DISMEMBER_MINIMUM_DAMAGE)
return
var/base_chance = wounding_dmg + (get_damage() / max_damage * 50) // how much damage we dealt with this blow, + 50% of the damage percentage we already had on this bodypart
if(locate(/datum/wound/blunt/critical) in wounds) // we only require a severe bone break, but if there's a critical bone break, we'll add 10% more
base_chance += 10
if(!prob(base_chance))
return
var/datum/wound/loss/dismembering = new
dismembering.apply_dismember(src, wounding_type)
return TRUE
//when a limb is dropped, the internal organs are removed from the mob and put into the limb
/obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C)
@@ -378,7 +423,7 @@
/mob/living/carbon/regenerate_limb(limb_zone, noheal)
var/obj/item/bodypart/L
if(get_bodypart(limb_zone))
return 0
return FALSE
L = newBodyPart(limb_zone, 0, 0)
if(L)
if(!noheal)
@@ -386,6 +431,8 @@
L.burn_dam = 0
L.brutestate = 0
L.burnstate = 0
var/datum/scar/scaries = new
var/datum/wound/loss/phantom_loss = new // stolen valor, really
scaries.generate(L, phantom_loss)
L.attach_limb(src, 1)
return 1
return TRUE
+1 -2
View File
@@ -36,11 +36,10 @@
var/custom_head
wound_resistance = 10
specific_locations = list("left eyebrow", "cheekbone", "neck", "throat", "jawline", "entire face")
scars_covered_by_clothes = FALSE
/obj/item/bodypart/head/can_dismember(obj/item/I)
if(!((owner.stat == DEAD) || owner.InFullCritical()))
if(owner && !((owner.stat == DEAD) || owner.InFullCritical()))
return FALSE
return ..()
+1 -1
View File
@@ -12,7 +12,7 @@
var/obj/item/cavity_item
/obj/item/bodypart/chest/can_dismember(obj/item/I)
if(!((owner.stat == DEAD) || owner.InFullCritical()))
if(!((owner.stat == DEAD) || owner.InFullCritical()) || !get_organs())
return FALSE
return ..()
+2 -1
View File
@@ -94,7 +94,8 @@
log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]")
burn_wound.sanitization += 3
burn_wound.flesh_healing += 5
burn_wound.force_bandage(tool)
var/obj/item/bodypart/the_part = target.get_bodypart(target_zone)
the_part.apply_gauze(tool)
else
to_chat(user, "<span class='warning'>[target] has no burns there!</span>")
return ..()
+108
View File
@@ -0,0 +1,108 @@
/////BURN FIXING SURGERIES//////
//the step numbers of each of these two, we only currently use the first to switch back and forth due to advancing after finishing steps anyway
#define REALIGN_INNARDS 1
#define WELD_VEINS 2
///// Repair puncture wounds
/datum/surgery/repair_puncture
name = "Repair puncture"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_innards, /datum/surgery_step/seal_veins, /datum/surgery_step/close) // repeat between steps 2 and 3 until healed
target_mobtypes = list(/mob/living/carbon)
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
requires_real_bodypart = TRUE
targetable_wound = /datum/wound/pierce
/datum/surgery/repair_puncture/can_start(mob/living/user, mob/living/carbon/target)
. = ..()
if(.)
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
var/datum/wound/burn/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound)
return(pierce_wound && pierce_wound.blood_flow > 0)
//SURGERY STEPS
///// realign the blood vessels so we can reweld them
/datum/surgery_step/repair_innards
name = "realign blood vessels"
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_WIRECUTTER = 40)
time = 3 SECONDS
/datum/surgery_step/repair_innards/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/datum/wound/pierce/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message("<span class='notice'>[user] looks for [target]'s [parse_zone(user.zone_selected)].</span>", "<span class='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
return
if(pierce_wound.blood_flow <= 0)
to_chat(user, "<span class='notice'>[target]'s [parse_zone(user.zone_selected)] has no puncture to repair!</span>")
surgery.status++
return
display_results(user, target, "<span class='notice'>You begin to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)]...</span>",
"<span class='notice'>[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
"<span class='notice'>[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)].</span>")
/datum/surgery_step/repair_innards/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/datum/wound/pierce/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, "<span class='warning'>[target] has no puncture wound there!</span>")
return ..()
display_results(user, target, "<span class='notice'>You successfully realign some of the blood vessels in [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
"<span class='notice'>[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)]!</span>")
log_combat(user, target, "excised infected flesh in", addition="INTENT: [uppertext(user.a_intent)]")
surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND)
pierce_wound.blood_flow -= 0.25
return ..()
/datum/surgery_step/repair_innards/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
. = ..()
display_results(user, target, "<span class='notice'>You jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)].</span>",
"<span class='notice'>[user] jerks apart some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
"<span class='notice'>[user] jerk apart some of the blood vessels in [target]'s [parse_zone(target_zone)]!</span>")
surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=SHARP_EDGED, wound_bonus = 10)
///// Sealing the vessels back together
/datum/surgery_step/seal_veins
name = "weld veins" // if your doctor says they're going to weld your blood vessels back together, you're either A) on SS13, or B) in grave mortal peril
implements = list(TOOL_CAUTERY = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70, /obj/item = 30)
time = 4 SECONDS
/datum/surgery_step/seal_veins/tool_check(mob/user, obj/item/tool)
if(implement_type == TOOL_WELDER || implement_type == /obj/item)
return tool.get_temperature()
return TRUE
/datum/surgery_step/seal_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/datum/wound/pierce/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message("<span class='notice'>[user] looks for [target]'s [parse_zone(user.zone_selected)].</span>", "<span class='notice'>You look for [target]'s [parse_zone(user.zone_selected)]...</span>")
return
display_results(user, target, "<span class='notice'>You begin to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)]...</span>",
"<span class='notice'>[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
"<span class='notice'>[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)].</span>")
/datum/surgery_step/seal_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/datum/wound/pierce/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, "<span class='warning'>[target] has no puncture there!</span>")
return ..()
display_results(user, target, "<span class='notice'>You successfully meld some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool].</span>",
"<span class='notice'>[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
"<span class='notice'>[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)]!</span>")
log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]")
pierce_wound.blood_flow -= 0.5
if(pierce_wound.blood_flow > 0)
surgery.status = REALIGN_INNARDS
to_chat(user, "<span class='notice'><i>There still seems to be misaligned blood vessels to finish...<i></span>")
else
to_chat(user, "<span class='green'>You've repaired all the internal damage in [target]'s [parse_zone(target_zone)]!</span>")
return ..()
#undef REALIGN_INNARDS
#undef WELD_VEINS