diff --git a/_maps/map_files/generic/centcomm.dmm b/_maps/map_files/generic/centcomm.dmm
index 2da9e445d72..975bb1dc2d1 100644
--- a/_maps/map_files/generic/centcomm.dmm
+++ b/_maps/map_files/generic/centcomm.dmm
@@ -10424,6 +10424,11 @@
/obj/item/flag/cargo,
/turf/simulated/floor/plasteel/dark,
/area/centcom/control)
+"Oo" = (
+/obj/structure/bookcase/random,
+/obj/item/book/granter/spell/summon_cheese,
+/turf/simulated/floor/carpet/red,
+/area/wizard_station)
"Op" = (
/obj/effect/landmark/spawner/tdomeobserve,
/turf/simulated/floor/plasteel{
@@ -61255,7 +61260,7 @@ zv
xH
xH
ZH
-ZU
+Oo
ZU
xH
xH
diff --git a/code/game/objects/items/granters/_granters.dm b/code/game/objects/items/granters/_granters.dm
index 01e40c8070e..cd1c4fa196c 100644
--- a/code/game/objects/items/granters/_granters.dm
+++ b/code/game/objects/items/granters/_granters.dm
@@ -104,3 +104,16 @@
// Action goes on the mind as the user actually learns the thing in your brain
var/datum/action/new_action = new granted_action(user.mind || user)
new_action.Grant(user)
+
+// Generic action giver
+/obj/item/book/granter/spell
+ /// The typepath of spell that is given
+ var/obj/effect/proc_holder/spell/granted_spell
+ /// The name of the spell, formatted in a more text-friendly way
+ var/spell_name = ""
+
+/obj/item/book/granter/spell/on_reading_finished(mob/living/user)
+ if(!user.mind)
+ return
+ to_chat(user, "You feel like you've got a good handle on [spell_name]!")
+ user.mind.AddSpell(new granted_spell(null))
diff --git a/code/game/objects/items/granters/action_granters/summon_cheese.dm b/code/game/objects/items/granters/action_granters/summon_cheese.dm
new file mode 100644
index 00000000000..b4e4d0a01b0
--- /dev/null
+++ b/code/game/objects/items/granters/action_granters/summon_cheese.dm
@@ -0,0 +1,41 @@
+/obj/item/book/granter/spell/summon_cheese
+ name = "Lusty Xenomorph Maid vol. III - Cheese Bakery"
+ desc = "Wonderful! Time for a celebration... Cheese for everyone!"
+ icon_state = "cheese_book"
+ spell_name = "summon cheese"
+ granted_spell = /obj/effect/proc_holder/spell/aoe/conjure/summon_cheese
+ remarks = list(
+ "Always forward, never back...",
+ "Are these pages... cheese slices?..",
+ "Healthy snacks for unsuspecting victims...",
+ "I never knew so many types of cheese existed...",
+ "Madness reeks of goat cheese...",
+ "Was it order or biscuits?..",
+ "Who wouldn't like that?..",
+ "Why cheese, of all things?..",
+ "Why do I need a reason for everything?..",
+ "Cheddar days are coming...",
+ "Leicester the Red's gouda guide to getting feta at Caseiculture...",
+ "A passage from Cheesus Christ, the gouda saint...",
+ "What is the cheese tax and how do I pay it?!..."
+ )
+
+/obj/item/book/granter/spell/summon_cheese/recoil(mob/living/user)
+ to_chat(user, "[src] turns into a wedge of cheese!")
+ var/obj/item/reagent_containers/food/snacks/cheesewedge/book_cheese = new
+ user.drop_item()
+ user.put_in_hands(book_cheese)
+ qdel(src)
+
+/obj/effect/proc_holder/spell/aoe/conjure/summon_cheese
+ name = "Summon Cheese"
+ desc = "Summon cheesy goodness around you!"
+ base_cooldown = 1 MINUTES
+ clothes_req = FALSE
+ overlay = null
+ action_icon_state = "cheese_wedge"
+ action_background_icon_state = "bg_spell"
+ summon_type = list(/obj/item/reagent_containers/food/snacks/cheesewedge)
+ summon_amt = 9
+ aoe_range = 1
+ summon_ignore_prev_spawn_points = TRUE
diff --git a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm
index bbf91842852..e39220515d8 100644
--- a/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm
+++ b/code/modules/awaymissions/mission_code/ruins/wizardcrash.dm
@@ -15,11 +15,11 @@
/obj/effect/spawner/lootdrop/wizardcrash
loot = list(
- /obj/item/guardiancreator = 1, //jackpot.
- /obj/item/spellbook/oneuse/knock = 1, //tresspassing charges incoming
- /obj/item/gun/magic/wand/resurrection = 1, //medbay's best friend
- /obj/item/spellbook/oneuse/charge = 20, //and now for less useful stuff to dilute the good loot chances
+ /obj/item/guardiancreator = 1, // jackpot.
+ /obj/item/spellbook/oneuse/knock = 1, // tresspassing charges incoming
+ /obj/item/gun/magic/wand/resurrection = 1, // medbay's best friend
+ /obj/item/spellbook/oneuse/charge = 20, // and now for less useful stuff to dilute the good loot chances
/obj/item/spellbook/oneuse/summonitem = 20,
/obj/item/spellbook/oneuse/forcewall = 10,
- /obj/item/soulstone = 15 //spooky wizard stuff
+ /obj/item/book/granter/spell/summon_cheese = 20 // hungry wizard stuff
)
diff --git a/icons/mob/actions/actions.dmi b/icons/mob/actions/actions.dmi
index 43ace519395..66c82897c2a 100644
Binary files a/icons/mob/actions/actions.dmi and b/icons/mob/actions/actions.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 90499093986..2b58ca4ab35 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 11f99b4df6b..57d69ea9d39 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -989,6 +989,7 @@
#include "code\game\objects\items\devices\radio\intercom.dm"
#include "code\game\objects\items\devices\radio\radio_objects.dm"
#include "code\game\objects\items\granters\_granters.dm"
+#include "code\game\objects\items\granters\action_granters\summon_cheese.dm"
#include "code\game\objects\items\granters\crafting_granters\_crafting_granter.dm"
#include "code\game\objects\items\granters\crafting_granters\combat_baking.dm"
#include "code\game\objects\items\mountable_frames\air_alarm_frame.dm"