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"