From dd7f1c041f7d658bc3a49f4ee27bec6198399b89 Mon Sep 17 00:00:00 2001
From: jzitnik-dev <email@jzitnik.dev>
Date: Fri, 14 Mar 2025 11:44:54 +0100
Subject: [PATCH] feat: New grass growing logic using age

---
 .../items/registry/blocks/DirtBlock.java      |  4 +++
 .../items/registry/blocks/GrassBlock.java     |  4 +++
 .../logic/services/grass/GrassDirtData.java   | 16 ++++++++++++
 .../services/grass/GrassGrowingLogic.java     | 26 ++++++++++++++-----
 4 files changed, 43 insertions(+), 7 deletions(-)
 create mode 100644 src/main/java/cz/jzitnik/game/logic/services/grass/GrassDirtData.java

diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/DirtBlock.java b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/DirtBlock.java
index ccbb58d..814d0dc 100644
--- a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/DirtBlock.java
+++ b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/DirtBlock.java
@@ -2,14 +2,18 @@ package cz.jzitnik.game.entities.items.registry.blocks;
 
 import cz.jzitnik.game.SpriteLoader;
 import cz.jzitnik.game.annotations.BlockRegistry;
+import cz.jzitnik.game.annotations.ResetDataOnMine;
 import cz.jzitnik.game.entities.Block;
 import cz.jzitnik.game.entities.items.ItemType;
+import cz.jzitnik.game.logic.services.grass.GrassDirtData;
 
 import java.util.ArrayList;
 
+@ResetDataOnMine
 @BlockRegistry("dirt")
 public class DirtBlock extends Block {
     public DirtBlock() {
         super("dirt", SpriteLoader.SPRITES.DIRT, 1, ItemType.SHOVEL, new ArrayList<>());
+        setData(new GrassDirtData());
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/GrassBlock.java b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/GrassBlock.java
index 277f226..d01dc4d 100644
--- a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/GrassBlock.java
+++ b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/GrassBlock.java
@@ -2,14 +2,18 @@ package cz.jzitnik.game.entities.items.registry.blocks;
 
 import cz.jzitnik.game.SpriteLoader;
 import cz.jzitnik.game.annotations.BlockRegistry;
+import cz.jzitnik.game.annotations.ResetDataOnMine;
 import cz.jzitnik.game.entities.Block;
 import cz.jzitnik.game.entities.items.ItemType;
+import cz.jzitnik.game.logic.services.grass.GrassDirtData;
 
 import java.util.ArrayList;
 
+@ResetDataOnMine
 @BlockRegistry(value = "grass", drops = "dirt")
 public class GrassBlock extends Block {
     public GrassBlock() {
         super("grass", SpriteLoader.SPRITES.GRASS, 1, ItemType.SHOVEL, new ArrayList<>());
+        setData(new GrassDirtData());
     }
 }
diff --git a/src/main/java/cz/jzitnik/game/logic/services/grass/GrassDirtData.java b/src/main/java/cz/jzitnik/game/logic/services/grass/GrassDirtData.java
new file mode 100644
index 0000000..a8b2151
--- /dev/null
+++ b/src/main/java/cz/jzitnik/game/logic/services/grass/GrassDirtData.java
@@ -0,0 +1,16 @@
+package cz.jzitnik.game.logic.services.grass;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+@Getter
+@Setter
+public class GrassDirtData implements Serializable {
+    private int age = 0;
+
+    public void increaseAge() {
+        age++;
+    }
+}
diff --git a/src/main/java/cz/jzitnik/game/logic/services/grass/GrassGrowingLogic.java b/src/main/java/cz/jzitnik/game/logic/services/grass/GrassGrowingLogic.java
index 0bd0733..fc257d8 100644
--- a/src/main/java/cz/jzitnik/game/logic/services/grass/GrassGrowingLogic.java
+++ b/src/main/java/cz/jzitnik/game/logic/services/grass/GrassGrowingLogic.java
@@ -32,17 +32,29 @@ public class GrassGrowingLogic implements CustomLogicInterface {
                     // Dirt
                     if (world[y - 1][x].stream()
                             .allMatch(block -> block.isGhost() || block.isMob() || block.getBlockId().equals("air"))
-                            && random.nextInt(3) < 1 && isGrassBesides(world, x, y)) {
-                        world[y][x].removeIf(block -> block.getBlockId().equals("dirt"));
-                        world[y][x].add(ItemBlockSupplier.getBlock("grass"));
+                            && isGrassBesides(world, x, y)) {
+                        var dirt = blocks.stream().filter(i -> i.getBlockId().equals("dirt")).findFirst().get();
+                        var dirtData = (GrassDirtData) dirt.getData();
+                        if (dirtData.getAge() == 9) {
+                            world[y][x].remove(dirt);
+                            world[y][x].add(ItemBlockSupplier.getBlock("grass"));
+                        } else {
+                            dirtData.increaseAge();
+                        }
+
                     }
                 } else if (blocks.stream().anyMatch(block -> block.getBlockId().equals("grass"))) {
                     // Grass
                     if (!world[y - 1][x].stream()
-                            .allMatch(block -> block.isGhost() || block.isMob() || block.getBlockId().equals("air"))
-                            && random.nextInt(3) < 1) {
-                        world[y][x].removeIf(block -> block.getBlockId().equals("grass"));
-                        world[y][x].add(ItemBlockSupplier.getBlock("dirt"));
+                            .allMatch(block -> block.isGhost() || block.isMob() || block.getBlockId().equals("air"))) {
+                        var grass = blocks.stream().filter(i -> i.getBlockId().equals("grass")).findFirst().get();
+                        var grassData = (GrassDirtData) grass.getData();
+                        if (grassData.getAge() == 9) {
+                            world[y][x].remove(grass);
+                            world[y][x].add(ItemBlockSupplier.getBlock("dirt"));
+                        } else {
+                            grassData.increaseAge();
+                        }
                     }
                 }
             }