diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 23d01e5a324..67b584a33eb 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -728,6 +728,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/twohanded/chainsaw
cost = 12
+/datum/uplink_item/dangerous/commando_kit
+ name = "Commandos knife operation kit"
+ desc = "A box that smells like a mix of gunpowder, napalm and cheap whiskey. Contains everything you need to survive in such places."
+ reference = "CK"
+ item = /obj/item/storage/box/syndie_kit/commando_kit
+ cost = 7
+ excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
// SUPPORT AND MECHAS
@@ -1095,7 +1102,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 8
uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
-
/datum/uplink_item/ammo/rocketHEDP
name = "84mm High Explosive Dual Purpose rocket"
desc = "A rocket from a rocketlauncher. This one emits shrapnel and incendiary ammunition. The rocket itself is strong enough to destroy station mechs and robots with one shot."
@@ -1104,6 +1110,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
cost = 6
uplinktypes = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
+/datum/uplink_item/ammo/knives_kit
+ name = "Throwing knives kit"
+ desc = "A box containing 7 throwing knives"
+ reference = "THR"
+ item = /obj/item/storage/box/syndie_kit/knives_kit
+ cost = 1
+ excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
+
// STEALTHY WEAPONS
/datum/uplink_item/stealthy_weapons
@@ -1629,6 +1643,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
item = /obj/item/clothing/accessory/holster
cost = 1
+/datum/uplink_item/device_tools/holster/knives
+ name = "Knife holster"
+ desc = "A bunch of straps connected into one holster. Has 7 special slots for holding knives."
+ reference = "KH"
+ item = /obj/item/clothing/accessory/holster/knives
+ cost = 2
+ excludefrom = list(UPLINK_TYPE_NUCLEAR, UPLINK_TYPE_SST)
+
/datum/uplink_item/device_tools/webbing
name = "Combat Webbing"
desc = "Sturdy mess of synthcotton belts and buckles, ready to share your burden."
diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm
index 362f35b0e74..2606ab3dfd3 100644
--- a/code/game/objects/effects/decals/contraband.dm
+++ b/code/game/objects/effects/decals/contraband.dm
@@ -45,6 +45,10 @@
poster_type = /obj/structure/sign/poster/contraband/syndicate_recruitment
icon_state = "rolled_poster"
+/obj/item/poster/commando
+ poster_type = /obj/structure/sign/poster/contraband/commando
+ icon_state = "rolled_poster"
+
//############################## THE ACTUAL DECALS ###########################
/obj/structure/sign/poster
@@ -387,6 +391,11 @@
desc = "You see a slightly battered poster, which shows a RED toolbox and the inscription \"Danger, very robust!\", some people say that this red paint on the poster is made of real blood."
icon_state = "poster36"
+/obj/structure/sign/poster/contraband/commando
+ name = "Commandos"
+ desc = "You see a muscular man in combat gear. Just the sight of this poster brings the scent of true masculinity."
+ icon_state = "poster37"
+
//official posters
/obj/structure/sign/poster/official
poster_item_name = "motivational poster"
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index e06cebbadb9..058fab5e506 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -175,6 +175,34 @@
bayonet = TRUE
embed_chance = 90
+/obj/item/kitchen/knife/combat/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, dodgeable = TRUE)
+ . = ..()
+ playsound(src, 'sound/weapons/knife_holster/knife_throw.ogg', 30, 1)
+
+/obj/item/kitchen/knife/combat/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
+ var/datum/martial_art/throwing/MA = throwingdatum?.thrower?.mind?.martial_art
+ if(istype(MA))
+ embed_chance = MA.knife_embed_chance
+ throwforce = initial(throwforce) + MA.knife_bonus_damage
+ . = ..()
+
+/obj/item/kitchen/knife/combat/after_throw(datum/callback/callback)
+ embed_chance = initial(embed_chance)
+ throwforce = initial(throwforce)
+ . = ..()
+
+/obj/item/kitchen/knife/combat/attack(mob/living/target, mob/living/user, def_zone)
+ var/datum/martial_art/throwing/MA = user?.mind?.martial_art
+ if(istype(MA))
+ force = initial(force) + MA.knife_bonus_damage
+ if(user.zone_selected == BODY_ZONE_HEAD && user.a_intent == INTENT_HARM)
+ MA.neck_cut(target, user)
+ . = ..()
+
+/obj/item/kitchen/knife/combat/afterattack(atom/target, mob/user, proximity, params)
+ force = initial(force)
+ . = ..()
+
/obj/item/kitchen/knife/combat/survival
name = "survival knife"
icon_state = "survivalknife"
@@ -183,13 +211,20 @@
force = 15
throwforce = 15
+/obj/item/kitchen/knife/combat/throwing
+ name = "Throwing knife"
+ desc = "A well-sharpened black knife. Designed to be thrown. It is made from a single piece of metal. The markings are scratched.\nAn excellent solution for live problems and cake cutting."
+ icon_state = "throwingknife"
+ item_state = "throwingknife"
+ belt_icon = "survival_knife"
+ force = 15
+ throwforce = 15
+
/obj/item/kitchen/knife/combat/survival/bone
name = "bone dagger"
item_state = "bone_dagger"
icon_state = "bone_dagger"
belt_icon = "bone_dagger"
- lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/items_righthand.dmi'
desc = "A sharpened bone. The bare minimum in survival."
materials = list()
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 08ac3fe940f..cae4c8899a1 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -502,3 +502,26 @@ To apply, hold the injector a short distance away from the outer thigh before ap
/obj/item/storage/box/syndie_kit/bowman_conversion_kit/populate_contents()
new /obj/item/encryptionkey/syndicate(src)
new /obj/item/bowman_conversion_tool(src)
+
+/obj/item/storage/box/syndie_kit/commando_kit
+ name = "Commandos knife operation kit"
+ desc = "A box that smells like a mix of gunpowder, napalm and cheap whiskey. Contains everything you need to survive in such places."
+ icon_state = "commandos_kit"
+
+/obj/item/storage/box/syndie_kit/commando_kit/populate_contents()
+ new /obj/item/throwing_manual(src)
+ new /obj/item/clothing/under/pants/camo/commando(src)
+ new /obj/item/clothing/shoes/combat/commando(src)
+ new /obj/item/clothing/head/commando(src)
+ new /obj/item/poster/commando(src)
+ new /obj/item/kitchen/knife/combat(src)
+ new /obj/item/kitchen/knife/combat(src)
+ new /obj/item/clothing/accessory/holster/knives(src)
+ new /obj/item/storage/box/syndie_kit/knives_kit(src)
+
+/obj/item/storage/box/syndie_kit/knives_kit
+ name = "Throwing knives kit"
+
+/obj/item/storage/box/syndie_kit/knives_kit/populate_contents()
+ for(var/i in 1 to 7)
+ new /obj/item/kitchen/knife/combat/throwing(src)
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index c64ad83c5cd..8d2c8200fbf 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -605,3 +605,9 @@
icon_state = "mr_chang_band"
item_state = "mr_chang_band"
+/obj/item/clothing/head/commando
+ name = "Red headband"
+ desc = "Simple red headband. Is that blood stains on it?"
+ w_class = WEIGHT_CLASS_TINY
+ icon_state = "commandos_band"
+ item_state = "commandos_band"
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 2107baae7f4..3799976ace4 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -533,3 +533,10 @@
desc = "Made of wood. Used to support world's economics stable."
icon_state = "mr_chang_sandals"
item_state = "mr_chang_sandals"
+
+/obj/item/clothing/shoes/combat/commando //basic syndicate combat boots for nuke ops and mob corpses
+ name = "Black military boots"
+ desc = "A pair of black military boots. They look really well-made. They have a metal sole, as if specially added to crush bones."
+ can_cut_open = FALSE
+ icon_state = "commandos_boots"
+ item_state = "commandos_boots"
diff --git a/code/modules/clothing/under/accessories/holster.dm b/code/modules/clothing/under/accessories/holster.dm
index 1fb324bd2fa..710c29e612c 100644
--- a/code/modules/clothing/under/accessories/holster.dm
+++ b/code/modules/clothing/under/accessories/holster.dm
@@ -4,83 +4,87 @@
icon_state = "holster"
item_color = "holster"
slot = ACCESSORY_SLOT_UTILITY
- var/holster_allow = /obj/item/gun
- var/obj/item/gun/holstered = null
+ w_class = WEIGHT_CLASS_NORMAL
actions_types = list(/datum/action/item_action/accessory/holster)
- w_class = WEIGHT_CLASS_NORMAL // so it doesn't fit in pockets
+ var/holster_allow = /obj/item/gun
+ var/list/holstered = list()
+ var/max_content = 1
+ var/sound_holster = 'sound/weapons/gun_interactions/1holster.ogg'
+ var/sound_unholster = 'sound/weapons/gun_interactions/1unholster.ogg'
/obj/item/clothing/accessory/holster/Destroy()
- if(holstered?.loc == src)
- QDEL_NULL(holstered)
- holstered = null
+ for(var/obj/item/I in holstered)
+ if(I.loc == src)
+ holstered -= I
+ QDEL_NULL(I)
return ..()
-//subtypes can override this to specify what can be holstered
-/obj/item/clothing/accessory/holster/proc/can_holster(obj/item/gun/W)
- if(!W.can_holster)
- return 0
- else if(!istype(W,holster_allow))
- return 0
- else if(W.w_class > WEIGHT_CLASS_NORMAL)
- return 0
- else
- return 1
+/obj/item/clothing/accessory/holster/proc/can_holster(obj/item/I)
+ if(!istype(I, holster_allow))
+ return FALSE
+ var/obj/item/gun/G = I
+ if(istype(G) && (!G.can_holster || G.w_class > WEIGHT_CLASS_NORMAL))
+ return FALSE
+ return TRUE
/obj/item/clothing/accessory/holster/attack_self(mob/user = usr)
var/holsteritem = user.get_active_hand()
- if(!holstered)
+ if(holsteritem)
holster(holsteritem, user)
else
unholster(user)
-/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user as mob)
- if(holstered)
- to_chat(user, "There is already a [holstered] holstered here!")
- return
-
- if(!istype(I, /obj/item/gun))
- to_chat(user, "Only guns can be holstered!")
+/obj/item/clothing/accessory/holster/proc/holster(obj/item/I, mob/user)
+ if(holstered.len >= max_content)
+ to_chat(user, span_warning("Holster is full!"))
return
- var/obj/item/gun/W = I
- if(!can_holster(W))
- to_chat(user, "This [W] won't fit in the [src]!")
+ if(!can_holster(I))
+ to_chat(user, span_warning("This [I] won't fit in the [src]!"))
return
- if(!user.can_unEquip(W))
- to_chat(user, "You can't let go of the [W]!")
+ if(!user.can_unEquip(I))
+ to_chat(user, span_warning("You can't let go of the [I]!"))
return
- holstered = W
- user.temporarily_remove_item_from_inventory(holstered)
- holstered.forceMove(src)
- holstered.add_fingerprint(user)
- user.visible_message("[user] holsters the [holstered].", "You holster the [holstered].")
- playsound(user.loc, 'sound/weapons/gun_interactions/1holster.ogg', 50, 1)
+ holstered += I
+ user.temporarily_remove_item_from_inventory(I)
+ I.forceMove(src)
+ I.add_fingerprint(user)
+ user.visible_message(span_notice("[user] holsters the [I]."), span_notice("You holster the [I]."))
+ playsound(user.loc, sound_holster, 50, 1)
-/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob)
- if(!holstered || user.stat == DEAD)
+/obj/item/clothing/accessory/holster/proc/unholster(mob/user)
+ if(!holstered.len)
+ to_chat(user, span_warning("Holster is empty!"))
return
- if(user.stat == UNCONSCIOUS)
- to_chat(user, "Вы не можете достать [holstered] сейчас!")
- return
+ var/obj/item/next_item = holstered[holstered.len]
+
+ if(isliving(user))
+ var/mob/living/L = user
+ if(L.IsStunned() || L.IsWeakened() || user.stat)
+ to_chat(user, span_warning("You can't get [next_item] now!"))
+ return
- if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
- to_chat(user, "You need an empty hand to draw the [holstered]!")
+ if(istype(user.get_active_hand(), /obj) && istype(user.get_inactive_hand(), /obj))
+ to_chat(user, span_warning("You need an empty hand to draw the [next_item]!"))
else
- if(user.a_intent == INTENT_HARM)
- usr.visible_message("[user] draws the [holstered], ready to shoot!", \
- "You draw the [holstered], ready to shoot!")
- else
- user.visible_message("[user] draws the [holstered], pointing it at the ground.", \
- "You draw the [holstered], pointing it at the ground.")
- user.put_in_hands(holstered)
- holstered.add_fingerprint(user)
- holstered = null
- playsound(user.loc, 'sound/weapons/gun_interactions/1unholster.ogg', 50, 1)
-
-/obj/item/clothing/accessory/holster/attack_hand(mob/user as mob)
+ user.put_in_hands(next_item)
+ next_item.add_fingerprint(user)
+ holstered -= next_item
+ unholster_message(user, next_item)
+ playsound(user.loc, sound_unholster, 50, 1)
+
+/obj/item/clothing/accessory/holster/proc/unholster_message(mob/user, obj/item/I)
+ if(user.a_intent == INTENT_HARM)
+ usr.visible_message(span_warning("[user] draws the [I], ready to shoot!"),
+ span_warning("You draw the [I], ready to shoot!"))
+ else
+ user.visible_message(span_notice("[user] draws the [I], pointing it at the ground."),
+ span_notice("You draw the [I], pointing it at the ground."))
+
+/obj/item/clothing/accessory/holster/attack_hand(mob/user)
if(has_suit) //if we are part of a suit
if(holstered)
unholster(user)
@@ -88,26 +92,29 @@
..(user)
-/obj/item/clothing/accessory/holster/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/item/clothing/accessory/holster/attackby(obj/item/W, mob/user, params)
+ if(istype(W, src.type))
+ return
holster(W, user)
/obj/item/clothing/accessory/holster/emp_act(severity)
- if(holstered)
- holstered.emp_act(severity)
+ for(var/obj/item/I in holstered)
+ I.emp_act(severity)
..()
/obj/item/clothing/accessory/holster/examine(mob/user)
- . = ..()
- if(holstered)
- . += "A [holstered] is holstered here."
+ . = ..(user)
+ if(holstered.len)
+ for(var/obj/item/I in holstered)
+ . += span_notice("A [I] is holstered here.")
else
- . += "It is empty."
+ . += span_notice("It is empty.")
-/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user as mob)
+/obj/item/clothing/accessory/holster/on_attached(obj/item/clothing/under/S, mob/user)
..()
has_suit.verbs += /obj/item/clothing/accessory/holster/verb/holster_verb
-/obj/item/clothing/accessory/holster/on_removed(mob/user as mob)
+/obj/item/clothing/accessory/holster/on_removed(mob/user)
has_suit.verbs -= /obj/item/clothing/accessory/holster/verb/holster_verb
..()
@@ -128,16 +135,9 @@
H = locate() in S.accessories
if(!H)
- to_chat(usr, "Something is very wrong.")
+ return
- if(!H.holstered)
- if(!istype(usr.get_active_hand(), /obj/item/gun))
- to_chat(usr, "You need your gun equiped to holster it.")
- return
- var/obj/item/gun/W = usr.get_active_hand()
- H.holster(W, usr)
- else
- H.unholster(usr)
+ H.attack_self(usr)
/obj/item/clothing/accessory/holster/armpit
name = "shoulder holster"
@@ -151,3 +151,22 @@
desc = "A handgun holster. Made of expensive leather."
icon_state = "holster"
item_color = "holster_low"
+
+/obj/item/clothing/accessory/holster/knives
+ name = "Knife holster"
+ desc = "A bunch of straps connected into one holster. Has 7 special slots for holding knives."
+ icon_state = "holsterknife"
+ item_color = "holsterknife"
+ holster_allow = /obj/item/kitchen/knife/combat
+ max_content = 7
+ sound_holster = 'sound/weapons/knife_holster/knife_holster.ogg'
+ sound_unholster = 'sound/weapons/knife_holster/knife_unholster.ogg'
+
+
+/obj/item/clothing/accessory/holster/knives/unholster_message(mob/user, obj/item/I)
+ if(user.a_intent == INTENT_HARM)
+ user.visible_message(span_warning("[user] takes the [I] out, ready to throw!"),
+ span_warning("You takes the [I] out, [holstered.len] knives left!"))
+ else
+ user.visible_message(span_notice("[user] takes the [I] out."),
+ span_notice("You takes the [I] out, [holstered.len] knives left"))
diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm
index 217ecd75671..a3055972b10 100644
--- a/code/modules/clothing/under/pants.dm
+++ b/code/modules/clothing/under/pants.dm
@@ -91,3 +91,6 @@
desc = "A pair of woodland camouflage pants. Probably not the best choice for a space station."
icon_state = "camopants"
item_color = "camopants"
+
+/obj/item/clothing/under/pants/camo/commando
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
diff --git a/code/modules/martial_arts/combos/throwing/remove_embended.dm b/code/modules/martial_arts/combos/throwing/remove_embended.dm
new file mode 100644
index 00000000000..c90c180134c
--- /dev/null
+++ b/code/modules/martial_arts/combos/throwing/remove_embended.dm
@@ -0,0 +1,34 @@
+/datum/martial_combo/throwing/remove_embended
+ name = "Вытащить нож"
+ steps = list(MARTIAL_COMBO_STEP_GRAB, MARTIAL_COMBO_STEP_GRAB)
+ explaination_text = "Вытаскивает из противника воткнувшийся предмет. Крайне мучительно для него."
+
+/datum/martial_combo/throwing/remove_embended/perform_combo(mob/living/carbon/human/user, mob/living/target, datum/martial_art/MA)
+ var/mob/living/carbon/human/H = target
+ if(!istype(H))
+ return MARTIAL_COMBO_FAIL
+
+ for(var/obj/item/organ/external/limb in H.bodyparts)
+ var/obj/item/I = locate() in limb.embedded_objects
+ if(!istype(I) || I.loc != H)
+ continue
+
+ var/time_taken = I.embedded_unsafe_removal_time
+ user.visible_message(span_warning("[user] attempts to remove [I] from [H]'s [limb.name]."),
+ span_notice("You attempt to remove [I] from [H]'s [limb.name]... (It will take [time_taken/10] seconds.)"))
+
+ if(do_after(user, time_taken, needhand = 1, target = H))
+ if(!I || !limb || I.loc != H || !(I in limb.embedded_objects))
+ return MARTIAL_COMBO_FAIL
+ limb.embedded_objects -= I
+ limb.receive_damage(I.embedded_unsafe_removal_pain_multiplier * I.w_class)
+ I.forceMove(get_turf(H))
+ user.put_in_hands(I)
+ H.emote("scream")
+ user.visible_message(span_notice("[user] successfully rips [I] out of [H]'s [limb.name]!"),
+ span_notice("You successfully remove [I] from [H]'s [limb.name]."))
+ if(!H.has_embedded_objects())
+ H.clear_alert("embeddedobject")
+ add_attack_logs(user, target, "Melee attacked with martial-art [MA] : Remove embended", ATKLOG_ALL)
+ return MARTIAL_COMBO_DONE
+ return MARTIAL_COMBO_FAIL
diff --git a/code/modules/martial_arts/martial.dm b/code/modules/martial_arts/martial.dm
index 8cd8ad9ab46..cd8a4d8bf7a 100644
--- a/code/modules/martial_arts/martial.dm
+++ b/code/modules/martial_arts/martial.dm
@@ -140,7 +140,7 @@
D.forcesay(GLOB.hit_appends)
return TRUE
-/datum/martial_art/proc/attack_reaction(var/mob/living/carbon/human/defender, var/mob/living/carbon/human/attacker, var/obj/item/I, var/visible_message, var/self_message)
+/datum/martial_art/proc/attack_reaction(mob/living/carbon/human/defender, mob/living/carbon/human/attacker, obj/item/I, visible_message, self_message)
if(can_use(defender) && defender.in_throw_mode && !defender.incapacitated(FALSE, TRUE))
if(prob(block_chance))
if(visible_message || self_message)
@@ -149,6 +149,9 @@
defender.visible_message("[defender] blocks [I]!")
return TRUE
+/datum/martial_art/proc/user_hit_by(atom/movable/AM, mob/living/carbon/human/H)
+ return FALSE
+
/datum/martial_art/proc/objective_damage(mob/living/user, mob/living/target, damage, damage_type)
var/all_objectives = user?.mind?.get_all_objectives()
if(target.mind && all_objectives)
@@ -399,6 +402,24 @@
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
+/obj/item/throwing_manual
+ name = "Commandos knife techniques manual"
+ desc = "This is a thin black book. On the front there is a picture of a man with knives. \nContains a guide for learning the commandos knife technique with a visual representation of the application of the techniques."
+ icon = 'icons/obj/library.dmi'
+ icon_state = "throwingknives"
+
+/obj/item/throwing_manual/attack_self(mob/living/carbon/human/user)
+ if(!istype(user) || !user)
+ return
+ to_chat(user, "You remember the basics of knife throwing.")
+
+ var/datum/martial_art/throwing/MA = new
+ MA.teach(user)
+ user.temporarily_remove_item_from_inventory(src)
+ 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/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."
diff --git a/code/modules/martial_arts/throwing_knives.dm b/code/modules/martial_arts/throwing_knives.dm
new file mode 100644
index 00000000000..5a2d65cf997
--- /dev/null
+++ b/code/modules/martial_arts/throwing_knives.dm
@@ -0,0 +1,51 @@
+/datum/martial_art/throwing
+ name = "Knife techniques"
+ combos = list(/datum/martial_combo/throwing/remove_embended)
+ block_chance = 50 //if holding knife in hand
+ has_explaination_verb = TRUE
+ var/knife_embed_chance = 100
+ var/knife_bonus_damage = 5
+
+/datum/martial_art/throwing/attack_reaction(mob/living/carbon/human/defender, mob/living/carbon/human/attacker, obj/item/I, visible_message, self_message)
+ if(can_use(defender) \
+ && !defender.incapacitated(FALSE, TRUE) \
+ && (istype(defender.get_active_hand(), /obj/item/kitchen/knife/combat) || istype(defender.get_inactive_hand(), /obj/item/kitchen/knife/combat)) \
+ && prob(block_chance))
+ if(visible_message || self_message)
+ defender.visible_message(visible_message, self_message)
+ else
+ defender.visible_message(span_warning("[defender] blocks [I]!"))
+ return TRUE
+
+/datum/martial_art/throwing/user_hit_by(atom/movable/AM, mob/living/carbon/human/H)
+ if(istype(AM, /obj/item/kitchen/knife/combat))
+ H.put_in_hands(AM)
+ H.visible_message(span_warning("[H] catches [AM]!"))
+ return TRUE
+ return FALSE
+
+/datum/martial_art/throwing/proc/neck_cut(mob/living/carbon/human/defender, mob/living/carbon/human/attacker)
+ var/obj/item/grab/grab = attacker.get_inactive_hand()
+ if(istype(grab) && grab.state >= GRAB_NECK && grab.affecting == defender && defender.dna && !(NO_BLOOD in defender.dna.species.species_traits))
+ attacker.visible_message(span_danger("[attacker] прикладывает нож к горлу [defender]!"), span_danger("Вы прикладываете нож к горлу [defender]!."))
+ if(do_after(attacker, 20, target = defender))
+ if(defender.blood_volume > BLOOD_VOLUME_SURVIVE)
+ defender.blood_volume -= BLOOD_VOLUME_NORMAL - BLOOD_VOLUME_SURVIVE
+ for(var/i in 1 to 2)
+ var/obj/effect/decal/cleanable/blood/B = new(defender.loc)
+ step(B, pick(GLOB.alldirs))
+ if(istype(attacker.l_hand, /obj/item/grab))
+ attacker.drop_l_hand()
+ else if(istype(attacker.r_hand, /obj/item/grab))
+ attacker.drop_r_hand()
+ var/sound = pick('sound/weapons/knife_holster/throat_slice.ogg','sound/weapons/knife_holster/throat_slice2.ogg')
+ playsound(defender.loc, sound, 25, 1)
+ attacker.visible_message(span_danger("[attacker] перерезает глотку [defender]! Ахуй."), span_danger("Вы перерезаете глотку [defender]! Ахуй."))
+
+/datum/martial_art/throwing/explaination_footer(user)
+ to_chat(user, "[span_notice("Работает с ножами")]: Боевой, шахтёрский, костяной, метательный")
+ to_chat(user, "[span_notice("Урон")]: +5 урона от бросков и ударов ножей")
+ to_chat(user, "[span_notice("Застревание")]: ножи застревают в жертве со 100% вероятностью")
+ to_chat(user, "[span_notice("Блок")]: 50% блока мили атак, пока в руках есть нож")
+ to_chat(user, "[span_notice("Поймать нож")]: Вы ловите все кинутые в вас ножи")
+ to_chat(user, "[span_notice("Перерезать глотку")]: Атака ножом в харме цели, которая находится в красном грабе уменьшит уровень крови жертвы на 70%")
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index b766c47c73d..322018c9062 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -518,7 +518,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
sharp = TRUE
. = ..()
-/obj/item/stack/spacecash/after_throw(datum/callback/callback)
+/obj/item/coin/after_throw(datum/callback/callback)
embed_chance = initial(embed_chance)
embedded_impact_pain_multiplier = initial(embedded_impact_pain_multiplier)
embedded_ignore_throwspeed_threshold = initial(embedded_ignore_throwspeed_threshold)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index cb050c4610a..ebe405a7a94 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -256,7 +256,7 @@ emp_act
return 1
return 0
-/mob/living/carbon/human/proc/check_martial_art_defense(var/mob/living/carbon/human/defender, var/mob/living/carbon/human/attacker, var/obj/item/I, var/visible_message, var/self_message)
+/mob/living/carbon/human/proc/check_martial_art_defense(mob/living/carbon/human/defender, mob/living/carbon/human/attacker, obj/item/I, visible_message, self_message)
if(mind && mind.martial_art)
return mind.martial_art.attack_reaction(defender, attacker, I, visible_message, self_message)
@@ -551,6 +551,10 @@ emp_act
if(spec_return)
return spec_return
+ var/MA_return = mind?.martial_art?.user_hit_by(AM, src)
+ if(MA_return)
+ return MA_return
+
var/obj/item/I
var/throwpower = 30
if(isitem(AM))
diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm
index 99e1d5458a6..f03d2c09ddb 100644
--- a/code/modules/research/designs/biogenerator_designs.dm
+++ b/code/modules/research/designs/biogenerator_designs.dm
@@ -171,6 +171,14 @@
build_path = /obj/item/clothing/accessory/holster
category = list("initial","Leather and Cloth")
+/datum/design/k_holster
+ name = "Knife holster"
+ id = "k_holster"
+ build_type = BIOGENERATOR
+ materials = list(MAT_BIOMASS = 400)
+ build_path = /obj/item/clothing/accessory/holster/knives
+ category = list("initial","Leather and Cloth")
+
/datum/design/webbing
name = "Webbing"
id = "webbing"
diff --git a/icons/mob/clothing/feet.dmi b/icons/mob/clothing/feet.dmi
index 6b6d0b58884..dae5962d6a0 100644
Binary files a/icons/mob/clothing/feet.dmi and b/icons/mob/clothing/feet.dmi differ
diff --git a/icons/mob/clothing/head.dmi b/icons/mob/clothing/head.dmi
index 8df04c07775..25f47bdd889 100644
Binary files a/icons/mob/clothing/head.dmi and b/icons/mob/clothing/head.dmi differ
diff --git a/icons/mob/clothing/species/drask/head.dmi b/icons/mob/clothing/species/drask/head.dmi
index 79b47e57efe..981e8f20858 100644
Binary files a/icons/mob/clothing/species/drask/head.dmi and b/icons/mob/clothing/species/drask/head.dmi differ
diff --git a/icons/mob/clothing/species/drask/shoes.dmi b/icons/mob/clothing/species/drask/shoes.dmi
index fc09fddbdba..a07ea67d0c7 100644
Binary files a/icons/mob/clothing/species/drask/shoes.dmi and b/icons/mob/clothing/species/drask/shoes.dmi differ
diff --git a/icons/mob/clothing/species/grey/head.dmi b/icons/mob/clothing/species/grey/head.dmi
index f8e7443ead1..90b20b580a9 100644
Binary files a/icons/mob/clothing/species/grey/head.dmi and b/icons/mob/clothing/species/grey/head.dmi differ
diff --git a/icons/mob/clothing/species/monkey/head.dmi b/icons/mob/clothing/species/monkey/head.dmi
index d032ab11817..7dbaa64cfd8 100644
Binary files a/icons/mob/clothing/species/monkey/head.dmi and b/icons/mob/clothing/species/monkey/head.dmi differ
diff --git a/icons/mob/clothing/species/monkey/shoes.dmi b/icons/mob/clothing/species/monkey/shoes.dmi
index 09c4e0ba395..c654088b02e 100644
Binary files a/icons/mob/clothing/species/monkey/shoes.dmi and b/icons/mob/clothing/species/monkey/shoes.dmi differ
diff --git a/icons/mob/clothing/species/unathi/shoes.dmi b/icons/mob/clothing/species/unathi/shoes.dmi
index 29dff6b6c3f..55f45b16d97 100644
Binary files a/icons/mob/clothing/species/unathi/shoes.dmi and b/icons/mob/clothing/species/unathi/shoes.dmi differ
diff --git a/icons/mob/clothing/species/vox/head.dmi b/icons/mob/clothing/species/vox/head.dmi
index 48d1251cc5b..7c6a00a9505 100644
Binary files a/icons/mob/clothing/species/vox/head.dmi and b/icons/mob/clothing/species/vox/head.dmi differ
diff --git a/icons/mob/clothing/species/vox/shoes.dmi b/icons/mob/clothing/species/vox/shoes.dmi
index 7ce01f8fa58..e2c9f4ac3ee 100644
Binary files a/icons/mob/clothing/species/vox/shoes.dmi and b/icons/mob/clothing/species/vox/shoes.dmi differ
diff --git a/icons/mob/clothing/ties.dmi b/icons/mob/clothing/ties.dmi
index bbbded05ba9..c564ca8af55 100644
Binary files a/icons/mob/clothing/ties.dmi and b/icons/mob/clothing/ties.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index ca2fecbf8b7..c9ecc13169f 100755
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index 05225b13cf6..27f9be00976 100755
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 34d42029229..2e7a23dacd9 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index 816d47e1919..b70ad8a1101 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/clothing/ties.dmi b/icons/obj/clothing/ties.dmi
index 8a650af4f19..61cfc3d7ed8 100644
Binary files a/icons/obj/clothing/ties.dmi and b/icons/obj/clothing/ties.dmi differ
diff --git a/icons/obj/contraband.dmi b/icons/obj/contraband.dmi
index 544c0988f8c..ab98d836141 100644
Binary files a/icons/obj/contraband.dmi and b/icons/obj/contraband.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index 73d0459c0a5..6a6fefc6fc0 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 7ca87274af2..58bb9c7e12e 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 241e8733d1f..f21a36b69c0 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 971f22d0c35..ead123850c8 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2002,6 +2002,7 @@
#include "code\modules\martial_arts\plasma_fist.dm"
#include "code\modules\martial_arts\sleeping_carp.dm"
#include "code\modules\martial_arts\synthojitsu.dm"
+#include "code\modules\martial_arts\throwing_knives.dm"
#include "code\modules\martial_arts\wrestling.dm"
#include "code\modules\martial_arts\combos\martial_combo.dm"
#include "code\modules\martial_arts\combos\adminfu\healing_palm.dm"
@@ -2027,6 +2028,7 @@
#include "code\modules\martial_arts\combos\synthojitsu\lock.dm"
#include "code\modules\martial_arts\combos\synthojitsu\overload.dm"
#include "code\modules\martial_arts\combos\synthojitsu\reanimate.dm"
+#include "code\modules\martial_arts\combos\throwing\remove_embended.dm"
#include "code\modules\mining\abandonedcrates.dm"
#include "code\modules\mining\fulton.dm"
#include "code\modules\mining\machine_processing.dm"
diff --git a/sound/weapons/knife_holster/knife_holster.ogg b/sound/weapons/knife_holster/knife_holster.ogg
new file mode 100644
index 00000000000..2ed7f9e45b5
Binary files /dev/null and b/sound/weapons/knife_holster/knife_holster.ogg differ
diff --git a/sound/weapons/knife_holster/knife_throw.ogg b/sound/weapons/knife_holster/knife_throw.ogg
new file mode 100644
index 00000000000..1c567055814
Binary files /dev/null and b/sound/weapons/knife_holster/knife_throw.ogg differ
diff --git a/sound/weapons/knife_holster/knife_unholster.ogg b/sound/weapons/knife_holster/knife_unholster.ogg
new file mode 100644
index 00000000000..6eeb9674a98
Binary files /dev/null and b/sound/weapons/knife_holster/knife_unholster.ogg differ
diff --git a/sound/weapons/knife_holster/throat_slice.ogg b/sound/weapons/knife_holster/throat_slice.ogg
new file mode 100644
index 00000000000..d653a73b909
Binary files /dev/null and b/sound/weapons/knife_holster/throat_slice.ogg differ
diff --git a/sound/weapons/knife_holster/throat_slice2.ogg b/sound/weapons/knife_holster/throat_slice2.ogg
new file mode 100644
index 00000000000..87efe275638
Binary files /dev/null and b/sound/weapons/knife_holster/throat_slice2.ogg differ