Skip to content
Merged
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
6 changes: 6 additions & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -467,3 +467,9 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define DODGING_PENALTY 1
/// A define so the cooldown on the baited status and the duration of the baitcd status are the same
#define BAIT_COOLDOWN_TIME 15 SECONDS

// try_crit keys for modifiers
/// Chance modifier
#define CRIT_MOD_CHANCE "crit_mod"
/// Specifically knockout modifier for head crits
#define CRIT_MOD_KNOCKOUT_CHANCE "knockout_mod"
152 changes: 81 additions & 71 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -436,42 +436,42 @@
var/dullfactor = 1
if(!I?.force)
return 0

// newforce starts here and is the default amount of damage the item does.
var/newforce = I.force

// If this weapon has no user and is somehow attacking you just return default.
if(!istype(user))
return newforce

var/dullness_ratio
if(I.max_blade_int && I.sharpness != IS_BLUNT)
dullness_ratio = I.blade_int / I.max_blade_int
var/cont = FALSE

var/used_str = GET_MOB_ATTRIBUTE_VALUE(user, STAT_STRENGTH)
if(iscarbon(user))
var/mob/living/carbon/C = user
/*
* If you have a dominant hand which is assigned at
* character creation. You suffer a -1 Str if your
* no using the item in your dominant hand.
* Check living/carbon/carbon.dm for more info.
*/
if(C.domhand)
used_str = C.get_str_arms(C.used_hand)
//STR is +1 from STRONG stance and -1 from SWIFT stance

// Apply rmb intent modifiers
if(istype(user.rmb_intent, /datum/rmb_intent/strong))
used_str++
if(istype(user.rmb_intent, /datum/rmb_intent/swift))
else if(istype(user.rmb_intent, /datum/rmb_intent/swift))
used_str--
if(istype(user.rmb_intent, /datum/rmb_intent/weak))
else if(istype(user.rmb_intent, /datum/rmb_intent/weak))
used_str /= 2

//Your max STR is 20.
used_str = CLAMP(used_str, 1, 20)
used_str = clamp(used_str, 1, 20)

//Vampire checks for Potence
if(ishuman(user))
var/mob/living/carbon/human/user_human = user
if(user_human.clan)
used_str += floor(0.5 * user_human.potence_weapon_buff)
// For each level of potence user gains 0.5 STR, at 5 Potence their STR buff is 2.5

if(used_str >= 11)
newforce = newforce + (newforce * ((used_str - 10) * 0.1))
if(dullness_ratio && (user.used_intent.blade_class in list(BCLASS_CHOP, BCLASS_CUT, BCLASS_STAB)))
Expand All @@ -488,8 +488,8 @@
if(HAS_TRAIT(I, TRAIT_WIELDED))
effective *= 0.75
//Strength influence is reduced to 30%
if(effective > GET_MOB_ATTRIBUTE_VALUE(user, STAT_STRENGTH))
newforce = max(newforce*0.3, 1)
if(effective > used_str)
newforce = max(newforce * 0.3, 1)

//Blade Dulling Starts here.
switch(blade_dulling)
Expand All @@ -503,7 +503,6 @@
else
dullfactor = 0.45 + (lumberskill * 0.15)
lumberjacker.mind.add_sleep_experience(/datum/attribute/skill/labor/lumberjacking, (GET_MOB_ATTRIBUTE_VALUE(lumberjacker, STAT_INTELLIGENCE)*0.2))
cont = TRUE
if(BCLASS_CHOP)
//Additional damage for axes against trees.
if(istype(I, /obj/item/weapon))
Expand All @@ -515,51 +514,42 @@
dullfactor = 0.2
else
dullfactor = 1.5
cont = TRUE
if(!cont)
return 0
else
return 0
if(DULLING_BASH) //stone/metal, can't be attacked by cutting
switch(user.used_intent.blade_class)
if(BCLASS_BLUNT)
cont = TRUE
EMPTY_BLOCK_GUARD
if(BCLASS_SMASH)
dullfactor = 1.5
cont = TRUE
if(BCLASS_DRILL)
dullfactor = 10
cont = TRUE
if(BCLASS_PICK)
dullfactor = 1.5
cont = TRUE
if(!cont)
return 0
else
return 0
if(DULLING_BASHCHOP) //structures that can be attacked by clubs also (doors fences etc)
switch(user.used_intent.blade_class)
if(BCLASS_CUT)
if(!I.remove_bintegrity(1, user))
dullfactor = 0.8
cont = TRUE
if(BCLASS_CHOP)
if(!I.remove_bintegrity(1, user))
dullfactor = 0.8
else
dullfactor = 1.5
cont = TRUE
if(BCLASS_SMASH)
dullfactor = 1.5
cont = TRUE
if(BCLASS_DRILL)
dullfactor = 10
cont = TRUE
if(BCLASS_BLUNT)
cont = TRUE
EMPTY_BLOCK_GUARD
if(BCLASS_PICK)
var/mob/living/miner = user
var/mineskill = GET_MOB_SKILL_VALUE_OLD(miner, /datum/attribute/skill/labor/mining)
dullfactor = 1.6 - (mineskill * 0.1)
cont = TRUE
if(!cont)
return 0
else
return 0
if(DULLING_PICK) //cannot deal damage if not a pick item. aka rock walls
if(user.body_position == LYING_DOWN)
to_chat(user, span_warning("I need to stand up to get a proper swing."))
Expand Down Expand Up @@ -595,23 +585,25 @@
var/damflerp = (dullness_ratio - SHARPNESS_TIER2_THRESHOLD) / (SHARPNESS_TIER1_THRESHOLD - SHARPNESS_TIER2_THRESHOLD)
newforce *= damflerp
newforce = round(newforce)

if(user.used_intent.get_chargetime() && user.client?.chargedprog < 100)
newforce = newforce * round(user.client?.chargedprog / 100, 0.1)
// newforce = round(newforce, 1)

if(user.body_position == LYING_DOWN)
newforce *= 0.5

if(user.has_status_effect(/datum/status_effect/divine_strike))
newforce += 5
// newforce is rounded upto the nearest intiger.
newforce = round(newforce,1)
//This is returning the maximum of the arguments meaning this is to prevent negative values.
newforce = max(newforce, 1)

if(dullness_ratio)
if(dullness_ratio < SHARPNESS_TIER2_THRESHOLD && (user.used_intent.blade_class in list(BCLASS_CHOP, BCLASS_CUT, BCLASS_STAB)))
var/lerpratio = LERP(0, SHARPNESS_TIER2_THRESHOLD, (dullness_ratio / SHARPNESS_TIER2_THRESHOLD))
if(prob(33))
to_chat(user, span_info("The blade is dull..."))
newforce *= (lerpratio * 2)

newforce = max(1, round(newforce, DAMAGE_PRECISION))

return newforce

/mob/living/proc/simple_limb_hit(zone)
Expand All @@ -637,43 +629,54 @@
return "foreleg"
return zone

/obj/item/proc/funny_attack_effects(mob/living/target, mob/living/user, nodmg)
/obj/item/proc/funny_attack_effects(mob/living/target, mob/living/user)
return

/mob/living/attacked_by(obj/item/I, mob/living/user)
var/hitlim = simple_limb_hit(user.zone_selected)
I.funny_attack_effects(src, user)
if(I.force)
var/newforce = get_complex_damage(I, user)
apply_damage(newforce, I.damtype, def_zone = hitlim)
if(I.damtype == BRUTE)
next_attack_msg.Cut()
if(HAS_TRAIT(src, TRAIT_SIMPLE_WOUNDS))
var/datum/wound/crit_wound = simple_woundcritroll(user.used_intent.blade_class, newforce, user, hitlim)
if(crit_wound?.should_embed(I))
// throw_alert("embeddedobject", /atom/movable/screen/alert/embeddedobject)
simple_add_embedded_object(I, silent = FALSE, crit_message = TRUE)
src.grabbedby(user, 1, item_override = I)
var/haha = user.used_intent.blade_class
if(newforce > 5)
if(haha != BCLASS_BLUNT)
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
user.adjust_hygiene(-10)
if(newforce > 15)
if(haha == BCLASS_BLUNT)
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
user.adjust_hygiene(-10)
if(!I.force)
return FALSE

var/newforce = get_complex_damage(I, user)

apply_damage(newforce, I.damtype, def_zone = hitlim)

if(!cmode && !stat && user.m_intent == MOVE_INTENT_SNEAK && (dir == REVERSE_DIR(get_dir(src, user))))
var/blunt = (user.used_intent.blade_class == BCLASS_BLUNT)
var/attacker_sneaking = GET_MOB_SKILL_VALUE(user, /datum/attribute/skill/misc/sneaking)
if((blunt || I.wbalance >= HARD_TO_DODGE) && attacker_sneaking >= 10)
next_attack_msg += " [span_userdanger("SNEAK ATTACK!")]"
// Get extra damage as a percent of 50% extra based on skill
var/percentage = attacker_sneaking / (SKILL_LEVEL_LEGENDARY * 10)
newforce += (newforce * 0.5) * percentage

if(I.damtype == BRUTE)
if(HAS_TRAIT(src, TRAIT_SIMPLE_WOUNDS))
var/datum/wound/crit_wound = simple_woundcritroll(user.used_intent.blade_class, newforce, user, hitlim)
if(crit_wound?.should_embed(I))
// throw_alert("embeddedobject", /atom/movable/screen/alert/embeddedobject)
simple_add_embedded_object(I, silent = FALSE, crit_message = TRUE)
grabbedby(user, 1, item_override = I)
if(newforce > 5)
if(user.used_intent.blade_class != BCLASS_BLUNT)
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
user.adjust_hygiene(-10)
else if(newforce > 15)
if(user.used_intent.blade_class == BCLASS_BLUNT)
I.add_mob_blood(src)
var/turf/location = get_turf(src)
add_splatter_floor(location)
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
user.add_mob_blood(src)
user.adjust_hygiene(-10)

send_item_attack_message(I, user, hitlim)
if(I.force)
return TRUE
return TRUE

/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user)
var/hitlim = simple_limb_hit(user.zone_selected)
Expand Down Expand Up @@ -820,17 +823,24 @@
return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100

/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area)
if(!I.force)
return

var/message_verb = "attacked"
if(user.used_intent)
message_verb = "[pick(user.used_intent.attack_verb)]"
else if(!I.force)
return

var/message_hit_area = ""
if(hit_area)
message_hit_area = " in the [hit_area]"

var/attack_message = "[user] [message_verb] [src][message_hit_area] with [I]!"
var/attack_message_local = "[user] [message_verb] me[message_hit_area] with [I]!"
visible_message("<span class='danger'>[attack_message][next_attack_msg.Join()]</span>",\
"<span class='danger'>[attack_message_local][next_attack_msg.Join()]</span>", null, COMBAT_MESSAGE_RANGE)
visible_message(
span_danger("[attack_message][next_attack_msg.Join()]"),
span_danger("[attack_message_local][next_attack_msg.Join()]"),
null,
COMBAT_MESSAGE_RANGE
)
next_attack_msg.Cut()
return 1
2 changes: 1 addition & 1 deletion code/game/objects/items/weapons/melee/special.dm
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@
STOP_PROCESSING(SSobj, src)
. = ..()

/obj/item/weapon/mace/stunmace/funny_attack_effects(mob/living/target, mob/living/user, nodmg)
/obj/item/weapon/mace/stunmace/funny_attack_effects(mob/living/target, mob/living/user)
. = ..()
if(on)
target.electrocute_act(5, src)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/combat/_special_intent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@
var/obj/item/bodypart/affecting = human_victim.get_bodypart(damage_zone)
var/armor_block = human_victim.run_armor_check(damage_zone, damage_type, damage = damage)
if(human_victim.apply_damage(damage, damage_type, affecting, armor_block))
affecting?.bodypart_attacked_by(damage_class, damage, user, crit_message = TRUE, reduce_crit = 100)
affecting?.bodypart_attacked_by(damage_class, damage, user, crit_message = TRUE, modifiers = list(CRIT_MOD_CHANCE = -100))
message += "<b> It pierces through to their flesh!</b>"
playsound(human_victim, weapon.hitsound, 80, TRUE)

Expand Down
2 changes: 1 addition & 1 deletion code/modules/crafting/alchemy/reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ If you want to expand on poisons theres tons of fun effects TG chemistry has tha
to_chat(graggar_lover, span_bloody("More... More..."))
var/obj/item/bodypart/bp = graggar_lover.get_bodypart()
bp?.lingering_pain += 10
bp?.bodypart_attacked_by(BCLASS_BLUNT, 12, null, BODY_ZONE_CHEST, crit_message = FALSE, reduce_crit = 10)
bp?.bodypart_attacked_by(BCLASS_BLUNT, 12, null, BODY_ZONE_CHEST, crit_message = FALSE, modifiers = list(CRIT_MOD_CHANCE = -10))
M.do_jitter_animation(100)
if(60)
M.do_jitter_animation(150)
Expand Down
Loading
Loading