forked from jzitnik/twodcraft
feat: Implemented sapling growing
This commit is contained in:
parent
bc7480459a
commit
13e2a74b37
11
src/main/java/cz/jzitnik/game/annotations/Sapling.java
Normal file
11
src/main/java/cz/jzitnik/game/annotations/Sapling.java
Normal file
@ -0,0 +1,11 @@
|
||||
package cz.jzitnik.game.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Sapling {
|
||||
}
|
@ -2,13 +2,16 @@ package cz.jzitnik.game.entities.items.registry.blocks;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||
import cz.jzitnik.game.annotations.Sapling;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.logic.services.saplings.SaplingData;
|
||||
|
||||
@Sapling
|
||||
@BlockRegistry("oak_sapling")
|
||||
public class OakSaplingBlock extends Block {
|
||||
public OakSaplingBlock() {
|
||||
super("oak_sapling", SpriteLoader.SPRITES.OAK_SAPLING, 0);
|
||||
setData(new SaplingData());
|
||||
setGhost(true);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ public class Generation {
|
||||
// Spawn player at a valid starting point
|
||||
world[terrainHeight[256] - 1][256].add(steveBlock2);
|
||||
world[terrainHeight[256] - 2][256].add(steveBlock);
|
||||
|
||||
game.getInventory().addItem(ItemBlockSupplier.getItem("oak_sapling"));
|
||||
}
|
||||
|
||||
private static void initializeWorld(List<Block>[][] world) {
|
||||
@ -96,7 +98,11 @@ public class Generation {
|
||||
if (treeBase - 3 < 0)
|
||||
continue;
|
||||
|
||||
// Place trunk
|
||||
tree(world, i, treeBase);
|
||||
}
|
||||
}
|
||||
|
||||
public static void tree(List<Block>[][] world, int i, int treeBase) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
if (treeBase - j >= 0) {
|
||||
world[treeBase - j - 1][i].add(ItemBlockSupplier.getBlock("oak_log"));
|
||||
@ -105,7 +111,6 @@ public class Generation {
|
||||
|
||||
int leafY = treeBase - 4;
|
||||
|
||||
// 2D Pyramid-shaped leaf placement
|
||||
for (int layer = 0; layer < 3; layer++) {
|
||||
int size = 5 - (layer * 2);
|
||||
int offsetY = leafY - layer;
|
||||
@ -120,7 +125,4 @@ public class Generation {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,95 @@
|
||||
package cz.jzitnik.game.logic.services.saplings;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||
import cz.jzitnik.game.annotations.CustomLogic;
|
||||
import cz.jzitnik.game.annotations.Sapling;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.generation.Generation;
|
||||
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@CustomLogic
|
||||
public class SaplingLogic implements CustomLogicInterface {
|
||||
private static final int RADIUS = 30;
|
||||
|
||||
private static final Set<String> saplings = new HashSet<>();
|
||||
|
||||
public SaplingLogic() {
|
||||
Reflections reflections = new Reflections("cz.jzitnik.game.entities.items.registry.blocks");
|
||||
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(Sapling.class);
|
||||
|
||||
for (Class<?> clazz : handlerClasses) {
|
||||
if (clazz.isAnnotationPresent(BlockRegistry.class)) {
|
||||
String value = clazz.getAnnotation(BlockRegistry.class).value();
|
||||
saplings.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextIteration(Game game) {
|
||||
int[] data = game.getPlayerCords();
|
||||
var world = game.getWorld();
|
||||
int playerX = data[0];
|
||||
int playerY = data[1];
|
||||
|
||||
int startX = Math.max(0, playerX - RADIUS);
|
||||
int startY = Math.max(0, playerY - RADIUS);
|
||||
int endX = Math.min(world[0].length - 1, playerX + RADIUS);
|
||||
int endY = Math.min(world.length - 1, playerY + RADIUS);
|
||||
|
||||
for (int x = startX; x <= endX; x++) {
|
||||
for (int y = startY; y <= endY; y++) {
|
||||
var blocks = world[y][x];
|
||||
if (blocks.stream().anyMatch(block -> saplings.contains(block.getBlockId()))) {
|
||||
sapling(game, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean check(Block block) {
|
||||
return block.isMob() || block.getBlockId().equals("air") || saplings.contains(block.getBlockId());
|
||||
}
|
||||
|
||||
private boolean canGrowSapling(List<Block>[][] world, int x, int y) {
|
||||
return
|
||||
world[y][x].stream().allMatch(this::check) &&
|
||||
world[y - 1][x].stream().allMatch(this::check) &&
|
||||
world[y - 2][x].stream().allMatch(this::check) &&
|
||||
world[y - 3][x].stream().allMatch(this::check) &&
|
||||
world[y - 4][x].stream().allMatch(this::check) &&
|
||||
world[y - 5][x].stream().allMatch(this::check) &&
|
||||
world[y - 3][x - 2].stream().allMatch(this::check) &&
|
||||
world[y - 3][x - 1].stream().allMatch(this::check) &&
|
||||
world[y - 3][x + 1].stream().allMatch(this::check) &&
|
||||
world[y - 3][x + 2].stream().allMatch(this::check) &&
|
||||
world[y - 4][x - 1].stream().allMatch(this::check) &&
|
||||
world[y - 4][x + 1].stream().allMatch(this::check);
|
||||
}
|
||||
|
||||
private void sapling(Game game, int x, int y) {
|
||||
var world = game.getWorld();
|
||||
if (!canGrowSapling(world, x, y)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var sapling = world[y][x].stream().filter(i -> saplings.contains(i.getBlockId())).findFirst().get();
|
||||
var data = (SaplingData) sapling.getData();
|
||||
|
||||
if (data.getGrowWait() == 1) {
|
||||
// Grow
|
||||
world[y][x].remove(sapling);
|
||||
Generation.tree(world, x, y + 1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data.setGrowWait(data.getGrowWait() - 1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user