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.