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