diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 57c77e5983..beb62d0ed1 100755 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -541,6 +541,25 @@ /obj/item/ammo_casing/shotgun )) +/obj/item/storage/belt/medolier + name = "medolier" + desc = "A medical bandolier for holding smartdarts." + icon_state = "medolier" + item_state = "medolier" + +/obj/item/storage/belt/medolier/ComponentInitialize() + . = ..() + GET_COMPONENT(STR, /datum/component/storage) + STR.max_items = 15 + STR.display_numerical_stacking = FALSE + STR.can_hold = typecacheof(list( + /obj/item/reagent_containers/syringe/dart + )) + +/obj/item/storage/belt/medolier/full/PopulateContents() + for(var/i in 1 to 16) + new /obj/item/reagent_containers/syringe/dart/(src) + /obj/item/storage/belt/holster name = "shoulder holster" desc = "A holster to carry a handgun and ammo. WARNING: Badasses only." diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index c1cc6d856e..a76be1ff45 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -790,3 +790,36 @@ /datum/reagent/water = 15) time = 40 category = CAT_MISC + +/datum/crafting_recipe/smartdart + name = "Medical smartdart" + result = /obj/item/reagent_containers/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/sheet/glass = 1, + /obj/item/stack/sheet/plastic = 1) + time = 10 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/medolier + name = "Medolier" + result = /obj/item/storage/belt/medolier + reqs = list(/obj/item/stack/sheet/metal = 2, + /obj/item/stack/sheet/cloth = 3, + /obj/item/stack/sheet/plastic = 4) + time = 30 + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/smartdartgun + name = "Smart dartgun" + result = /obj/item/gun/syringe/dart + reqs = list(/obj/item/stack/sheet/metal = 15, + /obj/item/stack/sheet/glass = 10, + /obj/item/tank/internals = 1, + /obj/item/reagent_containers/glass/beaker = 1, + /obj/item/stack/sheet/plastic = 10, + /obj/item/stack/cable_coil = 2) + time = 150 //It's a gun + category = CAT_WEAPONRY + subcategory = CAT_WEAPON diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index 4a2a354ca6..d5cba6936f 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -59,3 +59,20 @@ S.forceMove(D) D.injector = S ..() + +/obj/item/ammo_casing/syringegun/dart + name = "used air canister" + desc = "A small canister of compressed gas." + projectile_type = /obj/item/projectile/bullet/dart/syringe/dart + firing_effect_type = null + harmful = FALSE + +/obj/item/ammo_casing/syringegun/dart/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + ..() + var/obj/item/gun/syringe/SG = loc + if(!SG.syringes.len) + return + var/obj/item/reagent_containers/syringe/dart/S = SG.syringes[1] + if(S.emptrig == TRUE) + var/obj/item/projectile/bullet/dart/syringe/dart/D = BB + D.emptrig = TRUE diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm index cc1b321e3a..26e66b1987 100644 --- a/code/modules/projectiles/guns/misc/syringe_gun.dm +++ b/code/modules/projectiles/guns/misc/syringe_gun.dm @@ -102,3 +102,23 @@ else to_chat(user, "[src] cannot hold more syringes!") return FALSE + +/obj/item/gun/syringe/dart + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + icon_state = "dartgun" + item_state = "dartgun" + materials = list(MAT_METAL=2000, MAT_GLASS=500) + suppressed = TRUE //Softer fire sound + can_unsuppress = FALSE + +/obj/item/gun/syringe/dart/Initialize() + ..() + chambered = new /obj/item/ammo_casing/syringegun/dart(src) + +/obj/item/gun/syringe/dart/attackby(obj/item/A, mob/user, params, show_msg = TRUE) + if(istype(A, /obj/item/reagent_containers/syringe/dart)) + ..() + else + to_chat(user, "You can't put the [A] into \the [src]!") + return FALSE diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 94d075c789..bdbf706448 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -8,12 +8,14 @@ . = ..() create_reagents(50, NO_REACT) -/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) +/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE, skip = FALSE) if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) // not completely blocked if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..() + if(skip == TRUE) + return reagents.reaction(M, INJECT) reagents.trans_to(M, reagents.total_volume) return TRUE @@ -36,3 +38,44 @@ /obj/item/projectile/bullet/dart/syringe name = "syringe" icon_state = "syringeproj" + +//I am in a mess of my own making +/obj/item/projectile/bullet/dart/syringe/dart + name = "Smartdart" + icon_state = "dartproj" + damage = 0 + var/emptrig = FALSE + +/obj/item/projectile/bullet/dart/syringe/dart/on_hit(atom/target, blocked = FALSE) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + ..(target, blocked, TRUE) + for(var/datum/reagent/R in reagents.reagent_list) //OD prevention time! + if(istype(R, /datum/reagent/medicine)) //Is this a medicine? + if(M.reagents.has_reagent(R.id)) + if(R.overdose_threshold == 0 || emptrig == TRUE) //Is there a possible OD? + M.reagents.add_reagent(R.id, R.volume) + else + var/transVol = CLAMP(R.volume, 0, (R.overdose_threshold - M.reagents.get_reagent_amount(R.id)) -1) + M.reagents.add_reagent(R.id, transVol) + else + if(!R.overdose_threshold == 0) + var/transVol = CLAMP(R.volume, 0, R.overdose_threshold-1) + M.reagents.add_reagent(R.id, transVol) + else + M.reagents.add_reagent(R.id, R.volume) + + + + target.visible_message("\The [src] beeps!") + to_chat("You feel a tiny prick as a smartdart embeds itself in you with a beep.") + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You see a [src] bounce off you, booping sadly!") + + target.visible_message("\The [src] fails to land on target!") + return TRUE diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 4947ddde6f..cc83eb28f6 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -259,3 +259,92 @@ /obj/item/reagent_containers/syringe/get_belt_overlay() return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch") + +/obj/item/reagent_containers/syringe/dart + name = "medicinal smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + volume = 20 + amount_per_transfer_from_this = 20 + icon_state = "empty" + item_state = "syringe_empty" + var/emptrig = FALSE + +/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity) + + if(busy) + return + if(!proximity) + return + if(!target.reagents) + return + + var/mob/living/L + if(isliving(target)) + L = target + if(!L.can_inject(user, 1)) + return + + switch(mode) + if(SYRINGE_DRAW) + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "The dart is full!") + return + + if(L) //living mob + to_chat(user, "You can't draw blood using a dart!") + return + + else //if not mob + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty!") + return + + if(!target.is_drawable()) + to_chat(user, "You cannot directly remove reagents from [target]!") + return + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) + + to_chat(user, "You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.") + if (reagents.total_volume >= reagents.maximum_volume) + mode=!mode + update_icon() + + if(SYRINGE_INJECT) + src.visible_message("The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!") + +/obj/item/reagent_containers/syringe/dart/attack_self(mob/user) + return + +/obj/item/reagent_containers/syringe/dart/update_icon() + cut_overlays() + var/rounded_vol + + rounded_vol = "empty" + if(reagents && reagents.total_volume) + if(volume/reagents.total_volume == 1) + rounded_vol="full" + + icon_state = "[rounded_vol]" + item_state = "syringe_[rounded_vol]" + if(ismob(loc)) + var/mob/M = loc + var/injoverlay + switch(mode) + if (SYRINGE_DRAW) + injoverlay = "draw" + if (SYRINGE_INJECT) + injoverlay = "ready" + add_overlay(injoverlay) + M.update_inv_hands() + +/obj/item/reagent_containers/syringe/dart/emp_act(severity) + emptrig = TRUE + ..() + +/obj/item/reagent_containers/syringe/dart/bluespace + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + amount_per_transfer_from_this = 50 + volume = 50 diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 8a8377601a..3a7ef68903 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -92,6 +92,36 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/medicinalsmartdart + name = "Medicinal Smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented." + id = "medicinalsmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 100, MAT_PLASTIC = 100, MAT_METAL = 100) + build_path = /obj/item/reagent_containers/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/bluespacesmartdart + name = "bluespace smartdart" + desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam." + id = "bluespacesmartdart" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 250, MAT_PLASTIC = 250, MAT_METAL = 250, MAT_BLUESPACE = 250) + build_path = /obj/item/reagent_containers/syringe/dart/bluespace + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/smartdartgun + name = "dart gun" + desc = "A compressed air gun, designed to fit medicinal darts for application of medicine for those patients just out of reach." + id = "smartdartgun" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_PLASTIC = 1000, MAT_METAL = 500) + build_path = /obj/item/gun/syringe/dart + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/bluespacebodybag name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index c1124efe2d..4331d8858b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -69,7 +69,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -246,7 +246,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo") + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "roastingstick", "ore_silo", "bluespacesmartdart") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500) export_price = 5000 diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 5eba9b6b21..523606aa6a 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -32,7 +32,10 @@ /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1, - /obj/item/storage/briefcase/medical = 2) + /obj/item/storage/belt/medolier/full = 2, + /obj/item/gun/syringe/dart = 2, + /obj/item/storage/briefcase/medical = 2) + armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 018eb09d86..514bbd8730 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -10,7 +10,8 @@ /obj/item/reagent_containers/medspray/styptic = 2, /obj/item/reagent_containers/medspray/silver_sulf = 2, /obj/item/reagent_containers/pill/charcoal = 2, - /obj/item/reagent_containers/medspray/sterilizine = 1) + /obj/item/reagent_containers/medspray/sterilizine = 1, + /obj/item/reagent_containers/syringe/dart = 10) contraband = list(/obj/item/reagent_containers/pill/tox = 2, /obj/item/reagent_containers/pill/morphine = 2) premium = list(/obj/item/reagent_containers/medspray/synthflesh = 2) diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi index dc5dde9cb6..3e56574fbf 100644 Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ diff --git a/icons/obj/dart.dmi b/icons/obj/dart.dmi new file mode 100644 index 0000000000..50ba4fc1ab Binary files /dev/null and b/icons/obj/dart.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index e4a39903b3..7d44d35f55 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index d276655ae8..bff1b631c3 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index f77735fc3e..80e681399a 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ