diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 553c9d720..41a9ec53b 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -106,6 +106,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("button frame", /obj/item/wallframe/button, 1), \
null, \
new/datum/stack_recipe("iron door", /obj/structure/mineral_door/iron, 20, one_per_turf = TRUE, on_floor = TRUE), \
+ new/datum/stack_recipe("pestle", /obj/item/pestle, 1, time = 50), \
new/datum/stack_recipe("floodlight frame", /obj/structure/floodlight_frame, 5, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("micro powered fan assembly", /obj/machinery/fan_assembly, 10, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
))
@@ -243,6 +244,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\
null, \
new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 10),\
+ new/datum/stack_recipe("mortar", /obj/item/reagent_containers/glass/mortar, 3), \
new/datum/stack_recipe("painting frame", /obj/item/wallframe/painting, 1, time = 10),\
new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\
new/datum/stack_recipe("cross", /obj/structure/kitchenspike/cross, 10, time = 10),\
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index cb38d8855..0a577dc44 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -1,371 +1,432 @@
-/obj/item/reagent_containers/glass
- name = "glass"
- amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
- volume = 50
- reagent_flags = OPENCONTAINER
- spillable = TRUE
- resistance_flags = ACID_PROOF
- container_HP = 2
-
-
-/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
- if(!canconsume(M, user))
- return
-
- if(!spillable)
- return
-
- if(!reagents || !reagents.total_volume)
- to_chat(user, "[src] is empty!")
- return
-
- if(istype(M))
- if(user.a_intent == INTENT_HARM)
- M.visible_message("[user] splashes the contents of [src] onto [M]!", \
- "[user] splashes the contents of [src] onto [M]!")
- var/R = reagents?.log_list()
- if(isturf(target) && reagents.reagent_list.len && thrownby)
- log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
- message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
- reagents.reaction(M, TOUCH)
- log_combat(user, M, "splashed", R)
- reagents.clear_reagents()
- else
- if(M != user)
- M.visible_message("[user] attempts to feed something to [M].", \
- "[user] attempts to feed something to you.")
- if(!do_mob(user, M))
- return
- if(!reagents || !reagents.total_volume)
- return // The drink might be empty after the delay, such as by spam-feeding
- M.visible_message("[user] feeds something to [M].", "[user] feeds something to you.")
- log_combat(user, M, "fed", reagents.log_list())
- else
- to_chat(user, "You swallow a gulp of [src].")
- var/fraction = min(5/reagents.total_volume, 1)
- reagents.reaction(M, INGEST, fraction)
- addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
- playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
-
-/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
- . = ..()
- if((!proximity) || !check_allowed_items(target,target_self=1))
- return
-
- if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
- if(!reagents.total_volume)
- to_chat(user, "[src] is empty!")
- return
-
- if(target.reagents.holder_full())
- to_chat(user, "[target] is full.")
- return
-
- var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
- to_chat(user, "You transfer [trans] unit\s of the solution to [target].")
-
- else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
- if(!target.reagents.total_volume)
- to_chat(user, "[target] is empty and can't be refilled!")
- return
-
- if(reagents.holder_full())
- to_chat(user, "[src] is full.")
- return
-
- var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
- to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].")
-
- else if(reagents.total_volume)
- if(user.a_intent == INTENT_HARM)
- user.visible_message("[user] splashes the contents of [src] onto [target]!", \
- "You splash the contents of [src] onto [target].")
- reagents.reaction(target, TOUCH)
- reagents.clear_reagents()
-
-/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
- var/hotness = I.is_hot()
- if(hotness && reagents)
- reagents.expose_temperature(hotness)
- to_chat(user, "You heat [name] with [I]!")
-
- if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
- var/obj/item/reagent_containers/food/snacks/egg/E = I
- if(reagents)
- if(reagents.total_volume >= reagents.maximum_volume)
- to_chat(user, "[src] is full.")
- else
- to_chat(user, "You break [E] in [src].")
- E.reagents.trans_to(src, E.reagents.total_volume)
- qdel(E)
- return
- ..()
-
-
-/obj/item/reagent_containers/glass/beaker
- name = "beaker"
- desc = "A beaker. It can hold up to 50 units. Unable to withstand extreme pHes"
- icon = 'icons/obj/chemical.dmi'
- icon_state = "beaker"
- item_state = "beaker"
- materials = list(MAT_GLASS=500)
- beaker_weakness_bitflag = PH_WEAK
-
-/obj/item/reagent_containers/glass/beaker/Initialize()
- . = ..()
- update_icon()
-
-/obj/item/reagent_containers/glass/beaker/get_part_rating()
- return reagents.maximum_volume
-
-/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
- update_icon()
-
-/obj/item/reagent_containers/glass/beaker/update_icon()
- if(!cached_icon)
- cached_icon = icon_state
- cut_overlays()
-
- if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
-
- var/percent = round((reagents.total_volume / volume) * 100)
- switch(percent)
- if(0 to 9)
- filling.icon_state = "[cached_icon]-10"
- if(10 to 24)
- filling.icon_state = "[cached_icon]10"
- if(25 to 49)
- filling.icon_state = "[cached_icon]25"
- if(50 to 74)
- filling.icon_state = "[cached_icon]50"
- if(75 to 79)
- filling.icon_state = "[cached_icon]75"
- if(80 to 90)
- filling.icon_state = "[cached_icon]80"
- if(91 to INFINITY)
- filling.icon_state = "[cached_icon]100"
-
- filling.color = mix_color_from_reagents(reagents.reagent_list)
- add_overlay(filling)
-
-/obj/item/reagent_containers/glass/beaker/jar
- name = "honey jar"
- desc = "A jar for honey. It can hold up to 50 units of sweet delight. Unable to withstand reagents of an extreme pH."
- icon = 'icons/obj/chemical.dmi'
- icon_state = "vapour"
-
-/obj/item/reagent_containers/glass/beaker/large
- name = "large beaker"
- desc = "A large beaker. Can hold up to 100 units. Unable to withstand reagents of an extreme pH."
- icon_state = "beakerlarge"
- materials = list(MAT_GLASS=2500)
- volume = 100
- amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
- container_HP = 3
-
-/obj/item/reagent_containers/glass/beaker/plastic
- name = "x-large beaker"
- desc = "An extra-large beaker. Can hold up to 150 units. Is able to resist acid and alkaline solutions, but melts at 444K"
- icon_state = "beakerwhite"
- materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
- volume = 150
- amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(5,10,15,20,25,30,50,100,150)
-
-/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
- beaker_weakness_bitflag &= ~PH_WEAK
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
-
-/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
- icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
- ..()
- icon_state = "beakerwhite"
-
-/obj/item/reagent_containers/glass/beaker/meta
- name = "metamaterial beaker"
- desc = "A large beaker. Can hold up to 200 units. Is able to withstand all chemical situations."
- icon_state = "beakergold"
- materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
- volume = 200
- amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(5,10,15,20,25,30,50,100,200)
-
-/obj/item/reagent_containers/glass/beaker/meta/Initialize()
- beaker_weakness_bitflag &= ~PH_WEAK
- . = ..()
-
-/obj/item/reagent_containers/glass/beaker/noreact
- name = "cryostasis beaker"
- desc = "A cryostasis beaker that allows for chemical storage without \
- reactions. Can hold up to 50 units."
- icon_state = "beakernoreact"
- materials = list(MAT_METAL=3000)
- reagent_flags = OPENCONTAINER | NO_REACT
- volume = 50
- amount_per_transfer_from_this = 10
- container_HP = 10//shouldn't be needed
-
-/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
- beaker_weakness_bitflag &= ~PH_WEAK
- . = ..()
- //reagents.set_reacting(FALSE) was this removed in a recent pr?
-
-/obj/item/reagent_containers/glass/beaker/bluespace
- name = "bluespace beaker"
- desc = "A bluespace beaker, powered by experimental bluespace technology \
- and Element Cuban combined with the Compound Pete. Can hold up to \
- 300 units. Unable to withstand reagents of an extreme pH."
- icon_state = "beakerbluespace"
- materials = list(MAT_GLASS=3000)
- volume = 300
- amount_per_transfer_from_this = 10
- possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
- container_HP = 4
-
-/obj/item/reagent_containers/glass/beaker/cryoxadone
- list_reagents = list(/datum/reagent/medicine/cryoxadone = 30)
-
-/obj/item/reagent_containers/glass/beaker/sulphuric
- list_reagents = list(/datum/reagent/toxin/acid = 50)
-
-/obj/item/reagent_containers/glass/beaker/slime
- list_reagents = list(/datum/reagent/toxin/slimejelly = 50)
-
-/obj/item/reagent_containers/glass/beaker/large/styptic
- name = "styptic reserve tank"
- list_reagents = list(/datum/reagent/medicine/styptic_powder = 50)
-
-/obj/item/reagent_containers/glass/beaker/large/silver_sulfadiazine
- name = "silver sulfadiazine reserve tank"
- list_reagents = list(/datum/reagent/medicine/silver_sulfadiazine = 50)
-
-/obj/item/reagent_containers/glass/beaker/large/charcoal
- name = "charcoal reserve tank"
- list_reagents = list(/datum/reagent/medicine/charcoal = 50)
-
-/obj/item/reagent_containers/glass/beaker/large/epinephrine
- name = "epinephrine reserve tank"
- list_reagents = list(/datum/reagent/medicine/epinephrine = 50)
-
-/obj/item/reagent_containers/glass/beaker/synthflesh
- list_reagents = list(/datum/reagent/medicine/synthflesh = 50)
-
-/obj/item/reagent_containers/glass/bucket
- name = "bucket"
- desc = "It's a bucket."
- icon = 'icons/obj/janitor.dmi'
- icon_state = "bucket"
- item_state = "bucket"
- lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
- materials = list(MAT_METAL=200)
- w_class = WEIGHT_CLASS_NORMAL
- amount_per_transfer_from_this = 20
- possible_transfer_amounts = list(5,10,15,20,25,30,50,70)
- volume = 70
- flags_inv = HIDEHAIR
- slot_flags = ITEM_SLOT_HEAD
- resistance_flags = NONE
- armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head
- slot_equipment_priority = list( \
- SLOT_BACK, SLOT_WEAR_ID,\
- SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\
- SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\
- SLOT_SHOES, SLOT_GLOVES,\
- SLOT_EARS, SLOT_GLASSES,\
- SLOT_BELT, SLOT_S_STORE,\
- SLOT_L_STORE, SLOT_R_STORE,\
- SLOT_GENERC_DEXTROUS_STORAGE
- )
- container_HP = 1
-
-/obj/item/reagent_containers/glass/bucket/Initialize()
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
-
-/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
- if(istype(O, /obj/item/mop))
- if(reagents.total_volume < 1)
- to_chat(user, "[src] is out of water!")
- else
- reagents.trans_to(O, 5)
- to_chat(user, "You wet [O] in [src].")
- playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
- else if(isprox(O))
- to_chat(user, "You add [O] to [src].")
- qdel(O)
- qdel(src)
- user.put_in_hands(new /obj/item/bot_assembly/cleanbot)
- else
- ..()
-
-/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
- ..()
- if (slot == SLOT_HEAD)
- if(reagents.total_volume)
- to_chat(user, "[src]'s contents spill all over you!")
- reagents.reaction(user, TOUCH)
- reagents.clear_reagents()
- reagent_flags = NONE
-
-/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
- . = ..()
- reagent_flags = initial(reagent_flags)
-
-/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
- if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
- var/index = slot_equipment_priority.Find(SLOT_HEAD)
- slot_equipment_priority.Remove(SLOT_HEAD)
- . = ..()
- slot_equipment_priority.Insert(index, SLOT_HEAD)
- return
- return ..()
-
-/obj/item/reagent_containers/glass/beaker/waterbottle
- name = "bottle of water"
- desc = "A bottle of water filled at some factory in space."
- icon = 'icons/obj/drinks.dmi'
- icon_state = "smallbottle"
- item_state = "bottle"
- list_reagents = list(/datum/reagent/water = 50)//see desc, don't think about it too hard
- materials = list(MAT_GLASS=0)
- volume = 50
- amount_per_transfer_from_this = 10
- container_HP = 1
- price = 1
-
-/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
- beaker_weakness_bitflag |= TEMP_WEAK
- . = ..()
-
-/obj/item/reagent_containers/glass/beaker/waterbottle/empty
- list_reagents = list()
-
-/obj/item/reagent_containers/glass/beaker/waterbottle/large
- desc = "A fresh commercial-sized bottle of water."
- icon_state = "largebottle"
- materials = list(MAT_GLASS=0)
- list_reagents = list(/datum/reagent/water = 100)
- volume = 100
- amount_per_transfer_from_this = 20
- container_HP = 1
-
-/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
- list_reagents = list()
-
-/obj/item/reagent_containers/glass/beaker/waterbottle/wataur
- name = "Bottled Wataur"
- desc = "Finally, a bottle as proportionate as you. Incredible!"
- icon = 'icons/obj/drinks.dmi'
- icon_state = "wataur"
- list_reagents = list(/datum/reagent/water = 100) //robust ass wataur
- volume = 100
- amount_per_transfer_from_this = 20
- container_HP = 1
-
-/obj/item/reagent_containers/glass/get_belt_overlay()
- return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "bottle")
+/obj/item/reagent_containers/glass
+ name = "glass"
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
+ volume = 50
+ reagent_flags = OPENCONTAINER
+ spillable = TRUE
+ resistance_flags = ACID_PROOF
+ container_HP = 2
+
+
+/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
+ if(!canconsume(M, user))
+ return
+
+ if(!spillable)
+ return
+
+ if(!reagents || !reagents.total_volume)
+ to_chat(user, "[src] is empty!")
+ return
+
+ if(istype(M))
+ if(user.a_intent == INTENT_HARM)
+ M.visible_message("[user] splashes the contents of [src] onto [M]!", \
+ "[user] splashes the contents of [src] onto [M]!")
+ var/R = reagents?.log_list()
+ if(isturf(target) && reagents.reagent_list.len && thrownby)
+ log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
+ message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
+ reagents.reaction(M, TOUCH)
+ log_combat(user, M, "splashed", R)
+ reagents.clear_reagents()
+ else
+ if(M != user)
+ M.visible_message("[user] attempts to feed something to [M].", \
+ "[user] attempts to feed something to you.")
+ if(!do_mob(user, M))
+ return
+ if(!reagents || !reagents.total_volume)
+ return // The drink might be empty after the delay, such as by spam-feeding
+ M.visible_message("[user] feeds something to [M].", "[user] feeds something to you.")
+ log_combat(user, M, "fed", reagents.log_list())
+ else
+ to_chat(user, "You swallow a gulp of [src].")
+ var/fraction = min(5/reagents.total_volume, 1)
+ reagents.reaction(M, INGEST, fraction)
+ addtimer(CALLBACK(reagents, /datum/reagents.proc/trans_to, M, 5), 5)
+ playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
+
+/obj/item/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
+ . = ..()
+ if((!proximity) || !check_allowed_items(target,target_self=1))
+ return
+
+ if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
+ if(!reagents.total_volume)
+ to_chat(user, "[src] is empty!")
+ return
+
+ if(target.reagents.holder_full())
+ to_chat(user, "[target] is full.")
+ return
+
+ var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
+ to_chat(user, "You transfer [trans] unit\s of the solution to [target].")
+
+ else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
+ if(!target.reagents.total_volume)
+ to_chat(user, "[target] is empty and can't be refilled!")
+ return
+
+ if(reagents.holder_full())
+ to_chat(user, "[src] is full.")
+ return
+
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
+ to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].")
+
+ else if(reagents.total_volume)
+ if(user.a_intent == INTENT_HARM)
+ user.visible_message("[user] splashes the contents of [src] onto [target]!", \
+ "You splash the contents of [src] onto [target].")
+ reagents.reaction(target, TOUCH)
+ reagents.clear_reagents()
+
+/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
+ var/hotness = I.is_hot()
+ if(hotness && reagents)
+ reagents.expose_temperature(hotness)
+ to_chat(user, "You heat [name] with [I]!")
+
+ if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs
+ var/obj/item/reagent_containers/food/snacks/egg/E = I
+ if(reagents)
+ if(reagents.total_volume >= reagents.maximum_volume)
+ to_chat(user, "[src] is full.")
+ else
+ to_chat(user, "You break [E] in [src].")
+ E.reagents.trans_to(src, E.reagents.total_volume)
+ qdel(E)
+ return
+ ..()
+
+
+/obj/item/reagent_containers/glass/beaker
+ name = "beaker"
+ desc = "A beaker. It can hold up to 50 units. Unable to withstand extreme pHes"
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "beaker"
+ item_state = "beaker"
+ materials = list(MAT_GLASS=500)
+ beaker_weakness_bitflag = PH_WEAK
+
+/obj/item/reagent_containers/glass/beaker/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/reagent_containers/glass/beaker/get_part_rating()
+ return reagents.maximum_volume
+
+/obj/item/reagent_containers/glass/beaker/on_reagent_change(changetype)
+ update_icon()
+
+/obj/item/reagent_containers/glass/beaker/update_icon()
+ if(!cached_icon)
+ cached_icon = icon_state
+ cut_overlays()
+
+ if(reagents.total_volume)
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "[cached_icon]10")
+
+ var/percent = round((reagents.total_volume / volume) * 100)
+ switch(percent)
+ if(0 to 9)
+ filling.icon_state = "[cached_icon]-10"
+ if(10 to 24)
+ filling.icon_state = "[cached_icon]10"
+ if(25 to 49)
+ filling.icon_state = "[cached_icon]25"
+ if(50 to 74)
+ filling.icon_state = "[cached_icon]50"
+ if(75 to 79)
+ filling.icon_state = "[cached_icon]75"
+ if(80 to 90)
+ filling.icon_state = "[cached_icon]80"
+ if(91 to INFINITY)
+ filling.icon_state = "[cached_icon]100"
+
+ filling.color = mix_color_from_reagents(reagents.reagent_list)
+ add_overlay(filling)
+
+/obj/item/reagent_containers/glass/beaker/jar
+ name = "honey jar"
+ desc = "A jar for honey. It can hold up to 50 units of sweet delight. Unable to withstand reagents of an extreme pH."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "vapour"
+
+/obj/item/reagent_containers/glass/beaker/large
+ name = "large beaker"
+ desc = "A large beaker. Can hold up to 100 units. Unable to withstand reagents of an extreme pH."
+ icon_state = "beakerlarge"
+ materials = list(MAT_GLASS=2500)
+ volume = 100
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
+ container_HP = 3
+
+/obj/item/reagent_containers/glass/beaker/plastic
+ name = "x-large beaker"
+ desc = "An extra-large beaker. Can hold up to 150 units. Is able to resist acid and alkaline solutions, but melts at 444K"
+ icon_state = "beakerwhite"
+ materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
+ volume = 150
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5,10,15,20,25,30,50,100,150)
+
+/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
+ beaker_weakness_bitflag &= ~PH_WEAK
+ beaker_weakness_bitflag |= TEMP_WEAK
+ . = ..()
+
+/obj/item/reagent_containers/glass/beaker/plastic/update_icon()
+ icon_state = "beakerlarge" // hack to lets us reuse the large beaker reagent fill states
+ ..()
+ icon_state = "beakerwhite"
+
+/obj/item/reagent_containers/glass/beaker/meta
+ name = "metamaterial beaker"
+ desc = "A large beaker. Can hold up to 200 units. Is able to withstand all chemical situations."
+ icon_state = "beakergold"
+ materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
+ volume = 200
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5,10,15,20,25,30,50,100,200)
+
+/obj/item/reagent_containers/glass/beaker/meta/Initialize()
+ beaker_weakness_bitflag &= ~PH_WEAK
+ . = ..()
+
+/obj/item/reagent_containers/glass/beaker/noreact
+ name = "cryostasis beaker"
+ desc = "A cryostasis beaker that allows for chemical storage without \
+ reactions. Can hold up to 50 units."
+ icon_state = "beakernoreact"
+ materials = list(MAT_METAL=3000)
+ reagent_flags = OPENCONTAINER | NO_REACT
+ volume = 50
+ amount_per_transfer_from_this = 10
+ container_HP = 10//shouldn't be needed
+
+/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
+ beaker_weakness_bitflag &= ~PH_WEAK
+ . = ..()
+ //reagents.set_reacting(FALSE) was this removed in a recent pr?
+
+/obj/item/reagent_containers/glass/beaker/bluespace
+ name = "bluespace beaker"
+ desc = "A bluespace beaker, powered by experimental bluespace technology \
+ and Element Cuban combined with the Compound Pete. Can hold up to \
+ 300 units. Unable to withstand reagents of an extreme pH."
+ icon_state = "beakerbluespace"
+ materials = list(MAT_GLASS=3000)
+ volume = 300
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
+ container_HP = 4
+
+/obj/item/reagent_containers/glass/beaker/cryoxadone
+ list_reagents = list(/datum/reagent/medicine/cryoxadone = 30)
+
+/obj/item/reagent_containers/glass/beaker/sulphuric
+ list_reagents = list(/datum/reagent/toxin/acid = 50)
+
+/obj/item/reagent_containers/glass/beaker/slime
+ list_reagents = list(/datum/reagent/toxin/slimejelly = 50)
+
+/obj/item/reagent_containers/glass/beaker/large/styptic
+ name = "styptic reserve tank"
+ list_reagents = list(/datum/reagent/medicine/styptic_powder = 50)
+
+/obj/item/reagent_containers/glass/beaker/large/silver_sulfadiazine
+ name = "silver sulfadiazine reserve tank"
+ list_reagents = list(/datum/reagent/medicine/silver_sulfadiazine = 50)
+
+/obj/item/reagent_containers/glass/beaker/large/charcoal
+ name = "charcoal reserve tank"
+ list_reagents = list(/datum/reagent/medicine/charcoal = 50)
+
+/obj/item/reagent_containers/glass/beaker/large/epinephrine
+ name = "epinephrine reserve tank"
+ list_reagents = list(/datum/reagent/medicine/epinephrine = 50)
+
+/obj/item/reagent_containers/glass/beaker/synthflesh
+ list_reagents = list(/datum/reagent/medicine/synthflesh = 50)
+
+/obj/item/reagent_containers/glass/bucket
+ name = "bucket"
+ desc = "It's a bucket."
+ icon = 'icons/obj/janitor.dmi'
+ icon_state = "bucket"
+ item_state = "bucket"
+ lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
+ materials = list(MAT_METAL=200)
+ w_class = WEIGHT_CLASS_NORMAL
+ amount_per_transfer_from_this = 20
+ possible_transfer_amounts = list(5,10,15,20,25,30,50,70)
+ volume = 70
+ flags_inv = HIDEHAIR
+ slot_flags = ITEM_SLOT_HEAD
+ resistance_flags = NONE
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head
+ slot_equipment_priority = list( \
+ SLOT_BACK, SLOT_WEAR_ID,\
+ SLOT_W_UNIFORM, SLOT_WEAR_SUIT,\
+ SLOT_WEAR_MASK, SLOT_HEAD, SLOT_NECK,\
+ SLOT_SHOES, SLOT_GLOVES,\
+ SLOT_EARS, SLOT_GLASSES,\
+ SLOT_BELT, SLOT_S_STORE,\
+ SLOT_L_STORE, SLOT_R_STORE,\
+ SLOT_GENERC_DEXTROUS_STORAGE
+ )
+ container_HP = 1
+
+/obj/item/reagent_containers/glass/bucket/Initialize()
+ beaker_weakness_bitflag |= TEMP_WEAK
+ . = ..()
+
+/obj/item/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
+ if(istype(O, /obj/item/mop))
+ if(reagents.total_volume < 1)
+ to_chat(user, "[src] is out of water!")
+ else
+ reagents.trans_to(O, 5)
+ to_chat(user, "You wet [O] in [src].")
+ playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
+ else if(isprox(O))
+ to_chat(user, "You add [O] to [src].")
+ qdel(O)
+ qdel(src)
+ user.put_in_hands(new /obj/item/bot_assembly/cleanbot)
+ else
+ ..()
+
+/obj/item/reagent_containers/glass/bucket/equipped(mob/user, slot)
+ ..()
+ if (slot == SLOT_HEAD)
+ if(reagents.total_volume)
+ to_chat(user, "[src]'s contents spill all over you!")
+ reagents.reaction(user, TOUCH)
+ reagents.clear_reagents()
+ reagent_flags = NONE
+
+/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
+ . = ..()
+ reagent_flags = initial(reagent_flags)
+
+/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
+ if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
+ var/index = slot_equipment_priority.Find(SLOT_HEAD)
+ slot_equipment_priority.Remove(SLOT_HEAD)
+ . = ..()
+ slot_equipment_priority.Insert(index, SLOT_HEAD)
+ return
+ return ..()
+
+/obj/item/reagent_containers/glass/beaker/waterbottle
+ name = "bottle of water"
+ desc = "A bottle of water filled at some factory in space."
+ icon = 'icons/obj/drinks.dmi'
+ icon_state = "smallbottle"
+ item_state = "bottle"
+ list_reagents = list(/datum/reagent/water = 50)//see desc, don't think about it too hard
+ materials = list(MAT_GLASS=0)
+ volume = 50
+ amount_per_transfer_from_this = 10
+ container_HP = 1
+ price = 1
+
+/obj/item/reagent_containers/glass/beaker/waterbottle/Initialize()
+ beaker_weakness_bitflag |= TEMP_WEAK
+ . = ..()
+
+/obj/item/reagent_containers/glass/beaker/waterbottle/empty
+ list_reagents = list()
+
+/obj/item/reagent_containers/glass/beaker/waterbottle/large
+ desc = "A fresh commercial-sized bottle of water."
+ icon_state = "largebottle"
+ materials = list(MAT_GLASS=0)
+ list_reagents = list(/datum/reagent/water = 100)
+ volume = 100
+ amount_per_transfer_from_this = 20
+ container_HP = 1
+
+/obj/item/reagent_containers/glass/beaker/waterbottle/large/empty
+ list_reagents = list()
+
+/obj/item/reagent_containers/glass/beaker/waterbottle/wataur
+ name = "Bottled Wataur"
+ desc = "Finally, a bottle as proportionate as you. Incredible!"
+ icon = 'icons/obj/drinks.dmi'
+ icon_state = "wataur"
+ list_reagents = list(/datum/reagent/water = 100) //robust ass wataur
+ volume = 100
+ amount_per_transfer_from_this = 20
+ container_HP = 1
+
+/obj/item/reagent_containers/glass/get_belt_overlay()
+ return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "bottle")
+
+//Mortar & Pestle
+
+/obj/item/pestle
+ name = "pestle"
+ desc = "An ancient, simple tool used in conjunction with a mortar to grind or juice items."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "pestle"
+ force = 4
+
+/obj/item/reagent_containers/glass/mortar
+ name = "mortar"
+ desc = "A specially formed bowl of ancient design. It is possible to crush or juice items placed in it using a pestle; however the process, unlike modern methods, is slow and physically exhausting. Alt click to eject the item."
+ icon_state = "mortar"
+ amount_per_transfer_from_this = 10
+ possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
+ item_flags = NO_MAT_REDEMPTION
+ reagent_flags = OPENCONTAINER
+ spillable = TRUE
+ var/obj/item/grinded
+
+/obj/item/reagent_containers/glass/mortar/AltClick(mob/user)
+ . = ..()
+ if(grinded)
+ grinded.forceMove(drop_location())
+ grinded = null
+ to_chat(user, "You eject the item inside.")
+ return TRUE
+
+/obj/item/reagent_containers/glass/mortar/attackby(obj/item/I, mob/living/carbon/human/user)
+ ..()
+ if(istype(I,/obj/item/pestle))
+ if(grinded)
+ to_chat(user, "You start grinding...")
+ if((do_after(user, 25, target = src)) && grinded)
+ user.adjustStaminaLoss(20)
+ if(grinded.juice_results) //prioritize juicing
+ grinded.on_juice()
+ reagents.add_reagent_list(grinded.juice_results)
+ to_chat(user, "You juice [grinded] into a fine liquid.")
+ QDEL_NULL(grinded)
+ return
+ grinded.on_grind()
+ reagents.add_reagent_list(grinded.grind_results)
+ if(grinded.reagents) //food and pills
+ grinded.reagents.trans_to(src, grinded.reagents.total_volume)
+ to_chat(user, "You break [grinded] into powder.")
+ QDEL_NULL(grinded)
+ return
+ return
+ else
+ to_chat(user, "There is nothing to grind!")
+ return
+ if(grinded)
+ to_chat(user, "There is something inside already!")
+ return
+ if(I.juice_results || I.grind_results)
+ I.forceMove(src)
+ grinded = I
+ return
+ to_chat(user, "You can't grind this!")
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index b723785e0..b753093c3 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ