Skip to content

Commit

Permalink
Directional blocking (#1105)
Browse files Browse the repository at this point in the history
* adds directional blocking

* fix

* unused vars
  • Loading branch information
Kapu1178 authored Oct 28, 2024
1 parent 0ffd79d commit edd6fcc
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 42 deletions.
2 changes: 0 additions & 2 deletions code/__HELPERS/type2type.dm → code/__HELPERS/_type2type.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@
return SOUTHEAST
if("SOUTHWEST")
return SOUTHWEST
else
return

//Converts an angle (degrees) into a ss13 direction
GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,SOUTHWEST,WEST,NORTHWEST))
Expand Down
26 changes: 26 additions & 0 deletions code/__HELPERS/combat_helpers.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// Returns an angle between 0 and 180, where 0 is the attacker is directly infront of the defender, 180 for directly behind.
/proc/get_relative_attack_angle(mob/living/carbon/human/defender, atom/movable/hitby)
var/attack_dir = defender.dir // Default to the defender's dir so that the attack angle is 0 by default
var/turf/defender_turf = get_turf(defender)

if(isprojectile(hitby))
var/obj/projectile/P = hitby
if(P.starting != defender_turf)
attack_dir = REVERSE_DIR(angle2dir(P.Angle))

else if(isitem(hitby))
if(ismob(hitby.loc))
attack_dir = get_dir(defender, hitby.loc)
else
attack_dir = get_dir(defender, hitby)

else
attack_dir = get_dir(defender, hitby)

var/attack_angle = dir2angle(attack_dir) || 0 // If attack_dir == 0, dir2angle returns null
var/facing_angle = dir2angle(defender.dir) || 0
var/delta = abs(attack_angle - facing_angle)
if(delta > 180)
delta = 360 - delta

return delta
8 changes: 4 additions & 4 deletions code/datums/martial/sleeping_carp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@
else
return ..()

/obj/item/staff/bostaff/get_block_chance(atom/movable/hitby, damage, attack_type, armor_penetration)
if(wielded)
return ..()
return FALSE
/obj/item/staff/bostaff/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(!wielded)
return FALSE
return ..()
14 changes: 13 additions & 1 deletion code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ DEFINE_INTERACTABLE(/obj/item)

/// The baseline chance to block **ANY** attack, projectiles included
var/block_chance = 0
/// The angle infront of the defender that is a valid block range.
var/block_angle = 45 // Infront and infront + sides, but not direct sides

/// The type of effect to create on a successful block
var/obj/effect/temp_visual/block_effect = /obj/effect/temp_visual/block

Expand Down Expand Up @@ -703,7 +706,8 @@ DEFINE_INTERACTABLE(/obj/item)
var/sig_return = SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK)
var/block_result = sig_return & COMPONENT_CHECK_BLOCK_BLOCKED

block_result ||= prob(get_block_chance(wielder, hitby, damage, attack_type, armor_penetration))
if(!block_result && can_block_attack(wielder, hitby, attack_type))
block_result = prob(get_block_chance(wielder, hitby, damage, attack_type, armor_penetration))

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

return block_result

/// Checks if this item can block an incoming attack.
/obj/item/proc/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
var/angle = get_relative_attack_angle(wielder, hitby)
if(angle <= block_angle)
return TRUE

return FALSE

/// Returns a number to feed into prob() to determine if the attack was blocked.
/obj/item/proc/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
var/block_chance_modifier = round(damage / -3)
Expand Down
8 changes: 4 additions & 4 deletions code/game/objects/items/dualsaber.dm
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@
else
user.stamina.adjust(-25)

/obj/item/dualsaber/get_block_chance(atom/movable/hitby, damage, attack_type, armor_penetration)
if(wielded)
return ..()
return FALSE
/obj/item/dualsaber/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(!wielded)
return FALSE
return ..()

/obj/item/dualsaber/process()
if(!wielded)
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/grenades/_grenade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,10 @@
/obj/item/grenade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
var/obj/projectile/hit_projectile = hitby
if(!istype(hitby))
return FALSE
return 0

if(damage && attack_type == PROJECTILE_ATTACK && hit_projectile.damage_type != STAMINA && prob(15))
return TRUE
return 100

/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)
. = ..()
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/holy_weapons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@
attack_verb_simple = list("attack", "slash", "stab", "slice", "tear", "lacerate", "rip", "dice", "cut")
menu_description = "A sharp claymore which provides a low chance of blocking incoming melee attacks. Can be worn on the back or belt."

/obj/item/nullrod/claymore/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
/obj/item/nullrod/claymore/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(attack_type == PROJECTILE_ATTACK)
return FALSE
return ..()
Expand Down
10 changes: 5 additions & 5 deletions code/game/objects/items/melee/energy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,10 @@
block_chance = 50
embedding = list("embed_chance" = 75, "impact_pain_mult" = 10)

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

/obj/item/melee/energy/sword/cyborg
name = "cyborg energy sword"
Expand Down Expand Up @@ -223,7 +223,7 @@
active_force = 30
sword_color_icon = null // Stops icon from breaking when turned on.

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

// The colored energy swords we all know and love.
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/melee/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@
. = ..()
AddComponent(/datum/component/butchering, 30, 95, 5) //fast and effective, but as a sword, it might damage the results.

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

/obj/item/melee/sabre/on_exit_storage(datum/storage/container)
Expand Down
13 changes: 8 additions & 5 deletions code/game/objects/items/shields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@
max_integrity = 75


/obj/item/shield/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
/obj/item/shield/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(transparent && (hitby.pass_flags & PASSGLASS))
return FALSE
return ..()

/obj/item/shield/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
. = ..()
if(attack_type == THROWN_PROJECTILE_ATTACK)
. += 30
Expand Down Expand Up @@ -269,10 +272,10 @@
attack_verb_simple_on = list("smack", "strike", "crack", "beat"))
RegisterSignal(src, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))

/obj/item/shield/riot/tele/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
if(extended)
return ..()
return FALSE
/obj/item/shield/riot/tele/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(!extended)
return FALSE
return ..()

/*
* Signal proc for [COMSIG_TRANSFORMING_ON_TRANSFORM].
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/toys.dm
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@
attack_verb_continuous = list("attacks", "strikes", "hits")
attack_verb_simple = list("attack", "strike", "hit")

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

/obj/item/dualsaber/toy/IsReflect() //Stops Toy Dualsabers from reflecting energy projectiles
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/weaponry.dm
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301

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

. = ..()

Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/beds_chairs/chair.dm
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
/obj/item/chair/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
. = ..()
if(prob(50) && ((attack_type == UNARMED_ATTACK) || (attack_type == LEAP_ATTACK)))
return TRUE
return 100

/obj/item/chair/block_feedback(mob/living/carbon/human/wielder, attack_text, attack_type, do_message = TRUE, do_sound = TRUE)
if(do_message)
Expand Down
15 changes: 7 additions & 8 deletions code/modules/antagonists/cult/cult_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ Striking a noncultist, however, will tear their flesh."}

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

/obj/item/melee/cultblade/dagger/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
if(IS_CULTIST(wielder) && attack_type != PROJECTILE_ATTACK)
return ..()

return FALSE
/obj/item/melee/cultblade/dagger/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(attack_type == PROJECTILE_ATTACK)
return FALSE
return ..()

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

/obj/item/melee/cultblade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
/obj/item/melee/cultblade/can_block_attack(mob/living/carbon/human/wielder, atom/movable/hitby, attack_type)
if(IS_CULTIST(wielder))
return ..()

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

/datum/action/innate/cult/spin2win/proc/stop_spinning()
sword.spinning = FALSE
sword.block_chance = 50
sword.block_angle = 45
sword.slowdown -= 1.5
sleep(sword.spin_cooldown)
holder?.update_mob_action_buttons()
Expand Down Expand Up @@ -775,8 +776,6 @@ Striking a noncultist, however, will tear their flesh."}
qdel(src)

/obj/item/melee/cultblade/halberd/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
if(!IS_CULTIST(wielder))
return FALSE
. = ..()
if(wielded)
. *= 2
Expand Down
2 changes: 1 addition & 1 deletion code/modules/clothing/suits/reactive_armour.dm
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
update_icon()
add_fingerprint(user)

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

Expand Down
2 changes: 1 addition & 1 deletion code/modules/projectiles/guns/magic/staff.dm
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
. = ..()
AddComponent(/datum/component/butchering, 15, 125, 0, hitsound)

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

Expand Down
6 changes: 4 additions & 2 deletions code/modules/religion/sparring/ceremonial_gear.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
force = old_force
throwforce = old_throwforce

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

/obj/item/ceremonial_blade/get_block_chance(mob/living/carbon/human/wielder, atom/movable/hitby, damage, attack_type, armor_penetration)
. = ..()
if(HAS_TRAIT(hitby.loc, TRAIT_SPARRING))
//becomes 30 block
Expand Down
3 changes: 2 additions & 1 deletion daedalus.dme
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@
#include "code\__HELPERS\_lists.dm"
#include "code\__HELPERS\_logging.dm"
#include "code\__HELPERS\_string_lists.dm"
#include "code\__HELPERS\_type2type.dm"
#include "code\__HELPERS\admin.dm"
#include "code\__HELPERS\ai.dm"
#include "code\__HELPERS\areas.dm"
Expand All @@ -355,6 +356,7 @@
#include "code\__HELPERS\clients.dm"
#include "code\__HELPERS\cmp.dm"
#include "code\__HELPERS\colors.dm"
#include "code\__HELPERS\combat_helpers.dm"
#include "code\__HELPERS\config.dm"
#include "code\__HELPERS\construction.dm"
#include "code\__HELPERS\dates.dm"
Expand Down Expand Up @@ -408,7 +410,6 @@
#include "code\__HELPERS\time.dm"
#include "code\__HELPERS\traits.dm"
#include "code\__HELPERS\turfs.dm"
#include "code\__HELPERS\type2type.dm"
#include "code\__HELPERS\type_processing.dm"
#include "code\__HELPERS\typelists.dm"
#include "code\__HELPERS\varset_callback.dm"
Expand Down

0 comments on commit edd6fcc

Please sign in to comment.