diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index a54d126abb..b596e40e36 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -120,6 +120,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
)), \
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), \
))
@@ -255,6 +256,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("honey frame", /obj/item/honey_frame, 5, time = 10),\
))
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 74e99cc326..800d66969d 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -388,3 +388,67 @@
/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)
+ if(IS_STAMCRIT(user))
+ to_chat(user, "You are too tired to work!")
+ return
+ 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 b13e06e824..76094938e8 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ