diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm
index 7408663f44..30750d64fe 100644
--- a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_temple.dm
@@ -306,7 +306,7 @@
switch(trap_type)
if("sawburst")
M << "\red A sawblade shoots out of the ground and strikes you!"
- M.apply_damage(rand(5,10), BRUTE)
+ M.apply_damage(rand(5,10), BRUTE, sharp=1, edge=1)
var/atom/myloc = src.loc
var/image/flicker = image('code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi',"sawblade")
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm
index 86b4a112c5..7daeae006b 100644
--- a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm
+++ b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle_turfs.dm
@@ -143,25 +143,25 @@
var/turf/T = get_turf(M)
if(istype(T, /turf/unsimulated/jungle/water))
M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
- M.apply_damage(rand(0,1), BRUTE)
+ M.apply_damage(rand(0,1), BRUTE, sharp=1)
if(prob(50))
spawn(rand(25,50))
var/turf/T = get_turf(M)
if(istype(T, /turf/unsimulated/jungle/water))
M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
- M.apply_damage(rand(0,1), BRUTE)
+ M.apply_damage(rand(0,1), BRUTE, sharp=1)
if(prob(50))
spawn(rand(25,50))
var/turf/T = get_turf(M)
if(istype(T, /turf/unsimulated/jungle/water))
M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
- M.apply_damage(rand(0,1), BRUTE)
+ M.apply_damage(rand(0,1), BRUTE, sharp=1)
if(prob(50))
spawn(rand(25,50))
var/turf/T = get_turf(M)
if(istype(T, /turf/unsimulated/jungle/water))
M << pick("\red Something sharp bites you!","\red Sharp teeth grab hold of you!","\red You feel something take a chunk out of your leg!")
- M.apply_damage(rand(0,1), BRUTE)
+ M.apply_damage(rand(0,1), BRUTE, sharp=1)
/turf/unsimulated/jungle/water/deep
plants_spawn = 0
diff --git a/code/WorkInProgress/Ported/policetape.dm b/code/WorkInProgress/Ported/policetape.dm
index cdd547d7c0..12059c63ed 100644
--- a/code/WorkInProgress/Ported/policetape.dm
+++ b/code/WorkInProgress/Ported/policetape.dm
@@ -136,7 +136,7 @@
breaktape(/obj/item/weapon/wirecutters,user)
/obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob)
- if(user.a_intent == "help" && ((!is_sharp(W) && src.allowed(user))))
+ if(user.a_intent == "help" && ((!can_puncture(W) && src.allowed(user))))
user << "You can't break the [src] with that!"
return
user.show_viewers("\blue [user] breaks the [src]!")
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 98d539e391..c6c1c38a4f 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1275,8 +1275,21 @@ proc/is_hot(obj/item/W as obj)
return 0
-//Is this even used for anything besides balloons? Yes I took out the W:lit stuff because : really shouldnt be used.
-/proc/is_sharp(obj/item/W as obj) // For the record, WHAT THE HELL IS THIS METHOD OF DOING IT?
+//Whether or not the given item counts as sharp in terms of dealing damage
+/proc/is_sharp(obj/O as obj)
+ if (!O) return 0
+ if (O.sharp) return 1
+ if (O.edge) return 1
+ return 0
+
+//Whether or not the given item counts as cutting with an edge in terms of removing limbs
+/proc/has_edge(obj/O as obj)
+ if (!O) return 0
+ if (O.edge) return 1
+ return 0
+
+//Returns 1 if the given item is capable of popping things like balloons, inflatable barriers, or cutting police tape.
+/proc/can_puncture(obj/item/W as obj) // For the record, WHAT THE HELL IS THIS METHOD OF DOING IT?
if(!W) return 0
if(W.sharp) return 1
return ( \
@@ -1287,20 +1300,7 @@ proc/is_hot(obj/item/W as obj)
istype(W, /obj/item/weapon/lighter/zippo) || \
istype(W, /obj/item/weapon/match) || \
istype(W, /obj/item/clothing/mask/cigarette) || \
- istype(W, /obj/item/weapon/wirecutters) || \
- istype(W, /obj/item/weapon/circular_saw) || \
- istype(W, /obj/item/weapon/melee/energy/sword) || \
- istype(W, /obj/item/weapon/melee/energy/blade) || \
- istype(W, /obj/item/weapon/shovel) || \
- istype(W, /obj/item/weapon/kitchenknife) || \
- istype(W, /obj/item/weapon/butch) || \
- istype(W, /obj/item/weapon/scalpel) || \
- istype(W, /obj/item/weapon/kitchen/utensil/knife) || \
- istype(W, /obj/item/weapon/shard) || \
- istype(W, /obj/item/weapon/broken_bottle) || \
- istype(W, /obj/item/weapon/reagent_containers/syringe) || \
- istype(W, /obj/item/weapon/kitchen/utensil/fork) && W.icon_state != "forkloaded" || \
- istype(W, /obj/item/weapon/twohanded/fireaxe) \
+ istype(W, /obj/item/weapon/shovel) \
)
/proc/is_surgery_tool(obj/item/W as obj)
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index e11a950eee..353158cf90 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -228,6 +228,7 @@
icon = 'icons/obj/shards.dmi'
icon_state = "large"
sharp = 1
+ edge = 1
desc = "Could probably be used as ... a throwing weapon?"
w_class = 2.0
force = 5.0
@@ -471,6 +472,8 @@
icon_state = "hatchet"
flags = FPRINT | TABLEPASS | CONDUCT
force = 12.0
+ sharp = 1
+ edge = 1
w_class = 2.0
throwforce = 15.0
throw_speed = 4
@@ -496,6 +499,8 @@
desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow."
force = 13.0
throwforce = 5.0
+ sharp = 1
+ edge = 1
throw_speed = 1
throw_range = 3
w_class = 4.0
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 53b2c36ea8..9fa38d54c7 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -169,7 +169,7 @@
src.visible_message("[src] stabs [T] with the proboscis!")
T << "You feel a sharp stabbing pain!"
var/datum/organ/external/affecting = T.get_organ(src.zone_sel.selecting)
- if(affecting.take_damage(39,0,1,"large organic needle"))
+ if(affecting.take_damage(39,0,1,0,"large organic needle"))
T:UpdateDamageIcon()
continue
diff --git a/code/game/machinery/bots/farmbot.dm b/code/game/machinery/bots/farmbot.dm
index b6f8198463..228b525049 100644
--- a/code/game/machinery/bots/farmbot.dm
+++ b/code/game/machinery/bots/farmbot.dm
@@ -441,7 +441,7 @@
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = human.get_organ(ran_zone(dam_zone))
var/armor = human.run_armor_check(affecting, "melee")
- human.apply_damage(damage,BRUTE,affecting,armor)
+ human.apply_damage(damage,BRUTE,affecting,armor,sharp=1,edge=1)
else // warning, plants infested with weeds!
mode = FARMBOT_MODE_WAITING
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 5ad758015e..9b6895e0d9 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -44,5 +44,5 @@
return
/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob)
- if (is_sharp(W))
+ if (can_puncture(W))
burst()
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 82df54987e..72c4589343 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -5,6 +5,7 @@
icon_state = "d66"
w_class = 1
var/sides = 6
+ attack_verb = list("diced")
/obj/item/weapon/dice/New()
icon_state = "[name][rand(sides)]"
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 58a0713ecc..46639ea101 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -112,7 +112,7 @@ var/last_chew = 0
H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])")
log_attack("[s] ([H.ckey])")
- if(O.take_damage(3,0,1,"teeth marks"))
+ if(O.take_damage(3,0,1,1,"teeth marks"))
H:UpdateDamageIcon()
last_chew = world.time
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index 534634529d..67f471db10 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -53,6 +53,7 @@
name = "fork"
desc = "Pointy."
icon_state = "fork"
+ sharp = 1
/obj/item/weapon/kitchen/utensil/fork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
@@ -114,6 +115,8 @@
icon_state = "knife"
force = 10.0
throwforce = 10.0
+ sharp = 1
+ edge = 1
suicide_act(mob/user)
viewers(user) << pick("\red [user] is slitting \his wrists with the [src.name]! It looks like \he's trying to commit suicide.", \
@@ -154,6 +157,7 @@
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
flags = FPRINT | TABLEPASS | CONDUCT
sharp = 1
+ edge = 1
force = 10.0
w_class = 3.0
throwforce = 6.0
@@ -192,6 +196,8 @@
m_amt = 12000
origin_tech = "materials=1"
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ sharp = 1
+ edge = 1
/obj/item/weapon/butch/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 627d689b1a..afa97b983b 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -19,6 +19,8 @@
flags = FPRINT | CONDUCT | NOSHIELD | TABLEPASS | NOBLOODY
origin_tech = "combat=3"
attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut")
+ sharp = 1
+ edge = 1
suicide_act(mob/user)
viewers(user) << "\red [user] swings the [src.name] towards /his head! It looks like \he's trying to commit suicide."
@@ -37,6 +39,8 @@
flags = FPRINT | TABLEPASS | NOSHIELD | NOBLOODY
origin_tech = "magnets=3;syndicate=4"
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ sharp = 1
+ edge = 1
/obj/item/weapon/melee/energy/sword/pirate
name = "energy cutlass"
@@ -48,6 +52,8 @@
desc = "A concentrated beam of energy in the shape of a blade. Very stylish... and lethal."
icon_state = "blade"
force = 70.0//Normal attacks deal very high damage.
+ sharp = 1
+ edge = 1
throwforce = 1//Throwing or dropping the item deletes it.
throw_speed = 1
throw_range = 1
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 4bd89f7d43..245ebea739 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -379,6 +379,8 @@ LOOK FOR SURGERY.DM*/
icon_state = "scalpel"
flags = FPRINT | TABLEPASS | CONDUCT
force = 10.0
+ sharp = 1
+ edge = 1
w_class = 2.0
throwforce = 5.0
throw_speed = 3
@@ -668,6 +670,8 @@ LOOK FOR SURGERY.DM*/
g_amt = 10000
origin_tech = "materials=1;biotech=1"
attack_verb = list("attacked", "slashed", "sawed", "cut")
+ sharp = 1
+ edge = 1
/*
/obj/item/weapon/circular_saw/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm
index 2a7f3a5061..d70a821c59 100644
--- a/code/game/objects/items/weapons/tools.dm
+++ b/code/game/objects/items/weapons/tools.dm
@@ -106,6 +106,8 @@
m_amt = 80
origin_tech = "materials=1;engineering=1"
attack_verb = list("pinched", "nipped")
+ sharp = 1
+ edge = 1
/obj/item/weapon/wirecutters/New()
if(prob(50))
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index 2e4d7ed311..abff1a9b5b 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -109,6 +109,8 @@
name = "fire axe"
desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?"
force = 5
+ sharp = 1
+ edge = 1
w_class = 4.0
slot_flags = SLOT_BACK
force_unwielded = 10
@@ -154,6 +156,8 @@
flags = FPRINT | TABLEPASS | NOSHIELD
origin_tech = "magnets=3;syndicate=4"
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ sharp = 1
+ edge = 1
/obj/item/weapon/twohanded/dualsaber/update_icon()
icon_state = "dualsaber[wielded]"
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 77a9d1267b..d087ca28cf 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -79,6 +79,8 @@
slot_flags = SLOT_BELT
force = 2
throwforce = 1
+ sharp = 1
+ edge = 1
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -99,6 +101,8 @@
slot_flags = SLOT_BELT
force = 40
throwforce = 10
+ sharp = 1
+ edge = 1
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -122,6 +126,8 @@
slot_flags = SLOT_BELT | SLOT_BACK
force = 40
throwforce = 10
+ sharp = 1
+ edge = 1
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -139,6 +145,7 @@
/obj/item/weapon/harpoon
name = "harpoon"
sharp = 1
+ edge = 0
desc = "Tharr she blows!"
icon_state = "harpoon"
item_state = "harpoon"
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index d68a7b3c8d..a46e22c1c4 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -10,7 +10,8 @@
animate_movement = 2
var/throwforce = 1
var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
- var/sharp = 0 // whether this object cuts
+ var/sharp = 0 // whether this object cuts
+ var/edge = 0 // whether this object is more likely to dismember
var/in_use = 0 // If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
var/damtype = "brute"
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index a0a9a9131b..3d21a3a2b2 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -110,7 +110,7 @@
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(!istype(W)) return
- if (is_sharp(W))
+ if (can_puncture(W))
visible_message("\red [user] pierces [src] with [W]!")
deflate(1)
if(W.damtype == BRUTE || W.damtype == BURN)
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index 288546872c..06bde28b9a 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -190,6 +190,7 @@ proc/move_mining_shuttle()
attack_verb = list("hit", "pierced", "sliced", "attacked")
var/drill_sound = 'sound/weapons/Genhit.ogg'
var/drill_verb = "picking"
+ sharp = 1
var/excavation_amount = 100
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 2620a20964..c39fe115ac 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -111,19 +111,16 @@
return 1
if("hurt")
+ var/datum/unarmed_attack/attack = M.species.unarmed
- M.attack_log += text("\[[time_stamp()]\] [M.species.attack_verb]ed [src.name] ([src.ckey])")
- src.attack_log += text("\[[time_stamp()]\] Has been [M.species.attack_verb]ed by [M.name] ([M.ckey])")
- msg_admin_attack("[key_name(M)] [M.species.attack_verb]ed [key_name(src)]")
+ M.attack_log += text("\[[time_stamp()]\] [pick(attack.attack_verb)]ed [src.name] ([src.ckey])")
+ src.attack_log += text("\[[time_stamp()]\] Has been [pick(attack.attack_verb)]ed by [M.name] ([M.ckey])")
+ msg_admin_attack("[key_name(M)] [pick(attack.attack_verb)]ed [key_name(src)]")
var/damage = rand(0, 5)//BS12 EDIT
if(!damage)
- if(M.species.attack_verb == "punch")
- playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
- else
- playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
-
- visible_message("\red [M] has attempted to [M.species.attack_verb] [src]!")
+ playsound(loc, attack.miss_sound, 25, 1, -1)
+ visible_message("\red [M] tried to [pick(attack.attack_verb)] [src]!")
return 0
@@ -133,20 +130,16 @@
if(HULK in M.mutations) damage += 5
- if(M.species.attack_verb == "punch")
- playsound(loc, "punch", 25, 1, -1)
- else
- playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
+ playsound(loc, attack.attack_sound, 25, 1, -1)
- visible_message("\red [M] has [M.species.attack_verb]ed [src]!")
+ visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!")
//Rearranged, so claws don't increase weaken chance.
if(damage >= 5 && prob(50))
visible_message("\red [M] has weakened [src]!")
apply_effect(2, WEAKEN, armor_block)
- if(M.species.punch_damage)
- damage += M.species.punch_damage
- apply_damage(damage, BRUTE, affecting, armor_block)
+ damage += attack.damage
+ apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge)
if("disarm")
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 1b12f62562..d53e4353b5 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -59,6 +59,36 @@
heal_overall_damage(0, -amount)
hud_updateflag |= 1 << HEALTH_HUD
+/mob/living/carbon/human/proc/adjustBruteLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
+ if(species && species.brute_mod)
+ amount = amount*species.brute_mod
+
+ if (organ_name in organs_by_name)
+ var/datum/organ/external/O = get_organ(organ_name)
+
+ if(amount > 0)
+ O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
+ else
+ //if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
+ O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
+
+ hud_updateflag |= 1 << HEALTH_HUD
+
+/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
+ if(species && species.burn_mod)
+ amount = amount*species.burn_mod
+
+ if (organ_name in organs_by_name)
+ var/datum/organ/external/O = get_organ(organ_name)
+
+ if(amount > 0)
+ O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
+ else
+ //if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
+ O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
+
+ hud_updateflag |= 1 << HEALTH_HUD
+
/mob/living/carbon/human/Stun(amount)
if(HULK in mutations) return
..()
@@ -138,11 +168,11 @@
//Damages ONE external organ, organ gets randomly selected from damagable ones.
//It automatically updates damage overlays if necesary
//It automatically updates health status
-/mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0)
+/mob/living/carbon/human/take_organ_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0)
var/list/datum/organ/external/parts = get_damageable_organs()
if(!parts.len) return
var/datum/organ/external/picked = pick(parts)
- if(picked.take_damage(brute,burn,sharp))
+ if(picked.take_damage(brute,burn,sharp,edge))
UpdateDamageIcon()
hud_updateflag |= 1 << HEALTH_HUD
updatehealth()
@@ -172,7 +202,7 @@
if(update) UpdateDamageIcon()
// damage MANY external organs, in random order
-/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/used_weapon = null)
+/mob/living/carbon/human/take_overall_damage(var/brute, var/burn, var/sharp = 0, var/edge = 0, var/used_weapon = null)
if(status_flags & GODMODE) return //godmode
var/list/datum/organ/external/parts = get_damageable_organs()
var/update = 0
@@ -182,7 +212,7 @@
var/brute_was = picked.brute_dam
var/burn_was = picked.burn_dam
- update |= picked.take_damage(brute,burn,sharp,used_weapon)
+ update |= picked.take_damage(brute,burn,sharp,edge,used_weapon)
brute -= (picked.brute_dam - brute_was)
burn -= (picked.burn_dam - burn_was)
@@ -227,7 +257,7 @@ This function restores all organs.
zone = "head"
return organs_by_name[zone]
-/mob/living/carbon/human/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/obj/used_weapon = null)
+/mob/living/carbon/human/apply_damage(var/damage = 0, var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/sharp = 0, var/edge = 0, var/obj/used_weapon = null)
//visible_message("Hit debug. [damage] | [damagetype] | [def_zone] | [blocked] | [sharp] | [used_weapon]")
if((damagetype != BRUTE) && (damagetype != BURN))
@@ -250,11 +280,15 @@ This function restores all organs.
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
- if(organ.take_damage(damage, 0, sharp, used_weapon))
+ if(species && species.brute_mod)
+ damage = damage*species.brute_mod
+ if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
UpdateDamageIcon()
if(BURN)
damageoverlaytemp = 20
- if(organ.take_damage(0, damage, sharp, used_weapon))
+ if(species && species.burn_mod)
+ damage = damage*species.burn_mod
+ if(organ.take_damage(0, damage, sharp, edge, used_weapon))
UpdateDamageIcon()
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 44deb248ca..8298d35564 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -232,7 +232,7 @@ emp_act
if(armor >= 2) return 0
if(!I.force) return 0
- apply_damage(I.force, I.damtype, affecting, armor , is_sharp(I), I)
+ apply_damage(I.force, I.damtype, affecting, armor , is_sharp(I), has_edge(I), I)
var/bloody = 0
if(((I.damtype == BRUTE) || (I.damtype == HALLOSS)) && prob(25 + (I.force * 2)))
diff --git a/code/modules/mob/living/carbon/monkey/npc.dm b/code/modules/mob/living/carbon/monkey/npc.dm
index 34f77bc75f..f863558605 100644
--- a/code/modules/mob/living/carbon/monkey/npc.dm
+++ b/code/modules/mob/living/carbon/monkey/npc.dm
@@ -86,14 +86,4 @@ mob/living/carbon/monkey/react_to_attack(mob/M)
emote("me", 2, "whimpers fearfully!")
npc_fleeing = M
- fleeing_duration = 30
-
-
-/*/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/slash = 0, var/used_weapon = null)
- if(!client && !stat)
- if(damage > 10)
- if(prob(40) || health == 100)
- emote("me", 2, pick("screams loudly!", "whimpers in pain!"))
- else if(health == 100 || (damage > 0 && prob(10)))
- emote("me", 1, pick("flails about wildly!", "cringes visibly!", "chimpers nervously."))
- return ..()*/
\ No newline at end of file
+ fleeing_duration = 30
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index 0537d59023..a928369dea 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -12,8 +12,8 @@
var/primitive // Lesser form, if any (ie. monkey for humans)
var/tail // Name of tail image in species effects icon file.
var/language // Default racial language, if any.
- var/attack_verb = "punch" // Empty hand hurt intent verb.
- var/punch_damage = 0 // Extra empty hand attack damage.
+ var/unarmed //For empty hand harm-intent attack
+ var/unarmed_type = /datum/unarmed_attack
var/mutantrace // Safeguard due to old code.
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
@@ -68,6 +68,9 @@
var/list/sprite_sheets = list()
+/datum/species/New()
+ unarmed = new unarmed_type()
+
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
//This is a basic humanoid limb setup.
H.organs = list()
@@ -121,6 +124,7 @@
name = "Human"
language = "Sol Common"
primitive = /mob/living/carbon/monkey
+ unarmed_type = /datum/unarmed_attack/punch
flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR
@@ -133,8 +137,7 @@
deform = 'icons/mob/human_races/r_def_lizard.dmi'
language = "Sinta'unathi"
tail = "sogtail"
- attack_verb = "scratch"
- punch_damage = 5
+ unarmed_type = /datum/unarmed_attack/claws
primitive = /mob/living/carbon/monkey/unathi
darksight = 3
@@ -156,8 +159,7 @@
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
language = "Siik'tajr"
tail = "tajtail"
- attack_verb = "scratch"
- punch_damage = 5
+ unarmed_type = /datum/unarmed_attack/claws
darksight = 8
cold_level_1 = 200 //Default 260
@@ -180,6 +182,7 @@
deform = 'icons/mob/human_races/r_def_skrell.dmi'
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
+ unarmed_type = /datum/unarmed_attack/punch
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
@@ -190,6 +193,7 @@
icobase = 'icons/mob/human_races/r_vox.dmi'
deform = 'icons/mob/human_races/r_def_vox.dmi'
language = "Vox-pidgin"
+ unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too.
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -231,7 +235,7 @@
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
language = "Vox-pidgin"
- attack_verb = "slash"
+ unarmed_type = /datum/unarmed_attack/claws/armalis
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -295,8 +299,7 @@
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
- attack_verb = "slash"
- punch_damage = 5
+ unarmed_type = /datum/unarmed_attack/diona
primitive = /mob/living/carbon/monkey/diona
warning_low_pressure = 50
@@ -341,7 +344,7 @@
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
language = "Tradeband"
- punch_damage = 2
+ unarmed_type = /datum/unarmed_attack/punch
eyes = "blank_eyes"
brute_mod = 0.5
@@ -362,3 +365,32 @@
blood_color = "#1F181F"
flesh_color = "#575757"
+
+//Species unarmed attacks
+
+/datum/unarmed_attack
+ var/attack_verb = list("attack") // Empty hand hurt intent verb.
+ var/damage = 0 // Extra empty hand attack damage.
+ var/attack_sound = "punch"
+ var/miss_sound = 'sound/weapons/punchmiss.ogg'
+ var/sharp = 0
+ var/edge = 0
+
+/datum/unarmed_attack/punch
+ attack_verb = list("punch")
+
+/datum/unarmed_attack/diona
+ attack_verb = list("lash", "bludgeon")
+ damage = 5
+
+/datum/unarmed_attack/claws
+ attack_verb = list("scratch", "claw")
+ attack_sound = 'sound/weapons/slice.ogg'
+ miss_sound = 'sound/weapons/slashmiss.ogg'
+ damage = 5
+ sharp = 1
+ edge = 1
+
+/datum/unarmed_attack/claws/armalis
+ attack_verb = list("slash", "claw")
+ damage = 10 //they're huge! they should do a little more damage, i'd even go for 15-20 maybe...
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index 333cc07380..5431a2775a 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, var/used_weapon = null)
+/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/used_weapon = null, var/sharp = 0, var/edge = 0)
if(!damage || (blocked >= 2)) return 0
switch(damagetype)
if(BRUTE)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 508ff93e23..c3075bcc13 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -53,11 +53,8 @@
signaler.signal()
var/absorb = run_armor_check(def_zone, P.flag)
- if(absorb >= 2)
- P.on_hit(src,2)
- return 2
if(!P.nodamage)
- apply_damage((P.damage/(absorb+1)), P.damage_type, def_zone, absorb, 0, P)
+ apply_damage(P.damage, P.damage_type, def_zone, absorb, 0, P, sharp=is_sharp(P), edge=has_edge(P))
P.on_hit(src, absorb, def_zone)
return absorb
@@ -72,7 +69,7 @@
src.visible_message("\red [src] has been hit by [O].")
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened hit to your [zone].")
if(armor < 2)
- apply_damage(O.throwforce*(speed/5), dtype, zone, armor, O.sharp, O)
+ apply_damage(O.throwforce*(speed/5), dtype, zone, armor, O, sharp=is_sharp(O), edge=has_edge(O))
if(!O.fingerprintslast)
return
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index fba4477b1d..9859518064 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -33,7 +33,7 @@
installed = -1
uninstall()
-/datum/robot_component/proc/take_damage(brute, electronics, sharp)
+/datum/robot_component/proc/take_damage(brute, electronics, sharp, edge)
if(installed != 1) return
brute_damage += brute
diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm
index 58f2042826..ed66f1ae49 100644
--- a/code/modules/mob/living/silicon/robot/robot_damage.dm
+++ b/code/modules/mob/living/silicon/robot/robot_damage.dm
@@ -62,7 +62,7 @@
var/datum/robot_component/picked = pick(parts)
picked.heal_damage(brute,burn)
-/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0)
+/mob/living/silicon/robot/take_organ_damage(var/brute = 0, var/burn = 0, var/sharp = 0, var/edge = 0)
var/list/components = get_damageable_components()
if(!components.len)
return
@@ -86,11 +86,11 @@
var/datum/robot_component/armour/A = get_armour()
if(A)
- A.take_damage(brute,burn,sharp)
+ A.take_damage(brute,burn,sharp,edge)
return
var/datum/robot_component/C = pick(components)
- C.take_damage(brute,burn,sharp)
+ C.take_damage(brute,burn,sharp,edge)
/mob/living/silicon/robot/heal_overall_damage(var/brute, var/burn)
var/list/datum/robot_component/parts = get_damaged_components(brute,burn)
diff --git a/code/modules/mob/living/simple_animal/bees.dm b/code/modules/mob/living/simple_animal/bees.dm
index 76e1de9457..45ece9f6df 100644
--- a/code/modules/mob/living/simple_animal/bees.dm
+++ b/code/modules/mob/living/simple_animal/bees.dm
@@ -41,7 +41,7 @@
if(worn_helmet)
sting_prob -= min(worn_helmet.armor["bio"],30) // Is your helmet sealed? I can't get to 30% of your body.
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) ) // Try to sting! If you're not moving, think about stinging.
- M.apply_damage(min(strength,2)+mut, BRUTE) // Stinging. The more mutated I am, the harder I sting.
+ M.apply_damage(min(strength,2)+mut, BRUTE, sharp=1) // Stinging. The more mutated I am, the harder I sting.
M.apply_damage((round(feral/10,1)*(max((round(strength/20,1)),1)))+toxic, TOX) // Bee venom based on how angry I am and how many there are of me!
M << "\red You have been stung!"
M.flash_pain()
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index b375755f54..0036d3c153 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -135,7 +135,7 @@
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
+ H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 79d41a16a9..f5955d337f 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -496,7 +496,7 @@
var/mob/living/carbon/human/H = parrot_interest
var/datum/organ/external/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
- H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
+ H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1)
emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons"))
else
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 72b26c939a..acd9efcb65 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -70,9 +70,9 @@
if(prob(probability))
droplimb(1)
else
- take_damage(damage, 0, 1, used_weapon = "EMP")
+ take_damage(damage, 0, 1, 1, used_weapon = "EMP")
-/datum/organ/external/proc/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
+/datum/organ/external/proc/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
if((brute <= 0) && (burn <= 0))
return 0
@@ -95,7 +95,7 @@
//If limb took enough damage, try to cut or tear it off
if(body_part != UPPER_TORSO && body_part != LOWER_TORSO) //as hilarious as it is, getting hit on the chest too much shouldn't effectively gib you.
if(config.limbs_can_break && brute_dam >= max_damage * config.organ_health_multiplier)
- if( (sharp && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) )
+ if( (edge && prob(5 * brute)) || (brute > 20 && prob(2 * brute)) )
droplimb(1)
return
@@ -159,7 +159,7 @@
if(possible_points.len)
//And pass the pain around
var/datum/organ/external/target = pick(possible_points)
- target.take_damage(brute, burn, sharp, used_weapon, forbidden_limbs + src)
+ target.take_damage(brute, burn, sharp, edge, used_weapon, forbidden_limbs + src)
// sync the organ's damage with its wounds
src.update_damages()
@@ -223,35 +223,7 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
if(damage == 0) return
- // first check whether we can widen an existing wound
- if(wounds.len > 0 && prob(max(50+owner.number_wounds*10,100)))
- if((type == CUT || type == BRUISE) && damage >= 5)
- var/datum/wound/W = pick(wounds)
- if(W.amount == 1 && W.started_healing())
- W.open_wound(damage)
- if(prob(25))
- owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
- "\red The wound on your [display_name] widens with a nasty ripping voice.",\
- "You hear a nasty ripping noise, as if flesh is being torn apart.")
- return
-
- //Creating wound
- var/datum/wound/W
- var/size = min( max( 1, damage/10 ) , 6)
- //Possible types of wound
- var/list/size_names = list()
- switch(type)
- if(CUT)
- size_names = typesof(/datum/wound/cut/) - /datum/wound/cut/
- if(BRUISE)
- size_names = typesof(/datum/wound/bruise/) - /datum/wound/bruise/
- if(BURN)
- size_names = typesof(/datum/wound/burn/) - /datum/wound/burn/
-
- size = min(size,size_names.len)
- var/wound_type = size_names[size]
- W = new wound_type(damage)
-
+ //moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage
//Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage
if(damage > 15 && type != BURN && local_damage > 30 && prob(damage) && !(status & ORGAN_ROBOT))
@@ -259,17 +231,56 @@ This function completely restores a damaged organ to perfect condition.
wounds += I
owner.custom_pain("You feel something rip in your [display_name]!", 1)
+ // first check whether we can widen an existing wound
+ if(wounds.len > 0 && prob(max(50+(number_wounds-1)*10,90)))
+ if((type == CUT || type == BRUISE) && damage >= 5)
+ //we need to make sure that the wound we are going to worsen is compatible with the type of damage...
+ var/list/compatible_wounds = list()
+ for (var/datum/wound/W in wounds)
+ if (W.can_worsen(type, damage))
+ compatible_wounds += W
+
+ var/datum/wound/W = pick(compatible_wounds)
+ W.open_wound(damage)
+ if(prob(25))
+ //maybe have a separate message for BRUISE type damage?
+ owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
+ "\red The wound on your [display_name] widens with a nasty ripping voice.",\
+ "You hear a nasty ripping noise, as if flesh is being torn apart.")
+ return
+
+ //Creating wound
+ var/wound_type = get_wound_type(type, damage)
+ var/datum/wound/W = new wound_type(damage)
+
//Check whether we can add the wound to an existing wound
for(var/datum/wound/other in wounds)
- if(other.desc == W.desc)
- // okay, add it!
- other.damage += W.damage
- other.amount += 1
+ if(other.can_merge(W))
+ other.merge_wound(W)
W = null // to signify that the wound was added
break
if(W)
wounds += W
+/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
+ //if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
+ switch(type)
+ if(CUT)
+ if (damage <= 5) return /datum/wound/cut/small
+ if (damage <= 15) return /datum/wound/cut/deep
+ if (damage <= 25) return /datum/wound/cut/flesh
+ if (damage <= 50) return /datum/wound/cut/gaping
+ if (damage <= 60) return /datum/wound/cut/gaping_big
+ return /datum/wound/cut/massive
+ if(BRUISE)
+ return /datum/wound/bruise
+ if(BURN)
+ if (damage <= 5) return /datum/wound/burn/moderate
+ if (damage <= 15) return /datum/wound/burn/large
+ if (damage <= 30) return /datum/wound/burn/severe
+ if (damage <= 40) return /datum/wound/burn/deep
+ if (damage <= 50) return /datum/wound/burn/carbonised
+
/****************************************************
PROCESSING & UPDATING
****************************************************/
@@ -388,15 +399,12 @@ This function completely restores a damaged organ to perfect condition.
if(prob(1 * wound_update_accuracy))
owner.custom_pain("You feel a stabbing pain in your [display_name]!",1)
-
// slow healing
var/heal_amt = 0
- if (W.damage < 15) //this thing's edges are not in day's travel of each other, what healing?
- heal_amt += 0.2
-
- if(W.is_treated() && W.damage < 50) //whoa, not even magical band aid can hold it together
- heal_amt += 0.3
+ // if damage >= 50 AFTER treatment then it's probably too severe to heal within the timeframe of a round.
+ if (W.is_treated() && W.wound_damage() < 50)
+ heal_amt += 0.5
//we only update wounds once in [wound_update_accuracy] ticks so have to emulate realtime
heal_amt = heal_amt * wound_update_accuracy
@@ -800,8 +808,8 @@ This function completely restores a damaged organ to perfect condition.
else
. = new /icon(owner.race_icon, "[icon_name]_[g]")
-/datum/organ/external/head/take_damage(brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list())
- ..(brute, burn, sharp, used_weapon, forbidden_limbs)
+/datum/organ/external/head/take_damage(brute, burn, sharp, edge, used_weapon = null, list/forbidden_limbs = list())
+ ..(brute, burn, sharp, edge, used_weapon, forbidden_limbs)
if (!disfigured)
if (brute_dam > 40)
if (prob(50))
diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm
index 3df9e206c9..a789248627 100644
--- a/code/modules/organs/wound.dm
+++ b/code/modules/organs/wound.dm
@@ -3,8 +3,6 @@
WOUNDS
****************************************************/
/datum/wound
- // stages such as "cut", "deep cut", etc.
- var/list/stages
// number representing the current stage
var/current_stage = 0
@@ -18,38 +16,42 @@
// amount of damage the current wound type requires(less means we need to apply the next healing stage)
var/min_damage = 0
- // one of CUT, BRUISE, BURN
- var/damage_type = CUT
-
- // whether this wound needs a bandage/salve to heal at all
- var/needs_treatment = 0
-
// is the wound bandaged?
- var/tmp/bandaged = 0
+ var/bandaged = 0
// Similar to bandaged, but works differently
- var/tmp/clamped = 0
+ var/clamped = 0
// is the wound salved?
- var/tmp/salved = 0
+ var/salved = 0
// is the wound disinfected?
- var/tmp/disinfected = 0
- var/tmp/created = 0
-
+ var/disinfected = 0
+ var/created = 0
// number of wounds of this type
- var/tmp/amount = 1
+ var/amount = 1
+ // amount of germs in the wound
+ var/germ_level = 0
+ /* These are defined by the wound type and should not be changed */
+
+ // stages such as "cut", "deep cut", etc.
+ var/list/stages
+ // internal wounds can only be fixed through surgery
+ var/internal = 0
// maximum stage at which bleeding should still happen, counted from the right rather than the left of the list
// 1 means all stages except the last should bleed
var/max_bleeding_stage = 1
+ // one of CUT, BRUISE, BURN
+ var/damage_type = CUT
+ // whether this wound needs a bandage/salve to heal at all
+ // the maximum amount of damage that this wound can have and still autoheal
+ var/autoheal_cutoff = 15
+
- // internal wounds can only be fixed through surgery
- var/internal = 0
- // amount of germs in the wound
- var/germ_level = 0
// helper lists
var/tmp/list/desc_list = list()
var/tmp/list/damage_list = list()
+
New(var/damage)
created = world.time
@@ -62,42 +64,58 @@
src.damage = damage
- // initialize with the first stage
- next_stage()
-
- // this will ensure the size of the wound matches the damage
- src.heal_damage(0)
-
- // make the max_bleeding_stage count from the end of the list rather than the start
- // this is more robust to changes to the list
max_bleeding_stage = src.desc_list.len - max_bleeding_stage
+
+ // initialize with the appropriate stage
+ src.init_stage(damage)
bleed_timer += damage
// returns 1 if there's a next stage, 0 otherwise
- proc/next_stage()
- if(current_stage + 1 > src.desc_list.len)
- return 0
-
- current_stage++
+ proc/init_stage(var/initial_damage)
+ current_stage = stages.len
+
+ while(src.current_stage > 1 && src.damage_list[current_stage-1] <= initial_damage / src.amount)
+ src.current_stage--
src.min_damage = damage_list[current_stage]
src.desc = desc_list[current_stage]
- return 1
-
- // returns 1 if the wound has started healing
- proc/started_healing()
- return (current_stage > 1)
+ // the amount of damage per wound
+ proc/wound_damage()
+ return src.damage / src.amount
+
// checks whether the wound has been appropriately treated
- // always returns 1 for wounds that don't need to be treated
+ // always returns 1 for wounds that are too minor to need treatment
proc/is_treated()
- if(!needs_treatment) return 1
+ if(src.wound_damage() <= autoheal_cutoff)
+ return 1
if(damage_type == BRUISE || damage_type == CUT)
return bandaged
else if(damage_type == BURN)
return salved
+
+
+ // Checks whether other other can be merged into src.
+ proc/can_merge(var/datum/wound/other)
+ if (other.type != src.type) return 0
+ if (other.current_stage != src.current_stage) return 0
+ if (other.damage_type != src.damage_type) return 0
+ if (!(other.is_treated()) != !(src.is_treated())) return 0
+ if (!(other.bandaged) != !(src.bandaged)) return 0
+ if (!(other.clamped) != !(src.clamped)) return 0
+ if (!(other.salved) != !(src.salved)) return 0
+ if (!(other.disinfected) != !(src.disinfected)) return 0
+ //if (other.germ_level != src.germ_level) return 0
+ return 1
+
+ proc/merge_wound(var/datum/wound/other)
+ src.damage += other.damage
+ src.amount += other.amount
+ src.bleed_timer += other.bleed_timer
+ src.germ_level = max(src.germ_level, other.germ_level)
+ src.created = max(src.created, other.created) //take the newer created time
// checks if wound is considered open for external infections
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
@@ -128,7 +146,7 @@
amount -= healed_damage
src.damage -= healed_damage
- while(src.damage / src.amount < damage_list[current_stage] && current_stage < src.desc_list.len)
+ while(src.wound_damage() < damage_list[current_stage] && current_stage < src.desc_list.len)
current_stage++
desc = desc_list[current_stage]
src.min_damage = damage_list[current_stage]
@@ -141,118 +159,98 @@
src.damage += damage
bleed_timer += damage
- while(src.current_stage > 1 && src.damage_list[current_stage-1] <= src.damage)
+ while(src.current_stage > 1 && src.damage_list[current_stage-1] <= src.damage / src.amount)
src.current_stage--
src.desc = desc_list[current_stage]
src.min_damage = damage_list[current_stage]
+ // returns whether this wound can absorb the given amount of damage.
+ // this will prevent large amounts of damage being trapped in less severe wound types
+ proc/can_worsen(damage_type, damage)
+ if (src.damage_type != damage_type)
+ return 0 //incompatible damage types
+
+ if (src.amount > 1)
+ return 0
+
+ //with 1.5*, a shallow cut will be able to carry at most 30 damage,
+ //37.5 for a deep cut
+ //52.5 for a flesh wound, etc.
+ var/max_wound_damage = 1.5*src.damage_list[1]
+ if (src.damage + damage > max_wound_damage)
+ return 0
+
+ return 1
+
+
proc/bleeding()
// internal wounds don't bleed in the sense of this function
- return ((damage > 30 || bleed_timer > 0) && !(bandaged||clamped) && (damage_type == BRUISE && damage >= 20 || damage_type == CUT && damage >= 5) && current_stage <= max_bleeding_stage && !src.internal)
+ return ((wound_damage() > 30 || bleed_timer > 0) && !(bandaged||clamped) && (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5) && current_stage <= max_bleeding_stage && !src.internal)
/** CUTS **/
/datum/wound/cut/small
// link wound descriptions to amounts of damage
max_bleeding_stage = 2
stages = list("ugly ripped cut" = 20, "ripped cut" = 10, "cut" = 5, "healing cut" = 2, "small scab" = 0)
+ damage_type = CUT
/datum/wound/cut/deep
max_bleeding_stage = 3
stages = list("ugly deep ripped cut" = 25, "deep ripped cut" = 20, "deep cut" = 15, "clotted cut" = 8, "scab" = 2, "fresh skin" = 0)
+ damage_type = CUT
/datum/wound/cut/flesh
max_bleeding_stage = 3
stages = list("ugly ripped flesh wound" = 35, "ugly flesh wound" = 30, "flesh wound" = 25, "blood soaked clot" = 15, "large scab" = 5, "fresh skin" = 0)
+ damage_type = CUT
/datum/wound/cut/gaping
max_bleeding_stage = 2
- stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "large clot" = 15, "small angry scar" = 5, \
- "small straight scar" = 0)
+ stages = list("gaping wound" = 50, "large blood soaked clot" = 25, "large clot" = 15, "small angry scar" = 5, "small straight scar" = 0)
+ damage_type = CUT
/datum/wound/cut/gaping_big
max_bleeding_stage = 2
stages = list("big gaping wound" = 60, "healing gaping wound" = 40, "large angry scar" = 10, "large straight scar" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
+ damage_type = CUT
datum/wound/cut/massive
max_bleeding_stage = 2
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive angry scar" = 10, "massive jagged scar" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
+ damage_type = CUT
/** BRUISES **/
/datum/wound/bruise
stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,\
"moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
-
- needs_treatment = 1 // this only heals when bandaged
+ max_bleeding_stage = 3
+ autoheal_cutoff = 30
damage_type = BRUISE
-/datum/wound/bruise/monumental
-
-// implement sub-paths by starting at a later stage
-
-/datum/wound/bruise/tiny
- current_stage = 5
- needs_treatment = 0
-
-/datum/wound/bruise/small
- current_stage = 4
- needs_treatment = 0
-
-/datum/wound/bruise/moderate
- current_stage = 3
- needs_treatment = 0
-
-/datum/wound/bruise/large
- current_stage = 2
-
-/datum/wound/bruise/huge
- current_stage = 1
-
/** BURNS **/
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "moderate salved burn" = 2, "fresh skin" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
-
damage_type = BURN
/datum/wound/burn/large
stages = list("ripped large burn" = 20, "large burn" = 15, "large salved burn" = 5, "fresh skin" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
-
damage_type = BURN
/datum/wound/burn/severe
stages = list("ripped severe burn" = 35, "severe burn" = 30, "severe salved burn" = 10, "burn scar" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
-
damage_type = BURN
/datum/wound/burn/deep
stages = list("ripped deep burn" = 45, "deep burn" = 40, "deep salved burn" = 15, "large burn scar" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
-
damage_type = BURN
-
/datum/wound/burn/carbonised
stages = list("carbonised area" = 50, "treated carbonised area" = 20, "massive burn scar" = 0)
-
- needs_treatment = 1 // this only heals when bandaged
-
damage_type = BURN
/datum/wound/internal_bleeding
internal = 1
-
stages = list("severed vein" = 30, "cut vein" = 20, "damaged vein" = 10, "bruised vein" = 5)
- max_bleeding_stage = 0
-
- needs_treatment = 1
+ autoheal_cutoff = 5
+ max_bleeding_stage = 0 //all stages bleed. It's called internal bleeding after all.
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 24465bc08f..928c56b10c 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -750,5 +750,6 @@
src.visible_message("\red [name] shatters.","\red You hear a small glass object shatter.")
status = LIGHT_BROKEN
force = 5
+ sharp = 1
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
update()
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 272216f275..a76dc35767 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -201,7 +201,7 @@
in_chamber.on_hit(M)
if (in_chamber.damage_type != HALLOSS)
- user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]")
+ user.apply_damage(in_chamber.damage*2.5, in_chamber.damage_type, "head", used_weapon = "Point blank shot in the mouth with \a [in_chamber]", sharp=1)
user.death()
else
user << "Ow..."
diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm
index 1a2889e08c..6aa16bc08e 100644
--- a/code/modules/projectiles/guns/alien.dm
+++ b/code/modules/projectiles/guns/alien.dm
@@ -5,6 +5,7 @@
name = "alloy spike"
desc = "It's about a foot of weird silver metal with a wicked point."
sharp = 1
+ edge = 0
throwforce = 5
w_class = 2
icon = 'icons/obj/weapons.dmi'
diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm
index 3d80063aa6..912b5f2f1e 100644
--- a/code/modules/projectiles/guns/projectile/bow.dm
+++ b/code/modules/projectiles/guns/projectile/bow.dm
@@ -9,6 +9,7 @@
throwforce = 8
w_class = 3.0
sharp = 1
+ edge = 0
/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart.
return
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 07bf9bd0f6..19806429a3 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -183,7 +183,7 @@
playsound(user, fire_sound, 50, 1)
user.visible_message("[user.name] fires [src] at \his head!", "You fire [src] at your head!", "You hear a [istype(in_chamber, /obj/item/projectile/beam) ? "laser blast" : "gunshot"]!")
if(!P.nodamage)
- user.apply_damage(300, BRUTE, affecting) // You are dead, dead, dead.
+ user.apply_damage(300, BRUTE, affecting, sharp=1) // You are dead, dead, dead.
return
..()
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index dfc898f575..cc38efa29e 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -6,6 +6,7 @@
nodamage = 0
flag = "bullet"
embed = 1
+ sharp = 1
on_hit(var/atom/target, var/blocked = 0)
if (..(target, blocked))
@@ -17,6 +18,7 @@
stun = 5
weaken = 5
embed = 0
+ sharp = 0
/obj/item/projectile/bullet/weakbullet/beanbag //because beanbags are not bullets
name = "beanbag"
@@ -47,6 +49,8 @@
/obj/item/projectile/bullet/burstbullet//I think this one needs something for the on hit
name = "exploding bullet"
damage = 20
+ embed = 0
+ edge = 1
/obj/item/projectile/bullet/stunshot
@@ -56,6 +60,7 @@
weaken = 10
stutter = 10
embed = 0
+ sharp = 0
/obj/item/projectile/bullet/a762
damage = 25
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index 70a5e9e326..f426eefb2f 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -17,7 +17,8 @@
icon_state= "bolter"
damage = 50
flag = "bullet"
-
+ sharp = 1
+ edge = 1
on_hit(var/atom/target, var/blocked = 0)
explosion(target, -1, 0, 2)
diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
index 64cd2c3e94..93c61ece1c 100644
--- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
+++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm
@@ -77,7 +77,7 @@
armor_duration /= 10
//Apply the damage!
- target.apply_damage(force, BRUTE, affecting, armor_block)
+ target.apply_damage(force, BRUTE, affecting, armor_block, sharp=0)
// You are going to knock someone out for longer if they are not wearing a helmet.
if(affecting == "head" && istype(target, /mob/living/carbon/))
@@ -125,6 +125,8 @@
throw_range = 5
item_state = "beer"
attack_verb = list("stabbed", "slashed", "attacked")
+ sharp = 1
+ edge = 0
var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken")
/obj/item/weapon/broken_bottle/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 183e74fba0..95ff6c40b2 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -16,6 +16,7 @@
possible_transfer_amounts = null //list(5,10,15)
volume = 15
w_class = 1
+ sharp = 1
var/mode = SYRINGE_DRAW
on_reagent_change()
diff --git a/code/modules/research/xenoarchaeology/finds/finds_misc.dm b/code/modules/research/xenoarchaeology/finds/finds_misc.dm
index 874bd907a4..e3e0d96197 100644
--- a/code/modules/research/xenoarchaeology/finds/finds_misc.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds_misc.dm
@@ -5,6 +5,9 @@
force = 8.0
throwforce = 15.0
icon_state = "phoronlarge"
+ sharp = 1
+ edge = 1
+
/obj/item/weapon/shard/phoron/New()
src.icon_state = pick("phoronlarge", "phoronmedium", "phoronsmall")
diff --git a/code/modules/research/xenoarchaeology/geosample.dm b/code/modules/research/xenoarchaeology/geosample.dm
index a2ea98a430..401ae13cd3 100644
--- a/code/modules/research/xenoarchaeology/geosample.dm
+++ b/code/modules/research/xenoarchaeology/geosample.dm
@@ -20,6 +20,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "sliver1" //0-4
w_class = 1
+ sharp = 1
//item_state = "electronic"
var/source_rock = "/turf/simulated/mineral/"
var/datum/geosample/geological_data
diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm
index 767cef719a..b89c48275b 100644
--- a/code/modules/surgery/braincore.dm
+++ b/code/modules/surgery/braincore.dm
@@ -62,7 +62,7 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
"\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(50, BRUTE, "head", 1)
+ target.apply_damage(50, BRUTE, "head", 1, sharp=1)
/datum/surgery_step/brain/saw_spine
allowed_tools = list(
@@ -114,7 +114,7 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, cutting a vein in [target]'s brain with \the [tool]!", \
"\red Your hand slips, cutting a vein in [target]'s brain with \the [tool]!")
- target.apply_damage(30, BRUTE, "head", 1)
+ target.apply_damage(30, BRUTE, "head", 1, sharp=1)
if (ishuman(user))
user:bloody_body(target)
user:bloody_hands(target, 0)
@@ -151,7 +151,7 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, jabbing \the [tool] in [target]'s brain!", \
"\red Your hand slips, jabbing \the [tool] in [target]'s brain!")
- target.apply_damage(30, BRUTE, "head", 1)
+ target.apply_damage(30, BRUTE, "head", 1, sharp=1)
/datum/surgery_step/brain/hematoma
allowed_tools = list(
@@ -181,7 +181,7 @@
fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("\red [user]'s hand slips, bruising [target]'s brain with \the [tool]!", \
"\red Your hand slips, bruising [target]'s brain with \the [tool]!")
- target.apply_damage(20, BRUTE, "head", 1)
+ target.apply_damage(20, BRUTE, "head", 1, sharp=1)
//////////////////////////////////////////////////////////////////
// SLIME CORE EXTRACTION //
diff --git a/code/modules/surgery/eye.dm b/code/modules/surgery/eye.dm
index b65aaf9608..9977271c76 100644
--- a/code/modules/surgery/eye.dm
+++ b/code/modules/surgery/eye.dm
@@ -104,7 +104,7 @@
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, stabbing \the [tool] into [target]'s eye!", \
"\red Your hand slips, stabbing \the [tool] into [target]'s eye!")
- target.apply_damage(10, BRUTE, affected)
+ target.apply_damage(10, BRUTE, affected, sharp=1)
eyes.take_damage(5, 0)
/datum/surgery_step/eye/cauterize
diff --git a/code/modules/surgery/face.dm b/code/modules/surgery/face.dm
index b3569b0887..7c04800f5a 100644
--- a/code/modules/surgery/face.dm
+++ b/code/modules/surgery/face.dm
@@ -98,7 +98,7 @@
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, tearing skin on [target]'s face with \the [tool]!", \
"\red Your hand slips, tearing skin on [target]'s face with \the [tool]!")
- target.apply_damage(10, BRUTE, affected)
+ target.apply_damage(10, BRUTE, affected, sharp=1, sharp=1)
/datum/surgery_step/face/cauterize
allowed_tools = list(
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index 1ee3408b41..dc0af3936a 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -228,7 +228,7 @@
msg = "\red [user]'s hand slips, damaging several organs in [target]'s lower abdomen with \the [tool]"
self_msg = "\red Your hand slips, damaging several organs in [target]'s lower abdomen with \the [tool]!"
user.visible_message(msg, self_msg)
- target.apply_damage(12, BRUTE, affected)
+ target.apply_damage(12, BRUTE, affected, sharp=1)
/datum/surgery_step/generic/cauterize
allowed_tools = list(
diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm
index eb5c696426..038ba1dfcd 100644
--- a/code/modules/surgery/headreattach.dm
+++ b/code/modules/surgery/headreattach.dm
@@ -189,4 +189,4 @@
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, damaging connectors on [target]'s neck!", \
"\red Your hand slips, damaging connectors on [target]'s neck!")
- target.apply_damage(10, BRUTE, affected)
+ target.apply_damage(10, BRUTE, affected, sharp=1)
diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm
index 3be16401be..f4af506c63 100644
--- a/code/modules/surgery/robolimbs.dm
+++ b/code/modules/surgery/robolimbs.dm
@@ -85,7 +85,7 @@
affected = affected.parent
user.visible_message("\red [user]'s hand slips, tearing flesh on [target]'s [affected.display_name]!", \
"\red Your hand slips, tearing flesh on [target]'s [affected.display_name]!")
- target.apply_damage(10, BRUTE, affected)
+ target.apply_damage(10, BRUTE, affected, sharp=1)
/datum/surgery_step/limb/prepare
@@ -166,4 +166,4 @@
var/datum/organ/external/affected = target.get_organ(target_zone)
user.visible_message("\red [user]'s hand slips, damaging connectors on [target]'s [affected.display_name]!", \
"\red Your hand slips, damaging connectors on [target]'s [affected.display_name]!")
- target.apply_damage(10, BRUTE, affected)
+ target.apply_damage(10, BRUTE, affected, sharp=1)