/obj/item/reagent_containers/syringe
name = "syringe"
desc = "A syringe that can hold up to 15 units."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
icon_state = "0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 15
var/mode = SYRINGE_DRAW
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
var/show_filling = TRUE
custom_materials = list(/datum/material/iron=10, /datum/material/glass=20)
reagent_flags = TRANSPARENT
custom_price = PRICE_CHEAP_AS_FREE
sharpness = SHARP_POINTY
/obj/item/reagent_containers/syringe/Initialize(mapload)
. = ..()
if(list_reagents) //syringe starts in inject mode if its already got something inside
mode = SYRINGE_INJECT
update_icon()
/obj/item/reagent_containers/syringe/ComponentInitialize()
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
/obj/item/reagent_containers/syringe/on_reagent_change(changetype)
update_icon()
/obj/item/reagent_containers/syringe/pickup(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/dropped(mob/user)
..()
update_icon()
/obj/item/reagent_containers/syringe/attack_self(mob/user)
mode = !mode
update_icon()
/obj/item/reagent_containers/syringe/on_attack_hand()
. = ..()
update_icon()
/obj/item/reagent_containers/syringe/attack_paw(mob/user)
return attack_hand(user)
/obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params)
return
/obj/item/reagent_containers/syringe/attack()
return // no bludgeoning.
/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity)
. = ..()
INVOKE_ASYNC(src, PROC_REF(attempt_inject), target, user, proximity)
/obj/item/reagent_containers/syringe/proc/attempt_inject(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
// chance of monkey retaliation
if(ismonkey(target) && prob(MONKEY_SYRINGE_RETALIATION_PROB))
var/mob/living/carbon/monkey/M
M = target
M.retaliate(user)
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "The syringe is full.")
return
if(L) //living mob
var/drawn_amount = reagents.maximum_volume - reagents.total_volume
if(target != user)
target.visible_message("[user] is trying to take a blood sample from [target]!", \
"[user] is trying to take a blood sample from [target]!")
busy = TRUE
if(!do_mob(user, target, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),user,1)))
busy = FALSE
return
if(reagents.total_volume >= reagents.maximum_volume)
return
busy = FALSE
if(L.transfer_blood_to(src, drawn_amount))
user.visible_message("[user] takes a blood sample from [L].")
else
to_chat(user, "You are unable to draw any blood from [L]!")
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, log = TRUE) // transfer from, transfer to - who cares?
to_chat(user, "You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")
if (round(reagents.total_volume, 0.1) >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
// Always log attemped injections for admins
var/contained = reagents.log_list()
log_combat(user, target, "attempted to inject", src, addition="which had [contained]")
if(!reagents.total_volume)
to_chat(user, "[src] is empty.")
return
if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
to_chat(user, "You cannot directly fill [target]!")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "[target] is full.")
return
if(L) //living mob
if(!L.can_inject(user, TRUE))
return
if(L != user)
L.visible_message("[user] is trying to inject [L]!", \
"[user] is trying to inject [L]!")
if(!do_mob(user, L, extra_checks=CALLBACK(L, TYPE_PROC_REF(/mob/living, can_inject),user,1)))
return
if(!reagents.total_volume)
return
if(L.reagents.total_volume >= L.reagents.maximum_volume)
return
L.visible_message("[user] injects [L] with the syringe!", \
"[user] injects [L] with the syringe!")
if(L != user)
log_combat(user, L, "injected", src, addition="which had [contained]")
else
L.log_message("injected themselves ([contained]) with [src.name]", LOG_ATTACK, color="orange")
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
reagents.reaction(L, INJECT, fraction)
reagents.trans_to(target, amount_per_transfer_from_this, log = TRUE)
to_chat(user, "You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.")
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
/obj/item/reagent_containers/syringe/update_icon_state()
var/rounded_vol = get_rounded_vol()
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
/obj/item/reagent_containers/syringe/update_overlays()
. = ..()
if(show_filling)
var/rounded_vol = get_rounded_vol()
if(reagents && reagents.total_volume)
. += mutable_appearance('icons/obj/reagentfillings.dmi', "syringe[rounded_vol]", color = mix_color_from_reagents(reagents.reagent_list))
if(ismob(loc))
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
. += injoverlay
///Used by update_icon() and update_overlays()
/obj/item/reagent_containers/syringe/proc/get_rounded_vol()
if(reagents && reagents.total_volume)
return clamp(round((reagents.total_volume / volume * 15),5), 1, 15)
else
return FALSE
/obj/item/reagent_containers/syringe/epinephrine
name = "syringe (epinephrine)"
desc = "Contains epinephrine - used to stabilize patients."
list_reagents = list(/datum/reagent/medicine/epinephrine = 15)
/obj/item/reagent_containers/syringe/charcoal
name = "syringe (charcoal)"
desc = "Contains charcoal."
list_reagents = list(/datum/reagent/medicine/charcoal = 15)
/obj/item/reagent_containers/syringe/antiviral
name = "syringe (spaceacillin)"
desc = "Contains antiviral agents."
list_reagents = list(/datum/reagent/medicine/spaceacillin = 15)
/obj/item/reagent_containers/syringe/bioterror
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
list_reagents = list(/datum/reagent/consumable/ethanol/neurotoxin = 5, /datum/reagent/toxin/mutetoxin = 5, /datum/reagent/toxin/sodium_thiopental = 5)
/obj/item/reagent_containers/syringe/stimulants
name = "Stimpack"
desc = "Contains stimulants."
amount_per_transfer_from_this = 50
volume = 50
list_reagents = list(/datum/reagent/medicine/stimulants = 50)
/obj/item/reagent_containers/syringe/contraband
name = "unlabeled syringe"
desc = "A syringe containing some sort of unknown chemical cocktail."
/obj/item/reagent_containers/syringe/contraband/space_drugs
list_reagents = list(/datum/reagent/drug/space_drugs = 15)
/obj/item/reagent_containers/syringe/contraband/krokodil
list_reagents = list(/datum/reagent/drug/krokodil = 15)
/obj/item/reagent_containers/syringe/contraband/crank
list_reagents = list(/datum/reagent/drug/crank = 15)
/obj/item/reagent_containers/syringe/contraband/methamphetamine
list_reagents = list(/datum/reagent/drug/methamphetamine = 15)
/obj/item/reagent_containers/syringe/contraband/bath_salts
list_reagents = list(/datum/reagent/drug/bath_salts = 15)
/obj/item/reagent_containers/syringe/contraband/fentanyl
list_reagents = list(/datum/reagent/toxin/fentanyl = 15)
/obj/item/reagent_containers/syringe/contraband/morphine
list_reagents = list(/datum/reagent/medicine/morphine = 15)
/obj/item/reagent_containers/syringe/calomel
name = "syringe (calomel)"
desc = "Contains calomel."
list_reagents = list(/datum/reagent/medicine/calomel = 15)
/obj/item/reagent_containers/syringe/plasma
name = "syringe (plasma)"
desc = "Contains plasma."
list_reagents = list(/datum/reagent/toxin/plasma = 15)
/obj/item/reagent_containers/syringe/lethal
name = "lethal injection syringe"
desc = "A syringe used for lethal injections. It can hold up to 50 units."
amount_per_transfer_from_this = 50
volume = 50
/obj/item/reagent_containers/syringe/lethal/choral
list_reagents = list(/datum/reagent/toxin/chloralhydrate = 50)
/obj/item/reagent_containers/syringe/lethal/execution
list_reagents = list(/datum/reagent/toxin/amatoxin = 15, /datum/reagent/toxin/formaldehyde = 15, /datum/reagent/toxin/cyanide = 10, /datum/reagent/toxin/acid/fluacid = 10) //Citadel edit, changing out plasma from lethals
/obj/item/reagent_containers/syringe/mulligan
name = "Mulligan"
desc = "A syringe used to completely change the users identity."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/mulligan = 1)
/obj/item/reagent_containers/syringe/gluttony
name = "Gluttony's Blessing"
desc = "A syringe recovered from a dread place. It probably isn't wise to use."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list(/datum/reagent/gluttonytoxin = 1)
/obj/item/reagent_containers/syringe/bluespace
name = "bluespace syringe"
desc = "An advanced syringe that can hold 60 units of chemicals."
amount_per_transfer_from_this = 20
volume = 60
/obj/item/reagent_containers/syringe/noreact
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
reagent_flags = TRANSPARENT | NO_REACT
/obj/item/reagent_containers/syringe/piercing
name = "piercing syringe"
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/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"
show_filling = FALSE
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 (round(reagents.total_volume,1) >= 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_state()
var/empty_full = "empty"
if(round(reagents.total_volume, 1) == reagents.maximum_volume)
empty_full = "full"
mode = SYRINGE_INJECT
icon_state = "[empty_full]"
item_state = "syringe_[empty_full]"
/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