/datum/martial_art var/name = "Martial Art" var/streak = "" var/max_streak_length = 6 var/current_target = null var/temporary = 0 var/datum/martial_art/base = null // The permanent style var/deflection_chance = 0 //Chance to deflect projectiles var/help_verb = null /datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) return 0 /datum/martial_art/proc/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) return 0 /datum/martial_art/proc/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) return 0 /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/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) A.do_attack_animation(D) var/damage = rand(A.species.punchdamagelow, A.species.punchdamagehigh) var/datum/unarmed_attack/attack = A.species.unarmed var/atk_verb = "[pick(attack.attack_verb)]" if(D.lying) atk_verb = "kick" if(!damage) playsound(D.loc, attack.miss_sound, 25, 1, -1) D.visible_message("[A] has attempted to [atk_verb] [D]!") return 0 var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") playsound(D.loc, attack.attack_sound, 25, 1, -1) D.visible_message("[A] has [atk_verb]ed [D]!", \ "[A] has [atk_verb]ed [D]!") D.apply_damage(damage, BRUTE, affecting, armor_block) add_logs(D, A, "punched") if((D.stat != DEAD) && damage >= A.species.punchstunthreshold) D.visible_message("[A] has weakened [D]!!", \ "[A] has weakened [D]!") D.apply_effect(4, WEAKEN, armor_block) D.forcesay(hit_appends) else if(D.lying) D.forcesay(hit_appends) return 1 /datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) if(help_verb) H.verbs += help_verb if(make_temporary) temporary = 1 if(temporary) if(H.martial_art) base = H.martial_art.base else base = src H.martial_art = src /datum/martial_art/proc/remove(var/mob/living/carbon/human/H) if(H.martial_art != src) return H.martial_art = base if(help_verb) H.verbs -= help_verb /datum/martial_art/boxing name = "Boxing" /datum/martial_art/boxing/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) to_chat(A, "Can't disarm while boxing!") return 1 /datum/martial_art/boxing/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) to_chat(A, "Can't grab while boxing!") return 1 /datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) A.do_attack_animation(D) var/atk_verb = pick("left hook","right hook","straight punch") var/damage = rand(5, 8) + A.species.punchdamagelow if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") add_logs(D, A, "attempted to hit", atk_verb) return 0 var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) D.visible_message("[A] has hit [D] with a [atk_verb]!", \ "[A] has hit [D] with a [atk_verb]!") D.apply_damage(damage, STAMINA, affecting, armor_block) add_logs(D, A, "punched") 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(hit_appends) else if(D.lying) D.forcesay(hit_appends) return 1 /datum/martial_art/drunk_brawling name = "Drunken Brawling" /datum/martial_art/drunk_brawling/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(prob(70)) A.visible_message("[A] tries to grab ahold of [D], but fails!", \ "You fail to grab ahold of [D]!") return 1 D.grabbedby(A,1) var/obj/item/weapon/grab/G = A.get_active_hand() if(G) D.visible_message("[A] grabs ahold of [D] drunkenly!", \ "[A] grabs ahold of [D] drunkenly!") return 1 /datum/martial_art/drunk_brawling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) add_logs(D, A, "punched") A.do_attack_animation(D) var/atk_verb = pick("jab","uppercut","overhand punch","drunken right hook","drunken left hook") var/damage = rand(0,6) if(atk_verb == "uppercut") if(prob(90)) damage = 0 else //10% chance to do a massive amount of damage damage = 14 if(prob(50)) //they are drunk, they aren't going to land half of their hits damage = 0 if(!damage) playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") return 1 //returns 1 so that they actually miss and don't switch to attackhand damage var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) D.visible_message("[A] has hit [D] with a [atk_verb]!", \ "[A] has hit [D] with a [atk_verb]!") D.apply_damage(damage, BRUTE, null, armor_block) D.apply_effect(damage, STAMINA, armor_block) 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.Paralyse(5) D.forcesay(hit_appends) else if(D.lying) D.forcesay(hit_appends) return 1 /datum/martial_art/wrestling name = "Wrestling" help_verb = /mob/living/carbon/human/proc/wrestling_help // combo refence since wrestling uses a different format to sleeping carp and plasma fist. // Clinch "G" // Suplex "GD" // Advanced grab "G" /datum/martial_art/wrestling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) D.grabbedby(A,1) var/obj/item/weapon/grab/G = A.get_active_hand() if(G && prob(50)) G.state = GRAB_AGGRESSIVE D.visible_message("[A] has [D] in a clinch!", \ "[A] has [D] in a clinch!") else D.visible_message("[A] fails to get [D] in a clinch!", \ "[A] fails to get [D] in a clinch!") return 1 /datum/martial_art/wrestling/proc/Suplex(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) D.visible_message("[A] suplexes [D]!", \ "[A] suplexes [D]!") D.forceMove(A.loc) var/armor_block = D.run_armor_check(null, "melee") D.apply_damage(30, BRUTE, null, armor_block) D.apply_effect(6, WEAKEN, armor_block) add_logs(D, A, "suplexed") A.SpinAnimation(10,1) D.SpinAnimation(10,1) spawn(3) armor_block = A.run_armor_check(null, "melee") A.apply_effect(4, WEAKEN, armor_block) return /datum/martial_art/wrestling/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) if(istype(A.get_inactive_hand(),/obj/item/weapon/grab)) var/obj/item/weapon/grab/G = A.get_inactive_hand() if(G.affecting == D) Suplex(A,D) return 1 harm_act(A,D) return 1 /datum/martial_art/wrestling/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) D.grabbedby(A,1) D.visible_message("[A] holds [D] down!", \ "[A] holds [D] down!") var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) var/armor_block = D.run_armor_check(affecting, "melee") D.apply_damage(10, STAMINA, affecting, armor_block) 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(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) 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 /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 basic_hit(A,D) return 1 /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 basic_hit(A,D) return 1 /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 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 help_verb = /mob/living/carbon/human/proc/sleeping_carp_help /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.weakened) A.do_attack_animation(D) 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 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.weakened) A.do_attack_animation(D) 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 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.weakened) A.do_attack_animation(D) 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 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.weakened) A.do_attack_animation(D) 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 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.weakened || D.resting || D.stat) A.do_attack_animation(D) 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 return basic_hit(A,D) /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 D.grabbedby(A,1) var/obj/item/weapon/grab/G = A.get_active_hand() if(G) G.state = GRAB_AGGRESSIVE //Instant aggressive grab /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) 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) 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" 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.") //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) to_chat(user, "You have an urge to flex your muscles and get into a fight. You have the knowledge of a thousand wrestlers before you. You can remember more by using the Recall teaching verb in the wrestling tab.") 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) to_chat(user, "You no longer have an urge to flex your muscles.") 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 as mob) 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/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 as mob) if(!istype(user) || !user) return to_chat(user, "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.") 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 = 4 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" /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_organ_damage(2*force) return if(isrobot(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 switch(user.a_intent) if("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 <= config.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) return else return ..() return ..() /obj/item/weapon/twohanded/bostaff/IsShield() if(wielded) return 1 else return 0