diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm
index e982f6488de0..bd81b07a38e5 100644
--- a/code/datums/martial/cqc.dm
+++ b/code/datums/martial/cqc.dm
@@ -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)
@@ -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)
diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm
index 56bd900fdf8d..4279e8d08dc4 100644
--- a/code/datums/martial/sleeping_carp.dm
+++ b/code/datums/martial/sleeping_carp.dm
@@ -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
@@ -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)
@@ -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)
@@ -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"
@@ -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))
@@ -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)
@@ -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
@@ -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)
@@ -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
diff --git a/monkestation/code/modules/antagonists/cult/blood_magic.dm b/monkestation/code/modules/antagonists/cult/blood_magic.dm
index 635c6cce7910..95317060806a 100644
--- a/monkestation/code/modules/antagonists/cult/blood_magic.dm
+++ b/monkestation/code/modules/antagonists/cult/blood_magic.dm
@@ -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()]!"),
@@ -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
diff --git a/monkestation/code/datums/martial_arts/awakened_dragon.dm b/monkestation/code/modules/martial_arts/awakened_dragon.dm
similarity index 91%
rename from monkestation/code/datums/martial_arts/awakened_dragon.dm
rename to monkestation/code/modules/martial_arts/awakened_dragon.dm
index 08671dbbc4b7..632cae09c605 100644
--- a/monkestation/code/datums/martial_arts/awakened_dragon.dm
+++ b/monkestation/code/modules/martial_arts/awakened_dragon.dm
@@ -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",
@@ -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)
. = ..()
@@ -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)
diff --git a/monkestation/code/modules/martial_arts/tunnel_arts.dm b/monkestation/code/modules/martial_arts/tunnel_arts.dm
index 2b183d7e4cf0..c07a94a4dd73 100644
--- a/monkestation/code/modules/martial_arts/tunnel_arts.dm
+++ b/monkestation/code/modules/martial_arts/tunnel_arts.dm
@@ -11,10 +11,16 @@
allow_temp_override = FALSE
help_verb = /mob/living/proc/tunnel_arts_help
display_combos = TRUE
- /// List of traits applied to users of this martial art.
- var/list/tunnel_traits = list(TRAIT_HARDLY_WOUNDED, TRAIT_NOSOFTCRIT, TRAIT_BATON_RESISTANCE, TRAIT_PERFECT_ATTACKER, TRAIT_NOGUNS)
/// Probability of successfully blocking attacks while on throw mode
block_chance = 50
+ /// List of traits applied to users of this martial art.
+ var/static/list/tunnel_traits = list(
+ TRAIT_HARDLY_WOUNDED,
+ TRAIT_NOSOFTCRIT,
+ TRAIT_BATON_RESISTANCE,
+ TRAIT_PERFECT_ATTACKER,
+ TRAIT_NOGUNS
+ )
/datum/martial_art/the_tunnel_arts/teach(mob/living/new_holder)
. = ..()
@@ -48,13 +54,12 @@
var/obj/item/bodypart/affecting = defender.get_bodypart(defender.get_random_valid_zone(attacker.zone_selected))
attacker.do_attack_animation(defender, ATTACK_EFFECT_PUNCH)
defender.visible_message(
- span_danger("[attacker] uppercuts [defender], sending them skyward!"),
+ span_danger("[attacker] uppercuts [defender], sending [defender.p_them()] skyward!"),
span_userdanger("[attacker] uppercuts you, sending you hurtling through the air!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"),
- null,
- attacker,
+ ignored_mobs = list(attacker),
)
- to_chat(attacker, span_danger("You uppercut [defender]!"))
+ to_chat(attacker, span_danger("You uppercut [defender]!"), type = MESSAGE_TYPE_COMBAT)
playsound(defender, 'sound/weapons/punch1.ogg', 25, TRUE, -1)
log_combat(attacker, defender, "god fist (The Tunnel Arts))")
defender.apply_damage(20, attacker.get_attack_type(), affecting)
@@ -69,13 +74,12 @@
var/obj/item/bodypart/affecting = defender.get_bodypart(defender.get_random_valid_zone(attacker.zone_selected))
attacker.do_attack_animation(defender, ATTACK_EFFECT_PUNCH)
defender.visible_message(
- span_danger("[attacker] slams their palm into [defender]!"),
+ span_danger("[attacker] slams [attacker.p_their()] palm into [defender]!"),
span_userdanger("[attacker] palm strikes you, rattling you to your very core!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"),
- null,
- attacker,
+ ignored_mobs = list(attacker),
)
- to_chat(attacker, span_danger("You palm strike [defender], corrupting their Chi energy!"))
+ to_chat(attacker, span_danger("You palm strike [defender], corrupting [defender.p_their()] Chi energy!"), type = MESSAGE_TYPE_COMBAT)
playsound(defender, 'sound/weapons/punch1.ogg', 25, TRUE, -1)
log_combat(attacker, defender, "god fist (The Tunnel Arts))")
defender.apply_damage(30, attacker.get_attack_type(), affecting)
@@ -94,10 +98,9 @@
span_danger("[attacker] punches [defender] with a rapid series of blows!"),
span_userdanger("[attacker] rapidly punches you!"),
span_hear("You hear a sickening sound of flesh hitting flesh!"),
- null,
- attacker,
+ ignored_mobs = list(attacker),
)
- to_chat(attacker, span_danger("You rapidly punch [defender]!"))
+ to_chat(attacker, span_danger("You rapidly punch [defender]!"), type = MESSAGE_TYPE_COMBAT)
// Borrows this trick from standard holoparsites
for(var/sounds in 1 to 4)
@@ -109,18 +112,17 @@
if(!defender.mind || defender.stat != CONSCIOUS || prob(50))
return TRUE
- var/mob/living/simple_animal/hostile/illusion/khan = new(attacker.loc)
+ var/mob/living/simple_animal/hostile/illusion/khan_warrior/khan = new(attacker.loc)
khan.faction = attacker.faction.Copy()
- khan.Copy_Parent(attacker, 100, attacker.health/2.5, 12, 30)
+ khan.Copy_Parent(attacker, 100, attacker.health / 2.5, 12, 30)
khan.GiveTarget(defender)
attacker.visible_message(
span_danger("[attacker] seems to duplicate before your very eyes!"),
span_userdanger("[attacker] seems to duplicate before your eyes!"),
span_hear("You hear a multitude of stamping feet!"),
- null,
- attacker,
+ ignored_mobs = list(attacker),
)
- to_chat(attacker, span_danger("You conjure an illusionary warrior to fight with you!"))
+ to_chat(attacker, span_danger("You conjure an illusionary warrior to fight with you!"), type = MESSAGE_TYPE_COMBAT)
return TRUE
/// Echo our punching sounds
@@ -153,7 +155,7 @@
span_hear("You hear a sickening snap!"),
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))
@@ -179,8 +181,8 @@
log_combat(attacker, defender, "disarmed (The Tunnel Arts)")
return MARTIAL_ATTACK_INVALID // normal disarm
-/datum/martial_art/the_tunnel_arts/proc/check_usability(mob/living/khan_user)
- if(!(khan_user.istate & ISTATE_HARM)) // monke edit: istates/intents
+/datum/martial_art/the_tunnel_arts/proc/check_usability(mob/living/khan_user, check_intent = TRUE)
+ if(check_intent && !(khan_user.istate & ISTATE_HARM))
return FALSE
if(khan_user.incapacitated(IGNORE_GRAB)) //NO STUN
return FALSE
@@ -194,12 +196,11 @@
return TRUE
///Signal from getting attacked with an item, for a special interaction with touch spells
-/datum/martial_art/the_tunnel_arts/proc/on_attackby(mob/living/khan_user, obj/item/attack_weapon, mob/attacker, params)
+/datum/martial_art/the_tunnel_arts/proc/on_attackby(mob/living/khan_user, obj/item/melee/touch_attack/touch_weapon, mob/attacker, params)
SIGNAL_HANDLER
- if(!istype(attack_weapon, /obj/item/melee/touch_attack) || !check_usability(khan_user))
+ if(!istype(touch_weapon) || !check_usability(khan_user, check_intent = !touch_weapon.dangerous))
return
- var/obj/item/melee/touch_attack/touch_weapon = attack_weapon
khan_user.visible_message(
span_danger("[khan_user] carefully dodges [attacker]'s [touch_weapon]!"),
span_userdanger("You take great care to remain untouched by [attacker]'s [touch_weapon]!"),
@@ -207,6 +208,7 @@
)
to_chat(attacker, span_userdanger("[khan_user] carefully dodges your [touch_weapon], remaining completely untouched!"), type = MESSAGE_TYPE_COMBAT)
khan_user.balloon_alert(attacker, "miss!")
+ attacker.changeNext_move(CLICK_CD_MELEE)
playsound(khan_user, 'monkestation/sound/effects/miss.ogg', vol = 50, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE)
return COMPONENT_NO_AFTERATTACK
@@ -216,12 +218,15 @@
set desc = "Remember the martial techniques of Maint Khan, who brought to the Spinward Sector the knowledge of the Tunnel Arts."
set category = "The Tunnel Arts"
- to_chat(usr, "You retreat inward and recall the teachings of the Tunnel Arts...\n\
+ to_chat(src, "You retreat inward and recall the teachings of the Tunnel Arts...\n\
[span_notice("One Thousand Fists")]: Punch Punch. Deal additional damage every second (consecutive) punch, and potentially conjure forth an illusionary Khan Warrior.\n\
[span_notice("Chaos Reigns")]: Shove Punch. Launch your opponent away from you and corrupt their Chi energy, causing them to flail madly in their confused state!\n\
[span_notice("Space Wind God Fist")]: Punch Shove. Send the target spinning helplessly through the air with this vicious uppercut.\n\
While in throw mode (and not stunned, not a hulk, and not in a mech), you can block various attacks against you in melee with your bare hands!")
+/mob/living/simple_animal/hostile/illusion/khan_warrior
+ speed = 0
+
#undef SPACE_WIND_GOD_FIST_COMBO
#undef CHAOS_REIGNS_COMBO
#undef ONE_THOUSAND_FISTS_COMBO
diff --git a/monkestation/code/modules/spells/spell_types/touch/_touch.dm b/monkestation/code/modules/spells/spell_types/touch/_touch.dm
new file mode 100644
index 000000000000..e5b3f8957ced
--- /dev/null
+++ b/monkestation/code/modules/spells/spell_types/touch/_touch.dm
@@ -0,0 +1,7 @@
+/obj/item/melee/touch_attack
+ /// If this touch attack is "dangerous" - this is used for martial arts bypassing intent checks.
+ /// This should only be FALSE for benign / non-antag attacks, to prevent metagaming by randomly shock touching people to see if they have martial arts.
+ var/dangerous = TRUE
+
+/obj/item/melee/touch_attack/shock
+ dangerous = FALSE
diff --git a/tgstation.dme b/tgstation.dme
index d05c0f077771..cfa866c8d0ee 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -5996,7 +5996,6 @@
#include "monkestation\code\datums\keybinding\communication.dm"
#include "monkestation\code\datums\keybinding\living.dm"
#include "monkestation\code\datums\looping_sounds\weather.dm"
-#include "monkestation\code\datums\martial_arts\awakened_dragon.dm"
#include "monkestation\code\datums\memory\key_memories.dm"
#include "monkestation\code\datums\mind\_mind.dm"
#include "monkestation\code\datums\mocking\client.dm"
@@ -7516,6 +7515,7 @@
#include "monkestation\code\modules\mapping\access_helpers.dm"
#include "monkestation\code\modules\mapping\mapping_helpers.dm"
#include "monkestation\code\modules\maptext\maptext_image_helper.dm"
+#include "monkestation\code\modules\martial_arts\awakened_dragon.dm"
#include "monkestation\code\modules\martial_arts\tribal_claw.dm"
#include "monkestation\code\modules\martial_arts\tunnel_arts.dm"
#include "monkestation\code\modules\martial_arts\granters\tribal_claw_gr.dm"
@@ -8219,6 +8219,7 @@
#include "monkestation\code\modules\spells\spell_types\conjure_item\summon_mjollnir.dm"
#include "monkestation\code\modules\spells\spell_types\pointed\fire_ball.dm"
#include "monkestation\code\modules\spells\spell_types\pointed\smite.dm"
+#include "monkestation\code\modules\spells\spell_types\touch\_touch.dm"
#include "monkestation\code\modules\store\admin\admin_coin_modification.dm"
#include "monkestation\code\modules\store\atm\_atm.dm"
#include "monkestation\code\modules\store\pre_round\_pre_round_store.dm"