Skip to content

Commit

Permalink
[MIRROR] The Brawlening: Unarmed fighting interactions for shoving, g…
Browse files Browse the repository at this point in the history
…rabbing 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 <[email protected]>
Co-authored-by: necromanceranne <[email protected]>
Co-authored-by: Giz <[email protected]>
  • Loading branch information
4 people authored Nov 13, 2023
1 parent 007c121 commit ba6e869
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 34 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions code/game/machinery/dna_infuser/organ_sets/carp_organs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
. = ..()
Expand All @@ -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)
. = ..()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/carbon_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 24 additions & 10 deletions code/modules/mob/living/carbon/human/_species.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/living.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand Down
4 changes: 2 additions & 2 deletions code/modules/surgery/bodyparts/_bodyparts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion code/modules/surgery/bodyparts/head.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 7 additions & 8 deletions code/modules/surgery/bodyparts/parts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand Down
16 changes: 8 additions & 8 deletions code/modules/surgery/bodyparts/species_parts/misc_bodyparts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -378,29 +378,29 @@
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

/obj/item/bodypart/leg/right/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 fungus big fungus

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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'
Expand All @@ -575,7 +575,7 @@
dmg_overlay_type = null
unarmed_damage_low = 7
unarmed_damage_high = 21
unarmed_stun_threshold = 11
unarmed_effectiveness = 25

///flesh

Expand Down

0 comments on commit ba6e869

Please sign in to comment.