Skip to content

Commit b689005

Browse files
authored
adds directional blocking (#1103)
* adds directional blocking * fix
1 parent 4a8d5cb commit b689005

File tree

18 files changed

+84
-42
lines changed

18 files changed

+84
-42
lines changed

code/__HELPERS/type2type.dm code/__HELPERS/_type2type.dm

-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@
6262
return SOUTHEAST
6363
if("SOUTHWEST")
6464
return SOUTHWEST
65-
else
66-
return
6765

6866
//Converts an angle (degrees) into a ss13 direction
6967
GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST,WEST,NORTHWEST))

code/__HELPERS/combat_helpers.dm

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/// Returns an angle between 0 and 180, where 0 is the attacker is directly infront of the defender, 180 for directly behind.
2+
/proc/get_relative_attack_angle(mob/living/carbon/human/defender, atom/movable/hitby)
3+
var/attack_dir = defender.dir // Default to the defender's dir so that the attack angle is 0 by default
4+
var/turf/defender_turf = get_turf(defender)
5+
6+
if(isprojectile(hitby))
7+
var/obj/projectile/P = hitby
8+
if(P.starting != get_turf(defender))
9+
attack_dir = REVERSE_DIR(angle2dir(P.Angle))
10+
11+
else if(isitem(hitby))
12+
var/obj/item/weapon = hitby
13+
if(ismob(hitby.loc))
14+
attack_dir = get_dir(defender, hitby.loc)
15+
else
16+
attack_dir = get_dir(defender, hitby)
17+
18+
else
19+
attack_dir = get_dir(defender, hitby)
20+
21+
var/attack_angle = dir2angle(attack_dir) || 0 // If attack_dir == 0, dir2angle returns null
22+
var/facing_angle = dir2angle(defender.dir) || 0
23+
var/delta = abs(attack_angle - facing_angle)
24+
if(delta > 180)
25+
delta = 360 - delta
26+
27+
return delta

code/datums/martial/sleeping_carp.dm

+4-4
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
else
230230
return ..()
231231

232-
/obj/item/staff/bostaff/get_block_chance(atom/movable/hitby, damage, attack_type, armor_penetration)
233-
if(wielded)
234-
return ..()
235-
return FALSE
232+
/obj/item/staff/bostaff/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
233+
if(!wielded)
234+
return FALSE
235+
return ..()

code/game/objects/items.dm

+13-1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ DEFINE_INTERACTABLE(/obj/item)
239239

240240
/// The baseline chance to block **ANY** attack, projectiles included
241241
var/block_chance = 0
242+
/// The angle infront of the defender that is a valid block range.
243+
var/block_angle = 45 // Infront and infront + sides, but not direct sides
244+
242245
/// The type of effect to create on a successful block
243246
var/obj/effect/temp_visual/block_effect = /obj/effect/temp_visual/block
244247

@@ -703,7 +706,8 @@ DEFINE_INTERACTABLE(/obj/item)
703706
var/sig_return = SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK)
704707
var/block_result = sig_return & COMPONENT_CHECK_BLOCK_BLOCKED
705708

706-
block_result ||= prob(get_block_chance(wielder, hitby, damage, attack_type, armor_penetration))
709+
if(!block_result && can_block_attack(wielder, hitby, attack_type))
710+
block_result = prob(get_block_chance(wielder, hitby, damage, attack_type, armor_penetration))
707711

708712
var/list/reaction_args = args.Copy()
709713
if(block_result)
@@ -720,6 +724,14 @@ DEFINE_INTERACTABLE(/obj/item)
720724

721725
return block_result
722726

727+
/// Checks if this item can block an incoming attack.
728+
/obj/item/proc/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
729+
var/angle = get_relative_attack_angle(wielder, hitby)
730+
if(angle <= block_angle)
731+
return TRUE
732+
733+
return FALSE
734+
723735
/// Returns a number to feed into prob() to determine if the attack was blocked.
724736
/obj/item/proc/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
725737
var/block_chance_modifier = round(damage / -3)

code/game/objects/items/dualsaber.dm

+4-4
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@
138138
else
139139
user.stamina.adjust(-25)
140140

141-
/obj/item/dualsaber/get_block_chance(atom/movable/hitby, damage, attack_type, armor_penetration)
142-
if(wielded)
143-
return ..()
144-
return FALSE
141+
/obj/item/dualsaber/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
142+
if(!wielded)
143+
return FALSE
144+
return ..()
145145

146146
/obj/item/dualsaber/process()
147147
if(!wielded)

code/game/objects/items/grenades/_grenade.dm

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,10 @@
214214
/obj/item/grenade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
215215
var/obj/projectile/hit_projectile = hitby
216216
if(!istype(hitby))
217-
return FALSE
217+
return 0
218218

219219
if(damage && attack_type == PROJECTILE_ATTACK && hit_projectile.damage_type != STAMINA && prob(15))
220-
return TRUE
220+
return 100
221221

222222
/obj/item/grenade/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", damage = 0, attack_type = MELEE_ATTACK, block_success = TRUE)
223223
. = ..()

code/game/objects/items/holy_weapons.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@
248248
attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
249249
menu_description = "A sharp claymore which provides a low chance of blocking incoming melee attacks. Can be worn on the back or belt."
250250

251-
/obj/item/nullrod/claymore/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
251+
/obj/item/nullrod/claymore/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
252252
if(attack_type == PROJECTILE_ATTACK)
253253
return FALSE
254254
return ..()

code/game/objects/items/melee/energy.dm

+5-5
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@
179179
block_chance = 50
180180
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)
181181

182-
/obj/item/melee/energy/sword/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
183-
if(blade_active)
184-
return ..()
185-
return FALSE
182+
/obj/item/melee/energy/sword/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
183+
if(!blade_active)
184+
return FALSE
185+
return ..()
186186

187187
/obj/item/melee/energy/sword/cyborg
188188
name = "cyborg energy sword"
@@ -223,7 +223,7 @@
223223
active_force = 30
224224
sword_color_icon = null // Stops icon from breaking when turned on.
225225

226-
/obj/item/melee/energy/sword/cyborg/saw/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
226+
/obj/item/melee/energy/sword/cyborg/saw/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
227227
return FALSE
228228

229229
// The colored energy swords we all know and love.

code/game/objects/items/melee/misc.dm

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@
7676
. = ..()
7777
AddComponent(/datum/component/butchering, 30, 95, 5) //fast and effective, but as a sword, it might damage the results.
7878

79-
/obj/item/melee/sabre/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
79+
/obj/item/melee/sabre/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
8080
if(attack_type == PROJECTILE_ATTACK)
81-
return FALSE //Don't bring a sword to a gunfight
81+
return FALSE
8282
return ..()
8383

8484
/obj/item/melee/sabre/on_exit_storage(datum/storage/container)

code/game/objects/items/shields.dm

+8-5
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
max_integrity = 75
2929

3030

31-
/obj/item/shield/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
31+
/obj/item/shield/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
3232
if(transparent && (hitby.pass_flags & PASSGLASS))
3333
return FALSE
34+
return ..()
35+
36+
/obj/item/shield/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
3437
. = ..()
3538
if(attack_type == THROWN_PROJECTILE_ATTACK)
3639
. += 30
@@ -269,10 +272,10 @@
269272
attack_verb_simple_on = list("smack", "strike", "crack", "beat"))
270273
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
271274

272-
/obj/item/shield/riot/tele/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
273-
if(extended)
274-
return ..()
275-
return FALSE
275+
/obj/item/shield/riot/tele/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
276+
if(!extended)
277+
return FALSE
278+
return ..()
276279

277280
/*
278281
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].

code/game/objects/items/toys.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@
520520
attack_verb_continuous = list("attacks", "strikes", "hits")
521521
attack_verb_simple = list("attack", "strike", "hit")
522522

523-
/obj/item/dualsaber/toy/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
523+
/obj/item/dualsaber/toy/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
524524
return FALSE
525525

526526
/obj/item/dualsaber/toy/IsReflect() //Stops Toy Dualsabers from reflecting energy projectiles

code/game/objects/items/weaponry.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
780780

781781
/obj/item/highfrequencyblade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
782782
if((attack_type == PROJECTILE_ATTACK) && wielded)
783-
return TRUE
783+
return 100
784784

785785
. = ..()
786786

code/game/objects/structures/beds_chairs/chair.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
368368
/obj/item/chair/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
369369
. = ..()
370370
if(prob(50) && ((attack_type == UNARMED_ATTACK) || (attack_type == LEAP_ATTACK)))
371-
return TRUE
371+
return 100
372372

373373
/obj/item/chair/block_feedback(mob/living/carbon/human/wielder, attack_text, attack_type, do_message = TRUE, do_sound = TRUE)
374374
if(do_message)

code/modules/antagonists/cult/cult_items.dm

+7-8
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ Striking a noncultist, however, will tear their flesh."}
3737

3838
AddComponent(/datum/component/cult_ritual_item, span_cult(examine_text))
3939

40-
/obj/item/melee/cultblade/dagger/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
41-
if(IS_CULTIST(wielder) && attack_type != PROJECTILE_ATTACK)
42-
return ..()
43-
44-
return FALSE
40+
/obj/item/melee/cultblade/dagger/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
41+
if(attack_type == PROJECTILE_ATTACK)
42+
return FALSE
43+
return ..()
4544

4645
/obj/item/melee/cultblade/dagger/block_feedback(mob/living/carbon/human/wielder, attack_text, attack_type, do_message = TRUE, do_sound = TRUE)
4746
if(do_message)
@@ -78,7 +77,7 @@ Striking a noncultist, however, will tear their flesh."}
7877
. = ..()
7978
AddComponent(/datum/component/butchering, 40, 100)
8079

81-
/obj/item/melee/cultblade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
80+
/obj/item/melee/cultblade/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
8281
if(IS_CULTIST(wielder))
8382
return ..()
8483

@@ -278,13 +277,15 @@ Striking a noncultist, however, will tear their flesh."}
278277
holder.apply_status_effect(/datum/status_effect/sword_spin)
279278
sword.spinning = TRUE
280279
sword.block_chance = 100
280+
sword.block_angle = 180
281281
sword.slowdown += 1.5
282282
addtimer(CALLBACK(src, PROC_REF(stop_spinning)), 50)
283283
holder?.update_mob_action_buttons()
284284

285285
/datum/action/innate/cult/spin2win/proc/stop_spinning()
286286
sword.spinning = FALSE
287287
sword.block_chance = 50
288+
sword.block_angle = 45
288289
sword.slowdown -= 1.5
289290
sleep(sword.spin_cooldown)
290291
holder?.update_mob_action_buttons()
@@ -775,8 +776,6 @@ Striking a noncultist, however, will tear their flesh."}
775776
qdel(src)
776777

777778
/obj/item/melee/cultblade/halberd/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
778-
if(!IS_CULTIST(wielder))
779-
return FALSE
780779
. = ..()
781780
if(wielded)
782781
. *= 2

code/modules/clothing/suits/reactive_armour.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
update_icon()
6868
add_fingerprint(user)
6969

70-
/obj/item/clothing/suit/armor/reactive/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
70+
/obj/item/clothing/suit/armor/reactive/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
7171
if(!active)
7272
return FALSE
7373

code/modules/projectiles/guns/magic/staff.dm

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
. = ..()
183183
AddComponent(/datum/component/butchering, 15, 125, 0, hitsound)
184184

185-
/obj/item/gun/magic/staff/spellblade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
185+
/obj/item/gun/magic/staff/spellblade/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
186186
if(attack_type == PROJECTILE_ATTACK)
187187
return FALSE
188188

code/modules/religion/sparring/ceremonial_gear.dm

+4-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@
4242
force = old_force
4343
throwforce = old_throwforce
4444

45-
/obj/item/ceremonial_blade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
45+
/obj/item/ceremonial_blade/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
4646
if(attack_type != MELEE_ATTACK || !ishuman(hitby.loc))
47-
return ..()
47+
return FALSE
48+
return ..()
4849

50+
/obj/item/ceremonial_blade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
4951
. = ..()
5052
if(HAS_TRAIT(hitby.loc, TRAIT_SPARRING))
5153
//becomes 30 block

daedalus.dme

+2-1
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@
342342
#include "code\__HELPERS\_lists.dm"
343343
#include "code\__HELPERS\_logging.dm"
344344
#include "code\__HELPERS\_string_lists.dm"
345+
#include "code\__HELPERS\_type2type.dm"
345346
#include "code\__HELPERS\admin.dm"
346347
#include "code\__HELPERS\ai.dm"
347348
#include "code\__HELPERS\areas.dm"
@@ -355,6 +356,7 @@
355356
#include "code\__HELPERS\clients.dm"
356357
#include "code\__HELPERS\cmp.dm"
357358
#include "code\__HELPERS\colors.dm"
359+
#include "code\__HELPERS\combat_helpers.dm"
358360
#include "code\__HELPERS\config.dm"
359361
#include "code\__HELPERS\construction.dm"
360362
#include "code\__HELPERS\dates.dm"
@@ -408,7 +410,6 @@
408410
#include "code\__HELPERS\time.dm"
409411
#include "code\__HELPERS\traits.dm"
410412
#include "code\__HELPERS\turfs.dm"
411-
#include "code\__HELPERS\type2type.dm"
412413
#include "code\__HELPERS\type_processing.dm"
413414
#include "code\__HELPERS\typelists.dm"
414415
#include "code\__HELPERS\varset_callback.dm"

0 commit comments

Comments
 (0)