diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm index cb4a43321..e0eace8db 100644 --- a/code/__DEFINES/melee.dm +++ b/code/__DEFINES/melee.dm @@ -7,4 +7,5 @@ #define MARTIALART_MUSHPUNCH "mushroom punch" #define MARTIALART_KRAVMAGA "krav maga" #define MARTIALART_CQC "CQC" -#define MARTIALART_PLASMAFIST "plasma fist" \ No newline at end of file +#define MARTIALART_PLASMAFIST "plasma fist" +#define MARTIALART_KNS_CQC "KNS CQC" diff --git a/code/datums/martial/kinaris.dm b/code/datums/martial/kinaris.dm new file mode 100644 index 000000000..fed965802 --- /dev/null +++ b/code/datums/martial/kinaris.dm @@ -0,0 +1,116 @@ +#define KNS_KICK_COMBO "DG" +#define KNS_RESTRAIN_COMBO "GG" + +/datum/martial_art/kinaris + name = "KNS CQC" + id = MARTIALART_KNS_CQC + help_verb = /mob/living/carbon/human/proc/KNS_CQC_help + block_chance = 75 + +/datum/martial_art/kinaris/proc/drop_restraining() + restraining = FALSE + +/datum/martial_art/kinaris/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D) + if(!can_use(A)) + return FALSE + if(findtext(streak,KNS_KICK_COMBO)) + streak = "" + Kick(A,D) + return TRUE + if(findtext(streak,KNS_RESTRAIN_COMBO)) + streak = "" + Restrain(A,D) + return TRUE + return FALSE + +/datum/martial_art/kinaris/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 (KNS 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/kinaris/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/kinaris/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/kinaris/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 (KNS 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/KNS_CQC_help() + set name = "Remember The Basics" + set desc = "You try to remember some of the basics of training." + set category = "KNS CQC" + to_chat(usr, "You try to remember some of your training, undertaken when entering Kinaris employ.") + + to_chat(usr, "CQC Kick: Disarm Grab. 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.") diff --git a/code/game/objects/items/implants/implant_kinaris.dm b/code/game/objects/items/implants/implant_kinaris.dm new file mode 100644 index 000000000..3a2039ab8 --- /dev/null +++ b/code/game/objects/items/implants/implant_kinaris.dm @@ -0,0 +1,38 @@ +/obj/item/implant/kinaris + name = "KNS ENH implant" + desc = "Enables enhanced reflexes, permitting the user to deploy specialised training." + icon = 'icons/obj/implants.dmi' + icon_state ="adrenal" + activated = 1 + var/datum/martial_art/kinaris/style = new + +/obj/item/implant/kinaris/get_data() + var/dat = {"Implant Specifications:
+ Name: KNS ENH Implant
+ Life: Roughly twelve hours after death of host
+ Implant Details:
+ Function: Forces certain sections of the brain and body into a state of higher function, permitting the user to deploy specialised training."} + return dat + +/obj/item/implant/kinaris/activate() + . = ..() + var/mob/living/carbon/human/H = imp_in + if(!ishuman(H)) + return + if(!H.mind) + return + if(H.mind.has_martialart(MARTIALART_KNS_CQC)) + style.remove(H) + to_chat(H, "You disable your reflex implant.") + else + style.teach(H,1) + to_chat(H, "You feel your body burn briefly as you enable your reflex implant.") + +/obj/item/implanter/kinaris + name = "implanter (KNS ENH)" + imp_type = /obj/item/implant/kinaris + +/obj/item/implantcase/kinaris + name = "implant case - 'KNS ENH'" + desc = "A glass case containing an implant that can enhance the body of the user." + imp_type = /obj/item/implant/kinaris diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 1565ab437..f568378c1 100644 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -65,7 +65,7 @@ Captain satchel = /obj/item/storage/backpack/satchel/cap duffelbag = /obj/item/storage/backpack/duffelbag/captain - implants = list(/obj/item/implant/mindshield) + implants = list(/obj/item/implant/mindshield, /obj/item/implant/kinaris) accessory = /obj/item/clothing/accessory/medal/gold/captain chameleon_extras = list(/obj/item/gun/energy/e_gun, /obj/item/stamp/captain) diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index 0b18fd650..c199641ff 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -62,7 +62,7 @@ Head of Security duffelbag = /obj/item/storage/backpack/duffelbag/sec box = /obj/item/storage/box/security - implants = list(/obj/item/implant/mindshield) + implants = list(/obj/item/implant/mindshield, /obj/item/implant/kinaris) chameleon_extras = list(/obj/item/gun/energy/e_gun/hos, /obj/item/stamp/hos) diff --git a/tgstation.dme b/tgstation.dme index d78010587..3d8ea6179 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -510,6 +510,7 @@ #include "code\datums\looping_sounds\weather.dm" #include "code\datums\martial\boxing.dm" #include "code\datums\martial\cqc.dm" +#include "code\datums\martial\kinaris.dm" #include "code\datums\martial\krav_maga.dm" #include "code\datums\martial\mushpunch.dm" #include "code\datums\martial\plasma_fist.dm" @@ -983,6 +984,7 @@ #include "code\game\objects\items\implants\implant_exile.dm" #include "code\game\objects\items\implants\implant_explosive.dm" #include "code\game\objects\items\implants\implant_freedom.dm" +#include "code\game\objects\items\implants\implant_kinaris.dm" #include "code\game\objects\items\implants\implant_krav_maga.dm" #include "code\game\objects\items\implants\implant_mindshield.dm" #include "code\game\objects\items\implants\implant_misc.dm"