From 25df88509ab7fe7f54bd477ca9bbe47867c4540b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 22 May 2017 07:13:10 -0500 Subject: [PATCH] Reorganizes martial arts and stores them in the MIND. --- code/_onclick/click.dm | 2 +- code/datums/martial.dm | 676 +----------------- code/datums/martial/boxing.dm | 67 ++ code/datums/martial/cqc.dm | 199 ++++++ code/datums/martial/krav_maga.dm | 18 +- code/datums/martial/plasma_fist.dm | 114 +++ code/datums/martial/sleeping_carp.dm | 247 +++++++ code/datums/martial/wrestling.dm | 40 +- code/datums/mind.dm | 3 +- .../weapons/implants/implant_krav_maga.dm | 4 +- code/modules/mob/living/carbon/human/human.dm | 3 +- .../mob/living/carbon/human/human_defense.dm | 22 +- .../mob/living/carbon/human/human_defines.dm | 3 - .../mob/living/carbon/human/human_helpers.dm | 8 +- code/modules/mob/living/carbon/human/login.dm | 9 + .../mob/living/carbon/human/species.dm | 4 +- .../carbon/human/species_types/golems.dm | 4 +- .../hostile/megafauna/colossus.dm | 5 +- tgstation.dme | 4 + 19 files changed, 722 insertions(+), 710 deletions(-) create mode 100644 code/datums/martial/boxing.dm create mode 100644 code/datums/martial/cqc.dm create mode 100644 code/datums/martial/plasma_fist.dm create mode 100644 code/datums/martial/sleeping_carp.dm create mode 100644 code/modules/mob/living/carbon/human/login.dm diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index ad4a84529b..7e2f29052f 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -326,7 +326,7 @@ /mob/living/carbon/human/CtrlClick(mob/user) if(ishuman(user) && Adjacent(user)) var/mob/living/carbon/human/H = user - H.dna.species.grab(H, src, H.martial_art) + H.dna.species.grab(H, src, H.mind.martial_art) H.next_click = world.time + CLICK_CD_MELEE else ..() diff --git a/code/datums/martial.dm b/code/datums/martial.dm index b20bf556d5..fa02a2f092 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -79,681 +79,17 @@ /datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0) if(make_temporary) temporary = 1 - if(temporary && H.martial_art) - if(!H.martial_art.allow_temp_override) + if(temporary && H.mind.martial_art) + if(!H.mind.martial_art.allow_temp_override) return - base = H.martial_art + base = H.mind.martial_art if(help_verb) H.verbs += help_verb - H.martial_art = src + H.mind.martial_art = src /datum/martial_art/proc/remove(mob/living/carbon/human/H) - if(H.martial_art != src) + if(H.mind.martial_art != src) return - H.martial_art = base + H.mind.martial_art = base if(help_verb) H.verbs -= help_verb - -/datum/martial_art/boxing - name = "Boxing" - -/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - to_chat(A, "Can't disarm while boxing!") - return 1 - -/datum/martial_art/boxing/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - to_chat(A, "Can't grab while boxing!") - return 1 - -/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - - var/atk_verb = pick("left hook","right hook","straight punch") - - var/damage = rand(5, 8) + A.dna.species.punchdamagelow - if(!damage) - playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) - D.visible_message("[A] has attempted to [atk_verb] [D]!", \ - "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE) - add_logs(A, D, "attempted to hit", atk_verb) - return 0 - - - var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") - - playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) - - D.visible_message("[A] has [atk_verb]ed [D]!", \ - "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE) - - D.apply_damage(damage, STAMINA, affecting, armor_block) - add_logs(A, D, "punched (boxing) ") - if(D.getStaminaLoss() > 50) - var/knockout_prob = D.getStaminaLoss() + rand(-15,15) - if((D.stat != DEAD) && prob(knockout_prob)) - D.visible_message("[A] has knocked [D] out with a haymaker!", \ - "[A] has knocked [D] out with a haymaker!") - D.apply_effect(10,WEAKEN,armor_block) - D.SetSleeping(5) - D.forcesay(GLOB.hit_appends) - add_logs(A, D, "knocked out (boxing) ") - else if(D.lying) - D.forcesay(GLOB.hit_appends) - return 1 - -/mob/living/carbon/human/proc/wrestling_help() - set name = "Recall Teachings" - set desc = "Remember how to wrestle." - set category = "Wrestling" - - to_chat(usr, "You flex your muscles and have a revelation...") - to_chat(usr, "Clinch: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful.") - to_chat(usr, "Suplex: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor.") - to_chat(usr, "Advanced grab: Grab. Passively causes stamina damage when grabbing someone.") - -#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(mob/living/carbon/human/A, 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/TornadoAnimate(mob/living/carbon/human/A) - set waitfor = FALSE - for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) - if(!A) - break - A.setDir(i) - playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) - sleep(1) - -/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D) - A.say("TORNADO SWEEP!") - TornadoAnimate(A) - 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) - add_logs(A, D, "tornado sweeped(Plasma Fist)") - return - -/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, 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!") - add_logs(A, D, "threw back (Plasma Fist)") - return - -/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, 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() - add_logs(A, D, "gibbed (Plasma Fist)") - return - -/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 - basic_hit(A,D) - return 1 - -/datum/martial_art/plasma_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("D",D) - if(check_streak(A,D)) - return 1 - basic_hit(A,D) - return 1 - -/datum/martial_art/plasma_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 - basic_hit(A,D) - return 1 - -/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.") - -//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 - no_guns = TRUE - allow_temp_override = FALSE - help_verb = /mob/living/carbon/human/proc/sleeping_carp_help - -/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, 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(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!D.stat && !D.stunned && !D.weakened) - 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) - D.emote("scream") - D.drop_item() - D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) - D.Stun(3) - return 1 - add_logs(A, D, "wrist wrenched (Sleeping Carp)") - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.dir == D.dir && !D.stat && !D.weakened) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - 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) - return 1 - add_logs(A, D, "back-kicked (Sleeping Carp)") - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!D.stat && !D.weakened) - 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.losebreath += 3 - D.Stun(2) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) - return 1 - add_logs(A, D, "stomach kneed (Sleeping Carp)") - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!D.stat && !D.weakened) - 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) - D.Stun(4) - return 1 - add_logs(A, D, "head kicked (Sleeping Carp)") - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(D.weakened || D.resting || D.stat) - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - D.visible_message("[A] elbow drops [D]!", \ - "[A] piledrives you with 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) - return 1 - add_logs(A, D, "elbow dropped (Sleeping Carp)") - return basic_hit(A,D) - -/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 - if(A.grab_state >= GRAB_AGGRESSIVE) - D.grabbedby(A, 1) - else - A.start_pulling(D, 1) - if(A.pulling) - D.drop_all_held_items() - D.stop_pulling() - if(A.a_intent == INTENT_GRAB) - add_logs(A, D, "grabbed", addition="aggressively") - A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab - else - add_logs(A, D, "grabbed", addition="passively") - A.grab_state = GRAB_PASSIVE - return 1 - -/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 - A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) - var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") - D.visible_message("[A] [atk_verb] [D]!", \ - "[A] [atk_verb] you!") - D.apply_damage(rand(10,15), BRUTE) - playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1) - if(prob(D.getBruteLoss()) && !D.lying) - D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!") - D.Weaken(4) - add_logs(A, D, "[atk_verb] (Sleeping Carp)") - return 1 - - -/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, 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" - - 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.") - -//CQC -#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 - -/datum/martial_art/cqc/proc/drop_restraining() - restraining = 0 - -/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(findtext(streak,SLAM_COMBO)) - streak = "" - Slam(A,D) - return 1 - if(findtext(streak,KICK_COMBO)) - streak = "" - Kick(A,D) - return 1 - if(findtext(streak,RESTRAIN_COMBO)) - streak = "" - Restrain(A,D) - return 1 - if(findtext(streak,PRESSURE_COMBO)) - streak = "" - Pressure(A,D) - return 1 - if(findtext(streak,CONSECUTIVE_COMBO)) - streak = "" - Consecutive(A,D) - return 0 - -/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!D.stat || !D.weakened) - 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_logs(A, D, "cqc slammed") - return 1 - -/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(!D.stat || !D.weakened) - 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_logs(A, D, "cqc kicked") - if(D.weakened && !D.stat) - D.visible_message("[A] kicks [D]'s head, knocking 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(25) - return 1 - -/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) - 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) - return 1 - -/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(restraining) - return - 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 = 1 - addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) - return 1 - -/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D) - 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_held_item() - if(I && D.drop_item()) - A.put_in_hands(I) - D.adjustStaminaLoss(50) - D.apply_damage(25, BRUTE) - return 1 - -/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("G",D) - if(check_streak(A,D)) - return 1 - if(A.grab_state >= GRAB_AGGRESSIVE) - D.grabbedby(A, 1) - else - A.start_pulling(D, 1) - if(A.pulling) - D.stop_pulling() - add_logs(A, D, "grabbed", addition="aggressively") - A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab - - return 1 - -/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("H",D) - if(check_streak(A,D)) - return 1 - add_logs(A, D, "CQC'd") - A.do_attack_animation(D) - var/picked_hit_type = pick("CQC'd", "Big Bossed") - var/bonus_damage = 13 - if(D.weakened || D.resting || D.lying) - bonus_damage += 5 - picked_hit_type = "stomps on" - D.apply_damage(bonus_damage, BRUTE) - if(picked_hit_type == "kicks" || picked_hit_type == "stomps on") - playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) - else - playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - D.visible_message("[A] [picked_hit_type] [D]!", \ - "[A] [picked_hit_type] you!") - add_logs(A, D, "[picked_hit_type] with CQC") - if(A.resting && !D.stat && !D.weakened) - 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(10, BRUTE) - D.Weaken(3) - add_logs(A, D, "cqc sweeped") - return 1 - -/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - add_to_streak("D",D) - var/obj/item/I = null - if(check_streak(A,D)) - return 1 - if(prob(65)) - if(!D.stat || !D.weakened || !restraining) - I = D.get_active_held_item() - D.visible_message("[A] strikes [D]'s jaw with their hand!", \ - "[A] strikes your jaw, disorienting you!") - playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) - if(I && D.drop_item()) - A.put_in_hands(I) - D.Jitter(2) - D.apply_damage(5, BRUTE) - else - D.visible_message("[A] attempted to disarm [D]!", \ - "[A] attempted to disarm [D]!") - playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]") - if(restraining && A.pulling == D) - D.visible_message("[A] puts [D] into a chokehold!", \ - "[A] puts you into a chokehold!") - D.SetSleeping(20) - restraining = 0 - if(A.grab_state < GRAB_NECK) - A.grab_state = GRAB_NECK - else - restraining = 0 - return 0 - return 1 - -/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.") - - to_chat(usr, "Slam: Grab Harm. Slam opponent into the ground, weakens and knocks down.") - to_chat(usr, "CQC Kick: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents.") - to_chat(usr, "Restrain: Grab 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.") - -//ITEMS - -/obj/item/clothing/gloves/boxing - var/datum/martial_art/boxing/style = new - -/obj/item/clothing/gloves/boxing/equipped(mob/user, slot) - if(!ishuman(user)) - return - if(slot == slot_gloves) - var/mob/living/carbon/human/H = user - style.teach(H,1) - return - -/obj/item/clothing/gloves/boxing/dropped(mob/user) - if(!ishuman(user)) - return - var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(slot_gloves) == src) - style.remove(H) - return - -/obj/item/weapon/storage/belt/champion/wrestling - name = "Wrestling Belt" - var/datum/martial_art/wrestling/style = new - -/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot) - if(!ishuman(user)) - return - if(slot == slot_belt) - var/mob/living/carbon/human/H = user - style.teach(H,1) - return - -/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) - if(!ishuman(user)) - return - var/mob/living/carbon/human/H = user - if(H.get_item_by_slot(slot_belt) == src) - style.remove(H) - return - -/obj/item/weapon/plasma_fist_scroll - name = "frayed scroll" - desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." - icon = 'icons/obj/wizard.dmi' - icon_state ="scroll2" - var/used = 0 - -/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user) - if(!ishuman(user)) - return - if(!used) - var/mob/living/carbon/human/H = user - var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) - F.teach(H) - to_chat(H, "You have learned the ancient martial art of Plasma Fist.") - used = 1 - desc = "It's completely blank." - name = "empty scroll" - icon_state = "blankscroll" - -/obj/item/weapon/cqc_manual - name = "old manual" - desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat." - icon = 'icons/obj/library.dmi' - icon_state ="cqcmanual" - -/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user) - if(!istype(user) || !user) - return - to_chat(user, "You remember the basics of CQC.") - var/datum/martial_art/cqc/D = new(null) - D.teach(user) - user.drop_item() - visible_message("[src] beeps ominously, and a moment later it bursts up in flames.") - new /obj/effect/decal/cleanable/ash(get_turf(src)) - qdel(src) - -/obj/item/weapon/sleeping_carp_scroll - name = "mysterious scroll" - desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art." - icon = 'icons/obj/wizard.dmi' - icon_state = "scroll2" - -/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user) - if(!istype(user) || !user) - return - var/message = "You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \ - directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab." - to_chat(user, message) - var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null) - theSleepingCarp.teach(user) - user.drop_item() - visible_message("[src] lights up in fire and quickly burns to ash.") - new /obj/effect/decal/cleanable/ash(get_turf(src)) - qdel(src) - -/obj/item/weapon/twohanded/bostaff - name = "bo staff" - desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate." - force = 10 - w_class = WEIGHT_CLASS_BULKY - slot_flags = SLOT_BACK - force_unwielded = 10 - force_wielded = 24 - throwforce = 20 - throw_speed = 2 - attack_verb = list("smashed", "slammed", "whacked", "thwacked") - icon = 'icons/obj/weapons.dmi' - icon_state = "bostaff0" - block_chance = 50 - -/obj/item/weapon/twohanded/bostaff/update_icon() - icon_state = "bostaff[wielded]" - return - -/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user) - add_fingerprint(user) - if((CLUMSY in user.disabilities) && prob(50)) - to_chat(user, "You club yourself over the head with [src].") - user.Weaken(3) - if(ishuman(user)) - var/mob/living/carbon/human/H = user - H.apply_damage(2*force, BRUTE, "head") - else - user.take_bodypart_damage(2*force) - return - if(iscyborg(target)) - return ..() - if(!isliving(target)) - return ..() - var/mob/living/carbon/C = target - if(C.stat) - to_chat(user, "It would be dishonorable to attack a foe while they cannot retaliate.") - return - if(user.a_intent == INTENT_DISARM) - if(!wielded) - return ..() - if(!ishuman(target)) - return ..() - var/mob/living/carbon/human/H = target - var/list/fluffmessages = list("[user] clubs [H] with [src]!", \ - "[user] smacks [H] with the butt of [src]!", \ - "[user] broadsides [H] with [src]!", \ - "[user] smashes [H]'s head with [src]!", \ - "[user] beats [H] with front of [src]!", \ - "[user] twirls and slams [H] with [src]!") - H.visible_message("[pick(fluffmessages)]", \ - "[pick(fluffmessages)]") - playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1) - H.adjustStaminaLoss(rand(13,20)) - if(prob(10)) - H.visible_message("[H] collapses!", \ - "Your legs give out!") - H.Weaken(4) - if(H.staminaloss && !H.sleeping) - var/total_health = (H.health - H.staminaloss) - if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat) - H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \ - "[user] knocks you unconscious!") - H.SetSleeping(30) - H.adjustBrainLoss(25) - else - return ..() - -/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) - if(wielded) - return ..() - return 0 - diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm new file mode 100644 index 0000000000..6a3a059890 --- /dev/null +++ b/code/datums/martial/boxing.dm @@ -0,0 +1,67 @@ +/datum/martial_art/boxing + name = "Boxing" + +/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + to_chat(A, "Can't disarm while boxing!") + return 1 + +/datum/martial_art/boxing/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + to_chat(A, "Can't grab while boxing!") + return 1 + +/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + + var/atk_verb = pick("left hook","right hook","straight punch") + + var/damage = rand(5, 8) + A.dna.species.punchdamagelow + if(!damage) + playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1) + D.visible_message("[A] has attempted to [atk_verb] [D]!", \ + "[A] has attempted to [atk_verb] [D]!", null, COMBAT_MESSAGE_RANGE) + add_logs(A, D, "attempted to hit", atk_verb) + return 0 + + + var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) + var/armor_block = D.run_armor_check(affecting, "melee") + + playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) + + D.visible_message("[A] has [atk_verb]ed [D]!", \ + "[A] has [atk_verb]ed [D]!", null, COMBAT_MESSAGE_RANGE) + + D.apply_damage(damage, STAMINA, affecting, armor_block) + add_logs(A, D, "punched (boxing) ") + if(D.getStaminaLoss() > 50) + var/knockout_prob = D.getStaminaLoss() + rand(-15,15) + if((D.stat != DEAD) && prob(knockout_prob)) + D.visible_message("[A] has knocked [D] out with a haymaker!", \ + "[A] has knocked [D] out with a haymaker!") + D.apply_effect(10,WEAKEN,armor_block) + D.SetSleeping(5) + D.forcesay(GLOB.hit_appends) + add_logs(A, D, "knocked out (boxing) ") + else if(D.lying) + D.forcesay(GLOB.hit_appends) + return 1 + +/obj/item/clothing/gloves/boxing + var/datum/martial_art/boxing/style = new + +/obj/item/clothing/gloves/boxing/equipped(mob/user, slot) + if(!ishuman(user)) + return + if(slot == slot_gloves) + var/mob/living/carbon/human/H = user + style.teach(H,1) + return + +/obj/item/clothing/gloves/boxing/dropped(mob/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(slot_gloves) == src) + style.remove(H) + return diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm new file mode 100644 index 0000000000..ebb570fa0c --- /dev/null +++ b/code/datums/martial/cqc.dm @@ -0,0 +1,199 @@ +#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 + +/datum/martial_art/cqc/proc/drop_restraining() + restraining = 0 + +/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(findtext(streak,SLAM_COMBO)) + streak = "" + Slam(A,D) + return 1 + if(findtext(streak,KICK_COMBO)) + streak = "" + Kick(A,D) + return 1 + if(findtext(streak,RESTRAIN_COMBO)) + streak = "" + Restrain(A,D) + return 1 + if(findtext(streak,PRESSURE_COMBO)) + streak = "" + Pressure(A,D) + return 1 + if(findtext(streak,CONSECUTIVE_COMBO)) + streak = "" + Consecutive(A,D) + return 0 + +/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D.stat || !D.weakened) + 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_logs(A, D, "cqc slammed") + return 1 + +/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D.stat || !D.weakened) + 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_logs(A, D, "cqc kicked") + if(D.weakened && !D.stat) + D.visible_message("[A] kicks [D]'s head, knocking 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(25) + return 1 + +/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D) + 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) + return 1 + +/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(restraining) + return + 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 = 1 + addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) + return 1 + +/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D) + 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_held_item() + if(I && D.drop_item()) + A.put_in_hands(I) + D.adjustStaminaLoss(50) + D.apply_damage(25, BRUTE) + return 1 + +/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("G",D) + if(check_streak(A,D)) + return 1 + if(A.grab_state >= GRAB_AGGRESSIVE) + D.grabbedby(A, 1) + else + A.start_pulling(D, 1) + if(A.pulling) + D.stop_pulling() + add_logs(A, D, "grabbed", addition="aggressively") + A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab + + return 1 + +/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("H",D) + if(check_streak(A,D)) + return 1 + add_logs(A, D, "CQC'd") + A.do_attack_animation(D) + var/picked_hit_type = pick("CQC'd", "Big Bossed") + var/bonus_damage = 13 + if(D.weakened || D.resting || D.lying) + bonus_damage += 5 + picked_hit_type = "stomps on" + D.apply_damage(bonus_damage, BRUTE) + if(picked_hit_type == "kicks" || picked_hit_type == "stomps on") + playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1) + else + playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + D.visible_message("[A] [picked_hit_type] [D]!", \ + "[A] [picked_hit_type] you!") + add_logs(A, D, "[picked_hit_type] with CQC") + if(A.resting && !D.stat && !D.weakened) + 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(10, BRUTE) + D.Weaken(3) + add_logs(A, D, "cqc sweeped") + return 1 + +/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("D",D) + var/obj/item/I = null + if(check_streak(A,D)) + return 1 + if(prob(65)) + if(!D.stat || !D.weakened || !restraining) + I = D.get_active_held_item() + D.visible_message("[A] strikes [D]'s jaw with their hand!", \ + "[A] strikes your jaw, disorienting you!") + playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1) + if(I && D.drop_item()) + A.put_in_hands(I) + D.Jitter(2) + D.apply_damage(5, BRUTE) + else + D.visible_message("[A] attempted to disarm [D]!", \ + "[A] attempted to disarm [D]!") + playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]") + if(restraining && A.pulling == D) + D.visible_message("[A] puts [D] into a chokehold!", \ + "[A] puts you into a chokehold!") + D.SetSleeping(20) + restraining = 0 + if(A.grab_state < GRAB_NECK) + A.grab_state = GRAB_NECK + else + restraining = 0 + return 0 + return 1 + +/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.") + + to_chat(usr, "Slam: Grab Harm. Slam opponent into the ground, weakens and knocks down.") + to_chat(usr, "CQC Kick: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents.") + to_chat(usr, "Restrain: Grab 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.") + +/obj/item/weapon/cqc_manual + name = "old manual" + desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat." + icon = 'icons/obj/library.dmi' + icon_state ="cqcmanual" + +/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user) + if(!istype(user) || !user) + return + to_chat(user, "You remember the basics of CQC.") + var/datum/martial_art/cqc/D = new(null) + D.teach(user) + user.drop_item() + visible_message("[src] beeps ominously, and a moment later it bursts up in flames.") + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 5bc9b0588b..eb5f74b411 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -13,12 +13,12 @@ to_chat(owner, "You can't use Krav Maga while you're incapacitated.") return var/mob/living/carbon/human/H = owner - if (H.martial_art.streak == "neck_chop") + if (H.mind.martial_art.streak == "neck_chop") owner.visible_message("[owner] assumes a neutral stance.", "Your next attack is cleared.") - H.martial_art.streak = "" + H.mind.martial_art.streak = "" else owner.visible_message("[owner] assumes the Neck Chop stance!", "Your next attack will be a Neck Chop.") - H.martial_art.streak = "neck_chop" + H.mind.martial_art.streak = "neck_chop" /datum/action/leg_sweep name = "Leg Sweep - Trips the victim, knocking them down for a brief moment." @@ -29,12 +29,12 @@ to_chat(owner, "You can't use Krav Maga while you're incapacitated.") return var/mob/living/carbon/human/H = owner - if (H.martial_art.streak == "leg_sweep") + if (H.mind.martial_art.streak == "leg_sweep") owner.visible_message("[owner] assumes a neutral stance.", "Your next attack is cleared.") - H.martial_art.streak = "" + H.mind.martial_art.streak = "" else owner.visible_message("[owner] assumes the Leg Sweep stance!", "Your next attack will be a Leg Sweep.") - H.martial_art.streak = "leg_sweep" + H.mind.martial_art.streak = "leg_sweep" /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." @@ -45,12 +45,12 @@ to_chat(owner, "You can't use Krav Maga while you're incapacitated.") return var/mob/living/carbon/human/H = owner - if (H.martial_art.streak == "quick_choke") + if (H.mind.martial_art.streak == "quick_choke") owner.visible_message("[owner] assumes a neutral stance.", "Your next attack is cleared.") - H.martial_art.streak = "" + H.mind.martial_art.streak = "" else owner.visible_message("[owner] assumes the Lung Punch stance!", "Your next attack will be a Lung Punch.") - H.martial_art.streak = "quick_choke"//internal name for lung punch + H.mind.martial_art.streak = "quick_choke"//internal name for lung punch /datum/martial_art/krav_maga/teach(var/mob/living/carbon/human/H,var/make_temporary=0) ..() diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm new file mode 100644 index 0000000000..c79ef032ee --- /dev/null +++ b/code/datums/martial/plasma_fist.dm @@ -0,0 +1,114 @@ +#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(mob/living/carbon/human/A, 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/TornadoAnimate(mob/living/carbon/human/A) + set waitfor = FALSE + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + if(!A) + break + A.setDir(i) + playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) + sleep(1) + +/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D) + A.say("TORNADO SWEEP!") + TornadoAnimate(A) + 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) + add_logs(A, D, "tornado sweeped(Plasma Fist)") + return + +/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, 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!") + add_logs(A, D, "threw back (Plasma Fist)") + return + +/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, 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() + add_logs(A, D, "gibbed (Plasma Fist)") + return + +/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("H",D) + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + +/datum/martial_art/plasma_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("D",D) + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + +/datum/martial_art/plasma_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("G",D) + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + +/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.") + +/obj/item/weapon/plasma_fist_scroll + name = "frayed scroll" + desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism." + icon = 'icons/obj/wizard.dmi' + icon_state ="scroll2" + var/used = 0 + +/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user) + if(!ishuman(user)) + return + if(!used) + var/mob/living/carbon/human/H = user + var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) + F.teach(H) + to_chat(H, "You have learned the ancient martial art of Plasma Fist.") + used = 1 + desc = "It's completely blank." + name = "empty scroll" + icon_state = "blankscroll" diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm new file mode 100644 index 0000000000..f079d2a7db --- /dev/null +++ b/code/datums/martial/sleeping_carp.dm @@ -0,0 +1,247 @@ +#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 + no_guns = TRUE + allow_temp_override = FALSE + help_verb = /mob/living/carbon/human/proc/sleeping_carp_help + +/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, 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(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D.stat && !D.stunned && !D.weakened) + 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) + D.emote("scream") + D.drop_item() + D.apply_damage(5, BRUTE, pick("l_arm", "r_arm")) + D.Stun(3) + return 1 + add_logs(A, D, "wrist wrenched (Sleeping Carp)") + return basic_hit(A,D) + +/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(A.dir == D.dir && !D.stat && !D.weakened) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + 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) + return 1 + add_logs(A, D, "back-kicked (Sleeping Carp)") + return basic_hit(A,D) + +/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D.stat && !D.weakened) + 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.losebreath += 3 + D.Stun(2) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1) + return 1 + add_logs(A, D, "stomach kneed (Sleeping Carp)") + return basic_hit(A,D) + +/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!D.stat && !D.weakened) + 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) + D.Stun(4) + return 1 + add_logs(A, D, "head kicked (Sleeping Carp)") + return basic_hit(A,D) + +/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(D.weakened || D.resting || D.stat) + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + D.visible_message("[A] elbow drops [D]!", \ + "[A] piledrives you with 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) + return 1 + add_logs(A, D, "elbow dropped (Sleeping Carp)") + return basic_hit(A,D) + +/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) + add_to_streak("G",D) + if(check_streak(A,D)) + return 1 + if(A.grab_state >= GRAB_AGGRESSIVE) + D.grabbedby(A, 1) + else + A.start_pulling(D, 1) + if(A.pulling) + D.drop_all_held_items() + D.stop_pulling() + if(A.a_intent == INTENT_GRAB) + add_logs(A, D, "grabbed", addition="aggressively") + A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab + else + add_logs(A, D, "grabbed", addition="passively") + A.grab_state = GRAB_PASSIVE + return 1 + +/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 + A.do_attack_animation(D, ATTACK_EFFECT_PUNCH) + var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams") + D.visible_message("[A] [atk_verb] [D]!", \ + "[A] [atk_verb] you!") + D.apply_damage(rand(10,15), BRUTE) + playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1) + if(prob(D.getBruteLoss()) && !D.lying) + D.visible_message("[D] stumbles and falls!", "The blow sends you to the ground!") + D.Weaken(4) + add_logs(A, D, "[atk_verb] (Sleeping Carp)") + return 1 + + +/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, 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" + + 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.") + +/obj/item/weapon/sleeping_carp_scroll + name = "mysterious scroll" + desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art." + icon = 'icons/obj/wizard.dmi' + icon_state = "scroll2" + +/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user) + if(!istype(user) || !user) + return + var/message = "You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \ + directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab." + to_chat(user, message) + var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null) + theSleepingCarp.teach(user) + user.drop_item() + visible_message("[src] lights up in fire and quickly burns to ash.") + new /obj/effect/decal/cleanable/ash(get_turf(src)) + qdel(src) + +/obj/item/weapon/twohanded/bostaff + name = "bo staff" + desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate." + force = 10 + w_class = WEIGHT_CLASS_BULKY + slot_flags = SLOT_BACK + force_unwielded = 10 + force_wielded = 24 + throwforce = 20 + throw_speed = 2 + attack_verb = list("smashed", "slammed", "whacked", "thwacked") + icon = 'icons/obj/weapons.dmi' + icon_state = "bostaff0" + block_chance = 50 + +/obj/item/weapon/twohanded/bostaff/update_icon() + icon_state = "bostaff[wielded]" + return + +/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user) + add_fingerprint(user) + if((CLUMSY in user.disabilities) && prob(50)) + to_chat(user, "You club yourself over the head with [src].") + user.Weaken(3) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.apply_damage(2*force, BRUTE, "head") + else + user.take_bodypart_damage(2*force) + return + if(iscyborg(target)) + return ..() + if(!isliving(target)) + return ..() + var/mob/living/carbon/C = target + if(C.stat) + to_chat(user, "It would be dishonorable to attack a foe while they cannot retaliate.") + return + if(user.a_intent == INTENT_DISARM) + if(!wielded) + return ..() + if(!ishuman(target)) + return ..() + var/mob/living/carbon/human/H = target + var/list/fluffmessages = list("[user] clubs [H] with [src]!", \ + "[user] smacks [H] with the butt of [src]!", \ + "[user] broadsides [H] with [src]!", \ + "[user] smashes [H]'s head with [src]!", \ + "[user] beats [H] with front of [src]!", \ + "[user] twirls and slams [H] with [src]!") + H.visible_message("[pick(fluffmessages)]", \ + "[pick(fluffmessages)]") + playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1) + H.adjustStaminaLoss(rand(13,20)) + if(prob(10)) + H.visible_message("[H] collapses!", \ + "Your legs give out!") + H.Weaken(4) + if(H.staminaloss && !H.sleeping) + var/total_health = (H.health - H.staminaloss) + if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat) + H.visible_message("[user] delivers a heavy hit to [H]'s head, knocking them out cold!", \ + "[user] knocks you unconscious!") + H.SetSleeping(30) + H.adjustBrainLoss(25) + else + return ..() + +/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance) + if(wielded) + return ..() + return 0 diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index 5554ceeaeb..fc1c7a9b6d 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -1,3 +1,13 @@ +/mob/living/carbon/human/proc/wrestling_help() + set name = "Recall Teachings" + set desc = "Remember how to wrestle." + set category = "Wrestling" + + to_chat(usr, "You flex your muscles and have a revelation...") + to_chat(usr, "Clinch: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful.") + to_chat(usr, "Suplex: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor.") + to_chat(usr, "Advanced grab: Grab. Passively causes stamina damage when grabbing someone.") + /datum/martial_art/wrestling name = "Wrestling" var/datum/action/slam/slam = new/datum/action/slam() @@ -40,7 +50,7 @@ return owner.visible_message("[owner] prepares to BODY SLAM!", "Your next attack will be a BODY SLAM.") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "slam" + H.mind.martial_art.streak = "slam" /datum/action/throw_wrassle name = "Throw (Cinch) - Spin a cinched opponent around and throw them." @@ -52,7 +62,7 @@ return owner.visible_message("[owner] prepares to THROW!", "Your next attack will be a THROW.") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "throw" + H.mind.martial_art.streak = "throw" /datum/action/kick name = "Kick - A powerful kick, sends people flying away from you. Also useful for escaping from bad situations." @@ -64,7 +74,7 @@ return owner.visible_message("[owner] prepares to KICK!", "Your next attack will be a KICK.") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "kick" + H.mind.martial_art.streak = "kick" /datum/action/strike name = "Strike - Hit a neaby opponent with a quick attack." @@ -76,7 +86,7 @@ return owner.visible_message("[owner] prepares to STRIKE!", "Your next attack will be a STRIKE.") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "strike" + H.mind.martial_art.streak = "strike" /datum/action/drop name = "Drop - Smash down onto an opponent." @@ -88,7 +98,7 @@ return owner.visible_message("[owner] prepares to LEG DROP!", "Your next attack will be a LEG DROP.") var/mob/living/carbon/human/H = owner - H.martial_art.streak = "drop" + H.mind.martial_art.streak = "drop" /datum/martial_art/wrestling/teach(var/mob/living/carbon/human/H,var/make_temporary=0) ..() @@ -430,3 +440,23 @@ D.Stun(rand(3,5)) add_logs(A, D, "cinched") return 1 + +/obj/item/weapon/storage/belt/champion/wrestling + name = "Wrestling Belt" + var/datum/martial_art/wrestling/style = new + +/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot) + if(!ishuman(user)) + return + if(slot == slot_belt) + var/mob/living/carbon/human/H = user + style.teach(H,1) + return + +/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(slot_belt) == src) + style.remove(H) + return diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 04bec0a7a4..7f7310665b 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -50,7 +50,8 @@ var/datum/faction/faction //associated faction var/datum/changeling/changeling //changeling holder var/linglink - + var/datum/martial_art/martial_art = null + var/static/default_martial_art = new/datum/martial_art var/miming = 0 // Mime's vow of silence var/list/antag_datums var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state 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 1db7601255..60823f3279 100644 --- a/code/game/objects/items/weapons/implants/implant_krav_maga.dm +++ b/code/game/objects/items/weapons/implants/implant_krav_maga.dm @@ -19,7 +19,9 @@ var/mob/living/carbon/human/H = imp_in if(!ishuman(H)) return - if(istype(H.martial_art, /datum/martial_art/krav_maga)) + if(!H.mind) + return + if(istype(H.mind.martial_art, /datum/martial_art/krav_maga)) style.remove(H) else style.teach(H,1) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index be7e851a8e..8f597f5531 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -36,7 +36,8 @@ //initialise organs create_internal_organs() - martial_art = default_martial_art + if(mind) + mind.martial_art = mind.default_martial_art handcrafting = new() diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 0623921d63..46f5bc3d4f 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -40,12 +40,13 @@ if(spec_return) return spec_return - if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles! - if(prob(martial_art.deflection_chance)) - if(!lying && dna && !dna.check_mutation(HULK)) //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!") - playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) - return 0 + if(mind) + if(mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles! + if(prob(mind.martial_art.deflection_chance)) + if(!lying && dna && !dna.check_mutation(HULK)) //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!") + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) + return 0 if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) @@ -103,10 +104,11 @@ return 0 /mob/living/carbon/human/proc/check_block() - if(martial_art && martial_art.block_chance \ - && prob(martial_art.block_chance) && in_throw_mode \ - && !stat && !weakened && !stunned) - return TRUE + if(mind) + if(mind.martial_art && mind.martial_art.block_chance \ + && prob(mind.martial_art.block_chance) && in_throw_mode \ + && !stat && !weakened && !stunned) + return TRUE return FALSE /mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index f697215a4a..c1f5075b43 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -39,9 +39,6 @@ var/bleed_rate = 0 //how much are we bleeding var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding - var/datum/martial_art/martial_art = null - var/static/default_martial_art = new/datum/martial_art - var/name_override //For temporary visible name changes var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 3a4b241f10..0620ebd062 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -144,9 +144,9 @@ if(NOGUNS in src.dna.species.species_traits) to_chat(src, "Your fingers don't fit in the trigger guard!") return 0 - - if(martial_art && martial_art.no_guns) //great dishonor to famiry - to_chat(src, "Use of ranged weaponry would bring dishonor to the clan.") - return 0 + if(mind) + if(mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry + to_chat(src, "Use of ranged weaponry would bring dishonor to the clan.") + return 0 return . diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm new file mode 100644 index 0000000000..1ac24cffa9 --- /dev/null +++ b/code/modules/mob/living/carbon/human/login.dm @@ -0,0 +1,9 @@ +/mob/living/carbon/human/Login() + ..() + if(src.martial_art == default_martial_art && mind.stored_martial_art) //If the mind has a martial art stored and the body has the default one. + src.mind.stored_martial_art.teach(src) //Running teach so that it deals with help verbs. + else if(src.martial_art != default_martial_art && src.martial_art != mind.stored_martial_art) //If the body has a martial art which is not the default one and is not stored in the mind. + if(src.martial_art_owner != mind) + src.martial_art.remove(src) + else + src.mind.stored_martial_art = src.martial_art diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index b3f436ec68..cf92de53e1 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1304,7 +1304,7 @@ /datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) return -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) if(!istype(M)) return CHECK_DNA_AND_SPECIES(M) @@ -1312,6 +1312,8 @@ if(!istype(M)) //sanity check for drones. return + if(M.mind) + attacker_style = M.mind.martial_art if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK)) add_logs(M, H, "attempted to touch") H.visible_message("[M] attempted to touch [H]!") diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index aba76f570a..e5008b95d4 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -406,7 +406,7 @@ else reactive_teleport(H) -/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) +/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) ..() if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP) reactive_teleport(H) @@ -490,7 +490,7 @@ var/golem_name = "[uppertext(clown_name)]" return golem_name -/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) +/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) ..() if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(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 a390ecae71..e49ce03a29 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -123,8 +123,9 @@ 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) + if(H.mind.martial_art && prob(H.mind.martial_art.deflection_chance)) + . = TRUE /mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() dir_shots(GLOB.diagonals) diff --git a/tgstation.dme b/tgstation.dme index ad998e8286..1d35b890da 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -324,7 +324,11 @@ #include "code\datums\helper_datums\icon_snapshot.dm" #include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\topic_input.dm" +#include "code\datums\martial\boxing.dm" +#include "code\datums\martial\cqc.dm" #include "code\datums\martial\krav_maga.dm" +#include "code\datums\martial\plasma_fist.dm" +#include "code\datums\martial\sleeping_carp.dm" #include "code\datums\martial\wrestling.dm" #include "code\datums\ruins\lavaland.dm" #include "code\datums\ruins\space.dm"