more changes
This commit is contained in:
+194
-290
@@ -71,6 +71,28 @@
|
||||
var/medium_burn_msg = "blistered"
|
||||
var/heavy_burn_msg = "peeling away"
|
||||
|
||||
/// The wounds currently afflicting this body part
|
||||
var/list/wounds
|
||||
|
||||
/// The scars currently afflicting this body part
|
||||
var/list/scars
|
||||
/// Our current stored wound damage multiplier
|
||||
var/wound_damage_multiplier = 1
|
||||
|
||||
/// This number is subtracted from all wound rolls on this bodypart, higher numbers mean more defense, negative means easier to wound
|
||||
var/wound_resistance = 0
|
||||
/// When this bodypart hits max damage, this number is added to all wound rolls. Obviously only relevant for bodyparts that have damage caps.
|
||||
var/disabled_wound_penalty = 15
|
||||
|
||||
/// 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
|
||||
|
||||
/obj/item/bodypart/examine(mob/user)
|
||||
. = ..()
|
||||
if(brute_dam > DAMAGE_PRECISION)
|
||||
@@ -149,7 +171,7 @@
|
||||
//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
|
||||
//Damage will not exceed max_damage using this proc
|
||||
//Cannot apply negative damage
|
||||
/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE)
|
||||
/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) // maybe separate BRUTE_SHARP and BRUTE_OTHER eventually somehow hmm
|
||||
if(owner && (owner.status_flags & GODMODE))
|
||||
return FALSE //godmode
|
||||
var/dmg_mlt = CONFIG_GET(number/damage_multiplier)
|
||||
@@ -163,20 +185,38 @@
|
||||
if(!brute && !burn && !stamina)
|
||||
return FALSE
|
||||
|
||||
brute *= wound_damage_multiplier
|
||||
burn *= wound_damage_multiplier
|
||||
|
||||
switch(animal_origin)
|
||||
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)
|
||||
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
|
||||
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
|
||||
|
||||
var/can_inflict = max_damage - get_damage()
|
||||
if(can_inflict <= 0)
|
||||
return FALSE
|
||||
|
||||
var/total_damage = brute + burn
|
||||
|
||||
if(total_damage > can_inflict)
|
||||
if(total_damage > can_inflict && total_damage > 0) // TODO: the second part of this check should be removed once disabling is all done
|
||||
brute = round(brute * (max_damage / total_damage),DAMAGE_PRECISION)
|
||||
burn = round(burn * (max_damage / total_damage),DAMAGE_PRECISION)
|
||||
|
||||
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
|
||||
|
||||
@@ -196,6 +236,107 @@
|
||||
update_disabled()
|
||||
return update_bodypart_damage_state()
|
||||
|
||||
/**
|
||||
* 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 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.
|
||||
* * 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
|
||||
*/
|
||||
/obj/item/bodypart/proc/check_wounding(woundtype, damage, wound_bonus, bare_wound_bonus)
|
||||
// actually roll wounds if applicable
|
||||
if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE))
|
||||
damage *= 1.5
|
||||
|
||||
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
|
||||
|
||||
switch(woundtype)
|
||||
if(WOUND_SHARP)
|
||||
wounds_checking = WOUND_LIST_CUT
|
||||
if(WOUND_BRUTE)
|
||||
wounds_checking = WOUND_LIST_BONE
|
||||
if(WOUND_BURN)
|
||||
wounds_checking = WOUND_LIST_BURN
|
||||
|
||||
//cycle through the wounds of the relevant category from the most severe down
|
||||
for(var/PW in wounds_checking)
|
||||
var/datum/wound/possible_wound = PW
|
||||
var/datum/wound/replaced_wound
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/existing_wound = i
|
||||
if(existing_wound.type in wounds_checking)
|
||||
if(existing_wound.severity >= initial(possible_wound.severity))
|
||||
return
|
||||
else
|
||||
replaced_wound = existing_wound
|
||||
|
||||
if(initial(possible_wound.threshold_minimum) < injury_roll)
|
||||
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)
|
||||
else
|
||||
var/datum/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
|
||||
|
||||
// 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.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
|
||||
|
||||
var/datum/wound/new_wound = new potential_wound
|
||||
new_wound.apply_wound(src, smited = smited)
|
||||
|
||||
/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)
|
||||
for(var/c in clothing)
|
||||
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)
|
||||
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)
|
||||
|
||||
if(!armor_ablation)
|
||||
injury_mod += bare_wound_bonus
|
||||
|
||||
injury_mod -= armor_ablation
|
||||
injury_mod += wound_bonus
|
||||
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
injury_mod += W.threshold_penalty
|
||||
|
||||
var/part_mod = -wound_resistance
|
||||
if(is_disabled())
|
||||
part_mod += disabled_wound_penalty
|
||||
|
||||
injury_mod += part_mod
|
||||
|
||||
return injury_mod
|
||||
|
||||
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
|
||||
//Damage cannot go below zero.
|
||||
//Cannot remove negative damage (i.e. apply damage)
|
||||
@@ -227,16 +368,29 @@
|
||||
|
||||
//Checks disabled status thresholds
|
||||
/obj/item/bodypart/proc/update_disabled()
|
||||
if(!owner)
|
||||
return
|
||||
set_disabled(is_disabled())
|
||||
|
||||
/obj/item/bodypart/proc/is_disabled()
|
||||
if(!owner)
|
||||
return
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/W = i
|
||||
if(W.disabling)
|
||||
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%
|
||||
return BODYPART_DISABLED_DAMAGE
|
||||
if(disabled && (get_damage(TRUE) <= (max_damage * 0.5)))
|
||||
if(!last_maxed)
|
||||
owner.emote("scream")
|
||||
last_maxed = TRUE
|
||||
if(!is_organic_limb())
|
||||
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
|
||||
return BODYPART_NOT_DISABLED
|
||||
else
|
||||
return BODYPART_NOT_DISABLED
|
||||
@@ -251,9 +405,11 @@
|
||||
|
||||
|
||||
/obj/item/bodypart/proc/set_disabled(new_disabled)
|
||||
if(disabled == new_disabled)
|
||||
if(disabled == new_disabled || !owner)
|
||||
return FALSE
|
||||
disabled = new_disabled
|
||||
if(disabled && owner.get_item_for_held_index(held_index))
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
owner.update_health_hud() //update the healthdoll
|
||||
owner.update_body()
|
||||
owner.update_mobility()
|
||||
@@ -581,293 +737,41 @@
|
||||
drop_organs()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bodypart/chest
|
||||
name = BODY_ZONE_CHEST
|
||||
desc = "It's impolite to stare at a person's chest."
|
||||
icon_state = "default_human_chest"
|
||||
max_damage = 200
|
||||
body_zone = BODY_ZONE_CHEST
|
||||
body_part = CHEST
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
stam_damage_coeff = 1
|
||||
max_stamina_damage = 200
|
||||
var/obj/item/cavity_item
|
||||
|
||||
/obj/item/bodypart/chest/can_dismember(obj/item/I)
|
||||
if(!((owner.stat == DEAD) || owner.InFullCritical()))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/Destroy()
|
||||
if(cavity_item)
|
||||
qdel(cavity_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/drop_organs(mob/user)
|
||||
if(cavity_item)
|
||||
cavity_item.forceMove(user.loc)
|
||||
cavity_item = null
|
||||
..()
|
||||
|
||||
/obj/item/bodypart/chest/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_chest"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 500
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/larva
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "larva_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 50
|
||||
animal_origin = LARVA_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm
|
||||
name = "left arm"
|
||||
desc = "Did you know that the word 'sinister' stems originally from the \
|
||||
Latin 'sinestra' (left hand), because the left hand was supposed to \
|
||||
be possessed by the devil? This arm appears to be possessed by no \
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
|
||||
/obj/item/bodypart/l_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
/// Get whatever wound of the given type is currently attached to this limb, if any
|
||||
/obj/item/bodypart/proc/get_wound_type(checking_type)
|
||||
if(isnull(wounds))
|
||||
return
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(L)
|
||||
L.update_icon()
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
if(istype(W, checking_type))
|
||||
return W
|
||||
|
||||
/obj/item/bodypart/l_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_x = -5
|
||||
px_y = -3
|
||||
/// 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()
|
||||
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
|
||||
wound_damage_multiplier = dam_mul
|
||||
update_disabled()
|
||||
|
||||
/obj/item/bodypart/l_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm
|
||||
name = "right arm"
|
||||
desc = "Over 87% of humans are right handed. That figure is much lower \
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
max_stamina_damage = 50
|
||||
|
||||
/obj/item/bodypart/r_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
/obj/item/bodypart/proc/get_bleed_rate()
|
||||
if(status != BODYPART_ORGANIC) // maybe in the future we can bleed oil from aug parts, but not now
|
||||
return
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(R)
|
||||
R.update_icon()
|
||||
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)
|
||||
for(var/obj/item/embeddies in embedded_objects)
|
||||
if(!embeddies.isEmbedHarmless())
|
||||
bleed_rate += 0.5
|
||||
|
||||
/obj/item/bodypart/r_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_x = 5
|
||||
px_y = -3
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
bleed_rate += W.blood_flow
|
||||
|
||||
/obj/item/bodypart/r_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg
|
||||
name = "left leg"
|
||||
desc = "Some athletes prefer to tie their left shoelaces first for good \
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
max_stamina_damage = 50
|
||||
|
||||
/obj/item/bodypart/l_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!. || owner.stat >= UNCONSCIOUS)
|
||||
return
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
|
||||
/obj/item/bodypart/l_leg/digitigrade
|
||||
name = "left digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/l_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/l_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg
|
||||
name = "right leg"
|
||||
desc = "You put your right leg in, your right leg out. In, out, in, out, \
|
||||
shake it all about. And apparently then it detaches.\n\
|
||||
The hokey pokey has certainly changed a lot since space colonisation."
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
|
||||
/obj/item/bodypart/r_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!. || owner.stat >= UNCONSCIOUS)
|
||||
return
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/r_leg/digitigrade
|
||||
name = "right digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/r_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/r_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
return bleed_rate
|
||||
@@ -15,7 +15,7 @@
|
||||
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
|
||||
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)) //Damage the chest based on limb's existing damage
|
||||
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>")
|
||||
C.emote("scream")
|
||||
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
|
||||
@@ -83,11 +83,12 @@
|
||||
|
||||
|
||||
//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)
|
||||
/obj/item/bodypart/proc/drop_limb(special, dismembered)
|
||||
if(!owner)
|
||||
return
|
||||
var/atom/Tsec = owner.drop_location()
|
||||
var/mob/living/carbon/C = owner
|
||||
SEND_SIGNAL(C, COMSIG_CARBON_REMOVE_LIMB, src, dismembered)
|
||||
update_limb(1)
|
||||
C.bodyparts -= src
|
||||
|
||||
@@ -95,6 +96,15 @@
|
||||
C.dropItemToGround(owner.get_item_for_held_index(held_index), 1)
|
||||
C.hand_bodyparts[held_index] = null
|
||||
|
||||
for(var/thing in scars)
|
||||
var/datum/scar/S = thing
|
||||
S.victim = null
|
||||
LAZYREMOVE(owner.all_scars, S)
|
||||
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
W.remove_wound(TRUE)
|
||||
|
||||
owner = null
|
||||
|
||||
for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it.
|
||||
@@ -298,6 +308,15 @@
|
||||
for(var/obj/item/organ/O in contents)
|
||||
O.Insert(C)
|
||||
|
||||
for(var/thing in scars)
|
||||
var/datum/scar/S = thing
|
||||
S.victim = C
|
||||
LAZYADD(C.all_scars, thing)
|
||||
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/W = i
|
||||
W.apply_wound(src, TRUE)
|
||||
|
||||
update_bodypart_damage_state()
|
||||
update_disabled()
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
//If the head is a special sprite
|
||||
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()))
|
||||
return FALSE
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
if(L.body_zone == zone)
|
||||
return L
|
||||
|
||||
///Get the bodypart for whatever hand we have active, Only relevant for carbons
|
||||
/mob/proc/get_active_hand()
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/get_active_hand()
|
||||
var/which_hand = BODY_ZONE_PRECISE_L_HAND
|
||||
if(!(active_hand_index % 2))
|
||||
which_hand = BODY_ZONE_PRECISE_R_HAND
|
||||
return get_bodypart(check_zone(which_hand))
|
||||
|
||||
/mob/living/carbon/has_hand_for_held_index(i)
|
||||
if(i)
|
||||
var/obj/item/bodypart/L = hand_bodyparts[i]
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
|
||||
/obj/item/bodypart/chest
|
||||
name = BODY_ZONE_CHEST
|
||||
desc = "It's impolite to stare at a person's chest."
|
||||
icon_state = "default_human_chest"
|
||||
max_damage = 200
|
||||
body_zone = BODY_ZONE_CHEST
|
||||
body_part = CHEST
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
stam_damage_coeff = 1
|
||||
max_stamina_damage = 120
|
||||
var/obj/item/cavity_item
|
||||
specific_locations = list("upper chest", "lower abdomen", "midsection", "collarbone", "lower back")
|
||||
wound_resistance = 10
|
||||
|
||||
/obj/item/bodypart/chest/can_dismember(obj/item/I)
|
||||
if(!((owner.stat == DEAD) || owner.InFullCritical()))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/Destroy()
|
||||
QDEL_NULL(cavity_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/drop_organs(mob/user, violent_removal)
|
||||
if(cavity_item)
|
||||
cavity_item.forceMove(drop_location())
|
||||
cavity_item = null
|
||||
..()
|
||||
|
||||
/obj/item/bodypart/chest/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_chest"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
|
||||
/obj/item/bodypart/chest/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 500
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/larva
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "larva_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 50
|
||||
animal_origin = LARVA_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm
|
||||
name = "left arm"
|
||||
desc = "Did you know that the word 'sinister' stems originally from the \
|
||||
Latin 'sinestra' (left hand), because the left hand was supposed to \
|
||||
be possessed by the devil? This arm appears to be possessed by no \
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_zone = BODY_ZONE_PRECISE_L_HAND
|
||||
aux_layer = HANDS_PART_LAYER
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
specific_locations = list("outer left forearm", "inner left wrist", "left elbow", "left bicep", "left shoulder")
|
||||
|
||||
/obj/item/bodypart/l_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(L)
|
||||
L.update_icon()
|
||||
|
||||
/obj/item/bodypart/l_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_x = -5
|
||||
px_y = -3
|
||||
|
||||
/obj/item/bodypart/l_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm
|
||||
name = "right arm"
|
||||
desc = "Over 87% of humans are right handed. That figure is much lower \
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_zone = BODY_ZONE_PRECISE_R_HAND
|
||||
aux_layer = HANDS_PART_LAYER
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("outer right forearm", "inner right wrist", "right elbow", "right bicep", "right shoulder")
|
||||
|
||||
/obj/item/bodypart/r_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(R)
|
||||
R.update_icon()
|
||||
|
||||
/obj/item/bodypart/r_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_x = 5
|
||||
px_y = -3
|
||||
|
||||
/obj/item/bodypart/r_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg
|
||||
name = "left leg"
|
||||
desc = "Some athletes prefer to tie their left shoelaces first for good \
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("inner left thigh", "outer left calf", "outer left hip", " left kneecap", "lower left shin")
|
||||
|
||||
/obj/item/bodypart/l_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/l_leg/digitigrade
|
||||
name = "left digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/l_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/l_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg
|
||||
name = "right leg"
|
||||
desc = "You put your right leg in, your right leg out. In, out, in, out, \
|
||||
shake it all about. And apparently then it detaches.\n\
|
||||
The hokey pokey has certainly changed a lot since space colonisation."
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("inner right thigh", "outer right calf", "outer right hip", "right kneecap", "lower right shin")
|
||||
|
||||
/obj/item/bodypart/r_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/r_leg/digitigrade
|
||||
name = "right digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/r_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/r_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
Reference in New Issue
Block a user