diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 9c6b0fc548d..fb55eee1200 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -1,101 +1,127 @@
/obj/machinery/iv_drip
name = "\improper IV drip"
icon = 'icons/obj/iv_drip.dmi'
+ icon_state = "iv_drip"
anchored = 0
density = 1
+ var/mob/living/carbon/human/attached = null
+ var/mode = 1 // 1 is injecting, 0 is taking blood.
+ var/obj/item/weapon/reagent_containers/beaker = null
+/obj/machinery/iv_drip/New()
+ ..()
+ update_icon()
-/obj/machinery/iv_drip/var/mob/living/carbon/human/attached = null
-/obj/machinery/iv_drip/var/mode = 1 // 1 is injecting, 0 is taking blood.
-/obj/machinery/iv_drip/var/obj/item/weapon/reagent_containers/beaker = null
+/obj/machinery/iv_drip/Destroy()
+ attached = null
+ if(beaker)
+ qdel(beaker)
+ beaker = null
+ return ..()
/obj/machinery/iv_drip/update_icon()
- if(src.attached)
- icon_state = "hooked"
+ if(attached)
+ if(mode)
+ icon_state = "injecting"
+ else
+ icon_state = "donating"
else
- icon_state = ""
+ if(mode)
+ icon_state = "injectidle"
+ else
+ icon_state = "donateidle"
- overlays = null
+ overlays.Cut()
if(beaker)
- var/datum/reagents/reagents = beaker.reagents
- if(reagents.total_volume)
+ if(attached)
+ overlays += "beakeractive"
+ else
+ overlays += "beakeridle"
+ if(beaker.reagents.total_volume)
var/image/filling = image('icons/obj/iv_drip.dmi', src, "reagent")
- var/percent = round((reagents.total_volume / beaker.volume) * 100)
+ var/percent = round((beaker.reagents.total_volume / beaker.volume) * 100)
switch(percent)
- if(0 to 9) filling.icon_state = "reagent0"
- if(10 to 24) filling.icon_state = "reagent10"
- if(25 to 49) filling.icon_state = "reagent25"
- if(50 to 74) filling.icon_state = "reagent50"
- if(75 to 79) filling.icon_state = "reagent75"
- if(80 to 90) filling.icon_state = "reagent80"
- if(91 to INFINITY) filling.icon_state = "reagent100"
+ if(0 to 9)
+ filling.icon_state = "reagent0"
+ if(10 to 24)
+ filling.icon_state = "reagent10"
+ if(25 to 49)
+ filling.icon_state = "reagent25"
+ if(50 to 74)
+ filling.icon_state = "reagent50"
+ if(75 to 79)
+ filling.icon_state = "reagent75"
+ if(80 to 90)
+ filling.icon_state = "reagent80"
+ if(91 to INFINITY)
+ filling.icon_state = "reagent100"
- filling.icon += mix_color_from_reagents(reagents.reagent_list)
+ filling.icon += mix_color_from_reagents(beaker.reagents.reagent_list)
overlays += filling
-/obj/machinery/iv_drip/MouseDrop(over_object, src_location, over_location)
- ..()
-
- if(!ishuman(usr) && !isrobot(usr))
- return
-
- var/turf/T = get_turf(src)
- if(!usr in range(1, T))
+/obj/machinery/iv_drip/MouseDrop(mob/living/target)
+ if(!ishuman(usr))
return
if(attached)
- visible_message("[src.attached] is detached from \the [src]")
- src.attached = null
- src.update_icon()
+ visible_message("[attached] is detached from [src].")
+ attached = null
+ update_icon()
return
- if(in_range(src, usr) && ishuman(over_object) && get_dist(over_object, src) <= 1)
- visible_message("[usr] attaches \the [src] to \the [over_object].")
- src.attached = over_object
- src.update_icon()
+ if(!target.dna)
+ to_chat(usr, "The drip beeps: Warning, incompatible creature!")
+ return
-
-/obj/machinery/iv_drip/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- if(istype(W, /obj/item/weapon/reagent_containers))
- if(!isnull(src.beaker))
- to_chat(user, "There is already a reagent container loaded!")
- return
-
- if(user.drop_item())
- W.forceMove(src)
- src.beaker = W
- to_chat(user, "You attach \the [W] to \the [src].")
- src.update_icon()
- return
+ if(Adjacent(target) && usr.Adjacent(target))
+ if(beaker)
+ usr.visible_message("[usr] attaches [src] to [target].", "You attach [src] to [target].")
+ attached = target
+ addAtProcessing()
+ update_icon()
else
- to_chat(user, "\The [W] is stuck to you!")
+ to_chat(usr, "There's nothing attached to the IV drip!")
+
+/obj/machinery/iv_drip/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/weapon/reagent_containers))
+ if(beaker)
+ to_chat(user, "There is already a reagent container loaded!")
+ return
+ if(!user.drop_item())
+ return
+
+ W.forceMove(src)
+ beaker = W
+ to_chat(user, "You attach [W] to [src].")
+ update_icon()
else
return ..()
/obj/machinery/iv_drip/process()
- //set background = 1
+ if(!attached)
+ return PROCESS_KILL
- if(src.attached)
+ if(get_dist(src, attached) > 1 && isturf(attached.loc))
+ to_chat(attached, "The IV drip needle is ripped out of you!")
+ attached.apply_damage(3, BRUTE, pick("r_arm", "l_arm"))
+ attached = null
+ update_icon()
+ return PROCESS_KILL
- if(!(get_dist(src, src.attached) <= 1 && isturf(src.attached.loc)))
- visible_message("The needle is ripped out of [src.attached], doesn't that hurt?")
- src.attached:apply_damage(3, BRUTE, pick("r_arm", "l_arm"))
- src.attached = null
- src.update_icon()
- return
-
- if(src.attached && src.beaker)
+ if(beaker)
// Give blood
if(mode)
- if(src.beaker.volume > 0)
- var/transfer_amount = REAGENTS_METABOLISM
- if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
+ if(beaker.volume > 0)
+ var/transfer_amount = 5
+ if(istype(beaker, /obj/item/weapon/reagent_containers/blood))
// speed up transfer on blood packs
- transfer_amount = 4
- src.beaker.reagents.trans_to(src.attached, transfer_amount)
+ transfer_amount = 10
+ var/fraction = min(transfer_amount/beaker.volume, 1) //the fraction that is transfered of the total volume
+ beaker.reagents.reaction(attached, INGEST, fraction) //make reagents reacts, but don't spam messages
+ beaker.reagents.trans_to(attached, transfer_amount)
update_icon()
// Take blood
@@ -104,71 +130,111 @@
amount = min(amount, 4)
// If the beaker is full, ping
if(amount == 0)
- if(prob(5)) visible_message("\The [src] pings.")
+ if(prob(5))
+ visible_message("[src] pings.")
return
var/mob/living/carbon/human/T = attached
- if(!istype(T)) return
+ if(!ishuman(T))
+ return
+
if(!T.dna)
return
+
if(NOCLONE in T.mutations)
return
- if(T.species && T.species.flags & NO_BLOOD)
+ if(T.species.flags & NO_BLOOD)
return
- // If the human is losing too much blood, beep.
- if(T.vessel.get_reagent_amount("blood") < BLOOD_VOLUME_SAFE) if(prob(5))
- visible_message("\The [src] beeps loudly.")
-
- var/datum/reagent/B = T.take_blood(beaker,amount)
-
- if(B)
- beaker.reagents.reagent_list |= B
- beaker.reagents.update_total()
- beaker.on_reagent_change()
- beaker.reagents.handle_reactions()
+ if(T.species.exotic_blood)
+ T.vessel.trans_to(beaker, amount)
update_icon()
+ else
+ var/datum/reagent/B = T.take_blood(beaker, amount)
-/obj/machinery/iv_drip/attack_hand(mob/living/carbon/user)
- if(!istype(user))
+ if(B)
+ beaker.reagents.reagent_list |= B
+ beaker.reagents.update_total()
+ beaker.on_reagent_change()
+ beaker.reagents.handle_reactions()
+ update_icon()
+
+ // If attached is losing too much blood, beep.
+ var/blood_type = attached.get_blood_name()
+ if(T.vessel.get_reagent_amount(blood_type) < BLOOD_VOLUME_SAFE && prob(5))
+ visible_message("[src] beeps loudly.")
+ playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
+
+/obj/machinery/iv_drip/attack_hand(mob/user)
+ if(!ishuman(user))
return
- if(src.beaker)
- src.beaker.loc = get_turf(src)
- src.beaker = null
+ if(attached)
+ visible_message("[attached] is detached from [src]")
+ attached = null
update_icon()
+ return
+ else if(beaker)
+ eject_beaker(user)
else
- return ..()
+ toggle_mode()
+/obj/machinery/iv_drip/AltClick(mob/user)
+ ..()
+ if(user.incapacitated())
+ to_chat(user, "You can't do that right now!")
+ return
+ if(!Adjacent(user))
+ return
+ toggle_mode()
-/obj/machinery/iv_drip/verb/toggle_mode()
- set name = "Toggle Mode"
+/obj/machinery/iv_drip/verb/eject_beaker(mob/user)
set category = "Object"
+ set name = "Remove IV Container"
set src in view(1)
- if(!istype(usr, /mob/living))
- to_chat(usr, "\red You can't do that.")
+ if(!iscarbon(usr))
+ to_chat(usr, "You can't do that!")
return
- if(usr.stat)
+ if(usr.incapacitated())
+ return
+
+ if(beaker)
+ beaker.forceMove(get_turf(src))
+ beaker = null
+ update_icon()
+
+/obj/machinery/iv_drip/verb/toggle_mode()
+ set category = "Object"
+ set name = "Toggle Mode"
+ set src in view(1)
+
+ if(!iscarbon(usr))
+ to_chat(usr, "You can't do that!")
+ return
+
+ if(usr.incapacitated())
return
mode = !mode
to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].")
+ update_icon()
/obj/machinery/iv_drip/examine(mob/user)
..(user)
- if(!(user in view(2)) && usr != src.loc) return
+ if(!(user in view(2)) && user != loc)
+ return
- to_chat(usr, "The IV drip is [mode ? "injecting" : "taking blood"].")
+ to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
if(beaker)
if(beaker.reagents && beaker.reagents.reagent_list.len)
- to_chat(user, "\blue Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.")
+ to_chat(user, "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid.")
else
- to_chat(user, "\blue Attached is an empty [beaker].")
+ to_chat(user, "Attached is an empty [beaker].")
else
- to_chat(user, "\blue No chemicals are attached.")
+ to_chat(user, "No chemicals are attached.")
- to_chat(user, "\blue [attached ? attached : "No one"] is attached.")
+ to_chat(user, "[attached ? attached : "No one"] is attached.")
diff --git a/icons/obj/iv_drip.dmi b/icons/obj/iv_drip.dmi
index 40068f216e7..016513245e1 100644
Binary files a/icons/obj/iv_drip.dmi and b/icons/obj/iv_drip.dmi differ