Merge pull request #9538 from variableundefined/ContainerTypeRefactor

TG container_type refactor
This commit is contained in:
tigercat2000
2018-10-20 18:34:57 -07:00
committed by GitHub
41 changed files with 232 additions and 228 deletions
-2
View File
@@ -17,8 +17,6 @@
#define HEADBANGPROTECT 4096
#define OPENCONTAINER 4096 // is an open container for chemistry purposes
#define BLOCK_GAS_SMOKE_EFFECT 8192 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY!
#define THICKMATERIAL 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with BLOCK_GAS_SMOKE_EFFECT)
+12
View File
@@ -4,3 +4,15 @@
#define REAGENT_OVERDOSE_EFFECT 1
#define REAGENT_OVERDOSE_FLAGS 2
// container_type defines
#define INJECTABLE 1 // Makes it possible to add reagents through droppers and syringes.
#define DRAWABLE 2 // Makes it possible to remove reagents through syringes.
#define REFILLABLE 4 // Makes it possible to add reagents through any reagent container.
#define DRAINABLE 8 // Makes it possible to remove reagents through any reagent container.
#define TRANSPARENT 16 // Used on containers which you want to be able to see the reagents off.
#define AMOUNT_VISIBLE 32 // For non-transparent containers that still have the general amount of reagents in them visible.
// Is an open container for all intents and purposes.
#define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT)
+29 -25
View File
@@ -16,6 +16,7 @@
var/dont_save = 0 // For atoms that are temporary by necessity - like lighting overlays
///Chemistry.
var/container_type = NONE
var/datum/reagents/reagents = null
//This atom's HUD (med/sec, etc) images. Associative list.
@@ -23,9 +24,6 @@
//HUD images that this atom can provide.
var/list/hud_possible
//var/chem_is_open_container = 0
// replaced by OPENCONTAINER flags and atom/proc/is_open_container()
///Chemistry.
@@ -198,22 +196,21 @@
/atom/proc/Bumped(AM as mob|obj)
return
// Convenience proc to see if a container is open for chemistry handling
// returns true if open
// false if closed
// Convenience procs to see if a container is open for chemistry handling
/atom/proc/is_open_container()
return flags & OPENCONTAINER
return is_refillable() && is_drainable()
/*//Convenience proc to see whether a container can be accessed in a certain way.
/atom/proc/is_injectable(allowmobs = TRUE)
return reagents && (container_type & (INJECTABLE | REFILLABLE))
proc/can_subract_container()
return flags & EXTRACT_CONTAINER
proc/can_add_container()
return flags & INSERT_CONTAINER
*/
/atom/proc/is_drawable(allowmobs = TRUE)
return reagents && (container_type & (DRAWABLE | DRAINABLE))
/atom/proc/is_refillable()
return reagents && (container_type & REFILLABLE)
/atom/proc/is_drainable()
return reagents && (container_type & DRAINABLE)
/atom/proc/CheckExit()
return 1
@@ -279,17 +276,24 @@
if(desc)
to_chat(user, desc)
if(reagents && is_open_container()) //is_open_container() isn't really the right proc for this, but w/e
to_chat(user, "It contains:")
if(reagents.reagent_list.len)
if(user.can_see_reagents()) //Show each individual reagent
for(var/datum/reagent/R in reagents.reagent_list)
to_chat(user, "[R.volume] units of [R.name]")
else //Otherwise, just show the total volume
if(reagents && reagents.reagent_list.len)
to_chat(user, "[reagents.total_volume] units of various reagents.")
else
to_chat(user, "Nothing.")
if(reagents)
if(container_type & TRANSPARENT)
to_chat(user, "<span class='notice'>It contains:</span>")
if(reagents.reagent_list.len)
if(user.can_see_reagents()) //Show each individual reagent
for(var/I in reagents.reagent_list)
var/datum/reagent/R = I
to_chat(user, "<span class='notice'>[R.volume] units of [R.name]</span>")
else //Otherwise, just show the total volume
if(reagents && reagents.reagent_list.len)
to_chat(user, "<span class='notice'>[reagents.total_volume] units of various reagents.</span>")
else
to_chat(user, "<span class='notice'>Nothing.</span> ")
else if(container_type & AMOUNT_VISIBLE)
if(reagents.total_volume)
to_chat(user, "<span class='notice'>It has [reagents.total_volume] unit\s left.</span>")
else
to_chat(user, "<span class='danger'>It's empty.</span>")
SendSignal(COMSIG_PARENT_EXAMINE, user)
+1 -1
View File
@@ -281,7 +281,7 @@
return
B.forceMove(src)
beaker = B
add_attack_logs(user, null, "Added [B] containing [B.reagentlist()] to a cryo cell at [COORD(src)]")
add_attack_logs(user, null, "Added [B] containing [B.reagents.log_list()] to a cryo cell at [COORD(src)]")
user.visible_message("[user] adds \a [B] to [src]!", "You add \a [B] to [src]!")
+2 -1
View File
@@ -439,7 +439,8 @@ REAGENT SCANNER
icon_state = "spectrometer"
item_state = "analyzer"
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT | OPENCONTAINER
flags = CONDUCT
container_type = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 5
throw_speed = 4
@@ -11,6 +11,7 @@
throw_speed = 2
throw_range = 7
force = 10
container_type = AMOUNT_VISIBLE
materials = list(MAT_METAL=90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
var/max_water = 50
@@ -36,11 +37,8 @@
sprite_name = "miniFE"
/obj/item/extinguisher/examine(mob/user)
if(..(user, 0))
to_chat(usr, "[bicon(src)] [src.name] contains:")
if(reagents && reagents.reagent_list.len)
for(var/datum/reagent/R in reagents.reagent_list)
to_chat(user, "<span class='notice'>[R.volume] units of [R.name]</span>")
. = ..()
to_chat(user, "<span class='notice'>The safety is [safety ? "on" : "off"].</span>")
/obj/item/extinguisher/New()
@@ -3,7 +3,7 @@
desc = "Injects things."
icon_state = "reagents"
origin_tech = "materials=3;biotech=4"
flags = OPENCONTAINER
container_type = OPENCONTAINER
/obj/item/implant/chem/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>
+1 -1
View File
@@ -13,7 +13,7 @@
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(5,10,20,30,50,70)
volume = 70
flags = OPENCONTAINER
container_type = OPENCONTAINER
/obj/item/reagent_containers/glass/paint/afterattack(turf/simulated/target, mob/user, proximity)
if(!proximity)
@@ -116,7 +116,8 @@
amount_per_transfer_from_this = 50
possible_transfer_amounts = list(25,50,100)
volume = 500
flags = NODROP | OPENCONTAINER | NOBLUDGEON
flags = NODROP | NOBLUDGEON
container_type = OPENCONTAINER
var/obj/item/watertank/tank
+1 -1
View File
@@ -7,7 +7,7 @@
icon_state = "cart"
anchored = 0
density = 1
flags = OPENCONTAINER
container_type = OPENCONTAINER
//copypaste sorry
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
var/obj/item/storage/bag/trash/mybag = null
+1 -1
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/janitor.dmi'
icon_state = "mopbucket"
density = 1
flags = OPENCONTAINER
container_type = OPENCONTAINER
var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite
/obj/structure/mopbucket/New()
+2 -2
View File
@@ -115,8 +115,8 @@
if(!open)
return
var/obj/item/reagent_containers/RG = I
if(RG.is_open_container())
if(RG.reagents.total_volume >= RG.volume)
if(RG.is_refillable())
if(RG.reagents.holder_full())
to_chat(user, "<span class='warning'>[RG] is full.</span>")
else
RG.reagents.add_reagent("toiletwater", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
+1 -1
View File
@@ -69,7 +69,7 @@
else
if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = I
if(RC.flags & OPENCONTAINER)
if(RC.container_type & OPENCONTAINER)
for(var/datum/reagent/A in RC.reagents.reagent_list)
.[A.type] += A.volume
.[I.type] += 1
@@ -19,7 +19,8 @@
possible_transfer_amounts = list(5)
volume = 5
can_be_placed_into = null
flags = OPENCONTAINER | NOBLUDGEON
flags = NOBLUDGEON
container_type = OPENCONTAINER
var/wipespeed = 30
/obj/item/reagent_containers/glass/rag/attack(atom/target as obj|turf|area, mob/user as mob , flag)
+65 -70
View File
@@ -474,7 +474,7 @@
//Finally, report the full examine_message constructed from the above reports
to_chat(user, "[examine_message]")
to_chat(user, "<span class='notice'>[examine_message]</span>")
return examine_message
//////////////////////////////
@@ -485,37 +485,37 @@
if(istype(M, /mob/living/simple_animal/pet/cat))
if(M.a_intent == INTENT_HELP) //Cats can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
M.visible_message("[M.name] stares at into [src] while sitting perfectly still.", "The lid is closed, so you stare into [src] intently.")
M.visible_message("<span class='notice'>[M.name] stares at into [src] while sitting perfectly still.</span>", "<span class='notice'>The lid is closed, so you stare into [src] intently.</span>")
else
if(fish_count) //Tank must actually have fish to try catching one
M.visible_message("[M.name] leaps up onto [src] and attempts to fish through the opening!", "You jump up onto [src] and begin fishing through the opening!")
M.visible_message("<span class='warning'>[M.name] leaps up onto [src] and attempts to fish through the opening!</span>", "<span class='notice'>You jump up onto [src] and begin fishing through the opening!</span>")
if(water_level && prob(45)) //If there is water, there is a chance the cat will slip, Syndicat will spark like E-N when this happens
M.visible_message("[M.name] slipped and got soaked!", "You slipped and got soaked!")
M.visible_message("<span class='notice'>[M.name] slipped and got soaked!</span>", "<span class='notice'>You slipped and got soaked!</span>")
if(istype(M, /mob/living/simple_animal/pet/cat/Syndi))
do_sparks(3, 1, src)
else //No water or didn't slip, get that fish!
M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
M.visible_message("<span class='warning'>[M.name] catches and devours a live fish!</span>", "<span class='notice'>You catch and devour a live fish, yum!</span>")
kill_fish() //Kill a random fish
M.health = M.maxHealth //Eating fish heals the predator
else
to_chat(M, "There are no fish in [src]!")
to_chat(M, "<span class='warning'>There are no fish in [src]!</span>")
else
return ..()
else if(istype(M, /mob/living/simple_animal/hostile/bear))
if(M.a_intent == INTENT_HELP) //Bears can try to fish in open tanks on help intent
if(lid_switch) //Can't fish in a closed tank. Fishbowls are ALWAYS open.
M.visible_message("[M.name] scrapes it's claws along [src]'s lid.", "The lid is closed, so you scrape your claws against [src]'s lid.")
M.visible_message("<span class='notice'>[M.name] scrapes it's claws along [src]'s lid.</span>", "<span class='notice'>The lid is closed, so you scrape your claws against [src]'s lid.</span>")
else
if(fish_count) //Tank must actually have fish to try catching one
M.visible_message("[M.name] reaches into [src] and attempts to fish through the opening!", "You reach into [src] and begin fishing through the opening!")
M.visible_message("<span class='warning'>[M.name] reaches into [src] and attempts to fish through the opening!</span>", "<span class='warning'>You reach into [src] and begin fishing through the opening!</span>")
if(water_level && prob(5)) //Bears are good at catching fish, only a 5% chance to fail
M.visible_message("[M.name] swipes at the water!", "You just barely missed that fish!")
M.visible_message("<span class='warning'>[M.name] swipes at the water!</span>", "<span class='notice'>You just barely missed that fish!</span>")
else //No water or didn't slip, get that fish!
M.visible_message("[M.name] catches and devours a live fish!", "You catch and devour a live fish, yum!")
M.visible_message("<span class='warning'>[M.name] catches and devours a live fish!</span>", "<span class='notice'>You catch and devour a live fish, yum!</span>")
kill_fish() //Kill a random fish
M.health = M.maxHealth //Eating fish heals the predator
else
to_chat(M, "There are no fish in [src]!")
to_chat(M, "<span class='warning'>There are no fish in [src]!</span>")
else
return ..()
else
@@ -530,8 +530,8 @@
"You hear a banging sound.")
else
playsound(loc, 'sound/effects/glassknock.ogg', 80, 1)
user.visible_message("[user.name] taps on the [name].", \
"You tap on the [name].", \
user.visible_message("<span class='notice'>[user.name] taps on the [name].</span>", \
"<span class='notice'>You tap on the [name].</span>", \
"You hear a knocking sound.")
/obj/machinery/fishtank/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1)
@@ -571,62 +571,57 @@
if(W.isOn())
if(obj_integrity < max_integrity)
playsound(loc, W.usesound, 50, 1)
to_chat(user, "You repair some of the cracks on [src].")
to_chat(user, "<span class='notice'>You repair some of the cracks on [src].</span>")
obj_integrity = min(obj_integrity + 20, max_integrity)
check_health()
else
to_chat(user, "There is no damage to fix!")
to_chat(user, "<span class='notice'>There is no damage to fix!</span>")
else
if(obj_integrity < max_integrity)
to_chat(user, "[W] must be on to repair this damage.")
to_chat(user, "<span class='notice'>[W] must be on to repair this damage.</span>")
else
return ..()
//Open reagent containers add and remove water
else if(O.is_open_container())
if(istype(O, /obj/item/reagent_containers/glass))
if(lid_switch)
to_chat(user, "Open the lid on [src] first!")
return
var/obj/item/reagent_containers/glass/C = O
//Containers with any reagents will get dumped in
if(C.reagents.total_volume)
var/water_value = 0
water_value += C.reagents.get_reagent_amount("water") //Water is full value
water_value += C.reagents.get_reagent_amount("holywater") *1.1 //Holywater is (somehow) better. Who said religion had to make sense?
water_value += C.reagents.get_reagent_amount("tonic") * 0.25 //Tonic water is 25% value
water_value += C.reagents.get_reagent_amount("sodawater") * 0.50 //Sodawater is 50% value
water_value += C.reagents.get_reagent_amount("fishwater") * 0.75 //Fishwater is 75% value, to account for the fish poo
water_value += C.reagents.get_reagent_amount("ice") * 0.80 //Ice is 80% value
var/message = ""
if(!water_value) //The container has no water value, clear everything in it
message = "The filtration process removes everything, leaving the water level unchanged."
C.reagents.clear_reagents()
else
if(water_level == water_capacity)
to_chat(user, "[src] is already full!")
else
message = "The filtration process purifies the water, raising the water level."
if((water_level + water_value) == water_capacity)
message += " You filled [src] to the brim!"
if((water_level + water_value) > water_capacity)
message += " You overfilled [src] and some water runs down the side, wasted."
C.reagents.clear_reagents()
adjust_water_level(water_value)
user.visible_message("[user.name] pours the contents of [C.name] into [src].", "[message]")
//Empty containers will scoop out water, filling the container as much as possible from the water_level
else if(O.is_drainable())
//Containers with any reagents will get dumped in
if(O.reagents.total_volume)
var/water_value = 0
water_value += O.reagents.get_reagent_amount("water") //Water is full value
water_value += O.reagents.get_reagent_amount("holywater") *1.1 //Holywater is (somehow) better. Who said religion had to make sense?
water_value += O.reagents.get_reagent_amount("tonic") * 0.25 //Tonic water is 25% value
water_value += O.reagents.get_reagent_amount("sodawater") * 0.50 //Sodawater is 50% value
water_value += O.reagents.get_reagent_amount("fishwater") * 0.75 //Fishwater is 75% value, to account for the fish poo
water_value += O.reagents.get_reagent_amount("ice") * 0.80 //Ice is 80% value
var/message = ""
if(!water_value) //The container has no water value, clear everything in it
message = "The filtration process removes everything, leaving the water level unchanged."
O.reagents.clear_reagents()
else
if(!water_level)
to_chat(user, "[src] is empty!")
if(water_level == water_capacity)
to_chat(user, "<span class='notice'>[src] is already full!</span>")
else
if(water_level >= C.volume) //Enough to fill the container completely
C.reagents.add_reagent("fishwater", C.volume)
adjust_water_level(-C.volume)
user.visible_message("[user.name] scoops out some water from [src].", "You completely fill [C.name] from [src].")
else //Fill the container as much as possible with the water_level
C.reagents.add_reagent("fishwater", water_level)
adjust_water_level(-water_level)
user.visible_message("[user.name] scoops out some water from [src].", "You fill [C.name] with the last of the water in [src].")
message = "The filtration process purifies the water, raising the water level."
if((water_level + water_value) == water_capacity)
message += " You filled [src] to the brim!"
if((water_level + water_value) > water_capacity)
message += " You overfilled [src] and some water runs down the side, wasted."
O.reagents.clear_reagents()
adjust_water_level(water_value)
user.visible_message("<span class='notice'>[user.name] pours the contents of [O.name] into [src].</span>", "<span class='notice'>[message]</span>")
//Empty containers will scoop out water, filling the container as much as possible from the water_level
else if(O.is_refillable())
if(!water_level)
to_chat(user, "<span class='notice'>[src] is empty!</span>")
else
if(water_level >= O.reagents.maximum_volume) //Enough to fill the container completely
O.reagents.add_reagent("fishwater", O.reagents.maximum_volume)
adjust_water_level(-O.reagents.maximum_volume)
user.visible_message("<span class='notice'>[user.name] scoops out some water from [src].</span>", "<span class='notice'>You completely fill [O.name] from [src].</span>")
else //Fill the container as much as possible with the water_level
O.reagents.add_reagent("fishwater", water_level)
adjust_water_level(-water_level)
user.visible_message("<span class='notice'>[user.name] scoops out some water from [src].</span>", "<span class='notice'>You fill [O.name] with the last of the water in [src].</span>")
//Wrenches can deconstruct empty tanks, but not tanks with any water. Kills any fish left inside and destroys any unharvested eggs in the process
else if(iswrench(O))
if(!water_level)
@@ -635,17 +630,17 @@
if(do_after(user, 50 * O.toolspeed, target = src))
deconstruct(TRUE)
else
to_chat(user, "[src] must be empty before you disassemble it!")
to_chat(user, "<span class='warning'>[src] must be empty before you disassemble it!</span>")
//Fish eggs
else if(istype(O, /obj/item/fish_eggs))
var/obj/item/fish_eggs/egg = O
//Don't add eggs if there is no water (they kinda need that to live)
if(!water_level)
to_chat(user, "[src] has no water; [egg.name] won't hatch without water!")
to_chat(user, "<span class='warning'>[src] has no water; [egg.name] won't hatch without water!</span>")
else
//Don't add eggs if the tank already has the max number of fish
if(fish_count >= max_fish)
to_chat(user, "[src] can't hold any more fish.")
to_chat(user, "<span class='notice'>[src] can't hold any more fish.</span>")
else
add_fish(egg.fish_type)
qdel(egg)
@@ -655,30 +650,30 @@
if(water_level)
if(food_level < 10)
if(fish_count == 0)
user.visible_message("[user.name] shakes some fish food into the empty [src]... How sad.", "You shake some fish food into the empty [src]... If only it had fish.")
user.visible_message("<span class='notice'>[user.name] shakes some fish food into the empty [src]... How sad.</span>", "<span class='notice'>You shake some fish food into the empty [src]... If only it had fish.</span>")
else
user.visible_message("[user.name] feeds the fish in [src]. The fish look excited!", "You feed the fish in [src]. They look excited!")
user.visible_message("<span class='notice'>[user.name] feeds the fish in [src]. The fish look excited!</span>", "<span class='notice'>You feed the fish in [src]. They look excited!</span>")
adjust_food_level(10)
else
to_chat(user, "[src] already has plenty of food in it. You decide to not add more.")
to_chat(user, "<span class='notice'>[src] already has plenty of food in it. You decide to not add more.</span>")
else
to_chat(user, "[src] doesn't have any water in it. You should fill it with water first.")
to_chat(user, "<span class='notice'>[src] doesn't have any water in it. You should fill it with water first.</span>")
//Fish egg scoop
else if(istype(O, /obj/item/egg_scoop))
if(egg_count)
user.visible_message("[user.name] harvests some fish eggs from [src].", "You scoop the fish eggs out of [src].")
user.visible_message("<span class='notice'>[user.name] harvests some fish eggs from [src].</span>", "<span class='notice'>You scoop the fish eggs out of [src].</span>")
harvest_eggs(user)
else
user.visible_message("[user.name] fails to harvest any fish eggs from [src].", "There are no fish eggs in [src] to scoop out.")
user.visible_message("<span class='notice'>[user.name] fails to harvest any fish eggs from [src].</span>", "<span class='notice'>There are no fish eggs in [src] to scoop out.</span>")
//Fish net
else if(istype(O, /obj/item/fish_net))
harvest_fish(user)
//Tank brush
else if(istype(O, /obj/item/tank_brush))
if(filth_level == 0)
to_chat(user, "[src] is already spotless!")
to_chat(user, "<span class='warning'>[src] is already spotless!</span>")
else
adjust_filth_level(-filth_level)
user.visible_message("[user.name] scrubs the inside of [src], cleaning the filth.", "You scrub the inside of [src], cleaning the filth.")
user.visible_message("<span class='notice'>[user.name] scrubs the inside of [src], cleaning the filth.</span>", "<span class='notice'>You scrub the inside of [src], cleaning the filth.</span>")
else
return ..()
@@ -235,7 +235,7 @@
//empties aren't sealed, so let's open it quietly
drink_container = new drink_container()
drink_container.canopened = 1
drink_container.flags |= OPENCONTAINER
drink_container.container_type |= OPENCONTAINER
drink_container.forceMove(loc)
containers[con_type]--
+37 -42
View File
@@ -6,7 +6,7 @@
desc = "yummy"
icon = 'icons/obj/drinks.dmi'
icon_state = null
flags = OPENCONTAINER
container_type = OPENCONTAINER
consume_sound = 'sound/items/drink.ogg'
possible_transfer_amounts = list(5,10,15,20,25,30,50)
volume = 50
@@ -26,7 +26,11 @@
/obj/item/reagent_containers/food/drinks/attack(mob/M, mob/user, def_zone)
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='warning'> None of [src] left, oh no!</span>")
return 0
return FALSE
if(!is_drainable())
to_chat(user, "<span class='warning'> You need to open [src] first!</span>")
return FALSE
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
@@ -36,14 +40,13 @@
borg.cell.use(30)
var/refill = reagents.get_master_reagent_id()
if(refill in GLOB.drinks) // Only synthesize drinks
spawn(600)
reagents.add_reagent(refill, bitesize)
return 1
return 0
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, bitesize), 600)
return TRUE
return FALSE
/obj/item/reagent_containers/food/drinks/MouseDrop(atom/over_object) //CHUG! CHUG! CHUG!
var/mob/living/carbon/chugger = over_object
if (!(flags & OPENCONTAINER))
if (!(container_type & DRAINABLE))
to_chat(chugger, "<span class='notice'>You need to open [src] first!</span>")
return
if(istype(chugger) && loc == chugger && src == chugger.get_active_hand() && reagents.total_volume)
@@ -56,39 +59,18 @@
break
/obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user, proximity)
if(!proximity) return
if(!proximity)
return
// Moved from the can code; not necessary since closed cans aren't open containers now, but, eh.
if(istype(target, /obj/item/reagent_containers/food/drinks/cans))
var/obj/item/reagent_containers/food/drinks/cans/cantarget = target
if(cantarget.canopened == 0)
to_chat(user, "<span class='notice'>You need to open the drink you want to pour into!</span>")
return
if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'> [target] is empty.</span>")
return
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='warning'> [src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'> You fill [src] with [trans] units of the contents of [target].</span>")
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'> [src] is empty.</span>")
return
return FALSE
if(target.reagents.total_volume >= target.reagents.maximum_volume)
if(target.reagents.holder_full())
to_chat(user, "<span class='warning'> [target] is full.</span>")
return
return FALSE
var/datum/reagent/refill
var/datum/reagent/refillName
if(isrobot(user))
@@ -103,18 +85,30 @@
var/mob/living/silicon/robot/bro = user
var/chargeAmount = max(30,4*trans)
bro.cell.use(chargeAmount)
to_chat(user, "Now synthesizing [trans] units of [refillName]...")
to_chat(user, "<span class='notice'>Now synthesizing [trans] units of [refillName]...</span>")
addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 300)
addtimer(CALLBACK(GLOBAL_PROC, .proc/__to_chat, user, "<span class='notice'>Cyborg [src] refilled.</span>"), 300)
else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
if(!is_refillable())
to_chat(user, "<span class='warning'>[src]'s tab isn't open!</span>")
return FALSE
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty.</span>")
return FALSE
spawn(300)
reagents.add_reagent(refill, trans)
to_chat(user, "Cyborg [src] refilled.")
if(reagents.holder_full())
to_chat(user, "<span class='warning'>[src] is full.</span>")
return FALSE
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
return FALSE
/obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/clothing/mask/cigarette)) //ciggies are weird
return
return FALSE
if(is_hot(I))
if(reagents)
reagents.chem_temp += 15
@@ -151,7 +145,8 @@
materials = list(MAT_METAL=100)
possible_transfer_amounts = list()
volume = 5
flags = CONDUCT | OPENCONTAINER
flags = CONDUCT
container_type = OPENCONTAINER
/obj/item/reagent_containers/food/drinks/trophy/gold_cup
name = "gold cup"
@@ -10,7 +10,7 @@
desc = "Just your average condiment container."
icon = 'icons/obj/food/containers.dmi'
icon_state = "emptycondiment"
flags = OPENCONTAINER
container_type = OPENCONTAINER
possible_transfer_amounts = list(1, 5, 10, 15, 20, 25, 30, 50)
volume = 50
//Possible_states has the reagent id as key and a list of, in order, the icon_state, the name and the desc as values. Used in the on_reagent_change() to change names, descs and sprites.
@@ -47,7 +47,7 @@
if(!reagents || !reagents.total_volume)
return // The condiment might be empty after the delay.
user.visible_message("<span class='warning'>[user] feeds [M] from [src].</span>")
add_attack_logs(user, M, "Fed [src] containing [reagentlist()]")
add_attack_logs(user, M, "Fed [src] containing [reagents.log_list()]")
var/fraction = min(10/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
@@ -75,7 +75,7 @@
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
//Something like a glass or a food item. Player probably wants to transfer TO it.
else if(target.is_open_container() || istype(target, /obj/item/reagent_containers/food/snacks))
else if(target.is_drainable() || istype(target, /obj/item/reagent_containers/food/snacks))
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>[src] is empty!</span>")
return
@@ -8,7 +8,7 @@
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 100
flags = OPENCONTAINER
container_type = OPENCONTAINER
var/operating = 0 // Is it on?
var/dirty = 0 // = {0..100} Does it need cleaning?
var/broken = 0 // ={0,1,2} How broken is it???
@@ -93,7 +93,7 @@
icon_state = off_icon
broken = 0 // Fix it!
dirty = 0 // just to be sure
flags = OPENCONTAINER
container_type = OPENCONTAINER
else
to_chat(user, "<span class='alert'>It's broken!</span>")
return 1
@@ -105,7 +105,7 @@
dirty = 0 // It's clean!
broken = 0 // just to be sure
icon_state = off_icon
flags = OPENCONTAINER
container_type = OPENCONTAINER
else //Otherwise bad luck!!
to_chat(user, "<span class='alert'>It's dirty!</span>")
return 1
+2 -2
View File
@@ -21,7 +21,7 @@
icon_state = "weedspray"
item_state = "plantbgone"
volume = 100
flags = OPENCONTAINER
container_type = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
@@ -43,7 +43,7 @@
icon_state = "pestspray"
item_state = "plantbgone"
volume = 100
flags = OPENCONTAINER
container_type = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
+2 -2
View File
@@ -763,8 +763,8 @@
else if(transfer_amount) // Droppers, cans, beakers, what have you.
visi_msg="[user] uses [reagent_source] on [target]"
irrigate = 1
// Beakers, bottles, buckets, etc. Can't use is_open_container though.
if(istype(reagent_source, /obj/item/reagent_containers/glass/))
// Beakers, bottles, buckets, etc.
if(reagent_source.is_drainable())
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
if(irrigate && transfer_amount > 30 && reagent_source.reagents.total_volume >= 30 && using_irrigation)
+1 -1
View File
@@ -1019,7 +1019,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
return 1
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/reagent_containers/food/toEat, mob/user)
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagentlist(toEat)]", ATKLOG_MOST)
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagents.log_list(toEat)]", ATKLOG_MOST)
if(!iscarbon(user))
LAssailant = null
else
+7 -1
View File
@@ -329,7 +329,13 @@
/mob/living/proc/can_inject()
return 1
return TRUE
/mob/living/is_injectable(allowmobs = TRUE)
return (allowmobs && reagents && can_inject())
/mob/living/is_drawable(allowmobs = TRUE)
return (allowmobs && reagents && can_inject())
/mob/living/proc/get_organ_target()
var/mob/shooter = src
+1 -1
View File
@@ -123,7 +123,7 @@
* Sleepypens
*/
/obj/item/pen/sleepy
flags = OPENCONTAINER
container_type = OPENCONTAINER
origin_tech = "engineering=4;syndicate=2"
@@ -242,11 +242,11 @@
name = "shotgun dart"
desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical."
icon_state = "cshell"
container_type = OPENCONTAINER
projectile_type = /obj/item/projectile/bullet/dart
/obj/item/ammo_casing/shotgun/dart/New()
..()
flags |= OPENCONTAINER
create_reagents(30)
/obj/item/ammo_casing/shotgun/dart/attackby()
+3 -3
View File
@@ -29,7 +29,7 @@
var/obj/item/dart_cartridge/cartridge = null //Container of darts.
var/max_beakers = 3
var/dart_reagent_amount = 15
var/container_type = /obj/item/reagent_containers/glass/beaker
var/containers_type = /obj/item/reagent_containers/glass/beaker
var/list/starting_chems = null
/obj/item/gun/dartgun/update_icon()
@@ -49,7 +49,7 @@
..()
if(starting_chems)
for(var/chem in starting_chems)
var/obj/B = new container_type(src)
var/obj/B = new containers_type(src)
B.reagents.add_reagent(chem, 50)
beakers += B
cartridge = new /obj/item/dart_cartridge(src)
@@ -87,7 +87,7 @@
update_icon()
return
if(istype(I, /obj/item/reagent_containers/glass))
if(!istype(I, container_type))
if(!istype(I, containers_type))
to_chat(user, "<span class='warning'>[I] doesn't seem to fit into [src].</span>")
return
if(beakers.len >= max_beakers)
@@ -143,7 +143,8 @@
fire_sound = 'sound/weapons/laser.ogg'
usesound = 'sound/items/Welder.ogg'
toolspeed = 1
flags = CONDUCT | OPENCONTAINER
container_type = OPENCONTAINER
flags = CONDUCT
attack_verb = list("attacked", "slashed", "cut", "sliced")
force = 12
sharp = 1
+15
View File
@@ -683,6 +683,16 @@ var/const/INGEST = 2
stuff += A.id
return english_list(stuff)
/datum/reagents/proc/log_list()
if(!length(reagent_list))
return "no reagents"
var/list/data = list()
for(var/r in reagent_list) //no reagents will be left behind
var/datum/reagent/R = r
data += "[R.id] ([round(R.volume, 0.1)]u)"
//Using IDs because SOME chemicals (I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
return english_list(data)
//two helper functions to preserve data across reactions (needed for xenoarch)
/datum/reagents/proc/get_data(reagent_id)
for(var/datum/reagent/D in reagent_list)
@@ -744,6 +754,11 @@ var/const/INGEST = 2
break
return result
/datum/reagents/proc/holder_full()
if(total_volume >= maximum_volume)
return TRUE
return FALSE
/datum/reagents/Destroy()
. = ..()
processing_objects -= src
@@ -30,7 +30,6 @@
if(BL.data && BL.data["viruses"])
var/list/viruses = BL.data["viruses"]
return viruses[index]
return null
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
if(beaker && beaker.reagents)
@@ -40,13 +39,11 @@
if(BL.data && BL.data["resistances"])
var/list/resistances = BL.data["resistances"]
return resistances[index]
return null
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
var/datum/disease/D = GetVirusByIndex(index)
if(D)
return D.GetDiseaseID()
return null
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
wait = 1
@@ -175,7 +172,6 @@
return
add_fingerprint(usr)
return
//Prints a nice virus release form. Props to Urbanliner for the layout
/obj/machinery/computer/pandemic/proc/print_form(var/datum/disease/advance/D, mob/living/user)
@@ -319,12 +315,12 @@
popup.set_content(dat)
popup.open(0)
onclose(user, "pandemic")
return
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers) && (I.flags & OPENCONTAINER))
if(stat & (NOPOWER|BROKEN)) return
if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER))
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
to_chat(user, "<span class='warning'>A beaker is already loaded into the machine!</span>")
return
@@ -112,7 +112,7 @@
if(default_unfasten_wrench(user, I))
return
if (istype(I, /obj/item/reagent_containers) && (I.flags & OPENCONTAINER) )
if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) )
if (!beaker)
if(!user.drop_item())
return 1
@@ -238,12 +238,4 @@ About the Tools:
It simply tells us how much to transfer when
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks atom/var/flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
transfer code since you will not be able to use the standard
tools to manipulate it.
*/
@@ -61,14 +61,6 @@
/obj/item/reagent_containers/afterattack(obj/target, mob/user , flag)
return
/obj/item/reagent_containers/proc/reagentlist() //Return reagents in a reagent_container, default to source
var/data
if(reagents && reagents.reagent_list && reagents.reagent_list.len) //find a reagent list if there is and check if it has entries
for(var/datum/reagent/R in reagents.reagent_list) //no reagents will be left behind
data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
return data
else return "No reagents"
/obj/item/reagent_containers/wash(mob/user, atom/source)
if(is_open_container())
if(reagents.total_volume >= volume)
@@ -9,7 +9,7 @@
item_state = "atoxinbottle"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25,30)
flags = OPENCONTAINER
container_type = OPENCONTAINER
volume = 30
/obj/item/reagent_containers/glass/bottle/on_reagent_change()
@@ -11,7 +11,7 @@
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25,30,50)
volume = 50
flags = OPENCONTAINER
container_type = OPENCONTAINER
var/label_text = ""
// the fucking asshole who designed this can go die in a fire - Iamgoofball
@@ -59,10 +59,10 @@
..()
if(is_open_container())
to_chat(usr, "<span class='notice'>You put the lid on [src].</span>")
flags ^= OPENCONTAINER
container_type ^= REFILLABLE | DRAINABLE
else
to_chat(usr, "<span class='notice'>You take the lid off [src].</span>")
flags |= OPENCONTAINER
container_type |= REFILLABLE | DRAINABLE
update_icon()
/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
@@ -262,7 +262,7 @@
volume = 100
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25,30,50,100)
flags = OPENCONTAINER
container_type = OPENCONTAINER
/obj/item/reagent_containers/glass/beaker/vial
name = "vial"
@@ -272,7 +272,7 @@
volume = 25
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25)
flags = OPENCONTAINER
container_type = OPENCONTAINER
can_assembly = 0
/obj/item/reagent_containers/glass/beaker/drugs
@@ -282,7 +282,7 @@
amount_per_transfer_from_this = 2
possible_transfer_amounts = 2
volume = 10
flags = OPENCONTAINER
container_type = OPENCONTAINER
can_assembly = 0
/obj/item/reagent_containers/glass/beaker/noreact
@@ -293,7 +293,7 @@
volume = 50
amount_per_transfer_from_this = 10
origin_tech = "materials=2;engineering=3;plasmatech=3"
flags = OPENCONTAINER
container_type = OPENCONTAINER
/obj/item/reagent_containers/glass/beaker/noreact/New()
..()
@@ -307,7 +307,7 @@
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,25,30,50,100,300)
flags = OPENCONTAINER
container_type = OPENCONTAINER
origin_tech = "bluespace=5;materials=4;plasmatech=4"
/obj/item/reagent_containers/glass/beaker/cryoxadone
@@ -337,7 +337,7 @@
volume = 120
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
slot_flags = SLOT_HEAD
flags = OPENCONTAINER
container_type = OPENCONTAINER
/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
..()
@@ -11,7 +11,7 @@
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list(1,2,3,4,5,10,15,20,25,30)
flags = OPENCONTAINER
container_type = OPENCONTAINER
slot_flags = SLOT_BELT
var/ignore_flags = FALSE
var/emagged = FALSE
@@ -4,7 +4,8 @@
icon = 'icons/obj/janitor.dmi'
icon_state = "cleaner"
item_state = "cleaner"
flags = OPENCONTAINER | NOBLUDGEON
flags = NOBLUDGEON
container_type = OPENCONTAINER
slot_flags = SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
@@ -16,6 +16,7 @@
volume = 15
w_class = WEIGHT_CLASS_TINY
sharp = 1
container_type = TRANSPARENT
var/busy = 0
var/mode = SYRINGE_DRAW
var/projectile_type = /obj/item/projectile/bullet/dart/syringe
@@ -78,7 +79,7 @@
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
if(reagents.holder_full())
to_chat(user, "<span class='notice'>The syringe is full.</span>")
return
@@ -91,7 +92,7 @@
if(!do_mob(user, target))
busy = 0
return
if(reagents.total_volume >= reagents.maximum_volume)
if(reagents.holder_full())
return
busy = 0
if(L.transfer_blood_to(src, drawn_amount))
@@ -104,14 +105,14 @@
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers) && !istype(target,/obj/item/slime_extract))
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the solution.</span>")
if(reagents.total_volume >= reagents.maximum_volume)
if(reagents.holder_full())
mode=!mode
update_icon()
@@ -120,7 +121,7 @@
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/reagent_containers/food) && !istype(target, /obj/item/slime_extract) && !istype(target, /obj/item/clothing/mask/cigarette) && !istype(target, /obj/item/storage/fancy/cigarettes))
if(!L && !target.is_injectable())
to_chat(user, "<span class='warning'>You cannot directly fill [target]!</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
+5 -11
View File
@@ -6,28 +6,22 @@
density = 1
anchored = 0
pressure_resistance = 2*ONE_ATMOSPHERE
container_type = DRAINABLE | AMOUNT_VISIBLE
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = "water" //The ID of the reagent that the dispenser uses
var/lastrigger = "" // The last person to rig this fuel tank - Stored with the object. Only the last person matter for investigation
/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params)
return
/obj/structure/reagent_dispensers/attackby(obj/item/I, mob/user, params)
. = ..()
if(I.is_refillable())
return FALSE //so we can refill them via their afterattack.
/obj/structure/reagent_dispensers/New()
create_reagents(tank_volume)
reagents.add_reagent(reagent_id, tank_volume)
..()
/obj/structure/reagent_dispensers/examine(mob/user)
if(!..(user, 2))
return
if(reagents.total_volume)
to_chat(user, "<span class='notice'>It has [reagents.total_volume] units left.</span>")
else
to_chat(user, "<span class='danger'>It's empty.</span>")
/obj/structure/reagent_dispensers/proc/boom()
visible_message("<span class='danger'>[src] ruptures!</span>")
chem_splash(loc, 5, list(reagents))
+1 -1
View File
@@ -8,7 +8,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
name = "Circuit Imprinter"
desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
flags = OPENCONTAINER
container_type = OPENCONTAINER
var/efficiency_coeff
+1 -1
View File
@@ -11,7 +11,7 @@ Note: Must be placed west/left of and R&D console to function.
name = "Protolathe"
desc = "Converts raw materials into useful objects."
icon_state = "protolathe"
flags = OPENCONTAINER
container_type = OPENCONTAINER
var/efficiency_coeff
@@ -8,6 +8,7 @@
icon_state = "grey slime extract"
force = 1
w_class = WEIGHT_CLASS_TINY
container_type = INJECTABLE | DRAWABLE
throwforce = 0
throw_speed = 3
throw_range = 6