code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////DONUTS////////////////////////////////////////////////

/datum/table_recipe/chaosdonut
	name = "Chaos donut"
	reqs = list(
		/datum/reagent/consumable/frostoil = 5,
		/datum/reagent/consumable/capsaicin = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donut/chaos
	category = CAT_FOOD

/datum/table_recipe/donut
	time = 15
	name = "Donut"
	reqs = list(
		/datum/reagent/consumable/sugar = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donut
	category = CAT_FOOD

/datum/table_recipe/jellydonut
	name = "Jelly donut"
	reqs = list(
		/datum/reagent/consumable/berryjuice = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly
	category = CAT_FOOD

/datum/table_recipe/cherryjellydonut
	name = "Cherry jelly donut"
	reqs = list(
		/datum/reagent/consumable/cherryjelly = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/cherryjelly
	category = CAT_FOOD

/datum/table_recipe/slimejellydonut
	name = "Slime jelly donut"
	reqs = list(
		/datum/reagent/toxin/slimejelly = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donut/jelly/slimejelly
	category = CAT_FOOD

////////////////////////////////////////////////WAFFLES////////////////////////////////////////////////

/datum/table_recipe/waffles
	time = 15
	name = "Waffles"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/waffles
	category = CAT_FOOD

/datum/table_recipe/soylenviridians
	name = "Soylent viridians"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soylenviridians
	category = CAT_FOOD

/datum/table_recipe/soylentgreen
	name = "Soylent green"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 2,
		/obj/item/weapon/reagent_containers/food/snacks/meat/slab/human = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soylentgreen
	category = CAT_FOOD

/datum/table_recipe/rofflewaffles
	name = "Roffle waffles"
	reqs = list(
		/datum/reagent/mushroomhallucinogen = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/rofflewaffles
	category = CAT_FOOD

////////////////////////////////////////////////DONKPOCCKETS////////////////////////////////////////////////

/datum/table_recipe/donkpocket
	time = 15
	name = "Donkpocket"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/donkpocket
	category = CAT_FOOD

////////////////////////////////////////////////MUFFINS////////////////////////////////////////////////

/datum/table_recipe/muffin
	time = 15
	name = "Muffin"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/muffin
	category = CAT_FOOD

/datum/table_recipe/berrymuffin
	name = "Berry muffin"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/berries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/muffin/berry
	category = CAT_FOOD

/datum/table_recipe/booberrymuffin
	name = "Booberry muffin"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/berries = 1,
		/obj/item/weapon/ectoplasm = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/muffin/booberry
	category = CAT_FOOD

/datum/table_recipe/chawanmushi
	name = "Chawanmushi"
	reqs = list(
		/datum/reagent/water = 5,
		/datum/reagent/consumable/soysauce = 5,
		/obj/item/weapon/reagent_containers/food/snacks/boiledegg = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/chawanmushi
	category = CAT_FOOD

////////////////////////////////////////////OTHER////////////////////////////////////////////

/datum/table_recipe/hotdog
	name = "Hot dog"
	reqs = list(
		/datum/reagent/consumable/ketchup = 5,
		/obj/item/weapon/reagent_containers/food/snacks/bun = 1,
		/obj/item/weapon/reagent_containers/food/snacks/sausage = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/hotdog
	category = CAT_FOOD

/datum/table_recipe/meatbun
	name = "Meat bun"
	reqs = list(
		/datum/reagent/consumable/soysauce = 5,
		/obj/item/weapon/reagent_containers/food/snacks/bun = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/meatbun
	category = CAT_FOOD

/datum/table_recipe/sugarcookie
	time = 15
	name = "Sugar cookie"
	reqs = list(
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie
	category = CAT_FOOD

/datum/table_recipe/fortunecookie
	time = 15
	name = "Fortune cookie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/paper = 1
	)
	parts =	list(
		/obj/item/weapon/paper = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/fortunecookie
	category = CAT_FOOD

/datum/table_recipe/poppypretzel
	time = 15
	name = "Poppy pretzel"
	reqs = list(
		/obj/item/seeds/poppy = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/poppypretzel
	category = CAT_FOOD

/datum/table_recipe/plumphelmetbiscuit
	time = 15
	name = "Plumphelmet biscuit"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit
	category = CAT_FOOD

/datum/table_recipe/cracker
	time = 15
	name = "Cracker"
	reqs = list(
		/datum/reagent/consumable/sodiumchloride = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/cracker
	category = CAT_FOOD

/datum/table_recipe/chococornet
	name = "Choco cornet"
	reqs = list(
		/datum/reagent/consumable/sodiumchloride = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/chococornet
	category = CAT_FOOD

/datum/table_recipe/oatmealcookie
	name = "Oatmeal cookie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/oat = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/oatmealcookie

/datum/table_recipe/raisincookie
	name = "Raisin cookie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/oat = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/raisincookie
	category = CAT_FOOD

/datum/table_recipe/cherrycupcake
	name = "Cherry cupcake"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/cherrycupcake
	category = CAT_FOOD

/datum/table_recipe/bluecherrycupcake
	name = "Blue cherry cupcake"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/bluecherrycupcake
	category = CAT_FOOD

/datum/table_recipe/honeybun
	name = "Honey bun"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastrybase = 1,
		/datum/reagent/consumable/honey = 5
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/honeybun
	category = CAT_FOOD


code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////PIES////////////////////////////////////////////////

/datum/table_recipe/bananacreampie
	name = "Banana cream pie"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		 /obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/cream
	category = CAT_FOOD

/datum/table_recipe/meatpie
	name = "Meat pie"
	reqs = list(
		/datum/reagent/consumable/blackpepper = 1,
		/datum/reagent/consumable/sodiumchloride = 1,
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/steak/plain = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/meatpie
	category = CAT_FOOD

/datum/table_recipe/tofupie
	name = "Tofu pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/tofu = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/tofupie
	category = CAT_FOOD

/datum/table_recipe/xenopie
	name = "Xeno pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet/xeno = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/xemeatpie
	category = CAT_FOOD

/datum/table_recipe/cherrypie
	name = "Cherry pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		 /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/cherrypie
	category = CAT_FOOD

/datum/table_recipe/berryclafoutis
	name = "Berry clafoutis"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/berries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/berryclafoutis
	category = CAT_FOOD

/datum/table_recipe/bearypie
	name = "Beary Pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/berries = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/steak/bear = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/bearypie
	category = CAT_FOOD

/datum/table_recipe/amanitapie
	name = "Amanita pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/amanita_pie
	category = CAT_FOOD

/datum/table_recipe/plumppie
	name = "Plump pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/plump_pie
	category = CAT_FOOD

/datum/table_recipe/applepie
	name = "Apple pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/applepie
	category = CAT_FOOD

/datum/table_recipe/pumpkinpie
	name = "Pumpkin pie"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/pumpkinpie
	category = CAT_FOOD

/datum/table_recipe/goldenappletart
	name = "Golden apple tart"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/appletart
	category = CAT_FOOD

/datum/table_recipe/grapetart
	name = "Grape tart"
	reqs = list(
            /datum/reagent/consumable/milk = 5,
            /datum/reagent/consumable/sugar = 5,
            /obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
	        /obj/item/weapon/reagent_containers/food/snacks/grown/grapes = 3
	        )
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/grapetart
	category = CAT_FOOD

/datum/table_recipe/blumpkinpie
	name = "Blumpkin pie"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/blumpkinpie
	category = CAT_FOOD

/datum/table_recipe/dulcedebatata
	name = "Dulce de batata"
	reqs = list(
		/datum/reagent/consumable/vanilla = 5,
		/datum/reagent/water = 5,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/dulcedebatata
	category = CAT_FOOD

/datum/table_recipe/frostypie
	name = "Frosty pie"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pie/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pie/frostypie
	category = CAT_FOOD

license: mit


code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////PIZZA!!!////////////////////////////////////////////////

/datum/table_recipe/margheritapizza
	name = "Margherita pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 4,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/margherita
	category = CAT_FOOD

/datum/table_recipe/meatpizza
	name = "Meat pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 4,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/meat
	category = CAT_FOOD

/datum/table_recipe/mushroompizza
	name = "Mushroom pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom = 5
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/mushroom
	category = CAT_FOOD

/datum/table_recipe/vegetablepizza
	name = "Vegetable pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/corn = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/vegetable
	category = CAT_FOOD

/datum/table_recipe/donpocketpizza
	name = "Donkpocket pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/donkpocket/warm = 3,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/donkpocket
	category = CAT_FOOD

/datum/table_recipe/dankpizza
	name = "Dank pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris = 3,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/dank
	category = CAT_FOOD

/datum/table_recipe/sassysagepizza
	name = "Sassysage pizza"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pizzabread = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 3,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pizza/sassysage
	category = CAT_FOOD


code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////SALADS////////////////////////////////////////////////

/datum/table_recipe/herbsalad
	name = "Herb salad"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris = 3,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/herbsalad
	category = CAT_FOOD

/datum/table_recipe/aesirsalad
	name = "Aesir salad"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus = 3,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/aesirsalad
	category = CAT_FOOD

/datum/table_recipe/validsalad
	name = "Valid salad"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris = 3,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/validsalad
	category = CAT_FOOD

/datum/table_recipe/monkeysdelight
	name = "Monkeys delight"
	reqs = list(
		/datum/reagent/consumable/flour = 5,
		/datum/reagent/consumable/sodiumchloride = 1,
		/datum/reagent/consumable/blackpepper = 1,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/monkeycube = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/monkeysdelight
	category = CAT_FOOD

/datum/table_recipe/oatmeal
	name = "Oatmeal"
	reqs = list(
		/datum/reagent/consumable/milk = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/oat = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/oatmeal
	category = CAT_FOOD

/datum/table_recipe/fruitsalad
	name = "Fruit salad"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/grapes = 1,
		/obj/item/weapon/reagent_containers/food/snacks/watermelonslice = 2

	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/fruit
	category = CAT_FOOD

/datum/table_recipe/junglesalad
	name = "Jungle salad"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/apple = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/grapes = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/banana = 2,
		/obj/item/weapon/reagent_containers/food/snacks/watermelonslice = 2

	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/jungle
	category = CAT_FOOD

/datum/table_recipe/citrusdelight
	name = "Citrus delight"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = 1

	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/citrusdelight
	category = CAT_FOOD

/datum/table_recipe/ricepork
	name = "Rice and pork"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/salad/boiledrice = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/ricepork
	category = CAT_FOOD

/datum/table_recipe/eggbowl
	name = "Egg bowl"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/salad/boiledrice = 1,
		/obj/item/weapon/reagent_containers/food/snacks/boiledegg = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/corn = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/eggbowl
	category = CAT_FOOD

/datum/table_recipe/ricepudding
	name = "Rice pudding"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/food/snacks/salad/boiledrice = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/salad/ricepudding
	category = CAT_FOOD


code:
// see code/datums/recipe.dm

// see code/module/crafting/table.dm

////////////////////////////////////////////////SANDWICHES////////////////////////////////////////////////

/datum/table_recipe/sandwich
	name = "Sandwich"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2,
		/obj/item/weapon/reagent_containers/food/snacks/meat/steak = 1,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/sandwich
	category = CAT_FOOD

/datum/table_recipe/grilledcheesesandwich
	name = "Grilled cheese sandwich"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/grilledcheese
	category = CAT_FOOD

/datum/table_recipe/slimesandwich
	name = "Jelly sandwich"
	reqs = list(
		/datum/reagent/toxin/slimejelly = 5,
		/obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/slime
	category = CAT_FOOD

/datum/table_recipe/cherrysandwich
	name = "Jelly sandwich"
	reqs = list(
		/datum/reagent/consumable/cherryjelly = 5,
		/obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/jellysandwich/cherry
	category = CAT_FOOD

/datum/table_recipe/icecreamsandwich
	name = "Icecream sandwich"
	reqs = list(
		/datum/reagent/consumable/cream = 5,
		/datum/reagent/consumable/ice = 5,
		/obj/item/weapon/reagent_containers/food/snacks/icecream = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/icecreamsandwich
	category = CAT_FOOD

/datum/table_recipe/notasandwich
	name = "Not a sandwich"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 2,
		/obj/item/clothing/mask/fakemoustache = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/notasandwich
	category = CAT_FOOD


code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////SOUP////////////////////////////////////////////////

/datum/table_recipe/meatballsoup
	name = "Meatball soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/meatball
	category = CAT_FOOD

/datum/table_recipe/vegetablesoup
	name = "Vegetable soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/corn = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/vegetable
	category = CAT_FOOD

/datum/table_recipe/nettlesoup
	name = "Nettle soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/grown/nettle = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato = 1,
		/obj/item/weapon/reagent_containers/food/snacks/boiledegg = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/nettle
	category = CAT_FOOD

/datum/table_recipe/wingfangchu
	name = "Wingfangchu"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/datum/reagent/consumable/soysauce = 5,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet/xeno = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/wingfangchu
	category = CAT_FOOD

/datum/table_recipe/wishsoup
	name = "Wish soup"
	reqs = list(
		/datum/reagent/water = 20,
		/obj/item/weapon/reagent_containers/glass/bowl = 1
	)
	result= /obj/item/weapon/reagent_containers/food/snacks/soup/wish
	category = CAT_FOOD

/datum/table_recipe/hotchili
	name = "Hot chili"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/chili = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/hotchili
	category = CAT_FOOD

/datum/table_recipe/coldchili
	name = "Cold chili"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/coldchili
	category = CAT_FOOD

/datum/table_recipe/tomatosoup
	name = "Tomato soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/tomato
	category = CAT_FOOD

/datum/table_recipe/milosoup
	name = "Milo soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/soydope = 2,
		/obj/item/weapon/reagent_containers/food/snacks/tofu = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/milo
	category = CAT_FOOD

/datum/table_recipe/bloodsoup
	name = "Blood soup"
	reqs = list(
		/datum/reagent/blood = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/blood
	category = CAT_FOOD

/datum/table_recipe/slimesoup
	name = "Slime soup"
	reqs = list(
			/datum/reagent/water = 10,
			/datum/reagent/toxin/slimejelly = 5,
			/obj/item/weapon/reagent_containers/glass/bowl = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/slime
	category = CAT_FOOD

/datum/table_recipe/clownstears
	name = "Clowns tears"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1,
		/obj/item/weapon/ore/bananium = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/clownstears
	category = CAT_FOOD

/datum/table_recipe/mysterysoup
	name = "Mystery soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/badrecipe = 1,
		/obj/item/weapon/reagent_containers/food/snacks/tofu = 1,
		/obj/item/weapon/reagent_containers/food/snacks/boiledegg = 1,
		/obj/item/weapon/reagent_containers/food/snacks/cheesewedge = 1,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/mystery
	category = CAT_FOOD

/datum/table_recipe/mushroomsoup
	name = "Mushroom soup"
	reqs = list(
		/datum/reagent/consumable/milk = 5,
		/datum/reagent/water = 5,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/mushroom
	category = CAT_FOOD

/datum/table_recipe/beetsoup
	name = "Beet soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage = 1,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/beet
	category = CAT_FOOD

/datum/table_recipe/stew
	name = "Stew"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 3,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/stew
	category = CAT_FOOD

/datum/table_recipe/spacylibertyduff
	name = "Spacy liberty duff"
	reqs = list(
		/datum/reagent/consumable/ethanol/vodka = 5,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap = 3
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/spacylibertyduff
	category = CAT_FOOD

/datum/table_recipe/amanitajelly
	name = "Amanita jelly"
	reqs = list(
		/datum/reagent/consumable/ethanol/vodka = 5,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/amanita = 3
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/amanitajelly
	category = CAT_FOOD

/datum/table_recipe/sweetpotatosoup
	name = "Sweet potato soup"
	reqs = list(
		/datum/reagent/water = 10,
		/datum/reagent/consumable/sugar = 5,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/sweetpotato
	category = CAT_FOOD

/datum/table_recipe/redbeetsoup
	name = "Red beet soup"
	reqs = list(
		/datum/reagent/water = 10,
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/redbeet = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/beet/red
	category = CAT_FOOD


code:
// see code/module/crafting/table.dm

////////////////////////////////////////////////SPAGHETTI////////////////////////////////////////////////

/datum/table_recipe/tomatopasta
	name = "Tomato pasta"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/pastatomato
	category = CAT_FOOD

/datum/table_recipe/copypasta
	name = "Copypasta"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/pastatomato = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/copypasta
	category = CAT_FOOD

/datum/table_recipe/spaghettimeatball
	name = "Spaghetti meatball"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/meatballspaghetti
	category = CAT_FOOD

/datum/table_recipe/spesslaw
	name = "Spesslaw"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 4
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/spesslaw
	category = CAT_FOOD

/datum/table_recipe/beefnoodle
	name = "Beef noodle"
	reqs = list(
		/obj/item/weapon/reagent_containers/glass/bowl = 1,
		/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/beefnoodle
	category = CAT_FOOD

/datum/table_recipe/chowmein
	name = "Chowmein"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1,
		/obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 1,
		/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage = 2,
		/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/chowmein
	category = CAT_FOOD


code:
/datum/playingcard
	var/name = "playing card"
	var/card_icon = "card_back"
	var/suit
	var/number

/* Deck */

/obj/item/weapon/deck
	name = "deck of cards"
	desc = "A simple deck of playing cards."
	icon = 'playing_cards.dmi'
	icon_state = "deck"
	w_class = 2

	var/list/cards = list()

/obj/item/weapon/deck/New()
	. = ..()

	var/color
	var/datum/playingcard/card

	for (var/suit in list("spades", "clubs", "diamonds", "hearts"))
		if (suit == "spades" || suit == "clubs") color = "black_"
		else                                     color = "red_"

		for (var/number in list("ace", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"))
			card               = new()
			card.name          = "[number] of [suit]"
			card.card_icon     = "[color]num"
			card.suit          = suit
			card.number        = number

			src.cards.Add(card)

		for (var/number in list("jack", "queen", "king"))
			card               = new()
			card.name          = "[number] of [suit]"
			card.card_icon     = "[color]col"
			card.suit          = suit
			card.number        = number

			src.cards.Add(card)

	for (var/i = 0, i < 2, i++)
		card                   = new()
		card.name              = "joker"
		card.card_icon         = "joker"
		card.suit              = "joker"
		card.number            = ""

		src.cards.Add(card)

/obj/item/weapon/deck/attackby(obj/O, mob/user)
	if (istype(O,/obj/item/weapon/hand))
		var/obj/item/weapon/hand/H = O

		for (var/datum/playingcard/P in H.cards) src.cards.Add(P)

		qdel (O)

		user.show_message("You place your cards on the bottom of the deck.")
	else return ..()

/obj/item/weapon/deck/attack_self(mob/user)
	var/list/newcards           = list()
	var/datum/playingcard/card

	while (cards.len)
		card                    = pick(cards)
		newcards.Add(card)
		src.cards.Remove(card)

	src.cards                   = newcards

	user.visible_message("\The [user] shuffles [src].")

/obj/item/weapon/deck/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params)
	if(flag)
		return //It's adjacent, is the user, or is on the user's person

	if (istype(A, /mob/living))
		src.dealTo(A, user)
	else
		return ..()

/obj/item/weapon/deck/attack(mob/living/M, mob/living/user, def_zone)
	if (istype(M))
		src.dealTo(M, user)
	else
		return ..()

/obj/item/weapon/deck/proc/dealTo(mob/living/target, mob/living/source)
	if (!cards.len)
		source.show_message("There are no cards in the deck.")
		return

	var/datum/playingcard/card = src.cards[1]

	src.cards.Remove(card)

	var/obj/item/weapon/hand/H = new(get_turf(src))

	H.concealed = 1
	H.update_conceal()

	H.cards.Add(card)
	H.update_icon()

	source.visible_message("\The [source] deals a card to \the [target].")
	H.throw_at(get_step(target, target.dir), 10, 1, source)

/* Hand */

/obj/item/weapon/hand
	name           = "hand of cards"
	desc           = "Some playing cards."
	icon           = 'playing_cards.dmi'
	icon_state     = "empty"
	w_class        = 1

	var/concealed  = 0
	var/list/cards = list()
	var/datum/html_interface/hi

/obj/item/weapon/hand/New(loc)
	. = ..()

	src.hi = new/datum/html_interface/cards(src, "Your hand", 540, 302)
	src.update_conceal()

/obj/item/weapon/hand/Destroy()
	if (src.hi)
		qdel(src.hi)

	return ..()

/obj/item/weapon/hand/attackby(obj/O, mob/user)
	if(istype(O,/obj/item/weapon/hand))
		var/obj/item/weapon/hand/H = O

		for(var/datum/playingcard/P in src.cards) H.cards.Add(P)

		H.update_icon()

		qdel(src)
	else
		return ..()

/obj/item/weapon/hand/verb/discard(datum/playingcard/card in cards)
	set category = "Object"
	set name     = "Discard"
	set desc     = "Place a card from your hand in front of you."

	if (!card)
		return

	var/obj/item/weapon/hand/H = new(src.loc)

	H.concealed = 0
	H.update_conceal()

	H.cards.Add(card)
	src.cards.Remove(card)

	H.update_icon()

	ASSERT(H)

	usr.visible_message("\The [usr] plays \the [card.name].")
	H.loc = get_step(usr,usr.dir)

	src.update_icon()

/obj/item/weapon/hand/verb/toggle_conceal()
	set category  = "Object"
	set name      = "Toggle conceal"
	set desc      = "Toggle concealment of your hand"

	src.concealed = !src.concealed

	src.update_conceal()

	usr.visible_message("\The [usr] [concealed ? "conceals" : "reveals"] their hand.")

	src.update_icon()

/obj/item/weapon/hand/attack_self(mob/user)
	src.hi.show(user)

/obj/item/weapon/hand/examine()
	. = ..()

	if((!concealed || src.loc == usr) && cards.len)
		usr.show_message("It contains: ", 1)

		for (var/datum/playingcard/card in cards)
			usr.show_message("The [card.name].", 1)

/obj/item/weapon/hand/proc/update_conceal()
	if (src.concealed)
		src.hi.updateContent("headbar", "You are currently concealing your hand. Reveal your hand.")
	else
		src.hi.updateContent("headbar", "You are currently revealing your hand. Conceal your hand.")

/obj/item/weapon/hand/update_icon()
	if (!cards.len)
		qdel (src)
	else
		if(cards.len > 1)
			name = "hand of cards"
			desc = "Some playing cards."
		else
			name = "a playing card"
			desc = "A playing card."

		overlays.len = 0

		if (cards.len == 1)
			var/datum/playingcard/P = cards[1]
			var/image/I             = new(src.icon, (concealed ? "card_back" : "[P.card_icon]") )

			I.pixel_x               = I.pixel_x + (-5 + rand(10))
			I.pixel_y               = I.pixel_y + (-5 + rand(10))

			overlays.Add(I)
		else
			var/origin              = -12
			var/offset              = round(32 / cards.len)

			var/i                   = 0
			var/image/I

			for(var/datum/playingcard/P in cards)
				I                   = new(src.icon, (concealed ? "card_back" : "[P.card_icon]") )
				I.pixel_x           = origin + (offset * i)

				overlays.Add(I)

				i                   = i + 1

		var/html                    = ""

		for(var/datum/playingcard/card in cards)
			html                    = html + ""

		src.hi.updateContent("hand", html)

/obj/item/weapon/hand/Topic(href, href_list[], datum/html_interface_client/hclient)
	if (istype(hclient))
		switch (href_list["action"])
			if ("play_card")
				var/datum/playingcard/card = locate(href_list["card"])

				if (card in src.cards)
					src.discard(card)
			if ("toggle_conceal")
				src.toggle_conceal()

// Hook for html_interface module to prevent updates to clients who don't have this in their inventory.
/obj/item/weapon/hand/proc/hiIsValidClient(datum/html_interface_client/hclient, datum/html_interface/hi)
	return (hclient.client.mob && hclient.client.mob.stat == 0 && (src in hclient.client.mob.contents))


code:
//Easter start
/datum/holiday/easter/greet()
	return "Greetings! Have a Happy Easter and keep an eye out for Easter Bunnies!"

/datum/round_event_control/easter
	name = "Easter Eggselence"
	holidayID = EASTER
	typepath = /datum/round_event/easter
	weight = -1
	max_occurrences = 1
	earliest_start = 0

/datum/round_event/easter/announce()
	priority_announce(pick("Hip-hop into Easter!","Find some Bunny's stash!","Today is National 'Hunt a Wabbit' Day.","Be kind, give Chocolate Eggs!"))

/datum/round_event_control/rabbitrelease
	name = "Release the Rabbits!"
	holidayID = EASTER
	typepath = /datum/round_event/rabbitrelease
	weight = 5
	max_occurrences = 10

/datum/round_event/rabbitrelease/announce()
	priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", 'sound/AI/aliens.ogg')

/datum/round_event/rabbitrelease/start()
	for(var/obj/effect/landmark/R in landmarks_list)
		if(R.name != "blobspawn")
			if(prob(35))
				if(istype(R.loc,/turf/open/space))
					new /mob/living/simple_animal/chicken/rabbit/space(R.loc)
				else
					new /mob/living/simple_animal/chicken/rabbit(R.loc)

/mob/living/simple_animal/chicken/rabbit
	name = "\improper rabbit"
	desc = "The hippiest hop around."
	icon = 'icons/mob/Easter.dmi'
	icon_state = "rabbit"
	icon_living = "rabbit"
	icon_dead = "rabbit_dead"
	speak = list("Hop into Easter!","Come get your eggs!","Prizes for everyone!")
	speak_emote = list("sniffles","twitches")
	emote_hear = list("hops.")
	emote_see = list("hops around","bounces up and down")
	butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 1)
	egg_type = /obj/item/weapon/reagent_containers/food/snacks/egg/loaded
	food_type = /obj/item/weapon/reagent_containers/food/snacks/grown/carrot
	eggsleft = 10
	eggsFertile = FALSE
	icon_prefix = "rabbit"
	feedMessages = list("It nibbles happily.","It noms happily.")
	layMessage = list("hides an egg.","scampers around suspiciously.","begins making a huge racket.","begins shuffling.")

/mob/living/simple_animal/chicken/rabbit/space
	icon_prefix = "s_rabbit"
	icon_state = "s_rabbit"
	icon_living = "s_rabbit"
	icon_dead = "s_rabbit_dead"
	atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
	minbodytemp = 0
	maxbodytemp = 1500
	unsuitable_atmos_damage = 0	//This damage is taken when atmos doesn't fit all the requirements above

//Easter Baskets
/obj/item/weapon/storage/bag/easterbasket
	name = "Easter Basket"
	icon = 'icons/mob/Easter.dmi'
	icon_state = "basket"
	can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/egg,/obj/item/weapon/reagent_containers/food/snacks/chocolateegg,/obj/item/weapon/reagent_containers/food/snacks/boiledegg)

/obj/item/weapon/storage/bag/easterbasket/proc/countEggs()
	overlays.Cut()
	overlays += image("icon" = icon, "icon_state" = "basket-grass", "layer" = -1)
	overlays += image("icon" = icon, "icon_state" = "basket-egg[contents.len <= 5 ? contents.len : 5]", "layer" = -1)

/obj/item/weapon/storage/bag/easterbasket/remove_from_storage(obj/item/W as obj, atom/new_location)
	..()
	countEggs()

/obj/item/weapon/storage/bag/easterbasket/handle_item_insertion(obj/item/I, prevent_warning = 0)
	..()
	countEggs()

//Bunny Suit
/obj/item/clothing/head/bunnyhead
	name = "Easter Bunny Head"
	icon_state = "bunnyhead"
	item_state = "bunnyhead"
	desc = "Considerably more cute than 'Frank'"
	slowdown = -1
	flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR

/obj/item/clothing/suit/bunnysuit
	name = "Easter Bunny Suit"
	desc = "Hop Hop Hop!"
	icon_state = "bunnysuit"
	item_state = "bunnysuit"
	slowdown = -1
	body_parts_covered = CHEST|GROIN|LEGS|ARMS
	flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT

//Egg prizes and egg spawns!
/obj/item/weapon/reagent_containers/food/snacks/egg
	var/containsPrize = FALSE

/obj/item/weapon/reagent_containers/food/snacks/egg/loaded
	containsPrize = TRUE

/obj/item/weapon/reagent_containers/food/snacks/egg/loaded/New()
	..()
	var/color = pick("blue","green","mime","orange","purple","rainbow","red","yellow")
	icon_state = "egg-[color]"
	item_color = "[color]"

/obj/item/weapon/reagent_containers/food/snacks/egg/proc/dispensePrize(turf/where)
	var/won = pick(/obj/item/clothing/head/bunnyhead,
	/obj/item/clothing/suit/bunnysuit,
	/obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
	/obj/item/weapon/reagent_containers/food/snacks/chocolateegg,
	/obj/item/toy/balloon,
	/obj/item/toy/gun,
	/obj/item/toy/sword,
	/obj/item/toy/foamblade,
	/obj/item/toy/prize/ripley,
	/obj/item/toy/prize/honk,
	/obj/item/toy/carpplushie,
	/obj/item/toy/redbutton,
	/obj/item/clothing/head/collectable/rabbitears)
	new won(where)
	new/obj/item/weapon/reagent_containers/food/snacks/chocolateegg(where)

/obj/item/weapon/reagent_containers/food/snacks/egg/attack_self(mob/user)
	..()
	if(containsPrize)
		user << "You unwrap the [src] and find a prize inside!"
		dispensePrize(get_turf(user))
		containsPrize = FALSE
		qdel(src)

/obj/effect/spawner/lootdrop/maintenance/New()
	..()
	loot += list(/obj/item/weapon/reagent_containers/food/snacks/egg/loaded = 15, /obj/item/weapon/storage/bag/easterbasket = 15)

//Easter Recipes + food
/obj/item/weapon/reagent_containers/food/snacks/hotcrossbun
	bitesize = 2
	name = "hot-cross bun"
	desc = "The Cross represents the Assistants that died for your sins."
	icon_state = "hotcrossbun"

/datum/table_recipe/hotcrossbun
	name = "Hot-Cross Bun"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/store/bread/plain = 1,
		/datum/reagent/consumable/sugar = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/hotcrossbun
	category = CAT_FOOD

/obj/item/weapon/reagent_containers/food/snacks/store/cake/brioche
	name = "brioche cake"
	desc = "A ring of sweet, glazed buns."
	icon_state = "briochecake"
	slice_path = /obj/item/weapon/reagent_containers/food/snacks/cakeslice/brioche
	slices_num = 6
	bonus_reagents = list("nutriment" = 10, "vitamin" = 2)

/obj/item/weapon/reagent_containers/food/snacks/cakeslice/brioche
	name = "brioche cake slice"
	desc = "Delicious sweet-bread. Who needs anything else?"
	icon_state = "briochecake_slice"
	filling_color = "#FFD700"

/datum/table_recipe/briochecake
	name = "Brioche cake"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/store/cake/plain = 1,
		/datum/reagent/consumable/sugar = 2
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/store/cake/brioche
	category = CAT_FOOD

/obj/item/weapon/reagent_containers/food/snacks/scotchegg
	name = "scotch egg"
	desc = "A boiled egg wrapped in a delicious, seasoned meatball."
	icon_state = "scotchegg"
	bonus_reagents = list("nutriment" = 2, "vitamin" = 2)
	bitesize = 3
	filling_color = "#FFFFF0"
	list_reagents = list("nutriment" = 6)

/datum/table_recipe/scotchegg
	name = "Scotch egg"
	reqs = list(
		/datum/reagent/consumable/sodiumchloride = 1,
		/datum/reagent/consumable/blackpepper = 1,
		/obj/item/weapon/reagent_containers/food/snacks/boiledegg = 1,
		/obj/item/weapon/reagent_containers/food/snacks/faggot = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/scotchegg
	category = CAT_FOOD

/obj/item/weapon/reagent_containers/food/snacks/soup/mammi
	name = "Mämmi"
	desc = "A bowl of mushy bread and milk. It reminds you, not too fondly, of a bowel movement."
	icon_state = "mammi"
	bonus_reagents = list("nutriment" = 3, "vitamin" = 1)
	list_reagents = list("nutriment" = 8, "vitamin" = 1)

/datum/table_recipe/mammi
	name = "Mämmi"
	reqs = list(
		/obj/item/weapon/reagent_containers/food/snacks/store/bread/plain = 1,
		/obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 1,
		/datum/reagent/consumable/milk = 5
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/soup/mammi
	category = CAT_FOOD

/obj/item/weapon/reagent_containers/food/snacks/chocolatebunny
	name = "chocolate bunny"
	desc = "Contains less than 10% real rabbit!"
	icon_state = "chocolatebunny"
	bonus_reagents = list("nutriment" = 1, "vitamin" = 1)
	list_reagents = list("nutriment" = 4, "sugar" = 2, "cocoa" = 2)
	filling_color = "#A0522D"

/datum/table_recipe/chocolatebunny
	name = "Chocolate bunny"
	reqs = list(
		/datum/reagent/consumable/sugar = 2,
		/obj/item/weapon/reagent_containers/food/snacks/chocolatebar = 1
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/chocolatebunny
	category = CAT_FOOD


code:
//spooky halloween stuff. only tick on halloween!!!

//uses super seekrit double proc definition stuffs. remember to call ..()!
/*/mob/dead/observer/say(var/message) //this doesn't actually work vOv
	..()
	for(var/mob/M in hearers(src, 1))
		if(!M.stat)
			if(M.job == "Chaplain")
				if (prob (49))
					M.show_message("You hear muffled speech... but nothing is there...", 2)
					if(prob(20))
						playsound(loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
				else
					M.show_message("You hear muffled speech... you can almost make out some words...", 2)
//				M.show_message("[stutter(message)]", 2)
					if(prob(30))
						playsound(loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
			else
				if(prob(50))
					return
				else if(prob (95))
					M.show_message("You hear muffled speech... but nothing is there...", 2)
					if(prob(20))
						playsound(loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)
				else
					M.show_message("You hear muffled speech... you can almost make out some words...", 2)
//				M.show_message("[stutter(message)]", 2)
					playsound(loc, pick('sound/effects/ghost.ogg','sound/effects/ghost2.ogg'), 10, 1)*/

///////////////////////////////////////
///////////HALLOWEEN CONTENT///////////
///////////////////////////////////////

//spooky recipes

/datum/recipe/sugarcookie/spookyskull
	reagents = list("flour" = 5, "sugar" = 5, "milk" = 5)
	items = list(
		/obj/item/weapon/reagent_containers/food/snacks/egg,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookyskull

/datum/recipe/sugarcookie/spookycoffin
	reagents = list("flour" = 5, "sugar" = 5, "coffee" = 5)
	items = list(
		/obj/item/weapon/reagent_containers/food/snacks/egg,
	)
	result = /obj/item/weapon/reagent_containers/food/snacks/sugarcookie/spookycoffin

//////////////////////////////
//Spookoween trapped closets//
//////////////////////////////

#define SPOOKY_SKELETON 1
#define ANGRY_FAITHLESS 2
#define SCARY_BATS 		3
#define INSANE_CLOWN	4
#define HOWLING_GHOST	5

//Spookoween variables
/obj/structure/closet
	var/trapped = 0
	var/mob/trapped_mob

/obj/structure/closet/initialize()
	..()
	if(prob(30))
		set_spooky_trap()

/obj/structure/closet/dump_contents()
	..()
	trigger_spooky_trap()

/obj/structure/closet/proc/set_spooky_trap()
	if(prob(0.1))
		trapped = INSANE_CLOWN
		return
	if(prob(1))
		trapped = ANGRY_FAITHLESS
		return
	if(prob(15))
		trapped = SCARY_BATS
		return
	if(prob(20))
		trapped = HOWLING_GHOST
		return
	else
		var/mob/living/carbon/human/H = new(loc)
		H.makeSkeleton()
		H.health = 1e5
		insert(H)
		trapped_mob = H
		trapped = SPOOKY_SKELETON
		return

/obj/structure/closet/proc/trigger_spooky_trap()
	if(!trapped)
		return

	else if(trapped == SPOOKY_SKELETON)
		visible_message("BOO!")
		playsound(loc, pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg','sound/spookoween/girlscream.ogg'), 300, 1)
		trapped = 0
		spawn(90)
			if(trapped_mob && trapped_mob.loc)
				var/datum/effect/effect/system/harmless_smoke_spread/smoke = new()
				smoke.set_up(1, 0, trapped_mob.loc, 0)
				smoke.start()
				qdel(trapped_mob)

	else if(trapped == HOWLING_GHOST)
		visible_message("[pick("OooOOooooOOOoOoOOooooOOOOO", "BooOOooOooooOOOO", "BOO!", "WoOOoOoooOooo")]")
		playsound(loc, 'sound/spookoween/ghosty_wind.ogg', 300, 1)
		new /mob/living/simple_animal/shade/howling_ghost(loc)
		trapped = 0

	else if(trapped == SCARY_BATS)
		visible_message("Protect your hair!")
		playsound(loc, 'sound/spookoween/bats.ogg', 300, 1)
		var/number = rand(1,3)
		for(var/i=0,i < number,i++)
			new /mob/living/simple_animal/hostile/retaliate/bat(loc)
		trapped = 0

	else if(trapped == ANGRY_FAITHLESS)
		visible_message("The closet bursts open!")
		visible_message("THIS BEING RADIATES PURE EVIL! YOU BETTER RUN!!!")
		playsound(loc, 'sound/hallucinations/wail.ogg', 300, 1)
		var/mob/living/simple_animal/hostile/faithless/F = new(loc)
		F.stance = HOSTILE_STANCE_ATTACK
		F.GiveTarget(usr)
		trapped = 0
		spawn(120)
			if(F && F.loc)
				var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
				smoke.set_up(1,0, F.loc, 0)
				smoke.start()
				qdel(F)

	else if(trapped == INSANE_CLOWN)
		visible_message("...")
		playsound(loc, 'sound/spookoween/scary_clown_appear.ogg', 300, 1)
		var/mob/living/simple_animal/hostile/retaliate/clown/insane/IC = new (loc)
		IC.GiveTarget(usr)
		trapped = 0

//don't spawn in crates
/obj/structure/closet/crate/trigger_spooky_trap()
	return

/obj/structure/closet/crate/set_spooky_trap()
	return

////////////////////
//Spookoween Ghost//
////////////////////

/mob/living/simple_animal/shade/howling_ghost
	name = "ghost"
	real_name = "ghost"
	icon = 'icons/mob/mob.dmi'
	maxHealth = 1e6
	health = 1e6
	speak_emote = list("howls")
	emote_hear = list("wails","screeches")
	density = 0
	anchored = 1
	incorporeal_move = 1
	layer = 4
	var/timer = 0

/mob/living/simple_animal/shade/howling_ghost/New()
	..()
	icon_state = pick("ghost","ghostian","ghostian2","ghostking","ghost1","ghost2")
	icon_living = icon_state
	status_flags |= GODMODE
	timer = rand(1,15)

/mob/living/simple_animal/shade/howling_ghost/Life()
	..()
	timer--
	if(prob(20))
		roam()
	if(timer == 0)
		spooky_ghosty()
		timer = rand(1,15)

/mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction)
	loc = get_step(src, direction)
	dir = direction

/mob/living/simple_animal/shade/howling_ghost/proc/roam()
	if(prob(80))
		var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST)
		EtherealMove(direction)

/mob/living/simple_animal/shade/howling_ghost/proc/spooky_ghosty()
	if(prob(20)) //haunt
		playsound(loc, pick('sound/spookoween/ghosty_wind.ogg','sound/spookoween/ghost_whisper.ogg','sound/spookoween/chain_rattling.ogg'), 300, 1)
	if(prob(10)) //flickers
		var/obj/machinery/light/L = locate(/obj/machinery/light) in view(5, src)
		if(L)
			L.flicker()
	if(prob(5)) //poltergeist
		var/obj/item/I = locate(/obj/item) in view(3, src)
		if(I)
			var/direction = pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST)
			step(I,direction)
		return

/mob/living/simple_animal/shade/howling_ghost/adjustHealth()
	. = 0

/mob/living/simple_animal/shade/howling_ghost/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
	return 1

///////////////////////////
//Spookoween Insane Clown//
///////////////////////////

/mob/living/simple_animal/hostile/retaliate/clown/insane
	name = "insane clown"
	desc = "Some clowns do not manage to be accepted, and go insane. This is one of them."
	icon_state = "scary_clown"
	icon_living = "scary_clown"
	icon_dead = "scary_clown"
	icon_gib = "scary_clown"
	speak = list("...", ". . .")
	maxHealth = 1e6
	health = 1e6
	emote_see = list("silently stares")
	unsuitable_atmos_damage = 0
	var/timer

/mob/living/simple_animal/hostile/retaliate/clown/insane/New()
	..()
	timer = rand(5,15)
	status_flags = (status_flags | GODMODE)
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/Retaliate()
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/ex_act()
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/Life()
	timer--
	if(target)
		stalk()
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/proc/stalk()
	var/mob/living/M = target
	if(M.stat == DEAD)
		playsound(M.loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
		qdel(src)
	if(timer == 0)
		timer = rand(5,15)
		playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1)
		spawn(12)
			loc = M.loc

/mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget()
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/AttackTarget()
	return

/mob/living/simple_animal/hostile/retaliate/clown/insane/adjustHealth()
	. = 0
	if(prob(5))
		playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)

/mob/living/simple_animal/hostile/retaliate/clown/insane/attackby(obj/item/O, mob/user)
	if(istype(O,/obj/item/weapon/nullrod))
		if(prob(5))
			visible_message("[src] finally found the peace it deserves. You hear honks echoing off into the distance.")
			playsound(loc, 'sound/spookoween/insane_low_laugh.ogg', 300, 1)
			qdel(src)
		else
			visible_message("[src] seems to be resisting the effect!")
	else
		..()

/mob/living/simple_animal/hostile/retaliate/clown/insane/handle_temperature_damage()
	return


code:
/datum/holiday
	var/name = "Bugsgiving"
	//Right now, only holidays that take place on a certain day or within a time period are supported
	//It would be nice to support things like "the second monday in march" or "the first sunday after the second sunday in june"
	var/begin_day = 1
	var/begin_month = 0
	var/end_day = 0 // Default of 0 means the holiday lasts a single day
	var/end_month = 0

// This proc gets run before the game starts when the holiday is activated. Do festive shit here.
/datum/holiday/proc/celebrate()

// When the round starts, this proc is ran to get a text message to display to everyone to wish them a happy holiday
/datum/holiday/proc/greet()
	return "Have a happy [name]!"

// Returns special prefixes for the station name on certain days. You wind up with names like "Christmas Object Epsilon". See new_station_name()
/datum/holiday/proc/getStationPrefix()
	//get the first word of the Holiday and use that
	var/i = findtext(name," ",1,0)
	return copytext(name,1,i)

// Return 1 if this holidy should be celebrated today
/datum/holiday/proc/shouldCelebrate(dd, mm, yy)
	if(!end_day)
		end_day = begin_day
	if(!end_month)
		end_month = begin_month

	if(end_month > begin_month) //holiday spans multiple months in one year
		if(mm == end_month) //in final month
			if(dd <= end_day)
				return 1

		else if(mm == begin_month)//in first month
			if(dd >= begin_day)
				return 1

		else if(mm in begin_month to end_month) //holiday spans 3+ months and we're in the middle, day doesn't matter at all
			return 1

	else if(end_month == begin_month) // starts and stops in same month, simplest case
		if(mm == begin_month && (dd in begin_day to end_day))
			return 1

	else // starts in one year, ends in the next
		if(mm >= begin_month && dd >= begin_day) // Holiday ends next year
			return 1
		if(mm <= end_month && dd <= end_day) // Holiday started last year
			return 1

	return 0

// The actual holidays

/datum/holiday/new_year
	name = NEW_YEAR
	begin_day = 30
	begin_month = DECEMBER
	end_day = 2
	end_month = JANUARY

/datum/holiday/new_year/getStationPrefix()
	return pick("Party","New","Hangover","Resolution")

/datum/holiday/groundhog
	name = "Groundhog Day"
	begin_day = 2
	begin_month = FEBRUARY

/datum/holiday/valentines
	name = VALENTINES
	begin_day = 13
	end_day = 15
	begin_month = FEBRUARY

/datum/holiday/valentines/getStationPrefix()
	return pick("Love","Amore","Single","Smootch","Hug")

/datum/holiday/birthday
	name = "Birthday of Space Station 13"
	begin_day = 16
	begin_month = FEBRUARY

/datum/holiday/birthday/greet()
	var/game_age = text2num(time2text(world.timeofday, "YY")) - 3
	var/Fact
	switch(game_age)
		if(16)
			Fact = " SS13 is now old enough to drive!"
		if(18)
			Fact = " SS13 is now legal!"
		if(21)
			Fact = " SS13 can now drink!"
		if(26)
			Fact = " SS13 can now rent a car!"
		if(30)
			Fact = " SS13 can now go home and be a family man!"
		if(40)
			Fact = " SS13 can now suffer a midlife crisis!"
		if(50)
			Fact = " Happy golden anniversary!"
		if(65)
			Fact = " SS13 can now start thinking about retirement!"
		if(96)
			Fact = " Please send a time machine back to pick me up, I need to update the time formatting for this feature!" //See you later suckers
	if(!Fact)
		Fact = " SS13 is now [game_age] years old!"

	return "Say 'Happy Birthday' to Space Station 13, first publicly playable on February 16th, 2003![Fact]"

/datum/holiday/random_kindness
	name = "Random Acts of Kindness Day"
	begin_day = 17
	begin_month = FEBRUARY

/datum/holiday/random_kindness/greet()
	return "Go do some random acts of kindness for a stranger!" //haha yeah right

/datum/holiday/leap
	name = "Leap Day"
	begin_day = 29
	begin_month = FEBRUARY

/datum/holiday/pi
	name = "Pi Day"
	begin_day = 14
	begin_month = MARCH

/datum/holiday/no_this_is_patrick
	name = "St. Patrick's Day"
	begin_day = 17
	begin_month = MARCH

/datum/holiday/no_this_is_patrick/getStationPrefix()
	return pick("Blarney","Green","Leprechaun","Booze")

/datum/holiday/april_fools
	name = APRIL_FOOLS
	begin_day = 1
	end_day = 2
	begin_month = APRIL

/datum/holiday/fourtwenty
	name = "Four-Twenty"
	begin_day = 20
	begin_month = APRIL

/datum/holiday/fourtwenty/getStationPrefix()
	return pick("Snoop","Blunt","Toke","Dank")

/datum/holiday/earth
	name = "Earth Day"
	begin_day = 22
	begin_month = APRIL

/datum/holiday/labor
	name = "Labor Day"
	begin_day = 1
	begin_month = MAY

/datum/holiday/firefighter
	name = "Firefighter's Day"
	begin_day = 4
	begin_month = MAY

/datum/holiday/firefighter/getStationPrefix()
	return pick("Burning","Blazing","Plasma","Fire")

/datum/holiday/summersolstice
	name = "Summer Solstice"
	begin_day = 21
	begin_month = JUNE

/datum/holiday/doctor
	name = "Doctor's Day"
	begin_day = 1
	begin_month = JULY

/datum/holiday/UFO
	name = "UFO Day"
	begin_day = 2
	begin_month = JULY

/datum/holiday/UFO/getStationPrefix() //Is such a thing even possible?
	return pick("Ayy","Truth","Tsoukalos","Mulder") //Yes it is!

/datum/holiday/writer
	name = "Writer's Day"
	begin_day = 8
	begin_month = JULY

/datum/holiday/friendship
	name = "Friendship Day"
	begin_day = 30
	begin_month = JULY

/datum/holiday/friendship/greet()
	return "Have a magical [name]!"

/datum/holiday/beer
	name = "Beer Day"
	begin_day = 5
	begin_month = AUGUST

/datum/holiday/pirate
	name = "Talk-Like-a-Pirate Day"
	begin_day = 19
	begin_month = SEPTEMBER

/datum/holiday/pirate/greet()
	return "Ye be talkin' like a pirate today or else ye'r walkin' tha plank, matey!"

/datum/holiday/pirate/getStationPrefix()
	return pick("Yarr","Scurvy","Yo-ho-ho")

/datum/holiday/programmers
	name = "Programmers' Day"

/datum/holiday/programmers/shouldCelebrate(dd, mm, yy) //Programmer's day falls on the 2^8th day of the year
	if(mm == 9)
		if(yy/4 == round(yy/4)) //Note: Won't work right on September 12th, 2200 (at least it's a Friday!)
			if(dd == 12)
				return 1
		else
			if(dd == 13)
				return 1
	return 0

/datum/holiday/programmers/getStationPrefix()
	return pick("span>","DEBUG: ","null","/list","EVENT PREFIX NOT FOUND") //Portability

/datum/holiday/questions
	name = "Stupid-Questions Day"
	begin_day = 28
	begin_month = SEPTEMBER

/datum/holiday/questions/greet()
	return "Are you having a happy [name]?"

/datum/holiday/animal
	name = "Animal's Day"
	begin_day = 4
	begin_month = OCTOBER

/datum/holiday/animal/getStationPrefix()
	return pick("Parrot","Corgi","Cat","Pug","Goat","Fox")

/datum/holiday/smile
	name = "Smiling Day"
	begin_day = 7
	begin_month = OCTOBER

/datum/holiday/boss
	name = "Boss' Day"
	begin_day = 16
	begin_month = OCTOBER

/datum/holiday/halloween
	name = HALLOWEEN
	begin_day = 30
	begin_month = OCTOBER
	end_day = 2
	end_month = NOVEMBER

/datum/holiday/halloween/greet()
	return "Have a spooky Halloween!"

/datum/holiday/halloween/getStationPrefix()
	return pick("Bone-Rattling","Mr. Bones' Own","2SPOOKY","Spooky","Scary","Skeletons")

/datum/holiday/vegan
	name = "Vegan Day"
	begin_day = 1
	begin_month = NOVEMBER

/datum/holiday/kindness
	name = "Kindness Day"
	begin_day = 13
	begin_month = NOVEMBER

/datum/holiday/flowers
	name = "Flowers Day"
	begin_day = 19
	begin_month = NOVEMBER

/datum/holiday/hello
	name = "Saying-'Hello' Day"
	begin_day = 21
	begin_month = NOVEMBER

/datum/holiday/hello/greet()
	return "[pick(list("Aloha", "Bonjour", "Hello", "Hi", "Greetings", "Salutations", "Bienvenidos", "Hola", "Howdy"))]! " + ..()

/datum/holiday/human_rights
	name = "Human-Rights Day"
	begin_day = 10
	begin_month = DECEMBER

/datum/holiday/monkey
	name = "Monkey Day"
	begin_day = 14
	begin_month = DECEMBER

/datum/holiday/xmas
	name = CHRISTMAS
	begin_day = 23
	begin_month = DECEMBER
	end_day = 25

/datum/holiday/xmas/greet()
	return "Have a merry Christmas!"

/datum/holiday/boxing
	name = "Boxing Day"
	begin_day = 26
	begin_month = DECEMBER

/datum/holiday/friday_thirteenth
	name = "Friday the 13th"

/datum/holiday/friday_thirteenth/shouldCelebrate(dd, mm, yy)
	if(dd == 13)
		if(time2text(world.timeofday, "DDD") == "Fri")
			return 1
	return 0

/datum/holiday/friday_thirteenth/getStationPrefix()
	return pick("Mike","Friday","Evil","Myers","Murder","Deathly","Stabby")

/datum/holiday/easter
	name = EASTER
	var/const/days_early = 1 //to make editing the holiday easier
	var/const/days_extra = 1

/datum/holiday/easter/shouldCelebrate(dd, mm, yy)
// Easter's celebration day is as snowflakey as Uhangi's code

	if(!begin_month)

		var/yy_string = "[yy]"
// year = days after March 22that Easter falls on that year.
// For 2015 Easter is on April 5th, so 2015 = 14 since the 5th is 14 days past the 22nd
// If it's 2040 and this is still in use, invent a time machine and teach me a better way to do this. Also tell us about HL3.
		var/list/easters = list(
		"15" = 14,\
		"16" = 6,\
		"17" = 25,\
		"18" = 10,\
		"19" = 30,\
		"20" = 22,\
		"21" = 13,\
		"22" = 26,\
		"23" = 18,\
		"24" = 9,\
		"25" = 29,\
		"26" = 14,\
		"27" = 6,\
		"28" = 25,\
		"29" = 10,\
		"30" = 30,\
		"31" = 23,\
		"32" = 6,\
		"33" = 26,\
		"34" = 18,\
		"35" = 3,\
		"36" = 22,\
		"37" = 14,\
		"38" = 34,\
		"39" = 19,\
		"40" = 9,\
		)

		begin_day = easters[yy_string]
		if(begin_day <= 9)
			begin_day += 22
			begin_month = MARCH
		else
			begin_day -= 9
			begin_month = APRIL

		end_day = begin_day + days_extra
		end_month = begin_month
		if(end_day >= 32 && end_month == MARCH) //begins in march, ends in april
			end_day -= 31
			end_month++
		if(end_day >= 31 && end_month == APRIL) //begins in april, ends in june
			end_day -= 30
			end_month++

		begin_day -= days_early
		if(begin_day <= 0)
			if(begin_month == APRIL)
				begin_day += 31
				begin_month-- //begins in march, ends in april

//	world << "Easter calculates to be on [begin_day] of [begin_month] ([days_early] early) to [end_day] of [end_month] ([days_extra] extra) for 20[yy]"
	return ..()


code:
/proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0, var/atom/newloc = null, var/nerf = 0)
	if(!original)
		return null
	var/obj/O

	if(sameloc)
		O = new original.type(original.loc)
	else
		O = new original.type(newloc)

	if(perfectcopy && O && original)
		var/global/list/forbidden_vars = list("type","loc","locs","vars", "parent","parent_type", "verbs","ckey","key","power_supply","contents","reagents","stat","x","y","z","group")

		for(var/V in original.vars - forbidden_vars)
			if(istype(original.vars[V],/list))
				var/list/L = original.vars[V]
				O.vars[V] = L.Copy()
			else if(istype(original.vars[V],/datum))
				continue	// this would reference the original's object, that will break when it is used or deleted.
			else
				O.vars[V] = original.vars[V]

	if(istype(O))
		O.burn_state = FIRE_PROOF // holoitems do not burn
		if(nerf && istype(O,/obj/item))
			var/obj/item/I = O
			I.damtype = STAMINA // thou shalt not
		if(istype(O,/obj/machinery))
			var/obj/machinery/M = O
			M.power_change()
	O.update_icon()
	return O

/area/proc/copy_contents_to(var/area/A , var/platingRequired = 0, var/nerf_weapons = 0 )
	//Takes: Area. Optional: If it should copy to areas that don't have plating
	//Returns: Nothing.
	//Notes: Attempts to move the contents of one area to another area.
	//       Movement based on lower left corner. Tiles that do not fit
	//		 into the new area will not be moved.

	if(!A || !src) return 0

	var/list/turfs_src = get_area_turfs(src.type)
	var/list/turfs_trg = get_area_turfs(A.type)

	var/src_min_x = 99999
	var/src_min_y = 99999
	var/list/refined_src = new/list()

	for (var/turf/T in turfs_src)
		src_min_x = min(src_min_x,T.x)
		src_min_y = min(src_min_y,T.y)
	for (var/turf/T in turfs_src)
		refined_src[T] = "[T.x - src_min_x].[T.y - src_min_y]"

	var/trg_min_x = 99999
	var/trg_min_y = 99999
	var/list/refined_trg = new/list()

	for (var/turf/T in turfs_trg)
		trg_min_x = min(trg_min_x,T.x)
		trg_min_y = min(trg_min_y,T.y)
	for (var/turf/T in turfs_trg)
		refined_trg["[T.x - trg_min_x].[T.y - trg_min_y]"] = T

	var/list/toupdate = new/list()

	var/copiedobjs = list()

	for (var/turf/T in refined_src)
		//var/datum/coords/C_src = refined_src[T]
		var/coordstring = refined_src[T]
		var/turf/B = refined_trg[coordstring]
		if(!istype(B))
			continue

		if(platingRequired)
			if(istype(B, /turf/open/space))
				continue

		var/old_dir1 = T.dir
		var/old_icon_state1 = T.icon_state
		var/old_icon1 = T.icon

		var/turf/X = new T.type(B)
		X.dir = old_dir1
		X.icon = old_icon1
		X.icon_state = old_icon_state1

		for(var/obj/O in T)
			var/obj/O2 = DuplicateObject(O , 1, newloc = X, nerf=nerf_weapons)
			if(!O2) continue
			copiedobjs += O2.GetAllContents()

		for(var/mob/M in T)
			if(istype(M, /mob/camera)) continue // If we need to check for more mobs, I'll add a variable
			var/mob/SM = DuplicateObject(M , 1, newloc = X)
			copiedobjs += SM.GetAllContents()

		var/global/list/forbidden_vars = list("type","stat","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity")
		for(var/V in T.vars - forbidden_vars)
			if(V == "air")
				var/turf/open/O1 = X
				var/turf/open/O2 = T
				O1.air.copy_from(O2.air)
				continue
			X.vars[V] = T.vars[V]
		toupdate += X

	if(toupdate.len)
		for(var/turf/T1 in toupdate)
			T1.CalculateAdjacentTurfs()
			SSair.add_to_active(T1,1)

	return copiedobjs


code:
/area/holodeck
	name = "Holodeck"
	icon_state = "Holodeck"
	luminosity = 1
	lighting_use_dynamic = 0

	var/obj/machinery/computer/holodeck/linked
	var/restricted = 0 // if true, program goes on emag list

/*
	Power tracking: Use the holodeck computer's power grid
	Asserts are to avoid the inevitable infinite loops
*/

/area/holodeck/powered(var/chan)
	if(!master.requires_power)
		return 1
	if(master.always_unpowered)
		return 0
	if(!linked)
		return 0
	var/area/A = get_area(linked)
	ASSERT(!istype(A,/area/holodeck))
	return A.powered(chan)

/area/holodeck/usage(var/chan)
	if(!linked)
		return 0
	var/area/A = get_area(linked)
	ASSERT(!istype(A,/area/holodeck))
	return A.usage(chan)

/area/holodeck/addStaticPower(value, powerchannel)
	if(!linked)
		return
	var/area/A = get_area(linked)
	ASSERT(!istype(A,/area/holodeck))
	return A.addStaticPower(value,powerchannel)

/area/holodeck/use_power(var/amount, var/chan)
	if(!linked)
		return 0
	var/area/A = get_area(linked)
	ASSERT(!istype(A,/area/holodeck))
	return A.use_power(amount,chan)

/*
	This is the standard holodeck.  It is intended to allow you to
	blow off steam by doing stupid things like laying down, throwing
	spheres at holes, or bludgeoning people.
*/
/area/holodeck/rec_center
	name = "\improper Recreational Holodeck"

/area/holodeck/rec_center/offline
	name = "Holodeck - Offline"

/area/holodeck/rec_center/court
	name = "Holodeck - Empty Court"

/area/holodeck/rec_center/dodgeball
	name = "Holodeck - Dodgeball Court"

/area/holodeck/rec_center/basketball
	name = "Holodeck - Basketball Court"

/area/holodeck/rec_center/thunderdome
	name = "Holodeck - Thunderdome Court"

/area/holodeck/rec_center/beach
	name = "Holodeck - Beach"

/area/holodeck/rec_center/lounge
	name = "Holodeck - Lounge"

/area/holodeck/rec_center/medical
	name = "Holodeck - Emergency Medical"

/area/holodeck/rec_center/pet_lounge
	name = "Holodeck - Pet Playground"

// Bad programs

/area/holodeck/rec_center/burn
	name = "Holodeck - Atmospheric Burn Test"
	restricted = 1

/area/holodeck/rec_center/wildlife
	name = "Holodeck - Wildlife Simulation"
	restricted = 1

/area/holodeck/rec_center/bunker
	name = "Holodeck - Holdout Bunker"
	restricted = 1


code:
/*
	Holodeck Update

	The on-station holodeck area is of type [holodeck_type].
	All subtypes of [program_type] are loaded into the program cache or emag programs list.
	If init_program is null, a random program will be loaded on startup.
	If you don't wish this, set it to the offline program or another of your choosing.

	You can use this to add holodecks with minimal code:
	1) Define new areas for the holodeck programs
	2) Map them
	3) Create a new control console that uses those areas

	Non-mapped areas should be skipped but you should probably comment them out anyway.
	The base of program_type will always be ignored; only subtypes will be loaded.
*/

/obj/machinery/computer/holodeck
	name = "holodeck control console"
	desc = "A computer used to control a nearby holodeck."
	icon_screen = "holocontrol"
	idle_power_usage = 10
	active_power_usage = 50
	var/area/holodeck/linked
	var/area/holodeck/program
	var/area/holodeck/last_program
	var/area/offline_program = /area/holodeck/rec_center/offline

	var/list/program_cache = list()
	var/list/emag_programs = list()

	// Splitting this up allows two holodecks of the same size
	// to use the same source patterns.  Y'know, if you want to.
	var/holodeck_type = /area/holodeck/rec_center	// locate(this) to get the target holodeck
	var/program_type = /area/holodeck/rec_center	// subtypes of this (but not this itself) are loadable programs

	// set this if you want it to start with some particular program.
	var/init_program = null
	// or this to get anything
	var/random_program = 0

	var/active = 0
	var/damaged = 0
	var/list/spawned = list()
	var/list/effects = list()
	var/last_change = 0

/obj/machinery/computer/holodeck/New()

	if(ispath(holodeck_type,/area))
		linked = locate(holodeck_type)
	if(ispath(offline_program,/area))
		offline_program = locate(offline_program)
	// the following is necessary for power reasons
	var/area/AS = get_area(src)
	if(istype(AS,/area/holodeck))
		world.log << "### MAPPING ERROR"
		world.log << "Holodeck computer cannot be in a holodeck."
		world.log << "This would cause circular power dependency."
		qdel(src)  // todo handle constructed computers
		return
	else
		linked.linked = src // todo detect multiple/constructed computers

	if(ticker && ticker.current_state >= GAME_STATE_PLAYING)
		initialize()
	..()

/obj/machinery/computer/holodeck/initialize()
	program_cache = list()
	emag_programs = list()
	for(var/typekey in subtypesof(program_type))
		var/area/holodeck/A = locate(typekey)
		if(!A || A == offline_program) continue
		if(A.contents.len == 0) continue // not loaded
		if(A.restricted)
			emag_programs += A
		else
			program_cache += A
		if(typekey == init_program)
			load_program(A,force=1)
	if(random_program && program_cache.len && init_program == null)
		load_program(pick(program_cache),force=1)
	else if(!program)
		load_program(offline_program)

/obj/machinery/computer/holodeck/power_change()
	..()
	toggle_power(!stat)

/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = 0)
	if(active == toggleOn) return

	if(toggleOn)
		if(last_program && last_program != offline_program)
			load_program(last_program, delay = 1)
		active = 1
	else
		last_program = program
		load_program(offline_program,force=1)
		active = 0

/obj/machinery/computer/holodeck/proc/emergency_shutdown()
	last_program = program
	load_program(offline_program,1)
	active = 0

/obj/machinery/computer/holodeck/process()
	if(damaged)
		if(prob(10))
			for(var/turf/T in linked)
				if(prob(5))
					var/datum/effect_system/spark_spread/s = new
					s.set_up(2, 1, T)
					s.start()
					return

	if(!..() || !active)
		return

	if(!floorcheck())
		emergency_shutdown()
		damaged = 1
		for(var/mob/M in urange(10,src))
			M.show_message("The holodeck overloads!")

		for(var/turf/T in linked)
			if(prob(30))
				var/datum/effect_system/spark_spread/s = new
				s.set_up(2, 1, T)
				s.start()
			T.ex_act(3)
			T.hotspot_expose(1000,500,1)

	if(!emagged)
		for(var/item in spawned)
			if(!(get_turf(item) in linked))
				derez(item, 0)
	for(var/obj/effect/holodeck_effect/HE in effects)
		HE.tick()

	active_power_usage = 50 + spawned.len * 3 + effects.len * 5

/obj/machinery/computer/holodeck/proc/floorcheck()
	for(var/turf/T in linked)
		if(!T.intact || istype(T,/turf/open/space))
			return 0
	return 1

/obj/machinery/computer/holodeck/Topic(href, list/href_list)
	if(..())
		return
	if(!Adjacent(usr) && !istype(usr, /mob/living/silicon))
		return
	usr.set_machine(src)
	add_fingerprint(usr)
	if(href_list["loadarea"])
		var/areapath = text2path(href_list["loadarea"])
		if(!ispath(areapath, /area/holodeck))
			return
		var/area/holodeck/area = locate(areapath)
		if(!istype(area))
			return
		if(area == offline_program || (area in program_cache) || (emagged && (area in emag_programs)))
			load_program(area)
	else if("safety" in href_list)
		var/safe = text2num(href_list["safety"])
		emagged = !safe
		if(!program)
			return
		if(safe && (program in emag_programs))
			emergency_shutdown()
		nerf(safe)
	updateUsrDialog()

/obj/machinery/computer/holodeck/proc/nerf(active)
	for(var/obj/item/I in spawned)
		I.damtype = (active? STAMINA : initial(I.damtype) )
	for(var/obj/effect/holodeck_effect/HE in effects)
		HE.safety(active)

/obj/machinery/computer/holodeck/emag_act(mob/user as mob)
	if(!emagged)
		if(!emag_programs.len)
			user << "[src] does not seem to have a card swipe port.  It must be an inferior model."
			return
		playsound(loc, 'sound/effects/sparks4.ogg', 75, 1)
		emagged = 1
		user << "You vastly increase projector power and override the safety and security protocols."
		user << "Warning.  Automatic shutoff and derezing protocols have been corrupted.  Please call Nanotrasen maintenance and do not use the simulator."
		log_game("[key_name(user)] emagged the Holodeck Control Console")
		updateUsrDialog()
		nerf(!emagged)

/obj/machinery/computer/holodeck/Destroy()
	emergency_shutdown()
	..()

/obj/machinery/computer/holodeck/emp_act(severity)
	emergency_shutdown()
	..()

/obj/machinery/computer/holodeck/ex_act(severity, target)
	emergency_shutdown()
	..()

/obj/machinery/computer/holodeck/blob_act()
	emergency_shutdown()
	..()


code:
/obj/machinery/computer/holodeck/attack_hand(var/mob/user as mob)
	user.set_machine(src)

	var/dat = "
Current Loaded Programs
"
	dat += "Power Off
"
	for(var/area/A in program_cache)
		dat += "[A.name]
"
	if(emagged && emag_programs.len)
		dat += "SUPERVISOR ACCESS - SAFETY PROTOCOLS DISABLED - CAUTION: EMITTER ANOMALY
"
		for(var/area/A in emag_programs)
			dat += "[A.name]
"

	var/datum/browser/popup = new(user, "computer", name, 400, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()
	return

/obj/machinery/computer/holodeck/attack_ai(var/mob/user as mob)
	var/dat = "
Current Loaded Programs
"

	dat += "Power Off
"
	for(var/area/A in program_cache)
		dat += "[A.name]
"

	if(emag_programs.len)
		dat += "
"
		if(emagged)
			dat += "Safety protocol: Offline Engage
"
			for(var/area/A in emag_programs)
				dat += "[A.name]
"
		else
			dat += "Safety protocol: Online Disengage
"

	var/datum/browser/popup = new(user, "computer", name, 400, 500)
	popup.set_content(dat)
	popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
	popup.open()

/obj/machinery/computer/holodeck/proc/load_program(var/area/A, var/force = 0, var/delay = 0)
	if(stat)
		A = offline_program
		force = 1
		delay = 0
	if(program == A)
		return
	if(world.time < (last_change + 25 + (damaged?500:0)) && !force)
		if(delay)
			sleep(25)
		else
			if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve
				return
			if(get_dist(usr,src) <= 3)
				usr << "ERROR. Recalibrating projection apparatus."
				return

	last_change = world.time
	active = (A != offline_program)
	use_power = active+1

	for(var/obj/effect/holodeck_effect/HE in effects)
		HE.deactivate(src)

	for(var/item in spawned)
		derez(item, forced=force)

	program = A
	// note nerfing does not yet work on guns, should
	// should also remove/limit/filter reagents?
	// this is an exercise left to others I'm afraid.  -Sayu
	spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged)
	for(var/obj/machinery/M in spawned)
		M.flags |= NODECONSTRUCT
	for(var/obj/structure/S in spawned)
		S.flags |= NODECONSTRUCT
	effects = list()

	spawn(30)
		var/list/added = list()
		for(var/obj/effect/holodeck_effect/HE in spawned)
			effects += HE
			spawned -= HE
			var/atom/x = HE.activate(src)
			if(istype(x) || islist(x))
				spawned += x // holocarp are not forever
				added += x
		for(var/obj/machinery/M in added)
			M.flags |= NODECONSTRUCT
		for(var/obj/structure/S in added)
			S.flags |= NODECONSTRUCT

/obj/machinery/computer/holodeck/proc/derez(var/obj/obj, var/silent = 1, var/forced = 0)
	// Emagging a machine creates an anomaly in the derez systems.
	if(obj && src.emagged && !src.stat && !forced)
		if((ismob(obj) || istype(obj.loc,/mob)) && prob(50))
			spawn(50) .(obj,silent) // may last a disturbingly long time
			return
	spawned.Remove(obj)

	if(!obj)
		return
	var/turf/T = get_turf(obj)
	for(var/atom/movable/AM in obj.contents) // these should be derezed if they were generated
		AM.loc = T							// otherwise make sure they are dropped

	if(istype(obj))
		var/mob/M = obj.loc
		if(ismob(M))
			M.unEquip(obj, 1) //Holoweapons should always drop.

	for(var/mob/M in obj.contents)
		M.loc = obj.loc
		silent = 0

	if(!silent)
		var/obj/oldobj = obj
		visible_message("The [oldobj.name] fades away!")
	qdel(obj)


code:
/*
	The holodeck activates these shortly after the program loads,
	and deactivates them immediately before changing or disabling the holodeck.

	These remove snowflake code for special holodeck functions.
*/
/obj/effect/holodeck_effect
	icon = 'icons/mob/screen_gen.dmi'
	icon_state = "x2"
	invisibility = 101

/obj/effect/holodeck_effect/proc/activate(var/obj/machinery/computer/holodeck/HC)
	return

/obj/effect/holodeck_effect/proc/deactivate(var/obj/machinery/computer/holodeck/HC)
	qdel(src)
	return

// Called by the holodeck computer as long as the program is running
/obj/effect/holodeck_effect/proc/tick(var/obj/machinery/computer/holodeck/HC)
	return

/obj/effect/holodeck_effect/proc/safety(var/active)
	return

// Generates a holodeck-tracked card deck
/obj/effect/holodeck_effect/cards
	icon = 'icons/obj/toy.dmi'
	icon_state = "deck_nanotrasen_full"
	var/obj/item/toy/cards/deck/D

/obj/effect/holodeck_effect/cards/activate(var/obj/machinery/computer/holodeck/HC)
	D = new(loc)
	safety(!HC.emagged)
	D.holo = HC
	return D

/obj/effect/holodeck_effect/cards/safety(active)
	if(!D)
		return
	if(active)
		D.card_hitsound = null
		D.card_force = 0
		D.card_throwforce = 0
		D.card_throw_speed = 3
		D.card_throw_range = 7
		D.card_attack_verb = list("attacked")
	else
		D.card_hitsound = 'sound/weapons/bladeslice.ogg'
		D.card_force = 5
		D.card_throwforce = 10
		D.card_throw_speed = 3
		D.card_throw_range = 7
		D.card_attack_verb = list("attacked", "sliced", "diced", "slashed", "cut")

/obj/effect/holodeck_effect/sparks/activate(var/obj/machinery/computer/holodeck/HC)
	var/turf/T = get_turf(src)
	if(T)
		var/datum/effect_system/spark_spread/s = new
		s.set_up(3, 1, T)
		s.start()
		T.temperature = 5000
		T.hotspot_expose(50000,50000,1)

/obj/effect/holodeck_effect/mobspawner
	var/mobtype = /mob/living/simple_animal/hostile/carp/holocarp
	var/mob/mob = null

/obj/effect/holodeck_effect/mobspawner/activate(var/obj/machinery/computer/holodeck/HC)
	if(islist(mobtype))
		mobtype = pick(mobtype)
	mob = new mobtype(loc)

	// these vars are not really standardized but all would theoretically create stuff on death
	for(var/v in list("butcher_results","corpse","weapon1","weapon2") & mob.vars)
		mob.vars[v] = null
	return mob

/obj/effect/holodeck_effect/mobspawner/deactivate(var/obj/machinery/computer/holodeck/HC)
	if(mob)
		HC.derez(mob)
	qdel(src)

/obj/effect/holodeck_effect/mobspawner/pet
	mobtype = list(
		/mob/living/simple_animal/butterfly, /mob/living/simple_animal/chick/holo,
		/mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/cat/kitten,
		/mob/living/simple_animal/pet/dog/corgi, /mob/living/simple_animal/pet/dog/corgi/puppy,
		/mob/living/simple_animal/pet/dog/pug, /mob/living/simple_animal/pet/fox)


code:
/*
	Items, Structures, Machines
*/

//
// Items
//

/obj/item/weapon/holo
	damtype = STAMINA

/obj/item/weapon/holo/esword
	name = "holographic energy sword"
	desc = "May the force be with you. Sorta"
	icon_state = "sword0"
	force = 3.0
	throw_speed = 2
	throw_range = 5
	throwforce = 0
	w_class = 2.0
	hitsound = "swing_hit"
	armour_penetration = 50
	var/active = 0

/obj/item/weapon/holo/esword/green/New()
	item_color = "green"

/obj/item/weapon/holo/esword/red/New()
	item_color = "red"

/obj/item/weapon/holo/esword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
	if(active)
		return ..()
	return 0

/obj/item/weapon/holo/esword/attack(target as mob, mob/user as mob)
	..()

/obj/item/weapon/holo/esword/New()
	item_color = pick("red","blue","green","purple")

/obj/item/weapon/holo/esword/attack_self(mob/living/user as mob)
	active = !active
	if (active)
		force = 30
		icon_state = "sword[item_color]"
		w_class = 4
		hitsound = 'sound/weapons/blade1.ogg'
		playsound(user, 'sound/weapons/saberon.ogg', 20, 1)
		user << "[src] is now active."
	else
		force = 3
		icon_state = "sword0"
		w_class = 2
		hitsound = "swing_hit"
		playsound(user, 'sound/weapons/saberoff.ogg', 20, 1)
		user << "[src] can now be concealed."
	return

//BASKETBALL OBJECTS

/obj/item/toy/beach_ball/holoball
	name = "basketball"
	icon = 'icons/obj/basketball.dmi'
	icon_state = "basketball"
	item_state = "basketball"
	desc = "Here's your chance, do your dance at the Space Jam."
	w_class = 4 //Stops people from hiding it in their bags/pockets

/obj/item/toy/beach_ball/holoball/dodgeball
	name = "dodgeball"
	icon_state = "dodgeball"
	item_state = "dodgeball"
	desc = "Used for playing the most violent and degrading of childhood games."

/obj/item/toy/beach_ball/holoball/dodgeball/throw_impact(atom/hit_atom)
	..()
	if((ishuman(hit_atom)))
		var/mob/living/carbon/M = hit_atom
		playsound(src, 'sound/items/dodgeball.ogg', 50, 1)
		M.apply_damage(10, STAMINA)
		if(prob(5))
			M.Weaken(3)
			visible_message("[M] is knocked right off \his feet!", 3)

//
// Structures
//

/obj/structure/holohoop
	name = "basketball hoop"
	desc = "Boom, shakalaka!"
	icon = 'icons/obj/basketball.dmi'
	icon_state = "hoop"
	anchored = 1
	density = 1

/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
		var/obj/item/weapon/grab/G = W
		if(G.state < GRAB_AGGRESSIVE)
			user << "You need a better grip to do that!"
			return
		G.affecting.loc = src.loc
		G.affecting.Weaken(5)
		visible_message("[G.assailant] dunks [G.affecting] into \the [src]!", 3)
		qdel(W)
		return
	else if (istype(W, /obj/item) && get_dist(src,user)<2)
		user.drop_item(src)
		visible_message(" [user] dunks [W] into \the [src]!", 3)
		return

/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0)
	if (istype(mover,/obj/item) && mover.throwing)
		var/obj/item/I = mover
		if(istype(I, /obj/item/projectile))
			return
		if(prob(50))
			I.loc = src.loc
			visible_message(" Swish! \the [I] lands in \the [src].", 3)
		else
			visible_message(" \the [I] bounces off of \the [src]'s rim!", 3)
		return 0
	else
		return ..(mover, target, height)

//
// Machines
//

/obj/machinery/readybutton
	name = "ready declaration device"
	desc = "This device is used to declare ready. If all devices in an area are ready, the event will begin!"
	icon = 'icons/obj/monitors.dmi'
	icon_state = "auth_off"
	var/ready = 0
	var/area/currentarea = null
	var/eventstarted = 0

	anchored = 1.0
	use_power = 1
	idle_power_usage = 2
	active_power_usage = 6
	power_channel = ENVIRON

/obj/machinery/readybutton/attack_ai(mob/user as mob)
	user << "The station AI is not to interact with these devices"
	return

/obj/machinery/readybutton/attack_paw(mob/user as mob)
	user << "You are too primitive to use this device!"
	return

/obj/machinery/readybutton/New()
	..()

/obj/machinery/readybutton/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
	user << "The device is a solid button, there's nothing you can do with it!"

/obj/machinery/readybutton/attack_hand(mob/user as mob)
	if(user.stat || stat & (NOPOWER|BROKEN))
		user << "This device is not powered!"
		return

	currentarea = get_area(src.loc)
	if(!currentarea)
		qdel(src)

	if(eventstarted)
		usr << "The event has already begun!"
		return

	ready = !ready

	update_icon()

	var/numbuttons = 0
	var/numready = 0
	for(var/obj/machinery/readybutton/button in currentarea)
		numbuttons++
		if (button.ready)
			numready++

	if(numbuttons == numready)
		begin_event()

/obj/machinery/readybutton/update_icon()
	if(ready)
		icon_state = "auth_on"
	else
		icon_state = "auth_off"

/obj/machinery/readybutton/proc/begin_event()

	eventstarted = 1

	for(var/obj/structure/window/W in currentarea)
		if(W.flags&NODECONSTRUCT) // Just in case: only holo-windows
			qdel(W)

	for(var/mob/M in currentarea)
		M << "FIGHT!"


code:
/turf/open/floor/holofloor
	icon_state = "floor"
	thermal_conductivity = 0
	broken_states = list("engine")
	burnt_states = list("engine")

/turf/open/floor/holofloor/attackby(obj/item/weapon/W as obj, mob/user as mob)
	return // HOLOFLOOR DOES NOT GIVE A FUCK

/turf/open/floor/holofloor/plating
	name = "Holodeck Projector Floor"
	icon_state = "engine"

/turf/open/floor/holofloor/grass
	gender = PLURAL
	name = "lush grass"
	icon_state = "grass"

/turf/open/floor/holofloor/beach
	name = "sand"
	icon = 'icons/misc/beach.dmi'
	icon_state = "sand"

/turf/open/floor/holofloor/beach/coast_t
	name = "coastline"
	icon_state = "sandwater_t"

/turf/open/floor/holofloor/beach/coast_b
	name = "coastline"
	icon_state = "sandwater_b"

/turf/open/floor/holofloor/beach/water
	name = "water"
	icon_state = "water"

/turf/open/floor/holofloor/asteroid
	name = "Asteroid"
	icon_state = "asteroid0"

/turf/open/floor/holofloor/asteroid/New()
	icon_state = "asteroid[pick(0,1,2,3,4,5,6,7,8,9,10,11,12)]"
	..()

/turf/open/floor/holofloor/space
	name = "Space"
	icon = 'icons/turf/space.dmi'
	icon_state = "0"

/turf/open/floor/holofloor/space/New()
	icon_state = SPACE_ICON_STATE // so realistic
	..()

/turf/open/floor/holofloor/hyperspace
	name = "Hyperspace"
	icon = 'icons/turf/space.dmi'
	icon_state = "speedspace_ew_1"

/turf/open/floor/holofloor/hyperspace/New()
	icon_state = "speedspace_ew_[(x + 5*y + (y%2+1)*7)%15+1]"
	..()

/turf/open/floor/holofloor/hyperspace/ns/New()
	..()
	icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]"

/turf/open/floor/holofloor/carpet
	name = "Carpet"
	desc = "Electrically inviting."
	icon = 'icons/turf/floors/carpet.dmi'
	icon_state = "carpet"
	floor_tile = /obj/item/stack/tile/carpet
	broken_states = list("damaged")
	smooth = SMOOTH_TRUE
	canSmoothWith = null

/turf/open/floor/holofloor/carpet/New()
	..()
	spawn(1)
		update_icon()

/turf/open/floor/holofloor/carpet/update_icon()
	if(!..())
		return 0
	if(intact)
		queue_smooth(src)


code:
html, body, div.wrapper > table
{
	width: 100%;
	height: 100%;
}

body
{
	background-color: #EAEAEA;
	font-family: verdana,Geneva,sans-serif;
	font-size: 12px;
	color: #272727;
}

a
{
	color: #5353B1;
}

div.wrapper
{
	position: absolute; top: 24px; left: 0px; right: 0px; bottom: 0px;
}

div#headbar
{
	background-color: #B2B2B2;
	border-bottom: 1px solid #C2C2C2;
	height: 24px;
	padding: 4px 8px;
	box-sizing: border-box;
}

div#hand
{
	padding: 8px 8px;
	padding-bottom: 4px;
	background-color: #EAEAEA;
	text-align: center;
}

a.card
{
	display: inline-block;
	margin: 0px 2px;

	background-image: url(cards.png);
	background-repeat: no-repeat;
	width: 94px;
	height: 129px;

	box-sizing: border-box;
	background-position: 0px 0px;
	background-origin: border-box;

	text-decoration: none;
	font-size: 0px;
}

a.card.clubs.ten			{ background-position: -5px -5px; }
a.card.diamonds.ten			{ background-position: -109px -5px; }
a.card.hearts.ten			{ background-position: -213px -5px; }
a.card.spades.ten			{ background-position: -317px -5px; }
a.card.clubs.two			{ background-position: -421px -5px; }
a.card.diamonds.two			{ background-position: -525px -5px; }
a.card.hearts.two			{ background-position: -629px -5px; }
a.card.spades.two			{ background-position: -733px -5px; }
a.card.clubs.three			{ background-position: -5px -144px; }
a.card.diamonds.three		{ background-position: -109px -144px; }
a.card.hearts.three			{ background-position: -213px -144px; }
a.card.spades.three			{ background-position: -317px -144px; }
a.card.clubs.four			{ background-position: -421px -144px; }
a.card.diamonds.four		{ background-position: -525px -144px; }
a.card.hearts.four			{ background-position: -629px -144px; }
a.card.spades.four			{ background-position: -733px -144px; }
a.card.clubs.five			{ background-position: -5px -283px; }
a.card.diamonds.five		{ background-position: -109px -283px; }
a.card.hearts.five			{ background-position: -213px -283px; }
a.card.spades.five			{ background-position: -317px -283px; }
a.card.clubs.six			{ background-position: -421px -283px; }
a.card.diamonds.six			{ background-position: -525px -283px; }
a.card.hearts.six			{ background-position: -629px -283px; }
a.card.spades.six			{ background-position: -733px -283px; }
a.card.clubs.seven			{ background-position: -5px -422px; }
a.card.diamonds.seven		{ background-position: -109px -422px; }
a.card.hearts.seven			{ background-position: -213px -422px; }
a.card.spades.seven			{ background-position: -317px -422px; }
a.card.clubs.eight			{ background-position: -421px -422px; }
a.card.diamonds.eight		{ background-position: -525px -422px; }
a.card.hearts.eight			{ background-position: -629px -422px; }
a.card.spades.eight			{ background-position: -733px -422px; }
a.card.clubs.nine			{ background-position: -5px -561px; }
a.card.diamonds.nine		{ background-position: -109px -561px; }
a.card.hearts.nine			{ background-position: -213px -561px; }
a.card.spades.nine			{ background-position: -317px -561px; }
a.card.clubs.ace			{ background-position: -421px -561px; }
a.card.diamonds.ace			{ background-position: -525px -561px; }
a.card.hearts.ace			{ background-position: -629px -561px; }
a.card.spades.ace			{ background-position: -733px -561px; }
a.card.clubs.jack			{ background-position: -5px -700px; }
a.card.diamonds.jack		{ background-position: -109px -700px; }
a.card.hearts.jack			{ background-position: -213px -700px; }
a.card.spades.jack			{ background-position: -317px -700px; }
a.card.clubs.king			{ background-position: -421px -700px; }
a.card.diamonds.king		{ background-position: -525px -700px; }
a.card.hearts.king			{ background-position: -629px -700px; }
a.card.spades.king			{ background-position: -733px -700px; }
a.card.clubs.queen			{ background-position: -837px -5px; }
a.card.diamonds.queen		{ background-position: -837px -144px; }
a.card.hearts.queen			{ background-position: -837px -283px; }
a.card.spades.queen			{ background-position: -837px -422px; }
a.card.joker				{ background-position: -837px -561px; }


code:
// Used by playing cards; /obj/item/weapon/hand
// Subtype exists because of sendResources; these must be sent when the client connects.

/datum/html_interface/cards/New()
	. = ..()

	src.head = src.head + "<link rel=\"stylesheet\" type=\"text/css\" href=\"cards.css\" />"
	src.updateLayout("

")

/datum/html_interface/cards/registerResources(var/list/resources = list())
	resources["cards.css"] = 'cards.css'
	resources["cards.png"] = 'cards.png'
	..(resources)


code:
html
{
	-ms-overflow-style: scrollbar;
}

body
{
	font-family: Arial;
	overflow-y: scroll;
	overflow-x: auto;
}