Merge branch 'master' into cool-ipcs
This commit is contained in:
@@ -25,12 +25,12 @@
|
||||
return TRUE
|
||||
/datum/surgery_step/revive
|
||||
name = "electrically stimulate brain"
|
||||
implements = list(/obj/item/twohanded/shockpaddles = 100, /obj/item/abductor/gizmo = 100, /obj/item/melee/baton = 75, /obj/item/organ/cyberimp/arm/baton = 75, /obj/item/organ/cyberimp/arm/gun/taser = 60, /obj/item/gun/energy/e_gun/advtaser = 60, /obj/item/gun/energy/taser = 60)
|
||||
implements = list(/obj/item/shockpaddles = 100, /obj/item/abductor/gizmo = 100, /obj/item/melee/baton = 75, /obj/item/organ/cyberimp/arm/baton = 75, /obj/item/organ/cyberimp/arm/gun/taser = 60, /obj/item/gun/energy/e_gun/advtaser = 60, /obj/item/gun/energy/taser = 60)
|
||||
time = 120
|
||||
/datum/surgery_step/revive/tool_check(mob/user, obj/item/tool)
|
||||
. = TRUE
|
||||
if(istype(tool, /obj/item/twohanded/shockpaddles))
|
||||
var/obj/item/twohanded/shockpaddles/S = tool
|
||||
if(istype(tool, /obj/item/shockpaddles))
|
||||
var/obj/item/shockpaddles/S = tool
|
||||
if((S.req_defib && !S.defib.powered) || !S.wielded || S.cooldown || S.busy)
|
||||
to_chat(user, "<span class='warning'>You need to wield both paddles, and [S.defib] must be powered!</span>")
|
||||
return FALSE
|
||||
@@ -60,6 +60,7 @@
|
||||
playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1)
|
||||
target.adjustOxyLoss(-50, 0)
|
||||
target.updatehealth()
|
||||
var/tplus = world.time - target.timeofdeath
|
||||
if(target.revive())
|
||||
user.visible_message("...[target] wakes up, alive and aware!", "<span class='notice'><b>IT'S ALIVE!</b></span>")
|
||||
target.visible_message("...[target] wakes up, alive and aware!")
|
||||
@@ -68,6 +69,13 @@
|
||||
for(var/obj/item/organ/O in target.internal_organs)//zap those buggers back to life!
|
||||
if(O.organ_flags & ORGAN_FAILING)
|
||||
O.applyOrganDamage(-5)
|
||||
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
|
||||
var/timelimit = CONFIG_GET(number/defib_cmd_time_limit)
|
||||
var/late = timelimit && (tplus > timelimit)
|
||||
var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
|
||||
if(policy)
|
||||
to_chat(target, policy)
|
||||
target.log_message("revived using surgical revival, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
|
||||
return TRUE
|
||||
else
|
||||
user.visible_message("...[target.p_they()] convulses, then lies still.")
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
requires_bodypart_type = 0
|
||||
/datum/surgery_step/sever_limb
|
||||
name = "sever limb"
|
||||
implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
|
||||
implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
|
||||
time = 64
|
||||
|
||||
/datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
|
||||
+362
-299
@@ -73,6 +73,28 @@
|
||||
|
||||
var/render_like_organic = FALSE // forces limb to render as if it were an organic limb
|
||||
|
||||
/// 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
|
||||
/// 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)
|
||||
. = ..()
|
||||
if(brute_dam > DAMAGE_PRECISION)
|
||||
@@ -131,8 +153,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)
|
||||
@@ -151,7 +185,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 = SHARP_NONE) // 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)
|
||||
@@ -165,20 +199,82 @@
|
||||
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
|
||||
|
||||
/*
|
||||
// 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)
|
||||
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()
|
||||
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
|
||||
|
||||
brute_dam += brute
|
||||
burn_dam += burn
|
||||
|
||||
@@ -198,6 +294,165 @@
|
||||
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 [/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_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
|
||||
*/
|
||||
/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
|
||||
else
|
||||
damage = min(damage, WOUND_MAX_CONSIDERED_DAMAGE)
|
||||
|
||||
var/base_roll = rand(max(damage/1.5,25), 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 = GLOB.global_wound_types[woundtype]
|
||||
|
||||
// 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)
|
||||
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)
|
||||
var/datum/wound/new_wound
|
||||
if(replaced_wound)
|
||||
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
|
||||
new_wound = new possible_wound
|
||||
new_wound.apply_wound(src)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
|
||||
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.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
|
||||
|
||||
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
|
||||
|
||||
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_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)
|
||||
|
||||
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(get_damage(TRUE) >= max_damage)
|
||||
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)
|
||||
@@ -229,16 +484,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(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() || 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
|
||||
return BODYPART_NOT_DISABLED
|
||||
else
|
||||
return BODYPART_NOT_DISABLED
|
||||
@@ -253,9 +521,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()
|
||||
@@ -330,22 +600,21 @@
|
||||
|
||||
var/datum/species/S = H.dna.species
|
||||
base_bp_icon = S?.icon_limbs || DEFAULT_BODYPART_ICON
|
||||
species_id = S.limbs_id
|
||||
species_id = S.mutant_bodyparts["limbs_id"]
|
||||
species_flags_list = H.dna.species.species_traits
|
||||
|
||||
//body marking memes
|
||||
var/list/colorlist = list()
|
||||
colorlist.Cut()
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor2"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor3"]]0")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor"]]00")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor2"]]00")
|
||||
colorlist += ReadRGB("[H.dna.features["mcolor3"]]00")
|
||||
colorlist += list(0,0,0, S.hair_alpha)
|
||||
for(var/index=1, index<=colorlist.len, index++)
|
||||
colorlist[index] = colorlist[index]/255
|
||||
|
||||
if(S.use_skintones)
|
||||
skin_tone = H.skin_tone
|
||||
base_bp_icon = (base_bp_icon == DEFAULT_BODYPART_ICON) ? DEFAULT_BODYPART_ICON_ORGANIC : base_bp_icon
|
||||
else
|
||||
skin_tone = ""
|
||||
|
||||
@@ -358,13 +627,9 @@
|
||||
species_color = S.fixed_mut_color
|
||||
else
|
||||
species_color = H.dna.features["mcolor"]
|
||||
base_bp_icon = (base_bp_icon == DEFAULT_BODYPART_ICON) ? DEFAULT_BODYPART_ICON_ORGANIC : base_bp_icon
|
||||
else
|
||||
species_color = ""
|
||||
|
||||
if(base_bp_icon != DEFAULT_BODYPART_ICON)
|
||||
color_src = mut_colors ? MUTCOLORS : ((H.dna.skin_tone_override && S.use_skintones == USE_SKINTONES_GRAYSCALE_CUSTOM) ? CUSTOM_SKINTONE : SKINTONE)
|
||||
|
||||
if(S.mutant_bodyparts["legs"])
|
||||
if(body_zone == BODY_ZONE_L_LEG || body_zone == BODY_ZONE_R_LEG)
|
||||
if(DIGITIGRADE in S.species_traits)
|
||||
@@ -384,11 +649,16 @@
|
||||
body_markings = "plain"
|
||||
aux_marking = "plain"
|
||||
markings_color = list(colorlist)
|
||||
|
||||
else
|
||||
body_markings = null
|
||||
aux_marking = null
|
||||
|
||||
if(species_id in GLOB.greyscale_limb_types) //should they have greyscales?
|
||||
base_bp_icon = DEFAULT_BODYPART_ICON_ORGANIC
|
||||
|
||||
if(base_bp_icon != DEFAULT_BODYPART_ICON)
|
||||
color_src = mut_colors ? MUTCOLORS : ((H.dna.skin_tone_override && S.use_skintones == USE_SKINTONES_GRAYSCALE_CUSTOM) ? CUSTOM_SKINTONE : SKINTONE)
|
||||
|
||||
if(!dropping_limb && H.dna.check_mutation(HULK))
|
||||
mutation_color = "00aa00"
|
||||
else
|
||||
@@ -584,293 +854,86 @@
|
||||
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 = 4
|
||||
|
||||
/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/i in wounds)
|
||||
if(istype(i, checking_type))
|
||||
return i
|
||||
|
||||
/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
|
||||
/**
|
||||
* 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
|
||||
// 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
|
||||
|
||||
/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
|
||||
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()
|
||||
|
||||
/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 = 4
|
||||
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++
|
||||
|
||||
//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
|
||||
if(owner.mobility_flags & ~MOBILITY_STAND)
|
||||
bleed_rate *= 0.75
|
||||
return bleed_rate
|
||||
|
||||
/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 = 4
|
||||
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)
|
||||
/**
|
||||
* 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
|
||||
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>")
|
||||
QDEL_NULL(current_gauze)
|
||||
current_gauze = new gauze.type(src, 1)
|
||||
gauze.use(1)
|
||||
|
||||
|
||||
/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 = 4
|
||||
|
||||
/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)
|
||||
/**
|
||||
* 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
|
||||
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
|
||||
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
|
||||
@@ -15,8 +15,9 @@
|
||||
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
|
||||
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
|
||||
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
|
||||
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,14 +82,13 @@
|
||||
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)
|
||||
/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.
|
||||
@@ -143,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)
|
||||
@@ -298,6 +353,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()
|
||||
|
||||
@@ -359,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)
|
||||
@@ -367,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
|
||||
|
||||
@@ -35,8 +35,11 @@
|
||||
//If the head is a special sprite
|
||||
var/custom_head
|
||||
|
||||
wound_resistance = 10
|
||||
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 ..()
|
||||
|
||||
|
||||
@@ -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,289 @@
|
||||
/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()) || !get_organs())
|
||||
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(!.)
|
||||
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()
|
||||
|
||||
/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
|
||||
|
||||
/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(!.)
|
||||
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()
|
||||
|
||||
|
||||
/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
|
||||
|
||||
/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
|
||||
@@ -0,0 +1,139 @@
|
||||
|
||||
/////BONE FIXING SURGERIES//////
|
||||
|
||||
///// Repair Hairline Fracture (Severe)
|
||||
/datum/surgery/repair_bone_hairline
|
||||
name = "Repair bone fracture (hairline)"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/repair_bone_hairline, /datum/surgery_step/close)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
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/blunt/severe
|
||||
|
||||
/datum/surgery/repair_bone_hairline/can_start(mob/living/user, mob/living/carbon/target)
|
||||
if(..())
|
||||
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
|
||||
return(targeted_bodypart.get_wound_type(targetable_wound))
|
||||
|
||||
|
||||
///// Repair Compound Fracture (Critical)
|
||||
/datum/surgery/repair_bone_compound
|
||||
name = "Repair Compound Fracture"
|
||||
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/reset_compound_fracture, /datum/surgery_step/repair_bone_compound, /datum/surgery_step/close)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
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/blunt/critical
|
||||
|
||||
/datum/surgery/repair_bone_compound/can_start(mob/living/user, mob/living/carbon/target)
|
||||
if(..())
|
||||
var/obj/item/bodypart/targeted_bodypart = target.get_bodypart(user.zone_selected)
|
||||
return(targeted_bodypart.get_wound_type(targetable_wound))
|
||||
|
||||
|
||||
|
||||
//SURGERY STEPS
|
||||
|
||||
///// Repair Hairline Fracture (Severe)
|
||||
/datum/surgery_step/repair_bone_hairline
|
||||
name = "repair hairline fracture (bonesetter/bone gel/tape)"
|
||||
implements = list(/obj/item/bonesetter = 100, /obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30)
|
||||
time = 40
|
||||
|
||||
/datum/surgery_step/repair_bone_hairline/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(surgery.operated_wound)
|
||||
display_results(user, target, "<span class='notice'>You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"<span class='notice'>[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
|
||||
"<span class='notice'>[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].</span>")
|
||||
else
|
||||
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>")
|
||||
|
||||
/datum/surgery_step/repair_bone_hairline/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
|
||||
if(surgery.operated_wound)
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
display_results(user, target, "<span class='notice'>You successfully repair the fracture in [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'>[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!</span>")
|
||||
log_combat(user, target, "repaired a hairline fracture in", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
qdel(surgery.operated_wound)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no hairline fracture there!</span>")
|
||||
return ..()
|
||||
|
||||
/datum/surgery_step/repair_bone_hairline/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
|
||||
..()
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
|
||||
|
||||
|
||||
///// Reset Compound Fracture (Crticial)
|
||||
/datum/surgery_step/reset_compound_fracture
|
||||
name = "reset bone"
|
||||
implements = list(/obj/item/bonesetter = 100, /obj/item/stack/sticky_tape/surgical = 60, /obj/item/stack/sticky_tape/super = 40, /obj/item/stack/sticky_tape = 20)
|
||||
time = 40
|
||||
|
||||
/datum/surgery_step/reset_compound_fracture/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(surgery.operated_wound)
|
||||
display_results(user, target, "<span class='notice'>You begin to reset the bone in [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"<span class='notice'>[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
|
||||
"<span class='notice'>[user] begins to reset the bone in [target]'s [parse_zone(user.zone_selected)].</span>")
|
||||
else
|
||||
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>")
|
||||
|
||||
/datum/surgery_step/reset_compound_fracture/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
|
||||
if(surgery.operated_wound)
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
display_results(user, target, "<span class='notice'>You successfully reset the bone in [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'>[user] successfully resets the bone in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] successfully resets the bone in [target]'s [parse_zone(target_zone)]!</span>")
|
||||
log_combat(user, target, "reset a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no compound fracture there!</span>")
|
||||
return ..()
|
||||
|
||||
/datum/surgery_step/reset_compound_fracture/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
|
||||
..()
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
|
||||
|
||||
///// Repair Compound Fracture (Crticial)
|
||||
/datum/surgery_step/repair_bone_compound
|
||||
name = "repair compound fracture (bone gel/tape)"
|
||||
implements = list(/obj/item/stack/medical/bone_gel = 100, /obj/item/stack/sticky_tape/surgical = 100, /obj/item/stack/sticky_tape/super = 50, /obj/item/stack/sticky_tape = 30)
|
||||
time = 40
|
||||
|
||||
/datum/surgery_step/repair_bone_compound/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(surgery.operated_wound)
|
||||
display_results(user, target, "<span class='notice'>You begin to repair the fracture in [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"<span class='notice'>[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
|
||||
"<span class='notice'>[user] begins to repair the fracture in [target]'s [parse_zone(user.zone_selected)].</span>")
|
||||
else
|
||||
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>")
|
||||
|
||||
/datum/surgery_step/repair_bone_compound/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE)
|
||||
if(surgery.operated_wound)
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
display_results(user, target, "<span class='notice'>You successfully repair the fracture in [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'>[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!</span>")
|
||||
log_combat(user, target, "repaired a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
qdel(surgery.operated_wound)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no compound fracture there!</span>")
|
||||
return ..()
|
||||
|
||||
/datum/surgery_step/repair_bone_compound/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
|
||||
..()
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
/////BURN FIXING SURGERIES//////
|
||||
|
||||
///// Debride burnt flesh
|
||||
/datum/surgery/debride
|
||||
name = "Debride infected flesh"
|
||||
steps = list(/datum/surgery_step/debride, /datum/surgery_step/dress)
|
||||
target_mobtypes = list(/mob/living/carbon/human)
|
||||
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/burn
|
||||
|
||||
/datum/surgery/debride/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/burn_wound = targeted_bodypart.get_wound_type(targetable_wound)
|
||||
return(burn_wound && burn_wound.infestation > 0)
|
||||
|
||||
//SURGERY STEPS
|
||||
|
||||
///// Debride
|
||||
/datum/surgery_step/debride
|
||||
name = "excise infection"
|
||||
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCALPEL = 85, TOOL_SAW = 60, TOOL_WIRECUTTER = 40)
|
||||
time = 30
|
||||
repeatable = TRUE
|
||||
|
||||
/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
|
||||
if(burn_wound.infestation <= 0)
|
||||
to_chat(user, "<span class='notice'>[target]'s [parse_zone(user.zone_selected)] has no infected flesh to remove!</span>")
|
||||
surgery.status++
|
||||
repeatable = FALSE
|
||||
return
|
||||
display_results(user, target, "<span class='notice'>You begin to excise infected flesh from [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"<span class='notice'>[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
|
||||
"<span class='notice'>[user] begins to excise infected flesh from [target]'s [parse_zone(user.zone_selected)].</span>")
|
||||
else
|
||||
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>")
|
||||
|
||||
/datum/surgery_step/debride/success(mob/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
|
||||
if(burn_wound)
|
||||
display_results(user, target, "<span class='notice'>You successfully excise some of the infected flesh from [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'>[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] successfully excises some of the infected flesh from [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)
|
||||
burn_wound.infestation -= 0.5
|
||||
burn_wound.sanitization += 0.5
|
||||
if(burn_wound.infestation <= 0)
|
||||
repeatable = FALSE
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[target] has no infected flesh there!</span>")
|
||||
return ..()
|
||||
|
||||
/datum/surgery_step/debride/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 carve away some of the healthy flesh from [target]'s [parse_zone(target_zone)].</span>",
|
||||
"<span class='notice'>[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] carves away some of the healthy flesh from [target]'s [parse_zone(target_zone)]!</span>")
|
||||
surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=TRUE)
|
||||
|
||||
/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
|
||||
while(burn_wound && burn_wound.infestation > 0.25)
|
||||
if(!..())
|
||||
break
|
||||
|
||||
///// Dressing burns
|
||||
/datum/surgery_step/dress
|
||||
name = "bandage burns"
|
||||
implements = list(/obj/item/stack/medical/gauze = 100, /obj/item/stack/sticky_tape/surgical = 100)
|
||||
time = 40
|
||||
|
||||
/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
|
||||
if(burn_wound)
|
||||
display_results(user, target, "<span class='notice'>You begin to dress the burns on [target]'s [parse_zone(user.zone_selected)]...</span>",
|
||||
"<span class='notice'>[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)] with [tool].</span>",
|
||||
"<span class='notice'>[user] begins to dress the burns on [target]'s [parse_zone(user.zone_selected)].</span>")
|
||||
else
|
||||
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>")
|
||||
|
||||
/datum/surgery_step/dress/success(mob/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
|
||||
if(burn_wound)
|
||||
display_results(user, target, "<span class='notice'>You successfully wrap [target]'s [parse_zone(target_zone)] with [tool].</span>",
|
||||
"<span class='notice'>[user] successfully wraps [target]'s [parse_zone(target_zone)] with [tool]!</span>",
|
||||
"<span class='notice'>[user] successfully wraps [target]'s [parse_zone(target_zone)]!</span>")
|
||||
log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]")
|
||||
burn_wound.sanitization += 3
|
||||
burn_wound.flesh_healing += 5
|
||||
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 ..()
|
||||
|
||||
/datum/surgery_step/dress/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, var/fail_prob = 0)
|
||||
..()
|
||||
if(istype(tool, /obj/item/stack))
|
||||
var/obj/item/stack/used_stack = tool
|
||||
used_stack.use(1)
|
||||
@@ -32,7 +32,8 @@
|
||||
display_results(user, target, "<span class='notice'>Blood pools around the incision in [H]'s heart.</span>",
|
||||
"Blood pools around the incision in [H]'s heart.",
|
||||
"")
|
||||
H.bleed_rate += 10
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(target_zone)
|
||||
BP.generic_bleedstacks += 10
|
||||
H.adjustBruteLoss(10)
|
||||
return TRUE
|
||||
|
||||
@@ -42,7 +43,8 @@
|
||||
display_results(user, target, "<span class='warning'>You screw up, cutting too deeply into the heart!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest!</span>")
|
||||
H.bleed_rate += 20
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(target_zone)
|
||||
BP.generic_bleedstacks += 10
|
||||
H.adjustOrganLoss(ORGAN_SLOT_HEART, 10)
|
||||
H.adjustBruteLoss(10)
|
||||
|
||||
@@ -74,5 +76,6 @@
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest profusely!</span>",
|
||||
"<span class='warning'>[user] screws up, causing blood to spurt out of [H]'s chest profusely!</span>")
|
||||
H.adjustOrganLoss(ORGAN_SLOT_HEART, 20)
|
||||
H.bleed_rate += 30
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(target_zone)
|
||||
BP.generic_bleedstacks += 30
|
||||
return FALSE
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
/datum/surgery_step/ventricular_electrotherapy
|
||||
name = "ventricular electrotherapy"
|
||||
implements = list(/obj/item/twohanded/shockpaddles = 90, /obj/item/defibrillator = 75, /obj/item/inducer = 55, /obj/item/stock_parts/cell = 25) //Just because the idea of a new player using the whole magine to defib is hillarious to me
|
||||
implements = list(/obj/item/shockpaddles = 90, /obj/item/defibrillator = 75, /obj/item/inducer = 55, /obj/item/stock_parts/cell = 25) //Just because the idea of a new player using the whole magine to defib is hillarious to me
|
||||
time = 50
|
||||
repeatable = TRUE //So you can retry
|
||||
|
||||
/datum/surgery_step/ventricular_electrotherapy/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(istype(tool, /obj/item/twohanded/shockpaddles))
|
||||
var/obj/item/twohanded/shockpaddles/pads = tool
|
||||
if(istype(tool, /obj/item/shockpaddles))
|
||||
var/obj/item/shockpaddles/pads = tool
|
||||
if(!pads.wielded)
|
||||
to_chat(user, "<span class='warning'>You need to wield the paddles in both hands before you can use them!</span>")
|
||||
return FALSE
|
||||
@@ -24,8 +24,8 @@
|
||||
playsound(src, 'sound/machines/defib_charge.ogg', 75, 0)
|
||||
|
||||
/datum/surgery_step/ventricular_electrotherapy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(istype(tool, /obj/item/twohanded/shockpaddles))
|
||||
var/obj/item/twohanded/shockpaddles/pads = tool
|
||||
if(istype(tool, /obj/item/shockpaddles))
|
||||
var/obj/item/shockpaddles/pads = tool
|
||||
if(!pads.wielded)
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = target
|
||||
@@ -53,7 +53,7 @@
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
|
||||
H.electrocute_act(0, (tool), 1, SHOCK_ILLUSION)
|
||||
//If we're using a defib, let the defib handle the revive.
|
||||
if(istype(tool, /obj/item/twohanded/shockpaddles))
|
||||
if(istype(tool, /obj/item/shockpaddles))
|
||||
return
|
||||
//Otherwise, we're ad hocing it
|
||||
if(!(do_after(user, 50, target = target)))
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"[user] dissects [target]!")
|
||||
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned))
|
||||
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
|
||||
target.apply_damage(80, BRUTE, L)
|
||||
target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND)
|
||||
ADD_TRAIT(target, TRAIT_DISSECTED, "[surgery.name]")
|
||||
repeatable = FALSE
|
||||
return TRUE
|
||||
@@ -89,7 +89,7 @@
|
||||
"[user] dissects [target], but looks a little dissapointed.")
|
||||
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (round(check_value(target, surgery) * 0.01))))
|
||||
var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
|
||||
target.apply_damage(80, BRUTE, L)
|
||||
target.apply_damage(80, BRUTE, L, wound_bonus=CANT_WOUND)
|
||||
return TRUE
|
||||
|
||||
/datum/surgery/advanced/experimental_dissection/adv
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1)
|
||||
urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1)
|
||||
|
||||
target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn)
|
||||
target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn, wound_bonus=CANT_WOUND)
|
||||
return FALSE
|
||||
|
||||
/***************************BRUTE***************************/
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
time = 64
|
||||
name = "manipulate organs"
|
||||
repeatable = 1
|
||||
implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100)
|
||||
implements = list(/obj/item/organ = 100, /obj/item/organ_storage = 100)
|
||||
var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55)
|
||||
var/current_type
|
||||
var/obj/item/organ/I = null
|
||||
@@ -86,6 +86,10 @@
|
||||
if(target_zone != I.zone || target.getorganslot(I.slot))
|
||||
to_chat(user, "<span class='notice'>There is no room for [I] in [target]'s [parse_zone(target_zone)]!</span>")
|
||||
return -1
|
||||
var/obj/item/organ/meatslab = tool
|
||||
if(!meatslab.useable)
|
||||
to_chat(user, "<span class='warning'>[I] seems to have been chewed on, you can't use this!</span>")
|
||||
return -1
|
||||
display_results(user, target, "<span class='notice'>You begin to insert [tool] into [target]'s [parse_zone(target_zone)]...</span>",
|
||||
"[user] begins to insert [tool] into [target]'s [parse_zone(target_zone)].",
|
||||
"[user] begins to insert something into [target]'s [parse_zone(target_zone)].")
|
||||
@@ -112,9 +116,6 @@
|
||||
else
|
||||
return -1
|
||||
|
||||
else if(istype(tool, /obj/item/reagent_containers/food/snacks/organ))
|
||||
to_chat(user, "<span class='warning'>[tool] was bitten by someone! It's too damaged to use!</span>")
|
||||
return -1
|
||||
/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
if(current_type == "insert")
|
||||
if(istype(tool, /obj/item/organ_storage))
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
display_results(user, target, "<span class='notice'>Blood pools around the incision in [H]'s [parse_zone(target_zone)].</span>",
|
||||
"Blood pools around the incision in [H]'s [parse_zone(target_zone)].",
|
||||
"")
|
||||
H.bleed_rate += 3
|
||||
var/obj/item/bodypart/BP = target.get_bodypart(target_zone)
|
||||
if(BP)
|
||||
BP.generic_bleedstacks += 10
|
||||
return TRUE
|
||||
|
||||
/datum/surgery_step/incise/nobleed //silly friendly!
|
||||
@@ -50,7 +52,9 @@
|
||||
target.heal_bodypart_damage(20,0)
|
||||
if (ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.bleed_rate = max( (H.bleed_rate - 3), 0)
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(target_zone)
|
||||
if(BP)
|
||||
BP.generic_bleedstacks -= 3
|
||||
return ..()
|
||||
//retract skin
|
||||
/datum/surgery_step/retract_skin
|
||||
@@ -86,12 +90,14 @@
|
||||
target.heal_bodypart_damage(45,0)
|
||||
if (ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
H.bleed_rate = max( (H.bleed_rate - 3), 0)
|
||||
var/obj/item/bodypart/BP = H.get_bodypart(target_zone)
|
||||
if(BP)
|
||||
BP.generic_bleedstacks -= 3
|
||||
return ..()
|
||||
//saw bone
|
||||
/datum/surgery_step/saw
|
||||
name = "saw bone"
|
||||
implements = list(TOOL_SAW = 100, /obj/item/melee/arm_blade = 75, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
|
||||
implements = list(TOOL_SAW = 100, /obj/item/melee/arm_blade = 75, /obj/item/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
|
||||
time = 54
|
||||
|
||||
/datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
@@ -100,7 +106,7 @@
|
||||
"[user] begins to saw through the bone in [target]'s [parse_zone(target_zone)].")
|
||||
|
||||
/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
target.apply_damage(50, BRUTE, "[target_zone]")
|
||||
target.apply_damage(50, BRUTE, "[target_zone]", wound_bonus=CANT_WOUND)
|
||||
display_results(user, target, "<span class='notice'>You saw [target]'s [parse_zone(target_zone)] open.</span>",
|
||||
"[user] saws [target]'s [parse_zone(target_zone)] open!",
|
||||
"[user] saws [target]'s [parse_zone(target_zone)] open!")
|
||||
|
||||
@@ -37,9 +37,3 @@
|
||||
..()
|
||||
if(inflamed)
|
||||
M.ForceContractDisease(new /datum/disease/appendicitis(), FALSE, TRUE)
|
||||
|
||||
/obj/item/organ/appendix/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
if(inflamed)
|
||||
S.reagents.add_reagent(/datum/reagent/toxin/bad_food, 5)
|
||||
return S
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"<span class='notice'>You extend [holder] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.</span>",
|
||||
"<span class='italics'>You hear a short mechanical noise.</span>")
|
||||
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/organ/cyberimp/arm/ui_action_click()
|
||||
if(crit_fail || (organ_flags & ORGAN_FAILING) || (!holder && !contents.len))
|
||||
@@ -273,12 +274,29 @@
|
||||
desc = "A deployable riot shield to help deal with civil unrest."
|
||||
contents = newlist(/obj/item/shield/riot/implant)
|
||||
|
||||
/obj/item/organ/cyberimp/arm/shield/Extend(obj/item/I)
|
||||
/obj/item/organ/cyberimp/arm/shield/Extend(obj/item/I, silent = FALSE)
|
||||
if(I.obj_integrity == 0) //that's how the shield recharge works
|
||||
to_chat(owner, "<span class='warning'>[I] is still too unstable to extend. Give it some time!</span>")
|
||||
if(!silent)
|
||||
to_chat(owner, "<span class='warning'>[I] is still too unstable to extend. Give it some time!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/cyberimp/arm/shield/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
RegisterSignal(M, COMSIG_LIVING_ACTIVE_BLOCK_START, .proc/on_signal)
|
||||
|
||||
/obj/item/organ/cyberimp/arm/shield/Remove(special = FALSE)
|
||||
UnregisterSignal(owner, COMSIG_LIVING_ACTIVE_BLOCK_START)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/cyberimp/arm/shield/proc/on_signal(datum/source, obj/item/blocking_item, list/other_items)
|
||||
if(!blocking_item) //if they don't have something
|
||||
var/obj/item/shield/S = locate() in contents
|
||||
if(!Extend(S, TRUE))
|
||||
return
|
||||
other_items += S
|
||||
|
||||
/obj/item/organ/cyberimp/arm/shield/emag_act()
|
||||
. = ..()
|
||||
if(obj_flags & EMAGGED)
|
||||
|
||||
@@ -265,6 +265,10 @@
|
||||
var/C = input(owner, "Select Color", "Select color", "#ffffff") as color|null
|
||||
if(!C || QDELETED(src) || QDELETED(user) || QDELETED(owner) || owner != user)
|
||||
return
|
||||
var/list/hsv = ReadHSV(RGBtoHSV(C))
|
||||
if(hsv[2] > 125)
|
||||
to_chat(user, "<span class='warning'>A color that saturated? Surely not!</span>")
|
||||
return
|
||||
var/range = input(user, "Enter range (0 - [max_light_beam_distance])", "Range Select", 0) as null|num
|
||||
if(!isnum(range))
|
||||
return
|
||||
@@ -405,4 +409,4 @@
|
||||
|
||||
#undef BLURRY_VISION_ONE
|
||||
#undef BLURRY_VISION_TWO
|
||||
#undef BLIND_VISION_THREE
|
||||
#undef BLIND_VISION_THREE
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
return "a healthy"
|
||||
return "<span class='danger'>an unstable</span>"
|
||||
|
||||
/obj/item/organ/heart/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.icon_state = "[icon_base]-off"
|
||||
return S
|
||||
/obj/item/organ/heart/OnEatFrom(eater, feeder)
|
||||
. = ..()
|
||||
beating = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/item/organ/heart/on_life()
|
||||
. = ..()
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
|
||||
var/filterToxins = TRUE //whether to filter toxins
|
||||
var/cachedmoveCalc = 1
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/iron = 5)
|
||||
|
||||
/obj/item/organ/liver/on_life()
|
||||
. = ..()
|
||||
@@ -44,11 +45,6 @@
|
||||
if(damage > 10 && prob(damage/3))//the higher the damage the higher the probability
|
||||
to_chat(owner, "<span class='warning'>You feel a dull pain in your abdomen.</span>")
|
||||
|
||||
/obj/item/organ/liver/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent(/datum/reagent/iron, 5)
|
||||
return S
|
||||
|
||||
/obj/item/organ/liver/applyOrganDamage(d, maximum = maxHealth)
|
||||
. = ..()
|
||||
if(!. || QDELETED(owner))
|
||||
@@ -77,8 +73,8 @@
|
||||
/obj/item/organ/liver/proc/sizeMoveMod(value, mob/living/carbon/C)
|
||||
if(cachedmoveCalc == value)
|
||||
return
|
||||
C.next_move_modifier /= cachedmoveCalc
|
||||
C.next_move_modifier *= value
|
||||
C.action_cooldown_mod /= cachedmoveCalc
|
||||
C.action_cooldown_mod *= value
|
||||
cachedmoveCalc = value
|
||||
|
||||
/obj/item/organ/liver/fly
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
now_fixed = "<span class='warning'>Your lungs seem to once again be able to hold air.</span>"
|
||||
high_threshold_cleared = "<span class='info'>The constriction around your chest loosens as your breathing calms down.</span>"
|
||||
|
||||
food_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/salbutamol = 5)
|
||||
|
||||
//Breath damage
|
||||
|
||||
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
|
||||
@@ -131,13 +133,11 @@
|
||||
|
||||
var/gas_breathed = 0
|
||||
|
||||
var/list/breath_gases = breath.gases
|
||||
|
||||
//Partial pressures in our breath
|
||||
var/O2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/oxygen])+(8*breath.get_breath_partial_pressure(breath_gases[/datum/gas/pluoxium]))
|
||||
var/N2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrogen])
|
||||
var/Toxins_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/plasma])
|
||||
var/CO2_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/carbon_dioxide])
|
||||
var/O2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/oxygen))+(8*breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/pluoxium)))
|
||||
var/N2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrogen))
|
||||
var/Toxins_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
|
||||
var/CO2_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/carbon_dioxide))
|
||||
|
||||
|
||||
//-- OXY --//
|
||||
@@ -145,7 +145,7 @@
|
||||
//Too much oxygen! //Yes, some species may not like it.
|
||||
if(safe_oxygen_max)
|
||||
if((O2_pp > safe_oxygen_max) && safe_oxygen_max == 0) //I guess plasma men technically need to have a check.
|
||||
var/ratio = (breath_gases[/datum/gas/oxygen]/safe_oxygen_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/oxygen)/safe_oxygen_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, oxy_breath_dam_min, oxy_breath_dam_max), oxy_damage_type)
|
||||
H.throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy)
|
||||
|
||||
@@ -168,18 +168,18 @@
|
||||
//Too little oxygen!
|
||||
if(safe_oxygen_min)
|
||||
if(O2_pp < safe_oxygen_min)
|
||||
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath_gases[/datum/gas/oxygen])
|
||||
gas_breathed = handle_too_little_breath(H, O2_pp, safe_oxygen_min, breath.get_moles(/datum/gas/oxygen))
|
||||
H.throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier) //More damaged lungs = slower oxy rate up to a factor of half
|
||||
gas_breathed = breath_gases[/datum/gas/oxygen]
|
||||
gas_breathed = breath.get_moles(/datum/gas/oxygen)
|
||||
H.clear_alert("not_enough_oxy")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/oxygen] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/oxygen, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
//-- Nitrogen --//
|
||||
@@ -187,7 +187,7 @@
|
||||
//Too much nitrogen!
|
||||
if(safe_nitro_max)
|
||||
if(N2_pp > safe_nitro_max)
|
||||
var/ratio = (breath_gases[/datum/gas/nitrogen]/safe_nitro_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/nitrogen)/safe_nitro_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, nitro_breath_dam_min, nitro_breath_dam_max), nitro_damage_type)
|
||||
H.throw_alert("too_much_nitro", /obj/screen/alert/too_much_nitro)
|
||||
H.losebreath += 2
|
||||
@@ -197,18 +197,18 @@
|
||||
//Too little nitrogen!
|
||||
if(safe_nitro_min)
|
||||
if(N2_pp < safe_nitro_min)
|
||||
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath_gases[/datum/gas/nitrogen])
|
||||
gas_breathed = handle_too_little_breath(H, N2_pp, safe_nitro_min, breath.get_moles(/datum/gas/nitrogen))
|
||||
H.throw_alert("nitro", /obj/screen/alert/not_enough_nitro)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/nitrogen]
|
||||
gas_breathed = breath.get_moles(/datum/gas/nitrogen)
|
||||
H.clear_alert("nitro")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/nitrogen] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/nitrogen, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
//-- CO2 --//
|
||||
@@ -234,18 +234,18 @@
|
||||
//Too little CO2!
|
||||
if(safe_co2_min)
|
||||
if(CO2_pp < safe_co2_min)
|
||||
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath_gases[/datum/gas/carbon_dioxide])
|
||||
gas_breathed = handle_too_little_breath(H, CO2_pp, safe_co2_min, breath.get_moles(/datum/gas/carbon_dioxide))
|
||||
H.throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/carbon_dioxide]
|
||||
gas_breathed = breath.get_moles(/datum/gas/carbon_dioxide)
|
||||
H.clear_alert("not_enough_co2")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/carbon_dioxide] -= gas_breathed
|
||||
breath_gases[/datum/gas/oxygen] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/oxygen, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
//Too much toxins!
|
||||
if(safe_toxins_max)
|
||||
if(Toxins_pp > safe_toxins_max)
|
||||
var/ratio = (breath_gases[/datum/gas/plasma]/safe_toxins_max) * 10
|
||||
var/ratio = (breath.get_moles(/datum/gas/plasma)/safe_toxins_max) * 10
|
||||
H.apply_damage_type(clamp(ratio, tox_breath_dam_min, tox_breath_dam_max), tox_damage_type)
|
||||
H.throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
|
||||
else
|
||||
@@ -264,18 +264,18 @@
|
||||
//Too little toxins!
|
||||
if(safe_toxins_min)
|
||||
if(Toxins_pp < safe_toxins_min)
|
||||
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath_gases[/datum/gas/plasma])
|
||||
gas_breathed = handle_too_little_breath(H, Toxins_pp, safe_toxins_min, breath.get_moles(/datum/gas/plasma))
|
||||
H.throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
|
||||
else
|
||||
H.failed_last_breath = FALSE
|
||||
if(H.health >= H.crit_threshold)
|
||||
H.adjustOxyLoss(-breathModifier)
|
||||
gas_breathed = breath_gases[/datum/gas/plasma]
|
||||
gas_breathed = breath.get_moles(/datum/gas/plasma)
|
||||
H.clear_alert("not_enough_tox")
|
||||
|
||||
//Exhale
|
||||
breath_gases[/datum/gas/plasma] -= gas_breathed
|
||||
breath_gases[/datum/gas/carbon_dioxide] += gas_breathed
|
||||
breath.adjust_moles(/datum/gas/plasma, -gas_breathed)
|
||||
breath.adjust_moles(/datum/gas/carbon_dioxide, gas_breathed)
|
||||
gas_breathed = 0
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
|
||||
// N2O
|
||||
|
||||
var/SA_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitrous_oxide])
|
||||
var/SA_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitrous_oxide))
|
||||
if(SA_pp > SA_para_min) // Enough to make us stunned for a bit
|
||||
H.Unconscious(60) // 60 gives them one second to wake up and run away a bit!
|
||||
if(SA_pp > SA_sleep_min) // Enough to make us sleep as well
|
||||
@@ -299,7 +299,7 @@
|
||||
|
||||
// BZ
|
||||
|
||||
var/bz_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/bz])
|
||||
var/bz_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/bz))
|
||||
if(bz_pp > BZ_trip_balls_min)
|
||||
H.hallucination += 10
|
||||
H.reagents.add_reagent(/datum/reagent/bz_metabolites,5)
|
||||
@@ -312,14 +312,14 @@
|
||||
|
||||
|
||||
// Tritium
|
||||
var/trit_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/tritium])
|
||||
var/trit_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/tritium))
|
||||
if (trit_pp > 50)
|
||||
H.radiation += trit_pp/2 //If you're breathing in half an atmosphere of radioactive gas, you fucked up.
|
||||
else
|
||||
H.radiation += trit_pp/10
|
||||
|
||||
// Nitryl
|
||||
var/nitryl_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/nitryl])
|
||||
var/nitryl_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/nitryl))
|
||||
if (prob(nitryl_pp))
|
||||
to_chat(H, "<span class='alert'>Your mouth feels like it's burning!</span>")
|
||||
if (nitryl_pp >40)
|
||||
@@ -330,22 +330,22 @@
|
||||
H.silent = max(H.silent, 3)
|
||||
else
|
||||
H.adjustFireLoss(nitryl_pp/4)
|
||||
gas_breathed = breath_gases[/datum/gas/nitryl]
|
||||
gas_breathed = breath.get_moles(/datum/gas/nitryl)
|
||||
if (gas_breathed > gas_stimulation_min)
|
||||
H.reagents.add_reagent(/datum/reagent/nitryl,1)
|
||||
|
||||
breath_gases[/datum/gas/nitryl]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/nitryl, -gas_breathed)
|
||||
|
||||
// Stimulum
|
||||
gas_breathed = breath_gases[/datum/gas/stimulum]
|
||||
gas_breathed = breath.get_moles(/datum/gas/stimulum)
|
||||
if (gas_breathed > gas_stimulation_min)
|
||||
var/existing = H.reagents.get_reagent_amount(/datum/reagent/stimulum)
|
||||
H.reagents.add_reagent(/datum/reagent/stimulum, max(0, 5 - existing))
|
||||
breath_gases[/datum/gas/stimulum]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/stimulum, -gas_breathed)
|
||||
|
||||
// Miasma
|
||||
if (breath_gases[/datum/gas/miasma])
|
||||
var/miasma_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/miasma])
|
||||
if (breath.get_moles(/datum/gas/miasma))
|
||||
var/miasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/miasma))
|
||||
if(miasma_pp > MINIMUM_MOLES_DELTA_TO_MOVE)
|
||||
|
||||
//Miasma sickness
|
||||
@@ -385,14 +385,13 @@
|
||||
// Then again, this is a purely hypothetical scenario and hardly reachable
|
||||
owner.adjust_disgust(0.1 * miasma_pp)
|
||||
|
||||
breath_gases[/datum/gas/miasma]-=gas_breathed
|
||||
breath.adjust_moles(/datum/gas/miasma, -gas_breathed)
|
||||
|
||||
// Clear out moods when no miasma at all
|
||||
else
|
||||
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "smell")
|
||||
|
||||
handle_breath_temperature(breath, H)
|
||||
GAS_GARBAGE_COLLECT(breath.gases)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -414,7 +413,7 @@
|
||||
|
||||
|
||||
/obj/item/organ/lungs/proc/handle_breath_temperature(datum/gas_mixture/breath, mob/living/carbon/human/H) // called by human/life, handles temperatures
|
||||
var/breath_temperature = breath.temperature
|
||||
var/breath_temperature = breath.return_temperature()
|
||||
|
||||
if(!HAS_TRAIT(H, TRAIT_RESISTCOLD)) // COLD DAMAGE
|
||||
var/cold_modifier = H.dna.species.coldmod
|
||||
@@ -458,11 +457,6 @@
|
||||
else if(!(organ_flags & ORGAN_FAILING))
|
||||
failed = FALSE
|
||||
|
||||
/obj/item/organ/lungs/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent(/datum/reagent/medicine/salbutamol, 5)
|
||||
return S
|
||||
|
||||
/obj/item/organ/lungs/ipc
|
||||
name = "ipc cooling system"
|
||||
icon_state = "lungs-c"
|
||||
@@ -547,8 +541,8 @@
|
||||
|
||||
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if (breath && breath.gases[/datum/gas/plasma])
|
||||
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma])
|
||||
if (breath)
|
||||
var/plasma_pp = breath.get_breath_partial_pressure(breath.get_moles(/datum/gas/plasma))
|
||||
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
|
||||
|
||||
/obj/item/organ/lungs/yamerol
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/zone = BODY_ZONE_CHEST
|
||||
var/slot
|
||||
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
|
||||
var/organ_flags = NONE
|
||||
var/organ_flags = ORGAN_EDIBLE
|
||||
var/maxHealth = STANDARD_ORGAN_THRESHOLD
|
||||
var/damage = 0 //total damage this organ has sustained
|
||||
///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick
|
||||
@@ -25,7 +25,23 @@
|
||||
var/now_fixed
|
||||
var/high_threshold_cleared
|
||||
var/low_threshold_cleared
|
||||
rad_flags = RAD_NO_CONTAMINATE
|
||||
|
||||
///When you take a bite you cant jam it in for surgery anymore.
|
||||
var/useable = TRUE
|
||||
var/list/food_reagents = list(/datum/reagent/consumable/nutriment = 5)
|
||||
|
||||
/obj/item/organ/Initialize()
|
||||
. = ..()
|
||||
if(organ_flags & ORGAN_EDIBLE)
|
||||
AddComponent(/datum/component/edible, food_reagents, null, RAW | MEAT | GROSS, null, 10, null, null, null, CALLBACK(src, .proc/OnEatFrom))
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
if(owner)
|
||||
// The special flag is important, because otherwise mobs can die
|
||||
// while undergoing transformation into different mobs.
|
||||
Remove(TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
if(!iscarbon(M) || owner == M)
|
||||
@@ -106,7 +122,7 @@
|
||||
if(istype(loc, /turf/))//Only concern is adding an organ to a freezer when the area around it is cold.
|
||||
var/turf/T = loc
|
||||
var/datum/gas_mixture/enviro = T.return_air()
|
||||
local_temp = enviro.temperature
|
||||
local_temp = enviro.return_temperature()
|
||||
|
||||
else if(!owner && ismob(loc))
|
||||
var/mob/M = loc
|
||||
@@ -116,7 +132,7 @@
|
||||
return TRUE
|
||||
var/turf/T = M.loc
|
||||
var/datum/gas_mixture/enviro = T.return_air()
|
||||
local_temp = enviro.temperature
|
||||
local_temp = enviro.return_temperature()
|
||||
|
||||
if(owner)
|
||||
//Don't interfere with bodies frozen by structures.
|
||||
@@ -157,47 +173,8 @@
|
||||
if(damage > high_threshold)
|
||||
. += "<span class='warning'>[src] is starting to look discolored.</span>"
|
||||
|
||||
|
||||
/obj/item/organ/proc/prepare_eat()
|
||||
var/obj/item/reagent_containers/food/snacks/organ/S = new
|
||||
S.name = name
|
||||
S.desc = desc
|
||||
S.icon = icon
|
||||
S.icon_state = icon_state
|
||||
S.w_class = w_class
|
||||
|
||||
return S
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/organ
|
||||
name = "appendix"
|
||||
icon_state = "appendix"
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
list_reagents = list(/datum/reagent/consumable/nutriment = 5)
|
||||
foodtype = RAW | MEAT | GROSS
|
||||
|
||||
|
||||
/obj/item/organ/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/organ/Destroy()
|
||||
if(owner)
|
||||
// The special flag is important, because otherwise mobs can die
|
||||
// while undergoing transformation into different mobs.
|
||||
Remove(TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/attack(mob/living/carbon/M, mob/user)
|
||||
if(M == user && ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(status == ORGAN_ORGANIC)
|
||||
var/obj/item/reagent_containers/food/snacks/S = prepare_eat()
|
||||
if(S)
|
||||
qdel(src)
|
||||
if(H.put_in_active_hand(S))
|
||||
S.attack(H, H)
|
||||
else
|
||||
..()
|
||||
/obj/item/organ/proc/OnEatFrom(eater, feeder)
|
||||
useable = FALSE //You can't use it anymore after eating it you spaztic
|
||||
|
||||
/obj/item/organ/item_action_slot_check(slot,mob/user)
|
||||
return //so we don't grant the organ's action to mobs who pick up the organ.
|
||||
|
||||
Executable → Regular
+32
@@ -103,3 +103,35 @@
|
||||
if(2)
|
||||
owner.nutrition = min(owner.nutrition - 100, 0)
|
||||
to_chat(owner, "<span class='warning'>Alert: Minor battery discharge!</span>")
|
||||
|
||||
/obj/item/organ/stomach/ethereal
|
||||
name = "biological battery"
|
||||
icon_state = "stomach-p" //Welp. At least it's more unique in functionaliy.
|
||||
desc = "A crystal-like organ that stores the electric charge of ethereals."
|
||||
var/crystal_charge = ETHEREAL_CHARGE_FULL
|
||||
|
||||
/obj/item/organ/stomach/ethereal/on_life()
|
||||
..()
|
||||
adjust_charge(-ETHEREAL_CHARGE_FACTOR)
|
||||
|
||||
/obj/item/organ/stomach/ethereal/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
RegisterSignal(owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, .proc/charge)
|
||||
RegisterSignal(owner, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_electrocute)
|
||||
|
||||
/obj/item/organ/stomach/ethereal/Remove(mob/living/carbon/M, special = 0)
|
||||
UnregisterSignal(owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT)
|
||||
UnregisterSignal(owner, COMSIG_LIVING_ELECTROCUTE_ACT)
|
||||
..()
|
||||
|
||||
/obj/item/organ/stomach/ethereal/proc/charge(datum/source, amount, repairs)
|
||||
adjust_charge(amount / 70)
|
||||
|
||||
/obj/item/organ/stomach/ethereal/proc/on_electrocute(datum/source, shock_damage, siemens_coeff = 1, flags = NONE)
|
||||
if(flags & SHOCK_ILLUSION)
|
||||
return
|
||||
adjust_charge(shock_damage * siemens_coeff * 2)
|
||||
to_chat(owner, "<span class='notice'>You absorb some of the shock into your body!</span>")
|
||||
|
||||
/obj/item/organ/stomach/ethereal/proc/adjust_charge(amount)
|
||||
crystal_charge = clamp(crystal_charge + amount, ETHEREAL_CHARGE_NONE, ETHEREAL_CHARGE_DANGEROUS)
|
||||
|
||||
@@ -45,14 +45,20 @@
|
||||
/obj/item/organ/tail/lizard/Insert(mob/living/carbon/human/H, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
if(istype(H))
|
||||
// Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in
|
||||
// Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in //yes, the if checks may cause snowflakes so that you can't insert another person's tail (haven't actually tested it but I assume that's the result of my addition) but it makes it so never again will lizards break their spine if set_species is called twice in a row (hopefully)
|
||||
if(!H.dna.species.mutant_bodyparts["tail_lizard"])
|
||||
H.dna.features["tail_lizard"] = tail_type
|
||||
H.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
|
||||
if (!H.dna.features["tail_lizard"])
|
||||
H.dna.features["tail_lizard"] = tail_type
|
||||
H.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
|
||||
else
|
||||
H.dna.species.mutant_bodyparts["tail_lizard"] = H.dna.features["tail_lizard"]
|
||||
|
||||
if(!H.dna.species.mutant_bodyparts["spines"])
|
||||
H.dna.features["spines"] = spines
|
||||
H.dna.species.mutant_bodyparts["spines"] = spines
|
||||
if (!H.dna.features["spines"])
|
||||
H.dna.features["spines"] = spines
|
||||
H.dna.species.mutant_bodyparts["spines"] = spines
|
||||
else
|
||||
H.dna.species.mutant_bodyparts["spines"] = H.dna.features["spines"]
|
||||
H.update_body()
|
||||
|
||||
/obj/item/organ/tail/lizard/Remove(special = FALSE)
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
name = "robotic voicebox"
|
||||
desc = "A voice synthesizer that can interface with organic lifeforms."
|
||||
status = ORGAN_ROBOTIC
|
||||
organ_flags = ORGAN_NO_SPOIL
|
||||
icon_state = "tonguerobot"
|
||||
say_mod = "states"
|
||||
attack_verb = list("beeped", "booped")
|
||||
@@ -311,3 +312,26 @@
|
||||
desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms."
|
||||
electronics_magic = FALSE
|
||||
organ_flags = ORGAN_SYNTHETIC
|
||||
|
||||
/obj/item/organ/tongue/ethereal
|
||||
name = "electric discharger"
|
||||
desc = "A sophisticated ethereal organ, capable of synthesising speech via electrical discharge."
|
||||
icon_state = "electrotongue"
|
||||
say_mod = "crackles"
|
||||
attack_verb = list("shocked", "jolted", "zapped")
|
||||
taste_sensitivity = 101 // Not a tongue, they can't taste shit
|
||||
var/static/list/languages_possible_ethereal = typecacheof(list(
|
||||
/datum/language/common,
|
||||
/datum/language/draconic,
|
||||
/datum/language/codespeak,
|
||||
/datum/language/monkey,
|
||||
/datum/language/narsie,
|
||||
/datum/language/beachbum,
|
||||
/datum/language/aphasia,
|
||||
/datum/language/sylvan,
|
||||
/datum/language/voltaic
|
||||
))
|
||||
|
||||
/obj/item/organ/tongue/ethereal/Initialize(mapload)
|
||||
. = ..()
|
||||
languages_possible = languages_possible_ethereal
|
||||
|
||||
@@ -254,7 +254,6 @@
|
||||
var/static/regex/clap_words = regex("clap|applaud")
|
||||
var/static/regex/honk_words = regex("ho+nk") //hooooooonk
|
||||
var/static/regex/multispin_words = regex("like a record baby|right round")
|
||||
var/static/regex/orgasm_words = regex("cum|orgasm|climax|squirt|heyo") //CITADEL CHANGE
|
||||
var/static/regex/dab_words = regex("dab|mood") //CITADEL CHANGE
|
||||
var/static/regex/snap_words = regex("snap") //CITADEL CHANGE
|
||||
var/static/regex/bwoink_words = regex("what the fuck are you doing|bwoink|hey you got a moment?") //CITADEL CHANGE
|
||||
@@ -319,13 +318,14 @@
|
||||
cooldown = COOLDOWN_DAMAGE
|
||||
for(var/V in listeners)
|
||||
var/mob/living/L = V
|
||||
L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST)
|
||||
L.apply_damage(15 * power_multiplier, def_zone = BODY_ZONE_CHEST, wound_bonus=CANT_WOUND)
|
||||
|
||||
//BLEED
|
||||
else if((findtext(message, bleed_words)))
|
||||
cooldown = COOLDOWN_DAMAGE
|
||||
for(var/mob/living/carbon/human/H in listeners)
|
||||
H.bleed_rate += (5 * power_multiplier)
|
||||
var/obj/item/bodypart/BP = pick(H.bodyparts)
|
||||
BP.generic_bleedstacks += 5
|
||||
|
||||
//FIRE
|
||||
else if((findtext(message, burn_words)))
|
||||
@@ -572,16 +572,6 @@
|
||||
var/mob/living/L = V
|
||||
L.SpinAnimation(speed = 10, loops = 5)
|
||||
|
||||
//CITADEL CHANGES
|
||||
//ORGASM
|
||||
else if((findtext(message, orgasm_words)))
|
||||
cooldown = COOLDOWN_MEME
|
||||
for(var/V in listeners)
|
||||
var/mob/living/carbon/human/H = V
|
||||
|
||||
if(H.client && H.client.prefs && H.client.prefs.cit_toggles & HYPNO) // probably a redundant check but for good measure
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
|
||||
//DAB
|
||||
else if((findtext(message, dab_words)))
|
||||
cooldown = COOLDOWN_DAMAGE
|
||||
@@ -765,7 +755,6 @@
|
||||
var/static/regex/forget_words = regex("forget|muddled|awake and forget")
|
||||
var/static/regex/attract_words = regex("come here|come to me|get over here|attract")
|
||||
//phase 2
|
||||
var/static/regex/orgasm_words = regex("cum|orgasm|climax|squirt|heyo") //wah, lewd
|
||||
var/static/regex/awoo_words = regex("howl|awoo|bark")
|
||||
var/static/regex/nya_words = regex("nya|meow|mewl")
|
||||
var/static/regex/sleep_words = regex("sleep|slumber|rest")
|
||||
@@ -1092,28 +1081,6 @@
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, L, "<span class='notice'>You are drawn towards [user]!</b></span>"), 5)
|
||||
to_chat(user, "<span class='notice'><i>You draw [L] towards you!</i></span>")
|
||||
|
||||
|
||||
//teir 2
|
||||
|
||||
/* removed for now
|
||||
//ORGASM
|
||||
else if((findtext(message, orgasm_words)))
|
||||
for(var/V in listeners)
|
||||
var/mob/living/carbon/human/H = V
|
||||
var/datum/status_effect/chem/enthrall/E = H.has_status_effect(/datum/status_effect/chem/enthrall)
|
||||
if(E.phase > 1)
|
||||
if(E.lewd) // probably a redundant check but for good measure
|
||||
addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, H, "<span class='love'>Your [E.enthrallGender] pushes you over the limit, overwhelming your body with pleasure.</b></span>"), 5)
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
H.SetStun(20)
|
||||
E.resistanceTally = 0 //makes resistance 0, but resets arousal, resistance buildup is faster unaroused (massively so).
|
||||
E.enthrallTally += power_multiplier
|
||||
E.cooldown += 6
|
||||
else
|
||||
H.throw_at(get_step_towards(user,H), 3 * power_multiplier, 1 * power_multiplier)
|
||||
*/
|
||||
|
||||
|
||||
//awoo
|
||||
else if((findtext(message, awoo_words)))
|
||||
for(var/V in listeners)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
return 1
|
||||
/datum/surgery_step/add_prosthetic
|
||||
name = "add prosthetic"
|
||||
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100, /obj/item/twohanded/required/chainsaw = 100, /obj/item/melee/synthetic_arm_blade = 100)
|
||||
implements = list(/obj/item/bodypart = 100, /obj/item/organ_storage = 100, /obj/item/chainsaw = 100, /obj/item/melee/synthetic_arm_blade = 100)
|
||||
time = 32
|
||||
var/organ_rejection_dam = 0
|
||||
/datum/surgery_step/add_prosthetic/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
@@ -79,7 +79,7 @@
|
||||
"[user] finishes attaching [tool]!",
|
||||
"[user] finishes the attachment procedure!")
|
||||
qdel(tool)
|
||||
if(istype(tool, /obj/item/twohanded/required/chainsaw))
|
||||
if(istype(tool, /obj/item/chainsaw))
|
||||
var/obj/item/mounted_chainsaw/new_arm = new(target)
|
||||
target_zone == BODY_ZONE_R_ARM ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm)
|
||||
return 1
|
||||
|
||||
@@ -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
|
||||
@@ -18,6 +18,8 @@
|
||||
var/lying_required = TRUE //Does the vicitm needs to be lying down.
|
||||
var/requires_tech = FALSE
|
||||
var/replaced_by
|
||||
var/datum/wound/operated_wound //The actual wound datum instance we're targeting
|
||||
var/datum/wound/targetable_wound //The wound type this surgery targets
|
||||
|
||||
/datum/surgery/New(surgery_target, surgery_location, surgery_bodypart)
|
||||
..()
|
||||
@@ -28,8 +30,13 @@
|
||||
location = surgery_location
|
||||
if(surgery_bodypart)
|
||||
operated_bodypart = surgery_bodypart
|
||||
if(targetable_wound)
|
||||
operated_wound = operated_bodypart.get_wound_type(targetable_wound)
|
||||
operated_wound.attached_surgery = src
|
||||
|
||||
/datum/surgery/Destroy()
|
||||
if(operated_wound)
|
||||
operated_wound.attached_surgery = null
|
||||
if(target)
|
||||
target.surgeries -= src
|
||||
target = null
|
||||
|
||||
@@ -163,9 +163,10 @@
|
||||
item_flags = SURGICAL_TOOL
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
sharpness = SHARP_POINTY
|
||||
tool_behaviour = TOOL_SCALPEL
|
||||
toolspeed = 1
|
||||
bare_wound_bonus = 20
|
||||
|
||||
/obj/item/scalpel/Initialize()
|
||||
. = ..()
|
||||
@@ -180,7 +181,7 @@
|
||||
force = 16
|
||||
toolspeed = 0.7
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
sharpness = SHARP_POINTY
|
||||
|
||||
/obj/item/scalpel/advanced/Initialize()
|
||||
. = ..()
|
||||
@@ -220,7 +221,7 @@
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
|
||||
toolspeed = 0.5
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
sharpness = IS_SHARP_ACCURATE
|
||||
sharpness = SHARP_POINTY
|
||||
|
||||
/obj/item/scalpel/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] [pick("wrists", "throat", "stomach")] with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
@@ -244,9 +245,11 @@
|
||||
throw_range = 5
|
||||
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
|
||||
attack_verb = list("attacked", "slashed", "sawed", "cut")
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
tool_behaviour = TOOL_SAW
|
||||
toolspeed = 1
|
||||
wound_bonus = 5
|
||||
bare_wound_bonus = 10
|
||||
|
||||
/obj/item/circular_saw/Initialize()
|
||||
. = ..()
|
||||
@@ -269,7 +272,7 @@
|
||||
custom_materials = list(/datum/material/iron=10000, /datum/material/glass=6000)
|
||||
toolspeed = 0.5
|
||||
attack_verb = list("attacked", "slashed", "sawed", "cut")
|
||||
sharpness = IS_SHARP
|
||||
sharpness = SHARP_EDGED
|
||||
|
||||
/obj/item/surgical_drapes
|
||||
name = "surgical drapes"
|
||||
@@ -374,3 +377,18 @@
|
||||
advanced_surgeries |= OC.advanced_surgeries
|
||||
return TRUE
|
||||
return
|
||||
|
||||
/obj/item/bonesetter
|
||||
name = "bonesetter"
|
||||
desc = "For setting things right."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
icon_state = "bone setter"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
custom_materials = list(/datum/material/iron=5000, /datum/material/glass=2500)
|
||||
flags_1 = CONDUCT_1
|
||||
item_flags = SURGICAL_TOOL
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("corrected", "properly set")
|
||||
tool_behaviour = TOOL_BONESET
|
||||
toolspeed = 1
|
||||
|
||||
Reference in New Issue
Block a user