Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Martial arts tweaks and fixes #5114

Merged
merged 4 commits into from
Feb 1, 2025
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
11 changes: 5 additions & 6 deletions code/datums/martial/cqc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,16 @@
return
// monkestation edit: improved messaging
cqc_user.visible_message(
span_danger("[cqc_user] twists [attacker]'s arm, sending their [attack_weapon] back towards them!"),
span_userdanger("Making sure to avoid [attacker]'s [attack_weapon], you twist their arm to send it right back at them!"),
span_danger("[cqc_user] twists [attacker]'s arm, sending [attacker.p_their()] [attack_weapon] back towards [attacker.p_them()]!"),
span_userdanger("Making sure to avoid [attacker]'s [attack_weapon], you twist [attacker.p_their()] arm to send it right back at [attacker.p_them()]!"),
ignored_mobs = list(attacker),
)
to_chat(attacker, span_userdanger("[cqc_user] swiftly grabs and twists your arm, hitting you with your own [attack_weapon]!"), type = MESSAGE_TYPE_COMBAT)
// monkestation end
var/obj/item/melee/touch_attack/touch_weapon = attack_weapon
var/datum/action/cooldown/spell/touch/touch_spell = touch_weapon.spell_which_made_us?.resolve()
if(!touch_spell)
return
INVOKE_ASYNC(touch_spell, TYPE_PROC_REF(/datum/action/cooldown/spell/touch, do_hand_hit), touch_weapon, attacker, attacker)
if(touch_spell)
INVOKE_ASYNC(touch_spell, TYPE_PROC_REF(/datum/action/cooldown/spell/touch, do_hand_hit), touch_weapon, attacker, attacker)
return COMPONENT_NO_AFTERATTACK

/datum/martial_art/cqc/reset_streak(mob/living/new_target)
Expand Down Expand Up @@ -242,7 +241,7 @@
if(prob(65))
if(!defender.stat || !defender.IsParalyzed() || !restraining_mob)
held_item = defender.get_active_held_item()
defender.visible_message(span_danger("[attacker] strikes [defender]'s jaw with their hand!"), \
defender.visible_message(span_danger("[attacker] strikes [defender]'s jaw with [attacker.p_their()] hand!"), \
span_userdanger("Your jaw is struck by [attacker], you feel disoriented!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker)
to_chat(attacker, span_danger("You strike [defender]'s jaw, leaving [defender.p_them()] disoriented!"))
playsound(get_turf(defender), 'sound/weapons/cqchit1.ogg', 50, TRUE, -1)
Expand Down
97 changes: 57 additions & 40 deletions code/datums/martial/sleeping_carp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
var/deflect_cooldown = 3 SECONDS //monke edit start
var/deflect_stamcost = 15 //how much stamina it costs per bullet deflected
var/log_name = "Sleeping Carp"
var/damage = 0
var/damage = 20
var/kick_speed = 0 //how fast you get punted into the stratosphere on launchkick
var/wounding = 0 //whether or not you get wounded by the attack
var/zone_message = "" //string for where the attack is targetting
Expand Down Expand Up @@ -52,31 +52,41 @@
return FALSE

///Gnashing Teeth: Harm Harm, consistent 20 force punch on every second harm punch
/datum/martial_art/the_sleeping_carp/proc/strongPunch(mob/living/attacker, mob/living/defender)
damage = 20
wounding = 0
/datum/martial_art/the_sleeping_carp/proc/strongPunch(mob/living/attacker, mob/living/defender, set_damage = TRUE)
if(set_damage)
damage = 20
wounding = 0
///this var is so that the strong punch is always aiming for the body part the user is targeting and not trying to apply to the chest before deviating
var/obj/item/bodypart/affecting = defender.get_bodypart(defender.get_random_valid_zone(attacker.zone_selected))
attacker.do_attack_animation(defender, ATTACK_EFFECT_PUNCH)
var/atk_verb = pick("precisely kick", "brutally chop", "cleanly hit", "viciously slam")
defender.visible_message(span_danger("[attacker] [atk_verb]s [defender]!"), \
span_userdanger("[attacker] [atk_verb]s you!"), null, null, attacker)
defender.visible_message(
span_danger("[attacker] [atk_verb]s [defender]!"),
span_userdanger("[attacker] [atk_verb]s you!"),
ignored_mobs = attacker
)
to_chat(attacker, span_danger("You [atk_verb] [defender]!"))
playsound(defender, 'sound/weapons/punch1.ogg', vol = 25, vary = TRUE, extrarange = -1)
log_combat(attacker, defender, "strong punched ([log_name])") //monke edit
defender.apply_damage(damage, attacker.get_attack_type(), affecting, wound_bonus = wounding)
return

///Crashing Wave Kick: Harm Disarm combo, throws people seven tiles backwards
/datum/martial_art/the_sleeping_carp/proc/launchKick(mob/living/attacker, mob/living/defender)
damage = 15 //monke edit start
kick_speed = 4
wounding = CANT_WOUND
zone_message = "chest"
zone = BODY_ZONE_CHEST
/datum/martial_art/the_sleeping_carp/proc/launchKick(mob/living/attacker, mob/living/defender, set_damage = TRUE)
//monke edit start
if(set_damage)
damage = 15
kick_speed = 4
wounding = CANT_WOUND
zone_message = "chest"
zone = BODY_ZONE_CHEST
attacker.do_attack_animation(defender, ATTACK_EFFECT_KICK)
defender.visible_message(span_warning("[attacker] kicks [defender] square in the [zone_message], sending them flying!"), \
span_userdanger("You are kicked square in the [zone_message] by [attacker], sending you flying!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker)
defender.visible_message(
span_warning("[attacker] kicks [defender] square in the [zone_message], sending [defender.p_them()] flying!"),
span_userdanger("You are kicked square in the [zone_message] by [attacker], sending you flying!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"),
vision_distance = COMBAT_MESSAGE_RANGE,
ignored_mobs = attacker,
)
playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', vol = 50, vary = TRUE, extrarange = -1)
var/atom/throw_target = get_edge_target_turf(defender, attacker.dir)
defender.throw_at(throw_target, 7, kick_speed, attacker)
Expand All @@ -85,24 +95,30 @@
return

///Keelhaul: Disarm Disarm combo, knocks people down and deals substantial stamina damage, and also discombobulates them. Knocks objects out of their hands if they're already on the ground.
/datum/martial_art/the_sleeping_carp/proc/dropKick(mob/living/attacker, mob/living/defender)
stamina_damage = 100 //monke edit start
/datum/martial_art/the_sleeping_carp/proc/dropKick(mob/living/attacker, mob/living/defender, set_damage = TRUE)
//monke edit start
if(set_damage)
stamina_damage = 100
attacker.do_attack_animation(defender, ATTACK_EFFECT_KICK)
playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', vol = 50, vary = TRUE, extrarange = -1)
if(defender.body_position == STANDING_UP)
defender.Knockdown(2 SECONDS)
defender.visible_message(
span_warning("[attacker] kicks [defender] in the head, sending them face first into the floor!"),
span_warning("[attacker] kicks [defender] in the head, sending [defender.p_them()] face first into the floor!"),
span_userdanger("You are kicked in the head by [attacker], sending you crashing to the floor!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker
)
span_hear("You hear a sickening sound of flesh hitting flesh!"),
vision_distance = COMBAT_MESSAGE_RANGE,
ignored_mobs = attacker,
)
else
defender.drop_all_held_items()
defender.visible_message(
span_warning("[attacker] kicks [defender] in the head!"),
span_userdanger("You are kicked in the head by [attacker]!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker
)
span_hear("You hear a sickening sound of flesh hitting flesh!"),
vision_distance = COMBAT_MESSAGE_RANGE,
ignored_mobs = attacker,
)
defender.stamina.adjust(stamina_damage)
defender.adjust_dizzy_up_to(10 SECONDS, 10 SECONDS)
defender.adjust_temp_blindness_up_to(2 SECONDS, 10 SECONDS)
Expand All @@ -121,7 +137,7 @@
playsound(defender, 'sound/weapons/punch1.ogg', vol = 25, vary = TRUE, extrarange = -1)
if(defender.stat != DEAD && !defender.IsUnconscious() && defender.stamina.current <= 50) //We put our target to sleep.
defender.visible_message(
span_danger("[attacker] carefully pinch a nerve in [defender]'s neck, knocking them out cold"),
span_danger("[attacker] carefully pinch a nerve in [defender]'s neck, knocking [defender.p_them()] out cold"),
span_userdanger("[attacker] pinches something in your neck, and you fall unconscious!"),
)
grab_log_description = "grabbed and nerve pinched"
Expand All @@ -143,9 +159,9 @@
span_danger("[attacker] snaps the neck of [defender]!"),
span_userdanger("Your neck is snapped by [attacker]!"),
span_hear("You hear a sickening snap!"),
ignored_mobs = attacker
ignored_mobs = attacker,
)
to_chat(attacker, span_danger("In a swift motion, you snap the neck of [defender]!"))
to_chat(attacker, span_danger("In a swift motion, you snap the neck of [defender]!"), type = MESSAGE_TYPE_COMBAT)
log_combat(attacker, defender, "snapped neck")
defender.apply_damage(100, BRUTE, BODY_ZONE_HEAD, wound_bonus=CANT_WOUND)
if(!HAS_TRAIT(defender, TRAIT_NODEATH))
Expand All @@ -164,7 +180,7 @@
span_danger("[attacker] [atk_verb]s [defender]!"),
span_userdanger("[attacker] [atk_verb]s you!"), null, null, attacker
)
to_chat(attacker, span_danger("You [atk_verb] [defender]!"))
to_chat(attacker, span_danger("You [atk_verb] [defender]!"), type = MESSAGE_TYPE_COMBAT)

defender.apply_damage(rand(10,15), attacker.get_attack_type(), affecting, wound_bonus = CANT_WOUND)
playsound(defender, 'sound/weapons/punch1.ogg', 25, TRUE, -1)
Expand All @@ -186,12 +202,12 @@

return ..()

/datum/martial_art/the_sleeping_carp/proc/can_deflect(mob/living/carp_user)
/datum/martial_art/the_sleeping_carp/proc/can_deflect(mob/living/carp_user, check_intent = TRUE)
if(!COOLDOWN_FINISHED(src, block_cooldown)) //monke edit
return FALSE
if(!can_use(carp_user))
return FALSE
if(!(carp_user.istate & ISTATE_HARM)) // monke edit: istates/intents
if(check_intent && !(carp_user.istate & ISTATE_HARM)) // monke edit: istates/intents
return FALSE
if(carp_user.incapacitated(IGNORE_GRAB)) //NO STUN
return FALSE
Expand Down Expand Up @@ -222,10 +238,11 @@
return COMPONENT_BULLET_PIERCED

///Signal from getting attacked with an item, for a special interaction with touch spells
/datum/martial_art/the_sleeping_carp/proc/on_attackby(mob/living/carbon/human/carp_user, obj/item/attack_weapon, mob/attacker, params) //no signal handler or this proc will explode
if(!istype(attack_weapon, /obj/item/melee/touch_attack) || !can_deflect(carp_user))
/datum/martial_art/the_sleeping_carp/proc/on_attackby(mob/living/carbon/human/carp_user, obj/item/melee/touch_attack/touch_weapon, mob/attacker, params)
SIGNAL_HANDLER

if(!istype(touch_weapon) || !can_deflect(carp_user, check_intent = !touch_weapon.dangerous))
return
var/obj/item/melee/touch_attack/touch_weapon = attack_weapon
var/datum/action/cooldown/spell/touch/touch_spell = touch_weapon.spell_which_made_us?.resolve()
// monkestation edit: flavor tweaks
if(!counter)
Expand All @@ -239,15 +256,15 @@
playsound(carp_user, 'monkestation/sound/effects/miss.ogg', vol = 50, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
else
carp_user.visible_message(
span_danger("[carp_user] twists [attacker]'s arm, sending their [attack_weapon] back towards them!"),
span_userdanger("Making sure to avoid [attacker]'s [attack_weapon], you twist their arm to send it right back at them!"),
ignored_mobs = list(attacker),
)
to_chat(attacker, span_userdanger("[carp_user] swiftly grabs and twists your arm, hitting you with your own [attack_weapon]!"), type = MESSAGE_TYPE_COMBAT)
carp_user.say(message = "PATHETIC!", language = /datum/language/common, ignore_spam = TRUE, forced = src)
if(!touch_spell)
return
INVOKE_ASYNC(touch_spell, TYPE_PROC_REF(/datum/action/cooldown/spell/touch, do_hand_hit), touch_weapon, attacker, attacker)
span_danger("[carp_user] twists [attacker]'s arm, sending [attacker.p_their()] [touch_weapon] back towards [attacker.p_them()]!"),
span_userdanger("Making sure to avoid [attacker]'s [touch_weapon], you twist [attacker.p_their()] arm to send it right back at [attacker.p_them()]!"),
ignored_mobs = list(attacker),
)
to_chat(attacker, span_userdanger("[carp_user] swiftly grabs and twists your arm, hitting you with your own [touch_weapon]!"), type = MESSAGE_TYPE_COMBAT)
INVOKE_ASYNC(carp_user, TYPE_PROC_REF(/atom/movable, say), message = "PATHETIC!", language = /datum/language/common, ignore_spam = TRUE, forced = src)
if(touch_spell)
INVOKE_ASYNC(touch_spell, TYPE_PROC_REF(/datum/action/cooldown/spell/touch, do_hand_hit), touch_weapon, attacker, attacker)
attacker.changeNext_move(CLICK_CD_MELEE)
// monkestation end
return COMPONENT_NO_AFTERATTACK

Expand Down
42 changes: 25 additions & 17 deletions monkestation/code/modules/antagonists/cult/blood_magic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,23 @@
// If this is gonna be a snowflake touch spell despite not being an actual touch spell, then we get to have snowflake code to ensure it behaves like it should.
/obj/item/melee/blood_magic/stun/proc/snowflake_martial_arts_handler(mob/living/target, mob/living/carbon/user)
var/datum/martial_art/martial_art = target?.mind?.martial_art
var/list/static/martial_counters_typecache = typecacheof(list(
/datum/martial_art/cqc,
/datum/martial_art/the_sleeping_carp/awakened_dragon,
))
if(!martial_art?.can_use())
return FALSE
if(is_type_in_typecache(martial_art, martial_counters_typecache))
var/counter = FALSE
var/dodge = FALSE
if(istype(martial_art, /datum/martial_art/cqc))
counter = TRUE
else if(istype(martial_art, /datum/martial_art/the_sleeping_carp))
var/datum/martial_art/the_sleeping_carp/eepy_carp = martial_art
if(eepy_carp.can_deflect(target, check_intent = FALSE))
if(eepy_carp.counter)
counter = TRUE
INVOKE_ASYNC(target, TYPE_PROC_REF(/atom/movable, say), message = "PATHETIC!", language = /datum/language/common, ignore_spam = TRUE, forced = martial_art)
else
dodge = TRUE
else if(istype(martial_art, /datum/martial_art/the_tunnel_arts))
dodge = TRUE
if(counter)
target.visible_message(
span_danger("[target] twists [user]'s arm, sending [user.p_their()] [src] back towards [user.p_them()]!"),
span_userdanger("Making sure to avoid [user]'s [src], you twist [user.p_their()] arm to send it right back at [user.p_them()]!"),
Expand All @@ -92,16 +102,14 @@
to_chat(user, span_userdanger("As you attempt to stun [target] with the spell, [target.p_they()] twist[target.p_s()] your arm and send[target.p_s()] the spell back at you!"), type = MESSAGE_TYPE_COMBAT)
effect_weakened(user, silent = TRUE)
return TRUE
else if(istype(martial_art, /datum/martial_art/the_sleeping_carp))
var/datum/martial_art/the_sleeping_carp/eepy_carp = martial_art
if(eepy_carp.can_deflect(target))
target.visible_message(
span_danger("[target] carefully dodges [user]'s [src]!"),
span_userdanger("You take great care to remain untouched by [user]'s [src]!"),
ignored_mobs = list(user),
)
to_chat(user, span_userdanger("[target] carefully dodges your [src], remaining completely untouched!"), type = MESSAGE_TYPE_COMBAT)
target.balloon_alert(user, "miss!")
playsound(target, 'monkestation/sound/effects/miss.ogg', vol = 50, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
return TRUE
else if(dodge)
target.visible_message(
span_danger("[target] carefully dodges [user]'s [src]!"),
span_userdanger("You take great care to remain untouched by [user]'s [src]!"),
ignored_mobs = list(user),
)
to_chat(user, span_userdanger("[target] carefully dodges your [src], remaining completely untouched!"), type = MESSAGE_TYPE_COMBAT)
target.balloon_alert(user, "miss!")
playsound(target, 'monkestation/sound/effects/miss.ogg', vol = 50, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
return TRUE
return FALSE
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
deflect_cooldown = 0
deflect_stamcost = 10
log_name = "Awakened Dragon"
scarp_traits = list(TRAIT_NOGUNS, TRAIT_NEVER_WOUNDED, TRAIT_NODISMEMBER, TRAIT_LIGHT_SLEEPER, TRAIT_THROW_GUNS, TRAIT_BATON_RESISTANCE)
counter = TRUE
var/title = null //YOUR TITLE BELOW THE HEAVENS! This is the prefix you use :]
var/static/list/character_prefixes = list(
"Heavenly Demon",
Expand All @@ -20,8 +22,6 @@
var/original_name
var/titled_name
var/list/datum/weakref/all_bodies = list()
scarp_traits = list(TRAIT_NOGUNS, TRAIT_NEVER_WOUNDED, TRAIT_NODISMEMBER, TRAIT_LIGHT_SLEEPER, TRAIT_THROW_GUNS, TRAIT_BATON_RESISTANCE)
counter = TRUE

/datum/martial_art/the_sleeping_carp/awakened_dragon/teach(mob/living/carbon/human/target, make_temporary)
. = ..()
Expand All @@ -31,33 +31,31 @@
if(title == null)
title = pick(character_prefixes)
all_bodies += target
titled_name = "[title] [target.get_face_name(original_name)]"
titled_name = "[title] [original_name]"
target.fully_replace_character_name(original_name, titled_name)

/datum/martial_art/the_sleeping_carp/awakened_dragon/remove(mob/living/carbon/human/target)
. = ..()
target.fully_replace_character_name(titled_name, original_name)


/datum/martial_art/the_sleeping_carp/awakened_dragon/strongPunch(mob/living/attacker, mob/living/defender)
. = ..()
/datum/martial_art/the_sleeping_carp/awakened_dragon/strongPunch(mob/living/attacker, mob/living/defender, set_damage)
damage = 40
wounding = 15
. = ..(attacker, defender, set_damage = FALSE)
attacker.say("Crushing Maw!!", forced = /datum/martial_art/the_sleeping_carp/awakened_dragon, ignore_spam = TRUE)


/datum/martial_art/the_sleeping_carp/awakened_dragon/launchKick(mob/living/attacker, mob/living/defender)
. = ..()
/datum/martial_art/the_sleeping_carp/awakened_dragon/launchKick(mob/living/attacker, mob/living/defender, set_damage)
damage = 30
kick_speed = 5
wounding = 5
zone = BODY_ZONE_HEAD
zone_message = "head"
. = ..(attacker, defender, set_damage = FALSE)
attacker.say("Tsunami Kick of the Heavenly Serpent!!", forced = /datum/martial_art/the_sleeping_carp/awakened_dragon, ignore_spam = TRUE)

/datum/martial_art/the_sleeping_carp/awakened_dragon/dropKick(mob/living/attacker, mob/living/defender)
. = ..()
/datum/martial_art/the_sleeping_carp/awakened_dragon/dropKick(mob/living/attacker, mob/living/defender, set_damage)
stamina_damage = 50
. = ..(attacker, defender, set_damage = FALSE)
defender.apply_damage(30, attacker.get_attack_type(), defender.zone_selected, wound_bonus = 10, bare_wound_bonus = 5)
attacker.say("Heavenly Dragon Kick!!", forced = /datum/martial_art/the_sleeping_carp/awakened_dragon, ignore_spam = TRUE)

Expand Down
Loading
Loading