[MIRROR] [TEST-MERGE FIRST] Allows all limbs to be dismembered and significantly refactors wounds [MDB IGNORE] (#23407)

* [TEST-MERGE FIRST] Allows all limbs to be dismembered and significantly refactors wounds

* ah fuck it

* test

* edaawdawd

* Revert "edaawdawd"

This reverts commit 47be710fe61a1f4ca79212b29b3e88bf05ec9a3a.

* nothing but sheer hatred

* freaawd

* dzfxg

* Fixing some diffs here while we are at it.

* These are deprecated and should be removed

---------

Co-authored-by: nikothedude <59709059+nikothedude@users.noreply.github.com>
Co-authored-by: nikothedude <simon.prouty@gmail.com>
Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-09-05 19:24:22 +02:00
committed by GitHub
parent 02f66628e2
commit 2bcbb36ab9
84 changed files with 1974 additions and 2797 deletions
+106 -78
View File
@@ -1,3 +1,6 @@
#define AUGGED_LIMB_EMP_BRUTE_DAMAGE 3
#define AUGGED_LIMB_EMP_BURN_DAMAGE 2
/obj/item/bodypart
name = "limb"
desc = "Why is it detached..."
@@ -22,14 +25,15 @@
/// DO NOT MODIFY DIRECTLY. Use set_owner()
var/mob/living/carbon/owner
/// If this limb can be scarred.
var/scarrable = TRUE
/**
* A bitfield of biological states, exclusively used to determine which wounds this limb will get,
* as well as how easily it will happen.
* Set to BIO_FLESH_BONE because most species have both flesh and bone in their limbs.
*
* This currently has absolutely no meaning for robotic limbs.
* Set to BIO_STANDARD because most species have both flesh bone and blood in their limbs.
*/
var/biological_state = BIO_FLESH_BONE
var/biological_state = BIO_STANDARD
///A bitfield of bodytypes for clothing, surgery, and misc information
var/bodytype = BODYTYPE_HUMANOID | BODYTYPE_ORGANIC
///Defines when a bodypart should not be changed. Example: BP_BLOCK_CHANGE_SPECIES prevents the limb from being overwritten on species gain
@@ -66,16 +70,14 @@
var/speed_modifier = 0
// Limb disabling variables
///Whether it is possible for the limb to be disabled whatsoever. TRUE means that it is possible.
var/can_be_disabled = FALSE //Defaults to FALSE, as only human limbs can be disabled, and only the appendages.
///Controls if the limb is disabled. TRUE means it is disabled (similar to being removed, but still present for the sake of targeted interactions).
var/bodypart_disabled = FALSE
///Handles limb disabling by damage. If 0 (0%), a limb can't be disabled via damage. If 1 (100%), it is disabled at max limb damage. Anything between is the percentage of damage against maximum limb damage needed to disable the limb.
//var/disabling_threshold_percentage = 0 //ORIGINAL
var/disabling_threshold_percentage = 1 //SKYRAT EDIT CHANGE - COMBAT
///Whether it is possible for the limb to be disabled whatsoever. TRUE means that it is possible.
var/can_be_disabled = FALSE //Defaults to FALSE, as only human limbs can be disabled, and only the appendages.
// Damage state variables
var/disabling_threshold_percentage = 1 //SKYRAT EDIT CHANGE - COMBAT - ORIGINAL : var/disabling_threshold_percentage = 0
// Damage variables
///A mutiplication of the burn and brute damage that the limb's stored damage contributes to its attached mob's overall wellbeing.
var/body_damage_coeff = 1
///The current amount of brute damage the limb has
@@ -152,20 +154,8 @@
var/cached_bleed_rate = 0
/// How much generic bleedstacks we have on this bodypart
var/generic_bleedstacks
//SKYRAT EDIT CHANGE BEGIN - MEDICAL
/*
/// If we have a gauze wrapping currently applied (not including splints)
var/obj/item/stack/current_gauze
*/
/// If we have a gauze wrapping currently applied
var/datum/bodypart_aid/gauze/current_gauze
/// If we have a splint currently applied
var/datum/bodypart_aid/splint/current_splint
/// What icon do we use to render this limb? Ususally used by robotic limb augments.
var/rendered_bp_icon
/// Do we use an organic render for this robotic limb?
var/organic_render = TRUE
//SKYRAT EDIT CHANGE END
/// If something is currently grasping this bodypart and trying to staunch bleeding (see [/obj/item/hand_item/self_grasp])
var/obj/item/hand_item/self_grasp/grasped_by
@@ -200,6 +190,16 @@
/// List of the above datums which have actually been instantiated, managed automatically
var/list/feature_offsets = list()
/// In the case we dont have dismemberable features, or literally cant get wounds, we will use this percent to determine when we can be dismembered.
/// Compared to our ABSOLUTE maximum. Stored in decimal; 0.8 = 80%.
var/hp_percent_to_dismemberable = 0.8
/// If true, we will use [hp_percent_to_dismemberable] even if we are dismemberable via wounds. Useful for things with extreme wound resistance.
var/use_alternate_dismemberment_calc_even_if_mangleable = FALSE
/// If false, no wound that can be applied to us can mangle our flesh. Used for determining if we should use [hp_percent_to_dismemberable] instead of normal dismemberment.
var/any_existing_wound_can_mangle_our_flesh
/// If false, no wound that can be applied to us can mangle our bone. Used for determining if we should use [hp_percent_to_dismemberable] instead of normal dismemberment.
var/any_existing_wound_can_mangle_our_bone
/obj/item/bodypart/apply_fantasy_bonuses(bonus)
. = ..()
unarmed_damage_low = modify_fantasy_variable("unarmed_damage_low", unarmed_damage_low, bonus, minimum = 1)
@@ -241,12 +241,6 @@
if(length(wounds))
stack_trace("[type] qdeleted with [length(wounds)] uncleared wounds")
wounds.Cut()
//SKYRAT EDIT ADDITION BEGIN - MEDICAL
if(current_gauze)
qdel(current_gauze)
if(current_splint)
qdel(current_splint)
//SKYRAT EDIT ADDITION END
if(length(external_organs))
for(var/obj/item/organ/external/external_organ as anything in external_organs)
@@ -415,11 +409,7 @@
var/atom/drop_loc = drop_location()
if(IS_ORGANIC_LIMB(src))
playsound(drop_loc, 'sound/misc/splort.ogg', 50, TRUE, -1)
//seep_gauze(9999) // destroy any existing gauze if any exists
if(current_gauze)
qdel(current_gauze)
if(current_splint)
qdel(current_splint)
seep_gauze(9999) // destroy any existing gauze if any exists
for(var/obj/item/organ/bodypart_organ in get_organs())
bodypart_organ.transfer_to_limb(src, owner)
for(var/obj/item/organ/external/external in external_organs)
@@ -505,40 +495,75 @@
else if (sharpness & SHARP_POINTY)
wounding_type = WOUND_PIERCE
if(owner)
if(owner) // i tried to modularize the below, but the modifications to wounding_dmg and wounding_type cant be extracted to a proc
var/mangled_state = get_mangled_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%)
//Handling for bone only/flesh only(none right now)/flesh and bone targets
switch(biological_state)
// if we're bone only, all cutting attacks go straight to the bone
if(BIO_BONE)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.6)
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_FLESH since we don't have any that are that right now (slimepeople maybe someday)
// standard humanoids
if(BIO_FLESH_BONE)
//SKYRAT EDIT ADDITION BEGIN - MEDICAL
//We do a body zone check here because muscles dont have any variants for head or chest, and rolling a muscle wound on them wound end up on a wasted wound roll
if(body_zone != BODY_ZONE_CHEST && body_zone != BODY_ZONE_HEAD && prob(35))
wounding_type = WOUND_MUSCLE
//SKYRAT EDIT ADDITION END
// 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) && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
wounding_dmg *= 0.6 // edged weapons pass along 60% 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_FLESH) && (mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
var/has_exterior = FALSE
var/has_interior = FALSE
for (var/state as anything in GLOB.bio_state_states)
var/flag = text2num(state)
if (!(biological_state & flag))
continue
var/value = GLOB.bio_state_states[state]
if (value & BIO_EXTERIOR)
has_exterior = TRUE
if (value & BIO_INTERIOR)
has_interior = TRUE
if (has_exterior && has_interior)
break
// We put this here so we dont increase init time by doing this all at once on initialization
// Effectively, we "lazy load"
if (isnull(any_existing_wound_can_mangle_our_bone) || isnull(any_existing_wound_can_mangle_our_flesh))
any_existing_wound_can_mangle_our_bone = FALSE
any_existing_wound_can_mangle_our_flesh = FALSE
for (var/datum/wound/wound_type as anything in GLOB.all_wound_pregen_data)
var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound_type]
if (!pregen_data.can_be_applied_to(src, random_roll = TRUE)) // we only consider randoms because non-randoms are usually really specific
continue
if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_FLESH)
any_existing_wound_can_mangle_our_flesh = TRUE
if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_BONE)
any_existing_wound_can_mangle_our_bone = TRUE
if (any_existing_wound_can_mangle_our_bone && any_existing_wound_can_mangle_our_flesh)
break
var/can_theoretically_be_dismembered = (any_existing_wound_can_mangle_our_bone || (any_existing_wound_can_mangle_our_flesh && !has_exterior))
var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_BONE) == BODYPART_MANGLED_BONE))
var/interior_ready_to_dismember = (!has_interior || ((mangled_state & BODYPART_MANGLED_FLESH) == BODYPART_MANGLED_FLESH))
// if we're bone only, all cutting attacks go straight to the bone
if(has_exterior && interior_ready_to_dismember)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.6)
else if(wounding_type == WOUND_PIERCE)
wounding_type = WOUND_BLUNT
wounding_dmg *= (easy_dismember ? 1 : 0.75)
if(exterior_ready_to_dismember && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
else
// 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(has_exterior && interior_ready_to_dismember && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
wounding_dmg *= 0.6 // edged weapons pass along 60% 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(interior_ready_to_dismember && exterior_ready_to_dismember && try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus))
return
if (use_alternate_dismemberment_calc_even_if_mangleable || !can_theoretically_be_dismembered)
var/percent_to_total_max = (get_damage() / max_damage)
if (percent_to_total_max >= hp_percent_to_dismemberable)
if (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
@@ -552,15 +577,14 @@
damaged_percent = DAMAGED_BODYPART_BONUS_WOUNDING_THRESHOLD
wounding_dmg = min(DAMAGED_BODYPART_BONUS_WOUNDING_BONUS, wounding_dmg + (damaged_percent * DAMAGED_BODYPART_BONUS_WOUNDING_COEFF))
if(current_gauze)
current_gauze.take_damage()
if(current_splint)
current_splint.take_damage()
if (istype(current_gauze, /obj/item/stack/medical/gauze))
var/obj/item/stack/medical/gauze/our_gauze = current_gauze
our_gauze.get_hit()
//SKYRAT EDIT ADDITION END - MEDICAL
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus, attack_direction, damage_source = damage_source)
for(var/datum/wound/iter_wound as anything in wounds)
iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus)
iter_wound.receive_damage(wounding_type, wounding_dmg, wound_bonus, damage_source)
/*
// END WOUND HANDLING
@@ -1162,7 +1186,7 @@
if(!owner)
return
if(HAS_TRAIT(owner, TRAIT_NOBLOOD) || !IS_ORGANIC_LIMB(src))
if(!can_bleed())
if(cached_bleed_rate != old_bleed_rate)
update_part_wound_overlay()
return
@@ -1203,7 +1227,7 @@
/obj/item/bodypart/proc/update_part_wound_overlay()
if(!owner)
return FALSE
if(HAS_TRAIT(owner, TRAIT_NOBLOOD) || !IS_ORGANIC_LIMB(src))
if(!can_bleed())
if(bleed_overlay_icon)
bleed_overlay_icon = null
owner.update_wound_overlays()
@@ -1236,6 +1260,11 @@
#undef BLEED_OVERLAY_MED
#undef BLEED_OVERLAY_GUSH
/obj/item/bodypart/proc/can_bleed()
SHOULD_BE_PURE(TRUE)
return ((biological_state & BIO_BLOODED) && (!owner || !HAS_TRAIT(owner, TRAIT_NOBLOOD)))
/**
* apply_gauze() is used to- well, apply gauze to a bodypart
*
@@ -1247,7 +1276,6 @@
* Arguments:
* * gauze- Just the gauze stack we're taking a sheet from to apply here
*/
/* SKYRAT EDIT REMOVAL
/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze)
if(!istype(gauze) || !gauze.absorption_capacity)
return
@@ -1259,7 +1287,6 @@
gauze.use(1)
if(newly_gauzed)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZED, gauze)
*/
/**
* seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity.
@@ -1269,7 +1296,6 @@
* 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?)
*/
/* SKYRAT EDIT REMOVAL
/obj/item/bodypart/proc/seep_gauze(seep_amt = 0)
if(!current_gauze)
return
@@ -1278,7 +1304,6 @@
owner.visible_message(span_danger("\The [current_gauze.name] on [owner]'s [name] falls away in rags."), span_warning("\The [current_gauze.name] on your [name] falls away in rags."), vision_distance=COMBAT_MESSAGE_RANGE)
QDEL_NULL(current_gauze)
SEND_SIGNAL(src, COMSIG_BODYPART_GAUZE_DESTROYED)
*/
///Loops through all of the bodypart's external organs and update's their color.
/obj/item/bodypart/proc/recolor_external_organs()
@@ -1328,14 +1353,17 @@
/obj/item/bodypart/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_WIRES || !(bodytype & BODYTYPE_ROBOTIC))
if(. & EMP_PROTECT_WIRES || !IS_ROBOTIC_LIMB(src))
return FALSE
owner.visible_message(span_danger("[owner]'s [src.name] seems to malfunction!"))
// with defines at the time of writing, this is 3 brute and 2 burn
// 3 + 2 = 5, with 6 limbs thats 30, on a heavy 60
// 60 * 0.8 = 48
var/time_needed = 10 SECONDS
var/brute_damage = 2.5 // SKYRAT EDIT : Balances direct EMP damage for Brute - SR's synth values are multiplied 3x 2.5 * 1.3 * 1.3
var/burn_damage = 2 // SKYRAT EDIT : Balances direct EMP damage for Burn - SR's synth values are multiplied 3x 2 * 1.3 * 1.3
var/brute_damage = AUGGED_LIMB_EMP_BRUTE_DAMAGE
var/burn_damage = AUGGED_LIMB_EMP_BURN_DAMAGE
if(severity == EMP_HEAVY)
time_needed *= 2
brute_damage *= 1.3 // SKYRAT EDIT : Balance - Lowers total damage from ~125 Brute to ~30
+35 -17
View File
@@ -1,11 +1,11 @@
/obj/item/bodypart/proc/can_dismember(obj/item/item)
if(bodypart_flags & BODYPART_UNREMOVABLE)
if(bodypart_flags & BODYPART_UNREMOVABLE || (owner && HAS_TRAIT(owner, TRAIT_NODISMEMBER)))
return FALSE
return TRUE
///Remove target limb from it's owner, with side effects.
/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE)
/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE, wound_type)
if(!owner || (bodypart_flags & BODYPART_UNREMOVABLE))
return FALSE
var/mob/living/carbon/limb_owner = owner
@@ -22,11 +22,15 @@
playsound(get_turf(limb_owner), 'sound/effects/dismember.ogg', 80, TRUE)
limb_owner.add_mood_event("dismembered_[body_zone]", /datum/mood_event/dismembered, src)
limb_owner.add_mob_memory(/datum/memory/was_dismembered, lost_limb = src)
if (wound_type)
LAZYSET(limb_owner.body_zone_dismembered_by, body_zone, wound_type)
drop_limb()
limb_owner.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
var/turf/owner_location = limb_owner.loc
if(istype(owner_location))
if(wound_type != WOUND_BURN && istype(owner_location) && can_bleed())
limb_owner.add_splatter_floor(owner_location)
if(QDELETED(src)) //Could have dropped into lava/explosion/chasm/whatever
@@ -34,8 +38,9 @@
if(dam_type == BURN)
burn()
return TRUE
add_mob_blood(limb_owner)
limb_owner.bleed(rand(20, 40))
if (can_bleed())
add_mob_blood(limb_owner)
limb_owner.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)
@@ -47,10 +52,10 @@
if(new_turf.density)
break
throw_at(target_turf, throw_range, throw_speed)
return TRUE
/obj/item/bodypart/chest/dismember()
/obj/item/bodypart/chest/dismember(dam_type = BRUTE, silent=TRUE, wound_type)
if(!owner)
return FALSE
var/mob/living/carbon/chest_owner = owner
@@ -59,7 +64,7 @@
if(HAS_TRAIT(chest_owner, TRAIT_NODISMEMBER))
return FALSE
. = list()
if(isturf(chest_owner.loc))
if(wound_type != WOUND_BURN && isturf(chest_owner.loc) && can_bleed())
chest_owner.add_splatter_floor(chest_owner.loc)
playsound(get_turf(chest_owner), 'sound/misc/splort.ogg', 80, TRUE)
for(var/obj/item/organ/organ as anything in chest_owner.organs)
@@ -81,8 +86,6 @@
. += cavity_item
cavity_item = null
///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)
@@ -180,14 +183,17 @@
* * bare_wound_bonus: ditto above
*/
/obj/item/bodypart/proc/try_dismember(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
if (!can_dismember())
return
if(wounding_dmg < DISMEMBER_MINIMUM_DAMAGE)
return
var/base_chance = wounding_dmg
base_chance += (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 15% more
base_chance += 15
for (var/datum/wound/iterated_wound as anything in wounds)
base_chance += iterated_wound.get_dismember_chance_bonus(base_chance)
if(prob(base_chance))
var/datum/wound/loss/dismembering = new
@@ -328,6 +334,8 @@
set_owner(new_limb_owner)
new_limb_owner.add_bodypart(src)
LAZYREMOVE(new_limb_owner.body_zone_dismembered_by, body_zone)
if(special) //non conventional limb attachment
for(var/datum/surgery/attach_surgery as anything in new_limb_owner.surgeries) //if we had an ongoing surgery to attach a new limb, we stop it.
var/surgery_zone = check_zone(attach_surgery.location)
@@ -416,12 +424,15 @@
/mob/living/carbon/proc/regenerate_limbs(list/excluded_zones = list())
SEND_SIGNAL(src, COMSIG_CARBON_REGENERATE_LIMBS, excluded_zones)
var/list/zone_list = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
var/list/dismembered_by_copy = body_zone_dismembered_by?.Copy()
if(length(excluded_zones))
zone_list -= excluded_zones
for(var/limb_zone in zone_list)
regenerate_limb(limb_zone)
regenerate_limb(limb_zone, dismembered_by_copy)
/mob/living/carbon/proc/regenerate_limb(limb_zone)
/mob/living/carbon/proc/regenerate_limb(limb_zone, list/dismembered_by_copy = body_zone_dismembered_by?.Copy())
var/obj/item/bodypart/limb
if(get_bodypart(limb_zone))
return FALSE
@@ -431,9 +442,16 @@
qdel(limb)
return FALSE
limb.update_limb(is_creating = TRUE)
var/datum/scar/scaries = new
var/datum/wound/loss/phantom_loss = new // stolen valor, really
scaries.generate(limb, phantom_loss)
if (LAZYLEN(dismembered_by_copy))
var/datum/scar/scaries = new
var/datum/wound/loss/phantom_loss = new // stolen valor, really
phantom_loss.loss_wound_type = dismembered_by_copy?[limb_zone]
if (phantom_loss.loss_wound_type)
scaries.generate(limb, phantom_loss)
LAZYREMOVE(dismembered_by_copy, limb_zone) // in case we're using a passed list
else
qdel(scaries)
qdel(phantom_loss)
//Copied from /datum/species/proc/on_species_gain()
for(var/obj/item/organ/external/organ_path as anything in dna.species.external_organs)
+4 -3
View File
@@ -191,9 +191,10 @@
/obj/item/bodypart/head/update_limb(dropping_limb, is_creating)
. = ..()
if(!isnull(owner))
real_name = owner.real_name
if(HAS_TRAIT(owner, TRAIT_HUSK))
real_name = "Unknown"
if(HAS_TRAIT(owner, TRAIT_HUSK))
real_name = "Unknown"
else
real_name = owner.real_name
update_hair_and_lips(dropping_limb, is_creating)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+4
View File
@@ -114,6 +114,8 @@
/// Datum describing how to offset things held in the hands of this arm, the x offset IS functional here
var/datum/worn_feature_offset/held_hand_offset
biological_state = (BIO_STANDARD|BIO_JOINTED)
/obj/item/bodypart/arm/Destroy()
QDEL_NULL(worn_glove_offset)
QDEL_NULL(held_hand_offset)
@@ -344,6 +346,8 @@
/// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here
var/datum/worn_feature_offset/worn_foot_offset
biological_state = (BIO_STANDARD|BIO_JOINTED)
/obj/item/bodypart/leg/Destroy()
QDEL_NULL(worn_foot_offset)
return ..()
@@ -37,6 +37,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC|BIO_JOINTED)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
disabling_threshold_percentage = 1
@@ -58,6 +60,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -68,6 +71,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC|BIO_JOINTED)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/left/robot
@@ -88,6 +93,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -98,6 +104,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC|BIO_JOINTED)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/left/robot/emp_act(severity)
@@ -127,6 +135,7 @@
brute_modifier = 0.8
burn_modifier = 0.8
disabling_threshold_percentage = 1
light_brute_msg = ROBOTIC_LIGHT_BRUTE_MSG
@@ -137,6 +146,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC|BIO_JOINTED)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
/obj/item/bodypart/leg/right/robot/emp_act(severity)
@@ -174,6 +185,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
var/wired = FALSE
@@ -294,6 +307,8 @@
medium_burn_msg = ROBOTIC_MEDIUM_BURN_MSG
heavy_burn_msg = ROBOTIC_HEAVY_BURN_MSG
biological_state = (BIO_ROBOTIC)
damage_examines = list(BRUTE = ROBOTIC_BRUTE_EXAMINE_TEXT, BURN = ROBOTIC_BURN_EXAMINE_TEXT, CLONE = DEFAULT_CLONE_EXAMINE_TEXT)
head_flags = HEAD_EYESPRITES
@@ -380,6 +395,11 @@
flash2?.forceMove(drop_loc)
return ..()
// Prosthetics - Cheap, mediocre, and worse than organic limbs
// The fact they dont have a internal biotype means theyre a lot weaker defensively,
// since they skip slash and go right to blunt
// They are VERY easy to delimb as a result
// HP is also reduced just in case this isnt enough
/obj/item/bodypart/arm/left/robot/surplus
name = "surplus prosthetic left arm"
@@ -390,6 +410,8 @@
brute_modifier = 1
max_damage = 20
biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/arm/right/robot/surplus
name = "surplus prosthetic right arm"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
@@ -399,6 +421,8 @@
brute_modifier = 1
max_damage = 20
biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/leg/left/robot/surplus
name = "surplus prosthetic left leg"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
@@ -408,6 +432,8 @@
burn_modifier = 1
max_damage = 20
biological_state = (BIO_METAL|BIO_JOINTED)
/obj/item/bodypart/leg/right/robot/surplus
name = "surplus prosthetic right leg"
desc = "A skeletal, robotic limb. Outdated and fragile, but it's still better than nothing."
@@ -417,6 +443,8 @@
burn_modifier = 1
max_damage = 20
biological_state = (BIO_METAL|BIO_JOINTED)
#undef ROBOTIC_LIGHT_BRUTE_MSG
#undef ROBOTIC_MEDIUM_BRUTE_MSG
#undef ROBOTIC_HEAVY_BRUTE_MSG
@@ -1,19 +1,19 @@
///SNAIL
/obj/item/bodypart/head/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
is_dimorphic = FALSE
burn_modifier = 2
head_flags = HEAD_EYESPRITES|HEAD_DEBRAIN
/obj/item/bodypart/chest/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
is_dimorphic = FALSE
burn_modifier = 2
/obj/item/bodypart/arm/left/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_attack_verb = "slap"
unarmed_attack_effect = ATTACK_EFFECT_DISARM
@@ -22,7 +22,7 @@
burn_modifier = 2
/obj/item/bodypart/arm/right/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_attack_verb = "slap"
unarmed_attack_effect = ATTACK_EFFECT_DISARM
@@ -31,7 +31,7 @@
burn_modifier = 2
/obj/item/bodypart/leg/left/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_damage_low = 1 //SKYRAT EDIT - Roundstart Snails - Lowest possible punch damage. if this is set to 0, punches will always miss.
unarmed_damage_high = 5 //snails are soft and squishy //SKYRAT EDIT - Roundstart Snails - A Bit More Damage. - ORIGINAL: unarmed_damage_high = 0.5 //snails are soft and squishy
@@ -39,7 +39,7 @@
// speed_modifier = 3 //disgustingly slow // SKYRAT EDIT - Moved the movespeed to the shell.
/obj/item/bodypart/leg/right/snail
biological_state = BIO_FLESH //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
biological_state = (BIO_BLOODED|BIO_FLESH) //SKYRAT EDIT - Roundstart Snails - Now invertebrates!
limb_id = SPECIES_SNAIL
unarmed_damage_low = 1 //SKYRAT EDIT - Roundstart Snails - Lowest possible punch damage. if this is set to 0, punches will always miss.
unarmed_damage_high = 5 //snails are soft and squishy //SKYRAT EDIT - Roundstart Snails - A Bit More Damage. - ORIGINAL: unarmed_damage_high = 0.5 //snails are soft and squishy
@@ -48,43 +48,37 @@
///ABDUCTOR
/obj/item/bodypart/head/abductor
biological_state = BIO_INORGANIC //i have no fucking clue why these mfs get no wounds but SURE
limb_id = SPECIES_ABDUCTOR
is_dimorphic = FALSE
should_draw_greyscale = FALSE
head_flags = NONE
/obj/item/bodypart/chest/abductor
biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
is_dimorphic = FALSE
should_draw_greyscale = FALSE
/obj/item/bodypart/arm/left/abductor
biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_CHUNKYFINGERS)
/obj/item/bodypart/arm/right/abductor
biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
bodypart_traits = list(TRAIT_CHUNKYFINGERS)
/obj/item/bodypart/leg/left/abductor
biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
/obj/item/bodypart/leg/right/abductor
biological_state = BIO_INORGANIC
limb_id = SPECIES_ABDUCTOR
should_draw_greyscale = FALSE
///JELLY
/obj/item/bodypart/head/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_JELLYPERSON
is_dimorphic = TRUE
dmg_overlay_type = null
@@ -92,90 +86,90 @@
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_JELLYPERSON
is_dimorphic = TRUE
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/arm/left/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/arm/right/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/leg/left/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
/obj/item/bodypart/leg/right/jelly
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_JELLYPERSON
dmg_overlay_type = null
burn_modifier = 0.5 // = 1/2x generic burn damage
///SLIME
/obj/item/bodypart/head/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
is_dimorphic = FALSE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
is_dimorphic = TRUE
/obj/item/bodypart/arm/left/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/arm/right/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/leg/left/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_SLIMEPERSON
/obj/item/bodypart/leg/right/slime
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_SLIMEPERSON
///LUMINESCENT
/obj/item/bodypart/head/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_LUMINESCENT
is_dimorphic = TRUE
head_flags = HEAD_ALL_FEATURES
/obj/item/bodypart/chest/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED)
limb_id = SPECIES_LUMINESCENT
is_dimorphic = TRUE
/obj/item/bodypart/arm/left/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/arm/right/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/leg/left/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
/obj/item/bodypart/leg/right/luminescent
biological_state = BIO_INORGANIC
biological_state = (BIO_FLESH|BIO_BLOODED|BIO_JOINTED)
limb_id = SPECIES_LUMINESCENT
///ZOMBIE
@@ -282,7 +276,6 @@
///SHADOW
/obj/item/bodypart/head/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
is_dimorphic = FALSE
should_draw_greyscale = FALSE
@@ -290,32 +283,27 @@
head_flags = NONE
/obj/item/bodypart/chest/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
is_dimorphic = FALSE
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/arm/left/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/arm/right/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/leg/left/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
/obj/item/bodypart/leg/right/shadow
biological_state = BIO_INORGANIC
limb_id = SPECIES_SHADOW
should_draw_greyscale = FALSE
burn_modifier = 1.5
@@ -343,25 +331,25 @@
dmg_overlay_type = null
/obj/item/bodypart/arm/left/skeleton
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/arm/right/skeleton
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/leg/left/skeleton
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
/obj/item/bodypart/leg/right/skeleton
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_SKELETON
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -414,7 +402,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_head"
biological_state = BIO_INORGANIC
biological_state = BIO_BONE
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
is_dimorphic = FALSE
@@ -451,7 +439,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_chest"
biological_state = BIO_INORGANIC
biological_state = BIO_BONE
acceptable_bodytype = BODYTYPE_GOLEM
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
@@ -472,7 +460,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_l_arm"
biological_state = BIO_INORGANIC
biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -506,7 +494,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_r_arm"
biological_state = BIO_INORGANIC
biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -540,7 +528,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_l_leg"
biological_state = BIO_INORGANIC
biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -553,7 +541,7 @@
icon = 'icons/mob/human/species/golems.dmi'
icon_static = 'icons/mob/human/species/golems.dmi'
icon_state = "golem_r_leg"
biological_state = BIO_INORGANIC
biological_state = (BIO_BONE|BIO_JOINTED)
bodytype = BODYTYPE_GOLEM | BODYTYPE_ORGANIC
limb_id = SPECIES_GOLEM
should_draw_greyscale = FALSE
@@ -27,7 +27,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_arm"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -38,7 +38,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_arm"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -49,7 +49,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_l_leg"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
@@ -60,7 +60,7 @@
icon = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
icon_state = "plasmaman_r_leg"
icon_static = 'icons/mob/human/species/plasmaman/bodyparts.dmi'
biological_state = BIO_BONE
biological_state = (BIO_BONE|BIO_JOINTED)
limb_id = SPECIES_PLASMAMAN
should_draw_greyscale = FALSE
dmg_overlay_type = null
+76 -38
View File
@@ -8,40 +8,74 @@
var/mangled_state = get_mangled_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 && sharpness)
if(sharpness & SHARP_EDGED)
wounding_type = WOUND_SLASH
else if (sharpness & SHARP_POINTY)
wounding_type = WOUND_PIERCE
var/has_exterior = FALSE
var/has_interior = FALSE
//Handling for bone only/flesh only(none right now)/flesh and bone targets
switch(biological_state)
// if we're bone only, all cutting attacks go straight to the bone
if(BIO_BONE)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
phantom_wounding_dmg *= (easy_dismember ? 1 : 0.6)
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_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) && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
phantom_wounding_dmg *= 0.6 // edged weapons pass along 60% 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_FLESH) && (mangled_state & BODYPART_MANGLED_BONE) && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
for (var/state as anything in GLOB.bio_state_states)
var/flag = text2num(state)
if (!(biological_state & flag))
continue
var/value = GLOB.bio_state_states[state]
if (value & BIO_EXTERIOR)
has_exterior = TRUE
if (value & BIO_INTERIOR)
has_interior = TRUE
if (has_exterior && has_interior)
break
// We put this here so we dont increase init time by doing this all at once on initialization
// Effectively, we "lazy load"
if (isnull(any_existing_wound_can_mangle_our_bone) || isnull(any_existing_wound_can_mangle_our_flesh))
any_existing_wound_can_mangle_our_bone = FALSE
any_existing_wound_can_mangle_our_flesh = FALSE
for (var/datum/wound/wound_type as anything in GLOB.all_wound_pregen_data)
var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[wound_type]
if (!pregen_data.can_be_applied_to(src, random_roll = TRUE)) // we only consider randoms because non-randoms are usually really specific
continue
if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_FLESH)
any_existing_wound_can_mangle_our_flesh = TRUE
if (initial(pregen_data.wound_path_to_generate.wound_flags) & MANGLES_BONE)
any_existing_wound_can_mangle_our_bone = TRUE
if (any_existing_wound_can_mangle_our_bone && any_existing_wound_can_mangle_our_flesh)
break
var/can_theoretically_be_dismembered = (any_existing_wound_can_mangle_our_bone || (any_existing_wound_can_mangle_our_flesh && !has_exterior))
var/exterior_ready_to_dismember = (!has_exterior || ((mangled_state & BODYPART_MANGLED_BONE) == BODYPART_MANGLED_BONE))
var/interior_ready_to_dismember = (!has_interior || ((mangled_state & BODYPART_MANGLED_FLESH) == BODYPART_MANGLED_FLESH))
// if we're bone only, all cutting attacks go straight to the bone
if(has_exterior && interior_ready_to_dismember)
if(wounding_type == WOUND_SLASH)
wounding_type = WOUND_BLUNT
phantom_wounding_dmg *= (easy_dismember ? 1 : 0.6)
else if(wounding_type == WOUND_PIERCE)
wounding_type = WOUND_BLUNT
phantom_wounding_dmg *= (easy_dismember ? 1 : 0.75)
if(exterior_ready_to_dismember && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
return
else
// 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(has_exterior && interior_ready_to_dismember && !(mangled_state & BODYPART_MANGLED_BONE) && sharpness)
playsound(src, "sound/effects/wounds/crackandbleed.ogg", 100)
if(wounding_type == WOUND_SLASH && !easy_dismember)
phantom_wounding_dmg *= 0.6 // edged weapons pass along 60% 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(interior_ready_to_dismember && exterior_ready_to_dismember && try_dismember(wounding_type, phantom_wounding_dmg, wound_bonus, bare_wound_bonus))
return
if (use_alternate_dismemberment_calc_even_if_mangleable || !can_theoretically_be_dismembered)
var/percent_to_total_max = (get_damage() / max_damage)
if (percent_to_total_max >= hp_percent_to_dismemberable)
if (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)
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
@@ -82,7 +116,11 @@
dismembering.apply_dismember(src, woundtype, outright = TRUE, attack_direction = attack_direction)
return
var/list/wounds_checking = GLOB.global_wound_types[woundtype]
var/list/datum/wound/possible_wounds = list()
for (var/datum/wound/type as anything in GLOB.all_wound_pregen_data)
var/datum/wound_pregen_data/pregen_data = GLOB.all_wound_pregen_data[type]
if (pregen_data.can_be_applied_to(src, woundtype, random_roll = TRUE))
possible_wounds += type
// 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
@@ -94,19 +132,19 @@
break
//cycle through the wounds of the relevant category from the most severe down
for(var/datum/wound/possible_wound as anything in wounds_checking)
for(var/datum/wound/possible_wound as anything in possible_wounds)
var/datum/wound/replaced_wound
for(var/datum/wound/existing_wound as anything in wounds)
if(existing_wound.type in wounds_checking)
if(existing_wound.wound_series == initial(possible_wound.wound_series))
if(existing_wound.severity >= initial(possible_wound.severity))
return
else
replaced_wound = existing_wound
replaced_wound = existing_wound // if we find something we keep iterating untilw e're done or we find we're outclassed by something in our series
if(initial(possible_wound.threshold_minimum) < injury_roll)
var/datum/wound/new_wound
if(replaced_wound)
new_wound = replaced_wound.replace_wound(possible_wound, attack_direction = attack_direction)
new_wound = replaced_wound.replace_wound(new possible_wound, attack_direction = attack_direction)
else
new_wound = new possible_wound
new_wound.apply_wound(src, attack_direction = attack_direction, wound_source = damage_source)
@@ -119,9 +157,9 @@
var/datum/wound/potential_wound = specific_woundtype
for(var/datum/wound/existing_wound as anything in wounds)
if(existing_wound.wound_type == initial(potential_wound.wound_type))
if (existing_wound.wound_series == initial(potential_wound.wound_series))
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)
existing_wound.replace_wound(new potential_wound, smited)
return
var/datum/wound/new_wound = new potential_wound
+2 -2
View File
@@ -5,7 +5,7 @@
/datum/surgery/repair_bone_hairline
name = "Repair bone fracture (hairline)"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
targetable_wound = /datum/wound/blunt/severe
targetable_wound = /datum/wound/blunt/bone/severe
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
@@ -31,7 +31,7 @@
/datum/surgery/repair_bone_compound
name = "Repair Compound Fracture"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
targetable_wound = /datum/wound/blunt/critical
targetable_wound = /datum/wound/blunt/bone/critical
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
+8 -8
View File
@@ -5,7 +5,7 @@
/datum/surgery/debride
name = "Debride burnt flesh"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
targetable_wound = /datum/wound/burn
targetable_wound = /datum/wound/burn/flesh
possible_locs = list(
BODY_ZONE_R_ARM,
BODY_ZONE_L_ARM,
@@ -24,7 +24,7 @@
return FALSE
if(..())
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
var/datum/wound/burn/burn_wound = targeted_bodypart.get_wound_type(targetable_wound)
var/datum/wound/burn/flesh/burn_wound = targeted_bodypart.get_wound_type(targetable_wound)
return(burn_wound && burn_wound.infestation > 0)
//SURGERY STEPS
@@ -48,7 +48,7 @@
var/infestation_removed = 4
/// To give the surgeon a heads up how much work they have ahead of them
/datum/surgery_step/debride/proc/get_progress(mob/user, mob/living/carbon/target, datum/wound/burn/burn_wound)
/datum/surgery_step/debride/proc/get_progress(mob/user, mob/living/carbon/target, datum/wound/burn/flesh/burn_wound)
if(!burn_wound?.infestation || !infestation_removed)
return
var/estimated_remaining_steps = burn_wound.infestation / infestation_removed
@@ -68,7 +68,7 @@
/datum/surgery_step/debride/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(surgery.operated_wound)
var/datum/wound/burn/burn_wound = surgery.operated_wound
var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound.infestation <= 0)
to_chat(user, span_notice("[target]'s [parse_zone(user.zone_selected)] has no infected flesh to remove!"))
surgery.status++
@@ -86,7 +86,7 @@
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
/datum/surgery_step/debride/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/datum/wound/burn/burn_wound = surgery.operated_wound
var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
var/progress_text = get_progress(user, target, burn_wound)
display_results(
@@ -120,7 +120,7 @@
/datum/surgery_step/debride/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
if(!..())
return
var/datum/wound/burn/burn_wound = surgery.operated_wound
var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
while(burn_wound && burn_wound.infestation > 0.25)
if(!..())
break
@@ -139,7 +139,7 @@
/datum/surgery_step/dress/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/datum/wound/burn/burn_wound = surgery.operated_wound
var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
display_results(
user,
@@ -153,7 +153,7 @@
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
/datum/surgery_step/dress/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
var/datum/wound/burn/burn_wound = surgery.operated_wound
var/datum/wound/burn/flesh/burn_wound = surgery.operated_wound
if(burn_wound)
display_results(
user,
+6 -6
View File
@@ -9,7 +9,7 @@
/datum/surgery/repair_puncture
name = "Repair puncture"
surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB
targetable_wound = /datum/wound/pierce
targetable_wound = /datum/wound/pierce/bleed
target_mobtypes = list(/mob/living/carbon)
possible_locs = list(
BODY_ZONE_R_ARM,
@@ -32,7 +32,7 @@
. = ..()
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)
var/datum/wound/burn/flesh/pierce_wound = targeted_bodypart.get_wound_type(targetable_wound)
return(pierce_wound && pierce_wound.blood_flow > 0)
//SURGERY STEPS
@@ -47,7 +47,7 @@
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
var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
return
@@ -67,7 +67,7 @@
display_pain(target, "You feel a horrible stabbing pain in your [parse_zone(user.zone_selected)]!")
/datum/surgery_step/repair_innards/success(mob/living/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
var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, span_warning("[target] has no puncture wound there!"))
return ..()
@@ -112,7 +112,7 @@
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
var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]..."))
return
@@ -126,7 +126,7 @@
display_pain(target, "You're being burned inside your [parse_zone(user.zone_selected)]!")
/datum/surgery_step/seal_veins/success(mob/living/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
var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound
if(!pierce_wound)
to_chat(user, span_warning("[target] has no puncture there!"))
return ..()