#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" id = MARTIALART_CQC help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 var/just_a_cook = FALSE 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/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.stat || !D.IsKnockdown()) 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.Knockdown(120) log_combat(A, D, "slammed (CQC)") return TRUE /datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D) if(!can_use(A)) return FALSE if(!D.stat || !D.IsKnockdown()) 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) log_combat(A, D, "kicked (CQC)") if(D.IsKnockdown() && !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(300) D.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150) 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) 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(100) restraining = TRUE addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE) 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_held_item() if(I && D.temporarilyRemoveItemFromInventory(I)) A.put_in_hands(I) D.adjustStaminaLoss(50) D.apply_damage(25, BRUTE) 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 if(A.grab_state >= GRAB_AGGRESSIVE) D.grabbedby(A, 1) else A.start_pulling(D, 1) if(A.pulling) D.stop_pulling() log_combat(A, D, "grabbed", addition="aggressively") A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab 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 log_combat(A, D, "attacked (CQC)") A.do_attack_animation(D) var/picked_hit_type = pick("CQC'd", "Big Bossed") var/bonus_damage = 13 if(D.IsKnockdown() || 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!") log_combat(A, D, "[picked_hit_type] (CQC)") if(A.resting && !D.stat && !D.IsKnockdown()) 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.Knockdown(60) log_combat(A, D, "sweeped (CQC)") 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 if(prob(65)) if(!D.stat || !D.IsKnockdown() || !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.temporarilyRemoveItemFromInventory(I)) 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) log_combat(A, D, "disarmed (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(400) restraining = FALSE if(A.grab_state < GRAB_NECK) A.grab_state = GRAB_NECK else restraining = FALSE return FALSE 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.") to_chat(usr, "Slam: Grab Harm. Slam opponent into the ground, knocking them down.") to_chat(usr, "CQC Kick: Disarm Harm Harm. Knocks opponent away. Knocks out stunned or knocked down 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.")