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