//Hydroponics tank and base code /obj/item/watertank name = "backpack water tank" desc = "A S.U.N.S.H.I.N.E. brand watertank backpack with nozzle to water plants." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "waterbackpack" item_state = "waterbackpack" w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK slowdown = 1 actions_types = list(/datum/action/item_action/toggle_mister) max_integrity = 200 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) resistance_flags = FIRE_PROOF var/obj/item/noz var/volume = 500 /obj/item/watertank/Initialize() . = ..() create_reagents(volume) noz = make_noz() /obj/item/watertank/ui_action_click(mob/user) toggle_mister(user) /obj/item/watertank/item_action_slot_check(slot, mob/user) if(slot == user.getBackSlot()) return 1 /obj/item/watertank/proc/toggle_mister(mob/living/user) if(!istype(user)) return if(user.get_item_by_slot(user.getBackSlot()) != src) to_chat(user, "The watertank must be worn properly to use!") return if(user.incapacitated()) return if(QDELETED(noz)) noz = make_noz() if(noz in src) //Detach the nozzle into the user's hands if(!user.put_in_hands(noz)) to_chat(user, "You need a free hand to hold the mister!") return else //Remove from their hands and put back "into" the tank remove_noz() /obj/item/watertank/verb/toggle_mister_verb() set name = "Toggle Mister" set category = "Object" toggle_mister(usr) /obj/item/watertank/proc/make_noz() return new /obj/item/reagent_containers/spray/mister(src) /obj/item/watertank/equipped(mob/user, slot) ..() if(slot != SLOT_BACK) remove_noz() /obj/item/watertank/proc/remove_noz() if(!QDELETED(noz)) if(ismob(noz.loc)) var/mob/M = noz.loc M.temporarilyRemoveItemFromInventory(noz, TRUE) noz.forceMove(src) /obj/item/watertank/Destroy() QDEL_NULL(noz) return ..() /obj/item/watertank/attack_hand(mob/user) if (user.get_item_by_slot(user.getBackSlot()) == src) toggle_mister(user) else return ..() /obj/item/watertank/MouseDrop(obj/over_object) var/mob/M = loc if(istype(M) && istype(over_object, /obj/screen/inventory/hand)) var/obj/screen/inventory/hand/H = over_object M.putItemFromInventoryInHandIfPossible(src, H.held_index) return ..() /obj/item/watertank/attackby(obj/item/W, mob/user, params) if(W == noz) remove_noz() return 1 else return ..() /obj/item/watertank/dropped(mob/user) ..() remove_noz() // This mister item is intended as an extension of the watertank and always attached to it. // Therefore, it's designed to be "locked" to the player's hands or extended back onto // the watertank backpack. Allowing it to be placed elsewhere or created without a parent // watertank object will likely lead to weird behaviour or runtimes. /obj/item/reagent_containers/spray/mister name = "water mister" desc = "A mister nozzle attached to a water tank." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "mister" item_state = "mister" lefthand_file = 'icons/mob/inhands/equipment/mister_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/mister_righthand.dmi' w_class = WEIGHT_CLASS_BULKY amount_per_transfer_from_this = 50 possible_transfer_amounts = list(25,50,100) volume = 500 item_flags = NOBLUDGEON | ABSTRACT // don't put in storage container_type = OPENCONTAINER slot_flags = 0 var/obj/item/watertank/tank /obj/item/reagent_containers/spray/mister/Initialize() . = ..() tank = loc if(!istype(tank)) return INITIALIZE_HINT_QDEL reagents = tank.reagents //This mister is really just a proxy for the tank's reagents /obj/item/reagent_containers/spray/mister/attack_self() return /obj/item/reagent_containers/spray/mister/doMove(atom/destination) if(destination && (destination != tank.loc || !ismob(destination))) if (loc != tank) to_chat(tank.loc, "The mister snaps back onto the watertank.") destination = tank ..() /obj/item/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity) if(target.loc == loc) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it return ..() //Janitor tank /obj/item/watertank/janitor name = "backpack water tank" desc = "A janitorial watertank backpack with nozzle to clean dirt and graffiti." icon_state = "waterbackpackjani" item_state = "waterbackpackjani" /obj/item/watertank/janitor/Initialize() . = ..() reagents.add_reagent("cleaner", 500) /obj/item/reagent_containers/spray/mister/janitor name = "janitor spray nozzle" desc = "A janitorial spray nozzle attached to a watertank, designed to clean up large messes." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "misterjani" item_state = "misterjani" lefthand_file = 'icons/mob/inhands/equipment/mister_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/mister_righthand.dmi' amount_per_transfer_from_this = 5 possible_transfer_amounts = list() /obj/item/watertank/janitor/make_noz() return new /obj/item/reagent_containers/spray/mister/janitor(src) /obj/item/reagent_containers/spray/mister/janitor/attack_self(var/mob/user) amount_per_transfer_from_this = (amount_per_transfer_from_this == 10 ? 5 : 10) to_chat(user, "You [amount_per_transfer_from_this == 10 ? "remove" : "fix"] the nozzle. You'll now use [amount_per_transfer_from_this] units per spray.") //ATMOS FIRE FIGHTING BACKPACK #define EXTINGUISHER 0 #define RESIN_LAUNCHER 1 #define RESIN_FOAM 2 /obj/item/watertank/atmos name = "backpack firefighter tank" desc = "A refrigerated and pressurized backpack tank with extinguisher nozzle, intended to fight fires. Swaps between extinguisher, resin launcher and a smaller scale resin foamer." item_state = "waterbackpackatmos" icon_state = "waterbackpackatmos" volume = 200 slowdown = 0 /obj/item/watertank/atmos/Initialize() . = ..() reagents.add_reagent("water", 200) /obj/item/watertank/atmos/make_noz() return new /obj/item/extinguisher/mini/nozzle(src) /obj/item/watertank/atmos/dropped(mob/user) ..() icon_state = "waterbackpackatmos" if(istype(noz, /obj/item/extinguisher/mini/nozzle)) var/obj/item/extinguisher/mini/nozzle/N = noz N.nozzle_mode = 0 /obj/item/extinguisher/mini/nozzle name = "extinguisher nozzle" desc = "A heavy duty nozzle attached to a firefighter's backpack tank." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "atmos_nozzle" item_state = "nozzleatmos" lefthand_file = 'icons/mob/inhands/equipment/mister_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/mister_righthand.dmi' safety = 0 max_water = 200 power = 8 force = 10 precision = 1 cooling_power = 5 w_class = WEIGHT_CLASS_HUGE item_flags = ABSTRACT // don't put in storage var/obj/item/watertank/tank var/nozzle_mode = 0 var/metal_synthesis_cooldown = 0 var/resin_cooldown = 0 /obj/item/extinguisher/mini/nozzle/Initialize() . = ..() tank = loc if (!istype(tank)) return INITIALIZE_HINT_QDEL reagents = tank.reagents max_water = tank.volume /obj/item/extinguisher/mini/nozzle/doMove(atom/destination) if(destination && (destination != tank.loc || !ismob(destination))) if(loc != tank) to_chat(tank.loc, "The nozzle snaps back onto the tank!") destination = tank ..() /obj/item/extinguisher/mini/nozzle/attack_self(mob/user) switch(nozzle_mode) if(EXTINGUISHER) nozzle_mode = RESIN_LAUNCHER tank.icon_state = "waterbackpackatmos_1" to_chat(user, "Swapped to resin launcher") return if(RESIN_LAUNCHER) nozzle_mode = RESIN_FOAM tank.icon_state = "waterbackpackatmos_2" to_chat(user, "Swapped to resin foamer") return if(RESIN_FOAM) nozzle_mode = EXTINGUISHER tank.icon_state = "waterbackpackatmos_0" to_chat(user, "Swapped to water extinguisher") return return /obj/item/extinguisher/mini/nozzle/afterattack(atom/target, mob/user) if(nozzle_mode == EXTINGUISHER) ..() return var/Adj = user.Adjacent(target) if(Adj) AttemptRefill(target, user) if(nozzle_mode == RESIN_LAUNCHER) if(Adj) return //Safety check so you don't blast yourself trying to refill your tank var/datum/reagents/R = reagents if(R.total_volume < 100) to_chat(user, "You need at least 100 units of water to use the resin launcher!") return if(resin_cooldown) to_chat(user, "Resin launcher is still recharging...") return resin_cooldown = TRUE R.remove_any(100) var/obj/effect/resin_container/A = new (get_turf(src)) log_game("[key_name(user)] used Resin Launcher at [AREACOORD(user)].") playsound(src,'sound/items/syringeproj.ogg',40,1) for(var/a=0, a<5, a++) step_towards(A, target) sleep(2) A.Smoke() spawn(100) if(src) resin_cooldown = FALSE return if(nozzle_mode == RESIN_FOAM) if(!Adj|| !isturf(target)) return for(var/S in target) if(istype(S, /obj/effect/particle_effect/foam/metal/resin) || istype(S, /obj/structure/foamedmetal/resin)) to_chat(user, "There's already resin here!") return if(metal_synthesis_cooldown < 5) var/obj/effect/particle_effect/foam/metal/resin/F = new (get_turf(target)) F.amount = 0 metal_synthesis_cooldown++ spawn(100) metal_synthesis_cooldown-- else to_chat(user, "Resin foam mix is still being synthesized...") return /obj/effect/resin_container name = "resin container" desc = "A compacted ball of expansive resin, used to repair the atmosphere in a room, or seal off breaches." icon = 'icons/effects/effects.dmi' icon_state = "frozen_smoke_capsule" mouse_opacity = MOUSE_OPACITY_TRANSPARENT pass_flags = PASSTABLE anchored = TRUE /obj/effect/resin_container/proc/Smoke() var/obj/effect/particle_effect/foam/metal/resin/S = new /obj/effect/particle_effect/foam/metal/resin(get_turf(loc)) S.amount = 4 playsound(src,'sound/effects/bamf.ogg',100,1) qdel(src) #undef EXTINGUISHER #undef RESIN_LAUNCHER #undef RESIN_FOAM /obj/item/reagent_containers/chemtank name = "backpack chemical injector" desc = "A chemical autoinjector that can be carried on your back." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "waterbackpackatmos" item_state = "waterbackpackatmos" w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK slowdown = 1 actions_types = list(/datum/action/item_action/activate_injector) var/on = FALSE volume = 300 var/usage_ratio = 5 //5 unit added per 1 removed var/injection_amount = 1 amount_per_transfer_from_this = 5 container_type = OPENCONTAINER spillable = FALSE possible_transfer_amounts = list(5,10,15) /obj/item/reagent_containers/chemtank/ui_action_click() toggle_injection() /obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user) if(slot == SLOT_BACK) return 1 /obj/item/reagent_containers/chemtank/proc/toggle_injection() var/mob/living/carbon/human/user = usr if(!istype(user)) return if (user.get_item_by_slot(SLOT_BACK) != src) to_chat(user, "The chemtank needs to be on your back before you can activate it!") return if(on) turn_off() else turn_on() //Todo : cache these. /obj/item/reagent_containers/chemtank/proc/update_filling() cut_overlays() if(reagents.total_volume) var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpack-10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) if(0 to 15) filling.icon_state = "backpack-10" if(16 to 60) filling.icon_state = "backpack50" if(61 to INFINITY) filling.icon_state = "backpack100" filling.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling) /obj/item/reagent_containers/chemtank/worn_overlays(var/isinhands = FALSE) //apply chemcolor and level . = list() //inhands + reagent_filling if(!isinhands && reagents.total_volume) var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "backpackmob-10") var/percent = round((reagents.total_volume / volume) * 100) switch(percent) if(0 to 15) filling.icon_state = "backpackmob-10" if(16 to 60) filling.icon_state = "backpackmob50" if(61 to INFINITY) filling.icon_state = "backpackmob100" filling.color = mix_color_from_reagents(reagents.reagent_list) . += filling /obj/item/reagent_containers/chemtank/proc/turn_on() on = TRUE START_PROCESSING(SSobj, src) if(ismob(loc)) to_chat(loc, "[src] turns on.") /obj/item/reagent_containers/chemtank/proc/turn_off() on = FALSE STOP_PROCESSING(SSobj, src) if(ismob(loc)) to_chat(loc, "[src] turns off.") /obj/item/reagent_containers/chemtank/process() if(!ishuman(loc)) turn_off() return if(!reagents.total_volume) turn_off() return var/mob/living/carbon/human/user = loc if(user.back != src) turn_off() return var/used_amount = injection_amount/usage_ratio reagents.reaction(user, INJECT,injection_amount,0) reagents.trans_to(user,used_amount,multiplier=usage_ratio) update_filling() user.update_inv_back() //for overlays update //Operator backpack spray /obj/item/watertank/op name = "backpack water tank" desc = "A New Russian backpack spray for systematic cleansing of carbon lifeforms." icon_state = "waterbackpackjani" item_state = "waterbackpackjani" w_class = WEIGHT_CLASS_NORMAL volume = 2000 slowdown = 0 /obj/item/watertank/op/Initialize() . = ..() reagents.add_reagent("mutagen",350) reagents.add_reagent("napalm",125) reagents.add_reagent("welding_fuel",125) reagents.add_reagent("clf3",300) reagents.add_reagent("cryptobiolin",350) reagents.add_reagent("plasma",250) reagents.add_reagent("condensedcapsaicin",500) /obj/item/reagent_containers/spray/mister/op desc = "A mister nozzle attached to several extended water tanks. It suspiciously has a compressor in the system and is labelled entirely in New Cyrillic." icon = 'icons/obj/hydroponics/equipment.dmi' icon_state = "misterjani" item_state = "misterjani" lefthand_file = 'icons/mob/inhands/equipment/mister_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/mister_righthand.dmi' w_class = WEIGHT_CLASS_BULKY amount_per_transfer_from_this = 100 possible_transfer_amounts = list(75,100,150) /obj/item/watertank/op/make_noz() return new /obj/item/reagent_containers/spray/mister/op(src)