/mob/living/carbon/human/getarmor(def_zone, type) var/armorval = 0 var/organnum = 0 if(def_zone) if(isbodypart(def_zone)) var/obj/item/bodypart/bp = def_zone if(bp.body_part) return checkarmor(def_zone, type) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(def_zone)) return checkarmor(affecting, type) //If a specific bodypart is targetted, check how that bodypart is protected and return the value. //If you don't specify a bodypart, it checks ALL your bodyparts for protection, and averages out the values for(var/X in bodyparts) var/obj/item/bodypart/BP = X armorval += checkarmor(BP, type) organnum++ return (armorval/max(organnum, 1)) /mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type) if(!d_type || !def_zone) return 0 var/protection = 0 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(istype(bp, /obj/item/clothing)) var/obj/item/clothing/C = bp if(C.body_parts_covered & def_zone.body_part) protection += C.armor.getRating(d_type) protection += physiology.armor.getRating(d_type) return protection /mob/living/carbon/human/on_hit(obj/item/projectile/P) if(dna && dna.species) dna.species.on_hit(P, src) /mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone) if(dna && dna.species) var/spec_return = dna.species.bullet_act(P, src) if(spec_return) return spec_return if(mind) //martial art stuff if(mind.martial_art && mind.martial_art.can_use(src)) //Some martial arts users can deflect projectiles! var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone) if(!(martial_art_result == BULLET_ACT_HIT)) return martial_art_result return ..() /mob/living/carbon/human/can_embed(obj/item/I) if(I.get_sharpness() || is_pointed(I) || is_type_in_typecache(I, GLOB.can_embed_types)) return TRUE return FALSE /mob/living/carbon/human/proc/check_martial_melee_block() if(mind) if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) return TRUE return FALSE /mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = FALSE, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) return dna?.species?.spec_hitby(AM, src) || ..() /mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (HAS_TRAIT(src, TRAIT_FAT)) && ismonkey(pulling)) devour_mob(pulling) else ..() /mob/living/carbon/human/grippedby(mob/living/user, instant = FALSE) if(w_uniform) w_uniform.add_fingerprint(user) ..() /mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user) if(!I || !user) return 0 var/obj/item/bodypart/affecting if(user == src) affecting = get_bodypart(check_zone(user.zone_selected)) //stabbing yourself always hits the right target else affecting = get_bodypart(ran_zone(user.zone_selected)) var/target_area = parse_zone(check_zone(user.zone_selected)) //our intended target SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting) SSblackbox.record_feedback("nested tally", "item_used_for_combat", 1, list("[I.force]", "[I.type]")) SSblackbox.record_feedback("tally", "zone_targeted", 1, target_area) // the attacked_by code varies among species return dna.species.spec_attacked_by(I, user, affecting, a_intent, src) /mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) if(user.a_intent == INTENT_HARM) . = ..(user, TRUE) if(.) return var/hulk_verb = pick("smash","pummel") playsound(loc, user.dna.species.attack_sound, 25, 1, -1) var/message = "[user] has [hulk_verb]ed [src]!" visible_message("[message]", \ "[message]") adjustBruteLoss(15) return 1 /mob/living/carbon/human/attack_hand(mob/user) . = ..() if(.) //To allow surgery to return properly. return if(ishuman(user)) var/mob/living/carbon/human/H = user dna.species.spec_attack_hand(H, src) /mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) if(M.a_intent == INTENT_HELP) return ..() //shaking if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead. var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) DefaultCombatKnockdown(100) log_combat(M, src, "tackled") visible_message("[M] has tackled down [src]!", \ "[M] has tackled down [src]!") if(M.limb_destroyer) dismembering_strike(M, affecting.body_zone) if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites. if(..()) //successful monkey bite, this handles disease contraction. var/damage = rand(1, 3) apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee")) return 1 /mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M) . = ..() if(!.) return if(M.a_intent == INTENT_HARM) if (w_uniform) w_uniform.add_fingerprint(M) var/damage = prob(90) ? M.meleeSlashHumanPower : 0 if(!damage) playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1) visible_message("[M] has lunged at [src]!", \ "[M] has lunged at [src]!") return 0 var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor_block = run_armor_check(affecting, "melee", null, null,10) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ "[M] has slashed at [src]!") log_combat(M, src, "attacked") if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful return 1 apply_damage(damage, BRUTE, affecting, armor_block) if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead. var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") else playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) DefaultCombatKnockdown(M.meleeKnockdownPower) log_combat(M, src, "tackled") visible_message("[M] has tackled down [src]!", \ "[M] has tackled down [src]!") /mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) . = ..() if(!.) //unsuccessful larva bite. return var/damage = rand(1, 3) if(stat != DEAD) L.amount_grown = min(L.amount_grown + damage, L.max_grown) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M) . = ..() if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) var/dam_zone = dismembering_strike(M, pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) if(!dam_zone) //Dismemberment successful return TRUE var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) 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) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) . = ..() if(!.) //unsuccessful slime attack return var/damage = rand(5, 25) if(M.is_adult) damage = rand(10, 35) 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 return 1 var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) /mob/living/carbon/human/mech_melee_attack(obj/mecha/M) if(M.occupant.a_intent == INTENT_HARM) if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM)) to_chat(M.occupant, "You don't want to harm other living beings!") return M.do_attack_animation(src) if(M.damtype == "brute") step_away(src,M,15) var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) if(temp) var/update = 0 var/dmg = rand(M.force/2, M.force) var/atom/throw_target = get_edge_target_turf(src, M.dir) switch(M.damtype) if("brute") if(M.force > 35) // durand and other heavy mechas DefaultCombatKnockdown(50) src.throw_at(throw_target, rand(1,5), 7) else if(M.force >= 20 && CHECK_MOBILITY(src, MOBILITY_STAND)) // lightweight mechas like gygax DefaultCombatKnockdown(30) src.throw_at(throw_target, rand(1,3), 7) update |= temp.receive_damage(dmg, 0) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) if("fire") update |= temp.receive_damage(0, dmg) playsound(src, 'sound/items/welder.ogg', 50, 1) if("tox") M.mech_toxin_damage(src) else return if(update) update_damage_overlays() updatehealth() visible_message("[M.name] has hit [src]!", \ "[M.name] has hit [src]!", null, COMBAT_MESSAGE_RANGE) log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") else ..() /mob/living/carbon/human/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) return ..() if (!severity) return var/brute_loss = 0 var/burn_loss = 0 var/bomb_armor = getarmor(null, "bomb") //200 max knockdown for EXPLODE_HEAVY //160 max knockdown for EXPLODE_LIGHT switch (severity) if (EXPLODE_DEVASTATE) if(bomb_armor < EXPLODE_GIB_THRESHOLD) //gibs the mob if their bomb armor is lower than EXPLODE_GIB_THRESHOLD for(var/I in contents) var/atom/A = I if(!QDELETED(A)) A.ex_act(severity) gib() return else brute_loss = 500 var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) throw_at(throw_target, 200, 4) damage_clothes(400 - bomb_armor, BRUTE, "bomb") if (EXPLODE_HEAVY) brute_loss = 60 burn_loss = 60 if(bomb_armor) brute_loss = 30*(2 - round(bomb_armor*0.01, 0.05)) burn_loss = brute_loss //damage gets reduced from 120 to up to 60 combined brute+burn damage_clothes(200 - bomb_armor, BRUTE, "bomb") if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(30, 120) Unconscious(20) //short amount of time for follow up attacks against elusive enemies like wizards Knockdown(200 - (bomb_armor * 1.6)) //between ~4 and ~20 seconds of knockdown depending on bomb armor if(EXPLODE_LIGHT) brute_loss = 30 if(bomb_armor) brute_loss = 15*(2 - round(bomb_armor*0.01, 0.05)) damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb") if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(15,60) Knockdown(160 - (bomb_armor * 1.6)) //100 bomb armor will prevent knockdown altogether take_overall_damage(brute_loss,burn_loss) //attempt to dismember bodyparts if(severity <= 2 || !bomb_armor) var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3. for(var/X in bodyparts) var/obj/item/bodypart/BP = X if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != BODY_ZONE_HEAD && BP.body_zone != BODY_ZONE_CHEST) BP.brute_dam = BP.max_damage BP.dismember() max_limb_loss-- if(!max_limb_loss) break /mob/living/carbon/human/blob_act(obj/structure/blob/B) if(stat == DEAD) return show_message("The blob attacks you!") var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) //Added a safety check in case you want to shock a human mob directly through electrocute_act. /mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) if(flags & SHOCK_TESLA) var/total_coeff = 1 if(gloves) var/obj/item/clothing/gloves/G = gloves if(G.siemens_coefficient <= 0) total_coeff -= 0.5 if(wear_suit) var/obj/item/clothing/suit/S = wear_suit if(S.siemens_coefficient <= 0) total_coeff -= 0.95 else if(S.siemens_coefficient == (-1)) total_coeff -= 1 siemens_coeff = total_coeff if(flags_1 & TESLA_IGNORE_1) siemens_coeff = 0 else if(!(flags & SHOCK_NOGLOVES)) var/gloves_siemens_coeff = 1 if(gloves) var/obj/item/clothing/gloves/G = gloves gloves_siemens_coeff = G.siemens_coefficient siemens_coeff = gloves_siemens_coeff if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION)) if(shock_damage * siemens_coeff >= 1 && prob(25)) var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART) heart.beating = TRUE if(stat == CONSCIOUS) to_chat(src, "You feel your heart beating again!") siemens_coeff *= physiology.siemens_coeff . = ..() if(.) electrocution_animation(40) /mob/living/carbon/human/emp_act(severity) . = ..() if(. & EMP_PROTECT_CONTENTS) return var/informed = FALSE for(var/obj/item/bodypart/L in src.bodyparts) if(L.status == BODYPART_ROBOTIC) if(!informed) to_chat(src, "You feel a sharp pain as your robotic limbs overload.") informed = TRUE switch(severity) if(1) L.receive_damage(0,10) Stun(200) if(2) L.receive_damage(0,5) Stun(100) /mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) var/list/damaged = list() var/list/inventory_items_to_kill = list() var/acidity = acidpwr * min(acid_volume*0.005, 0.1) //HEAD// if(!bodyzone_hit || bodyzone_hit == BODY_ZONE_HEAD) //only if we didn't specify a zone or if that zone is the head. var/obj/item/clothing/head_clothes = null if(glasses) head_clothes = glasses if(wear_mask) head_clothes = wear_mask if(wear_neck) head_clothes = wear_neck if(head) head_clothes = head if(head_clothes) if(!(head_clothes.resistance_flags & UNACIDABLE)) head_clothes.acid_act(acidpwr, acid_volume) update_inv_glasses() update_inv_wear_mask() update_inv_neck() update_inv_head() else to_chat(src, "Your [head_clothes.name] protects your head and face from the acid!") else . = get_bodypart(BODY_ZONE_HEAD) if(.) damaged += . if(ears) inventory_items_to_kill += ears //CHEST// if(!bodyzone_hit || bodyzone_hit == BODY_ZONE_CHEST) var/obj/item/clothing/chest_clothes = null if(w_uniform) chest_clothes = w_uniform if(wear_suit) chest_clothes = wear_suit if(chest_clothes) if(!(chest_clothes.resistance_flags & UNACIDABLE)) chest_clothes.acid_act(acidpwr, acid_volume) update_inv_w_uniform() update_inv_wear_suit() else to_chat(src, "Your [chest_clothes.name] protects your body from the acid!") else . = get_bodypart(BODY_ZONE_CHEST) if(.) damaged += . if(wear_id) inventory_items_to_kill += wear_id if(r_store) inventory_items_to_kill += r_store if(l_store) inventory_items_to_kill += l_store if(s_store) inventory_items_to_kill += s_store //ARMS & HANDS// if(!bodyzone_hit || bodyzone_hit == BODY_ZONE_L_ARM || bodyzone_hit == BODY_ZONE_R_ARM) var/obj/item/clothing/arm_clothes = null if(gloves) arm_clothes = gloves if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS))) arm_clothes = w_uniform if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS))) arm_clothes = wear_suit if(arm_clothes) if(!(arm_clothes.resistance_flags & UNACIDABLE)) arm_clothes.acid_act(acidpwr, acid_volume) update_inv_gloves() update_inv_w_uniform() update_inv_wear_suit() else to_chat(src, "Your [arm_clothes.name] protects your arms and hands from the acid!") else . = get_bodypart(BODY_ZONE_R_ARM) if(.) damaged += . . = get_bodypart(BODY_ZONE_L_ARM) if(.) damaged += . //LEGS & FEET// if(!bodyzone_hit || bodyzone_hit == BODY_ZONE_L_LEG || bodyzone_hit == BODY_ZONE_R_LEG || bodyzone_hit == "feet") var/obj/item/clothing/leg_clothes = null if(shoes) leg_clothes = shoes if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (w_uniform.body_parts_covered & LEGS)))) leg_clothes = w_uniform if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (wear_suit.body_parts_covered & LEGS)))) leg_clothes = wear_suit if(leg_clothes) if(!(leg_clothes.resistance_flags & UNACIDABLE)) leg_clothes.acid_act(acidpwr, acid_volume) update_inv_shoes() update_inv_w_uniform() update_inv_wear_suit() else to_chat(src, "Your [leg_clothes.name] protects your legs and feet from the acid!") else . = get_bodypart(BODY_ZONE_R_LEG) if(.) damaged += . . = get_bodypart(BODY_ZONE_L_LEG) if(.) damaged += . //DAMAGE// for(var/obj/item/bodypart/affecting in damaged) affecting.receive_damage(acidity, 2*acidity) if(affecting.name == BODY_ZONE_HEAD) if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement affecting.receive_damage(acidity, 2*acidity) emote("scream") facial_hair_style = "Shaved" hair_style = "Bald" update_hair() ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) update_damage_overlays() //MELTING INVENTORY ITEMS// //these items are all outside of armour visually, so melt regardless. if(!bodyzone_hit) if(back) inventory_items_to_kill += back if(belt) inventory_items_to_kill += belt inventory_items_to_kill += held_items for(var/obj/item/I in inventory_items_to_kill) I.acid_act(acidpwr, acid_volume) return 1 /mob/living/carbon/human/singularity_act() var/gain = 20 if(mind) if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") ) gain = 100 if(HAS_TRAIT(mind, TRAIT_CLOWN_MENTALITY)) gain = rand(-300, 300) investigate_log("([key_name(src)]) has been consumed by the singularity.", INVESTIGATE_SINGULO) //Oh that's where the clown ended up! gib() return(gain) /mob/living/carbon/human/help_shake_act(mob/living/carbon/M) if(!istype(M)) return if(health >= 0) if(src == M) if(has_status_effect(STATUS_EFFECT_CHOKINGSTRAND)) to_chat(src, "You attempt to remove the durathread strand from around your neck.") if(do_after(src, 35, null, src)) to_chat(src, "You succesfuly remove the durathread strand.") remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) return var/to_send = "" visible_message("[src] examines [p_them()]self.", \ "You check yourself for injuries.") var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) for(var/X in bodyparts) var/obj/item/bodypart/LB = X missing -= LB.body_zone if(LB.is_pseudopart) //don't show injury text for fake bodyparts; ie chainsaw arms or synthetic armblades continue var/limb_max_damage = LB.max_damage var/status = "" var/brutedamage = LB.brute_dam var/burndamage = LB.burn_dam if(hallucination) if(prob(30)) brutedamage += rand(30,40) if(prob(30)) burndamage += rand(30,40) if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) status = "[brutedamage] brute damage and [burndamage] burn damage" if(!brutedamage && !burndamage) status = "no damage" else if(brutedamage > 0) status = LB.light_brute_msg if(brutedamage > (limb_max_damage*0.4)) status = LB.medium_brute_msg if(brutedamage > (limb_max_damage*0.8)) status = LB.heavy_brute_msg if(brutedamage > 0 && burndamage > 0) status += " and " if(burndamage > (limb_max_damage*0.8)) status += LB.heavy_burn_msg else if(burndamage > (limb_max_damage*0.2)) status += LB.medium_burn_msg else if(burndamage > 0) status += LB.light_burn_msg if(status == "") status = "OK" var/no_damage if(status == "OK" || status == "no damage") no_damage = TRUE to_send += "\t Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].\n" for(var/obj/item/I in LB.embedded_objects) to_send += "\t There is \a [I] embedded in your [LB.name]!\n" for(var/t in missing) to_send += "Your [parse_zone(t)] is missing!\n" if(bleed_rate) to_send += "You are bleeding!\n" if(getStaminaLoss()) if(getStaminaLoss() > 30) to_send += "You're completely exhausted.\n" else to_send += "You feel fatigued.\n" if(HAS_TRAIT(src, TRAIT_SELF_AWARE)) if(toxloss) if(toxloss > 10) to_send += "You feel sick.\n" else if(toxloss > 20) to_send += "You feel nauseated.\n" else if(toxloss > 40) to_send += "You feel very unwell!\n" if(oxyloss) if(oxyloss > 10) to_send += "You feel lightheaded.\n" else if(oxyloss > 20) to_send += "Your thinking is clouded and distant.\n" else if(oxyloss > 30) to_send += "You're choking!\n" switch(nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) to_send += "You're completely stuffed!\n" if(NUTRITION_LEVEL_WELL_FED to NUTRITION_LEVEL_FULL) to_send += "You're well fed!\n" if(NUTRITION_LEVEL_FED to NUTRITION_LEVEL_WELL_FED) to_send += "You're not hungry.\n" if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FED) to_send += "You could use a bite to eat.\n" if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY) to_send += "You feel quite hungry.\n" if(0 to NUTRITION_LEVEL_STARVING) to_send += "You're starving!\n" //TODO: Convert these messages into vague messages, thereby encouraging actual dignosis. //Compiles then shows the list of damaged organs and broken organs var/list/broken = list() var/list/damaged = list() var/broken_message var/damaged_message var/broken_plural var/damaged_plural //Sets organs into their proper list for(var/O in internal_organs) var/obj/item/organ/organ = O if(organ.organ_flags & ORGAN_FAILING) if(broken.len) broken += ", " broken += organ.name else if(organ.damage > organ.low_threshold) if(damaged.len) damaged += ", " damaged += organ.name //Checks to enforce proper grammar, inserts words as necessary into the list if(broken.len) if(broken.len > 1) broken.Insert(broken.len, "and ") broken_plural = TRUE else var/holder = broken[1] //our one and only element if(holder[length(holder)] == "s") broken_plural = TRUE //Put the items in that list into a string of text for(var/B in broken) broken_message += B to_chat(src, " Your [broken_message] [broken_plural ? "are" : "is"] non-functional!") if(damaged.len) if(damaged.len > 1) damaged.Insert(damaged.len, "and ") damaged_plural = TRUE else var/holder = damaged[1] if(holder[length(holder)] == "s") damaged_plural = TRUE for(var/D in damaged) damaged_message += D to_chat(src, "Your [damaged_message] [damaged_plural ? "are" : "is"] hurt.") if(roundstart_quirks.len) to_send += "You have these quirks: [get_trait_string()].\n" to_chat(src, to_send) else if(wear_suit) wear_suit.add_fingerprint(M) else if(w_uniform) w_uniform.add_fingerprint(M) ..() /mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone) if(damage_type != BRUTE && damage_type != BURN) return damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed var/list/torn_items = list() //HEAD// if(!def_zone || def_zone == BODY_ZONE_HEAD) var/obj/item/clothing/head_clothes = null if(glasses) head_clothes = glasses if(wear_mask) head_clothes = wear_mask if(wear_neck) head_clothes = wear_neck if(head) head_clothes = head if(head_clothes) torn_items += head_clothes else if(ears) torn_items += ears //CHEST// if(!def_zone || def_zone == BODY_ZONE_CHEST) var/obj/item/clothing/chest_clothes = null if(w_uniform) chest_clothes = w_uniform if(wear_suit) chest_clothes = wear_suit if(chest_clothes) torn_items += chest_clothes //ARMS & HANDS// if(!def_zone || def_zone == BODY_ZONE_L_ARM || def_zone == BODY_ZONE_R_ARM) var/obj/item/clothing/arm_clothes = null if(gloves) arm_clothes = gloves if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS))) arm_clothes = w_uniform if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS))) arm_clothes = wear_suit if(arm_clothes) torn_items |= arm_clothes //LEGS & FEET// if(!def_zone || def_zone == BODY_ZONE_L_LEG || def_zone == BODY_ZONE_R_LEG) var/obj/item/clothing/leg_clothes = null if(shoes) leg_clothes = shoes if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS))) leg_clothes = w_uniform if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS))) leg_clothes = wear_suit if(leg_clothes) torn_items |= leg_clothes for(var/obj/item/I in torn_items) I.take_damage(damage_amount, damage_type, damage_flag, 0)