From 8c8df2d6e1e42dfd42a913346de27dc12ff75bda Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 20 Aug 2020 18:08:55 +0200 Subject: [PATCH] [MIRROR] Monkeys are now disarmed like humans (#439) * Monkeys are now disarmed like humans (#53036) Previously, monkey disarming was the old system of RNG stun/lose item. This PR makes disarming monkeys the same as disarming humans. * Monkeys are now disarmed like humans Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com> --- code/datums/components/tackle.dm | 2 +- code/modules/clothing/shoes/_shoes.dm | 2 +- .../mob/living/carbon/carbon_defense.dm | 125 ++++++++++++++++++ .../mob/living/carbon/carbon_defines.dm | 3 + code/modules/mob/living/carbon/human/human.dm | 15 --- .../mob/living/carbon/human/human_defines.dm | 2 + .../mob/living/carbon/human/species.dm | 101 +------------- .../mob/living/carbon/monkey/monkey.dm | 1 + .../living/carbon/monkey/monkey_defense.dm | 14 +- 9 files changed, 135 insertions(+), 130 deletions(-) diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index 0fb7d573c28..38287eab344 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -181,7 +181,7 @@ user.Knockdown(30) if(ishuman(target) && !T.has_movespeed_modifier(/datum/movespeed_modifier/shove)) T.add_movespeed_modifier(/datum/movespeed_modifier/shove) // maybe define a slightly more severe/longer slowdown for this - addtimer(CALLBACK(T, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + addtimer(CALLBACK(T, /mob/living/carbon/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) if(-1 to 0) // decent hit, both parties are about equally inconvenienced user.visible_message("[user] lands a passable [tackle_word] on [target], sending them both tumbling!", "You land a passable [tackle_word] on [target], sending you both tumbling!", target) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index ef71a981b65..fb03c76e4bf 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -244,7 +244,7 @@ to_chat(our_guy, "You stumble a bit on your untied shoelaces!") if(!our_guy.has_movespeed_modifier(/datum/movespeed_modifier/shove)) our_guy.add_movespeed_modifier(/datum/movespeed_modifier/shove) - addtimer(CALLBACK(our_guy, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + addtimer(CALLBACK(our_guy, /mob/living/carbon/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) if(26 to 1000) wiser = FALSE diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 2aa71321644..363b62f8b9a 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -231,6 +231,131 @@ return affecting.body_zone return dam_zone +/** + * Attempt to disarm the target mob. + * Will shove the target mob back, and drop them if they're in front of something dense + * or another carbon. +*/ +/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) + + if (ishuman(target)) + var/mob/living/carbon/human/human_target = target + human_target.w_uniform?.add_fingerprint(src) + + SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, src, zone_selected) + + var/turf/target_oldturf = target.loc + 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 + + //Thank you based whoneedsspace + target_collateral_carbon = locate(/mob/living/carbon) in target_shove_turf.contents + + // If we can't shove the target into the carbon (such as if it's an alien), then just pretend nothing was there + if (!target_collateral_carbon?.can_be_shoved_into) + target_collateral_carbon = null + + if(target_collateral_carbon) + 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) + target.visible_message("[name] kicks [target.name] onto [target.p_their()] side!", + "You're kicked onto your side by [name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You kick [target.name] onto [target.p_their()] side!") + addtimer(CALLBACK(target, /mob/living/proc/SetKnockdown, 0), SHOVE_CHAIN_PARALYZE) + log_combat(src, target, "kicks", "onto their side (paralyzing)") + + if(shove_blocked && !target.is_shove_knockdown_blocked() && !target.buckled) + var/directional_blocked = FALSE + if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that + var/target_turf = get_turf(target) + for(var/obj/obj_content in target_turf) + if(obj_content.flags_1 & ON_BORDER_1 && obj_content.dir == shove_dir && obj_content.density) + directional_blocked = TRUE + break + if(target_turf != target_shove_turf) //Make sure that we don't run the exact same check twice on the same tile + for(var/obj/obj_content in target_shove_turf) + 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("[name] shoves [target.name], knocking [target.p_them()] down!", + "You're knocked down from a shove by [name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You shove [target.name], knocking [target.p_them()] down!") + log_combat(src, target, "shoved", "knocking them down") + else if(target_table) + target.Knockdown(SHOVE_KNOCKDOWN_TABLE) + target.visible_message("[name] shoves [target.name] onto \the [target_table]!", + "You're shoved onto \the [target_table] by [name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You shove [target.name] onto \the [target_table]!") + 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) + target.Knockdown(SHOVE_KNOCKDOWN_HUMAN) + target_collateral_carbon.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL) + target.visible_message("[name] shoves [target.name] into [target_collateral_carbon.name]!", + "You're shoved into [target_collateral_carbon.name] by [name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You shove [target.name] into [target_collateral_carbon.name]!") + 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("[name] shoves [target.name] into \the [target_disposal_bin]!", + "You're shoved into \the [target_disposal_bin] by [target.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You shove [target.name] into \the [target_disposal_bin]!") + log_combat(src, target, "shoved", "into [target_disposal_bin] (disposal bin)") + else + target.visible_message("[name] shoves [target.name]!", + "You're shoved by [name]!", "You hear aggressive shuffling!", COMBAT_MESSAGE_RANGE, src) + to_chat(src, "You shove [target.name]!") + 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_held_item) + target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!", + "Your grip on \the [target_held_item] loosens!", null, COMBAT_MESSAGE_RANGE) + addtimer(CALLBACK(target, /mob/living/carbon/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) + else if(target_held_item) + target.dropItemToGround(target_held_item) + knocked_item = TRUE + target.visible_message("[target.name] drops \the [target_held_item]!", + "You drop \the [target_held_item]!", 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) + +/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()) + if(clothing.clothing_flags & BLOCKS_SHOVE_KNOCKDOWN) + return TRUE + return FALSE + +/mob/living/carbon/proc/clear_shove_slowdown() + remove_movespeed_modifier(/datum/movespeed_modifier/shove) + var/active_item = get_active_held_item() + if(is_type_in_typecache(active_item, GLOB.shove_disarming_types)) + visible_message("[name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/blob_act(obj/structure/blob/B) if (stat == DEAD) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 77002d61400..7385403352e 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -78,3 +78,6 @@ /// Simple modifier for whether this mob can handle greater or lesser skillchip complexity. See /datum/mutation/human/biotechcompat/ for example. var/skillchip_complexity_modifier = 0 + + /// Can other carbons be shoved into this one to make it fall? + var/can_be_shoved_into = FALSE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 138672a1171..3373c2a10df 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1158,21 +1158,6 @@ riding_datum.handle_vehicle_layer() . = ..(target, force, check_loc) -/mob/living/carbon/human/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this - var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) - for(var/bp in body_parts) - if(istype(bp, /obj/item/clothing)) - var/obj/item/clothing/C = bp - if(C.clothing_flags & BLOCKS_SHOVE_KNOCKDOWN) - return TRUE - return FALSE - -/mob/living/carbon/human/proc/clear_shove_slowdown() - remove_movespeed_modifier(/datum/movespeed_modifier/shove) - var/active_item = get_active_held_item() - if(is_type_in_typecache(active_item, GLOB.shove_disarming_types)) - visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) - /mob/living/carbon/human/do_after_coefficent() . = ..() . *= physiology.do_after_speed diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 144c6d936b6..a80b9374f56 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -12,6 +12,8 @@ buckle_lying = FALSE mob_biotypes = MOB_ORGANIC|MOB_HUMANOID blocks_emissive = EMISSIVE_BLOCK_UNIQUE + can_be_shoved_into = TRUE + //Hair colour and style var/hair_color = "000" var/hairstyle = "Bald" diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index eea967a8e28..81e3f115b49 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1407,106 +1407,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) if(user.loc == target.loc) return FALSE else - user.do_attack_animation(target, ATTACK_EFFECT_DISARM) - playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - - if(target.w_uniform) - target.w_uniform.add_fingerprint(user) - SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected) - - var/turf/target_oldturf = target.loc - var/shove_dir = get_dir(user.loc, target_oldturf) - var/turf/target_shove_turf = get_step(target.loc, shove_dir) - var/mob/living/carbon/human/target_collateral_human - 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 - - //Thank you based whoneedsspace - target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents - if(target_collateral_human) - 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) - target.visible_message("[user.name] kicks [target.name] onto [target.p_their()] side!", - "You're kicked onto your side by [user.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You kick [target.name] onto [target.p_their()] side!") - addtimer(CALLBACK(target, /mob/living/proc/SetKnockdown, 0), SHOVE_CHAIN_PARALYZE) - log_combat(user, target, "kicks", "onto their side (paralyzing)") - - if(shove_blocked && !target.is_shove_knockdown_blocked() && !target.buckled) - var/directional_blocked = FALSE - if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that - var/target_turf = get_turf(target) - for(var/obj/O in target_turf) - if(O.flags_1 & ON_BORDER_1 && O.dir == shove_dir && O.density) - directional_blocked = TRUE - break - if(target_turf != target_shove_turf) //Make sure that we don't run the exact same check twice on the same tile - for(var/obj/O in target_shove_turf) - if(O.flags_1 & ON_BORDER_1 && O.dir == turn(shove_dir, 180) && O.density) - directional_blocked = TRUE - break - if((!target_table && !target_collateral_human && !target_disposal_bin) || directional_blocked) - target.Knockdown(SHOVE_KNOCKDOWN_SOLID) - target.visible_message("[user.name] shoves [target.name], knocking [target.p_them()] down!", - "You're knocked down from a shove by [user.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You shove [target.name], knocking [target.p_them()] down!") - log_combat(user, target, "shoved", "knocking them down") - else if(target_table) - target.Knockdown(SHOVE_KNOCKDOWN_TABLE) - target.visible_message("[user.name] shoves [target.name] onto \the [target_table]!", - "You're shoved onto \the [target_table] by [user.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You shove [target.name] onto \the [target_table]!") - 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(user, target, "shoved", "onto [target_table] (table)") - else if(target_collateral_human) - target.Knockdown(SHOVE_KNOCKDOWN_HUMAN) - target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL) - target.visible_message("[user.name] shoves [target.name] into [target_collateral_human.name]!", - "You're shoved into [target_collateral_human.name] by [user.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You shove [target.name] into [target_collateral_human.name]!") - log_combat(user, target, "shoved", "into [target_collateral_human.name]") - else if(target_disposal_bin) - target.Knockdown(SHOVE_KNOCKDOWN_SOLID) - target.forceMove(target_disposal_bin) - target.visible_message("[user.name] shoves [target.name] into \the [target_disposal_bin]!", - "You're shoved into \the [target_disposal_bin] by [target.name]!", "You hear aggressive shuffling followed by a loud thud!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You shove [target.name] into \the [target_disposal_bin]!") - log_combat(user, target, "shoved", "into [target_disposal_bin] (disposal bin)") - else - target.visible_message("[user.name] shoves [target.name]!", - "You're shoved by [user.name]!", "You hear aggressive shuffling!", COMBAT_MESSAGE_RANGE, user) - to_chat(user, "You shove [target.name]!") - 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_held_item) - target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!", - "Your grip on \the [target_held_item] loosens!", null, COMBAT_MESSAGE_RANGE) - addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH) - else if(target_held_item) - target.dropItemToGround(target_held_item) - knocked_item = TRUE - target.visible_message("[target.name] drops \the [target_held_item]!", - "You drop \the [target_held_item]!", 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(user, target, "shoved", append_message) + user.disarm(target) /datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) return diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index e75c859334d..85e1cd6fcb0 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -12,6 +12,7 @@ type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey gib_type = /obj/effect/decal/cleanable/blood/gibs unique_name = TRUE + can_be_shoved_into = TRUE blocks_emissive = EMISSIVE_BLOCK_UNIQUE bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey, /obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 807ee64e2f6..8aec683738b 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -65,19 +65,7 @@ to_chat(M, "Your punch misses [name]!") if("disarm") if(stat < UNCONSCIOUS) - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - if (prob(25)) - Paralyze(40) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - log_combat(M, src, "pushed") - visible_message("[M] pushes [src] down!", \ - "[M] pushes you down!", "You hear aggressive shuffling followed by a loud thud!", null, M) - to_chat(M, "You push [src] down!") - else if(dropItemToGround(get_active_held_item())) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - visible_message("[M] disarms [src]!", \ - "[M] disarms you!", "You hear aggressive shuffling!", COMBAT_MESSAGE_RANGE, M) - to_chat(M, "You disarm [src]!") + M.disarm(src) /mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M) if(..()) //if harm or disarm intent.