diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 12a1b57364..aefa5d3cc8 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -24,12 +24,16 @@ var/shieldbash_push_distance = 1 /datum/block_parry_data/shield - block_stamina_efficiency = 1.5 - block_stamina_cost_per_second = 3 - block_start_delay = 3 - block_damage_absorption = 0 + block_damage_multiplier = 0.25 + block_stamina_efficiency = 2.5 + block_stamina_cost_per_second = 3.5 + block_slowdown = 0 + block_lock_attacking = FALSE + block_lock_sprinting = TRUE + block_start_delay = 1.5 + block_damage_absorption = 5 block_resting_stamina_penalty_multiplier = 2 - block_projectile_mitigation = 50 + block_projectile_mitigation = 75 /obj/item/shield/examine(mob/user) . = ..() diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 698adfd9d7..4437eefbf8 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -310,12 +310,14 @@ /datum/block_parry_data/dual_esword block_damage_absorption = 2 - block_damage_multiplier = 0.3 + block_damage_multiplier = 0.15 + block_damage_multiplier_override = list( + ATTACK_TYPE_MELEE = 0.25 + ) block_start_delay = 0 // instantaneous block - block_stamina_cost_per_second = 2 + block_stamina_cost_per_second = 2.5 block_stamina_efficiency = 3 - // slowdown - block_slowdown = 1 + block_lock_sprinting = TRUE // no attacking while blocking block_lock_attacking = TRUE block_projectile_mitigation = 75 diff --git a/code/modules/keybindings/keybind/mob.dm b/code/modules/keybindings/keybind/mob.dm index ca539e3ab7..2ce4dc35a0 100644 --- a/code/modules/keybindings/keybind/mob.dm +++ b/code/modules/keybindings/keybind/mob.dm @@ -17,6 +17,7 @@ return TRUE /datum/keybinding/mob/cycle_intent_right + hotkey_keys = list("Unbound") name = "cycle_intent_right" full_name = "Cycle Action Intent Right" description = "" @@ -27,6 +28,7 @@ return TRUE /datum/keybinding/mob/cycle_intent_left + hotkey_keys = list("Unbound") name = "cycle_intent_left" full_name = "Cycle Action Intent Left" description = "" diff --git a/code/modules/mob/living/living_active_block.dm b/code/modules/mob/living/living_active_block.dm index 64f9a8f6e7..4560b33bdb 100644 --- a/code/modules/mob/living/living_active_block.dm +++ b/code/modules/mob/living/living_active_block.dm @@ -7,6 +7,7 @@ active_block_effect_end() active_block_item = null REMOVE_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_BLOCK_TRAIT) + REMOVE_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT) remove_movespeed_modifier(/datum/movespeed_modifier/active_block) var/datum/block_parry_data/data = I.get_block_parry_data() if(timeToNextMove() < data.block_end_click_cd_add) @@ -25,6 +26,8 @@ active_block_item = I if(data.block_lock_attacking) ADD_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_BLOCK_TRAIT) //probably should be something else at some point + if(data.block_lock_sprinting) + ADD_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT) add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/active_block, multiplicative_slowdown = data.block_slowdown) active_block_effect_start() return TRUE @@ -75,10 +78,16 @@ /mob/living/proc/keybind_start_active_blocking() if(combat_flags & (COMBAT_FLAG_ACTIVE_BLOCK_STARTING | COMBAT_FLAG_ACTIVE_BLOCKING)) return FALSE + if(!(combat_flags & COMBAT_FLAG_BLOCK_CAPABLE)) + to_chat(src, "You're not something that can actively block.") + return FALSE + // QOL: Attempt to toggle on combat mode if it isn't already + SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE) if(!SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) to_chat(src, "You must be in combat mode to actively block!") return FALSE - var/obj/item/I = get_active_held_item() + // QOL: Instead of trying to just block with held item, grab first available item. + var/obj/item/I = find_active_block_item() if(!I) to_chat(src, "You can't block with your bare hands!") return @@ -89,7 +98,7 @@ var/delay = data.block_start_delay combat_flags |= COMBAT_FLAG_ACTIVE_BLOCK_STARTING animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = delay, FALSE, SINE_EASING | EASE_IN) - if(!do_after_advanced(src, delay, src, DO_AFTER_REQUIRES_USER_ON_TURF|DO_AFTER_NO_COEFFICIENT|DO_AFTER_DISALLOW_ACTIVE_ITEM_CHANGE, CALLBACK(src, .proc/continue_starting_active_block), MOBILITY_USE, null, null, I)) + if(!do_after_advanced(src, delay, src, DO_AFTER_REQUIRES_USER_ON_TURF|DO_AFTER_NO_COEFFICIENT, CALLBACK(src, .proc/continue_starting_active_block), MOBILITY_USE, null, null, I)) to_chat(src, "You fail to raise [I].") combat_flags &= ~(COMBAT_FLAG_ACTIVE_BLOCK_STARTING) animate(src, pixel_x = get_standard_pixel_x_offset(), pixel_y = get_standard_pixel_y_offset(), time = 2.5, FALSE, SINE_EASING | EASE_IN, ANIMATION_END_NOW) @@ -97,6 +106,18 @@ combat_flags &= ~(COMBAT_FLAG_ACTIVE_BLOCK_STARTING) start_active_blocking(I) +/** + * Gets the first item we can that can block, but if that fails, default to active held item.COMSIG_ENABLE_COMBAT_MODE + */ +/mob/living/proc/find_active_block_item() + var/obj/item/held = get_active_held_item() + if(!held.can_active_block()) + for(var/i in held_items - held) + var/obj/item/I = i + if(I.can_active_block()) + return I + return held + /** * Proc called by keybindings to stop active blocking. */ @@ -110,7 +131,7 @@ * Returns if we can actively block. */ /obj/item/proc/can_active_block() - return item_flags & ITEM_CAN_BLOCK + return block_parry_data && (item_flags & ITEM_CAN_BLOCK) /** * Calculates FINAL ATTACK DAMAGE after mitigation diff --git a/code/modules/mob/living/living_active_parry.dm b/code/modules/mob/living/living_active_parry.dm index f281399960..6ae83c5647 100644 --- a/code/modules/mob/living/living_active_parry.dm +++ b/code/modules/mob/living/living_active_parry.dm @@ -3,7 +3,7 @@ * Determines if we can actively parry. */ /obj/item/proc/can_active_parry() - return item_flags & ITEM_CAN_PARRY + return block_parry_data && (item_flags & ITEM_CAN_PARRY) /** * Called from keybindings. @@ -20,6 +20,8 @@ if(!(combat_flags & COMBAT_FLAG_PARRY_CAPABLE)) to_chat(src, "You are not something that can parry attacks.") return + //QOL: Try to enable combat mode if it isn't already + SEND_SIGNAL(src, COMSIG_ENABLE_COMBAT_MODE) if(!SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) to_chat(src, "You must be in combat mode to parry!") return FALSE @@ -38,8 +40,14 @@ data = block_parry_data method = UNARMED_PARRY else - to_chat(src, "You have nothing to parry with!") - return FALSE + // QOL: If none of the above work, try to find another item. + var/obj/item/backup = find_backup_parry_item() + if(!backup) + to_chat(src, "You have nothing to parry with!") + return FALSE + data = backup.block_parry_data + using_item = backup + method = ITEM_PARRY data = return_block_parry_datum(data) var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown // no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can. @@ -62,6 +70,16 @@ handle_parry_starting_effects(data) return TRUE +/** + * Tries to find a backup parry item. + * Does not look at active held item. + */ +/mob/living/proc/find_backup_parry_item() + for(var/i in held_items - get_active_held_item()) + var/obj/item/I = i + if(I.can_active_parry()) + return I + /** * Called via timer when the parry sequence ends. */ diff --git a/code/modules/mob/living/living_blocking_parrying.dm b/code/modules/mob/living/living_blocking_parrying.dm index 67d90a37f3..9f1ad1c27a 100644 --- a/code/modules/mob/living/living_blocking_parrying.dm +++ b/code/modules/mob/living/living_blocking_parrying.dm @@ -28,11 +28,13 @@ GLOBAL_LIST_EMPTY(block_parry_data) /// Attacks we can block var/can_block_attack_types = ALL /// Our slowdown added while blocking - var/block_slowdown = 2 + var/block_slowdown = 1 /// Clickdelay added to user after block ends var/block_end_click_cd_add = 0 /// Disallow attacking during block var/block_lock_attacking = TRUE + /// Disallow sprinting during block + var/block_lock_sprinting = FALSE /// The priority we get in [mob/do_run_block()] while we're being used to parry. var/block_active_priority = BLOCK_PRIORITY_ACTIVE_BLOCK /// Windup before we have our blocking active.