Merge pull request #13890 from silicons/parry

ablative parry armwraps
This commit is contained in:
Lin
2021-02-05 23:52:18 -06:00
committed by GitHub
7 changed files with 108 additions and 6 deletions

View File

@@ -290,7 +290,7 @@
#define COMSIG_LIVING_ACTIVE_BLOCK_START "active_block_start" //from base of mob/living/keybind_start_active_blocking(): (obj/item/blocking_item, list/backup_items)
#define COMPONENT_PREVENT_BLOCK_START 1
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items)
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
#define COMPONENT_PREVENT_PARRY_START 1
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!

View File

@@ -161,6 +161,68 @@
return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION
/obj/item/clothing/gloves/fingerless/ablative
name = "ablative armwraps"
desc = "Armwraps made out of a highly durable, reflective metal. Has the side effect of absorbing shocks."
siemens_coefficient = 0
icon_state = "ablative_armwraps"
item_state = "ablative_armwraps"
block_parry_data = /datum/block_parry_data/ablative_armwraps
var/wornonce = FALSE
/obj/item/clothing/gloves/fingerless/ablative/proc/get_component_parry_data(datum/source, parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
if(parrying_method && !(parrying_method == UNARMED_PARRY))
return
override[src] = ITEM_PARRY
/obj/item/clothing/gloves/fingerless/ablative/equipped(mob/user, slot)
. = ..()
if(current_equipped_slot == SLOT_GLOVES)
RegisterSignal(user, COMSIG_LIVING_ACTIVE_PARRY_START, .proc/get_component_parry_data)
wornonce = TRUE
/obj/item/clothing/gloves/fingerless/ablative/dropped(mob/user)
. = ..()
if(wornonce)
UnregisterSignal(user, COMSIG_LIVING_ACTIVE_PARRY_START)
wornonce = FALSE
/obj/item/clothing/gloves/fingerless/ablative/can_active_parry(mob/user)
var/mob/living/carbon/human/H = user
if(!istype(H))
return FALSE
return src == H.gloves
/obj/item/clothing/gloves/fingerless/ablative/on_active_parry(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/block_return, parry_efficiency, parry_time)
. = ..()
if(parry_efficiency > 0)
owner.visible_message("<span class='warning'>[owner] deflects \the [object] with their armwraps!</span>")
/datum/block_parry_data/ablative_armwraps
parry_stamina_cost = 4
parry_attack_types = ATTACK_TYPE_UNARMED | ATTACK_TYPE_PROJECTILE | ATTACK_TYPE_TACKLE | ATTACK_TYPE_THROWN | ATTACK_TYPE_MELEE
parry_flags = NONE
parry_time_windup = 0
parry_time_spindown = 0
parry_time_active = 7.5
parry_time_perfect = 1
parry_time_perfect_leeway = 7.5
parry_imperfect_falloff_percent = 20
parry_efficiency_perfect = 100
parry_time_perfect_leeway_override = list(
TEXT_ATTACK_TYPE_MELEE = 1
)
parry_efficiency_considered_successful = 0.01
parry_efficiency_to_counterattack = INFINITY // no auto counter
parry_max_attacks = INFINITY
parry_failed_cooldown_duration = 2.25 SECONDS
parry_failed_stagger_duration = 2.25 SECONDS
parry_cooldown = 0
parry_failed_clickcd_duration = 0
/obj/item/clothing/gloves/botanic_leather
name = "botanist's leather gloves"
desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin. They're also quite warm."

View File

@@ -2,7 +2,7 @@
/**
* Determines if we can actively parry.
*/
/obj/item/proc/can_active_parry()
/obj/item/proc/can_active_parry(mob/user)
return block_parry_data && (item_flags & ITEM_CAN_PARRY)
/**
@@ -29,7 +29,7 @@
var/datum/block_parry_data/data
var/datum/tool
var/method
if(using_item?.can_active_parry())
if(using_item?.can_active_parry(src))
data = using_item.block_parry_data
method = ITEM_PARRY
tool = using_item
@@ -50,9 +50,20 @@
using_item = backup
method = ITEM_PARRY
var/list/other_items = list()
if(SEND_SIGNAL(src, COMSIG_LIVING_ACTIVE_PARRY_START, method, tool, other_items) & COMPONENT_PREVENT_PARRY_START)
var/list/override = list()
if(SEND_SIGNAL(src, COMSIG_LIVING_ACTIVE_PARRY_START, method, tool, other_items, override) & COMPONENT_PREVENT_PARRY_START)
to_chat(src, "<span class='warning'>Something is preventing you from parrying!</span>")
return
if(length(override))
var/datum/thing = override[1]
var/_method = override[thing]
if(_method == ITEM_PARRY)
using_item = thing
method = ITEM_PARRY
data = using_item.block_parry_data
else if(_method == UNARMED_PARRY)
method = UNARMED_PARRY
data = thing
if(!using_item && !method && length(other_items))
using_item = other_items[1]
method = ITEM_PARRY
@@ -94,7 +105,7 @@
*/
/mob/living/proc/find_backup_parry_item()
for(var/obj/item/I in held_items - get_active_held_item())
if(I.can_active_parry())
if(I.can_active_parry(src))
return I
/**
@@ -231,7 +242,7 @@
var/efficiency = data.get_parry_efficiency(attack_type, get_parry_time())
switch(parrying)
if(ITEM_PARRY)
if(!active_parry_item.can_active_parry())
if(!active_parry_item.can_active_parry(src))
return BLOCK_NONE
. = active_parry_item.on_active_parry(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list, efficiency, get_parry_time())
if(UNARMED_PARRY)
@@ -243,6 +254,18 @@
if(efficiency <= 0) // Do not allow automatically handled/standardized parries that increase damage for now.
return
. |= BLOCK_SHOULD_PARTIAL_MITIGATE
if(efficiency >= data.parry_efficiency_perfect)
. |= data.perfect_parry_block_return_flags
if(data.perfect_parry_block_return_list)
return_list |= data.perfect_parry_block_return_list
else if(efficiency >= data.parry_efficiency_considered_successful)
. |= data.imperfect_parry_block_return_flags
if(data.imperfect_parry_block_return_list)
return_list |= data.imperfect_parry_block_return_list
else
. |= data.failed_parry_block_return_flags
if(data.failed_parry_block_return_list)
return_list |= data.failed_parry_block_return_list
if(isnull(return_list[BLOCK_RETURN_MITIGATION_PERCENT])) // if one of the on_active_parry procs overrode. We don't have to worry about interference since parries are the first thing checked in the [do_run_block()] sequence.
return_list[BLOCK_RETURN_MITIGATION_PERCENT] = clamp(efficiency, 0, 100) // do not allow > 100% or < 0% for now.
if((return_list[BLOCK_RETURN_MITIGATION_PERCENT] >= 100) || (damage <= 0))

View File

@@ -157,6 +157,16 @@ GLOBAL_LIST_EMPTY(block_parry_data)
/// Parry cooldown post-parry if failed. This is ADDED to parry_cooldown!!!
var/parry_failed_cooldown_duration = 0 SECONDS
// Advanced
/// Flags added to return value
var/perfect_parry_block_return_flags = NONE
var/imperfect_parry_block_return_flags = NONE
var/failed_parry_block_return_flags = NONE
/// List appended to block return
var/perfect_parry_block_return_list
var/imperfect_parry_block_return_list
var/failed_parry_block_return_list
/**
* Quirky proc to get average of flags in list that are in attack_type because why is attack_type a flag.
*/

View File

@@ -104,3 +104,10 @@
desc = "An eyepatch that connects itself to your eye socket, enhancing your shooting to an impossible degree, allowing your bullets to ricochet far more often than usual."
item = /obj/item/clothing/glasses/eyepatch/syndicate
cost = 8
/datum/uplink_item/device_tools/ablative_armwraps
name = "Ablative Armwraps"
desc = "A pair of highly reinforced armwraps allowing the user to parry almost anything. Fully reflects projectiles, no downsides to failing, but is very hard to parry melee with."
cost = 6
item = /obj/item/clothing/gloves/fingerless/ablative
exclude_modes = list(/datum/game_mode/nuclear)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB