feat: Implemented growing
This commit is contained in:
parent
9fc72a67ec
commit
bffee19583
@ -394,7 +394,7 @@ public class Game extends AutoTransientSupport {
|
||||
|
||||
Item item = inventory.getItemInHand().get();
|
||||
|
||||
CustomPlaceHandler placeHandler = gameStates.dependencies.placeHandler.get(item.getId());
|
||||
CustomPlaceHandler placeHandler = gameStates.dependencies.placeHandler.get(item.getBlock().get().getBlockId());
|
||||
|
||||
var blocksRemove = blocks.stream().filter(block -> block.getClass().isAnnotationPresent(BreaksByPlace.class))
|
||||
.toList();
|
||||
|
@ -158,6 +158,9 @@ public class SpriteLoader {
|
||||
LAVA_BUCKET,
|
||||
MILK_BUCKET,
|
||||
|
||||
// Seeds
|
||||
WHEAT,
|
||||
|
||||
// Food
|
||||
ITEM_PORKCHOP,
|
||||
ITEM_COOKED_PORKCHOP,
|
||||
@ -248,6 +251,9 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.HEART, new Heart());
|
||||
SPRITES_MAP.put(SPRITES.HUNGER, new Hunger());
|
||||
|
||||
// SEEDS
|
||||
SPRITES_MAP.put(SPRITES.WHEAT, new Farmable("dirt.ans", "grass.ans", "sand.ans"));
|
||||
|
||||
// ITEMS
|
||||
|
||||
// Items
|
||||
@ -339,8 +345,6 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.ITEM_BEEF, new SimpleSprite("items/beef.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_STEAK, new SimpleSprite("items/steak.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_APPLE, new SimpleSprite("items/apple.ans"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static SpriteList<SPRITES> load() {
|
||||
|
@ -0,0 +1,12 @@
|
||||
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;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@RequireAnnotation(BlockRegistry.class)
|
||||
public @interface ResetSpriteStateOnMine {
|
||||
}
|
@ -70,6 +70,10 @@ public class Block implements Serializable {
|
||||
this.spriteState = MyOptional.of(spriteState);
|
||||
}
|
||||
|
||||
public void setSpriteState() {
|
||||
this.spriteState = MyOptional.empty();
|
||||
}
|
||||
|
||||
public double calculateHardness(Inventory inventory) {
|
||||
double holdingDecrease = 0;
|
||||
if (inventory.getItemInHand().isPresent() && tool.isPresent()
|
||||
|
@ -3,16 +3,20 @@ package cz.jzitnik.game.entities.items.registry.blocks.grassy;
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.annotations.BlockRegistry;
|
||||
import cz.jzitnik.game.annotations.Farmable;
|
||||
import cz.jzitnik.game.annotations.PlaceOnSolidNoHandler;
|
||||
import cz.jzitnik.game.annotations.ResetDataOnMine;
|
||||
import cz.jzitnik.game.annotations.ResetSpriteStateOnMine;
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.logic.services.farmable.FarmableData;
|
||||
|
||||
@ResetDataOnMine
|
||||
@Farmable
|
||||
@BlockRegistry("wheat")
|
||||
@PlaceOnSolidNoHandler
|
||||
@ResetDataOnMine
|
||||
@ResetSpriteStateOnMine
|
||||
@BlockRegistry(value = "wheat", drops = "wheat_seeds")
|
||||
public class WheatBlock extends Block {
|
||||
public WheatBlock() {
|
||||
super("weat", SpriteLoader.SPRITES.OAK_SAPLING, 0);
|
||||
super("wheat", SpriteLoader.SPRITES.WHEAT, 0);
|
||||
setData(new FarmableData());
|
||||
setGhost(true);
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import cz.jzitnik.game.annotations.ItemRegistry;
|
||||
import cz.jzitnik.game.entities.items.Item;
|
||||
import cz.jzitnik.game.entities.items.ItemType;
|
||||
|
||||
@ItemRegistry(value = "wheat_seeds", block = "grass_bush")
|
||||
@ItemRegistry(value = "wheat_seeds", block = "wheat")
|
||||
public class WheatSeedsItem extends Item {
|
||||
public WheatSeedsItem() {
|
||||
super("wheat_seeds", "Wheat seeds", ItemType.USELESS_ITEM, SpriteLoader.SPRITES.ITEM_WHEAT_SEEDS);
|
||||
super("wheat_seeds", "Wheat seeds", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_WHEAT_SEEDS);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ public class Generation {
|
||||
|
||||
game.getInventory().addItem(ItemBlockSupplier.getItem("wooden_hoe"));
|
||||
game.getInventory().addItem(ItemBlockSupplier.getItem("water_bucket"));
|
||||
game.getInventory().addItem(ItemBlockSupplier.getItem("wheat_seeds"));
|
||||
}
|
||||
|
||||
private static void initializeWorld(List<Block>[][] world) {
|
||||
|
@ -15,7 +15,8 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
private final Class<?> clazz;
|
||||
private final DefaultPlaceHandler defaultPlaceHandler = new DefaultPlaceHandler();
|
||||
|
||||
private record BlockDrop(String drops, int percentage) {}
|
||||
private record BlockDrop(String drops, int percentage) {
|
||||
}
|
||||
|
||||
public CustomAnnotationHandler(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
@ -28,7 +29,11 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
if (clazz.isAnnotationPresent(PlaceOnSolid.class)) {
|
||||
place = placeOnSolid(game, x, y);
|
||||
}
|
||||
|
||||
|
||||
if (place && clazz.isAnnotationPresent(Farmable.class)) {
|
||||
place = placeFarmable(game, x, y);
|
||||
}
|
||||
|
||||
if (place && clazz.isAnnotationPresent(TwoblockBlock.class)) {
|
||||
var blocksTop = game.getWorld()[y - 1][x];
|
||||
if (!blocksTop.stream().allMatch(block -> block.getBlockId().equals("air"))) {
|
||||
@ -53,12 +58,10 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
|
||||
inventory.decreaseItemInHand();
|
||||
|
||||
|
||||
customPlace = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (!customPlace && place) {
|
||||
return defaultPlaceHandler.place(game, x, y);
|
||||
}
|
||||
@ -72,19 +75,27 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
resetDataOnMine(game, x, y);
|
||||
}
|
||||
|
||||
if (clazz.isAnnotationPresent(ResetSpriteStateOnMine.class)) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
|
||||
var blockx = blocks.stream().filter(block -> !block.getBlockId().equals("air")).findFirst().get();
|
||||
blockx.setSpriteState();
|
||||
}
|
||||
|
||||
boolean dropDefault = true;
|
||||
|
||||
if (clazz.isAnnotationPresent(CustomDrops.class) || clazz.isAnnotationPresent(CustomDrop.class)) {
|
||||
var annotations = clazz.isAnnotationPresent(CustomDrops.class) ?
|
||||
clazz.getAnnotation(CustomDrops.class).value() :
|
||||
new CustomDrop[] { clazz.getAnnotation(CustomDrop.class) };
|
||||
var annotations = clazz.isAnnotationPresent(CustomDrops.class)
|
||||
? clazz.getAnnotation(CustomDrops.class).value()
|
||||
: new CustomDrop[] { clazz.getAnnotation(CustomDrop.class) };
|
||||
|
||||
var hashmap = new HashMap<String, BlockDrop>();
|
||||
for (CustomDrop customDrop : annotations) {
|
||||
hashmap.put(customDrop.tool(), new BlockDrop(customDrop.drops(), customDrop.percentage()));
|
||||
}
|
||||
|
||||
if (game.getInventory().getItemInHand().isPresent() && hashmap.containsKey(game.getInventory().getItemInHand().get().getId())) {
|
||||
if (game.getInventory().getItemInHand().isPresent()
|
||||
&& hashmap.containsKey(game.getInventory().getItemInHand().get().getId())) {
|
||||
BlockDrop blockDrop = hashmap.get(game.getInventory().getItemInHand().get().getId());
|
||||
Random random = new Random();
|
||||
int num = random.nextInt(100);
|
||||
@ -103,10 +114,12 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
if (clazz.isAnnotationPresent(TwoblockBlock.class)) {
|
||||
var blocksTop = game.getWorld()[y - 1][x];
|
||||
if (blocksTop.stream().anyMatch(i -> !i.getBlockId().equals("air") && !i.isMob())) {
|
||||
blocksTop.removeAll(blocksTop.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
||||
blocksTop.removeAll(
|
||||
blocksTop.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
||||
} else {
|
||||
var blocksBottom = game.getWorld()[y + 1][x];
|
||||
blocksBottom.removeAll(blocksBottom.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
||||
blocksBottom.removeAll(
|
||||
blocksBottom.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,6 +146,17 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean placeFarmable(Game game, int x, int y) {
|
||||
var blocksBottom = game.getWorld()[y + 1][x];
|
||||
System.out.println("lol");
|
||||
|
||||
if (blocksBottom.stream().noneMatch(block -> block.getBlockId().equals("farmland"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void resetDataOnMine(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x].stream().filter(i -> !i.getBlockId().equals("air")).toList();
|
||||
|
||||
@ -145,8 +169,9 @@ public class CustomAnnotationHandler implements CustomPlaceHandler {
|
||||
Constructor<?> constructor = block.getData().getClass().getDeclaredConstructor();
|
||||
Object object = constructor.newInstance();
|
||||
block.setData(object);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
|
||||
InvocationTargetException _) {
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException
|
||||
| InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,15 +59,15 @@ public class PlaceHandler {
|
||||
for (Class<?> clazz : blocks) {
|
||||
var annotation = clazz.getAnnotation(BlockRegistry.class);
|
||||
var id = annotation.value();
|
||||
if (clazz.isAnnotationPresent(PlaceOnSolid.class) || clazz.isAnnotationPresent(ResetDataOnMine.class) || clazz.isAnnotationPresent(BlockDropPercentage.class) || clazz.isAnnotationPresent(CustomDrops.class) || clazz.isAnnotationPresent(CustomDrop.class)) {
|
||||
try {
|
||||
placeHandlerList.put(id, new CustomAnnotationHandler(clazz));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (clazz.isAnnotationPresent(PlaceOnSolid.class) || clazz.isAnnotationPresent(ResetDataOnMine.class)
|
||||
|| clazz.isAnnotationPresent(BlockDropPercentage.class)
|
||||
|| clazz.isAnnotationPresent(CustomDrops.class) || clazz.isAnnotationPresent(CustomDrop.class)
|
||||
|| clazz.isAnnotationPresent(TwoblockBlock.class) || clazz.isAnnotationPresent(ResetSpriteStateOnMine.class)) {
|
||||
placeHandlerList.put(id, new CustomAnnotationHandler(clazz));
|
||||
}
|
||||
|
||||
if (clazz.isAnnotationPresent(PlaceOnSolid.class) || clazz.isAnnotationPresent(PlaceOnSolidNoHandler.class)) {
|
||||
if (clazz.isAnnotationPresent(PlaceOnSolid.class)
|
||||
|| clazz.isAnnotationPresent(PlaceOnSolidNoHandler.class)) {
|
||||
placeOnSolid.add(id);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
package cz.jzitnik.game.logic.services.farmable;
|
||||
|
||||
public class FarmableData {
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FarmableData {
|
||||
private int age = 0;
|
||||
private int state = 0;
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
package cz.jzitnik.game.logic.services.farmable;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.annotations.CustomLogic;
|
||||
import cz.jzitnik.game.annotations.Farmable;
|
||||
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||
|
||||
@CustomLogic
|
||||
public class FarmableLogic implements CustomLogicInterface {
|
||||
private static int RADIUS = 50;
|
||||
private static int GROW_LENGTH = 5;
|
||||
|
||||
@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 y = startY; y <= endY; y++) {
|
||||
for (int x = startX; x <= endX; x++) {
|
||||
var blocks = world[y][x];
|
||||
|
||||
var farmable = blocks.stream().filter(block -> block.getClass().isAnnotationPresent(Farmable.class)).findFirst();
|
||||
|
||||
if (farmable.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var farmableBlock = farmable.get();
|
||||
var farmableData = (FarmableData) farmableBlock.getData();
|
||||
|
||||
if (farmableData.getAge() >= GROW_LENGTH) {
|
||||
if (farmableData.getState() >= 2) {
|
||||
// Fully grown
|
||||
continue;
|
||||
}
|
||||
|
||||
farmableData.setState(farmableData.getState() + 1);
|
||||
farmableData.setAge(0);
|
||||
farmableBlock.setSpriteState(cz.jzitnik.game.sprites.Farmable.getState(farmableData.getState()));
|
||||
} else {
|
||||
farmableData.setAge(farmableData.getAge() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package cz.jzitnik.game.logic.services.farmland;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.annotations.CustomLogic;
|
||||
import cz.jzitnik.game.annotations.Farmable;
|
||||
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||
import cz.jzitnik.game.sprites.Farmland.FarmlandState;
|
||||
@ -69,6 +70,8 @@ public class FarmlandLogic implements CustomLogicInterface {
|
||||
if (farmlandData.getDryAge() >= DRY_TO_DIRT_THRESHOLD) {
|
||||
blocks.remove(farmland);
|
||||
blocks.add(ItemBlockSupplier.getBlock("dirt"));
|
||||
|
||||
world[y-1][x].removeIf(block -> block.getClass().isAnnotationPresent(Farmable.class));
|
||||
farmlandData.setDryAge(0);
|
||||
}
|
||||
} else {
|
||||
|
49
src/main/java/cz/jzitnik/game/sprites/Farmable.java
Normal file
49
src/main/java/cz/jzitnik/game/sprites/Farmable.java
Normal file
@ -0,0 +1,49 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class Farmable extends Sprite {
|
||||
private String[] textures;
|
||||
|
||||
public Farmable(String first, String second, String third) {
|
||||
textures = new String[] {first, second, third};
|
||||
}
|
||||
|
||||
|
||||
public enum FarmableState {
|
||||
FIRST,
|
||||
SECOND,
|
||||
THIRD
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
return getSprite(getState(0));
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
return ResourceLoader.loadResource(textures[switch (e) {
|
||||
case FarmableState.FIRST -> 0;
|
||||
case FarmableState.SECOND -> 1;
|
||||
case FarmableState.THIRD -> 2;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}]);
|
||||
}
|
||||
|
||||
public static FarmableState getState(int num) {
|
||||
return switch (num) {
|
||||
case 0 -> FarmableState.FIRST;
|
||||
case 1 -> FarmableState.SECOND;
|
||||
case 2 -> FarmableState.THIRD;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + num);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Class<FarmableState>> getStates() {
|
||||
return Optional.of(FarmableState.class);
|
||||
}
|
||||
}
|
@ -7,5 +7,5 @@ public abstract class Sprite<E extends Enum<E>> {
|
||||
|
||||
public abstract String getSprite(E key);
|
||||
|
||||
public abstract Optional<Class<Enum>> getStates();
|
||||
public abstract Optional<Class<E>> getStates();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user