From 229cf3e34495bdc8ab7ea9bfef1e03a40173393c Mon Sep 17 00:00:00 2001 From: farie82 Date: Fri, 18 Sep 2020 17:07:19 +0200 Subject: [PATCH] Martial arts rework/refactor. And you can't prepare combos now. Arts tied to the mind (#13341) * first commit. combos, CQC started * CQC working * All transfered to new system * The actual bug fix * add time in between combos * time between combos limit and minor explaination tweak * Krav maga fixes, time change. Minor text changes * Move martial_art to mind * Merge mistake fixed * Steels review changes --- code/__DEFINES/martial_arts.dm | 16 ++ code/datums/mind.dm | 1 + .../items/weapons/highlander_swords.dm | 8 +- .../weapons/implants/implant_krav_maga.dm | 6 +- code/modules/martial_arts/adminfu.dm | 80 ++------ .../combos/adminfu/healing_palm.dm | 38 ++++ .../martial_arts/combos/cqc/consecutive.dm | 18 ++ code/modules/martial_arts/combos/cqc/kick.dm | 24 +++ .../martial_arts/combos/cqc/pressure.dm | 11 ++ .../martial_arts/combos/cqc/restrain.dm | 22 +++ code/modules/martial_arts/combos/cqc/slam.dm | 16 ++ .../combos/krav_maga/leg_sweep.dm | 14 ++ .../combos/krav_maga/lung_punch.dm | 12 ++ .../combos/krav_maga/neck_chop.dm | 12 ++ .../martial_arts/combos/martial_combo.dm | 36 ++++ .../combos/mimejutsu/mimechucks.dm | 26 +++ .../combos/mimejutsu/silent_palm.dm | 13 ++ .../combos/mimejutsu/smokebomb.dm | 13 ++ .../combos/plasma_fist/plasma_fist.dm | 13 ++ .../combos/plasma_fist/throwback.dm | 13 ++ .../combos/plasma_fist/tornado_sweep.dm | 20 ++ .../combos/sleeping_carp/back_kick.dm | 18 ++ .../combos/sleeping_carp/elbow_drop.dm | 18 ++ .../combos/sleeping_carp/head_kick.dm | 19 ++ .../combos/sleeping_carp/stomach_knee.dm | 20 ++ .../combos/sleeping_carp/wrist_wrench.dm | 20 ++ code/modules/martial_arts/cqc.dm | 176 ++---------------- code/modules/martial_arts/krav_maga.dm | 72 ++----- code/modules/martial_arts/martial.dm | 148 +++++++++++---- code/modules/martial_arts/mimejutsu.dm | 98 +--------- code/modules/martial_arts/plasma_fist.dm | 84 +-------- code/modules/martial_arts/sleeping_carp.dm | 136 +------------- .../{wrestleing.dm => wrestling.dm} | 0 code/modules/mob/living/carbon/human/human.dm | 18 +- .../mob/living/carbon/human/human_defense.dm | 2 +- .../mob/living/carbon/human/human_defines.dm | 3 - code/modules/mob/living/carbon/human/life.dm | 15 +- .../living/carbon/human/species/_species.dm | 5 +- .../hostile/megafauna/colossus.dm | 4 +- paradise.dme | 24 ++- 40 files changed, 648 insertions(+), 644 deletions(-) create mode 100644 code/__DEFINES/martial_arts.dm create mode 100644 code/modules/martial_arts/combos/adminfu/healing_palm.dm create mode 100644 code/modules/martial_arts/combos/cqc/consecutive.dm create mode 100644 code/modules/martial_arts/combos/cqc/kick.dm create mode 100644 code/modules/martial_arts/combos/cqc/pressure.dm create mode 100644 code/modules/martial_arts/combos/cqc/restrain.dm create mode 100644 code/modules/martial_arts/combos/cqc/slam.dm create mode 100644 code/modules/martial_arts/combos/krav_maga/leg_sweep.dm create mode 100644 code/modules/martial_arts/combos/krav_maga/lung_punch.dm create mode 100644 code/modules/martial_arts/combos/krav_maga/neck_chop.dm create mode 100644 code/modules/martial_arts/combos/martial_combo.dm create mode 100644 code/modules/martial_arts/combos/mimejutsu/mimechucks.dm create mode 100644 code/modules/martial_arts/combos/mimejutsu/silent_palm.dm create mode 100644 code/modules/martial_arts/combos/mimejutsu/smokebomb.dm create mode 100644 code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm create mode 100644 code/modules/martial_arts/combos/plasma_fist/throwback.dm create mode 100644 code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm create mode 100644 code/modules/martial_arts/combos/sleeping_carp/back_kick.dm create mode 100644 code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm create mode 100644 code/modules/martial_arts/combos/sleeping_carp/head_kick.dm create mode 100644 code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm create mode 100644 code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm rename code/modules/martial_arts/{wrestleing.dm => wrestling.dm} (100%) diff --git a/code/__DEFINES/martial_arts.dm b/code/__DEFINES/martial_arts.dm new file mode 100644 index 00000000000..4eb139cc44a --- /dev/null +++ b/code/__DEFINES/martial_arts.dm @@ -0,0 +1,16 @@ +#define MARTIAL_COMBO_FAIL 0 // If the combo failed +#define MARTIAL_COMBO_CONTINUE 1 // If the combo should continue +#define MARTIAL_COMBO_DONE 2 // If the combo is successful and done +#define MARTIAL_COMBO_DONE_NO_CLEAR 3 // If the combo is successful and done but the others should have a chance to finish +#define MARTIAL_COMBO_DONE_BASIC_HIT 4 // If the combo should do a basic hit after it's done +#define MARTIAL_COMBO_DONE_CLEAR_COMBOS 5 // If the combo should do a basic hit after it's done + +#define MARTIAL_ARTS_CANNOT_USE -1 + +#define MARTIAL_COMBO_STEP_HARM "Harm" +#define MARTIAL_COMBO_STEP_DISARM "Disarm" +#define MARTIAL_COMBO_STEP_GRAB "Grab" +#define MARTIAL_COMBO_STEP_HELP "Help" + +// A check used for all act types. Such as disarm_act +#define MARTIAL_ARTS_ACT_CHECK if((. = ..()) != FALSE) return . diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 148d8e8276f..53230d1f83d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -35,6 +35,7 @@ var/list/restricted_roles = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. + var/datum/martial_art/martial_art var/role_alt_title diff --git a/code/game/objects/items/weapons/highlander_swords.dm b/code/game/objects/items/weapons/highlander_swords.dm index 330da6beba0..568b023d051 100644 --- a/code/game/objects/items/weapons/highlander_swords.dm +++ b/code/game/objects/items/weapons/highlander_swords.dm @@ -25,14 +25,14 @@ return ..() /obj/item/claymore/highlander/equipped(mob/user, slot) - if(!ishuman(user)) + if(!ishuman(user) || !user.mind) return var/mob/living/carbon/human/H = user if(slot == slot_r_hand || slot == slot_l_hand) - if(H.martial_art && H.martial_art != style) - style.teach(H, 1) + if(H.mind.martial_art && H.mind.martial_art != style) + style.teach(H, TRUE) to_chat(H, "THERE CAN ONLY BE ONE!") - else if(H.martial_art && H.martial_art == style) + else if(H.mind.martial_art && H.mind.martial_art == style) style.remove(H) var/obj/item/claymore/highlander/sword = H.is_in_hands(/obj/item/claymore/highlander) if(sword) diff --git a/code/game/objects/items/weapons/implants/implant_krav_maga.dm b/code/game/objects/items/weapons/implants/implant_krav_maga.dm index 3c2666f3d66..9c33f43950a 100644 --- a/code/game/objects/items/weapons/implants/implant_krav_maga.dm +++ b/code/game/objects/items/weapons/implants/implant_krav_maga.dm @@ -17,12 +17,12 @@ /obj/item/implant/krav_maga/activate() var/mob/living/carbon/human/H = imp_in - if(!ishuman(H)) + if(!ishuman(H) || !H.mind) return - if(istype(H.martial_art, /datum/martial_art/krav_maga)) + if(istype(H.mind.martial_art, /datum/martial_art/krav_maga)) style.remove(H) else - style.teach(H,1) + style.teach(H, TRUE) /obj/item/implanter/krav_maga name = "implanter (krav maga)" diff --git a/code/modules/martial_arts/adminfu.dm b/code/modules/martial_arts/adminfu.dm index 12436061e20..20f3c95f7b6 100644 --- a/code/modules/martial_arts/adminfu.dm +++ b/code/modules/martial_arts/adminfu.dm @@ -1,93 +1,37 @@ -///Adminfu -//Help act:Heal/revie GP //p is for help -//Disarm:Stun -//Grab:Neck -//Harm:Gib -#define HEAL_COMBO "GP" - /datum/martial_art/adminfu name = "Way of the Dancing Admin" - help_verb = /mob/living/carbon/human/proc/adminfu_help - -/datum/martial_art/adminfu/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,HEAL_COMBO)) - streak = "" - healPalm(A,D) - return 1 - return 0 + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/adminfu/healing_palm) /datum/martial_art/adminfu/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - + MARTIAL_ARTS_ACT_CHECK if(!D.stat)//do not kill what is dead... A.do_attack_animation(D) D.visible_message("[A] manifests a large glowing toolbox and shoves it in [D]'s chest!", \ "[A] shoves a mystical toolbox in your chest!") D.death() - return 1 + return TRUE /datum/martial_art/adminfu/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D) D.Weaken(25) D.Stun(25) - return 1 + return TRUE /datum/martial_art/adminfu/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A,1) if(G) G.state = GRAB_NECK + return TRUE -/datum/martial_art/adminfu/help_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("P",D) - if(check_streak(A,D)) - return 1 - -/datum/martial_art/adminfu/proc/healPalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D) - D.visible_message("[A] smacks [D] in the forehead!") - - //its the staff of healing code..hush - if(istype(D,/mob)) - var/old_stat = D.stat - if(isanimal(D) && D.stat == DEAD) - var/mob/living/simple_animal/O = D - var/mob/living/simple_animal/P = new O.type(O.loc) - P.real_name = O.real_name - P.name = O.name - if(O.mind) - O.mind.transfer_to(P) - else - P.key = O.key - qdel(O) - D = P - else - D.revive() - D.suiciding = 0 - if(!D.ckey) - for(var/mob/dead/observer/ghost in GLOB.player_list) - if(D.real_name == ghost.real_name) - ghost.reenter_corpse() - break - if(old_stat != DEAD) - to_chat(D, "You feel great!") - else - to_chat(D, "You rise with a start, you're alive!!!") - return 1 - -/mob/living/carbon/human/proc/adminfu_help() - set name = "Recall Teachings" - set desc = "Remember the way of the dancing admin." - set category = "Adminfu" - - to_chat(usr, "Grab: Automatic Neck Grab.") - to_chat(usr, "Disarm: Stun/weaken") - to_chat(usr, "Harm: Death.") - to_chat(usr, "Healing Palm::Combo:Grab,Help intent. Heals or revives a crature.") - +/datum/martial_art/adminfu/explaination_header(user) + to_chat(user, "Grab: Automatic Neck Grab.") + to_chat(user, "Disarm: Stun/weaken") + to_chat(user, "Harm: Death.") /obj/item/adminfu_scroll name = "frayed scroll" diff --git a/code/modules/martial_arts/combos/adminfu/healing_palm.dm b/code/modules/martial_arts/combos/adminfu/healing_palm.dm new file mode 100644 index 00000000000..c5bd34f1886 --- /dev/null +++ b/code/modules/martial_arts/combos/adminfu/healing_palm.dm @@ -0,0 +1,38 @@ +/datum/martial_combo/adminfu/healing_palm + name = "Healing Palm" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HELP) + explaination_text = "Heals or revives a creature." + combo_text_override = "Grab, switch hands, Help" + +/datum/martial_combo/adminfu/healing_palm/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.do_attack_animation(target) + target.visible_message("[user] smacks [target] in the forehead!") + + //its the staff of healing code..hush + if(istype(target,/mob)) + var/old_stat = target.stat + if(isanimal(target) && target.stat == DEAD) + var/mob/living/simple_animal/O = target + var/mob/living/simple_animal/P = new O.type(O.loc) + P.real_name = O.real_name + P.name = O.name + if(O.mind) + O.mind.transfer_to(P) + else + P.key = O.key + qdel(O) + target = P + else + target.revive() + target.suiciding = 0 + if(!target.ckey) + for(var/mob/dead/observer/ghost in GLOB.player_list) + if(target.real_name == ghost.real_name) + ghost.reenter_corpse() + break + if(old_stat != DEAD) + to_chat(target, "You feel great!") + else + to_chat(target, "You rise with a start, you're alive!!!") + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/consecutive.dm b/code/modules/martial_arts/combos/cqc/consecutive.dm new file mode 100644 index 00000000000..b513c8191e4 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/consecutive.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/cqc/consecutive + name = "Consecutive CQC" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Mainly offensive move, huge damage and decent stamina damage." + +/datum/martial_combo/cqc/consecutive/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat) + target.visible_message("[user] strikes [target]'s abdomen, neck and back consecutively", \ + "[user] strikes your abdomen, neck and back consecutively!") + playsound(get_turf(target), 'sound/weapons/cqchit2.ogg', 50, 1, -1) + var/obj/item/I = target.get_active_hand() + if(I && target.drop_item()) + user.put_in_hands(I) + target.adjustStaminaLoss(50) + target.apply_damage(25, BRUTE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/kick.dm b/code/modules/martial_arts/combos/cqc/kick.dm new file mode 100644 index 00000000000..887a51b049d --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/kick.dm @@ -0,0 +1,24 @@ +/datum/martial_combo/cqc/kick + name = "CQC Kick" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks opponent away. Knocks out stunned or knocked down opponents." + +/datum/martial_combo/cqc/kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + . = MARTIAL_COMBO_FAIL + if(!target.stat || !target.IsWeakened()) + target.visible_message("[user] kicks [target] back!", \ + "[user] kicks you back!") + playsound(get_turf(user), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + var/atom/throw_target = get_edge_target_turf(target, user.dir) + target.throw_at(throw_target, 1, 14, user) + target.apply_damage(10, BRUTE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) + . = MARTIAL_COMBO_DONE + if(target.IsWeakened() && !target.stat) + target.visible_message("[user] kicks [target]'s head, knocking [target.p_them()] out!", \ + "[user] kicks your head, knocking you out!") + playsound(get_turf(user), 'sound/weapons/genhit1.ogg', 50, 1, -1) + target.SetSleeping(15) + target.adjustBrainLoss(15) + add_attack_logs(user, target, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) + . = MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/cqc/pressure.dm b/code/modules/martial_arts/combos/cqc/pressure.dm new file mode 100644 index 00000000000..b19bfb6ddf7 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/pressure.dm @@ -0,0 +1,11 @@ +/datum/martial_combo/cqc/pressure + name = "Pressure" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Decent stamina damage." + +/datum/martial_combo/cqc/pressure/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] forces their arm on [target]'s neck!") + target.adjustStaminaLoss(60) + playsound(get_turf(user), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Pressure", ATKLOG_ALL) + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/cqc/restrain.dm b/code/modules/martial_arts/combos/cqc/restrain.dm new file mode 100644 index 00000000000..e9495c61dba --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/restrain.dm @@ -0,0 +1,22 @@ +/datum/martial_combo/cqc/restrain + name = "Restrain" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Locks opponents into a restraining position, disarm to knock them out with a choke hold." + combo_text_override = "Grab, switch hands, Grab" + +/datum/martial_combo/cqc/restrain/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + var/datum/martial_art/cqc/CQC = MA + if(!istype(CQC)) + return MARTIAL_COMBO_FAIL + if(CQC.restraining) + return MARTIAL_COMBO_FAIL + if(!target.stat) + target.visible_message("[user] locks [target] into a restraining position!", \ + "[user] locks you into a restraining position!") + target.adjustStaminaLoss(20) + target.Stun(5) + CQC.restraining = TRUE + addtimer(CALLBACK(CQC, /datum/martial_art/cqc/.proc/drop_restraining), 50, TIMER_UNIQUE) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/cqc/slam.dm b/code/modules/martial_arts/combos/cqc/slam.dm new file mode 100644 index 00000000000..8c1a84d7817 --- /dev/null +++ b/code/modules/martial_arts/combos/cqc/slam.dm @@ -0,0 +1,16 @@ +/datum/martial_combo/cqc/slam + name = "Slam" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Slam opponent into the ground, knocking them down." + combo_text_override = "Grab, switch hands, Harm" + +/datum/martial_combo/cqc/slam/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.IsWeakened() && !target.resting && !target.lying) + target.visible_message("[user] slams [target] into the ground!", \ + "[user] slams you into the ground!") + playsound(get_turf(user), 'sound/weapons/slam.ogg', 50, 1, -1) + target.apply_damage(10, BRUTE) + target.Weaken(6) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_FAIL diff --git a/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm b/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm new file mode 100644 index 00000000000..0defb3e9eff --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/leg_sweep.dm @@ -0,0 +1,14 @@ +/datum/martial_combo/krav_maga/leg_sweep + name = "Leg Sweep" + explaination_text = "Trips the victim, rendering them prone and unable to move for a short time." + +/datum/martial_combo/krav_maga/leg_sweep/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(target.stat || target.IsWeakened()) + return FALSE + target.visible_message("[user] leg sweeps [target]!", \ + "[user] leg sweeps you!") + playsound(get_turf(user), 'sound/effects/hit_kick.ogg', 50, 1, -1) + target.apply_damage(5, BRUTE) + target.Weaken(2) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Leg Sweep", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/krav_maga/lung_punch.dm b/code/modules/martial_arts/combos/krav_maga/lung_punch.dm new file mode 100644 index 00000000000..e71289f9174 --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/lung_punch.dm @@ -0,0 +1,12 @@ +/datum/martial_combo/krav_maga/lung_punch + name = "Lung Punch" + explaination_text = "Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time." + +/datum/martial_combo/krav_maga/lung_punch/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] pounds [target] on the chest!", \ + "[user] slams your chest! You can't breathe!") + playsound(get_turf(user), 'sound/effects/hit_punch.ogg', 50, 1, -1) + target.AdjustLoseBreath(5) + target.adjustOxyLoss(10) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Lung Punch", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/krav_maga/neck_chop.dm b/code/modules/martial_arts/combos/krav_maga/neck_chop.dm new file mode 100644 index 00000000000..c0e2f71b6a5 --- /dev/null +++ b/code/modules/martial_arts/combos/krav_maga/neck_chop.dm @@ -0,0 +1,12 @@ +/datum/martial_combo/krav_maga/neck_chop + name = "Neck Chop" + explaination_text = "Injures the neck, stopping the victim from speaking for a while." + +/datum/martial_combo/krav_maga/neck_chop/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] karate chops [target]'s neck!", \ + "[user] karate chops your neck, rendering you unable to speak for a short time!") + playsound(get_turf(user), 'sound/effects/hit_punch.ogg', 50, 1, -1) + target.apply_damage(5, BRUTE) + target.AdjustSilence(10) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Neck Chop", ATKLOG_ALL) + return MARTIAL_COMBO_DONE_CLEAR_COMBOS diff --git a/code/modules/martial_arts/combos/martial_combo.dm b/code/modules/martial_arts/combos/martial_combo.dm new file mode 100644 index 00000000000..6b4eedb97dc --- /dev/null +++ b/code/modules/martial_arts/combos/martial_combo.dm @@ -0,0 +1,36 @@ +/datum/martial_combo + /// Name used to explain the combo + var/name = "Code Fu" + /// Which steps need to be performed + var/list/steps + /// What index to check + var/current_step_index = 1 + /// Who is the target the combo is being executed on + var/current_combo_target = null + /// If you require to do the combo's on the same target + var/combos_require_same_target = TRUE + /// What does it do + var/explaination_text = "Ability to break shit" + /// How to do the combo. If null it'll auto generate it from the steps + var/combo_text_override + +/datum/martial_combo/proc/check_combo(step, mob/living/target) + if(!combos_require_same_target || current_combo_target == null || current_combo_target == target) + if(!length(steps) || step == steps[current_step_index]) + return TRUE + return FALSE + +/datum/martial_combo/proc/progress_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + current_combo_target = target + if(current_step_index++ >= LAZYLEN(steps)) + return perform_combo(user, target, MA) + return MARTIAL_COMBO_CONTINUE + +/datum/martial_combo/proc/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + return MARTIAL_COMBO_FAIL // Override this + +/datum/martial_combo/proc/give_explaination(user) + var/final_combo_text = combo_text_override + if(!final_combo_text) + final_combo_text = english_list(steps, and_text = " ", comma_text = " ") + to_chat(user, "[name]: [final_combo_text]. [explaination_text]") diff --git a/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm b/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm new file mode 100644 index 00000000000..b7f2d247b4b --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/mimechucks.dm @@ -0,0 +1,26 @@ +/datum/martial_combo/mimejutsu/mimechucks + name = "Mimechucks" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Hits the opponent with invisible nunchucks." + +/datum/martial_combo/mimejutsu/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + var/damage = rand(5, 8) + user.dna.species.punchdamagelow + if(!damage) + playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + target.visible_message("[user] swings invisible nunchcuks at [target]..and misses?") + return MARTIAL_COMBO_DONE + + + var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_selected)) + var/armor_block = target.run_armor_check(affecting, "melee") + + target.visible_message("[user] has hit [target] with invisible nunchucks!", \ + "[user] has hit [target] with a with invisible nunchuck!") + playsound(get_turf(user), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + + target.apply_damage(damage, STAMINA, affecting, armor_block) + add_attack_logs(user, target, "Melee attacked with [src] (mimechuck)") + + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm b/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm new file mode 100644 index 00000000000..eb8df68fac4 --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/silent_palm.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/mimejutsu/silent_palm + name = "Silent Palm" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Use mime energy to throw someone back." + +/datum/martial_combo/mimejutsu/silent_palm/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + target.visible_message("[user] has barely touched [target] with [user.p_their()] palm!", \ + "[user] hovers [user.p_their()] palm over your face!") + + var/atom/throw_target = get_edge_target_turf(target, get_dir(target, get_step_away(target, user))) + target.throw_at(throw_target, 200, 4, user) + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm b/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm new file mode 100644 index 00000000000..23277fa5f0d --- /dev/null +++ b/code/modules/martial_arts/combos/mimejutsu/smokebomb.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/mimejutsu/smokebomb + name = "Smokebomb" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Drops a mime smokebomb." + +/datum/martial_combo/mimejutsu/smokebomb/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] throws an invisible smoke bomb!!") + + var/datum/effect_system/smoke_spread/bad/smoke = new + smoke.set_up(5, 0, target.loc) + smoke.start() + + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm b/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm new file mode 100644 index 00000000000..93c3e3ef480 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/plasma_fist.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/plasma_fist/plasma_fist + name = "The Plasma Fist" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks the brain out of the opponent and gibs their body." + +/datum/martial_combo/plasma_fist/plasma_fist/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + playsound(target.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + user.say("PLASMA FIST!") + target.visible_message("[user] has hit [target] with THE PLASMA FIST TECHNIQUE!", \ + "[user] has hit [target] with THE PLASMA FIST TECHNIQUE!") + target.gib() + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/plasma_fist/throwback.dm b/code/modules/martial_arts/combos/plasma_fist/throwback.dm new file mode 100644 index 00000000000..7057452a913 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/throwback.dm @@ -0,0 +1,13 @@ +/datum/martial_combo/plasma_fist/throwback + name = "Throwback" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Throws the target and an item at them." + +/datum/martial_combo/plasma_fist/throwback/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + target.visible_message("[user] has hit [target] with Plasma Punch!", \ + "[user] has hit [target] with Plasma Punch!") + playsound(target.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + var/atom/throw_target = get_edge_target_turf(target, get_dir(target, get_step_away(target, user))) + target.throw_at(throw_target, 200, 4, user) + user.say("HYAH!") + return MARTIAL_COMBO_DONE diff --git a/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm new file mode 100644 index 00000000000..41a7bd676d3 --- /dev/null +++ b/code/modules/martial_arts/combos/plasma_fist/tornado_sweep.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/plasma_fist/tornado_sweep + name = "Tornado Sweep" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Repulses target and everyone back." + +/datum/martial_combo/plasma_fist/tornado_sweep/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + user.say("TORNADO SWEEP!") + INVOKE_ASYNC(src, .proc/do_tornado_effect, user) + var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null) + var/list/turfs = list() + for(var/turf/T in range(1,user)) + turfs.Add(T) + R.cast(turfs) + return MARTIAL_COMBO_DONE + +/datum/martial_combo/plasma_fist/tornado_sweep/proc/do_tornado_effect(mob/living/carbon/human/user) + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + user.dir = i + playsound(user.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) + sleep(1) diff --git a/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm b/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm new file mode 100644 index 00000000000..3ebaa191e23 --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/back_kick.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/sleeping_carp/back_kick + name = "Back Kick" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_GRAB) + explaination_text = "Opponent must be facing away. Knocks down." + +/datum/martial_combo/sleeping_carp/back_kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(user.dir == target.dir && !target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] kicks [target] in the back!", \ + "[user] kicks you in the back, making you stumble and fall!") + step_to(target,get_step(target,target.dir),1) + target.Weaken(4) + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Back Kick", ATKLOG_ALL) + if(prob(80)) + user.say(pick("SURRPRIZU!","BACK STRIKE!","WOPAH!", "WATAAH", "ZOTA!", "Never turn your back to the enemy!")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm b/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm new file mode 100644 index 00000000000..0269c9bed4d --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/elbow_drop.dm @@ -0,0 +1,18 @@ +/datum/martial_combo/sleeping_carp/elbow_drop + name = "Elbow Drop" + steps = list(MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition." + +/datum/martial_combo/sleeping_carp/elbow_drop/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(target.IsWeakened() || target.resting || target.stat) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + target.visible_message("[user] elbow drops [target]!", \ + "[user] piledrives you with [user.p_their()] elbow!") + target.death() //FINISH HIM! + target.apply_damage(50, BRUTE, "chest") + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 75, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Elbow Drop", ATKLOG_ALL) + if(prob(80)) + user.say(pick("BANZAIII!", "KIYAAAA!", "OMAE WA MOU SHINDEIRU!", "YOU CAN'T SEE ME!", "MY TIME IS NOW!", "COWABUNGA")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm b/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm new file mode 100644 index 00000000000..b45e10e73ce --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/head_kick.dm @@ -0,0 +1,19 @@ +/datum/martial_combo/sleeping_carp/head_kick + name = "Head Kick" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_HARM, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Decent damage, forces opponent to drop item in hand." + +/datum/martial_combo/sleeping_carp/head_kick/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] kicks [target] in the head!", \ + "[user] kicks you in the jaw!") + target.apply_damage(20, BRUTE, "head") + target.drop_item() + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Head Kick", ATKLOG_ALL) + if(prob(60)) + user.say(pick("OOHYOO!", "OOPYAH!", "HYOOAA!", "WOOAAA!", "SHURYUKICK!", "HIYAH!")) + target.Stun(4) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm b/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm new file mode 100644 index 00000000000..312e575003d --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/stomach_knee.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/sleeping_carp/stomach_knee + name = "Stomach Knee" + steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_HARM) + explaination_text = "Knocks the wind out of opponent and stuns." + combo_text_override = "Grab, switch hands, Harm" + +/datum/martial_combo/sleeping_carp/stomach_knee/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_KICK) + target.visible_message("[user] knees [target] in the stomach!", \ + "[user] winds you with a knee in the stomach!") + target.audible_message("[target] gags!") + target.AdjustLoseBreath(3) + target.Stun(2) + playsound(get_turf(target), 'sound/weapons/punch1.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Stomach Knee", ATKLOG_ALL) + if(prob(80)) + user.say(pick("HWOP!", "KUH!", "YAKUUH!", "KYUH!", "KNEESTRIKE!")) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm b/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm new file mode 100644 index 00000000000..38c21e7309e --- /dev/null +++ b/code/modules/martial_arts/combos/sleeping_carp/wrist_wrench.dm @@ -0,0 +1,20 @@ +/datum/martial_combo/sleeping_carp/wrist_wrench + name = "Wrist Wrench" + steps = list(MARTIAL_COMBO_STEP_DISARM, MARTIAL_COMBO_STEP_DISARM) + explaination_text = "Forces opponent to drop item in hand." + +/datum/martial_combo/sleeping_carp/wrist_wrench/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA) + if(!target.stat && !target.stunned && !target.IsWeakened()) + user.do_attack_animation(target, ATTACK_EFFECT_PUNCH) + target.visible_message("[user] grabs [target]'s wrist and wrenches it sideways!", \ + "[user] grabs your wrist and violently wrenches it to the side!") + playsound(get_turf(user), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + add_attack_logs(user, target, "Melee attacked with martial-art [src] : Wrist Wrench", ATKLOG_ALL) + if(prob(60)) + user.say(pick("WRISTY TWIRLY!", "WE FIGHT LIKE MEN!", "YOU DISHONOR YOURSELF!", "POHYAH!", "WHERE IS YOUR BATON NOW?", "SAY UNCLE!")) + target.emote("scream") + target.drop_item() + target.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) + target.Stun(3) + return MARTIAL_COMBO_DONE + return MARTIAL_COMBO_DONE_BASIC_HIT diff --git a/code/modules/martial_arts/cqc.dm b/code/modules/martial_arts/cqc.dm index f0b5c016c5b..49a08c1bd3c 100644 --- a/code/modules/martial_arts/cqc.dm +++ b/code/modules/martial_arts/cqc.dm @@ -1,152 +1,27 @@ -#define SLAM_COMBO "GH" -#define KICK_COMBO "HH" -#define RESTRAIN_COMBO "GG" -#define PRESSURE_COMBO "DG" -#define CONSECUTIVE_COMBO "DDH" - /datum/martial_art/cqc name = "CQC" - help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 - var/just_a_cook = FALSE + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/cqc/slam, /datum/martial_combo/cqc/kick, /datum/martial_combo/cqc/restrain, /datum/martial_combo/cqc/pressure, /datum/martial_combo/cqc/consecutive) + var/restraining = FALSE //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not var/static/list/areas_under_siege = typecacheof(list(/area/crew_quarters/kitchen, /area/crew_quarters/cafeteria, /area/crew_quarters/bar)) /datum/martial_art/cqc/under_siege name = "Close Quarters Cooking" - just_a_cook = TRUE + +/datum/martial_art/cqc/under_siege/can_use(mob/living/carbon/human/H) + var/area/A = get_area(H) + if(!(is_type_in_typecache(A, areas_under_siege))) + return FALSE + return ..() /datum/martial_art/cqc/proc/drop_restraining() restraining = FALSE -/datum/martial_art/cqc/can_use(mob/living/carbon/human/H) - var/area/A = get_area(H) - if(just_a_cook && !(is_type_in_typecache(A, areas_under_siege))) - return FALSE - return ..() - -/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(findtext(streak, SLAM_COMBO)) - streak = "" - Slam(A, D) - return TRUE - if(findtext(streak, KICK_COMBO)) - streak = "" - Kick(A, D) - return TRUE - if(findtext(streak, RESTRAIN_COMBO)) - streak = "" - Restrain(A, D) - return TRUE - if(findtext(streak, PRESSURE_COMBO)) - streak = "" - Pressure(A, D) - return TRUE - if(findtext(streak, CONSECUTIVE_COMBO)) - streak = "" - Consecutive(A, D) - return FALSE - -/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(!D.IsWeakened() && !D.resting && !D.lying) - D.visible_message("[A] slams [D] into the ground!", \ - "[A] slams you into the ground!") - playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1) - D.apply_damage(10, BRUTE) - D.Weaken(6) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Slam", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - var/success = FALSE - if(!D.stat || !D.IsWeakened()) - D.visible_message("[A] kicks [D] back!", \ - "[A] kicks you back!") - playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - var/atom/throw_target = get_edge_target_turf(D, A.dir) - D.throw_at(throw_target, 1, 14, A) - D.apply_damage(10, BRUTE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Kick", ATKLOG_ALL) - success = TRUE - if(D.IsWeakened() && !D.stat) - D.visible_message("[A] kicks [D]'s head, knocking [D.p_them()] out!", \ - "[A] kicks your head, knocking you out!") - playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1) - D.SetSleeping(15) - D.adjustBrainLoss(15) - add_attack_logs(A, D, "Knocked out with martial-art [src] : Kick", ATKLOG_ALL) - success = TRUE - if(success) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - D.visible_message("[A] forces their arm on [D]'s neck!") - D.adjustStaminaLoss(60) - playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Pressure", ATKLOG_ALL) - return TRUE - -/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(restraining) - return - if(!can_use(A)) - return FALSE - if(!D.stat) - D.visible_message("[A] locks [D] into a restraining position!", \ - "[A] locks you into a restraining position!") - D.adjustStaminaLoss(20) - D.Stun(5) - restraining = TRUE - addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Restrain", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - -/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - if(!D.stat) - D.visible_message("[A] strikes [D]'s abdomen, neck and back consecutively", \ - "[A] strikes your abdomen, neck and back consecutively!") - playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) - var/obj/item/I = D.get_active_hand() - if(I && D.drop_item()) - A.put_in_hands(I) - D.adjustStaminaLoss(50) - D.apply_damage(25, BRUTE) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Consecutive", ATKLOG_ALL) - return TRUE - streak = "" - harm_act(A, D) - streak = "" - return TRUE - /datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("G", D) - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A, 1) if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab @@ -155,11 +30,7 @@ return TRUE /datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("H", D) - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK add_attack_logs(A, D, "Melee attacked with martial-art [src]", ATKLOG_ALL) A.do_attack_animation(D) var/picked_hit_type = pick("CQC'd", "neck chopped", "gut punched", "Big Bossed") @@ -185,12 +56,7 @@ return TRUE /datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!can_use(A)) - return FALSE - add_to_streak("D", D) - var/obj/item/I = null - if(check_streak(A, D)) - return TRUE + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = A.get_inactive_hand() if(restraining && istype(G) && G.affecting == D) D.visible_message("[A] puts [D] into a chokehold!", \ @@ -203,6 +69,8 @@ else restraining = FALSE + var/obj/item/I = null + if(prob(65)) if(!D.stat || !D.IsWeakened() || !restraining) I = D.get_active_hand() @@ -220,16 +88,8 @@ add_attack_logs(A, D, "Melee attacked with martial-art [src] : Disarmed [I ? " grabbing \the [I]" : ""]", ATKLOG_ALL) return TRUE -/mob/living/carbon/human/proc/CQC_help() - set name = "Remember The Basics" - set desc = "You try to remember some of the basics of CQC." - set category = "CQC" - to_chat(usr, "You try to remember some of the basics of CQC.") +/datum/martial_art/cqc/explaination_header(user) + to_chat(user, "You try to remember some of the basics of CQC.") - to_chat(usr, "Slam: Grab, switch hands, Harm. Slam opponent into the ground, knocking them down.") - to_chat(usr, "CQC Kick: Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.") - to_chat(usr, "Restrain: Grab, switch hands, Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.") - to_chat(usr, "Pressure: Disarm Grab. Decent stamina damage.") - to_chat(usr, "Consecutive CQC: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.") - - to_chat(usr, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") +/datum/martial_art/cqc/explaination_footer(user) + to_chat(user, "In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.") diff --git a/code/modules/martial_arts/krav_maga.dm b/code/modules/martial_arts/krav_maga.dm index d348b3765fb..cd3a6214e83 100644 --- a/code/modules/martial_arts/krav_maga.dm +++ b/code/modules/martial_arts/krav_maga.dm @@ -15,7 +15,9 @@ to_chat(owner, "Your next attack will be a Neck Chop.") owner.visible_message("[owner] assumes the Neck Chop stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "neck_chop" + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/neck_chop) + H.mind.martial_art.reset_combos() /datum/action/leg_sweep name = "Leg Sweep - Trips the victim, rendering them prone and unable to move for a short time." @@ -28,7 +30,9 @@ to_chat(owner, "Your next attack will be a Leg Sweep.") owner.visible_message("[owner] assumes the Leg Sweep stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "leg_sweep" + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/leg_sweep) + H.mind.martial_art.reset_combos() /datum/action/lung_punch//referred to internally as 'quick choke' name = "Lung Punch - Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time." @@ -41,7 +45,9 @@ to_chat(owner, "Your next attack will be a Lung Punch.") owner.visible_message("[owner] assumes the Lung Punch stance!") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "quick_choke"//internal name for lung punch + H.mind.martial_art.combos.Cut() + H.mind.martial_art.combos.Add(/datum/martial_combo/krav_maga/lung_punch) + H.mind.martial_art.reset_combos() /datum/martial_art/krav_maga/teach(var/mob/living/carbon/human/H,var/make_temporary=0) ..() @@ -58,59 +64,8 @@ legsweep.Remove(H) lungpunch.Remove(H) -/datum/martial_art/krav_maga/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - switch(streak) - if("neck_chop") - streak = "" - neck_chop(A,D) - return 1 - if("leg_sweep") - streak = "" - leg_sweep(A,D) - return 1 - if("quick_choke")//is actually lung punch - streak = "" - quick_choke(A,D) - return 1 - return 0 - -/datum/martial_art/krav_maga/proc/leg_sweep(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.stat || D.IsWeakened()) - return 0 - D.visible_message("[A] leg sweeps [D]!", \ - "[A] leg sweeps you!") - playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1) - D.apply_damage(5, BRUTE) - D.Weaken(2) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Leg Sweep", ATKLOG_ALL) - return 1 - -/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch - D.visible_message("[A] pounds [D] on the chest!", \ - "[A] slams your chest! You can't breathe!") - playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) - D.AdjustLoseBreath(5) - D.adjustOxyLoss(10) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Lung Punch", ATKLOG_ALL) - return 1 - -/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - D.visible_message("[A] karate chops [D]'s neck!", \ - "[A] karate chops your neck, rendering you unable to speak for a short time!") - playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1) - D.apply_damage(5, BRUTE) - D.AdjustSilence(10) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Neck Chop", ATKLOG_ALL) - return 1 - -/datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 - ..() - /datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK add_attack_logs(A, D, "Melee attacked with [src]") var/picked_hit_type = pick("punches", "kicks") var/bonus_damage = 10 @@ -126,11 +81,10 @@ playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1) D.visible_message("[A] [picked_hit_type] [D]!", \ "[A] [picked_hit_type] you!") - return 1 + return TRUE /datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK if(prob(60)) if(D.hand) if(istype(D.l_hand, /obj/item)) @@ -149,7 +103,7 @@ D.visible_message("[A] attempted to disarm [D]!", \ "[A] attempted to disarm [D]!") playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - return 1 + return TRUE //Krav Maga Gloves diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm index 8969463be1d..50ca634a22f 100644 --- a/code/modules/martial_arts/martial.dm +++ b/code/modules/martial_arts/martial.dm @@ -1,42 +1,87 @@ +#define HAS_COMBOS LAZYLEN(combos) +#define COMBO_ALIVE_TIME 5 SECONDS // How long the combo stays alive when no new attack is done + /datum/martial_art var/name = "Martial Art" var/streak = "" var/max_streak_length = 6 - var/current_target = null - var/temporary = 0 + var/temporary = FALSE var/datum/martial_art/base = null // The permanent style var/deflection_chance = 0 //Chance to deflect projectiles var/block_chance = 0 //Chance to block melee attacks using items while on throw mode. - var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not var/help_verb = null var/no_guns = FALSE //set to TRUE to prevent users of this style from using guns (sleeping carp, highlander). They can still pick them up, but not fire them. var/no_guns_message = "" //message to tell the style user if they try and use a gun while no_guns = TRUE (DISHONORABRU!) -/datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 + var/has_explaination_verb = FALSE // If the martial art has it's own explaination verb -/datum/martial_art/proc/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 + var/list/combos = list() // What combos can the user do? List of combo types + var/list/datum/martial_art/current_combos = list() // What combos are currently (possibly) being performed + var/last_hit = 0 // When the last hit happened -/datum/martial_art/proc/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 +/datum/martial_art/New() + . = ..() + reset_combos() -/datum/martial_art/proc/help_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - return 0 +/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_DISARM, A, D) + +/datum/martial_art/proc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_HARM, A, D) + +/datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_GRAB, A, D) + +/datum/martial_art/proc/help_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + return act(MARTIAL_COMBO_STEP_HELP, A, D) /datum/martial_art/proc/can_use(mob/living/carbon/human/H) return TRUE -/datum/martial_art/proc/add_to_streak(var/element,var/mob/living/carbon/human/D) - if(D != current_target) - current_target = D - streak = "" - streak = streak+element - if(length(streak) > max_streak_length) - streak = copytext(streak,2) - return +/datum/martial_art/proc/act(step, mob/living/carbon/human/user, mob/living/carbon/human/target) + if(!can_use(user)) + return MARTIAL_ARTS_CANNOT_USE + if(last_hit + COMBO_ALIVE_TIME < world.time) + reset_combos() + last_hit = world.time -/datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) + if(HAS_COMBOS) + return check_combos(step, user, target) + return FALSE + +/datum/martial_art/proc/reset_combos() + current_combos.Cut() + for(var/combo_type in combos) + current_combos.Add(new combo_type()) + +/datum/martial_art/proc/check_combos(step, mob/living/carbon/human/user, mob/living/carbon/human/target) + . = FALSE + for(var/thing in current_combos) + var/datum/martial_combo/MC = thing + if(!MC.check_combo(step, target)) + current_combos -= MC // It failed so remove it + else + switch(MC.progress_combo(user, target, src)) + if(MARTIAL_COMBO_FAIL) + current_combos -= MC + if(MARTIAL_COMBO_DONE_NO_CLEAR) + . = TRUE + current_combos -= MC + if(MARTIAL_COMBO_DONE) + reset_combos() + return TRUE + if(MARTIAL_COMBO_DONE_BASIC_HIT) + basic_hit(user, target) + reset_combos() + return TRUE + if(MARTIAL_COMBO_DONE_CLEAR_COMBOS) + combos.Cut() + reset_combos() + return TRUE + if(!LAZYLEN(current_combos)) + reset_combos() + +/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A, mob/living/carbon/human/D) var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh) var/datum/unarmed_attack/attack = A.dna.species.unarmed @@ -54,7 +99,7 @@ if(!damage) playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") - return 0 + return FALSE var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_selected)) var/armor_block = D.run_armor_check(affecting, "melee") @@ -74,26 +119,60 @@ D.forcesay(GLOB.hit_appends) else if(D.lying) D.forcesay(GLOB.hit_appends) - return 1 + return TRUE -/datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) - if(help_verb) - H.verbs += help_verb +/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE) + if(!H.mind) + return + if(has_explaination_verb) + H.verbs |= /mob/living/carbon/human/proc/martial_arts_help if(make_temporary) - temporary = 1 + temporary = TRUE if(temporary) - if(H.martial_art) - base = H.martial_art.base + if(H.mind.martial_art) + base = H.mind.martial_art.base else base = src - H.martial_art = src + H.mind.martial_art = src /datum/martial_art/proc/remove(var/mob/living/carbon/human/H) - if(H.martial_art != src) + if(!H.mind) return - H.martial_art = base - if(help_verb) - H.verbs -= help_verb + if(H.mind.martial_art != src) + return + H.mind.martial_art = base + if(has_explaination_verb && !(base && base.has_explaination_verb)) + H.verbs -= /mob/living/carbon/human/proc/martial_arts_help + +/mob/living/carbon/human/proc/martial_arts_help() + set name = "Show Info" + set desc = "Gives information about the martial arts you know." + set category = "Martial Arts" + var/mob/living/carbon/human/H = usr + if(!istype(H)) + to_chat(usr, "You shouldn't have access to this verb. Report this as a bug to the github please.") + return + H.mind.martial_art.give_explaination(H) + +/datum/martial_art/proc/give_explaination(user = usr) + explaination_header(user) + explaination_combos(user) + explaination_footer(user) + +// Put after the header and before the footer in the explaination text +/datum/martial_art/proc/explaination_combos(user) + if(HAS_COMBOS) + for(var/combo_type in combos) + var/datum/martial_combo/MC = new combo_type() + MC.give_explaination(user) + +// Put on top of the explaination text +/datum/martial_art/proc/explaination_header(user) + return + +// Put below the combos in the explaination text +/datum/martial_art/proc/explaination_footer(user) + return //ITEMS @@ -283,3 +362,6 @@ if(wielded) return ..() return 0 + +#undef HAS_COMBOS +#undef COMBO_ALIVE_TIME diff --git a/code/modules/martial_arts/mimejutsu.dm b/code/modules/martial_arts/mimejutsu.dm index 38904d407de..d57df486638 100644 --- a/code/modules/martial_arts/mimejutsu.dm +++ b/code/modules/martial_arts/mimejutsu.dm @@ -1,90 +1,16 @@ -#define MIMECHUCKS_COMBO "DH" -#define MIMESMOKE_COMBO "DD" -#define MIMEPALM_COMBO "GD" - /datum/martial_art/mimejutsu name = "Mimejutsu" - help_verb = /mob/living/carbon/human/proc/mimejutsu_help - -/datum/martial_art/mimejutsu/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,MIMECHUCKS_COMBO)) - streak = "" - mimeChuck(A,D) - return 1 - if(findtext(streak,MIMESMOKE_COMBO)) - streak = "" - mimeSmoke(A,D) - return 1 - if(findtext(streak,MIMEPALM_COMBO)) - streak = "" - mimePalm(A,D) - return 1 - return 0 - -/datum/martial_art/mimejutsu/proc/mimeChuck(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - var/damage = rand(5, 8) + A.dna.species.punchdamagelow - if(!damage) - playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - D.visible_message("[A] swings invisible nunchcuks at [D]..and misses?") - return 0 - - - var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") - - D.visible_message("[A] has hit [D] with invisible nunchucks!", \ - "[A] has hit [D] with a with invisible nunchuck!") - playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - D.apply_damage(damage, STAMINA, affecting, armor_block) - add_attack_logs(A, D, "Melee attacked with [src] (mimechuck)") - - return 1 - return basic_hit(A,D) - -/datum/martial_art/mimejutsu/proc/mimeSmoke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - - D.visible_message("[A] throws an invisible smoke bomb!!") - - var/datum/effect_system/smoke_spread/bad/smoke = new - smoke.set_up(5, 0, D.loc) - smoke.start() - - return basic_hit(A,D) - -/datum/martial_art/mimejutsu/proc/mimePalm(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - D.visible_message("[A] has barely touched [D] with [A.p_their()] palm!", \ - "[A] hovers [A.p_their()] palm over your face!") - - var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) - D.throw_at(throw_target, 200, 4,A) - return basic_hit(A,D) - - -/datum/martial_art/mimejutsu/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 - - return ..() + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/mimejutsu/mimechucks, /datum/martial_combo/mimejutsu/smokebomb, /datum/martial_combo/mimejutsu/silent_palm) /datum/martial_art/mimejutsu/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 - - return 1 + MARTIAL_ARTS_ACT_CHECK + return TRUE /datum/martial_art/mimejutsu/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 - + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D) - - return 1 + return TRUE /obj/item/mimejutsu_scroll name = "Mimejutsu 'scroll'" @@ -106,13 +32,5 @@ name = "beret with staple" icon_state = "beret" -/mob/living/carbon/human/proc/mimejutsu_help() - set name = "Recall Ancient Mimeing" - set desc = "Remember the martial techniques of Mimejutsu." - set category = "Mimejutsu" - - to_chat(usr, "You make a invisible box around yourself and recall the teachings of Mimejutsu...") - - to_chat(usr, "Mimechucks: Disarm Harm. Hits the opponent with invisible nunchucks.") - to_chat(usr, "Smokebomb: Disarm Disarm. Drops a mime smokebomb.") - to_chat(usr, "Silent Palm: Grab Disarm. Using mime energy throw someone back.") +/datum/martial_art/mimejutsu/explaination_header(user) + to_chat(user, "You make a invisible box around yourself and recall the teachings of Mimejutsu...") diff --git a/code/modules/martial_arts/plasma_fist.dm b/code/modules/martial_arts/plasma_fist.dm index ea5aef5ea74..a216a5d730f 100644 --- a/code/modules/martial_arts/plasma_fist.dm +++ b/code/modules/martial_arts/plasma_fist.dm @@ -1,86 +1,22 @@ -#define TORNADO_COMBO "HHD" -#define THROWBACK_COMBO "DHD" -#define PLASMA_COMBO "HDDDH" - /datum/martial_art/plasma_fist name = "Plasma Fist" - help_verb = /mob/living/carbon/human/proc/plasma_fist_help - - -/datum/martial_art/plasma_fist/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,TORNADO_COMBO)) - streak = "" - Tornado(A,D) - return 1 - if(findtext(streak,THROWBACK_COMBO)) - streak = "" - Throwback(A,D) - return 1 - if(findtext(streak,PLASMA_COMBO)) - streak = "" - Plasma(A,D) - return 1 - return 0 - -/datum/martial_art/plasma_fist/proc/Tornado(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.say("TORNADO SWEEP!") - spawn(0) - for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) - A.dir = i - playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) - sleep(1) - var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null) - var/list/turfs = list() - for(var/turf/T in range(1,A)) - turfs.Add(T) - R.cast(turfs) - return - -/datum/martial_art/plasma_fist/proc/Throwback(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - D.visible_message("[A] has hit [D] with Plasma Punch!", \ - "[A] has hit [D] with Plasma Punch!") - playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) - var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) - D.throw_at(throw_target, 200, 4,A) - A.say("HYAH!") - return - -/datum/martial_art/plasma_fist/proc/Plasma(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) - A.say("PLASMA FIST!") - D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \ - "[A] has hit [D] with THE PLASMA FIST TECHNIQUE!") - D.gib() - return + combos = list(/datum/martial_combo/plasma_fist/tornado_sweep, /datum/martial_combo/plasma_fist/throwback, /datum/martial_combo/plasma_fist/plasma_fist) + has_explaination_verb = TRUE /datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE /datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE /datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK basic_hit(A,D) - return 1 + return TRUE -/mob/living/carbon/human/proc/plasma_fist_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Plasma Fist." - set category = "Plasma Fist" - - to_chat(usr, "You clench your fists and have a flashback of knowledge...") - to_chat(usr, "Tornado Sweep: Harm Harm Disarm. Repulses target and everyone back.") - to_chat(usr, "Throwback: Disarm Harm Disarm. Throws the target and an item at them.") - to_chat(usr, "The Plasma Fist: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body.") +/datum/martial_art/plasma_fist/explaination_header(user) + to_chat(user, "You clench your fists and have a flashback of knowledge...") diff --git a/code/modules/martial_arts/sleeping_carp.dm b/code/modules/martial_arts/sleeping_carp.dm index 472fb6ca506..9ca070f8bfd 100644 --- a/code/modules/martial_arts/sleeping_carp.dm +++ b/code/modules/martial_arts/sleeping_carp.dm @@ -1,126 +1,21 @@ //Used by the gang of the same name. Uses combos. Basic attacks bypass armor and never miss -#define WRIST_WRENCH_COMBO "DD" -#define BACK_KICK_COMBO "HG" -#define STOMACH_KNEE_COMBO "GH" -#define HEAD_KICK_COMBO "DHH" -#define ELBOW_DROP_COMBO "HDHDH" /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" deflection_chance = 100 - help_verb = /mob/living/carbon/human/proc/sleeping_carp_help no_guns = TRUE no_guns_message = "Use of ranged weaponry would bring dishonor to the clan." - -/datum/martial_art/the_sleeping_carp/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(findtext(streak,WRIST_WRENCH_COMBO)) - streak = "" - wristWrench(A,D) - return 1 - if(findtext(streak,BACK_KICK_COMBO)) - streak = "" - backKick(A,D) - return 1 - if(findtext(streak,STOMACH_KNEE_COMBO)) - streak = "" - kneeStomach(A,D) - return 1 - if(findtext(streak,HEAD_KICK_COMBO)) - streak = "" - headKick(A,D) - return 1 - if(findtext(streak,ELBOW_DROP_COMBO)) - streak = "" - elbowDrop(A,D) - return 1 - return 0 - -/datum/martial_art/the_sleeping_carp/proc/wristWrench(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message("[A] grabs [D]'s wrist and wrenches it sideways!", \ - "[A] grabs your wrist and violently wrenches it to the side!") - playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Wrist Wrench", ATKLOG_ALL) - if(prob(60)) - A.say(pick("WRISTY TWIRLY!", "WE FIGHT LIKE MEN!", "YOU DISHONOR YOURSELF!", "POHYAH!", "WHERE IS YOUR BATON NOW?", "SAY UNCLE!")) - D.emote("scream") - D.drop_item() - D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - D.Stun(3) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/backKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(A.dir == D.dir && !D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] kicks [D] in the back!", \ - "[A] kicks you in the back, making you stumble and fall!") - step_to(D,get_step(D,D.dir),1) - D.Weaken(4) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Back Kick", ATKLOG_ALL) - if(prob(80)) - A.say(pick("SURRPRIZU!","BACK STRIKE!","WOPAH!", "WATAAH", "ZOTA!", "Never turn your back to the enemy!")) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/kneeStomach(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] knees [D] in the stomach!", \ - "[A] winds you with a knee in the stomach!") - D.audible_message("[D] gags!") - D.AdjustLoseBreath(3) - D.Stun(2) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Stomach Knee", ATKLOG_ALL) - if(prob(80)) - A.say(pick("HWOP!", "KUH!", "YAKUUH!", "KYUH!", "KNEESTRIKE!")) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/headKick(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(!D.stat && !D.IsWeakened()) - A.do_attack_animation(D, ATTACK_EFFECT_KICK) - D.visible_message("[A] kicks [D] in the head!", \ - "[A] kicks you in the jaw!") - D.apply_damage(20, BRUTE, "head") - D.drop_item() - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Head Kick", ATKLOG_ALL) - if(prob(60)) - A.say(pick("OOHYOO!", "OOPYAH!", "HYOOAA!", "WOOAAA!", "SHURYUKICK!", "HIYAH!")) - D.Stun(4) - return 1 - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/elbowDrop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - if(D.IsWeakened() || D.resting || D.stat) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message("[A] elbow drops [D]!", \ - "[A] piledrives you with [A.p_their()] elbow!") - if(D.stat) - D.death() //FINISH HIM! - D.apply_damage(50, BRUTE, "chest") - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1) - add_attack_logs(A, D, "Melee attacked with martial-art [src] : Elbow Drop", ATKLOG_ALL) - if(prob(80)) - A.say(pick("BANZAIII!", "KIYAAAA!", "OMAE WA MOU SHINDEIRU!", "YOU CAN'T SEE ME!", "MY TIME IS NOW!", "COWABUNGA")) - return 1 - return basic_hit(A,D) + has_explaination_verb = TRUE + combos = list(/datum/martial_combo/sleeping_carp/wrist_wrench, /datum/martial_combo/sleeping_carp/back_kick, /datum/martial_combo/sleeping_carp/stomach_knee, /datum/martial_combo/sleeping_carp/head_kick, /datum/martial_combo/sleeping_carp/elbow_drop) /datum/martial_art/the_sleeping_carp/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK var/obj/item/grab/G = D.grabbedby(A,1) if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab + return TRUE /datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 + MARTIAL_ARTS_ACT_CHECK A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") D.visible_message("[A] [atk_verb] [D]!", \ @@ -132,24 +27,7 @@ if(prob(D.getBruteLoss()) && !D.lying) D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!") D.Weaken(4) - return 1 - - -/datum/martial_art/the_sleeping_carp/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 - return ..() - -/mob/living/carbon/human/proc/sleeping_carp_help() - set name = "Recall Teachings" - set desc = "Remember the martial techniques of the Sleeping Carp clan." - set category = "Sleeping Carp" + return TRUE +/datum/martial_art/the_sleeping_carp/explaination_header(user) to_chat(usr, "You retreat inward and recall the teachings of the Sleeping Carp...") - - to_chat(usr, "Wrist Wrench: Disarm Disarm. Forces opponent to drop item in hand.") - to_chat(usr, "Back Kick: Harm Grab. Opponent must be facing away. Knocks down.") - to_chat(usr, "Stomach Knee: Grab Harm. Knocks the wind out of opponent and stuns.") - to_chat(usr, "Head Kick: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand.") - to_chat(usr, "Elbow Drop: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition.") diff --git a/code/modules/martial_arts/wrestleing.dm b/code/modules/martial_arts/wrestling.dm similarity index 100% rename from code/modules/martial_arts/wrestleing.dm rename to code/modules/martial_arts/wrestling.dm diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index d495ca3d2f4..4cb846139f7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -29,8 +29,6 @@ create_reagents(330) - martial_art = GLOB.default_martial_art - handcrafting = new() // Set up DNA. @@ -298,8 +296,8 @@ apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) /mob/living/carbon/human/bullet_act() - if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles! - if(!prob(martial_art.deflection_chance)) + if(mind && mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles! + if(!prob(mind.martial_art.deflection_chance)) return ..() if(!src.lying && !(HULK in mutations)) //But only if they're not lying down, and hulks can't do it visible_message("[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!", "You deflect the projectile!") @@ -1731,16 +1729,14 @@ Eyes need to have significantly high darksight to shine unless the mob has the X if(G.trigger_guard == TRIGGER_GUARD_NORMAL) if(HULK in mutations) to_chat(src, "Your meaty finger is much too large for the trigger guard!") - return 0 + return FALSE if(NOGUNS in dna.species.species_traits) to_chat(src, "Your fingers don't fit in the trigger guard!") - return 0 + return FALSE - if(martial_art && martial_art.no_guns) //great dishonor to famiry - to_chat(src, "[martial_art.no_guns_message]") - return 0 - - return . + if(mind && mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry + to_chat(src, "[mind.martial_art.no_guns_message]") + return FALSE /mob/living/carbon/human/proc/change_icobase(var/new_icobase, var/new_deform, var/owner_sensitive) for(var/obj/item/organ/external/O in bodyparts) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 958afaaef94..cf61162733e 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -214,7 +214,7 @@ emp_act return 0 /mob/living/carbon/human/proc/check_block() - if(martial_art && prob(martial_art.block_chance) && martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) + if(mind && mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE)) return TRUE /mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 3d365afa940..bc5c85e2929 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,4 +1,3 @@ -GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new()) /mob/living/carbon/human hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,GLAND_HUD) @@ -42,8 +41,6 @@ GLOBAL_DATUM_INIT(default_martial_art, /datum/martial_art, new()) var/datum/personal_crafting/handcrafting - var/datum/martial_art/martial_art = null - var/special_voice = "" // For changing our voice. Used by a symptom. var/hand_blood_color diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a1be84f8163..c9cd99ad2d0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -696,13 +696,14 @@ if(alcohol_strength >= slur_start) //slurring Slur(drunk) - if(alcohol_strength >= brawl_start) //the drunken martial art - if(!istype(martial_art, /datum/martial_art/drunk_brawling)) - var/datum/martial_art/drunk_brawling/F = new - F.teach(src, 1) - if(alcohol_strength < brawl_start) //removing the art - if(istype(martial_art, /datum/martial_art/drunk_brawling)) - martial_art.remove(src) + if(mind) + if(alcohol_strength >= brawl_start) //the drunken martial art + if(!istype(mind.martial_art, /datum/martial_art/drunk_brawling)) + var/datum/martial_art/drunk_brawling/F = new + F.teach(src, TRUE) + else if(alcohol_strength < brawl_start) //removing the art + if(istype(mind.martial_art, /datum/martial_art/drunk_brawling)) + mind.martial_art.remove(src) if(alcohol_strength >= confused_start && prob(33)) //confused walking if(!confused) Confused(1) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index a8e1eee5f52..1ba796c0435 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -516,7 +516,7 @@ playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) target.visible_message("[user] attempted to disarm [target]!") -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) //Handles any species-specific attackhand events. +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) //Handles any species-specific attackhand events. if(!istype(M)) return @@ -528,6 +528,9 @@ to_chat(M, "You can't use your hand.") return + if(M.mind) + attacker_style = M.mind.martial_art + if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) add_attack_logs(M, H, "Melee attacked with fists (miss/block)") H.visible_message("[M] attempted to touch [H]!") diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 2f97001d3ae..dd0316f4177 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -122,8 +122,8 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L) if(ishuman(L)) var/mob/living/carbon/human/H = L - if(H.martial_art && prob(H.martial_art.deflection_chance)) - . = TRUE + if(H.mind && H.mind.martial_art && prob(H.mind.martial_art.deflection_chance)) + return TRUE /mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() ranged_cooldown = world.time + 40 diff --git a/paradise.dme b/paradise.dme index 5ed4f7e3bc5..7fe2674b7d8 100644 --- a/paradise.dme +++ b/paradise.dme @@ -50,6 +50,7 @@ #include "code\__DEFINES\lighting.dm" #include "code\__DEFINES\logs.dm" #include "code\__DEFINES\machines.dm" +#include "code\__DEFINES\martial_arts.dm" #include "code\__DEFINES\math.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\mecha.dm" @@ -1664,7 +1665,28 @@ #include "code\modules\martial_arts\mimejutsu.dm" #include "code\modules\martial_arts\plasma_fist.dm" #include "code\modules\martial_arts\sleeping_carp.dm" -#include "code\modules\martial_arts\wrestleing.dm" +#include "code\modules\martial_arts\wrestling.dm" +#include "code\modules\martial_arts\combos\martial_combo.dm" +#include "code\modules\martial_arts\combos\adminfu\healing_palm.dm" +#include "code\modules\martial_arts\combos\cqc\consecutive.dm" +#include "code\modules\martial_arts\combos\cqc\kick.dm" +#include "code\modules\martial_arts\combos\cqc\pressure.dm" +#include "code\modules\martial_arts\combos\cqc\restrain.dm" +#include "code\modules\martial_arts\combos\cqc\slam.dm" +#include "code\modules\martial_arts\combos\krav_maga\leg_sweep.dm" +#include "code\modules\martial_arts\combos\krav_maga\lung_punch.dm" +#include "code\modules\martial_arts\combos\krav_maga\neck_chop.dm" +#include "code\modules\martial_arts\combos\mimejutsu\mimechucks.dm" +#include "code\modules\martial_arts\combos\mimejutsu\silent_palm.dm" +#include "code\modules\martial_arts\combos\mimejutsu\smokebomb.dm" +#include "code\modules\martial_arts\combos\plasma_fist\plasma_fist.dm" +#include "code\modules\martial_arts\combos\plasma_fist\throwback.dm" +#include "code\modules\martial_arts\combos\plasma_fist\tornado_sweep.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\back_kick.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\elbow_drop.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\head_kick.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\stomach_knee.dm" +#include "code\modules\martial_arts\combos\sleeping_carp\wrist_wrench.dm" #include "code\modules\mining\abandonedcrates.dm" #include "code\modules\mining\fulton.dm" #include "code\modules\mining\machine_processing.dm"