diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm
index c2f590c5613..6cc507aeecc 100644
--- a/code/game/objects/effects/misc.dm
+++ b/code/game/objects/effects/misc.dm
@@ -5,4 +5,23 @@
icon = 'icons/obj/items.dmi'
icon_state = "strangepresent"
density = 1
- anchored = 0
\ No newline at end of file
+ anchored = 0
+
+// Shown really briefly when attacking with axes.
+/obj/effect/temporary_effect/cleave_attack
+ name = "cleaving attack"
+ desc = "Something swinging really wide."
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "cleave"
+ layer = 6
+ time_to_die = 6
+ alpha = 140
+ invisibility = 0
+ mouse_opacity = 0
+ new_light_range = 0
+ new_light_power = 0
+ pixel_x = -32
+ pixel_y = -32
+
+/obj/effect/temporary_effect/cleave_attack/initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself.
+ animate(src, alpha = 0, time = time_to_die - 1)
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index 7b6e6184f1c..375c6eee680 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -100,3 +100,4 @@
icon_state = "survivalknife"
item_state = "knife"
applies_material_colour = FALSE
+ should_cleave = FALSE
diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm
index 6afacb30cb9..d66cd3efab8 100644
--- a/code/game/objects/items/weapons/material/misc.dm
+++ b/code/game/objects/items/weapons/material/misc.dm
@@ -32,6 +32,13 @@
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
attack_verb = list("chopped", "torn", "cut")
applies_material_colour = 0
+ var/should_cleave = TRUE // Because knives inherit from hatchets. For some reason.
+
+// This cannot go into afterattack since some mobs delete themselves upon dying.
+/obj/item/weapon/material/hatchet/pre_attack(var/mob/living/target, var/mob/living/user)
+ if(should_cleave && istype(target))
+ cleave(user, target)
+ ..()
/obj/item/weapon/material/hatchet/unathiknife
name = "duelling knife"
@@ -39,6 +46,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "unathiknife"
attack_verb = list("ripped", "torn", "cut")
+ should_cleave = FALSE
var hits = 0
/obj/item/weapon/material/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob)
@@ -56,6 +64,7 @@
hits = initial(hits)
..()
+// These probably shouldn't inherit from hatchets.
/obj/item/weapon/material/hatchet/tacknife
name = "tactical knife"
desc = "You'd be killing loads of people if this was Medal of Valor: Heroes of Space."
@@ -64,6 +73,7 @@
item_state = "knife"
attack_verb = list("stabbed", "chopped", "cut")
applies_material_colour = 1
+ should_cleave = FALSE
/obj/item/weapon/material/hatchet/tacknife/combatknife
name = "combat knife"
@@ -75,6 +85,7 @@
thrown_force_divisor = 1.75 // 20 with weight 20 (steel)
attack_verb = list("sliced", "stabbed", "chopped", "cut")
applies_material_colour = 1
+ should_cleave = FALSE
/obj/item/weapon/material/minihoe // -- Numbers
name = "mini hoe"
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 2533a07e63f..c2952cfc1e5 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -97,6 +97,12 @@
icon_state = initial(icon_state)
to_chat(user, "\The [src] is de-energised. It's just a regular axe now.")
+// This cannot go into afterattack since some mobs delete themselves upon dying.
+/obj/item/weapon/melee/energy/axe/pre_attack(var/mob/living/target, var/mob/living/user)
+ if(istype(target))
+ cleave(user, target)
+ ..()
+
/obj/item/weapon/melee/energy/axe/suicide_act(mob/user)
visible_message("\The [user] swings \the [src] towards \his head! It looks like \he's trying to commit suicide.")
return (BRUTELOSS|FIRELOSS)
diff --git a/code/game/objects/weapons.dm b/code/game/objects/weapons.dm
index b78f5d45857..7a619477eaf 100644
--- a/code/game/objects/weapons.dm
+++ b/code/game/objects/weapons.dm
@@ -19,6 +19,8 @@
/obj/item/weapon/proc/cleave(var/mob/living/user, var/mob/living/target)
if(cleaving)
return // We're busy.
+ if(get_turf(user) == get_turf(target))
+ return // Otherwise we would hit all eight surrounding tiles.
cleaving = TRUE
var/hit_mobs = 0
for(var/mob/living/simple_animal/SA in orange(get_turf(target), 1))
@@ -35,6 +37,13 @@
if(resolve_attackby(SA, user)) // Hit them with the weapon. This won't cause recursive cleaving due to the cleaving variable being set to true.
hit_mobs++
+ cleave_visual(user, target)
+
if(hit_mobs)
to_chat(user, "You used \the [src] to attack [hit_mobs] other thing\s!")
- cleaving = FALSE // We're done now.
\ No newline at end of file
+ cleaving = FALSE // We're done now.
+
+// This is purely the visual effect of cleaving.
+/obj/item/weapon/proc/cleave_visual(var/mob/living/user, var/mob/living/target)
+ var/obj/effect/temporary_effect/cleave_attack/E = new(get_turf(src))
+ E.dir = get_dir(user, target)
\ No newline at end of file
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index 5580e9a5da7..841c17d3f51 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ