more changes
This commit is contained in:
@@ -79,7 +79,7 @@
|
||||
send_item_attack_message(I, user, affecting.name, totitemdamage)
|
||||
I.do_stagger_action(src, user, totitemdamage)
|
||||
if(I.force)
|
||||
apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
apply_damage(totitemdamage, I.damtype, affecting, wound_bonus = I.wound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness()) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
|
||||
var/basebloodychance = affecting.brute_dam + totitemdamage
|
||||
if(prob(basebloodychance))
|
||||
@@ -132,6 +132,9 @@
|
||||
if(S.next_step(user, user.a_intent))
|
||||
return TRUE
|
||||
|
||||
for(var/datum/wound/W in all_wounds)
|
||||
if(W.try_handling(user))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
|
||||
|
||||
@@ -467,3 +470,8 @@
|
||||
if (BP.status < 2)
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/proc/get_interaction_efficiency(zone)
|
||||
var/obj/item/bodypart/limb = get_bodypart(zone)
|
||||
if(!limb)
|
||||
return
|
||||
|
||||
@@ -64,3 +64,8 @@
|
||||
|
||||
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
|
||||
var/tackling = FALSE //Whether or not we are tackling, this will prevent the knock into effects for carbons
|
||||
|
||||
/// All of the wounds a carbon has afflicted throughout their limbs
|
||||
var/list/all_wounds
|
||||
/// All of the scars a carbon has afflicted throughout their limbs
|
||||
var/list/all_scars
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!forced && hit_percent <= 0)
|
||||
@@ -21,13 +21,13 @@
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0))
|
||||
if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
|
||||
update_damage_overlays()
|
||||
else //no bodypart, we deal damage with a more general method.
|
||||
adjustBruteLoss(damage_amount, forced = forced)
|
||||
if(BURN)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
|
||||
if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustFireLoss(damage_amount, forced = forced)
|
||||
@@ -202,12 +202,12 @@
|
||||
//Damages ONE bodypart randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necessary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0)
|
||||
/mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.receive_damage(brute, burn, stamina))
|
||||
if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
|
||||
update_damage_overlays()
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
@@ -253,7 +253,7 @@
|
||||
var/stamina_was = picked.stamina_dam
|
||||
|
||||
|
||||
update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE)
|
||||
update |= picked.receive_damage(brute_per_part, burn_per_part, stamina_per_part, FALSE, required_status, wound_bonus = CANT_WOUND) // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck
|
||||
|
||||
brute = round(brute - (picked.brute_dam - brute_was), DAMAGE_PRECISION)
|
||||
burn = round(burn - (picked.burn_dam - burn_was), DAMAGE_PRECISION)
|
||||
@@ -265,3 +265,12 @@
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
update_stamina()
|
||||
|
||||
///Returns a list of bodyparts with wounds (in case someone has a wound on an otherwise fully healed limb)
|
||||
/mob/living/carbon/proc/get_wounded_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, status)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(LAZYLEN(BP.wounds))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
|
||||
for(var/datum/wound/W in BP.wounds)
|
||||
msg += "[W.get_examine_description(user)]\n"
|
||||
|
||||
for(var/X in disabled)
|
||||
var/obj/item/bodypart/BP = X
|
||||
@@ -99,6 +101,22 @@
|
||||
if(pulledby && pulledby.grab_state)
|
||||
msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n"
|
||||
|
||||
var/scar_severity = 0
|
||||
for(var/i in all_scars)
|
||||
var/datum/scar/S = i
|
||||
if(S.is_visible(user))
|
||||
scar_severity += S.severity
|
||||
|
||||
switch(scar_severity)
|
||||
if(1 to 2)
|
||||
msg += "<span class='smallnotice'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
|
||||
if(3 to 4)
|
||||
msg += "<span class='notice'><i>[t_He] [t_has] several bad scars, you can look again to take a closer look...</i></span>\n"
|
||||
if(5 to 6)
|
||||
msg += "<span class='notice'><b><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></b></span>\n"
|
||||
if(7 to INFINITY)
|
||||
msg += "<span class='notice'><b><i>[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...</i></b></span>\n"
|
||||
|
||||
if(msg.len)
|
||||
. += "<span class='warning'>[msg.Join("")]</span>"
|
||||
|
||||
@@ -135,3 +153,25 @@
|
||||
. += "[t_He] look[p_s()] ecstatic."
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/carbon/examine_more(mob/user)
|
||||
if(!all_scars)
|
||||
return ..()
|
||||
|
||||
var/list/visible_scars
|
||||
for(var/i in all_scars)
|
||||
var/datum/scar/S = i
|
||||
if(S.is_visible(user))
|
||||
LAZYADD(visible_scars, S)
|
||||
|
||||
if(!visible_scars)
|
||||
return ..()
|
||||
|
||||
var/msg = list("<span class='notice'><i>You examine [src] closer, and note the following...</i></span>")
|
||||
for(var/i in visible_scars)
|
||||
var/datum/scar/S = i
|
||||
var/scar_text = S.get_examine_description(user)
|
||||
if(scar_text)
|
||||
msg += "[scar_text]"
|
||||
|
||||
return msg
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage, wound_bonus, bare_wound_bonus, sharpness)
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced, spread_damage)
|
||||
|
||||
@@ -163,16 +163,18 @@
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] stuck to [t_his] [BP.name]!</B>\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [BP.name]!</B>\n"
|
||||
for(var/datum/wound/W in BP.wounds)
|
||||
msg += "[W.get_examine_description(user)]\n"
|
||||
|
||||
for(var/X in disabled)
|
||||
var/obj/item/bodypart/BP = X
|
||||
var/damage_text
|
||||
if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //Stamina is disabling the limb
|
||||
damage_text = "limp and lifeless"
|
||||
else
|
||||
damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg
|
||||
msg += "<B>[capitalize(t_his)] [BP.name] is [damage_text]!</B>\n"
|
||||
|
||||
if(BP.is_disabled() != BODYPART_DISABLED_WOUND) // skip if it's disabled by a wound (cuz we'll be able to see the bone sticking out!)
|
||||
if(!(BP.get_damage(include_stamina = FALSE) >= BP.max_damage)) //we don't care if it's stamcritted
|
||||
damage_text = "limp and lifeless"
|
||||
else
|
||||
damage_text = (BP.brute_dam >= BP.burn_dam) ? BP.heavy_brute_msg : BP.heavy_burn_msg
|
||||
msg += "<B>[capitalize(t_his)] [BP.name] is [damage_text]!</B>\n"
|
||||
//stores missing limbs
|
||||
var/l_limbs_missing = 0
|
||||
var/r_limbs_missing = 0
|
||||
@@ -246,16 +248,40 @@
|
||||
if(DISGUST_LEVEL_DISGUSTED to INFINITY)
|
||||
msg += "[t_He] look[p_s()] extremely disgusted.\n"
|
||||
|
||||
if(ShowAsPaleExamine())
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
var/apparent_blood_volume = blood_volume
|
||||
if(skin_tone == "albino")
|
||||
apparent_blood_volume -= 150 // enough to knock you down one tier
|
||||
switch(apparent_blood_volume)
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
msg += "<b>[t_He] look[p_s()] like pale death.</b>\n"
|
||||
if(-INFINITY to BLOOD_VOLUME_BAD)
|
||||
msg += "<span class='deadsay'><b>[t_He] resemble[p_s()] a crushed, empty juice pouch.</b></span>\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[t_He] [t_is] bandaged with something.\n"
|
||||
else if(bleed_rate)
|
||||
if(bleed_rate >= 8) //8 is the rate at which heparin causes you to bleed
|
||||
msg += "<b>[t_He] [t_is] bleeding uncontrollably!</b>\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_is] bleeding!</B>\n"
|
||||
msg += "[t_He] [t_is] embued with a power that defies bleeding.\n" // only statues and highlander sword can cause this so whatever
|
||||
else if(is_bleeding())
|
||||
var/list/obj/item/bodypart/bleeding_limbs = list()
|
||||
|
||||
for(var/i in bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
if(BP.get_bleed_rate())
|
||||
bleeding_limbs += BP
|
||||
|
||||
var/num_bleeds = LAZYLEN(bleeding_limbs)
|
||||
var/bleed_text = "<B>[t_He] [t_is] bleeding from [t_his]"
|
||||
switch(num_bleeds)
|
||||
if(1 to 2)
|
||||
bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]"
|
||||
if(3 to INFINITY)
|
||||
for(var/i in 1 to (num_bleeds - 1))
|
||||
var/obj/item/bodypart/BP = bleeding_limbs[i]
|
||||
bleed_text += " [BP.name],"
|
||||
bleed_text += " and [bleeding_limbs[num_bleeds].name]"
|
||||
|
||||
bleed_text += "!</B>\n"
|
||||
msg += bleed_text
|
||||
|
||||
if(reagents.has_reagent(/datum/reagent/teslium))
|
||||
msg += "[t_He] [t_is] emitting a gentle blue glow!\n"
|
||||
@@ -331,6 +357,21 @@
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
|
||||
|
||||
var/scar_severity = 0
|
||||
for(var/i in all_scars)
|
||||
var/datum/scar/S = i
|
||||
if(S.is_visible(user))
|
||||
scar_severity += S.severity
|
||||
|
||||
switch(scar_severity)
|
||||
if(1 to 2)
|
||||
msg += "<span class='smallnotice'>[t_He] [t_has] visible scarring, you can look again to take a closer look...</span>\n"
|
||||
if(3 to 4)
|
||||
msg += "<span class='notice'><i>[t_He] [t_has] several bad scars, you can look again to take a closer look...</i></span>\n"
|
||||
if(5 to 6)
|
||||
msg += "<span class='notice'><b><i>[t_He] [t_has] significantly disfiguring scarring, you can look again to take a closer look...</i></b></span>\n"
|
||||
if(7 to INFINITY)
|
||||
msg += "<span class='notice'><b><i>[t_He] [t_is] just absolutely fucked up, you can look again to take a closer look...</i></b></span>\n"
|
||||
|
||||
if (length(msg))
|
||||
. += "<span class='warning'>[msg.Join("")]</span>"
|
||||
|
||||
@@ -1055,10 +1055,21 @@
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
|
||||
|
||||
/mob/living/carbon/human/do_after_coefficent()
|
||||
. = ..()
|
||||
. *= physiology.do_after_speed
|
||||
|
||||
/mob/living/carbon/human/is_bleeding()
|
||||
if(NOBLOOD in dna.species.species_traits || bleedsuppress)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_total_bleed_rate()
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/species
|
||||
var/race = null
|
||||
|
||||
|
||||
@@ -34,6 +34,19 @@
|
||||
protection += physiology.armor.getRating(d_type)
|
||||
return protection
|
||||
|
||||
///Get all the clothing on a specific body part
|
||||
/mob/living/carbon/human/proc/clothingonpart(obj/item/bodypart/def_zone)
|
||||
var/list/covering_part = list()
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
for(var/bp in body_parts)
|
||||
if(!bp)
|
||||
continue
|
||||
if(bp && istype(bp , /obj/item/clothing))
|
||||
var/obj/item/clothing/C = bp
|
||||
if(C.body_parts_covered & def_zone.body_part)
|
||||
covering_part += C
|
||||
return covering_part
|
||||
|
||||
/mob/living/carbon/human/on_hit(obj/item/projectile/P)
|
||||
if(dna && dna.species)
|
||||
dna.species.on_hit(P, src)
|
||||
@@ -106,7 +119,7 @@
|
||||
visible_message("<span class='danger'>[user] [hulk_verb_continous] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] [hulk_verb_continous] you!</span>", null, COMBAT_MESSAGE_RANGE, null, user,
|
||||
"<span class='danger'>You [hulk_verb_simple] [src]!</span>")
|
||||
adjustBruteLoss(15)
|
||||
apply_damage(15, BRUTE, wound_bonus=10)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/user)
|
||||
@@ -217,16 +230,17 @@
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor)
|
||||
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor, wound_bonus = M.wound_bonus, bare_wound_bonus = M.bare_wound_bonus, sharpness = M.sharpness)
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
. = ..()
|
||||
if(!.) //unsuccessful slime attack
|
||||
return
|
||||
var/damage = rand(5, 25)
|
||||
var/wound_mod = -45 // 25^1.4=90, 90-45=45
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
wound_mod = -90 // 35^1.4=145, 145-90=55
|
||||
|
||||
var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
@@ -236,7 +250,7 @@
|
||||
if(!affecting)
|
||||
affecting = get_bodypart(BODY_ZONE_CHEST)
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
@@ -614,6 +628,20 @@
|
||||
no_damage = TRUE
|
||||
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
|
||||
|
||||
for(var/thing in LB.wounds)
|
||||
var/datum/wound/W = thing
|
||||
var/msg
|
||||
switch(W.severity)
|
||||
if(WOUND_SEVERITY_TRIVIAL)
|
||||
msg = "\t <span class='danger'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)].</span>"
|
||||
if(WOUND_SEVERITY_MODERATE)
|
||||
msg = "\t <span class='warning'>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</span>"
|
||||
if(WOUND_SEVERITY_SEVERE)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!</b></span>"
|
||||
if(WOUND_SEVERITY_CRITICAL)
|
||||
msg = "\t <span class='warning'><b>Your [LB.name] is suffering [W.a_or_from] [lowertext(W.name)]!!</b></span>"
|
||||
to_chat(src, msg)
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
if(I.isEmbedHarmless())
|
||||
to_chat(src, "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] stuck to your [LB.name]!</a>")
|
||||
@@ -623,8 +651,25 @@
|
||||
for(var/t in missing)
|
||||
to_send += "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>\n"
|
||||
|
||||
if(bleed_rate)
|
||||
to_send += "<span class='danger'>You are bleeding!</span>\n"
|
||||
if(is_bleeding())
|
||||
var/list/obj/item/bodypart/bleeding_limbs = list()
|
||||
for(var/i in bodyparts)
|
||||
var/obj/item/bodypart/BP = i
|
||||
if(BP.get_bleed_rate())
|
||||
bleeding_limbs += BP
|
||||
|
||||
var/num_bleeds = LAZYLEN(bleeding_limbs)
|
||||
var/bleed_text = "<span class='danger'>You are bleeding from your"
|
||||
switch(num_bleeds)
|
||||
if(1 to 2)
|
||||
bleed_text += " [bleeding_limbs[1].name][num_bleeds == 2 ? " and [bleeding_limbs[2].name]" : ""]"
|
||||
if(3 to INFINITY)
|
||||
for(var/i in 1 to (num_bleeds - 1))
|
||||
var/obj/item/bodypart/BP = bleeding_limbs[i]
|
||||
bleed_text += " [BP.name],"
|
||||
bleed_text += " and [bleeding_limbs[num_bleeds].name]"
|
||||
bleed_text += "!</span>"
|
||||
to_chat(src, bleed_text)
|
||||
if(getStaminaLoss())
|
||||
if(getStaminaLoss() > 30)
|
||||
to_send += "<span class='info'>You're completely exhausted.</span>\n"
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
var/bleed_rate = 0 //how much are we bleeding
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
|
||||
var/blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
|
||||
@@ -151,3 +151,22 @@
|
||||
if(blood_dna.len)
|
||||
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
|
||||
last_blood_DNA = blood_dna[blood_dna.len]*/
|
||||
|
||||
/// For use formatting all of the scars this human has for saving for persistent scarring
|
||||
/mob/living/carbon/human/proc/format_scars()
|
||||
if(!all_scars)
|
||||
return
|
||||
var/scars = ""
|
||||
for(var/i in all_scars)
|
||||
var/datum/scar/S = i
|
||||
scars += "[S.format()];"
|
||||
return scars
|
||||
|
||||
/// Takes a single scar from the persistent scar loader and recreates it from the saved data
|
||||
/mob/living/carbon/human/proc/load_scar(scar_line)
|
||||
var/list/scar_data = splittext(scar_line, "|")
|
||||
if(LAZYLEN(scar_data) != 4)
|
||||
return // invalid, should delete
|
||||
var/obj/item/bodypart/BP = get_bodypart("[scar_data[SCAR_SAVE_ZONE]]")
|
||||
var/datum/scar/S = new
|
||||
return S.load(BP, scar_data[SCAR_SAVE_DESC], scar_data[SCAR_SAVE_PRECISE_LOCATION], text2num(scar_data[SCAR_SAVE_SEVERITY]))
|
||||
|
||||
@@ -1728,9 +1728,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/armor_block = H.run_armor_check(affecting, "melee", "<span class='notice'>Your armor has protected your [hit_area].</span>", "<span class='notice'>Your armor has softened a hit to your [hit_area].</span>",I.armour_penetration)
|
||||
armor_block = min(90,armor_block) //cap damage reduction at 90%
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
var/Iwound_bonus = I.wound_bonus
|
||||
|
||||
// this way, you can't wound with a surgical tool on help intent if they have a surgery active and are laying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho)
|
||||
if((I.item_flags & SURGICAL_TOOL) && user.a_intent == INTENT_HELP && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0))
|
||||
Iwound_bonus = CANT_WOUND
|
||||
|
||||
var/weakness = H.check_weakness(I, user)
|
||||
apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
apply_damage(totitemdamage * weakness, I.damtype, def_zone, armor_block, H, wound_bonus = Iwound_bonus, bare_wound_bonus = I.bare_wound_bonus, sharpness = I.get_sharpness())
|
||||
|
||||
|
||||
H.send_item_attack_message(I, user, hit_area, totitemdamage)
|
||||
|
||||
@@ -1945,8 +1951,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
append_message += ", causing them to drop [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone)
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
SEND_SIGNAL(H, COMSIG_MOB_APPLY_DAMGE, damage, damagetype, def_zone, wound_bonus, bare_wound_bonus, sharpness) // make sure putting wound_bonus here doesn't screw up other signals or uses for this signal
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
|
||||
if(!forced && hit_percent <= 0)
|
||||
@@ -1973,7 +1979,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.damageoverlaytemp = 20
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0))
|
||||
if(BP.receive_damage(damage_amount, 0, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
|
||||
H.update_damage_overlays()
|
||||
if(HAS_TRAIT(H, TRAIT_MASO) && prob(damage_amount))
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
@@ -1984,7 +1990,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.damageoverlaytemp = 20
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
|
||||
if(BP.receive_damage(0, damage_amount, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness))
|
||||
H.update_damage_overlays()
|
||||
else
|
||||
H.adjustFireLoss(damage_amount)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR,CAN_SCAR)
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
use_skintones = USE_SKINTONES_GRAYSCALE_CUSTOM
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id = "lizard"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,CAN_SCAR)
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
|
||||
mutanttongue = /obj/item/organ/tongue/lizard
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
nojumpsuit = TRUE
|
||||
|
||||
say_mod = "poofs" //what does a mushroom sound like
|
||||
species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL)
|
||||
species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL,CAN_SCAR)
|
||||
inherent_traits = list(TRAIT_NOBREATH)
|
||||
speedmod = 1.5 //faster than golems but not by much
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "Anthromorphic Plant"
|
||||
id = "pod"
|
||||
default_color = "59CE00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,CAN_SCAR)
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
species_traits = list(NOBLOOD,NOEYES)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,CAN_SCAR)
|
||||
|
||||
dangerous_existence = 1
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING)
|
||||
species_traits = list(NOBLOOD,NOZOMBIE,NOTRANSSTING,CAN_SCAR)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
|
||||
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
|
||||
mutanttongue = /obj/item/organ/tongue/zombie
|
||||
@@ -45,7 +45,7 @@
|
||||
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
|
||||
. = min(20, amount)
|
||||
|
||||
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
|
||||
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
regen_cooldown = world.time + REGENERATION_DELAY
|
||||
@@ -62,6 +62,10 @@
|
||||
heal_amt *= 2
|
||||
C.heal_overall_damage(heal_amt,heal_amt)
|
||||
C.adjustToxLoss(-heal_amt)
|
||||
for(var/i in C.all_wounds)
|
||||
var/datum/wound/W = i
|
||||
if(prob(4-W.severity))
|
||||
W.remove_wound()
|
||||
if(!C.InCritical() && prob(4))
|
||||
playsound(C, pick(spooks), 50, TRUE, 10)
|
||||
|
||||
|
||||
@@ -404,6 +404,12 @@
|
||||
if(stat != DEAD || D.process_dead)
|
||||
D.stage_act()
|
||||
|
||||
/mob/living/carbon/handle_wounds()
|
||||
for(var/thing in all_wounds)
|
||||
var/datum/wound/W = thing
|
||||
if(W.processes) // meh
|
||||
W.handle_process()
|
||||
|
||||
//todo generalize this and move hud out
|
||||
/mob/living/carbon/proc/handle_changeling()
|
||||
if(mind && hud_used && hud_used.lingchemdisplay)
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(ancestor_chain > 1)
|
||||
generate_fake_scars(rand(ancestor_chain, ancestor_chain * 4))
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, SLOT_HEAD)
|
||||
if(relic_mask)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*
|
||||
* Returns TRUE if damage applied
|
||||
*/
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (hit_percent <= 0))
|
||||
return 0
|
||||
@@ -245,7 +245,7 @@
|
||||
update_stamina()
|
||||
|
||||
// damage ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE)
|
||||
/mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_status, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update
|
||||
adjustFireLoss(burn, FALSE)
|
||||
adjustStaminaLoss(stamina, FALSE)
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
/mob/living/proc/BiologicalLife(seconds, times_fired)
|
||||
handle_diseases()// DEAD check is in the proc itself; we want it to spread even if the mob is dead, but to handle its disease-y properties only if you're not.
|
||||
|
||||
handle_wounds()
|
||||
|
||||
// Everything after this shouldn't process while dead (as of the time of writing)
|
||||
if(stat == DEAD)
|
||||
return FALSE
|
||||
@@ -109,6 +111,9 @@
|
||||
/mob/living/proc/handle_diseases()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_wounds()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_diginvis()
|
||||
if(!digitaldisguise)
|
||||
src.digitaldisguise = image(loc = src)
|
||||
|
||||
@@ -636,7 +636,7 @@
|
||||
TH.transfer_mob_blood_dna(src)
|
||||
|
||||
/mob/living/carbon/human/makeTrail(turf/T)
|
||||
if((NOBLOOD in dna.species.species_traits) || !bleed_rate || bleedsuppress)
|
||||
if((NOBLOOD in dna.species.species_traits) || !is_bleeding() || bleedsuppress)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
totaldamage = block_calculate_resultant_damage(totaldamage, returnlist)
|
||||
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
|
||||
if(!P.nodamage)
|
||||
apply_damage(totaldamage, P.damage_type, def_zone, armor)
|
||||
apply_damage(P.damage, P.damage_type, def_zone, armor, wound_bonus=P.wound_bonus, bare_wound_bonus=P.bare_wound_bonus, sharpness=P.sharpness)
|
||||
if(P.dismemberment)
|
||||
check_projectile_dismemberment(P, def_zone)
|
||||
var/missing = 100 - final_percent
|
||||
@@ -138,7 +138,7 @@
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
|
||||
"<span class='userdanger'>You have been hit by [I].</span>")
|
||||
var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
|
||||
apply_damage(total_damage, dtype, impacting_zone, armor)
|
||||
apply_damage(total_damage, dtype, impacting_zone, armor, sharpness=I.sharpness)
|
||||
if(I.thrownby)
|
||||
log_combat(I.thrownby, src, "threw and hit", I)
|
||||
else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, spread_damage = FALSE)
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (!forced && hit_percent <= 0))
|
||||
return 0
|
||||
|
||||
@@ -334,9 +334,11 @@
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/bonesetter,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/borg/cyborghug/medical,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/stack/medical/bone_gel/cyborg,
|
||||
/obj/item/organ_storage,
|
||||
/obj/item/borg/lollipop,
|
||||
/obj/item/sensor_device,
|
||||
|
||||
@@ -29,8 +29,11 @@
|
||||
var/armored = FALSE
|
||||
|
||||
obj_damage = 60
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 30
|
||||
melee_damage_lower = 15 // i know it's like half what it used to be, but bears cause bleeding like crazy now so it works out
|
||||
melee_damage_upper = 15
|
||||
wound_bonus = -5
|
||||
bare_wound_bonus = 10 // BEAR wound bonus am i right
|
||||
sharpness = TRUE
|
||||
attack_verb_continuous = "claws"
|
||||
attack_verb_simple = "claw"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
@@ -69,8 +72,9 @@
|
||||
icon_dead = "combatbear_dead"
|
||||
faction = list("russian")
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 35
|
||||
melee_damage_lower = 18
|
||||
melee_damage_upper = 20
|
||||
wound_bonus = 0
|
||||
armour_penetration = 20
|
||||
health = 120
|
||||
maxHealth = 120
|
||||
@@ -99,8 +103,9 @@
|
||||
A.maxHealth += 60
|
||||
A.health += 60
|
||||
A.armour_penetration += 20
|
||||
A.melee_damage_lower += 5
|
||||
A.melee_damage_lower += 3
|
||||
A.melee_damage_upper += 5
|
||||
A.wound_bonus += 5
|
||||
A.update_icons()
|
||||
to_chat(user, "<span class='info'>You strap the armor plating to [A] and sharpen [A.p_their()] claws with the nail filer. This was a great idea.</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -643,7 +643,7 @@ Difficulty: Normal
|
||||
to_chat(L, "<span class='userdanger'>You're struck by a [name]!</span>")
|
||||
var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
|
||||
var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
|
||||
L.apply_damage(damage, BURN, limb_to_hit, armor)
|
||||
L.apply_damage(damage, BURN, limb_to_hit, armor, wound_bonus=CANT_WOUND)
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L //mobs find and damage you...
|
||||
if(H.stat == CONSCIOUS && !H.target && H.AIStatus != AI_OFF && !H.client)
|
||||
|
||||
@@ -52,6 +52,8 @@ Difficulty: Medium
|
||||
elimination = 1
|
||||
appearance_flags = 0
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
wound_bonus = -40
|
||||
bare_wound_bonus = 20
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/legion/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -129,7 +129,7 @@ Difficulty: Hard
|
||||
to_chat(L, "<span class='userdanger'>[src]'s ground slam shockwave sends you flying!</span>")
|
||||
var/turf/thrownat = get_ranged_target_turf_direct(src, L, 8, rand(-10, 10))
|
||||
L.throw_at(thrownat, 8, 2, src, TRUE) //, force = MOVE_FORCE_OVERPOWERING, gentle = TRUE)
|
||||
L.apply_damage(20, BRUTE)
|
||||
L.apply_damage(20, BRUTE, wound_bonus=CANT_WOUND)
|
||||
shake_camera(L, 2, 1)
|
||||
all_turfs -= T
|
||||
sleep(delay)
|
||||
|
||||
@@ -77,6 +77,9 @@
|
||||
/mob/living/simple_animal/hostile/syndicate/melee
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
wound_bonus = -10
|
||||
bare_wound_bonus = 20
|
||||
sharpness = TRUE
|
||||
icon_state = "syndicate_knife"
|
||||
icon_living = "syndicate_knife"
|
||||
loot = list(/obj/effect/gibspawner/human)
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
///What kind of footstep this mob should have. Null if it shouldn't have any.
|
||||
var/footstep_type
|
||||
|
||||
//How much wounding power it has
|
||||
var/wound_bonus = CANT_WOUND
|
||||
//How much bare wounding power it has
|
||||
var/bare_wound_bonus = 0
|
||||
//If the attacks from this are sharp
|
||||
var/sharpness = FALSE
|
||||
|
||||
/mob/living/simple_animal/Initialize()
|
||||
. = ..()
|
||||
GLOB.simple_animals[AIStatus] += src
|
||||
|
||||
@@ -8,6 +8,18 @@
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_slug
|
||||
custom_materials = list(/datum/material/iron=4000)
|
||||
|
||||
obj/item/ammo_casing/shotgun/executioner
|
||||
name = "executioner slug"
|
||||
desc = "A 12 gauge lead slug purpose built to annihilate flesh on impact."
|
||||
icon_state = "stunshell"
|
||||
projectile_type = /obj/projectile/bullet/shotgun_slug/executioner
|
||||
|
||||
/obj/item/ammo_casing/shotgun/pulverizer
|
||||
name = "pulverizer slug"
|
||||
desc = "A 12 gauge lead slug purpose built to annihilate bones on impact."
|
||||
icon_state = "stunshell"
|
||||
projectile_type = /obj/projectile/bullet/shotgun_slug/pulverizer
|
||||
|
||||
/obj/item/ammo_casing/shotgun/beanbag
|
||||
name = "beanbag slug"
|
||||
desc = "A weak beanbag slug for riot control."
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
select_name = "anti-vehicle"
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/hellfire
|
||||
projectile_type = /obj/projectile/beam/laser/hellfire
|
||||
e_cost = 130
|
||||
select_name = "maim"
|
||||
|
||||
/obj/item/ammo_casing/energy/laser/pulse
|
||||
projectile_type = /obj/item/projectile/beam/pulse
|
||||
e_cost = 200
|
||||
|
||||
@@ -184,6 +184,11 @@
|
||||
return
|
||||
if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected)
|
||||
return
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
for(var/datum/wound/W in C.all_wounds)
|
||||
if(W.try_treating(src, user))
|
||||
return // another coward cured!
|
||||
|
||||
if(istype(user))//Check if the user can use the gun, if the user isn't alive(turrets) assume it can.
|
||||
var/mob/living/L = user
|
||||
|
||||
@@ -44,6 +44,12 @@
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/lasergun/old)
|
||||
ammo_x_offset = 3
|
||||
|
||||
/obj/item/gun/energy/laser/hellgun
|
||||
name ="hellfire laser gun"
|
||||
desc = "A relic of a weapon, built before NT began installing regulators on its laser weaponry. This pattern of laser gun became infamous for the gruesome burn wounds it caused, and was quietly discontinued once it began to affect NT's reputation."
|
||||
icon_state = "hellgun"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire)
|
||||
|
||||
/obj/item/gun/energy/laser/captain
|
||||
name = "antique laser gun"
|
||||
icon_state = "caplaser"
|
||||
|
||||
@@ -154,6 +154,10 @@
|
||||
///If TRUE, hit mobs even if they're on the floor and not our target
|
||||
var/hit_stunned_targets = FALSE
|
||||
|
||||
wound_bonus = CANT_WOUND
|
||||
/// For telling whether we want to roll for bone breaking or lacerations if we're bothering with wounds
|
||||
var/sharpness = FALSE
|
||||
|
||||
/obj/item/projectile/Initialize()
|
||||
. = ..()
|
||||
permutated = list()
|
||||
|
||||
@@ -14,11 +14,26 @@
|
||||
ricochets_max = 50 //Honk!
|
||||
ricochet_chance = 80
|
||||
is_reflectable = TRUE
|
||||
wound_bonus = -20
|
||||
bare_wound_bonus = 10
|
||||
|
||||
/obj/item/projectile/beam/laser
|
||||
tracer_type = /obj/effect/projectile/tracer/laser
|
||||
muzzle_type = /obj/effect/projectile/muzzle/laser
|
||||
impact_type = /obj/effect/projectile/impact/laser
|
||||
wound_bonus = -30
|
||||
bare_wound_bonus = 40
|
||||
|
||||
//overclocked laser, does a bit more damage but has much higher wound power (-0 vs -20)
|
||||
/obj/projectile/beam/laser/hellfire
|
||||
name = "hellfire laser"
|
||||
wound_bonus = 0
|
||||
damage = 25
|
||||
speed = 0.6 // higher power = faster, that's how light works right
|
||||
|
||||
/obj/projectile/beam/laser/hellfire/Initialize()
|
||||
. = ..()
|
||||
transform *= 2
|
||||
|
||||
/obj/item/projectile/beam/laser/heavylaser
|
||||
name = "heavy laser"
|
||||
@@ -90,6 +105,7 @@
|
||||
tracer_type = /obj/effect/projectile/tracer/pulse
|
||||
muzzle_type = /obj/effect/projectile/muzzle/pulse
|
||||
impact_type = /obj/effect/projectile/impact/pulse
|
||||
wound_bonus = 10
|
||||
|
||||
/obj/item/projectile/beam/pulse/on_hit(atom/target, blocked = FALSE)
|
||||
. = ..()
|
||||
@@ -116,6 +132,8 @@
|
||||
damage = 30
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser
|
||||
light_color = LIGHT_COLOR_GREEN
|
||||
wound_bonus = -40
|
||||
bare_wound_bonus = 70
|
||||
|
||||
/obj/item/projectile/beam/emitter/singularity_pull()
|
||||
return
|
||||
|
||||
@@ -8,3 +8,4 @@
|
||||
flag = "bullet"
|
||||
hitsound_wall = "ricochet"
|
||||
impact_effect_type = /obj/effect/temp_visual/impact_effect
|
||||
sharpness = TRUE
|
||||
@@ -19,6 +19,8 @@
|
||||
ricochet_chance = 50
|
||||
ricochet_auto_aim_angle = 10
|
||||
ricochet_auto_aim_range = 3
|
||||
wound_bonus = -35
|
||||
sharpness = TRUE
|
||||
|
||||
/obj/item/projectile/bullet/c38/match
|
||||
name = ".38 Match bullet"
|
||||
@@ -29,6 +31,7 @@
|
||||
ricochet_incidence_leeway = 50
|
||||
ricochet_decay_chance = 1
|
||||
ricochet_decay_damage = 1
|
||||
wound_bonus = 0
|
||||
|
||||
/obj/item/projectile/bullet/c38/match/bouncy
|
||||
name = ".38 Rubber bullet"
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
name = "12g shotgun slug"
|
||||
damage = 60
|
||||
|
||||
/obj/projectile/bullet/shotgun_slug/executioner
|
||||
name = "executioner slug" // admin only, can dismember limbs
|
||||
sharpness = TRUE
|
||||
wound_bonus = 0
|
||||
|
||||
/obj/projectile/bullet/shotgun_slug/pulverizer
|
||||
name = "pulverizer slug" // admin only, can crush bones
|
||||
sharpness = FALSE
|
||||
wound_bonus = 0
|
||||
|
||||
/obj/item/projectile/bullet/shotgun_beanbag
|
||||
name = "beanbag slug"
|
||||
damage = 5
|
||||
damage = 10
|
||||
stamina = 70
|
||||
wound_bonus = 20
|
||||
sharpness = FALSE
|
||||
|
||||
/obj/item/projectile/bullet/incendiary/shotgun
|
||||
name = "incendiary slug"
|
||||
@@ -77,6 +89,7 @@
|
||||
/obj/item/projectile/bullet/pellet/shotgun_buckshot
|
||||
name = "buckshot pellet"
|
||||
damage = 12.5
|
||||
wound_bonus = -10
|
||||
|
||||
/obj/item/projectile/bullet/pellet/shotgun_rubbershot
|
||||
name = "rubbershot pellet"
|
||||
|
||||
@@ -144,6 +144,9 @@
|
||||
M.adjustFireLoss(-power, 0)
|
||||
M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs
|
||||
M.adjustCloneLoss(-power, 0)
|
||||
for(var/i in M.all_wounds)
|
||||
var/datum/wound/W = i
|
||||
W.on_xadone(power)
|
||||
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
|
||||
. = 1
|
||||
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5)
|
||||
@@ -192,6 +195,9 @@
|
||||
M.adjustFireLoss(-1.5 * power, 0)
|
||||
M.adjustToxLoss(-power, 0, TRUE)
|
||||
M.adjustCloneLoss(-power, 0)
|
||||
for(var/i in M.all_wounds)
|
||||
var/datum/wound/W = i
|
||||
W.on_xadone(power)
|
||||
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
|
||||
. = 1
|
||||
..()
|
||||
@@ -231,7 +237,7 @@
|
||||
|
||||
/datum/reagent/medicine/spaceacillin
|
||||
name = "Spaceacillin"
|
||||
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with."
|
||||
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns."
|
||||
color = "#f2f2f2"
|
||||
metabolization_rate = 0.1 * REAGENTS_METABOLISM
|
||||
pH = 8.1
|
||||
@@ -403,7 +409,7 @@
|
||||
|
||||
/datum/reagent/medicine/mine_salve
|
||||
name = "Miner's Salve"
|
||||
description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed."
|
||||
description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed. Also great for treating severe burn wounds in a pinch."
|
||||
reagent_state = LIQUID
|
||||
color = "#6D6374"
|
||||
metabolization_rate = 0.4 * REAGENTS_METABOLISM
|
||||
@@ -432,7 +438,7 @@
|
||||
// +10% success propability on each step, useful while operating in less-than-perfect conditions
|
||||
|
||||
if(show_message)
|
||||
to_chat(M, "<span class='danger'>You feel your wounds fade away to nothing!</span>" )
|
||||
to_chat(M, "<span class='danger'>You feel your injuries fade away to nothing!</span>" )
|
||||
..()
|
||||
|
||||
/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M)
|
||||
@@ -453,10 +459,10 @@
|
||||
|
||||
/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
|
||||
if(iscarbon(M))
|
||||
if (M.stat == DEAD)
|
||||
var/mob/living/carbon/C = M
|
||||
if(M.stat == DEAD)
|
||||
show_message = 0
|
||||
if(method in list(INGEST, VAPOR))
|
||||
var/mob/living/carbon/C = M
|
||||
C.losebreath++
|
||||
C.emote("cough")
|
||||
to_chat(M, "<span class='danger'>You feel your throat closing up!</span>")
|
||||
@@ -465,6 +471,8 @@
|
||||
else if(method in list(PATCH, TOUCH))
|
||||
M.adjustBruteLoss(-1 * reac_volume)
|
||||
M.adjustFireLoss(-1 * reac_volume)
|
||||
for(var/datum/wound/burn/burn_wound in C.all_wounds)
|
||||
burn_wound.regenerate_flesh(reac_volume)
|
||||
if(show_message)
|
||||
to_chat(M, "<span class='danger'>You feel your burns and bruises healing! It stings like hell!</span>")
|
||||
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
|
||||
@@ -1552,10 +1560,6 @@
|
||||
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
|
||||
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25)
|
||||
M.adjustBruteLoss(-0.35, 0)
|
||||
if(prob(50))
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.bleed_rate = max(H.bleed_rate - 1, 0)
|
||||
..()
|
||||
. = 1
|
||||
|
||||
@@ -1588,3 +1592,10 @@
|
||||
to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom
|
||||
..()
|
||||
|
||||
// handled in cut wounds process
|
||||
/datum/reagent/medicine/coagulant
|
||||
name = "Sanguirite"
|
||||
description = "A coagulant used to help open cuts clot faster."
|
||||
reagent_state = LIQUID
|
||||
color = "#bb2424"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
|
||||
@@ -2296,3 +2296,36 @@
|
||||
if(data["blood_DNA"])
|
||||
S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
|
||||
|
||||
/datum/reagent/determination
|
||||
name = "Determination"
|
||||
description = "For when you need to push on a little more. Do NOT allow near plants."
|
||||
reagent_state = LIQUID
|
||||
color = "#D2FFFA"
|
||||
metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks
|
||||
/// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound
|
||||
var/significant = FALSE
|
||||
|
||||
/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M)
|
||||
if(significant)
|
||||
var/stam_crash = 0
|
||||
for(var/thing in M.all_wounds)
|
||||
var/datum/wound/W = thing
|
||||
stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush
|
||||
M.adjustStaminaLoss(stam_crash)
|
||||
M.remove_status_effect(STATUS_EFFECT_DETERMINED)
|
||||
..()
|
||||
|
||||
/datum/reagent/determination/on_mob_life(mob/living/carbon/M)
|
||||
if(!significant && volume >= WOUND_DETERMINATION_SEVERE)
|
||||
significant = TRUE
|
||||
M.apply_status_effect(STATUS_EFFECT_DETERMINED) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high
|
||||
|
||||
volume = min(volume, WOUND_DETERMINATION_MAX)
|
||||
|
||||
for(var/thing in M.all_wounds)
|
||||
var/datum/wound/W = thing
|
||||
var/obj/item/bodypart/wounded_part = W.limb
|
||||
if(wounded_part)
|
||||
wounded_part.heal_damage(0.25, 0.25)
|
||||
M.adjustStaminaLoss(-0.25*REM) // the more wounds, the more stamina regen
|
||||
..()
|
||||
|
||||
@@ -154,6 +154,11 @@
|
||||
pH = 12
|
||||
value = REAGENT_VALUE_RARE
|
||||
|
||||
/datum/reagent/toxin/carpotoxin/on_mob_life(mob/living/carbon/M)
|
||||
. = ..()
|
||||
for(var/i in M.all_scars)
|
||||
qdel(i)
|
||||
|
||||
/datum/reagent/toxin/zombiepowder
|
||||
name = "Zombie Powder"
|
||||
description = "A strong neurotoxin that puts the subject into a death-like state."
|
||||
@@ -736,22 +741,13 @@
|
||||
|
||||
/datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic.
|
||||
name = "Heparin"
|
||||
description = "A powerful anticoagulant. Victims will bleed uncontrollably and suffer scaling bruising."
|
||||
description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster"
|
||||
reagent_state = LIQUID
|
||||
color = "#C8C8C8" //RGB: 200, 200, 200
|
||||
metabolization_rate = 0.2 * REAGENTS_METABOLISM
|
||||
toxpwr = 0
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
/datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.bleed_rate = min(H.bleed_rate + 2, 8)
|
||||
H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding
|
||||
. = 1
|
||||
return ..() || .
|
||||
|
||||
|
||||
/datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious
|
||||
name = "Rotatium"
|
||||
description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild."
|
||||
|
||||
@@ -90,12 +90,12 @@
|
||||
item_state = "medipen"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
|
||||
amount_per_transfer_from_this = 13
|
||||
volume = 13
|
||||
amount_per_transfer_from_this = 15
|
||||
volume = 15
|
||||
ignore_flags = 1 //so you can medipen through hardsuits
|
||||
reagent_flags = DRAWABLE
|
||||
flags_1 = null
|
||||
list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3)
|
||||
list_reagents = list(/datum/reagent/medicine/epinephrine = 10, /datum/reagent/preservahyde = 3, /datum/reagent/medicine/coagulant = 2)
|
||||
custom_premium_price = PRICE_ALMOST_EXPENSIVE
|
||||
|
||||
/obj/item/reagent_containers/hypospray/medipen/suicide_act(mob/living/carbon/user)
|
||||
@@ -133,6 +133,13 @@
|
||||
else
|
||||
. += "<span class='notice'>It is spent.</span>"
|
||||
|
||||
/obj/item/reagent_containers/hypospray/medipen/ekit
|
||||
name = "emergency first-aid autoinjector"
|
||||
desc = "An epinephrine medipen with trace amounts of coagulants and antibiotics to help stabilize bad cuts and burns."
|
||||
volume = 15
|
||||
amount_per_transfer_from_this = 15
|
||||
list_reagents = list(/datum/reagent/medicine/epinephrine = 12, /datum/reagent/medicine/coagulant = 2.5, /datum/reagent/medicine/spaceacillin = 0.5)
|
||||
|
||||
/obj/item/reagent_containers/hypospray/medipen/stimulants
|
||||
name = "illegal stimpack medipen"
|
||||
desc = "A highly illegal medipen due to its load and small injections, allow for five uses before being drained"
|
||||
|
||||
+18
@@ -119,6 +119,24 @@
|
||||
category = list("initial", "Medical","Tool Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/bonesetter
|
||||
name = "Bonesetter"
|
||||
id = "bonesetter"
|
||||
build_type = AUTOLATHE | PROTOLATHE
|
||||
materials = list(/datum/material/iron = 1000)
|
||||
build_path = /obj/item/bonesetter
|
||||
category = list("initial", "Medical", "Tool Designs")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
|
||||
|
||||
/datum/design/sticky_tape/surgical
|
||||
name = "Surgical Tape"
|
||||
id = "surgical_tape"
|
||||
build_type = PROTOLATHE
|
||||
materials = list(/datum/material/plastic = 500)
|
||||
build_path = /obj/item/stack/sticky_tape/surgical
|
||||
category = list("initial", "Medical")
|
||||
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
|
||||
|
||||
/datum/design/beaker
|
||||
name = "Beaker"
|
||||
id = "beaker"
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
display_name = "Advanced Surgery Tools"
|
||||
description = "Refined and improved redesigns for the run-of-the-mill medical utensils."
|
||||
prereq_ids = list("adv_biotech", "adv_surgery")
|
||||
design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv")
|
||||
design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv", "bonesetter", "surgical_tape")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/adv_surgery
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr)
|
||||
if(istype(user))
|
||||
if(istype(user, /mob/living/simple_animal/slaughter))
|
||||
var/mob/living/simple_animal/slaughter/slaught = user
|
||||
slaught.current_hitstreak = 0
|
||||
slaught.wound_bonus = initial(slaught.wound_bonus)
|
||||
slaught.bare_wound_bonus = initial(slaught.bare_wound_bonus)
|
||||
if(phased)
|
||||
if(user.phasein(target))
|
||||
phased = 0
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
var/damage_percent = (stored.maxHealth - stored.health)/stored.maxHealth;
|
||||
var/damapply = damage_percent * shape.maxHealth;
|
||||
|
||||
shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE);
|
||||
shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND);
|
||||
slink = soullink(/datum/soullink/shapeshift, stored , shape)
|
||||
slink.source = src
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
var/damage_percent = (shape.maxHealth - shape.health)/shape.maxHealth;
|
||||
var/damapply = stored.maxHealth * damage_percent
|
||||
|
||||
stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE)
|
||||
stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE, wound_bonus=CANT_WOUND)
|
||||
qdel(shape)
|
||||
qdel(src)
|
||||
|
||||
|
||||
+194
-290
@@ -71,6 +71,28 @@
|
||||
var/medium_burn_msg = "blistered"
|
||||
var/heavy_burn_msg = "peeling away"
|
||||
|
||||
/// The wounds currently afflicting this body part
|
||||
var/list/wounds
|
||||
|
||||
/// The scars currently afflicting this body part
|
||||
var/list/scars
|
||||
/// Our current stored wound damage multiplier
|
||||
var/wound_damage_multiplier = 1
|
||||
|
||||
/// This number is subtracted from all wound rolls on this bodypart, higher numbers mean more defense, negative means easier to wound
|
||||
var/wound_resistance = 0
|
||||
/// When this bodypart hits max damage, this number is added to all wound rolls. Obviously only relevant for bodyparts that have damage caps.
|
||||
var/disabled_wound_penalty = 15
|
||||
|
||||
/// A hat won't cover your face, but a shirt covering your chest will cover your... you know, chest
|
||||
var/scars_covered_by_clothes = TRUE
|
||||
/// Descriptions for the locations on the limb for scars to be assigned, just cosmetic
|
||||
var/list/specific_locations = list("general area")
|
||||
/// So we know if we need to scream if this limb hits max damage
|
||||
var/last_maxed
|
||||
/// How much generic bleedstacks we have on this bodypart
|
||||
var/generic_bleedstacks
|
||||
|
||||
/obj/item/bodypart/examine(mob/user)
|
||||
. = ..()
|
||||
if(brute_dam > DAMAGE_PRECISION)
|
||||
@@ -149,7 +171,7 @@
|
||||
//Applies brute and burn damage to the organ. Returns 1 if the damage-icon states changed at all.
|
||||
//Damage will not exceed max_damage using this proc
|
||||
//Cannot apply negative damage
|
||||
/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE)
|
||||
/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, stamina = 0, blocked = 0, updating_health = TRUE, required_status = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = FALSE) // maybe separate BRUTE_SHARP and BRUTE_OTHER eventually somehow hmm
|
||||
if(owner && (owner.status_flags & GODMODE))
|
||||
return FALSE //godmode
|
||||
var/dmg_mlt = CONFIG_GET(number/damage_multiplier)
|
||||
@@ -163,20 +185,38 @@
|
||||
if(!brute && !burn && !stamina)
|
||||
return FALSE
|
||||
|
||||
brute *= wound_damage_multiplier
|
||||
burn *= wound_damage_multiplier
|
||||
|
||||
switch(animal_origin)
|
||||
if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around
|
||||
burn *= 1.2
|
||||
|
||||
var/wounding_type = (brute > burn ? WOUND_BRUTE : WOUND_BURN)
|
||||
var/wounding_dmg = max(brute, burn)
|
||||
if(wounding_type == WOUND_BRUTE && sharpness)
|
||||
wounding_type = WOUND_SHARP
|
||||
// i know this is effectively the same check as above but i don't know if those can null the damage by rounding and want to be safe
|
||||
if(owner && wounding_dmg > 4 && wound_bonus != CANT_WOUND)
|
||||
// if you want to make tox wounds or some other type, this will need to be expanded and made more modular
|
||||
// handle all our wounding stuff
|
||||
check_wounding(wounding_type, wounding_dmg, wound_bonus, bare_wound_bonus)
|
||||
|
||||
var/can_inflict = max_damage - get_damage()
|
||||
if(can_inflict <= 0)
|
||||
return FALSE
|
||||
|
||||
var/total_damage = brute + burn
|
||||
|
||||
if(total_damage > can_inflict)
|
||||
if(total_damage > can_inflict && total_damage > 0) // TODO: the second part of this check should be removed once disabling is all done
|
||||
brute = round(brute * (max_damage / total_damage),DAMAGE_PRECISION)
|
||||
burn = round(burn * (max_damage / total_damage),DAMAGE_PRECISION)
|
||||
|
||||
if(can_inflict <= 0)
|
||||
return FALSE
|
||||
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/W = i
|
||||
W.receive_damage(wounding_type, wounding_dmg, wound_bonus)
|
||||
|
||||
brute_dam += brute
|
||||
burn_dam += burn
|
||||
|
||||
@@ -196,6 +236,107 @@
|
||||
update_disabled()
|
||||
return update_bodypart_damage_state()
|
||||
|
||||
/**
|
||||
* check_wounding() is where we handle rolling for, selecting, and applying a wound if we meet the criteria
|
||||
*
|
||||
* We generate a "score" for how woundable the attack was based on the damage and other factors discussed in [check_wounding_mods()], then go down the list from most severe to least severe wounds in that category.
|
||||
* We can promote a wound from a lesser to a higher severity this way, but we give up if we have a wound of the given type and fail to roll a higher severity, so no sidegrades/downgrades
|
||||
*
|
||||
* Arguments:
|
||||
* * woundtype- Either WOUND_SHARP, WOUND_BRUTE, or WOUND_BURN based on the attack type.
|
||||
* * damage- How much damage is tied to this attack, since wounding potential scales with damage in an attack (see: WOUND_DAMAGE_EXPONENT)
|
||||
* * wound_bonus- The wound_bonus of an attack
|
||||
* * bare_wound_bonus- The bare_wound_bonus of an attack
|
||||
*/
|
||||
/obj/item/bodypart/proc/check_wounding(woundtype, damage, wound_bonus, bare_wound_bonus)
|
||||
// actually roll wounds if applicable
|
||||
if(HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE))
|
||||
damage *= 1.5
|
||||
|
||||
var/base_roll = rand(1, round(damage ** WOUND_DAMAGE_EXPONENT))
|
||||
var/injury_roll = base_roll
|
||||
injury_roll += check_woundings_mods(woundtype, damage, wound_bonus, bare_wound_bonus)
|
||||
var/list/wounds_checking
|
||||
|
||||
switch(woundtype)
|
||||
if(WOUND_SHARP)
|
||||
wounds_checking = WOUND_LIST_CUT
|
||||
if(WOUND_BRUTE)
|
||||
wounds_checking = WOUND_LIST_BONE
|
||||
if(WOUND_BURN)
|
||||
wounds_checking = WOUND_LIST_BURN
|
||||
|
||||
//cycle through the wounds of the relevant category from the most severe down
|
||||
for(var/PW in wounds_checking)
|
||||
var/datum/wound/possible_wound = PW
|
||||
var/datum/wound/replaced_wound
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/existing_wound = i
|
||||
if(existing_wound.type in wounds_checking)
|
||||
if(existing_wound.severity >= initial(possible_wound.severity))
|
||||
return
|
||||
else
|
||||
replaced_wound = existing_wound
|
||||
|
||||
if(initial(possible_wound.threshold_minimum) < injury_roll)
|
||||
if(replaced_wound)
|
||||
var/datum/wound/new_wound = replaced_wound.replace_wound(possible_wound)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
|
||||
else
|
||||
var/datum/wound/new_wound = new possible_wound
|
||||
new_wound.apply_wound(src)
|
||||
log_wound(owner, new_wound, damage, wound_bonus, bare_wound_bonus, base_roll)
|
||||
return
|
||||
|
||||
// try forcing a specific wound, but only if there isn't already a wound of that severity or greater for that type on this bodypart
|
||||
/obj/item/bodypart/proc/force_wound_upwards(specific_woundtype, smited = FALSE)
|
||||
var/datum/wound/potential_wound = specific_woundtype
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/existing_wound = i
|
||||
if(existing_wound.type in (initial(potential_wound.wound_type)))
|
||||
if(existing_wound.severity < initial(potential_wound.severity)) // we only try if the existing one is inferior to the one we're trying to force
|
||||
existing_wound.replace_wound(potential_wound, smited)
|
||||
return
|
||||
|
||||
var/datum/wound/new_wound = new potential_wound
|
||||
new_wound.apply_wound(src, smited = smited)
|
||||
|
||||
/obj/item/bodypart/proc/check_woundings_mods(wounding_type, damage, wound_bonus, bare_wound_bonus)
|
||||
var/armor_ablation = 0
|
||||
var/injury_mod = 0
|
||||
|
||||
//var/bwb = 0
|
||||
|
||||
if(owner && ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/clothing = H.clothingonpart(src)
|
||||
for(var/c in clothing)
|
||||
var/obj/item/clothing/C = c
|
||||
// unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary
|
||||
armor_ablation += C.armor.getRating("wound")
|
||||
if(wounding_type == WOUND_SHARP)
|
||||
C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration)
|
||||
else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage()
|
||||
C.take_damage_zone(body_zone, damage, BURN, armour_penetration)
|
||||
|
||||
if(!armor_ablation)
|
||||
injury_mod += bare_wound_bonus
|
||||
|
||||
injury_mod -= armor_ablation
|
||||
injury_mod += wound_bonus
|
||||
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
injury_mod += W.threshold_penalty
|
||||
|
||||
var/part_mod = -wound_resistance
|
||||
if(is_disabled())
|
||||
part_mod += disabled_wound_penalty
|
||||
|
||||
injury_mod += part_mod
|
||||
|
||||
return injury_mod
|
||||
|
||||
//Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all.
|
||||
//Damage cannot go below zero.
|
||||
//Cannot remove negative damage (i.e. apply damage)
|
||||
@@ -227,16 +368,29 @@
|
||||
|
||||
//Checks disabled status thresholds
|
||||
/obj/item/bodypart/proc/update_disabled()
|
||||
if(!owner)
|
||||
return
|
||||
set_disabled(is_disabled())
|
||||
|
||||
/obj/item/bodypart/proc/is_disabled()
|
||||
if(!owner)
|
||||
return
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/W = i
|
||||
if(W.disabling)
|
||||
return BODYPART_DISABLED_WOUND
|
||||
if(can_dismember() && !HAS_TRAIT(owner, TRAIT_NODISMEMBER))
|
||||
. = disabled //inertia, to avoid limbs healing 0.1 damage and being re-enabled
|
||||
if((get_damage(TRUE) >= max_damage) || (HAS_TRAIT(owner, TRAIT_EASYLIMBDISABLE) && (get_damage(TRUE) >= (max_damage * 0.6)))) //Easy limb disable disables the limb at 40% health instead of 0%
|
||||
return BODYPART_DISABLED_DAMAGE
|
||||
if(disabled && (get_damage(TRUE) <= (max_damage * 0.5)))
|
||||
if(!last_maxed)
|
||||
owner.emote("scream")
|
||||
last_maxed = TRUE
|
||||
if(!is_organic_limb())
|
||||
return BODYPART_DISABLED_DAMAGE
|
||||
else if(disabled && (get_damage(TRUE) <= (max_damage * 0.8))) // reenabled at 80% now instead of 50% as of wounds update
|
||||
last_maxed = FALSE
|
||||
return BODYPART_NOT_DISABLED
|
||||
else
|
||||
return BODYPART_NOT_DISABLED
|
||||
@@ -251,9 +405,11 @@
|
||||
|
||||
|
||||
/obj/item/bodypart/proc/set_disabled(new_disabled)
|
||||
if(disabled == new_disabled)
|
||||
if(disabled == new_disabled || !owner)
|
||||
return FALSE
|
||||
disabled = new_disabled
|
||||
if(disabled && owner.get_item_for_held_index(held_index))
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
owner.update_health_hud() //update the healthdoll
|
||||
owner.update_body()
|
||||
owner.update_mobility()
|
||||
@@ -581,293 +737,41 @@
|
||||
drop_organs()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/bodypart/chest
|
||||
name = BODY_ZONE_CHEST
|
||||
desc = "It's impolite to stare at a person's chest."
|
||||
icon_state = "default_human_chest"
|
||||
max_damage = 200
|
||||
body_zone = BODY_ZONE_CHEST
|
||||
body_part = CHEST
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
stam_damage_coeff = 1
|
||||
max_stamina_damage = 200
|
||||
var/obj/item/cavity_item
|
||||
|
||||
/obj/item/bodypart/chest/can_dismember(obj/item/I)
|
||||
if(!((owner.stat == DEAD) || owner.InFullCritical()))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/Destroy()
|
||||
if(cavity_item)
|
||||
qdel(cavity_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/drop_organs(mob/user)
|
||||
if(cavity_item)
|
||||
cavity_item.forceMove(user.loc)
|
||||
cavity_item = null
|
||||
..()
|
||||
|
||||
/obj/item/bodypart/chest/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_chest"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 500
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/larva
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "larva_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 50
|
||||
animal_origin = LARVA_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm
|
||||
name = "left arm"
|
||||
desc = "Did you know that the word 'sinister' stems originally from the \
|
||||
Latin 'sinestra' (left hand), because the left hand was supposed to \
|
||||
be possessed by the devil? This arm appears to be possessed by no \
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
|
||||
/obj/item/bodypart/l_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
/// Get whatever wound of the given type is currently attached to this limb, if any
|
||||
/obj/item/bodypart/proc/get_wound_type(checking_type)
|
||||
if(isnull(wounds))
|
||||
return
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(L)
|
||||
L.update_icon()
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
if(istype(W, checking_type))
|
||||
return W
|
||||
|
||||
/obj/item/bodypart/l_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_x = -5
|
||||
px_y = -3
|
||||
/// very rough start for updating efficiency and other stats on a body part whenever a wound is gained/lost
|
||||
/obj/item/bodypart/proc/update_wounds()
|
||||
var/dam_mul = 1 //initial(wound_damage_multiplier)
|
||||
// we can only have one wound per type, but remember there's multiple types
|
||||
for(var/datum/wound/W in wounds)
|
||||
dam_mul *= W.damage_mulitplier_penalty
|
||||
wound_damage_multiplier = dam_mul
|
||||
update_disabled()
|
||||
|
||||
/obj/item/bodypart/l_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm
|
||||
name = "right arm"
|
||||
desc = "Over 87% of humans are right handed. That figure is much lower \
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER)
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
max_stamina_damage = 50
|
||||
|
||||
/obj/item/bodypart/r_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
/obj/item/bodypart/proc/get_bleed_rate()
|
||||
if(status != BODYPART_ORGANIC) // maybe in the future we can bleed oil from aug parts, but not now
|
||||
return
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(R)
|
||||
R.update_icon()
|
||||
var/bleed_rate = 0
|
||||
if(generic_bleedstacks > 0)
|
||||
bleed_rate++
|
||||
if(brute_dam >= 40)
|
||||
bleed_rate += (brute_dam * 0.008)
|
||||
|
||||
//We want an accurate reading of .len
|
||||
listclearnulls(embedded_objects)
|
||||
for(var/obj/item/embeddies in embedded_objects)
|
||||
if(!embeddies.isEmbedHarmless())
|
||||
bleed_rate += 0.5
|
||||
|
||||
/obj/item/bodypart/r_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_x = 5
|
||||
px_y = -3
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
bleed_rate += W.blood_flow
|
||||
|
||||
/obj/item/bodypart/r_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg
|
||||
name = "left leg"
|
||||
desc = "Some athletes prefer to tie their left shoelaces first for good \
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
max_stamina_damage = 50
|
||||
|
||||
/obj/item/bodypart/l_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!. || owner.stat >= UNCONSCIOUS)
|
||||
return
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
|
||||
/obj/item/bodypart/l_leg/digitigrade
|
||||
name = "left digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/l_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/l_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg
|
||||
name = "right leg"
|
||||
desc = "You put your right leg in, your right leg out. In, out, in, out, \
|
||||
shake it all about. And apparently then it detaches.\n\
|
||||
The hokey pokey has certainly changed a lot since space colonisation."
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
stam_heal_tick = STAM_RECOVERY_LIMB
|
||||
|
||||
/obj/item/bodypart/r_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!. || owner.stat >= UNCONSCIOUS)
|
||||
return
|
||||
switch(disabled)
|
||||
if(BODYPART_DISABLED_DAMAGE)
|
||||
owner.emote("scream")
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(BODYPART_DISABLED_PARALYSIS)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/r_leg/digitigrade
|
||||
name = "right digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/r_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/r_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
return bleed_rate
|
||||
@@ -15,7 +15,7 @@
|
||||
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
|
||||
return FALSE
|
||||
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
|
||||
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage
|
||||
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage
|
||||
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
|
||||
C.emote("scream")
|
||||
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
|
||||
@@ -83,11 +83,12 @@
|
||||
|
||||
|
||||
//limb removal. The "special" argument is used for swapping a limb with a new one without the effects of losing a limb kicking in.
|
||||
/obj/item/bodypart/proc/drop_limb(special)
|
||||
/obj/item/bodypart/proc/drop_limb(special, dismembered)
|
||||
if(!owner)
|
||||
return
|
||||
var/atom/Tsec = owner.drop_location()
|
||||
var/mob/living/carbon/C = owner
|
||||
SEND_SIGNAL(C, COMSIG_CARBON_REMOVE_LIMB, src, dismembered)
|
||||
update_limb(1)
|
||||
C.bodyparts -= src
|
||||
|
||||
@@ -95,6 +96,15 @@
|
||||
C.dropItemToGround(owner.get_item_for_held_index(held_index), 1)
|
||||
C.hand_bodyparts[held_index] = null
|
||||
|
||||
for(var/thing in scars)
|
||||
var/datum/scar/S = thing
|
||||
S.victim = null
|
||||
LAZYREMOVE(owner.all_scars, S)
|
||||
|
||||
for(var/thing in wounds)
|
||||
var/datum/wound/W = thing
|
||||
W.remove_wound(TRUE)
|
||||
|
||||
owner = null
|
||||
|
||||
for(var/X in C.surgeries) //if we had an ongoing surgery on that limb, we stop it.
|
||||
@@ -298,6 +308,15 @@
|
||||
for(var/obj/item/organ/O in contents)
|
||||
O.Insert(C)
|
||||
|
||||
for(var/thing in scars)
|
||||
var/datum/scar/S = thing
|
||||
S.victim = C
|
||||
LAZYADD(C.all_scars, thing)
|
||||
|
||||
for(var/i in wounds)
|
||||
var/datum/wound/W = i
|
||||
W.apply_wound(src, TRUE)
|
||||
|
||||
update_bodypart_damage_state()
|
||||
update_disabled()
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
//If the head is a special sprite
|
||||
var/custom_head
|
||||
|
||||
wound_resistance = 10
|
||||
specific_locations = list("left eyebrow", "cheekbone", "neck", "throat", "jawline", "entire face")
|
||||
scars_covered_by_clothes = FALSE
|
||||
|
||||
/obj/item/bodypart/head/can_dismember(obj/item/I)
|
||||
if(!((owner.stat == DEAD) || owner.InFullCritical()))
|
||||
return FALSE
|
||||
|
||||
@@ -10,6 +10,16 @@
|
||||
if(L.body_zone == zone)
|
||||
return L
|
||||
|
||||
///Get the bodypart for whatever hand we have active, Only relevant for carbons
|
||||
/mob/proc/get_active_hand()
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/get_active_hand()
|
||||
var/which_hand = BODY_ZONE_PRECISE_L_HAND
|
||||
if(!(active_hand_index % 2))
|
||||
which_hand = BODY_ZONE_PRECISE_R_HAND
|
||||
return get_bodypart(check_zone(which_hand))
|
||||
|
||||
/mob/living/carbon/has_hand_for_held_index(i)
|
||||
if(i)
|
||||
var/obj/item/bodypart/L = hand_bodyparts[i]
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
|
||||
/obj/item/bodypart/chest
|
||||
name = BODY_ZONE_CHEST
|
||||
desc = "It's impolite to stare at a person's chest."
|
||||
icon_state = "default_human_chest"
|
||||
max_damage = 200
|
||||
body_zone = BODY_ZONE_CHEST
|
||||
body_part = CHEST
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
stam_damage_coeff = 1
|
||||
max_stamina_damage = 120
|
||||
var/obj/item/cavity_item
|
||||
specific_locations = list("upper chest", "lower abdomen", "midsection", "collarbone", "lower back")
|
||||
wound_resistance = 10
|
||||
|
||||
/obj/item/bodypart/chest/can_dismember(obj/item/I)
|
||||
if(!((owner.stat == DEAD) || owner.InFullCritical()))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/Destroy()
|
||||
QDEL_NULL(cavity_item)
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/chest/drop_organs(mob/user, violent_removal)
|
||||
if(cavity_item)
|
||||
cavity_item.forceMove(drop_location())
|
||||
cavity_item = null
|
||||
..()
|
||||
|
||||
/obj/item/bodypart/chest/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_chest"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
|
||||
/obj/item/bodypart/chest/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 500
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/chest/larva
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "larva_chest"
|
||||
dismemberable = 0
|
||||
max_damage = 50
|
||||
animal_origin = LARVA_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm
|
||||
name = "left arm"
|
||||
desc = "Did you know that the word 'sinister' stems originally from the \
|
||||
Latin 'sinestra' (left hand), because the left hand was supposed to \
|
||||
be possessed by the devil? This arm appears to be possessed by no \
|
||||
one though."
|
||||
icon_state = "default_human_l_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
max_stamina_damage = 50
|
||||
body_zone = BODY_ZONE_L_ARM
|
||||
body_part = ARM_LEFT
|
||||
aux_zone = BODY_ZONE_PRECISE_L_HAND
|
||||
aux_layer = HANDS_PART_LAYER
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 1
|
||||
px_x = -6
|
||||
px_y = 0
|
||||
specific_locations = list("outer left forearm", "inner left wrist", "left elbow", "left bicep", "left shoulder")
|
||||
|
||||
/obj/item/bodypart/l_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/L = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(L)
|
||||
L.update_icon()
|
||||
|
||||
/obj/item/bodypart/l_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_x = -5
|
||||
px_y = -3
|
||||
|
||||
/obj/item/bodypart/l_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm
|
||||
name = "right arm"
|
||||
desc = "Over 87% of humans are right handed. That figure is much lower \
|
||||
among humans missing their right arm."
|
||||
icon_state = "default_human_r_arm"
|
||||
attack_verb = list("slapped", "punched")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_ARM
|
||||
body_part = ARM_RIGHT
|
||||
aux_zone = BODY_ZONE_PRECISE_R_HAND
|
||||
aux_layer = HANDS_PART_LAYER
|
||||
body_damage_coeff = 0.75
|
||||
held_index = 2
|
||||
px_x = 6
|
||||
px_y = 0
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("outer right forearm", "inner right wrist", "right elbow", "right bicep", "right shoulder")
|
||||
|
||||
/obj/item/bodypart/r_arm/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_ARM))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_arm/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
if(held_index)
|
||||
owner.dropItemToGround(owner.get_item_for_held_index(held_index))
|
||||
if(owner.hud_used)
|
||||
var/obj/screen/inventory/hand/R = owner.hud_used.hand_slots["[held_index]"]
|
||||
if(R)
|
||||
R.update_icon()
|
||||
|
||||
/obj/item/bodypart/r_arm/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_arm"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_x = 5
|
||||
px_y = -3
|
||||
|
||||
/obj/item/bodypart/r_arm/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_arm"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_arm/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg
|
||||
name = "left leg"
|
||||
desc = "Some athletes prefer to tie their left shoelaces first for good \
|
||||
luck. In this instance, it probably would not have helped."
|
||||
icon_state = "default_human_l_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_L_LEG
|
||||
body_part = LEG_LEFT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = -2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("inner left thigh", "outer left calf", "outer left hip", " left kneecap", "lower left shin")
|
||||
|
||||
/obj/item/bodypart/l_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/l_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/l_leg/digitigrade
|
||||
name = "left digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/l_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_l_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/l_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_l_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/l_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg
|
||||
name = "right leg"
|
||||
desc = "You put your right leg in, your right leg out. In, out, in, out, \
|
||||
shake it all about. And apparently then it detaches.\n\
|
||||
The hokey pokey has certainly changed a lot since space colonisation."
|
||||
// alternative spellings of 'pokey' are availible
|
||||
icon_state = "default_human_r_leg"
|
||||
attack_verb = list("kicked", "stomped")
|
||||
max_damage = 50
|
||||
body_zone = BODY_ZONE_R_LEG
|
||||
body_part = LEG_RIGHT
|
||||
body_damage_coeff = 0.75
|
||||
px_x = 2
|
||||
px_y = 12
|
||||
max_stamina_damage = 50
|
||||
specific_locations = list("inner right thigh", "outer right calf", "outer right hip", "right kneecap", "lower right shin")
|
||||
|
||||
/obj/item/bodypart/r_leg/is_disabled()
|
||||
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
|
||||
return BODYPART_DISABLED_PARALYSIS
|
||||
return ..()
|
||||
|
||||
/obj/item/bodypart/r_leg/set_disabled(new_disabled)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(disabled == BODYPART_DISABLED_DAMAGE)
|
||||
if(owner.stat < UNCONSCIOUS)
|
||||
owner.emote("scream")
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>Your [name] is too damaged to function!</span>")
|
||||
else if(disabled == BODYPART_DISABLED_PARALYSIS)
|
||||
if(owner.stat < DEAD)
|
||||
to_chat(owner, "<span class='userdanger'>You can't feel your [name]!</span>")
|
||||
|
||||
/obj/item/bodypart/r_leg/digitigrade
|
||||
name = "right digitigrade leg"
|
||||
use_digitigrade = FULL_DIGITIGRADE
|
||||
|
||||
/obj/item/bodypart/r_leg/monkey
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "default_monkey_r_leg"
|
||||
animal_origin = MONKEY_BODYPART
|
||||
wound_resistance = -10
|
||||
px_y = 4
|
||||
|
||||
/obj/item/bodypart/r_leg/alien
|
||||
icon = 'icons/mob/animal_parts.dmi'
|
||||
icon_state = "alien_r_leg"
|
||||
px_x = 0
|
||||
px_y = 0
|
||||
dismemberable = 0
|
||||
max_damage = 100
|
||||
animal_origin = ALIEN_BODYPART
|
||||
|
||||
/obj/item/bodypart/r_leg/devil
|
||||
dismemberable = 0
|
||||
max_damage = 5000
|
||||
animal_origin = DEVIL_BODYPART
|
||||
@@ -0,0 +1,142 @@
|
||||
|
||||
/////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/brute/bone/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/brute/bone/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
|
||||
experience_given = MEDICAL_SKILL_MEDIUM
|
||||
|
||||
/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
|
||||
experience_given = MEDICAL_SKILL_MEDIUM
|
||||
|
||||
/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
|
||||
experience_given = MEDICAL_SKILL_MEDIUM
|
||||
|
||||
/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,108 @@
|
||||
|
||||
/////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
|
||||
experience_given = MEDICAL_SKILL_MEDIUM
|
||||
|
||||
/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
|
||||
experience_given = MEDICAL_SKILL_MEDIUM
|
||||
|
||||
/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
|
||||
burn_wound.force_bandage(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)
|
||||
@@ -31,7 +31,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
|
||||
|
||||
@@ -41,7 +42,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)
|
||||
|
||||
@@ -73,5 +75,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
|
||||
|
||||
@@ -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***************************/
|
||||
|
||||
@@ -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,7 +90,9 @@
|
||||
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
|
||||
@@ -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!")
|
||||
|
||||
@@ -318,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)))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user