From be32774d4c49571b11c075784e590a0c49dec98e Mon Sep 17 00:00:00 2001
From: jzitnik-dev <email@jzitnik.dev>
Date: Sun, 2 Mar 2025 10:23:29 +0100
Subject: [PATCH] refactor: Rewritten crafting table

---
 .../annotations/CraftingRecipeRegistry.java   |  11 ++
 .../game/crafting/CraftingRecipeList.java     | 120 +++++-------------
 .../game/crafting/recipes/ChestRecipe.java    |  14 ++
 .../crafting/recipes/CraftingTableRecipe.java |  14 ++
 .../game/crafting/recipes/FurnaceRecipe.java  |  14 ++
 .../game/crafting/recipes/OakDoorRecipe.java  |  14 ++
 .../crafting/recipes/OakPlanksRecipe.java     |  14 ++
 .../game/crafting/recipes/StickRecipe.java    |  14 ++
 .../crafting/recipes/StoneAxe2Recipe.java     |  14 ++
 .../game/crafting/recipes/StoneAxeRecipe.java |  14 ++
 .../crafting/recipes/StonePickaxeRecipe.java  |  14 ++
 .../crafting/recipes/StoneShovelRecipe.java   |  14 ++
 .../crafting/recipes/WoodenAxe2Recipe.java    |  14 ++
 .../crafting/recipes/WoodenAxeRecipe.java     |  14 ++
 .../crafting/recipes/WoodenPickaxeRecipe.java |  14 ++
 .../crafting/recipes/WoodenShovelRecipe.java  |  14 ++
 16 files changed, 240 insertions(+), 87 deletions(-)
 create mode 100644 src/main/java/cz/jzitnik/game/annotations/CraftingRecipeRegistry.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/ChestRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/CraftingTableRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/FurnaceRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/OakDoorRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/OakPlanksRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/StickRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxe2Recipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxeRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/StonePickaxeRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/StoneShovelRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxe2Recipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxeRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/WoodenPickaxeRecipe.java
 create mode 100644 src/main/java/cz/jzitnik/game/crafting/recipes/WoodenShovelRecipe.java

diff --git a/src/main/java/cz/jzitnik/game/annotations/CraftingRecipeRegistry.java b/src/main/java/cz/jzitnik/game/annotations/CraftingRecipeRegistry.java
new file mode 100644
index 0000000..04506eb
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/annotations/CraftingRecipeRegistry.java
@@ -0,0 +1,11 @@
+package cz.jzitnik.game.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface CraftingRecipeRegistry {
+    String[] recipe();
+    String result();
+    int amount();
+}
diff --git a/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java
index 8101b13..bf604f9 100644
--- a/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java
+++ b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java
@@ -2,6 +2,8 @@ package cz.jzitnik.game.crafting;
 
 import cz.jzitnik.game.entities.items.InventoryItem;
 import cz.jzitnik.game.entities.items.ItemBlockSupplier;
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+import org.reflections.Reflections;
 
 import java.util.*;
 
@@ -9,97 +11,44 @@ public class CraftingRecipeList {
     private static final List<CraftingRecipe> recipes = new ArrayList<>();
 
     static {
-        // Oak planks
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_log", null, null},
-                {null, null, null},
-                {null, null, null}
-        }, () -> new InventoryItem(4, ItemBlockSupplier.getItem("oak_planks"))));
+        registerRecipes();
+    }
 
-        // Crafting table
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", "oak_planks", null},
-                {"oak_planks", "oak_planks", null},
-                {null, null, null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("crafting_table"))));
+    private static void registerRecipes() {
+        Reflections reflections = new Reflections("cz.jzitnik.game.crafting.recipes");
+        Set<Class<?>> recipeClasses = reflections.getTypesAnnotatedWith(CraftingRecipeRegistry.class);
 
-        // Stick
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", null, null},
-                {"oak_planks", null, null},
-                {null, null, null}
-        }, () -> new InventoryItem(4, ItemBlockSupplier.getItem("stick"))));
+        for (Class<?> clazz : recipeClasses) {
+            try {
+                CraftingRecipeRegistry annotation = clazz.getAnnotation(CraftingRecipeRegistry.class);
+                String[][] recipeGrid = convertTo2DGrid(annotation.recipe());
 
-        // Wooden pickaxe
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", "oak_planks", "oak_planks"},
-                {null, "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_pickaxe"))));
+                recipes.add(new CraftingRecipe(recipeGrid,
+                        () -> new InventoryItem(annotation.amount(), ItemBlockSupplier.getItem(annotation.result()))));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
 
-        // Wooden axe
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", "oak_planks", null},
-                {"oak_planks", "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_axe"))));
-        recipes.add(new CraftingRecipe(new String[][]{
-                {null, "oak_planks", "oak_planks"},
-                {null, "stick", "oak_planks"},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_axe"))));
+    private static String[][] convertTo2DGrid(String[] flatGrid) {
+        int size = (int) Math.sqrt(flatGrid.length); // Assumes 3x3
+        String[][] grid = new String[size][size];
 
-        // Stone pickaxe
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"cobblestone", "cobblestone", "cobblestone"},
-                {null, "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_axe"))));
+        for (int i = 0; i < size; i++) {
+            System.arraycopy(flatGrid, i * size, grid[i], 0, size);
+        }
 
-        // Stone axe
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"cobblestone", "cobblestone", null},
-                {"cobblestone", "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_axe"))));
-        recipes.add(new CraftingRecipe(new String[][]{
-                {null, "cobblestone", "cobblestone"},
-                {null, "stick", "cobblestone"},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_axe"))));
+        // Convert "_" placeholders back to null
+        for (int i = 0; i < size; i++) {
+            for (int j = 0; j < size; j++) {
+                if (grid[i][j].equals("_")) {
+                    grid[i][j] = null;
+                }
+            }
+        }
 
-        // Chest
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", "oak_planks", "oak_planks"},
-                {"oak_planks", null, "oak_planks"},
-                {"oak_planks", "oak_planks", "oak_planks"}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("chest"))));
-
-        // Wooden shovel
-        recipes.add(new CraftingRecipe(new String[][]{
-                {null, "oak_planks", null},
-                {null, "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("wooden_shovel"))));
-
-        // Stone shovel
-        recipes.add(new CraftingRecipe(new String[][]{
-                {null, "cobblestone", null},
-                {null, "stick", null},
-                {null, "stick", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("stone_shovel"))));
-
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"cobblestone", "cobblestone", "cobblestone"},
-                {"cobblestone", null, "cobblestone"},
-                {"cobblestone", "cobblestone", "cobblestone"}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("furnace"))));
-
-        recipes.add(new CraftingRecipe(new String[][]{
-                {"oak_planks", "oak_planks", null},
-                {"oak_planks", "oak_planks", null},
-                {"oak_planks", "oak_planks", null}
-        }, () -> new InventoryItem(1, ItemBlockSupplier.getItem("oak_door"))));
+        return grid;
     }
 
     public static Optional<CraftingRecipe> getRecipe(String[] r) {
@@ -115,7 +64,6 @@ public class CraftingRecipeList {
         int n = array.length;
         int minRow = n, maxRow = -1, minCol = n, maxCol = -1;
 
-        // Find the bounding box of non-null values
         for (int i = 0; i < n; i++) {
             for (int j = 0; j < n; j++) {
                 if (array[i][j] != null) {
@@ -127,7 +75,6 @@ public class CraftingRecipeList {
             }
         }
 
-        // If all elements are null, return an empty array
         if (maxRow == -1) {
             return new String[0][0];
         }
@@ -136,7 +83,6 @@ public class CraftingRecipeList {
         int newSizeCol = maxCol - minCol + 1;
         String[][] trimmedArray = new String[newSizeRow][newSizeCol];
 
-        // Copy the relevant portion of the array
         for (int i = 0; i < newSizeRow; i++) {
             System.arraycopy(array[minRow + i], minCol, trimmedArray[i], 0, newSizeCol);
         }
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/ChestRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/ChestRecipe.java
new file mode 100644
index 0000000..9cc55d6
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/ChestRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "oak_planks", "oak_planks",
+                "oak_planks", "_", "oak_planks",
+                "oak_planks", "oak_planks", "oak_planks"
+        },
+        result = "chest",
+        amount = 1
+)
+public class ChestRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/CraftingTableRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/CraftingTableRecipe.java
new file mode 100644
index 0000000..68b19fd
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/CraftingTableRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "oak_planks", "_",
+                "oak_planks", "oak_planks", "_",
+                "_", "_", "_"
+        },
+        result = "crafting_table",
+        amount = 1
+)
+public class CraftingTableRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/FurnaceRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/FurnaceRecipe.java
new file mode 100644
index 0000000..6026117
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/FurnaceRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "cobblestone", "cobblestone", "cobblestone",
+                "cobblestone", "_", "cobblestone",
+                "cobblestone", "cobblestone", "cobblestone"
+        },
+        result = "furnace",
+        amount = 1
+)
+public class FurnaceRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/OakDoorRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/OakDoorRecipe.java
new file mode 100644
index 0000000..a6e0a42
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/OakDoorRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "oak_planks", "_",
+                "oak_planks", "oak_planks", "_",
+                "oak_planks", "oak_planks", "_"
+        },
+        result = "oak_door",
+        amount = 3
+)
+public class OakDoorRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/OakPlanksRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/OakPlanksRecipe.java
new file mode 100644
index 0000000..1e8b763
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/OakPlanksRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_log", "_", "_",
+                "_", "_", "_",
+                "_", "_", "_"
+        },
+        result = "oak_planks",
+        amount = 4
+)
+public class OakPlanksRecipe {}
\ No newline at end of file
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/StickRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/StickRecipe.java
new file mode 100644
index 0000000..d05609a
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/StickRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "_", "_",
+                "oak_planks", "_", "_",
+                "_", "_", "_"
+        },
+        result = "stick",
+        amount = 4
+)
+public class StickRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxe2Recipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxe2Recipe.java
new file mode 100644
index 0000000..3b1e52d
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxe2Recipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "_", "cobblestone", "cobblestone",
+                "_", "stick", "cobblestone",
+                "_", "stick", "_"
+        },
+        result = "stone_pickaxe",
+        amount = 1
+)
+public class StoneAxe2Recipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxeRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxeRecipe.java
new file mode 100644
index 0000000..73838c9
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneAxeRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "cobblestone", "cobblestone", "_",
+                "cobblestone", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "stone_pickaxe",
+        amount = 1
+)
+public class StoneAxeRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/StonePickaxeRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/StonePickaxeRecipe.java
new file mode 100644
index 0000000..ca7d5ce
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/StonePickaxeRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "cobblestone", "cobblestone", "cobblestone",
+                "_", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "stone_pickaxe",
+        amount = 1
+)
+public class StonePickaxeRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/StoneShovelRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneShovelRecipe.java
new file mode 100644
index 0000000..d1757c2
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/StoneShovelRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "_", "cobblestone", "_",
+                "_", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "stone_shovel",
+        amount = 1
+)
+public class StoneShovelRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxe2Recipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxe2Recipe.java
new file mode 100644
index 0000000..a84f1ab
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxe2Recipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "_", "oak_planks", "oak_planks",
+                "_", "stick", "oak_planks",
+                "_", "stick", "_"
+        },
+        result = "wooden_axe",
+        amount = 1
+)
+public class WoodenAxe2Recipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxeRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxeRecipe.java
new file mode 100644
index 0000000..925b611
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenAxeRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "oak_planks", "_",
+                "oak_planks", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "oak_planks",
+        amount = 1
+)
+public class WoodenAxeRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenPickaxeRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenPickaxeRecipe.java
new file mode 100644
index 0000000..34a9d6a
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenPickaxeRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "oak_planks", "oak_planks", "oak_planks",
+                "_", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "wooden_pickaxe",
+        amount = 1
+)
+public class WoodenPickaxeRecipe {}
diff --git a/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenShovelRecipe.java b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenShovelRecipe.java
new file mode 100644
index 0000000..8cd9696
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/crafting/recipes/WoodenShovelRecipe.java
@@ -0,0 +1,14 @@
+package cz.jzitnik.game.crafting.recipes;
+
+import cz.jzitnik.game.annotations.CraftingRecipeRegistry;
+
+@CraftingRecipeRegistry(
+        recipe = {
+                "_", "oak_planks", "_",
+                "_", "stick", "_",
+                "_", "stick", "_"
+        },
+        result = "wooden_shovel",
+        amount = 1
+)
+public class WoodenShovelRecipe {}