diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index f2528f57862..94bc9e8f692 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -99,15 +99,9 @@ icon_state = "machete" force_divisor = 0.3 // 18 when hardness 60 (steel) attack_verb = list("slashed", "chopped", "gouged", "ripped", "cut") - var/should_cleave = TRUE //Now hatchets inherit from the machete, and thus knives. Tables turned. + can_cleave = TRUE //Now hatchets inherit from the machete, and thus knives. Tables turned. slot_flags = SLOT_BELT -// This cannot go into afterattack since some mobs delete themselves upon dying. -/obj/item/weapon/material/knife/machete/pre_attack(var/mob/living/target, var/mob/living/user) - if(should_cleave && istype(target)) - cleave(user, target) - ..() - /obj/item/weapon/material/knife/tacknife/survival name = "survival knife" desc = "A hunting grade survival knife." diff --git a/code/game/objects/items/weapons/material/misc.dm b/code/game/objects/items/weapons/material/misc.dm index 87bfb0454d3..bbb8171b10b 100644 --- a/code/game/objects/items/weapons/material/misc.dm +++ b/code/game/objects/items/weapons/material/misc.dm @@ -28,7 +28,7 @@ icon = 'icons/obj/weapons.dmi' icon_state = "unathiknife" attack_verb = list("ripped", "torn", "cut") - should_cleave = FALSE + can_cleave = FALSE var hits = 0 /obj/item/weapon/material/knife/machete/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob) diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm index 6631ec25fa9..acc3132712b 100644 --- a/code/game/objects/items/weapons/material/twohanded.dm +++ b/code/game/objects/items/weapons/material/twohanded.dm @@ -94,6 +94,7 @@ force_wielded = 30 attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") applies_material_colour = 0 + can_cleave = TRUE /obj/item/weapon/material/twohanded/fireaxe/update_held_icon() var/mob/living/M = loc @@ -124,12 +125,6 @@ var/obj/effect/plant/P = A P.die_off() -// This cannot go into afterattack since some mobs delete themselves upon dying. -/obj/item/weapon/material/twohanded/fireaxe/pre_attack(var/mob/living/target, var/mob/living/user) - if(istype(target)) - cleave(user, target) - ..() - /obj/item/weapon/material/twohanded/fireaxe/scythe icon_state = "scythe0" base_icon = "scythe" diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index f7497ec3ff4..ad30eb0a57f 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -87,6 +87,7 @@ attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut") sharp = 1 edge = 1 + can_cleave = TRUE /obj/item/weapon/melee/energy/axe/activate(mob/living/user) ..() @@ -98,12 +99,6 @@ 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) var/datum/gender/TU = gender_datums[user.get_visible_gender()] visible_message("\The [user] swings \the [src] towards [TU.his] head! It looks like [TU.he] [TU.is] trying to commit suicide.") diff --git a/code/game/objects/weapons.dm b/code/game/objects/weapons.dm index 7a619477eaf..c9a4babd9ef 100644 --- a/code/game/objects/weapons.dm +++ b/code/game/objects/weapons.dm @@ -2,6 +2,7 @@ name = "weapon" icon = 'icons/obj/weapons.dmi' hitsound = "swing_hit" + var/can_cleave = FALSE // If true, a 'cleaving' attack will occur. var/cleaving = FALSE // Used to avoid infinite cleaving. /obj/item/weapon/Bump(mob/M as mob) @@ -16,14 +17,17 @@ ) // Attacks mobs (atm only simple ones due to friendly fire issues) that are adjacent to the target and user. -/obj/item/weapon/proc/cleave(var/mob/living/user, var/mob/living/target) +/obj/item/weapon/proc/cleave(mob/living/user, atom/target) if(cleaving) - return // We're busy. + return FALSE // We're busy. + if(!target.Adjacent(user)) + return FALSE // Too far. if(get_turf(user) == get_turf(target)) - return // Otherwise we would hit all eight surrounding tiles. + return FALSE // 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)) + for(var/mob/living/simple_animal/SA in range(get_turf(target), 1)) if(SA.stat == DEAD) // Don't beat a dead horse. continue if(SA == user) // Don't hit ourselves. Simple mobs shouldn't be able to do this but that might change later to be able to hit all mob/living-s. @@ -42,6 +46,13 @@ if(hit_mobs) to_chat(user, "You used \the [src] to attack [hit_mobs] other thing\s!") cleaving = FALSE // We're done now. + return hit_mobs > 0 // Returns TRUE if anything got hit. + +// This cannot go into afterattack since some mobs delete themselves upon dying. +/obj/item/weapon/material/pre_attack(mob/living/target, mob/living/user) + if(can_cleave && istype(target)) + cleave(user, target) + ..() // This is purely the visual effect of cleaving. /obj/item/weapon/proc/cleave_visual(var/mob/living/user, var/mob/living/target) diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index 5602eac320d..91371e7beb5 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -3,6 +3,12 @@ if(!C || !user) return 0 + if(isliving(user) && istype(C, /obj/item/weapon)) + var/mob/living/L = user + if(L.a_intent != I_HELP) + attack_tile(C, L) // Be on help intent if you want to decon something. + return + if(flooring) if(istype(C, /obj/item/weapon)) try_deconstruct_tile(C, user) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 100c3b5a31c..58da7d11291 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -86,6 +86,34 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob) S.gather_all(src, user) return ..() +// Hits a mob on the tile. +/turf/proc/attack_tile(obj/item/weapon/W, mob/living/user) + if(!istype(W)) + return FALSE + + var/list/viable_targets = list() + var/success = FALSE // Hitting something makes this true. If its still false, the miss sound is played. + + for(var/mob/living/L in contents) + if(L == user) // Don't hit ourselves. + continue + viable_targets += L + + if(!viable_targets.len) // No valid targets on this tile. + if(W.can_cleave) + success = W.cleave(user, src) + else + var/mob/living/victim = pick(viable_targets) + success = W.resolve_attackby(victim, user) + + user.setClickCooldown(user.get_attack_speed(W)) + user.do_attack_animation(src, no_attack_icons = TRUE) + + if(!success) // Nothing got hit. + user.visible_message("\The [user] swipes \the [W] over \the [src].") + playsound(src, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + return success + /turf/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob) var/turf/T = get_turf(user) var/area/A = T.loc diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index 7f082e1ef08..5fe2122b8c8 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -201,8 +201,11 @@ note dizziness decrements automatically in the mob's Life() proc. animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) -/mob/living/do_attack_animation(atom/A) +/mob/living/do_attack_animation(atom/A, no_attack_icons = FALSE) ..() + if(no_attack_icons) + return FALSE + //Check for clients with pref enabled var/list/viewing = list() for(var/m in viewers(A))