From ba6e869440d6401958af8efcf8c534fc8c8bbdc8 Mon Sep 17 00:00:00 2001 From: Iajret Creature <122297233+AnArgonianLizardThatStealsPRs@users.noreply.github.com> Date: Mon, 13 Nov 2023 13:27:23 +0300 Subject: [PATCH] [MIRROR] The Brawlening: Unarmed fighting interactions for shoving, grabbing and nonlethal takedowns (not martial arts) [MDB IGNORE] (#24865) (#572) * The Brawlening: Unarmed fighting interactions for shoving, grabbing and nonlethal takedowns (not martial arts) * Fixing diffs * Update living.dm --------- Co-authored-by: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com> --- code/__DEFINES/combat.dm | 3 ++ .../dna_infuser/organ_sets/carp_organs.dm | 4 +-- .../stacks/golem_food/golem_status_effects.dm | 2 -- .../mob/living/carbon/carbon_defense.dm | 1 + .../mob/living/carbon/human/_species.dm | 34 +++++++++++++------ code/modules/mob/living/living.dm | 2 +- code/modules/surgery/bodyparts/_bodyparts.dm | 4 +-- code/modules/surgery/bodyparts/head.dm | 2 +- code/modules/surgery/bodyparts/parts.dm | 15 ++++---- .../bodyparts/species_parts/misc_bodyparts.dm | 16 ++++----- 10 files changed, 49 insertions(+), 34 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index cc9412208fb..ee4ddc5b7ce 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -169,6 +169,9 @@ DEFINE_BITFIELD(status_flags, list( GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( /obj/item/gun))) +//The define for base unarmed miss chance +#define UNARMED_MISS_CHANCE_BASE 20 +#define UNARMED_MISS_CHANCE_MAX 20 //Combat object defines diff --git a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm index 97b80b91969..cbe6e1c31c7 100644 --- a/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/carp_organs.dm @@ -60,7 +60,7 @@ var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD) head.unarmed_damage_low = 10 head.unarmed_damage_high = 15 - head.unarmed_stun_threshold = 15 + head.unarmed_effectiveness = 15 /obj/item/organ/internal/tongue/carp/on_remove(mob/living/carbon/tongue_owner) . = ..() @@ -74,7 +74,7 @@ var/obj/item/bodypart/head/head = human_receiver.get_bodypart(BODY_ZONE_HEAD) head.unarmed_damage_low = initial(head.unarmed_damage_low) head.unarmed_damage_high = initial(head.unarmed_damage_high) - head.unarmed_stun_threshold = initial(head.unarmed_stun_threshold) + head.unarmed_effectiveness = initial(head.unarmed_effectiveness) /obj/item/organ/internal/tongue/carp/on_life(seconds_per_tick, times_fired) . = ..() diff --git a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm index 26b5a4439ea..d34cb722763 100644 --- a/code/game/objects/items/stacks/golem_food/golem_status_effects.dm +++ b/code/game/objects/items/stacks/golem_food/golem_status_effects.dm @@ -364,7 +364,6 @@ /datum/status_effect/golem/titanium/proc/buff_arm(obj/item/bodypart/arm/arm) arm.unarmed_damage_low += damage_increase arm.unarmed_damage_high += damage_increase - arm.unarmed_stun_threshold += damage_increase // We don't want to make knockdown more likely RegisterSignal(arm, COMSIG_QDELETING, PROC_REF(on_arm_destroyed)) LAZYADD(modified_arms, arm) @@ -383,7 +382,6 @@ return arm.unarmed_damage_low -= damage_increase arm.unarmed_damage_high -= damage_increase - arm.unarmed_stun_threshold -= damage_increase UnregisterSignal(arm, COMSIG_QDELETING) /// Remove references to deleted arms diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index fb75bfa0234..ab94a5a0b38 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -408,6 +408,7 @@ if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove)) target.add_movespeed_modifier(/datum/movespeed_modifier/shove) + target.emote("sway") if(target_held_item) append_message = "loosening [target.p_their()] grip on [target_held_item]" target.visible_message(span_danger("[target.name]'s grip on \the [target_held_item] loosens!"), //He's already out what are you doing diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index f9dc29af278..14aa9018277 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -1177,16 +1177,29 @@ GLOBAL_LIST_EMPTY(features_by_species) return FALSE user.do_attack_animation(target, atk_effect) + //has our target been shoved recently? If so, they're off-balance and we get an easy hit. + var/off_balance = FALSE + + //Someone in a grapple is much more vulnerable to being harmed by punches. + var/grappled = FALSE + + if(target.has_movespeed_modifier(/datum/movespeed_modifier/shove)) + off_balance = TRUE + + if(target.pulledby && target.pulledby.grab_state >= GRAB_AGGRESSIVE) + grappled = TRUE + var/damage = rand(attacking_bodypart.unarmed_damage_low, attacking_bodypart.unarmed_damage_high) + var/limb_accuracy = attacking_bodypart.unarmed_effectiveness var/obj/item/bodypart/affecting = target.get_bodypart(target.get_random_valid_zone(user.zone_selected)) var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases if(attacking_bodypart.unarmed_damage_low) - if((target.body_position == LYING_DOWN) || HAS_TRAIT(user, TRAIT_PERFECT_ATTACKER)) //kicks never miss (provided your species deals more than 0 damage) + if((target.body_position == LYING_DOWN) || HAS_TRAIT(user, TRAIT_PERFECT_ATTACKER) || off_balance) //kicks and attacks against off-balance targets never miss (provided your species deals more than 0 damage) miss_chance = 0 else - miss_chance = min((attacking_bodypart.unarmed_damage_high/attacking_bodypart.unarmed_damage_low) + (user.getStaminaLoss() * 0.2) + (user.getBruteLoss()*0.5), 100) //old base chance for a miss + various damage. capped at 100 to prevent weirdness in prob() //SKYRAT EDIT CHANGE - ORIGINAL: miss_chance = min((attacking_bodypart.unarmed_damage_high/attacking_bodypart.unarmed_damage_low) + user.getStaminaLoss() + (user.getBruteLoss()*0.5), 100) + miss_chance = clamp(UNARMED_MISS_CHANCE_BASE - limb_accuracy + user.getStaminaLoss() + (user.getBruteLoss()*0.5), 0, UNARMED_MISS_CHANCE_MAX) //Limb miss chance + various damage. capped at 75 so there is at least a chance to land a hit. if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted playsound(target.loc, attacking_bodypart.unarmed_miss_sound, 25, TRUE, -1) @@ -1212,26 +1225,27 @@ GLOBAL_LIST_EMPTY(features_by_species) var/attack_direction = get_dir(user, target) var/attack_type = attacking_bodypart.attack_type - var/unarmed_sharpness = attacking_bodypart.unarmed_sharpness //SKYRAT EDIT - If unarmed damage sharpness needs to be taken into account. - if(atk_effect == ATTACK_EFFECT_KICK)//kicks deal 1.5x raw damage + var/unarmed_sharpness = attacking_bodypart.unarmed_sharpness //SKYRAT EDIT ADDITION - If unarmed damage sharpness needs to be taken into account. + if(atk_effect == ATTACK_EFFECT_KICK || grappled) //kicks and punches when grappling bypass armor slightly. if(damage >= 9) target.force_say() - log_combat(user, target, "kicked") - target.apply_damage(damage * PUNCH_STAMINA_MULTIPLIER, STAMINA, affecting, armor_block) //SKYRAT EDIT ADDITION - target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction) - else//other attacks deal full raw damage + 1.5x in stamina damage + log_combat(user, target, grappled ? "grapple punched" : "kicked") + target.apply_damage(damage * PUNCH_STAMINA_MULTIPLIER, attack_type, affecting, armor_block - limb_accuracy, attack_direction = attack_direction) // SKYRAT EDIT CHANGE - ORIGINAL : target.apply_damage(damage, attack_type, affecting, armor_block - limb_accuracy, attack_direction = attack_direction) + target.apply_damage(damage*1.5, STAMINA, affecting, armor_block - limb_accuracy) + else // Normal attacks do not gain the benefit of armor penetration. target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction, sharpness = unarmed_sharpness) //SKYRAT EDIT - Applies sharpness if it does - ORIGINAL: target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction) target.apply_damage(damage * PUNCH_STAMINA_MULTIPLIER, STAMINA, affecting, armor_block) //SKYRAT EDIT CHANGE: target.apply_damage(damage*1.5, STAMINA, affecting, armor_block) if(damage >= 9) target.force_say() log_combat(user, target, "punched") - if((target.stat != DEAD) && damage >= attacking_bodypart.unarmed_stun_threshold) + //If we rolled a punch high enough to hit our stun threshold, or our target is off-balance and they have at least 40 damage+stamina loss, we knock them down + if((target.stat != DEAD) && prob(limb_accuracy) || (target.stat != DEAD) && off_balance && (target.getStaminaLoss() + user.getBruteLoss()) >= 40) target.visible_message(span_danger("[user] knocks [target] down!"), \ span_userdanger("You're knocked down by [user]!"), span_hear("You hear aggressive shuffling followed by a loud thud!"), COMBAT_MESSAGE_RANGE, user) to_chat(user, span_danger("You knock [target] down!")) /* SKYRAT EDIT REMOVAL - Less combat lethality and hard stungs - var/knockdown_duration = 40 + (target.getStaminaLoss() + (target.getBruteLoss()*0.5))*0.8 //50 total damage = 40 base stun + 40 stun modifier = 80 stun duration, which is the old base duration + var/knockdown_duration = 4 SECONDS + (target.getStaminaLoss() + (target.getBruteLoss()*0.5))*0.8 //50 total damage = 4 second base stun + 4 second stun modifier = 8 second knockdown duration target.apply_effect(knockdown_duration, EFFECT_KNOCKDOWN, armor_block) */ // SKYRAT REMOVAL END target.StaminaKnockdown(20) //SKYRAT EDIT ADDITION diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 0a719d727a2..8b8efbc23cd 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1160,7 +1160,7 @@ /mob/living/resist_grab(moving_resist) . = TRUE - if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || staminaloss > STAMINA_THRESHOLD_HARD_RESIST) //SKYRAT EDIT CHANGE: if(pulledby.grab_state || resting || HAS_TRAIT(src, TRAIT_GRABWEAKNESS)) + if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || has_movespeed_modifier(/datum/movespeed_modifier/shove) && getStaminaLoss() > STAMINA_THRESHOLD_HARD_RESIST) //SKYRAT EDIT CHANGE - ORIGINAL : if(pulledby.grab_state || body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) || has_movespeed_modifier(/datum/movespeed_modifier/shove) && getStaminaLoss() >= 30) var/altered_grab_state = pulledby.grab_state if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_GRABWEAKNESS) && pulledby.grab_state < GRAB_KILL) //If prone, resisting out of a grab is equivalent to 1 grab state higher. won't make the grab state exceed the normal max, however - SKYRAT EDIT CHANGE: if((resting || HAS_TRAIT(src, TRAIT_GRABWEAKNESS)) && pulledby.grab_state < GRAB_KILL) //If resting, resisting out of a grab is equivalent to 1 grab state higher. won't make the grab state exceed the normal max, however altered_grab_state++ diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index a8f35aaa968..e6f0d99ce95 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -175,8 +175,8 @@ var/unarmed_damage_low = 1 ///Highest possible punch damage this bodypart can ive. var/unarmed_damage_high = 1 - ///Damage at which attacks from this bodypart will stun - var/unarmed_stun_threshold = 2 + ///Determines the accuracy bonus, armor penetration and knockdown probability. + var/unarmed_effectiveness = 10 /// How many pixels this bodypart will offset the top half of the mob, used for abnormally sized torsos and legs var/top_offset = 0 diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 30fb63a8034..f6d890c646a 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -23,7 +23,7 @@ unarmed_miss_sound = 'sound/weapons/bite.ogg' unarmed_damage_low = 1 // Yeah, biteing is pretty weak, blame the monkey super-nerf unarmed_damage_high = 3 - unarmed_stun_threshold = 4 + unarmed_effectiveness = 0 bodypart_trait_source = HEAD_TRAIT var/mob/living/brain/brainmob //The current occupant. diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 050a34efd38..247441c3c69 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -109,9 +109,8 @@ body_damage_coeff = 0.75 can_be_disabled = TRUE unarmed_attack_verb = "punch" /// The classic punch, wonderfully classic and completely random - unarmed_damage_low = 1 + unarmed_damage_low = 5 unarmed_damage_high = 10 - unarmed_stun_threshold = 10 body_zone = BODY_ZONE_L_ARM /// Datum describing how to offset things worn on the hands of this arm, note that an x offset won't do anything here var/datum/worn_feature_offset/worn_glove_offset @@ -216,7 +215,7 @@ dmg_overlay_type = SPECIES_MONKEY unarmed_damage_low = 1 /// monkey punches must be really weak, considering they bite people instead and their bites are weak as hell. unarmed_damage_high = 2 - unarmed_stun_threshold = 3 + unarmed_effectiveness = 0 appendage_noun = "paw" /obj/item/bodypart/arm/left/alien @@ -321,7 +320,7 @@ dmg_overlay_type = SPECIES_MONKEY unarmed_damage_low = 1 unarmed_damage_high = 2 - unarmed_stun_threshold = 3 + unarmed_effectiveness = 0 appendage_noun = "paw" /obj/item/bodypart/arm/right/alien @@ -350,9 +349,9 @@ unarmed_attack_effect = ATTACK_EFFECT_KICK body_zone = BODY_ZONE_L_LEG unarmed_attack_verb = "kick" // The lovely kick, typically only accessable by attacking a grouded foe. 1.5 times better than the punch. - unarmed_damage_low = 2 + unarmed_damage_low = 7 unarmed_damage_high = 15 - unarmed_stun_threshold = 10 + unarmed_effectiveness = 15 /// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here var/datum/worn_feature_offset/worn_foot_offset @@ -440,7 +439,7 @@ dmg_overlay_type = SPECIES_MONKEY unarmed_damage_low = 2 unarmed_damage_high = 3 - unarmed_stun_threshold = 4 + unarmed_effectiveness = 0 /obj/item/bodypart/leg/left/alien icon = 'icons/mob/human/species/alien/bodyparts.dmi' @@ -534,7 +533,7 @@ dmg_overlay_type = SPECIES_MONKEY unarmed_damage_low = 2 unarmed_damage_high = 3 - unarmed_stun_threshold = 4 + unarmed_effectiveness = 0 /obj/item/bodypart/leg/right/alien icon = 'icons/mob/human/species/alien/bodyparts.dmi' diff --git a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm index f928a56edf7..5ce136cdf63 100644 --- a/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm +++ b/code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm @@ -378,21 +378,21 @@ limb_id = SPECIES_MUSHROOM unarmed_damage_low = 6 unarmed_damage_high = 14 - unarmed_stun_threshold = 14 + unarmed_effectiveness = 15 burn_modifier = 1.25 /obj/item/bodypart/arm/right/mushroom limb_id = SPECIES_MUSHROOM unarmed_damage_low = 6 unarmed_damage_high = 14 - unarmed_stun_threshold = 14 + unarmed_effectiveness = 15 burn_modifier = 1.25 /obj/item/bodypart/leg/left/mushroom limb_id = SPECIES_MUSHROOM unarmed_damage_low = 9 unarmed_damage_high = 21 - unarmed_stun_threshold = 14 + unarmed_effectiveness = 20 burn_modifier = 1.25 speed_modifier = 0.75 //big big fungus @@ -400,7 +400,7 @@ limb_id = SPECIES_MUSHROOM unarmed_damage_low = 9 unarmed_damage_high = 21 - unarmed_stun_threshold = 14 + unarmed_effectiveness = 20 burn_modifier = 1.25 speed_modifier = 0.75 //big fungus big fungus @@ -495,7 +495,7 @@ bodypart_traits = list(TRAIT_CHUNKYFINGERS, TRAIT_FIST_MINING) unarmed_damage_low = 5 unarmed_damage_high = 14 - unarmed_stun_threshold = 11 + unarmed_effectiveness = 20 /obj/item/bodypart/arm/left/golem/Initialize(mapload) held_hand_offset = new( @@ -529,7 +529,7 @@ bodypart_traits = list(TRAIT_CHUNKYFINGERS, TRAIT_FIST_MINING) unarmed_damage_low = 5 unarmed_damage_high = 14 - unarmed_stun_threshold = 11 + unarmed_effectiveness = 20 /obj/item/bodypart/arm/right/golem/Initialize(mapload) held_hand_offset = new( @@ -562,7 +562,7 @@ dmg_overlay_type = null unarmed_damage_low = 7 unarmed_damage_high = 21 - unarmed_stun_threshold = 11 + unarmed_effectiveness = 25 /obj/item/bodypart/leg/right/golem icon = 'icons/mob/human/species/golems.dmi' @@ -575,7 +575,7 @@ dmg_overlay_type = null unarmed_damage_low = 7 unarmed_damage_high = 21 - unarmed_stun_threshold = 11 + unarmed_effectiveness = 25 ///flesh