diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index dd9e4f28b9..aa4e6ced11 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -1,12 +1,11 @@
-
//Called when the mob is hit with an item in combat.
/mob/living/carbon/resolve_item_attack(obj/item/I, mob/living/user, var/effective_force, var/hit_zone)
- if(check_attack_throat(I, user))
+ if(check_neckgrab_attack(I, user, hit_zone))
return null
..()
/mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone)
- if(!effective_force || blocked >= 100)
+ if(!effective_force || blocked >= 100)
return 0
//Hulk modifier
@@ -39,18 +38,23 @@
return 1
// Attacking someone with a weapon while they are neck-grabbed
-/mob/living/carbon/proc/check_attack_throat(obj/item/W, mob/user)
+/mob/living/carbon/proc/check_neckgrab_attack(obj/item/W, mob/user, var/hit_zone)
if(user.a_intent == I_HURT)
for(var/obj/item/weapon/grab/G in src.grabbed_by)
- if(G.assailant == user && G.state >= GRAB_NECK)
- if(attack_throat(W, G, user))
- return 1
+ if(G.assailant == user)
+ if(G.state >= GRAB_AGGRESSIVE)
+ if(hit_zone == BP_TORSO && shank_attack(W, G, user))
+ return 1
+ if(G.state >= GRAB_NECK)
+ if(hit_zone == BP_HEAD && attack_throat(W, G, user, hit_zone))
+ return 1
return 0
+
// Knifing
/mob/living/carbon/proc/attack_throat(obj/item/W, obj/item/weapon/grab/G, mob/user)
- if(!W.edge || !W.force || W.damtype != BRUTE)
+ if(!W.edge || !W.force || W.damtype != BRUTE)
return 0 //unsuitable weapon
user.visible_message("\The [user] begins to slit [src]'s throat with \the [W]!")
@@ -95,4 +99,59 @@
user.attack_log += "\[[time_stamp()]\] Knifed [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])"
src.attack_log += "\[[time_stamp()]\] Got knifed by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])"
msg_admin_attack("[key_name(user)] knifed [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" )
- return 1
\ No newline at end of file
+ return 1
+
+/mob/living/carbon/proc/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone)
+
+ if(!W.sharp || !W.force || W.damtype != BRUTE)
+ return 0 //unsuitable weapon
+
+ user.visible_message("\The [user] plunges \the [W] into \the [src]!")
+
+ var/damage = shank_armor_helper(W, G, user)
+ apply_damage(damage, W.damtype, "torso", 0, sharp=W.sharp, edge=W.edge)
+
+ if(W.hitsound)
+ playsound(loc, W.hitsound, 50, 1, -1)
+
+ user.attack_log += "\[[time_stamp()]\] Shanked [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])"
+ src.attack_log += "\[[time_stamp()]\] Got shanked by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])"
+ msg_admin_attack("[key_name(user)] shanked [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" )
+
+ return 1
+
+/mob/living/carbon/proc/shank_armor_helper(obj/item/W, obj/item/weapon/grab/G, mob/user)
+ var/damage = W.force
+ var/damage_mod = 1
+ if(W.edge)
+ damage = damage * 1.25 //small damage bonus for having sharp and edge
+
+ var/obj/item/clothing/suit/worn_suit
+ var/obj/item/clothing/under/worn_under
+ var/worn_suit_armor
+ var/worn_under_armor
+
+ //if(slot_wear_suit)
+ if(get_equipped_item(slot_wear_suit))
+ worn_suit = get_equipped_item(slot_wear_suit)
+ //worn_suit = get_equipped_item(slot_wear_suit)
+ worn_suit_armor = worn_suit.armor["melee"]
+ else
+ worn_suit_armor = 0
+
+ //if(slot_w_uniform)
+ if(get_equipped_item(slot_w_uniform))
+ worn_under = get_equipped_item(slot_w_uniform)
+ //worn_under_armor = slot_w_uniform.armor["melee"]
+ worn_under_armor = worn_under.armor["melee"]
+ else
+ worn_under_armor = 0
+
+ if(worn_under_armor > worn_suit_armor)
+ damage_mod = 1 - (worn_under_armor/100)
+ else
+ damage_mod = 1 - (worn_suit_armor/100)
+
+ damage = damage * damage_mod
+
+ return damage
\ 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 1d716b519d..2adb24665b 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -147,7 +147,7 @@ emp_act
..()
/mob/living/carbon/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone)
- if(check_attack_throat(I, user))
+ if(check_neckgrab_attack(I, user, target_zone))
return null
if(user == src) // Attacking yourself can't miss
@@ -464,3 +464,30 @@ emp_act
return perm
+/mob/living/carbon/human/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone)
+
+ if(!..())
+ return 0
+
+ var/organ_chance = 50
+ var/damage = shank_armor_helper(W, G, user)
+ var/obj/item/organ/external/chest = get_organ(hit_zone)
+
+ if(W.edge)
+ organ_chance = 75
+ user.next_move = world.time + 20
+ user.visible_message("\The [user] begins to twist \the [W] around inside [src]'s [chest]!")
+ if(!do_after(user, 20))
+ return 0
+ if(!(G && G.assailant == user && G.affecting == src)) //check that we still have a grab
+ return 0
+
+ user.visible_message("\The [user] twists \the [W] around inside [src]'s [chest]!")
+
+ if(prob(organ_chance))
+ var/obj/item/organ/internal/selected_organ = pick(chest.internal_organs)
+ selected_organ.damage = max(selected_organ.damage, damage * 0.5)
+ G.last_action = world.time
+ flick(G.hud.icon_state, G.hud)
+
+ return 1
\ No newline at end of file
diff --git a/html/changelogs/Yoshax-Shanking.yml b/html/changelogs/Yoshax-Shanking.yml
new file mode 100644
index 0000000000..b587abda14
--- /dev/null
+++ b/html/changelogs/Yoshax-Shanking.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Yoshax
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Shanking has been added. You can shank someone by getting an aggressive grab on them, targetting their chest and attacking them with a sharp item. This has a special attack that has greatly increased chance to do internal damage, also does bonus damage for weapons that are both sharp and have edge."