forked from jzitnik/twodcraft
204 lines
7.3 KiB
Java
204 lines
7.3 KiB
Java
package cz.jzitnik.game.handlers.place;
|
|
|
|
import cz.jzitnik.game.Game;
|
|
import cz.jzitnik.game.annotations.*;
|
|
import cz.jzitnik.game.entities.Block;
|
|
import cz.jzitnik.game.entities.items.InventoryItem;
|
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
|
import cz.jzitnik.game.logic.services.farmable.FarmableData;
|
|
import cz.jzitnik.game.sprites.TwoBlockSprite;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.HashMap;
|
|
import java.util.Random;
|
|
|
|
public class CustomAnnotationHandler implements CustomPlaceHandler {
|
|
private final Class<?> clazz;
|
|
private final DefaultPlaceHandler defaultPlaceHandler = new DefaultPlaceHandler();
|
|
private final Random random = new Random();
|
|
|
|
private record BlockDrop(String drops, int percentage) {
|
|
}
|
|
|
|
public CustomAnnotationHandler(Class<?> clazz) {
|
|
this.clazz = clazz;
|
|
}
|
|
|
|
@Override
|
|
public boolean place(Game game, int x, int y) {
|
|
boolean place = true;
|
|
boolean customPlace = false;
|
|
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"))) {
|
|
place = false;
|
|
}
|
|
}
|
|
|
|
if (place && clazz.isAnnotationPresent(TwoblockBlock.class)) {
|
|
var inventory = game.getInventory();
|
|
var blocks = game.getWorld()[y][x];
|
|
var blocksTop = game.getWorld()[y - 1][x];
|
|
|
|
Block block = inventory.getItemInHand().get().getBlock().get();
|
|
block.setSpriteState(TwoBlockSprite.TwoBlockSpriteState.BOTTOM);
|
|
blocks.add(block);
|
|
blocks.removeAll(blocks.stream().filter(Block::isFlowing).toList());
|
|
|
|
Block block2 = ItemBlockSupplier.getBlock(block.getBlockId());
|
|
block2.setSpriteState(TwoBlockSprite.TwoBlockSpriteState.TOP);
|
|
blocksTop.add(block2);
|
|
blocksTop.removeAll(blocksTop.stream().filter(Block::isFlowing).toList());
|
|
|
|
inventory.decreaseItemInHand();
|
|
|
|
customPlace = true;
|
|
return true;
|
|
}
|
|
|
|
if (!customPlace && place) {
|
|
return defaultPlaceHandler.place(game, x, y);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean mine(Game game, int x, int y) {
|
|
boolean dropDefault = true;
|
|
|
|
if (clazz.isAnnotationPresent(Farmable.class)) {
|
|
var blocks = game.getWorld()[y][x];
|
|
var blockx = blocks.stream().filter(block -> !block.getBlockId().equals("air")).findFirst().get();
|
|
|
|
var data = (FarmableData) blockx.getData();
|
|
|
|
if (data.getState() == 2) {
|
|
dropDefault = false;
|
|
var annotation = clazz.getAnnotation(Farmable.class);
|
|
var growDrop = annotation.value();
|
|
var seedDrop = blockx.getDrops().get(0);
|
|
var seedDropAmount = random.nextInt(4);
|
|
|
|
if (seedDropAmount != 0) {
|
|
game.getInventory().addItem(new InventoryItem(seedDropAmount, seedDrop));
|
|
}
|
|
|
|
game.getInventory().addItem(ItemBlockSupplier.getItem(growDrop));
|
|
}
|
|
}
|
|
|
|
if (clazz.isAnnotationPresent(ResetDataOnMine.class)) {
|
|
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();
|
|
}
|
|
|
|
|
|
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 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())) {
|
|
BlockDrop blockDrop = hashmap.get(game.getInventory().getItemInHand().get().getId());
|
|
Random random = new Random();
|
|
int num = random.nextInt(100);
|
|
|
|
if (num < blockDrop.percentage) {
|
|
dropDefault = false;
|
|
game.getInventory().addItem(ItemBlockSupplier.getItem(blockDrop.drops()));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dropDefault && clazz.isAnnotationPresent(BlockDropPercentage.class)) {
|
|
dropDefault = blockDropPercentage(game, x, y);
|
|
}
|
|
|
|
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());
|
|
} else {
|
|
var blocksBottom = game.getWorld()[y + 1][x];
|
|
blocksBottom.removeAll(
|
|
blocksBottom.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
|
}
|
|
}
|
|
|
|
defaultPlaceHandler.mine(game, x, y);
|
|
|
|
return dropDefault;
|
|
}
|
|
|
|
private boolean blockDropPercentage(Game game, int x, int y) {
|
|
var annotation = clazz.getAnnotation(BlockDropPercentage.class);
|
|
int percentage = annotation.value();
|
|
|
|
Random random = new Random();
|
|
return random.nextInt(100) < percentage;
|
|
}
|
|
|
|
private boolean placeOnSolid(Game game, int x, int y) {
|
|
var blocksBottom = game.getWorld()[y + 1][x];
|
|
|
|
if (blocksBottom.stream().allMatch(Block::isGhost)) {
|
|
return false;
|
|
}
|
|
|
|
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();
|
|
|
|
for (Block block : blocks) {
|
|
if (block.getData() == null) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
Constructor<?> constructor = block.getData().getClass().getDeclaredConstructor();
|
|
Object object = constructor.newInstance();
|
|
block.setData(object);
|
|
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException
|
|
| InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|