diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index 804b4f3..ac5247d 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -23,6 +23,7 @@ import lombok.Setter; import org.jline.terminal.Terminal; import java.util.List; +import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; @Getter @@ -339,6 +340,13 @@ public class Game { return; } + if (inventory.getItemInHand().isPresent() && inventory.getItemInHand().get().getType() == ItemType.PICKUPER) { + if (gameStates.dependencies.pickupHandlerProvider.get(inventory.getItemInHand().get().getId()).handle(this, x, y)) { + screenRenderer.render(this); + }; + return; + } + if (!blocks.stream().allMatch(block -> block.getBlockId().equals("air") || block.isFlowing())) { RightClickHandlerProvider.handle(x, y, this, screenRenderer); screenRenderer.render(this); diff --git a/src/main/java/cz/jzitnik/game/annotations/ItemRegistry.java b/src/main/java/cz/jzitnik/game/annotations/ItemRegistry.java index a66f144..78d2edd 100644 --- a/src/main/java/cz/jzitnik/game/annotations/ItemRegistry.java +++ b/src/main/java/cz/jzitnik/game/annotations/ItemRegistry.java @@ -9,4 +9,5 @@ import java.lang.annotation.ElementType; @Target(ElementType.TYPE) public @interface ItemRegistry { String value(); + String block() default ""; } diff --git a/src/main/java/cz/jzitnik/game/entities/items/ItemBlockSupplier.java b/src/main/java/cz/jzitnik/game/entities/items/ItemBlockSupplier.java index 6aa96ab..40d93a1 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/ItemBlockSupplier.java +++ b/src/main/java/cz/jzitnik/game/entities/items/ItemBlockSupplier.java @@ -8,16 +8,14 @@ import org.reflections.Reflections; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Optional; -import java.util.Set; -import java.util.List; +import java.util.*; public class ItemBlockSupplier { private static final HashMap> registeredBlocks = new HashMap<>(); private static final HashMap> registeredItems = new HashMap<>(); private static final HashMap> registeredEntities = new HashMap<>(); private static final HashMap dropsList = new HashMap<>(); + private static final HashMap blockList = new HashMap<>(); static { registerItems(); @@ -67,23 +65,35 @@ public class ItemBlockSupplier { Constructor itemInstance = (Constructor) clazz.getDeclaredConstructor(); ItemRegistry annotation = clazz.getAnnotation(ItemRegistry.class); registeredItems.put(annotation.value(), itemInstance); + + blockList.put(annotation.value(), annotation.block().isEmpty() ? annotation.value() : annotation.block()); } catch (Exception e) { e.printStackTrace(); } } } + public static Block getBlock(String key, Item item) { + try { + Block block = registeredBlocks.get(key).newInstance(); + + if (dropsList.get(key).equals(item.getId())) { + block.setDrops(List.of(item)); + } else { + block.setDrops(List.of(getItem(dropsList.get(key), block))); // Todo: Add block reference + } + + return block; + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + public static Block getBlock(String key) { try { Block block = registeredBlocks.get(key).newInstance(); - String dropKey = dropsList.get(key); - - if (dropKey != null && registeredItems.containsKey(dropKey)) { - Item dropItem = getItem(dropKey); - if (dropKey.equals(block.getBlockId())) { - dropItem.setBlock(Optional.of(block)); - } - block.setDrops(List.of(dropItem)); + if (registeredItems.containsKey(dropsList.get(key))) { + block.setDrops(List.of(getItem(dropsList.get(key), block))); } return block; @@ -95,11 +105,26 @@ public class ItemBlockSupplier { public static Item getItem(String key) { try { Item item = registeredItems.get(key).newInstance(); - if (registeredBlocks.containsKey(key)) { - Block block = registeredBlocks.get(key).newInstance(); - item.setBlock(Optional.of(block)); - block.setDrops(List.of(item)); + if (registeredBlocks.containsKey(blockList.get(key))) { + item.setBlock(Optional.of(getBlock(dropsList.get(key), item))); } + + return item; + } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static Item getItem(String key, Block block) { + try { + Item item = registeredItems.get(key).newInstance(); + + if (blockList.get(key).equals(block.getBlockId())) { + item.setBlock(Optional.of(block)); + } else { + item.setBlock(Optional.of(getBlock(blockList.get(key), item))); + } + return item; } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); diff --git a/src/main/java/cz/jzitnik/game/entities/items/ItemType.java b/src/main/java/cz/jzitnik/game/entities/items/ItemType.java index 9af2a77..78c452c 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/ItemType.java +++ b/src/main/java/cz/jzitnik/game/entities/items/ItemType.java @@ -10,4 +10,5 @@ public enum ItemType { USELESS_ITEM, HOE, SWORD, + PICKUPER } diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/WaterBlock.java b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/WaterBlock.java index c7ea153..483d168 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/WaterBlock.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/blocks/WaterBlock.java @@ -6,7 +6,7 @@ import cz.jzitnik.game.entities.Block; import cz.jzitnik.game.logic.services.water.WaterData; import cz.jzitnik.game.sprites.Water; -@BlockRegistry(value = "water", drops = "water_item") +@BlockRegistry(value = "water", drops = "water_bucket") public class WaterBlock extends Block { public WaterBlock() { super("water", SpriteLoader.SPRITES.WATER); diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/items/BucketItem.java b/src/main/java/cz/jzitnik/game/entities/items/registry/items/BucketItem.java index 3efd230..378350c 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/items/BucketItem.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/items/BucketItem.java @@ -8,6 +8,6 @@ import cz.jzitnik.game.entities.items.ItemType; @ItemRegistry("bucket") public class BucketItem extends Item { public BucketItem() { - super("bucket", "Bucket", ItemType.USELESS_ITEM, SpriteLoader.SPRITES.BUCKET); + super("bucket", "Bucket", ItemType.PICKUPER, SpriteLoader.SPRITES.BUCKET); } } diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/items/LavaBucketItem.java b/src/main/java/cz/jzitnik/game/entities/items/registry/items/LavaBucketItem.java index 7442442..a721c10 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/items/LavaBucketItem.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/items/LavaBucketItem.java @@ -8,6 +8,7 @@ import cz.jzitnik.game.entities.items.ItemType; @ItemRegistry("lava_bucket") public class LavaBucketItem extends Item { public LavaBucketItem() { - super("lava_bucket", "Lava bucket", ItemType.USELESS_ITEM, SpriteLoader.SPRITES.LAVA_BUCKET); + super("lava_bucket", "Lava bucket", ItemType.PICKUPER, SpriteLoader.SPRITES.LAVA_BUCKET); + setStackable(false); } } diff --git a/src/main/java/cz/jzitnik/game/entities/items/registry/items/WaterBucketItem.java b/src/main/java/cz/jzitnik/game/entities/items/registry/items/WaterBucketItem.java index 6e3c909..e074db4 100644 --- a/src/main/java/cz/jzitnik/game/entities/items/registry/items/WaterBucketItem.java +++ b/src/main/java/cz/jzitnik/game/entities/items/registry/items/WaterBucketItem.java @@ -5,9 +5,10 @@ import cz.jzitnik.game.annotations.ItemRegistry; import cz.jzitnik.game.entities.items.Item; import cz.jzitnik.game.entities.items.ItemType; -@ItemRegistry("water_bucket") +@ItemRegistry(value = "water_bucket", block = "water") public class WaterBucketItem extends Item { public WaterBucketItem() { - super("water_bucket", "Water bucket", ItemType.USELESS_ITEM, SpriteLoader.SPRITES.WATER_BUCKET); + super("water_bucket", "Water bucket", ItemType.PICKUPER, SpriteLoader.SPRITES.WATER_BUCKET); + setStackable(false); } } diff --git a/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/BucketPickupHandler.java b/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/BucketPickupHandler.java new file mode 100644 index 0000000..5d0458b --- /dev/null +++ b/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/BucketPickupHandler.java @@ -0,0 +1,42 @@ +package cz.jzitnik.game.handlers.pickup.handlers; + +import cz.jzitnik.game.Game; +import cz.jzitnik.game.annotations.PickupHandler; +import cz.jzitnik.game.entities.Block; +import cz.jzitnik.game.entities.items.Item; +import cz.jzitnik.game.handlers.pickup.CustomPickupHandler; +import cz.jzitnik.game.logic.services.water.FlowingData; + +import java.util.List; + +@PickupHandler("bucket") +public class BucketPickupHandler implements CustomPickupHandler { + private List returnItem(List blocks) { + var block = blocks.stream().filter(Block::isFlowing).findFirst().get(); + + return block.getDrops(); + } + + @Override + public boolean handle(Game game, int x, int y) { + var world = game.getWorld(); + var blockOptional = game.getWorld()[y][x].stream().filter(Block::isFlowing).findFirst(); + if (blockOptional.isEmpty()) { + return false; + } + + var block = blockOptional.get(); + if (!((FlowingData) block.getData()).isSource()) { + return false; + } + + var returnItems = returnItem(world[y][x]); + + game.getInventory().decreaseItemInHand(); + game.getInventory().addItem(returnItems); + + world[y][x].remove(world[y][x].stream().filter(Block::isFlowing).findFirst().get()); + + return true; + } +} diff --git a/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/FullBuckerPickupHandler.java b/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/FullBuckerPickupHandler.java new file mode 100644 index 0000000..2c1fed2 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/FullBuckerPickupHandler.java @@ -0,0 +1,33 @@ +package cz.jzitnik.game.handlers.pickup.handlers; + +import cz.jzitnik.game.Game; +import cz.jzitnik.game.annotations.PickupHandler; +import cz.jzitnik.game.entities.Block; +import cz.jzitnik.game.entities.items.ItemBlockSupplier; +import cz.jzitnik.game.handlers.pickup.CustomPickupHandler; + +@PickupHandler("water_bucket,lava_bucket") +public class FullBuckerPickupHandler implements CustomPickupHandler { + + @Override + public boolean handle(Game game, int x, int y) { + var world = game.getWorld(); + var inventory = game.getInventory(); + + if (world[y][x].stream().anyMatch(block -> !block.getBlockId().equals("air"))) { + return false; + } + + if (world[y][x].stream().anyMatch(Block::isFlowing)) { + return true; + } + + world[y][x].add(inventory.getItemInHand().get().getBlock().get()); + + inventory.decreaseItemInHand(); + + inventory.addItem(ItemBlockSupplier.getItem("bucket")); + + return true; + } +} diff --git a/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/WaterPickupHandler.java b/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/WaterPickupHandler.java deleted file mode 100644 index 7f81fe0..0000000 --- a/src/main/java/cz/jzitnik/game/handlers/pickup/handlers/WaterPickupHandler.java +++ /dev/null @@ -1,14 +0,0 @@ -package cz.jzitnik.game.handlers.pickup.handlers; - -import cz.jzitnik.game.Game; -import cz.jzitnik.game.annotations.PickupHandler; -import cz.jzitnik.game.handlers.pickup.CustomPickupHandler; - -@PickupHandler("bucket,water_bucket") -public class WaterPickupHandler implements CustomPickupHandler { - - @Override - public boolean handle(Game game, int x, int y) { - return false; - } -} diff --git a/src/main/java/cz/jzitnik/game/logic/services/water/FlowingData.java b/src/main/java/cz/jzitnik/game/logic/services/water/FlowingData.java new file mode 100644 index 0000000..20bdf8f --- /dev/null +++ b/src/main/java/cz/jzitnik/game/logic/services/water/FlowingData.java @@ -0,0 +1,10 @@ +package cz.jzitnik.game.logic.services.water; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class FlowingData { + protected boolean isSource = true; +} diff --git a/src/main/java/cz/jzitnik/game/logic/services/water/WaterData.java b/src/main/java/cz/jzitnik/game/logic/services/water/WaterData.java index 2f7fe31..562c57c 100644 --- a/src/main/java/cz/jzitnik/game/logic/services/water/WaterData.java +++ b/src/main/java/cz/jzitnik/game/logic/services/water/WaterData.java @@ -1,10 +1,3 @@ package cz.jzitnik.game.logic.services.water; -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class WaterData { - private boolean isSource = true; -} +public class WaterData extends FlowingData {} diff --git a/src/main/java/cz/jzitnik/game/ui/Inventory.java b/src/main/java/cz/jzitnik/game/ui/Inventory.java index 89ae233..0a89a1e 100644 --- a/src/main/java/cz/jzitnik/game/ui/Inventory.java +++ b/src/main/java/cz/jzitnik/game/ui/Inventory.java @@ -78,6 +78,13 @@ public class Inventory { } } + public void addItem(List item) { + for (Item i : item) { + addItem(i); + } + } + + public void addItem(Item item) { if (!item.isStackable()) { placeItem(item);