From a7b85707dddf9044f9f3d22ddc00c4fc1c1ab655 Mon Sep 17 00:00:00 2001 From: Tastyfish Date: Thu, 5 Jan 2012 17:15:29 -0500 Subject: [PATCH] porting in bones and dismemberment --- baystation12.dme | 1 + code/defines/obj.dm | 1 + code/defines/obj/weapon.dm | 8 + code/game/gamemodes/cult/cult_items.dm | 2 +- code/game/objects/items/item.dm | 20 +- code/game/objects/items/weapons/medical.dm | 24 +++ .../objects/items/weapons/swords_axes_etc.dm | 2 + code/game/objects/items/weapons/tools.dm | 1 + code/modules/chemical/Chemistry-Reagents.dm | 9 +- code/modules/mining/mine_items.dm | 1 + .../mob/living/carbon/human/examine.dm | 26 ++- code/modules/mob/living/carbon/human/human.dm | 59 ++++-- .../mob/living/carbon/human/human_damage.dm | 33 +-- .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 42 ++++ code/modules/mob/living/damage_procs.dm | 2 +- code/modules/mob/living/living.dm | 14 ++ code/modules/mob/organ/organ.dm | 193 +++++++++++++++++- code/modules/mob/organ/organ_external.dm | 71 ++++++- code/modules/mob/organ/pain.dm | 48 +++++ 20 files changed, 494 insertions(+), 65 deletions(-) create mode 100644 code/modules/mob/organ/pain.dm diff --git a/baystation12.dme b/baystation12.dme index f58c6eba48c..87772158f71 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -928,6 +928,7 @@ #include "code\modules\mob\organ\organ.dm" #include "code\modules\mob\organ\organ_external.dm" #include "code\modules\mob\organ\organ_internal.dm" +#include "code\modules\mob\organ\pain.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" #include "code\modules\power\cell.dm" diff --git a/code/defines/obj.dm b/code/defines/obj.dm index dd156c1695c..9f67387a9c0 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -294,6 +294,7 @@ var/icon_old = null // For when weapons get bloodied this saves their old icon. var/abstract = 0 var/force = 0 + var/slash = 0 var/item_state = null var/damtype = "brute" var/r_speed = 1.0 diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index d01409c9e4b..6e39b5b3523 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -208,6 +208,7 @@ throw_speed = 1 throw_range = 5 w_class = 3.0 + slash = 1 flags = FPRINT | CONDUCT | NOSHIELD | TABLEPASS origin_tech = "combat=3" @@ -243,6 +244,7 @@ throw_speed = 1 throw_range = 1 w_class = 4.0//So you can't hide it in your pocket or some such. + slash = 1 flags = FPRINT | TABLEPASS | NOSHIELD var/datum/effect/effect/system/spark_spread/spark_system @@ -622,6 +624,7 @@ desc = "A tool for breaking down those obstructions that stop you from fighting that fire." //Less ROBUST. --SkyMarshal force = 5 w_class = 4.0 + slash = 1 flags = ONBACK twohanded = 1 force_unwielded = 5 @@ -964,6 +967,7 @@ flags = FPRINT | TABLEPASS| CONDUCT force = 5.0 w_class = 1.0 + slash = 1 throwforce = 5.0 throw_speed = 3 throw_range = 5 @@ -977,6 +981,7 @@ desc = "Could probably be used as ... a throwing weapon?" w_class = 1.0 force = 5.0 + slash = 1 throwforce = 15.0 item_state = "shard-glass" g_amt = 3750 @@ -1353,6 +1358,7 @@ icon_state = "knife" force = 10.0 throwforce = 10.0 + slash = 1 /obj/item/weapon/kitchen/utensil/spoon name = "spoon" @@ -1367,6 +1373,7 @@ flags = FPRINT | TABLEPASS | CONDUCT force = 10.0 w_class = 1.0 + slash = 1 throwforce = 5.0 throw_speed = 3 throw_range = 5 @@ -1408,6 +1415,7 @@ icon_state = "drill" flags = FPRINT | TABLEPASS | CONDUCT w_class = 1.0 + slash = 1 origin_tech = "materials=1;biotech=1" /obj/item/weapon/circular_saw diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 694fed28ba9..efe21d281cc 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -6,7 +6,7 @@ flags = FPRINT | ONBELT | TABLEPASS force = 40 throwforce = 10 - + slash = 1 /obj/item/clothing/head/culthood diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm index 4a8d3c3b532..da113a8e0d7 100644 --- a/code/game/objects/items/item.dm +++ b/code/game/objects/items/item.dm @@ -127,9 +127,25 @@ user.next_move = world.time + 2 if (user.hand) - user.l_hand = src + if(ishuman(user)) + var/datum/organ/external/temp = user:organs["l_hand"] + if(!temp.destroyed) + user.l_hand = src + else + user << "\blue You pick \the [src] up with your ha- wait a minute." + return + else + user.l_hand = src else - user.r_hand = src + if(ishuman(user)) + var/datum/organ/external/temp = user:organs["r_hand"] + if(!temp.destroyed) + user.r_hand = src + else + user << "\blue You pick \the [src] up with your ha- wait a minute." + return + else + user.r_hand = src src.loc = user src.layer = 20 add_fingerprint(user) diff --git a/code/game/objects/items/weapons/medical.dm b/code/game/objects/items/weapons/medical.dm index cbf794b33a4..d1fee794bf7 100644 --- a/code/game/objects/items/weapons/medical.dm +++ b/code/game/objects/items/weapons/medical.dm @@ -57,6 +57,30 @@ MEDICAL if (affecting.heal_damage(src.heal_brute, src.heal_burn)) H.UpdateDamageIcon() + + if(H.bloodloss > 0 && heal_brute > 0) // fix wounds too if bruise pack + var/stoped = 0 + for(var/datum/organ/external/wound/W in affecting.wounds) + if(W.bleeding) + W.stopbleeding() + stoped = 0 + break + if(!stoped) + // user << "There is no bleeding wound at [t]" //code no longer in a dedicated obj, thus this doesn't really matter + return + if (user) + if (M != user) + for (var/mob/O in viewers(H, null)) + O.show_message("\red [H] has been bandaged with [src] by [user]", 1) + else + var/t_himself = "itself" + if (user.gender == MALE) + t_himself = "himself" + else if (user.gender == FEMALE) + t_himself = "herself" + for (var/mob/O in viewers(H, null)) + O.show_message("\red [H] bandaged [t_himself] with [src]", 1) + M.updatehealth() else M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2)) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 5f7185d72b6..1ecdff06ca1 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -33,6 +33,7 @@ STUN BATON else icon_state = "sword[color]" w_class = 4 + slash = 1 playsound(user, 'saberon.ogg', 50, 1) user << "\blue [src] is now active." else @@ -42,6 +43,7 @@ STUN BATON else icon_state = "sword0" w_class = 2 + slash = 0 playsound(user, 'saberoff.ogg', 50, 1) user << "\blue [src] can now be concealed." add_fingerprint(user) diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index a6f00c091a0..232a374f489 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -290,6 +290,7 @@ WELDINGTOOOL icon_state = "cutters" flags = FPRINT | TABLEPASS| CONDUCT force = 6.0 + slash = 1 throw_speed = 2 throw_range = 9 w_class = 2.0 diff --git a/code/modules/chemical/Chemistry-Reagents.dm b/code/modules/chemical/Chemistry-Reagents.dm index 683fcd0ab3e..ec511e28f00 100644 --- a/code/modules/chemical/Chemistry-Reagents.dm +++ b/code/modules/chemical/Chemistry-Reagents.dm @@ -667,8 +667,9 @@ datum return if(prob(15) && istype(M, /mob/living/carbon/human) && volume >= 30) - var/datum/organ/external/affecting = M:get_organ("head") + var/datum/organ/external/head/affecting = M:get_organ("head") if(affecting) + affecting.disfigured = 1 affecting.take_damage(25, 0) M:UpdateDamageIcon() M:emote("scream") @@ -714,7 +715,8 @@ datum del (M:head) M << "\red Your helmet melts into uselessness!" return - var/datum/organ/external/affecting = M:get_organ("head") + var/datum/organ/external/head/affecting = M:get_organ("head") + affecting.disfigured = 1 affecting.take_damage(35, 0) M:UpdateDamageIcon() M:emote("scream") @@ -729,7 +731,8 @@ datum M.take_organ_damage(min(15, volume * 4)) // same deal as sulphuric acid else if(istype(M, /mob/living/carbon/human)) - var/datum/organ/external/affecting = M:get_organ("head") + var/datum/organ/external/head/affecting = M:get_organ("head") + affecting.disfigured = 1 affecting.take_damage(30, 0) M:UpdateDamageIcon() M:emote("scream") diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index a49b639c21d..b527f6cb0a1 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -131,6 +131,7 @@ proc/move_mining_shuttle() throwforce = 4.0 item_state = "pickaxe" w_class = 4.0 + slash = 1 m_amt = 3750 //one sheet, but where can you make them? var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO origin_tech = "materials=1;engineering=1" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 1029a993577..71e9ba890d5 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -151,7 +151,31 @@ if (!src.client) usr << "\red [src.name] doesn't seem as though they want to talk." + for(var/name in organs) + var/datum/organ/external/temp = organs[name] + if(temp.destroyed) + usr << "\red [name] is missing [t_his] [temp.display_name]." + if(temp.wounds) + for(var/datum/organ/external/wound/w in temp.wounds) + var/size = w.wound_size + var/sizetext + switch(size) + if(1) + sizetext = "cut" + if(2) + sizetext = "deep cut" + if(3) + sizetext = "flesh wound" + if(4) + sizetext = "gaping wound" + if(5) + sizetext = "big gaping wound" + if(6) + sizetext = "massive wound" + if(w.bleeding) + usr << "\red [name] is bleeding from a [sizetext] on [t_his] [temp.display_name]." + continue + print_flavor_text() usr << "\blue *---------*" - diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ec6c2ee981d..320d77ea9c4 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -55,6 +55,7 @@ var/mutantrace = null var/list/organs = list() + var/bloodloss = 0 /mob/living/carbon/human/dummy real_name = "Test Dummy" @@ -69,24 +70,22 @@ if(!dna) dna = new /datum/dna(null) - var/datum/organ/external/chest/chest = new /datum/organ/external/chest(src) - var/datum/organ/external/head/head = new /datum/organ/external/head(src) - var/datum/organ/external/l_arm/l_arm = new /datum/organ/external/l_arm(src) - var/datum/organ/external/r_arm/r_arm = new /datum/organ/external/r_arm(src) - var/datum/organ/external/r_leg/r_leg = new /datum/organ/external/r_leg(src) - var/datum/organ/external/l_leg/l_leg = new /datum/organ/external/l_leg(src) - chest.owner = src - head.owner = src - r_arm.owner = src - l_arm.owner = src - r_leg.owner = src - l_leg.owner = src - organs += chest - organs += head - organs += r_arm - organs += l_arm - organs += r_leg - organs += l_leg + new /datum/organ/external/chest(src) + new /datum/organ/external/groin(src) + new /datum/organ/external/head(src) + new /datum/organ/external/l_arm(src) + new /datum/organ/external/r_arm(src) + new /datum/organ/external/r_leg(src) + new /datum/organ/external/l_leg(src) + + var/datum/organ/external/part = new /datum/organ/external/l_hand(src) + part.parent = organs["l_arm"] + part = new /datum/organ/external/l_foot(src) + part.parent = organs["l_leg"] + part = new /datum/organ/external/r_hand(src) + part.parent = organs["r_arm"] + part = new /datum/organ/external/r_foot(src) + part.parent = organs["r_leg"] var/g = "m" if (gender == MALE) @@ -170,6 +169,11 @@ var/hungry = (500 - nutrition)/5 // So overeat would be 100 and default level would be 80 if (hungry >= 70) tally += hungry/50 + for(var/organ in list("l_leg","l_foot","r_leg","r_foot")) + var/datum/organ/external/o = organs["[organ]"] + if(o.broken) + tally += 6 + if(wear_suit) tally += wear_suit.slowdown @@ -653,7 +657,7 @@ M.show_message(text("\red [] has been hit by []", src, O), 1) if (health > 0) var/datum/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head")) - if(!affecting) return + if(!affecting || affecting.destroyed) return if (istype(O, /obj/effect/immovablerod)) affecting.take_damage(101, 0) else @@ -1254,9 +1258,12 @@ stand_icon.Blend(new /icon('human.dmi', "chest_[g]_s"), ICON_OVERLAY) lying_icon.Blend(new /icon('human.dmi', "chest_[g]_l"), ICON_OVERLAY) - for (var/part in list("head", "arm_left", "arm_right", "hand_left", "hand_right", "leg_left", "leg_right", "foot_left", "foot_right")) - stand_icon.Blend(new /icon('human.dmi', "[part]_s"), ICON_OVERLAY) - lying_icon.Blend(new /icon('human.dmi', "[part]_l"), ICON_OVERLAY) + for(var/datum/organ/external/part in organs) + if(!istype(part, /datum/organ/external/groin) \ + && !istype(part, /datum/organ/external/chest) \ + && !part.destroyed) + stand_icon.Blend(new /icon('human.dmi', "[part.icon_name]_s"), ICON_OVERLAY) + lying_icon.Blend(new /icon('human.dmi', "[part.icon_name]_l"), ICON_OVERLAY) stand_icon.Blend(new /icon('human.dmi', "groin_[g]_s"), ICON_OVERLAY) lying_icon.Blend(new /icon('human.dmi', "groin_[g]_l"), ICON_OVERLAY) @@ -1275,6 +1282,14 @@ lying_icon.Blend(new /icon('human.dmi', "underwear[underwear]_[g]_l"), ICON_OVERLAY) /mob/living/carbon/human/proc/update_face() + if(organs) + var/datum/organ/external/head = organs["head"] + if(head) + if(head.destroyed) + del(face_standing) + del(face_lying) + return + if(!facial_hair_style || !hair_style) return//Seems people like to lose their icons, this should stop the runtimes for now del(face_standing) del(face_lying) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 0cc56c0070b..bd9dff32812 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -15,26 +15,31 @@ body_standing = list() del(body_lying) body_lying = list() - for(var/datum/organ/external/O in organs) - var/icon/DI = new /icon('dam_human.dmi', O.damage_state) // the damage icon for whole human - DI.Blend(new /icon('dam_mask.dmi', O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels - // world << "[O.icon_name] [O.damage_state] \icon[DI]" - body_standing += DI - DI = new /icon('dam_human.dmi', "[O.damage_state]-2") // repeat for lying icons - DI.Blend(new /icon('dam_mask.dmi', "[O.icon_name]2"), ICON_MULTIPLY) - // world << "[O.r_name]2 [O.d_i_state]-2 \icon[DI]" - body_lying += DI + + for(var/name in organs) + var/datum/organ/external/O = organs[name] + if(!O.destroyed) + O.update_icon() + var/icon/DI = new /icon('dam_human.dmi', O.damage_state) // the damage icon for whole human + DI.Blend(new /icon('dam_mask.dmi', O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels + // world << "[O.icon_name] [O.damage_state] \icon[DI]" + body_standing += DI + DI = new /icon('dam_human.dmi', "[O.damage_state]-2") // repeat for lying icons + DI.Blend(new /icon('dam_mask.dmi', "[O.icon_name]2"), ICON_MULTIPLY) + // world << "[O.r_name]2 [O.d_i_state]-2 \icon[DI]" + body_lying += DI /mob/living/carbon/human/proc/get_organ(var/zone) if(!zone) zone = "chest" - for(var/datum/organ/external/O in organs) + for(var/name in organs) + var/datum/organ/external/O = organs[name] if(O.name == zone) return O return null -/mob/living/carbon/human/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0) +/mob/living/carbon/human/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/slash = 0) if((damagetype != BRUTE) && (damagetype != BURN)) ..(damage, damagetype, def_zone, blocked) return 1 @@ -47,15 +52,15 @@ else if(!def_zone) def_zone = ran_zone(def_zone) organ = get_organ(check_zone(def_zone)) - if(!organ) return 0 + if(!organ || organ.destroyed) return 0 if(blocked) damage = (damage/(blocked+1)) switch(damagetype) if(BRUTE) - organ.take_damage(damage, 0) + organ.take_damage(damage, 0, slash) if(BURN) - organ.take_damage(0, damage) + organ.take_damage(0, damage, slash) UpdateDamageIcon() updatehealth() return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 55e53680200..a4ddaf4e121 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -95,7 +95,7 @@ emp_act var/armor = run_armor_check(affecting, "melee", "Your armor has protected you from a hit to the [hit_area].", "Your armor has softened hit to your [hit_area].") if(armor >= 2) return 0 if(!I.force) return 0 - apply_damage(I.force, I.damtype, affecting, armor) + apply_damage(I.force, I.damtype, affecting, armor, I.slash) var/bloody = 0 if((I.damtype == BRUTE) && prob(25 + (I.force * 2))) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 60780b57203..e15bb76dae2 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -73,6 +73,8 @@ UpdateLuminosity() handle_regular_status_updates() + handle_pain() + // Update clothing update_clothing() @@ -667,6 +669,25 @@ return //TODO: DEFERRED handle_regular_status_updates() + for(var/name in organs) + var/datum/organ/external/E = organs[name] + E.process() + if(E.broken) + if(E.name == "l_hand" || E.name == "l_arm") + if(hand && equipped()) + drop_item() + emote("scream") + else if(E.name == "r_hand" || E.name == "r_arm") + if(!hand && equipped()) + drop_item() + emote("scream") + if(E.open && (!resting) && (!sleeping)) + emote("scream") + E.take_damage(20,0) + emote("collapse") + paralysis = 10 + + updatehealth() // health = 100 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss()) @@ -729,6 +750,27 @@ if (stuttering) stuttering-- if (slurring) slurring-- + var/datum/organ/external/head/head = organs["head"] + if(head && !head.disfigured) + if(head.brute_dam >= 45 || head.burn_dam >= 45) + head.disfigured = 1 + emote("scream") + real_name = "Unknown" + src << "\red Your face has become disfigured." + warn_flavor_changed() + for(var/datum/organ/external/temp in organs) + if(!temp.bleeding) + continue + else + if(prob(35)) + bloodloss += rand(1,10) + if(temp.wounds) + for(var/datum/organ/external/wound/W in temp.wounds) + if(!temp.bleeding) + continue + else + if(prob(25)) + bloodloss++ if (eye_blind) eye_blind-- blinded = 1 diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 2293f00dd3a..b253c4de1c8 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -8,7 +8,7 @@ Returns standard 0 if fail */ -/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0) +/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/slash = 0) if(!damage || (blocked >= 2)) return 0 switch(damagetype) if(BRUTE) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 7561307562c..cd50f05b7a5 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -134,6 +134,20 @@ src.updatehealth() /mob/living/proc/revive() + if(istype(src, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = src + for(var/A in H.organs) + var/datum/organ/external/affecting = null + if(!H.organs[A]) continue + affecting = H.organs[A] + if(!istype(affecting, /datum/organ/external)) continue + affecting.heal_damage(1000, 1000) //fixes getting hit after ingestion, killing you when game updates organ health + affecting.broken = 0 + affecting.destroyed = 0 + for(var/datum/organ/external/wound/W in affecting.wounds) + W.stopbleeding() + H.UpdateDamageIcon() + H.update_body() //src.fireloss = 0 src.setToxLoss(0) //src.bruteloss = 0 diff --git a/code/modules/mob/organ/organ.dm b/code/modules/mob/organ/organ.dm index 0de3cd6ede2..6404cac6231 100644 --- a/code/modules/mob/organ/organ.dm +++ b/code/modules/mob/organ/organ.dm @@ -1,18 +1,15 @@ /datum/organ var name = "organ" - owner = null + mob/living/carbon/human/owner = null proc/process() return 0 - proc/receive_chem(chemical as obj) return 0 - - /**************************************************** EXTERNAL ORGANS ****************************************************/ @@ -29,11 +26,55 @@ max_damage = 0 wound_size = 0 max_size = 0 - var/obj/item/weapon/implant/implant = null + obj/item/weapon/implant/implant = null + display_name + list/wounds = list() + bleeding = 0 + perma_injury = 0 + perma_dmg = 0 + broken = 0 + destroyed = 0 + destspawn + min_broken_damage = 30 + datum/organ/external/parent + damage_msg = "\red You feel a intense pain" + + var/open = 0 + var/clean = 1 + var/stage = 0 + var/wound = 0 + var/split = 0 + + New(mob/living/carbon/human/H) + ..(H) + if(!display_name) + display_name = name + if(istype(H)) + owner = H + H.organs[name] = src + + proc/take_damage(brute, burn, slash) + if((brute <= 0) && (burn <= 0)) + return 0 + if(destroyed) + return 0 + + if(owner) owner.pain(display_name, (brute+burn)*3, 1) + if(slash) + var/chance = rand(1,5) + var/nux = brute * chance + if(brute_dam >= max_damage) + if(prob(5 * brute)) + for(var/mob/M in viewers(owner)) + M.show_message("\red [owner.name]'s [display_name] flies off.") + destroyed = 1 + droplimb() + return + else if(prob(nux)) + createwound(rand(1,5)) + owner << "You feel something wet on your [display_name]" - proc/take_damage(brute, burn) - if((brute <= 0) && (burn <= 0)) return 0 if((src.brute_dam + src.burn_dam + brute + burn) < src.max_damage) src.brute_dam += brute src.burn_dam += burn @@ -56,19 +97,57 @@ else return 0 + if(broken) + owner.emote("scream") + var/result = src.update_icon() return result - proc/heal_damage(brute, burn) - src.brute_dam = max(0, src.brute_dam - brute) - src.burn_dam = max(0, src.burn_dam - burn) + proc/heal_damage(brute, burn, internal = 0) + brute_dam = max(0, brute_dam - brute) + burn_dam = max(0, burn_dam - burn) + if(internal) + broken = 0 + perma_injury = 0 return update_icon() proc/get_damage() //returns total damage - return src.brute_dam + src.burn_dam //could use src.health? + return max(brute_dam + burn_dam - perma_injury,perma_injury) //could use health? + proc/get_damage_brute() + return max(brute_dam+perma_injury,perma_injury) + + proc/get_damage_fire() + return burn_dam + + process() + if(destroyed) + if(destspawn) + droplimb() + return + if(broken == 0) + perma_dmg = 0 + if(parent) + if(parent.destroyed) + destroyed = 1 + owner:update_body() + return + if(brute_dam > min_broken_damage) + if(broken == 0) + var/dmgmsg = "[damage_msg] in your [display_name]" + owner << dmgmsg + //owner.unlock_medal("Broke Yarrr Bones!", 0, "Break a bone.", "easy") + for(var/mob/M in viewers(owner)) + if(M != owner) + M.show_message("\red You hear a loud cracking sound coming from [owner.name].") + owner.emote("scream") + broken = 1 + wound = "broken" //Randomise in future + perma_injury = brute_dam + return + return // new damage icon system // returns just the brute/burn damage code @@ -105,7 +184,99 @@ return 1 return 0 + proc/droplimb() + if(destroyed) + //owner.unlock_medal("Lost something?", 0, "Lose a limb.", "easy") + switch(body_part) + if(UPPER_TORSO) + owner.gib() + if(HEAD) + var/obj/item/weapon/organ/head/H = new(owner.loc) + var/lol = pick(cardinal) + step(H,lol) + owner:update_face() + owner:update_body() + return + if(ARM_RIGHT) + var/obj/item/weapon/organ/r_arm/H = new(owner.loc) + if(owner:organs["r_hand"]) + var/datum/organ/external/S = owner:organs["r_hand"] + if(!S.destroyed) + var/obj/item/weapon/organ/r_hand/X = new(owner.loc) + for(var/mob/M in viewers(owner)) + M.show_message("\red [owner.name]'s [X.name] flies off.") + var/lol2 = pick(cardinal) + step(X,lol2) + var/lol = pick(cardinal) + step(H,lol) + destroyed = 1 + return + if(ARM_LEFT) + var/obj/item/weapon/organ/l_arm/H = new(owner.loc) + if(owner:organs["l_hand"]) + var/datum/organ/external/S = owner:organs["l_hand"] + if(!S.destroyed) + var/obj/item/weapon/organ/l_hand/X = new(owner.loc) + for(var/mob/M in viewers(owner)) + M.show_message("\red [owner.name]'s [X.name] flies off in arc.") + var/lol2 = pick(cardinal) + step(X,lol2) + var/lol = pick(cardinal) + step(H,lol) + destroyed = 1 + return + if(LEG_RIGHT) + var/obj/item/weapon/organ/r_leg/H = new(owner.loc) + if(owner:organs["r_foot"]) + var/datum/organ/external/S = owner:organs["r_foot"] + if(!S.destroyed) + var/obj/item/weapon/organ/l_foot/X = new(owner.loc) + for(var/mob/M in viewers(owner)) + M.show_message("\red [owner.name]'s [X.name] flies off flies off in arc.") + var/lol2 = pick(cardinal) + step(X,lol2) + var/lol = pick(cardinal) + step(H,lol) + destroyed = 1 + return + if(LEG_LEFT) + var/obj/item/weapon/organ/l_leg/H = new(owner.loc) + if(owner:organs["l_foot"]) + var/datum/organ/external/S = owner:organs["l_foot"] + if(!S.destroyed) + var/obj/item/weapon/organ/l_foot/X = new(owner.loc) + for(var/mob/M in viewers(owner)) + M.show_message("\red [owner.name]'s [X.name] flies off.") + var/lol2 = pick(cardinal) + step(X,lol2) + var/lol = pick(cardinal) + step(H,lol) + destroyed = 1 + return + proc/createwound(var/size = 1) + if(ishuman(src.owner)) + var/datum/organ/external/wound/W = new(src) + W.bleeding = 1 + src.owner:bloodloss += 10 * size + W.wound_size = size + W.owner = src.owner + src.wounds += W + +/datum/organ/external/wound + name = "wound" + wound_size = 1 + icon_name = "wound" + display_name = "wound" + parent = null + + proc/stopbleeding() + if(!src.bleeding) + return + var/t = 10 * src.wound_size + src.owner:bloodloss -= t + src.bleeding = 0 + del(src) /**************************************************** INTERNAL ORGANS diff --git a/code/modules/mob/organ/organ_external.dm b/code/modules/mob/organ/organ_external.dm index 029d28aa721..6fdeb413cdc 100644 --- a/code/modules/mob/organ/organ_external.dm +++ b/code/modules/mob/organ/organ_external.dm @@ -2,61 +2,114 @@ name = "chest" icon_name = "chest" max_damage = 150 + min_broken_damage = 75 body_part = UPPER_TORSO -/*/datum/organ/external/groin +/datum/organ/external/groin name = "groin" - icon_name = "groin" + icon_name = "diaper" + max_damage = 115 + min_broken_damage = 70 body_part = LOWER_TORSO -*/ + /datum/organ/external/head name = "head" icon_name = "head" max_damage = 125 + min_broken_damage = 70 body_part = HEAD + var/disfigured = 0 /datum/organ/external/l_arm name = "l_arm" + display_name = "left arm" icon_name = "l_arm" max_damage = 75 + min_broken_damage = 30 body_part = ARM_LEFT /datum/organ/external/l_leg name = "l_leg" + display_name = "left leg" icon_name = "l_leg" max_damage = 75 + min_broken_damage = 30 body_part = LEG_LEFT /datum/organ/external/r_arm name = "r_arm" + display_name = "right arm" icon_name = "r_arm" max_damage = 75 + min_broken_damage = 30 body_part = ARM_RIGHT /datum/organ/external/r_leg name = "r_leg" + display_name = "right leg" icon_name = "r_leg" max_damage = 75 + min_broken_damage = 30 body_part = LEG_RIGHT -/*Leaving these here in case we want to use them later /datum/organ/external/l_foot - name = "l foot" + name = "l_foot" + display_name = "left foot" icon_name = "l_foot" + max_damage = 40 + min_broken_damage = 15 body_part = FOOT_LEFT /datum/organ/external/r_foot - name = "r foot" + name = "r_foot" + display_name = "right foot" icon_name = "r_foot" + max_damage = 40 + min_broken_damage = 15 body_part = FOOT_RIGHT /datum/organ/external/r_hand - name = "r hand" + name = "r_hand" + display_name = "right hand" icon_name = "r_hand" + max_damage = 40 + min_broken_damage = 15 body_part = HAND_RIGHT /datum/organ/external/l_hand - name = "l hand" + name = "l_hand" + display_name = "left hand" icon_name = "l_hand" + max_damage = 40 + min_broken_damage = 15 body_part = HAND_LEFT -*/ \ No newline at end of file + +obj/item/weapon/organ/ + icon = 'human.dmi' +obj/item/weapon/organ/head + name = "head" + icon_state = "head_l" +obj/item/weapon/organ/l_arm + name = "left arm" + icon_state = "arm_left_l" +obj/item/weapon/organ/l_foot + name = "left foot" + icon_state = "foot_left_l" +obj/item/weapon/organ/l_hand + name = "left hand" + icon_state = "hand_left_l" +obj/item/weapon/organ/l_leg + name = "left leg" + icon_state = "leg_left_l" +obj/item/weapon/organ/r_arm + name = "right arm" + icon_state = "arm_right_l" +obj/item/weapon/organ/r_foot + name = "right foot" + icon_state = "foot_right_l" +obj/item/weapon/organ/r_hand + name = "right hand" + icon_state = "hand_right_l" +obj/item/weapon/organ/r_leg + name = "right leg" + icon_state = "leg_right_l" diff --git a/code/modules/mob/organ/pain.dm b/code/modules/mob/organ/pain.dm new file mode 100644 index 00000000000..0791211abc5 --- /dev/null +++ b/code/modules/mob/organ/pain.dm @@ -0,0 +1,48 @@ +mob/proc/flash_pain() + flick("pain",pain) + +mob/var/list/pain_stored = list() +mob/var/last_pain_message = "" +mob/var/next_pain_time = 0 + +// partname is the name of a body part +// amount is a num from 1 to 100 +mob/proc/pain(var/partname, var/amount, var/force) + if(stat >= 2) return + if(world.time < next_pain_time && !force) + return + if(amount > 10 && istype(src,/mob/living/carbon/human)) + if(src:paralysis) + src:paralysis = max(0, src:paralysis-round(amount/10)) + if(amount > 50 && prob(amount / 5)) + src:drop_item() + var/msg + switch(amount) + if(1 to 10) + msg = "Your [partname] hurts a bit." + if(11 to 90) + flash_weak_pain() + msg = "Ouch! Your [partname] hurts." + if(91 to 10000) + flash_pain() + msg = "OH GOD! Your [partname] is hurting terribly!" + if(msg && (msg != last_pain_message || prob(10))) + last_pain_message = msg + src << msg + next_pain_time = world.time + (100 - amount) + +mob/living/carbon/human/proc/handle_pain() + // not when sleeping + if(stat >= 2) return + var/maxdam = 0 + var/datum/organ/external/damaged_organ = null + for(var/name in organs) + var/datum/organ/external/E = organs[name] + var/dam = E.get_damage() + // make the choice of the organ depend on damage, + // but also sometimes use one of the less damaged ones + if(dam > maxdam && (maxdam == 0 || prob(70)) ) + damaged_organ = E + maxdam = dam + if(damaged_organ) + pain(damaged_organ.display_name, maxdam, 0)