Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Cooking makes food an interactive part of everyday life. Players grow and gather
- **Working kitchens** — fry, boil, prepare sauces and soups, and bake with cookware, heat sources, and fuelled ovens. Leaving food cooking too long can burn it.
- **Food preparation** — milling stones, mixing bowls, butter churns, sausage makers, and baking trays provide different ways to transform ingredients.
- **Sandwiches** — lay a slice of bread on a cutting board, add spreads, cheese and vegetables, close it with another slice and pick it up. Its fillings name it, and its food, quality and freshness come from its layers (`sandwiches.yml`).
- **Pizzas** — place a pizza peel, put dough on it, spread a paste and add cheese, vegetables, fruit, sausage and spices, then carry the peel into a lit oven to bake. A baked pizza is taken off a slice at a time. Its toppings name it, and its food, quality and freshness come from its layers (`pizzas.yml`).
- **Serving and sharing** — plate dishes, ladle soup into bowls, and carve foods into portions for the table.
- **Quality and freshness** — ingredient quality and composition influence finished dishes, while aging and food tags carry preparation history through the kitchen.
- **Farming and husbandry** — crop fertility and harvest quality sit alongside animal care, breeding, genetics, and produce collection.
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/net/tfminecraft/cooking/Cooking.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
import net.tfminecraft.cooking.baking.BakingTrayAging;
import net.tfminecraft.cooking.baking.BakingTrayHandler;
import net.tfminecraft.cooking.baking.BakingTrayLoader;
import net.tfminecraft.cooking.pizza.PizzaConfig;
import net.tfminecraft.cooking.pizza.PizzaHandler;
import net.tfminecraft.cooking.sandwich.SandwichConfig;
import net.tfminecraft.cooking.sandwich.SandwichHandler;
import net.tfminecraft.cooking.milling.MillingRecipeLoader;
Expand Down Expand Up @@ -135,6 +137,8 @@ public class Cooking extends JavaPlugin {
private final BakingTrayHandler bakingTrayHandler = new BakingTrayHandler();
private final SandwichConfig sandwichConfig = new SandwichConfig();
private final SandwichHandler sandwichHandler = new SandwichHandler();
private final PizzaConfig pizzaConfig = new PizzaConfig();
private final PizzaHandler pizzaHandler = new PizzaHandler();
private final MillingStoneHandler millingStoneHandler = new MillingStoneHandler();
private final TroughHandler troughHandler = new TroughHandler();
private final TroughAging troughAging = new TroughAging();
Expand Down Expand Up @@ -191,6 +195,7 @@ public void onEnable() {
liquidContainerHandler.resumeLoadedContainers();
meatHookHandler.resumeLoadedHooks();
sandwichHandler.resumeLoaded();
pizzaHandler.start();
warnIfCharacterIdentityMissing(getLogger());
SaturationGuard.start();
NutritionDrainTask.start();
Expand Down Expand Up @@ -258,6 +263,7 @@ public void loadConfigs() {
foodLoader.load(new File(getDataFolder(), "types.yml"));
bakingTrayLoader.load(new File(getDataFolder(), "baking-trays.yml"));
sandwichConfig.load(new File(getDataFolder(), "sandwiches.yml"));
pizzaConfig.load(new File(getDataFolder(), "pizzas.yml"));
millingRecipeLoader.load(new File(getDataFolder(), "milling-recipes.yml"));
stationLoader.load(new File(getDataFolder(), "crafting-stations.yml"));
trackLoader.load(new File(getDataFolder(), "tags.yml"));
Expand Down Expand Up @@ -322,6 +328,7 @@ public void registerListeners() {
getServer().getPluginManager().registerEvents(sausageMakerHandler, this);
getServer().getPluginManager().registerEvents(bakingTrayHandler, this);
getServer().getPluginManager().registerEvents(sandwichHandler, this);
getServer().getPluginManager().registerEvents(pizzaHandler, this);
getServer().getPluginManager().registerEvents(millingStoneHandler, this);
getServer().getPluginManager().registerEvents(troughHandler, this);
getServer().getPluginManager().registerEvents(ovenLifecycleHandler, this);
Expand Down Expand Up @@ -416,6 +423,7 @@ public void createConfigs() {
"crafting-stations.yml",
"baking-trays.yml",
"sandwiches.yml",
"pizzas.yml",
"milling-recipes.yml",
"cookware.yml",
"tags.yml",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ private void restoreExtras() {

// Preserve the existing serialized item format so previously saved graves remain readable.
@SuppressWarnings("deprecation")
static String encodeStack(ItemStack stack) {
public static String encodeStack(ItemStack stack) {
if (stack == null) return null;
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
Expand All @@ -564,7 +564,7 @@ static String encodeStack(ItemStack stack) {

// Preserve the existing serialized item format so previously saved graves remain readable.
@SuppressWarnings("deprecation")
static ItemStack decodeStack(String payload) {
public static ItemStack decodeStack(String payload) {
if (payload == null || payload.isBlank()) return null;
try {
byte[] bytes = Base64.getDecoder().decode(payload);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import net.tfminecraft.cooking.baking.BakingTrayRegistry;
import net.tfminecraft.cooking.heat.HeatSources;
import net.tfminecraft.cooking.pizza.PizzaConfig;
import net.tfminecraft.interactiblefurniture.events.FurnitureSlotFurnitureAddEvent;
import net.tfminecraft.interactiblefurniture.furniture.Furniture;
import net.tfminecraft.interactiblefurniture.furniture.SlotType;
Expand All @@ -23,11 +24,11 @@ public void onFurnitureAdd(FurnitureSlotFurnitureAddEvent event) {
}

Furniture nested = event.getNested();
if (nested == null || BakingTrayRegistry.isTray(nested)) {
if (nested == null || BakingTrayRegistry.isTray(nested) || PizzaConfig.isPeel(nested)) {
return;
}

event.setCancelled(true);
event.getPlayer().sendMessage("§cOnly baking trays can go in the oven.");
event.getPlayer().sendMessage("§cOnly baking trays and pizza peels can go in the oven.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import net.tfminecraft.cooking.heat.HeatSources;
import net.tfminecraft.cooking.item.FoodItem;
import net.tfminecraft.cooking.item.tag.TagTrack;
import net.tfminecraft.cooking.pizza.PizzaBaking;
import net.tfminecraft.cooking.pizza.PizzaConfig;
import net.tfminecraft.interactiblefurniture.furniture.Furniture;
import net.tfminecraft.interactiblefurniture.furniture.PlacedFurnitureSlot;
import net.tfminecraft.interactiblefurniture.furniture.PlacedSlot;
Expand Down Expand Up @@ -46,6 +48,10 @@ private void tick() {

for (PlacedFurnitureSlot slot : consumer.getActiveFurnitureSlots().values()) {
Furniture tray = slot.getNested();
if (PizzaConfig.isPeel(tray)) {
PizzaBaking.tick(consumer, tray);
continue;
}
BakingTrayRecipe recipe = BakingTrayRegistry.getByFurniture(tray);
if (recipe == null) {
continue;
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/net/tfminecraft/cooking/pizza/PizzaBaking.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.tfminecraft.cooking.pizza;

import net.tfminecraft.cooking.heat.HeatSources;
import net.tfminecraft.interactiblefurniture.InteractibleFurniture;
import net.tfminecraft.interactiblefurniture.furniture.Furniture;

/**
* Bakes the pizza on a peel in an oven, one second at a time while the oven is hot: it cooks after pizzas.yml's
* cook-seconds and burns at burn-seconds, and every layer then shows its cooked or burnt look.
*/
public final class PizzaBaking {

private PizzaBaking() {}

public static void tick(Furniture oven, Furniture peel) {
int baked = PizzaPeel.baked(peel);
if (baked >= PizzaPeel.BURNT || PizzaPeel.layers(peel).isEmpty() || !HeatSources.consumerHasHeat(oven)) return;
int elapsed = PizzaPeel.elapsed(peel) + 1;
int next = baked;
if (elapsed >= PizzaConfig.burnSeconds()) next = PizzaPeel.BURNT;
else if (elapsed >= PizzaConfig.cookSeconds()) next = PizzaPeel.COOKED;
PizzaPeel.setBake(peel, elapsed, next);
if (next != baked) {
// Slices still to be cut take the new bake.
PizzaPeel.forgetSlice(peel);
PizzaPeel.remodel(peel);
}
InteractibleFurniture.getInstance().getFurnitureManager().markDirty(peel);
}
}
106 changes: 106 additions & 0 deletions src/main/java/net/tfminecraft/cooking/pizza/PizzaConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package net.tfminecraft.cooking.pizza;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;

import net.tfminecraft.cooking.item.FoodItem;
import net.tfminecraft.cooking.sandwich.SandwichLayer;
import net.tfminecraft.interactiblefurniture.furniture.Furniture;

/**
* pizzas.yml: the peels pizzas are built on, the slices they're cut into, how long they bake and the layers they take.
*/
public final class PizzaConfig {
private static Set<String> furniture = Set.of();
private static int maxToppings = 6;
private static String output = "meal(type=pizza_slice;origin=Mixed)";
private static int slices = 4;
private static int cookSeconds = 20;
private static int burnSeconds = 60;
private static SandwichLayer base;
private static SandwichLayer sauce;
private static List<SandwichLayer> toppings = List.of();

public void load(File file) {
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
Set<String> peels = new HashSet<>();
for (String id : config.getStringList("furniture")) peels.add(id.toLowerCase(Locale.ROOT));
List<SandwichLayer> loaded = new ArrayList<>();
ConfigurationSection section = config.getConfigurationSection("toppings");
if (section != null) {
for (String id : section.getKeys(false)) {
ConfigurationSection topping = section.getConfigurationSection(id);
if (topping != null) loaded.add(new SandwichLayer(id, topping));
}
}
furniture = peels;
maxToppings = Math.max(1, config.getInt("max-toppings", 6));
output = config.getString("output", "meal(type=pizza_slice;origin=Mixed)");
slices = Math.max(1, config.getInt("slices", 4));
cookSeconds = Math.max(1, config.getInt("bake.cook-seconds", 20));
burnSeconds = Math.max(cookSeconds + 1, config.getInt("bake.burn-seconds", 60));
base = layer(config, "base");
sauce = layer(config, "sauce");
toppings = loaded;
}

private static SandwichLayer layer(YamlConfiguration config, String id) {
ConfigurationSection section = config.getConfigurationSection(id);
return section == null ? null : new SandwichLayer(id, section);
}

public static boolean isPeel(Furniture f) {
return f != null && f.getType() != null && furniture.contains(f.getType().getId().toLowerCase(Locale.ROOT));
}

/** The layer this food makes (the base, the sauce or a topping), or null when it doesn't go on a pizza. */
public static SandwichLayer layerFor(FoodItem food) {
if (base != null && base.matches(food)) return base;
if (sauce != null && sauce.matches(food)) return sauce;
for (SandwichLayer topping : toppings) {
if (topping.matches(food)) return topping;
}
return null;
}

/** The dough every pizza starts with. */
public static boolean isBase(SandwichLayer layer) {
return layer != null && layer == base;
}

/** The one spread that goes straight on the dough. */
public static boolean isSauce(SandwichLayer layer) {
return layer != null && layer == sauce;
}

public static int maxToppings() {
return maxToppings;
}

/** The food line of one slice of the finished pizza (types.yml type, origin, tags). */
public static String output() {
return output;
}

/** Slices a baked pizza is cut into; 1 takes it off the peel whole. */
public static int slices() {
return slices;
}

/** Seconds in a hot oven until the pizza is cooked. */
public static int cookSeconds() {
return cookSeconds;
}

/** Seconds in a hot oven, counted from when it went in, until the pizza burns. */
public static int burnSeconds() {
return burnSeconds;
}
}
Loading
Loading