From 9e4274620f8e63bdff92de73d9a472fcca53dfd5 Mon Sep 17 00:00:00 2001 From: nmajask Date: Thu, 19 May 2022 20:14:22 -0400 Subject: [PATCH 1/7] Squashed commit of the following: commit 8ec2fca541cad4386d7ff42add4676b9a57c1fc6 Author: nmajask Date: Thu May 19 15:26:09 2022 -0400 Converts embedding into a proc also adds a embed tic proc that is called whenever the embedde has a life tick --- code/game/objects/items.dm | 4 ++ .../mob/living/carbon/human/human_defense.dm | 40 +++++++++++++------ code/modules/mob/living/carbon/human/life.dm | 1 + 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 1b625bd68f16..30f83d69d73d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -878,3 +878,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(ismob(loc)) var/mob/mob_loc = loc mob_loc.regenerate_icons() + +// Called every life tick when the object is embedded in a human +/obj/item/proc/embed_tick(/mob/living/carbon/human/embedde, /obj/item/bodypart/part) + return diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index de8cc108f01b..b2bb2caab8c9 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -171,20 +171,36 @@ blocked = TRUE else if(I) if(((throwingdatum ? throwingdatum.speed : I.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || I.embedding.embedded_ignore_throwspeed_threshold) - if(can_embed(I)) - if(prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)) - throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) - var/obj/item/bodypart/L = pick(bodyparts) - L.embedded_objects |= I - I.add_mob_blood(src)//it embedded itself in you, of course it's bloody! - I.forceMove(src) - L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier, wound_bonus=-30, sharpness = TRUE) - visible_message(span_danger("[I] embeds itself in [src]'s [L.name]!"),span_userdanger("[I] embeds itself in your [L.name]!")) - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded) - hitpush = FALSE - skipcatch = TRUE //can't catch the now embedded item + if(prob(I.embedding.embed_chance) && embed_object(I, deal_damage = TRUE)) + hitpush = FALSE + skipcatch = TRUE //can't catch the now embedded item return ..() + +/mob/living/carbon/human/proc/embed_object(obj/item/embedding, part, deal_damage, silent, forced) + if(!(forced || (can_embed(embedding) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)))) + return FALSE + var/obj/item/bodypart/body_part = part + // In case its a zone + if(!istype(body_part) && body_part) + body_part = get_bodypart(body_part) + // Otherwise pick one + if(!istype(body_part)) + body_part = pick(bodyparts) + // Thats probably not good + if(!istype(body_part)) + return FALSE + + body_part.embedded_objects |= embedding + embedding.add_mob_blood(src)//it embedded itself in you, of course it's bloody! + embedding.forceMove(src) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded) + if(deal_damage) + body_part.receive_damage(embedding.w_class*embedding.embedding.embedded_impact_pain_multiplier, wound_bonus=-30, sharpness = TRUE) + if(!silent) + throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) + visible_message(span_danger("[embedding] embeds itself in [src]'s [body_part.name]!"), span_userdanger("[embedding] embeds itself in your [body_part.name]!")) + return TRUE /mob/living/carbon/human/grippedby(mob/living/user, instant = FALSE) if(w_uniform) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index ef6081b5d79e..e7652c6913cd 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -312,6 +312,7 @@ for(var/X in bodyparts) var/obj/item/bodypart/BP = X for(var/obj/item/I in BP.embedded_objects) + I.embed_tick(src, BP) var/pain_chance_current = I.embedding.embedded_pain_chance if(!(mobility_flags & MOBILITY_STAND)) pain_chance_current *= 0.2 From 76a60d6f9e62f1e6a08ea9f7b2e1b72a407e2238 Mon Sep 17 00:00:00 2001 From: nmajask Date: Fri, 20 May 2022 11:00:03 -0400 Subject: [PATCH 2/7] Syringe gun rework Syringe gun now embeds syringes and slowly transfers the reagents --- .../ammunition/ballistic/shotgun.dm | 22 +++++++++- .../projectiles/ammunition/special/syringe.dm | 17 ++++---- .../projectile/bullets/dart_syringe.dm | 42 ++++++++++--------- .../reagents/reagent_containers/syringes.dm | 17 ++++++++ 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 7e4609607a30..1a4db84b1363 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -125,12 +125,30 @@ name = "shotgun dart" desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical." icon_state = "cshell" - projectile_type = /obj/item/projectile/bullet/dart + projectile_type = /obj/item/projectile/bullet/reusable/dart var/reagent_amount = 30 + var/no_react = FALSE /obj/item/ammo_casing/shotgun/dart/Initialize() . = ..() create_reagents(reagent_amount, OPENCONTAINER) + if(no_react) + ENABLE_BITFIELD(reagents.flags, NO_REACT) + +/obj/item/ammo_casing/shotgun/dart/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") + if(!BB) + return + if(reagents.total_volume < 0) + return + var/obj/item/projectile/bullet/reusable/dart/D = BB + var/obj/item/reagent_containers/syringe/dart/temp/new_dart = new(D) + + new_dart.volume = reagents.total_volume + if(no_react) + new_dart.reagent_flags |= NO_REACT + reagents.trans_to(new_dart, reagents.total_volume, transfered_by = user) + D.add_dart(new_dart) + ..() /obj/item/ammo_casing/shotgun/dart/attackby() return @@ -140,10 +158,10 @@ desc = "A dart for use in shotguns, using similar technology as cryostatis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical." icon_state = "cnrshell" reagent_amount = 10 + no_react = TRUE /obj/item/ammo_casing/shotgun/dart/noreact/Initialize() . = ..() - ENABLE_BITFIELD(reagents.flags, NO_REACT) /obj/item/ammo_casing/shotgun/dart/bioterror desc = "A shotgun dart filled with deadly toxins." diff --git a/code/modules/projectiles/ammunition/special/syringe.dm b/code/modules/projectiles/ammunition/special/syringe.dm index b4f6f4397fd5..2762b7c1598f 100644 --- a/code/modules/projectiles/ammunition/special/syringe.dm +++ b/code/modules/projectiles/ammunition/special/syringe.dm @@ -1,7 +1,7 @@ /obj/item/ammo_casing/syringegun name = "syringe gun spring" desc = "A high-power spring that throws syringes." - projectile_type = /obj/item/projectile/bullet/dart/syringe + projectile_type = /obj/item/projectile/bullet/reusable/dart/syringe firing_effect_type = null /obj/item/ammo_casing/syringegun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") @@ -9,23 +9,21 @@ return if(istype(loc, /obj/item/gun/syringe)) var/obj/item/gun/syringe/SG = loc + var/obj/item/projectile/bullet/reusable/dart/D = BB if(!SG.syringes.len) return var/obj/item/reagent_containers/syringe/S = SG.syringes[1] S.reagents.trans_to(BB, S.reagents.total_volume, transfered_by = user) - BB.name = S.name - var/obj/item/projectile/bullet/dart/D = BB - D.piercing = S.proj_piercing + D.add_dart(S) SG.syringes.Remove(S) - qdel(S) ..() /obj/item/ammo_casing/chemgun name = "dart synthesiser" desc = "A high-power spring, linked to an energy-based dart synthesiser." - projectile_type = /obj/item/projectile/bullet/dart + projectile_type = /obj/item/projectile/bullet/reusable/dart firing_effect_type = null /obj/item/ammo_casing/chemgun/ready_proj(atom/target, mob/living/user, quiet, zone_override = "") @@ -35,8 +33,11 @@ var/obj/item/gun/chem/CG = loc if(CG.syringes_left <= 0) return - CG.reagents.trans_to(BB, 15, transfered_by = user) - BB.name = "chemical dart" + var/obj/item/projectile/bullet/reusable/dart/D = BB + var/obj/item/reagent_containers/syringe/dart/temp/new_dart = new(D) + + CG.reagents.trans_to(new_dart, 15, transfered_by = user) + D.add_dart(new_dart) CG.syringes_left-- ..() diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index b8f3782a8a5f..96541cea11bd 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -1,38 +1,42 @@ -/obj/item/projectile/bullet/dart +/obj/item/projectile/bullet/reusable/dart name = "dart" icon_state = "cbbolt" damage = 6 + var/obj/item/reagent_containers/container var/piercing = FALSE -/obj/item/projectile/bullet/dart/Initialize() +/obj/item/projectile/bullet/reusable/dart/Initialize() . = ..() - create_reagents(50, NO_REACT) -/obj/item/projectile/bullet/dart/on_hit(atom/target, blocked = FALSE) - if(iscarbon(target)) - var/mob/living/carbon/M = target +/obj/item/projectile/bullet/reusable/dart/on_hit(atom/target, blocked = FALSE) + if(ishuman(target)) + var/mob/living/carbon/human/H = 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(H.embed_object(container, def_zone, FALSE)) + dropped = TRUE ..() - reagents.reaction(M, INJECT) - reagents.trans_to(M, reagents.total_volume) return BULLET_ACT_HIT else blocked = 100 - target.visible_message(span_danger("\The [src] was deflected!"), \ - span_userdanger("You were protected against \the [src]!")) + target.visible_message(span_danger("\The [container] was deflected!"), \ + span_userdanger("You were protected against \the [container]!")) ..(target, blocked) - DISABLE_BITFIELD(reagents.flags, NO_REACT) - reagents.handle_reactions() return BULLET_ACT_HIT -/obj/item/projectile/bullet/dart/metalfoam/Initialize() - . = ..() - reagents.add_reagent(/datum/reagent/aluminium, 15) - reagents.add_reagent(/datum/reagent/foaming_agent, 5) - reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 5) +/obj/item/projectile/bullet/reusable/dart/handle_drop() + if(!dropped) + container.forceMove(get_turf(src)) + dropped = TRUE + +/obj/item/projectile/bullet/reusable/dart/proc/add_dart(obj/item/reagent_containers/new_dart) + container = new_dart + new_dart.forceMove(src) + name = new_dart.name + if(istype(new_dart, /obj/item/reagent_containers/syringe)) + var/obj/item/reagent_containers/syringe/syringe + piercing = syringe.proj_piercing -/obj/item/projectile/bullet/dart/syringe +/obj/item/projectile/bullet/reusable/dart/syringe name = "syringe" icon_state = "syringeproj" diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 34f60617b199..e1dddef3f519 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -15,6 +15,7 @@ materials = list(/datum/material/iron=10, /datum/material/glass=20) reagent_flags = TRANSPARENT sharpness = SHARP_POINTY + embedding = list("embedded_pain_chance" = 0, "embedded_pain_multiplier" = 0, "embedded_unsafe_removal_time" = 1 SECONDS, "embedded_unsafe_removal_pain_multiplier" = 0, "embed_chance" = 15, "embedded_fall_chance" = 5) /obj/item/reagent_containers/syringe/Initialize() . = ..() @@ -193,6 +194,9 @@ injoverlay = "inject" add_overlay(injoverlay) M.update_inv_hands() + +/obj/item/reagent_containers/syringe/embed_tick(embedde, part) + reagents.trans_to(embedde, amount_per_transfer_from_this*0.2) /obj/item/reagent_containers/syringe/epinephrine name = "syringe (epinephrine)" @@ -287,6 +291,11 @@ volume = 10 proj_piercing = 1 +/obj/item/reagent_containers/syringe/fast + name = "piercing syringe" + desc = "A mechanical syringe that can quickly inject its entire contents into someone." + amount_per_transfer_from_this = 15 + /obj/item/reagent_containers/syringe/crude name = "crude syringe" desc = "A crudely made syringe. The flimsy wooden construction makes it hold up minimal amounts of reagents." @@ -296,3 +305,11 @@ name = "spider extract syringe" desc = "Contains crikey juice - makes any gold core create the most deadly companions in the world." list_reagents = list(/datum/reagent/spider_extract = 1) + +/obj/item/reagent_containers/syringe/dart + name = "reagent dart" + amount_per_transfer_from_this = 15 + embedding = list("embed_chance" = 15, "embedded_fall_chance" = 0) + +/obj/item/reagent_containers/syringe/dart/temp + item_flags = DROPDEL From 11d0a7fcb2c6425e102e7ea51a7f7b1c70ea2b60 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 21 May 2022 16:14:04 -0400 Subject: [PATCH 3/7] Squashed commit of the following: commit c6d04d476bcd7efa1fb658d100595f6512c3b5a3 Author: nmajask Date: Sat May 21 16:12:51 2022 -0400 b commit da83fdc5a0c0a685a7d3f858fc27065c2558377d Author: nmajask Date: Sat May 21 15:47:52 2022 -0400 a commit 8ec2fca541cad4386d7ff42add4676b9a57c1fc6 Author: nmajask Date: Thu May 19 15:26:09 2022 -0400 Converts embedding into a proc also adds a embed tic proc that is called whenever the embedde has a life tick --- code/_onclick/hud/alert.dm | 6 +- code/game/objects/items.dm | 17 +++- code/modules/mob/living/carbon/carbon.dm | 20 +++++ .../mob/living/carbon/carbon_defense.dm | 90 ++++++++++++++++++- code/modules/mob/living/carbon/examine.dm | 17 ++-- code/modules/mob/living/carbon/human/human.dm | 23 ----- .../mob/living/carbon/human/human_defense.dm | 6 -- code/modules/mob/living/carbon/human/life.dm | 30 ------- code/modules/mob/living/carbon/life.dm | 33 +++++++ code/modules/spells/spell_types/summonitem.dm | 5 +- .../surgery/bodyparts/dismemberment.dm | 3 +- code/modules/surgery/bodyparts/helpers.dm | 5 +- .../modules/surgery/remove_embedded_object.dm | 37 ++++---- 13 files changed, 190 insertions(+), 102 deletions(-) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 572a75459647..95dda12cb3ce 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -241,9 +241,9 @@ If you're feeling frisky, examine yourself and click the underlined item to pull icon_state = "embeddedobject" /obj/screen/alert/embeddedobject/Click() - if(isliving(usr)) - var/mob/living/carbon/human/M = usr - return M.help_shake_act(M) + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + return C.try_remove_embedded_object(C) /obj/screen/alert/weightless name = "Weightless" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 30f83d69d73d..42722ca178c9 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -878,7 +878,20 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(ismob(loc)) var/mob/mob_loc = loc mob_loc.regenerate_icons() +/** + * Called when this object is first embedded into a carbon + */ +/obj/item/proc/on_embed(mob/living/carbon/human/embedde, obj/item/bodypart/part) + return TRUE + +/** + * Called when this object is no longer embedded into a carbon + */ +/obj/item/proc/on_embed_removal(mob/living/carbon/human/embedde) + return TRUE -// Called every life tick when the object is embedded in a human -/obj/item/proc/embed_tick(/mob/living/carbon/human/embedde, /obj/item/bodypart/part) +/** + * Called every life tick when the object is embedded in a carbon + */ +/obj/item/proc/embed_tick(mob/living/carbon/human/embedde, obj/item/bodypart/part) return diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 91c2c08c3ca7..fc4be77f34a1 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -273,6 +273,26 @@ visible_message(span_danger("[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name]."), \ span_userdanger("[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].")) + // Embed Stuff + if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts + if(!L) + return + var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects + if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore + return + var/time_taken = I.embedding.embedded_unsafe_removal_time*I.w_class + usr.visible_message(span_warning("[usr] attempts to remove [I] from [usr.p_their()] [L.name]."),span_notice("You attempt to remove [I] from your [L.name]... (It will take [DisplayTimeText(time_taken)].)")) + if(do_after(usr, time_taken, needhand = 1, target = src)) + if(!I || !L || I.loc != src) + return + var/damage_amount = I.embedding.embedded_unsafe_removal_pain_multiplier * I.w_class + L.receive_damage(damage_amount, sharpness = SHARP_EDGED)//It hurts to rip it out, get surgery you dingus. + if(remove_embedded_object(I, get_turf(src), damage_amount)) + usr.put_in_hands(I) + usr.visible_message("[usr] successfully rips [I] out of [usr.p_their()] [L.name]!", span_notice("You successfully remove [I] from your [L.name].")) + return + /mob/living/carbon/fall(forced) if(loc) loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index dc226b36efd4..569f80b1732f 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -50,10 +50,15 @@ return TRUE /mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) - if(!skipcatch) //ugly, but easy - if(can_catch_item()) - if(istype(AM, /obj/item)) - var/obj/item/I = AM + var/obj/item/I = AM + if(istype(I, /obj/item)) + if(((throwingdatum ? throwingdatum.speed : I.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || I.embedding.embedded_ignore_throwspeed_threshold) + var/obj/item/bodypart/body_part = pick(bodyparts) + if(prob(clamp(I.embedding.embed_chance - run_armor_check(body_part, MELEE), 0, 100)) && embed_object(I, deal_damage = TRUE)) + hitpush = FALSE + skipcatch = TRUE //can't catch the now embedded item + if(!skipcatch) //ugly, but easy + if(can_catch_item()) if(I.item_flags & UNCATCHABLE) return FALSE if(isturf(I.loc)) @@ -68,6 +73,83 @@ return TRUE ..() +/** + * Embeds an object into this carbon + */ +/mob/living/carbon/proc/embed_object(obj/item/embedding, part, deal_damage, silent, forced) + if(!(forced || (can_embed(embedding) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)))) + return FALSE + var/obj/item/bodypart/body_part = part + // In case its a zone + if(!istype(body_part) && body_part) + body_part = get_bodypart(body_part) + // Otherwise pick one + if(!istype(body_part)) + body_part = pick(bodyparts) + // Thats probably not good + if(!istype(body_part)) + return FALSE + if(!embedding.on_embed(src, body_part)) + return + body_part.embedded_objects |= embedding + embedding.add_mob_blood(src)//it embedded itself in you, of course it's bloody! + embedding.forceMove(src) + SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded) + if(deal_damage) + body_part.receive_damage(embedding.w_class*embedding.embedding.embedded_impact_pain_multiplier, wound_bonus=-30, sharpness = TRUE) + if(!silent) + throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) + visible_message(span_danger("[embedding] embeds itself in [src]'s [body_part.name]!"), span_userdanger("[embedding] embeds itself in your [body_part.name]!")) + return TRUE + +/** + * Removes the given embedded object from this carbon + */ +/mob/living/carbon/proc/remove_embedded_object(obj/item/embedded, new_loc, silent, forced) + var/obj/item/bodypart/body_part + for(var/obj/item/bodypart/part in bodyparts) + if(embedded in part.embedded_objects) + body_part = part + if(!body_part) + return + if(!embedded.on_embed_removal(src)) + return + body_part.embedded_objects -= embedded + if(!silent) + emote("scream") + if(!has_embedded_objects()) + clear_alert("embeddedobject") + SEND_SIGNAL(usr, COMSIG_CLEAR_MOOD_EVENT, "embedded") + if(new_loc) + embedded.forceMove(new_loc) + return TRUE + +/** + * Called when a mob tries to remove an embedded object from this carbon + */ +/mob/living/carbon/proc/try_remove_embedded_object(mob/user) + var/list/choice_list = list() + var/obj/item/bodypart/body_part + for(var/obj/item/bodypart/part in bodyparts) + for(var/obj/item/embedded in part.embedded_objects) + choice_list[embedded] = image(embedded) + var/obj/item/choice = show_radial_menu(user, src, choice_list, tooltips = TRUE) + for(var/obj/item/bodypart/part in bodyparts) + if(choice in part.embedded_objects) + body_part = part + if(!istype(choice) || !(choice in choice_list)) + return + var/time_taken = choice.embedding.embedded_unsafe_removal_time * choice.w_class + user.visible_message(span_warning("[user] attempts to remove [choice] from [usr.p_their()] [body_part.name]."),span_notice("You attempt to remove [choice] from your [body_part.name]... (It will take [DisplayTimeText(time_taken)].)")) + if(!do_after(user, time_taken, needhand = 1, target = src) && !(choice in body_part.embedded_objects)) + return + var/damage_amount = choice.embedding.embedded_unsafe_removal_pain_multiplier * choice.w_class + body_part.receive_damage(damage_amount > 0, sharpness = SHARP_EDGED)//It hurts to rip it out, get surgery you dingus. + if(remove_embedded_object(choice, get_turf(src), damage_amount)) + user.put_in_hands(choice) + user.visible_message("[user] successfully rips [choice] out of [user == src? p_their() : "[src]'s"] [body_part.name]!", span_notice("You successfully remove [choice] from your [body_part.name].")) + return TRUE + /mob/living/carbon/proc/get_interaction_efficiency(zone) var/obj/item/bodypart/limb = get_bodypart(zone) if(!limb) diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index f563234e99ac..75a3cb178ae5 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -32,6 +32,17 @@ else if(get_bodypart(BODY_ZONE_HEAD)) . += span_deadsay("It appears that [t_his] brain is missing...") + var/list/disabled = list() + for(var/X in bodyparts) + var/obj/item/bodypart/body_part = X + if(body_part.bodypart_disabled) + disabled += body_part + for(var/obj/item/I in body_part.embedded_objects) + . += "[t_He] [t_has] \a [icon2html(I, user)] [I] embedded in [t_his] [body_part.name]!\n" + for(var/i in body_part.wounds) + var/datum/wound/iter_wound = i + . += "[iter_wound.get_examine_description(user)]\n" + var/list/missing = get_missing_limbs() for(var/t in missing) if(t==BODY_ZONE_HEAD) @@ -68,12 +79,6 @@ else msg += "[t_He] [t_is] severely deformed!\n" - for(var/X in bodyparts) - var/obj/item/bodypart/BP = X - for(var/i in BP.wounds) - var/datum/wound/W = i - msg += "[W.get_examine_description(user)]\n" - if(HAS_TRAIT(src, TRAIT_DUMB)) msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 405c177e1ba3..8d8b545aef56 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -231,29 +231,6 @@ spreadFire(AM) /mob/living/carbon/human/Topic(href, href_list) - if(href_list["embedded_object"] && usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) - var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts - if(!L) - return - var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects - if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore - return - var/time_taken = I.embedding.embedded_unsafe_removal_time*I.w_class - usr.visible_message(span_warning("[usr] attempts to remove [I] from [usr.p_their()] [L.name]."),span_notice("You attempt to remove [I] from your [L.name]... (It will take [DisplayTimeText(time_taken)].)")) - if(do_after(usr, time_taken, needhand = 1, target = src)) - if(!I || !L || I.loc != src || !(I in L.embedded_objects)) - return - L.embedded_objects -= I - L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class, sharpness=SHARP_EDGED)//It hurts to rip it out, get surgery you dingus. - I.forceMove(get_turf(src)) - usr.put_in_hands(I) - usr.emote("scream") - usr.visible_message("[usr] successfully rips [I] out of [usr.p_their()] [L.name]!",span_notice("You successfully remove [I] from your [L.name].")) - if(!has_embedded_objects()) - clear_alert("embeddedobject") - SEND_SIGNAL(usr, COMSIG_CLEAR_MOOD_EVENT, "embedded") - return - if(href_list["item"]) //canUseTopic check for this is handled by mob/Topic() var/slot = text2num(href_list["item"]) if(slot in check_obscured_slots(TRUE)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b2bb2caab8c9..fc2f5395b17b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -169,12 +169,6 @@ hitpush = FALSE skipcatch = TRUE blocked = TRUE - else if(I) - if(((throwingdatum ? throwingdatum.speed : I.throw_speed) >= EMBED_THROWSPEED_THRESHOLD) || I.embedding.embedded_ignore_throwspeed_threshold) - if(prob(I.embedding.embed_chance) && embed_object(I, deal_damage = TRUE)) - hitpush = FALSE - skipcatch = TRUE //can't catch the now embedded item - return ..() /mob/living/carbon/human/proc/embed_object(obj/item/embedding, part, deal_damage, silent, forced) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index e7652c6913cd..a685a17423ce 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -38,10 +38,6 @@ //heart attack stuff handle_heart() - if(stat != DEAD) - //Stuff jammed in your limbs hurts - handle_embedded_objects() - dna.species.spec_life(src) // for mutantraces else for(var/i in all_wounds) @@ -307,32 +303,6 @@ return TRUE return ..() - -/mob/living/carbon/human/proc/handle_embedded_objects() - for(var/X in bodyparts) - var/obj/item/bodypart/BP = X - for(var/obj/item/I in BP.embedded_objects) - I.embed_tick(src, BP) - var/pain_chance_current = I.embedding.embedded_pain_chance - if(!(mobility_flags & MOBILITY_STAND)) - pain_chance_current *= 0.2 - if(prob(pain_chance_current)) - BP.receive_damage(I.w_class*I.embedding.embedded_pain_multiplier, wound_bonus = CANT_WOUND) - to_chat(src, span_userdanger("[I] embedded in your [BP.name] hurts!")) - - var/fall_chance_current = I.embedding.embedded_fall_chance - if(!(mobility_flags & MOBILITY_STAND)) - fall_chance_current *= 0.2 - - if(prob(fall_chance_current)) - BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier, wound_bonus = CANT_WOUND) // can wound - BP.embedded_objects -= I - I.forceMove(drop_location()) - visible_message(span_danger("[I] falls out of [name]'s [BP.name]!"),span_userdanger("[I] falls out of your [BP.name]!")) - if(!has_embedded_objects()) - clear_alert("embeddedobject") - SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded") - /mob/living/carbon/human/proc/handle_heart() var/we_breath = !HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 2d9411c6c62f..d4d5cd9c0c4c 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -37,6 +37,10 @@ if(stat != DEAD) handle_liver() + if(stat != DEAD) + //Stuff jammed in your limbs hurts + handle_embedded_objects() + else . = ..() @@ -650,6 +654,35 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put var/datum/brain_trauma/BT = T BT.on_life() + +//////////// +// EMBEDS // +//////////// + +/mob/living/carbon/proc/handle_embedded_objects() + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + for(var/obj/item/I in BP.embedded_objects) + I.embed_tick(src, BP) + var/pain_chance_current = I.embedding.embedded_pain_chance + if(!(mobility_flags & MOBILITY_STAND)) + pain_chance_current *= 0.2 + if(prob(pain_chance_current)) + BP.receive_damage(I.w_class*I.embedding.embedded_pain_multiplier, wound_bonus = CANT_WOUND) + to_chat(src, span_userdanger("[I] embedded in your [BP.name] hurts!")) + + var/fall_chance_current = I.embedding.embedded_fall_chance + if(!(mobility_flags & MOBILITY_STAND)) + fall_chance_current *= 0.2 + + if(prob(fall_chance_current)) + BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier, wound_bonus = CANT_WOUND) // can wound + remove_embedded_object(I, drop_location(), FALSE) + visible_message(span_danger("[I] falls out of [name]'s [BP.name]!"), span_userdanger("[I] falls out of your [BP.name]!")) + if(!has_embedded_objects()) + clear_alert("embeddedobject") + SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded") + ///////////////////////////////////// //MONKEYS WITH TOO MUCH CHOLOESTROL// ///////////////////////////////////// diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm index 6bee83f5488c..0382ccc81738 100644 --- a/code/modules/spells/spell_types/summonitem.dm +++ b/code/modules/spells/spell_types/summonitem.dm @@ -86,11 +86,8 @@ for(var/X in C.bodyparts) var/obj/item/bodypart/part = X if(item_to_retrieve in part.embedded_objects) - part.embedded_objects -= item_to_retrieve + C.remove_embedded_object(item_to_retrieve, silent = TRUE, forced = TRUE) to_chat(C, span_warning("The [item_to_retrieve] that was embedded in your [L] has mysteriously vanished. How fortunate!")) - if(!C.has_embedded_objects()) - C.clear_alert("embeddedobject") - SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "embedded") break else diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index a3c5b18e1cec..9e5d282cc961 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -104,8 +104,7 @@ break for(var/obj/item/I in embedded_objects) - embedded_objects -= I - I.forceMove(src) + phantom_owner.remove_embedded_object(I, src, TRUE, TRUE) if(!phantom_owner.has_embedded_objects()) phantom_owner.clear_alert("embeddedobject") SEND_SIGNAL(phantom_owner, COMSIG_CLEAR_MOOD_EVENT, "embedded") diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index d8896ad88966..594f36c97ca9 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -161,6 +161,7 @@ for(var/X in bodyparts) var/obj/item/bodypart/L = X for(var/obj/item/I in L.embedded_objects) + remove_embedded_object(I, T, TRUE, TRUE) L.embedded_objects -= I I.forceMove(T) @@ -168,11 +169,11 @@ SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded") /mob/living/carbon/proc/has_embedded_objects() - . = 0 + . = FALSE for(var/X in bodyparts) var/obj/item/bodypart/L = X for(var/obj/item/I in L.embedded_objects) - return 1 + return TRUE //Helper for quickly creating a new limb - used by augment code in species.dm spec_attacked_by diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index f6994a28a0d3..3b4f542f5d3a 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -1,14 +1,16 @@ /datum/surgery/embedded_removal name = "Removal of embedded objects" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/remove_object) + steps = list(/datum/surgery_step/incise, /datum/surgery_step/remove_object, /datum/surgery_step/close) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) /datum/surgery_step/remove_object name = "remove embedded objects" - time = 32 - accept_hand = 1 + time = 1.5 SECONDS + accept_hand = TRUE fuckup_damage = 0 + repeatable = TRUE + var/obj/item/target_item = null var/obj/item/bodypart/L = null @@ -25,25 +27,20 @@ /datum/surgery_step/remove_object/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(L) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - var/objects = 0 - for(var/obj/item/I in L.embedded_objects) - objects++ - I.forceMove(get_turf(H)) - L.embedded_objects -= I - if(!H.has_embedded_objects()) - H.clear_alert("embeddedobject") - SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "embedded") - - if(objects > 0) - display_results(user, target, span_notice("You successfully remove [objects] objects from [H]'s [L.name]."), - "[user] successfully removes [objects] objects from [H]'s [L]!", - "[user] successfully removes [objects] objects from [H]'s [L]!") + if(iscarbon(target)) + if(L.embedded_objects) + var/mob/living/carbon/C = target + var/obj/item/I = pick(L.embedded_objects) + if(C.remove_embedded_object(I, C.drop_location(), TRUE)) + display_results(user, target, span_notice("You successfully remove \the [I] from [C]'s [L.name]."), + "[user] successfully removes \the [I] from [C]'s [L]!", + "[user] successfully removes \the [I] from [C]'s [L]!") + else + to_chat(user, span_warning("You fail to remove \the [I] from [C]'s [L.name]!")) else - to_chat(user, span_warning("You find no objects embedded in [H]'s [L]!")) + to_chat(user, span_warning("You find no objects embedded in [target]'s [L]!")) else to_chat(user, span_warning("You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!")) - return 1 + return FALSE From 2e1cfe86da3242716cf15cc403286f5e2abd3780 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 21 May 2022 17:41:05 -0400 Subject: [PATCH 4/7] a --- .../mob/living/carbon/human/human_defense.dm | 25 ------------------- .../ammunition/ballistic/shotgun.dm | 3 --- 2 files changed, 28 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index fc2f5395b17b..e5e3a041939b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -170,31 +170,6 @@ skipcatch = TRUE blocked = TRUE return ..() - -/mob/living/carbon/human/proc/embed_object(obj/item/embedding, part, deal_damage, silent, forced) - if(!(forced || (can_embed(embedding) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE)))) - return FALSE - var/obj/item/bodypart/body_part = part - // In case its a zone - if(!istype(body_part) && body_part) - body_part = get_bodypart(body_part) - // Otherwise pick one - if(!istype(body_part)) - body_part = pick(bodyparts) - // Thats probably not good - if(!istype(body_part)) - return FALSE - - body_part.embedded_objects |= embedding - embedding.add_mob_blood(src)//it embedded itself in you, of course it's bloody! - embedding.forceMove(src) - SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded) - if(deal_damage) - body_part.receive_damage(embedding.w_class*embedding.embedding.embedded_impact_pain_multiplier, wound_bonus=-30, sharpness = TRUE) - if(!silent) - throw_alert("embeddedobject", /obj/screen/alert/embeddedobject) - visible_message(span_danger("[embedding] embeds itself in [src]'s [body_part.name]!"), span_userdanger("[embedding] embeds itself in your [body_part.name]!")) - return TRUE /mob/living/carbon/human/grippedby(mob/living/user, instant = FALSE) if(w_uniform) diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 1a4db84b1363..6fc5002873af 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -160,9 +160,6 @@ reagent_amount = 10 no_react = TRUE -/obj/item/ammo_casing/shotgun/dart/noreact/Initialize() - . = ..() - /obj/item/ammo_casing/shotgun/dart/bioterror desc = "A shotgun dart filled with deadly toxins." From ce16cfa2f92a5a909d5edb5bb9b3eddb3331315d Mon Sep 17 00:00:00 2001 From: nmajask Date: Sun, 22 May 2022 10:19:46 -0400 Subject: [PATCH 5/7] Pain --- code/modules/reagents/reagent_containers/syringes.dm | 6 ------ code/modules/research/designs/medical_designs.dm | 10 ++++++++++ code/modules/research/techweb/all_nodes.dm | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index e1dddef3f519..4cf454a3fff4 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -290,12 +290,6 @@ desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units." volume = 10 proj_piercing = 1 - -/obj/item/reagent_containers/syringe/fast - name = "piercing syringe" - desc = "A mechanical syringe that can quickly inject its entire contents into someone." - amount_per_transfer_from_this = 15 - /obj/item/reagent_containers/syringe/crude name = "crude syringe" desc = "A crudely made syringe. The flimsy wooden construction makes it hold up minimal amounts of reagents." diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 0e2910cdf84a..349eacbf9eb1 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -102,6 +102,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/dartsyringe + name = "Reagent Dart" + desc = "A specialized syringe that quickly inject reagent. It can hold up to 15 units." + id = "dartsyringe" + build_type = PROTOLATHE + materials = list(/datum/material/glass = 2500) + build_path = /obj/item/reagent_containers/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 5cb8a63230d9..4f1fc90ba25e 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -713,7 +713,7 @@ display_name = "Medical Weaponry" description = "Weapons using medical technology." prereq_ids = list("adv_biotech", "adv_weaponry") - design_ids = list("rapidsyringe", "shotgundartcryostatis") + design_ids = list("rapidsyringe", "shotgundartcryostatis", "dartsyringe") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 From 79645e490a6112ed2f4a9ba2752c3598a03ef1c6 Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 28 May 2022 02:07:49 -0400 Subject: [PATCH 6/7] Fixes and Buff --- code/modules/projectiles/projectile/bullets/dart_syringe.dm | 6 +++--- code/modules/reagents/reagent_containers/syringes.dm | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/modules/projectiles/projectile/bullets/dart_syringe.dm b/code/modules/projectiles/projectile/bullets/dart_syringe.dm index 96541cea11bd..824ca0c88040 100644 --- a/code/modules/projectiles/projectile/bullets/dart_syringe.dm +++ b/code/modules/projectiles/projectile/bullets/dart_syringe.dm @@ -9,10 +9,10 @@ . = ..() /obj/item/projectile/bullet/reusable/dart/on_hit(atom/target, blocked = FALSE) - if(ishuman(target)) - var/mob/living/carbon/human/H = target + if(iscarbon(target)) + var/mob/living/carbon/C = target if(blocked != 100) // not completely blocked - if(H.embed_object(container, def_zone, FALSE)) + if(C.embed_object(container, def_zone, FALSE)) dropped = TRUE ..() return BULLET_ACT_HIT diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 4cf454a3fff4..14f40710ca9a 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -196,7 +196,7 @@ M.update_inv_hands() /obj/item/reagent_containers/syringe/embed_tick(embedde, part) - reagents.trans_to(embedde, amount_per_transfer_from_this*0.2) + reagents.trans_to(embedde, amount_per_transfer_from_this * 0.5) /obj/item/reagent_containers/syringe/epinephrine name = "syringe (epinephrine)" @@ -307,3 +307,7 @@ /obj/item/reagent_containers/syringe/dart/temp item_flags = DROPDEL + +/obj/item/reagent_containers/syringe/dart/temp/on_embed_removal(mob/living/carbon/human/embedde) + qdel(src) + \ No newline at end of file From 98ac33a001edd0cc4f05862fd35a0d1be35f15ae Mon Sep 17 00:00:00 2001 From: nmajask Date: Sat, 11 Jun 2022 09:37:40 -0400 Subject: [PATCH 7/7] buff --- code/modules/reagents/reagent_containers/syringes.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 14f40710ca9a..6a7c441e9d99 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -15,7 +15,7 @@ materials = list(/datum/material/iron=10, /datum/material/glass=20) reagent_flags = TRANSPARENT sharpness = SHARP_POINTY - embedding = list("embedded_pain_chance" = 0, "embedded_pain_multiplier" = 0, "embedded_unsafe_removal_time" = 1 SECONDS, "embedded_unsafe_removal_pain_multiplier" = 0, "embed_chance" = 15, "embedded_fall_chance" = 5) + embedding = list("embedded_pain_chance" = 0, "embedded_pain_multiplier" = 0, "embedded_unsafe_removal_time" = 0.25 SECONDS, "embedded_unsafe_removal_pain_multiplier" = 0, "embed_chance" = 15, "embedded_fall_chance" = 5) /obj/item/reagent_containers/syringe/Initialize() . = ..() @@ -195,8 +195,11 @@ add_overlay(injoverlay) M.update_inv_hands() +/obj/item/reagent_containers/syringe/on_embed(mob/living/carbon/human/embedde, obj/item/bodypart/part) + reagents.trans_to(embedde, amount_per_transfer_from_this) + /obj/item/reagent_containers/syringe/embed_tick(embedde, part) - reagents.trans_to(embedde, amount_per_transfer_from_this * 0.5) + reagents.trans_to(embedde, amount_per_transfer_from_this * 0.2) /obj/item/reagent_containers/syringe/epinephrine name = "syringe (epinephrine)" @@ -302,7 +305,7 @@ /obj/item/reagent_containers/syringe/dart name = "reagent dart" - amount_per_transfer_from_this = 15 + amount_per_transfer_from_this = 10 embedding = list("embed_chance" = 15, "embedded_fall_chance" = 0) /obj/item/reagent_containers/syringe/dart/temp