Adds Tile-based Attacks

Adds ability to attack mobs by clicking their tile.
When someone clicks a tile with a weapon while off help intent, and if a mob is occupying that tile, the mob will be attacked as if they were clicked directly.
If more than one mob is on a tile, one is chosen randomly.
You cannot hit yourself by clicking your own tile.
Weapons with cleaving abilities will attempt a cleave on the tile clicked on, making it very easy to hit (simple) mobs with those weapons if near you.

Other changes.
Cleave proc can accept any atom now and not just a mob.
Also cleans up weapons deciding how they can cleave somewhat.
This commit is contained in:
Neerti
2018-04-05 13:07:38 -04:00
parent cdf794950e
commit 4ac6d34235
8 changed files with 57 additions and 25 deletions

View File

@@ -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."

View File

@@ -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)

View File

@@ -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"

View File

@@ -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, "<span class='notice'>\The [src] is de-energised. It's just a regular axe now.</span>")
// 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("<span class='warning'>\The [user] swings \the [src] towards [TU.his] head! It looks like [TU.he] [TU.is] trying to commit suicide.</span>")

View File

@@ -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, "<span class='danger'>You used \the [src] to attack [hit_mobs] other thing\s!</span>")
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)

View File

@@ -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)

View File

@@ -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("<span class='warning'>\The [user] swipes \the [W] over \the [src].</span>")
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

View File

@@ -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))