Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ports Yogstation's Version of Disarm Rework (nerfs disarms) #2654

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,15 @@
#define DEFAULT_MESSAGE_RANGE 7

//Shove knockdown lengths (deciseconds)
#define SHOVE_KNOCKDOWN_SOLID 30
#define SHOVE_KNOCKDOWN_HUMAN 30
#define SHOVE_KNOCKDOWN_TABLE 30
#define SHOVE_KNOCKDOWN_COLLATERAL 10
#define SHOVE_CHAIN_PARALYZE 40
#define SHOVE_KNOCKDOWN_HUMAN 10
#define SHOVE_CHAIN_PARALYZE 30
//Shove slowdown
#define SHOVE_SLOWDOWN_LENGTH 30
#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(/obj/item/gun)))
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))

//Combat object defines
//Embedded objects
#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user)
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/obj_flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#define ANTI_TINFOIL_MANEUVER (1<<12) //Hats with negative effects when worn (i.e the tinfoil hat).
#define DANGEROUS_OBJECT (1<<13) //Clothes that cause a larger notification when placed on a person.
#define FAST_EMBARK (1<<14) //Clothes that speed up mech and pod boarding.

/// Flags for the organ_flags var on /obj/item/organ

#define ORGAN_SYNTHETIC (1<<0) //Synthetic organs, or cybernetic organs. Reacts to EMPs and don't deteriorate or heal
Expand Down
104 changes: 50 additions & 54 deletions code/modules/mob/living/carbon/carbon_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,10 @@
/mob/living/carbon/proc/disarm(mob/living/carbon/target)
do_attack_animation(target, ATTACK_EFFECT_DISARM)
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
var/is_human_target = ishuman(target) // different logic for humans
var/mob/living/carbon/human/human_target = target // only used if the target is actually human

if (ishuman(target))
var/mob/living/carbon/human/human_target = target
if (is_human_target)
human_target.w_uniform?.add_fingerprint(src)

SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, src, zone_selected)
Expand All @@ -223,9 +224,8 @@
var/shove_dir = get_dir(loc, target_oldturf)
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
var/mob/living/carbon/target_collateral_carbon
var/obj/structure/table/target_table
var/obj/machinery/disposal/bin/target_disposal_bin
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
var/shove_blocked = FALSE //Used to check if a shove is blocked, so that if it is, disarm logic can be applied
var/target_held_item = target.get_active_held_item() // what the target is currently holding, if anything

//Thank you based whoneedsspace
target_collateral_carbon = locate(/mob/living/carbon) in target_shove_turf.contents
Expand All @@ -234,21 +234,27 @@
if (!target_collateral_carbon?.can_be_shoved_into)
target_collateral_carbon = null

if(target_collateral_carbon)
var/bothstanding = target_collateral_carbon && (target.mobility_flags & MOBILITY_STAND) && (target_collateral_carbon.mobility_flags & MOBILITY_STAND)
if(target_collateral_carbon && bothstanding)
shove_blocked = TRUE
else
target.Move(target_shove_turf, shove_dir)
if(get_turf(target) == target_oldturf)
target_table = locate(/obj/structure/table) in target_shove_turf.contents
target_disposal_bin = locate(/obj/machinery/disposal/bin) in target_shove_turf.contents
shove_blocked = TRUE

if(target.IsKnockdown() && !target.IsParalyzed())
target.Paralyze(SHOVE_CHAIN_PARALYZE)
if(is_human_target) // humans get to be paralyzed for less long if they're armored when shoved and prone
var/obj/item/bodypart/human_chest = human_target.get_bodypart(BODY_ZONE_CHEST)
var/armor_block = human_target.run_armor_check(human_chest, "melee", "Your armor prevents your fall!", "Your armor softens your fall!")
human_target.apply_effect(SHOVE_CHAIN_PARALYZE, EFFECT_PARALYZE, armor_block)
var/reset_timer = SHOVE_CHAIN_PARALYZE * (100-armor_block)/100
addtimer(CALLBACK(human_target, /mob/living/proc/SetKnockdown, 0), reset_timer)
else
target.Paralyze(SHOVE_CHAIN_PARALYZE)
addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living, SetKnockdown), 0), SHOVE_CHAIN_PARALYZE)
target.visible_message("<span class='danger'>[name] kicks [target.name] onto [target.p_their()] side!</span>",
"<span class='userdanger'>You're kicked onto your side by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
"<span class='userdanger'>You're kicked onto your side by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You kick [target.name] onto [target.p_their()] side!</span>")
addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living, SetKnockdown), 0), SHOVE_CHAIN_PARALYZE)
log_combat(src, target, "kicks", "onto their side (paralyzing)")

if(shove_blocked && !target.is_shove_knockdown_blocked() && !target.buckled)
Expand All @@ -264,59 +270,49 @@
if(obj_content.flags_1 & ON_BORDER_1 && obj_content.dir == turn(shove_dir, 180) && obj_content.density)
directional_blocked = TRUE
break
if((!target_table && !target_collateral_carbon && !target_disposal_bin) || directional_blocked)
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
target.visible_message("<span class='danger'>[name] shoves [target.name], knocking [target.p_them()] down!</span>",
"<span class='userdanger'>You're knocked down from a shove by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name], knocking [target.p_them()] down!</span>")
log_combat(src, target, "shoved", "knocking them down")
else if(target_table)
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
target.visible_message("<span class='danger'>[name] shoves [target.name] onto \the [target_table]!</span>",
"<span class='userdanger'>You're shoved onto \the [target_table] by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name] onto \the [target_table]!</span>")
target.throw_at(target_table, 1, 1, null, FALSE) //1 speed throws with no spin are basically just forcemoves with a hard collision check
log_combat(src, target, "shoved", "onto [target_table] (table)")
else if(target_collateral_carbon)
if(!bothstanding || directional_blocked) // if shoved into something, drop active item
if(target_held_item) // doesn't care if it's not mentioned on the list
target.dropItemToGround(target_held_item)
target.visible_message("<span class='danger'>[name] shoves [target.name], disarming [target.p_them()]!</span>",
"<span class='userdanger'>You're disarmed from a shove by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name], disarming [target.p_them()]!</span>")
log_combat(src, target, "shoved", "disarming them")
else if(bothstanding) // if shoved into someone also standing, knock them both down
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
target_collateral_carbon.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
if(!target_collateral_carbon.is_shove_knockdown_blocked())
target_collateral_carbon.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
target.visible_message("<span class='danger'>[name] shoves [target.name] into [target_collateral_carbon.name]!</span>",
"<span class='userdanger'>You're shoved into [target_collateral_carbon.name] by [name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name] into [target_collateral_carbon.name]!</span>")
log_combat(src, target, "shoved", "into [target_collateral_carbon.name]")
else if(target_disposal_bin)
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
target.forceMove(target_disposal_bin)
target.visible_message("<span class='danger'>[name] shoves [target.name] into \the [target_disposal_bin]!</span>",
"<span class='userdanger'>You're shoved into \the [target_disposal_bin] by [target.name]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name] into \the [target_disposal_bin]!</span>")
log_combat(src, target, "shoved", "into [target_disposal_bin] (disposal bin)")
else
target.visible_message("<span class='danger'>[name] shoves [target.name]!</span>",
"<span class='userdanger'>You're shoved by [name]!</span>", "<span class='hear'>You hear aggressive shuffling!</span>", COMBAT_MESSAGE_RANGE, src)
to_chat(src, "<span class='danger'>You shove [target.name]!</span>")
var/target_held_item = target.get_active_held_item()
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
if(!target.is_shove_knockdown_blocked())
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove))
target.add_movespeed_modifier(/datum/movespeed_modifier/shove)
if(target_held_item)
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living/carbon, clear_shove_slowdown)), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
target.dropItemToGround(target_held_item)
knocked_item = TRUE
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!</span>",
"<span class='danger'>You drop \the [target_held_item]!</span>", null, COMBAT_MESSAGE_RANGE)
var/append_message = ""
if(target_held_item)
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
"<span class='warning'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living/carbon, clear_shove_slowdown)), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
target.dropItemToGround(target_held_item)
knocked_item = TRUE
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!</span>",
"<span class='warning'>You drop \the [target_held_item]!</span>", null, COMBAT_MESSAGE_RANGE)
var/append_message = ""
if(target_held_item)
if(knocked_item)
append_message = "causing [target.p_them()] to drop [target_held_item]"
else
append_message = "loosening [target.p_their()] grip on [target_held_item]"
log_combat(src, target, "shoved", append_message)
if(knocked_item)
append_message = "causing [target.p_them()] to drop [target_held_item]"
else
append_message = "loosening [target.p_their()] grip on [target_held_item]"
log_combat(src, target, "shoved", append_message)
else
log_combat(src, target, "shoved")

/mob/living/carbon/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this
for (var/obj/item/clothing/clothing in get_equipped_items())
Expand Down
1 change: 0 additions & 1 deletion code/modules/unit_tests/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,4 @@
victim.attack_hand(attacker)

TEST_ASSERT_EQUAL(victim.loc.x, run_loc_bottom_left.x + 2, "Victim was moved after being pushed against a wall")
TEST_ASSERT(victim.has_status_effect(STATUS_EFFECT_KNOCKDOWN), "Victim was not knocked down after being pushed against a wall")
TEST_ASSERT_EQUAL(victim.get_active_held_item(), null, "Victim didn't drop toolbox after being pushed against a wall")