/obj/item/storage/box/bloodpacks name = "\improper IV bags" desc = "This box contains IV bags." illustration = "blood" /obj/item/storage/box/bloodpacks/fill() ..() new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) new /obj/item/reagent_containers/blood/empty(src) /obj/item/reagent_containers/blood name = "\improper IV bag" desc = "Contains fluids used for transfusions." icon = 'icons/obj/bloodpack.dmi' icon_state = "bloodpack" filling_states = "-10;10;25;50;75;80;100" w_class = WEIGHT_CLASS_SMALL volume = 200 amount_per_transfer_from_this = 0.2 possible_transfer_amounts = list(0.2, 1, 2, 3, 4) atom_flags = ATOM_FLAG_OPEN_CONTAINER var/datum/weakref/attached_mob var/blood_type = null var/vampire_marks = null var/being_feed = FALSE drop_sound = 'sound/items/drop/food.ogg' pickup_sound = 'sound/items/pickup/food.ogg' /obj/item/reagent_containers/blood/feedback_hints(mob/user, distance, is_adjacent) . += ..() if (distance <= 2 && vampire_marks) . += SPAN_WARNING("There are sharp, canine-like teeth marks on it.") /obj/item/reagent_containers/blood/Initialize() . = ..() if(blood_type != null) name = "\improper IV bag - [blood_type] blood" reagents.add_reagent(/singleton/reagent/blood, volume, list("donor"=null,"blood_DNA"=null,"blood_type"=blood_type,"trace_chem"=null,"dose_chem"=null)) w_class = WEIGHT_CLASS_NORMAL update_icon() /obj/item/reagent_containers/blood/Destroy() STOP_PROCESSING(SSprocessing, src) attached_mob = null return ..() /obj/item/reagent_containers/blood/on_reagent_change() update_icon() if(reagents.total_volume > volume / 2) w_class = WEIGHT_CLASS_NORMAL else w_class = WEIGHT_CLASS_SMALL /obj/item/reagent_containers/blood/update_icon() ClearOverlays() if(blood_type) AddOverlays(image('icons/obj/bloodpack.dmi', "[blood_type]")) if(attached_mob) AddOverlays(image('icons/obj/bloodpack.dmi', "dongle")) if(reagents && reagents.total_volume) AddOverlays(overlay_image('icons/obj/bloodpack.dmi', "[icon_state][get_filling_state()]", color = reagents.get_color())) /obj/item/reagent_containers/blood/attack(mob/living/target_mob, mob/living/user, target_zone) if(user == target_mob && (MODE_VAMPIRE in user.mind?.antag_datums)) var/datum/vampire/vampire = user.mind.antag_datums[MODE_VAMPIRE] if (being_feed) to_chat(user, SPAN_NOTICE("You are already feeding on \the [src].")) return if (REAGENT_VOLUME(reagents, /singleton/reagent/blood)) user.visible_message(SPAN_WARNING("[user] raises \the [src] up to their mouth and bites into it."), SPAN_NOTICE("You raise \the [src] up to your mouth and bite into it, starting to drain its contents.
You need to stand still.")) being_feed = TRUE vampire_marks = TRUE if (!LAZYLEN(src.other_DNA)) LAZYADD(src.other_DNA, target_mob.dna.unique_enzymes) src.other_DNA_type = "saliva" while (do_after(user, 25, 5)) var/blood_taken = 0 blood_taken = min(5, REAGENT_VOLUME(reagents, /singleton/reagent/blood)/4) reagents.remove_reagent(/singleton/reagent/blood, blood_taken*4) vampire.blood_usable += blood_taken if (blood_taken) to_chat(user, SPAN_NOTICE("You have accumulated [vampire.blood_usable] unit\s of usable blood. It tastes quite stale.")) if (REAGENT_VOLUME(reagents, /singleton/reagent/blood) < 1) break user.visible_message(SPAN_WARNING("[user] licks [user.get_pronoun("his")] fangs dry, lowering \the [src]."), SPAN_NOTICE("You lick your fangs clean of the tasteless blood.")) being_feed = FALSE else ..() /obj/item/reagent_containers/blood/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) if(!ismob(loc)) return var/turf/our_turf = get_turf(src) var/turf/target_turf = get_turf(over) if(!our_turf.Adjacent(target_turf)) return if(attached_mob) remove_iv_mob() else if(ishuman(over)) visible_message(SPAN_WARNING("\The [user] starts hooking \the [over] up to \the [src].")) if(do_after(user, 30)) to_chat(user, SPAN_NOTICE("You hook \the [over] up to \the [src].")) attached_mob = WEAKREF(over) START_PROCESSING(SSprocessing, src) update_icon() /obj/item/reagent_containers/blood/process() var/mob/living/carbon/human/attached if(attached_mob) attached = attached_mob.resolve() if(!attached) attached_mob = null return PROCESS_KILL var/is_adjacent = loc.Adjacent(attached) if(!is_adjacent || !ismob(loc)) remove_iv_mob(is_adjacent) update_icon() return PROCESS_KILL else remove_iv_mob() return var/mob/M = loc if(M.l_hand != src && M.r_hand != src) remove_iv_mob() return if(!reagents.total_volume) remove_iv_mob() return reagents.trans_to_mob(attached, amount_per_transfer_from_this, CHEM_BLOOD) update_icon() /obj/item/reagent_containers/blood/proc/remove_iv_mob(var/safe = TRUE) if(attached_mob) var/mob/living/carbon/human/attached = attached_mob.resolve() if(attached) if(safe) visible_message(SPAN_NOTICE("\The [attached] is taken off \the [src].")) else var/obj/item/organ/external/affecting = attached.get_organ(pick(BP_R_ARM, BP_L_ARM)) attached.visible_message(SPAN_WARNING("The needle is ripped out of [attached]'s [affecting.limb_name == BP_R_ARM ? "right arm" : "left arm"]."), SPAN_DANGER("The needle painfully rips out of your [affecting.limb_name == BP_R_ARM ? "right arm" : "left arm"].")) affecting.take_damage(brute = 5, damage_flags = DAMAGE_FLAG_SHARP) attached_mob = null STOP_PROCESSING(SSprocessing, src) /obj/item/reagent_containers/blood/attackby(obj/item/attacking_item, mob/user) ..() if (attacking_item.tool_behaviour == TOOL_PEN) if (REAGENT_VOLUME(reagents, /singleton/reagent/blood) && name != "empty IV bag") //Stops people mucking with bloodpacks that are filled to_chat(user, SPAN_NOTICE("You can't relabel [name] until it is empty!")) return var/choices = list("A+ blood", "A- blood", "B+ blood", "B- blood", "O+ blood", "O- blood", "AB+ blood", "AB- blood", "SBS blood", "Saline Plus", "Cryonics mixture", "Other mixture", "Clear", "Cancel") var/blood_name = tgui_input_list(user, "What would you like to label the IV bag?", "Label Selection", choices) if(blood_name == "Cancel") return var/obj/item/i = user.get_active_hand() if(!i.tool_behaviour == TOOL_PEN || !in_range(user, src)) //Checks to see if pen is still held or bloodpack is in range return if(blood_name == "Clear") blood_type = null name = initial(name) desc = initial(desc) to_chat(user, SPAN_NOTICE("You clear the IV bag label.")) update_icon() return blood_type = blood_name name = "\improper IV bag - [blood_type]" desc = "Contains fluids used for transfusions." to_chat(user, SPAN_NOTICE("You label the IV bag as [blood_type].")) update_icon() return if (istype(attacking_item, /obj/item/) && attacking_item.sharp == 1) var/mob/living/carbon/human/H = usr if(LAZYLEN(attacking_item.attack_verb)) user.visible_message(SPAN_DANGER("[src] has been [pick(attacking_item.attack_verb)] with \the [attacking_item] by [user]!")) var/atkmsg_filled = null if (REAGENT_VOLUME(reagents, /singleton/reagent/blood)) atkmsg_filled = " and the contents spray everywhere" if (src.loc != usr) var/strength var/percent = round((REAGENT_VOLUME(reagents, /singleton/reagent/blood) / volume) * 100) //the amount of blood changes the strength of spray switch(percent) if(1 to 9) strength = 2 if(10 to 50) strength = 3 if(51 to INFINITY) strength = 4 for (var/j = 0, j < strength - 1, j++) //The number of separate splatters spray_loop: var/direction = pick(GLOB.alldirs) var/target for (var/i = 1, i < strength, i++) //The distance the splatters will travel from random direction switch (direction) if (NORTH) target = locate(src.x, src.y+i, src.z) if (SOUTH) target = locate(src.x, src.y-i, src.z) if (EAST) target = locate(src.x+i, src.y, src.z) if (WEST) target = locate(src.x-i, src.y, src.z) if (NORTHEAST) target = locate(src.x+i, src.y+i, src.z) if (NORTHWEST) target = locate(src.x-i, src.y+i, src.z) if (SOUTHEAST) target = locate(src.x+i, src.y-i, src.z) if (SOUTHWEST) target = locate(src.x-i, src.y-i, src.z) if (istype(get_turf(target), /turf/simulated/wall)) blood_splatter(target, null, 1) break spray_loop var/turf/base = get_turf(target) for (var/atom/A in base) // Stops your blood spray if it meets a person, wall, door or window if (istype(A, /mob/living/carbon/human/)) var/mob/living/carbon/human/K = A K.bloody_body() break spray_loop if ((!istype(A, /obj/) && A.density) || istype(A, /obj/structure/window/) || istype(A, /obj/machinery/door/airlock/)) break spray_loop blood_splatter(target, null, 1) blood_splatter(src.loc, null, 1) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1, -6) if(istype(H)) H.bloody_hands() if (loc == usr) H.bloody_body() // Line below will do a check where the target bloodbag is located and create a new one accordingly var/obj/item/reagent_containers/I = src.loc != usr ? new/obj/item/reagent_containers/blood/ripped(src.loc) : new/obj/item/reagent_containers/blood/ripped(usr.loc) if (REAGENT_VOLUME(reagents, /singleton/reagent/blood)) I.add_blood() var/atkmsg = SPAN_WARNING("\The [src] rips apart[atkmsg_filled]!") user.visible_message(atkmsg) qdel(src) return return /obj/item/reagent_containers/blood/APlus blood_type = "A+" /obj/item/reagent_containers/blood/AMinus blood_type = "A-" /obj/item/reagent_containers/blood/BPlus blood_type = "B+" /obj/item/reagent_containers/blood/BMinus blood_type = "B-" /obj/item/reagent_containers/blood/OPlus blood_type = "O+" /obj/item/reagent_containers/blood/OMinus blood_type = "O-" /obj/item/reagent_containers/blood/sbs blood_type = "SBS" /obj/item/reagent_containers/blood/empty name = "empty IV bag" desc = "Seems pretty useless... Maybe if there were a way to fill it?" icon_state = "bloodpack" /obj/item/reagent_containers/blood/ripped name = "ripped IV bag" desc = "It's torn up and useless." icon = 'icons/obj/bloodpack.dmi' icon_state = "ripped" volume = 0 /obj/item/reagent_containers/blood/ripped/attackby(obj/item/attacking_item, mob/user) to_chat(user, SPAN_WARNING("You can't do anything further with this.")) return