diff --git a/src/main/java/cz/jzitnik/game/Block.java b/src/main/java/cz/jzitnik/game/Block.java index dbf2bea..347b76d 100644 --- a/src/main/java/cz/jzitnik/game/Block.java +++ b/src/main/java/cz/jzitnik/game/Block.java @@ -3,6 +3,7 @@ package cz.jzitnik.game; import cz.jzitnik.game.items.Item; import cz.jzitnik.game.items.ItemType; import cz.jzitnik.game.items.ToolVariant; +import cz.jzitnik.game.ui.Inventory; import lombok.Getter; import lombok.Setter; diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index a415598..1f96162 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -4,6 +4,7 @@ import cz.jzitnik.game.items.Item; import cz.jzitnik.game.items.ItemType; import cz.jzitnik.game.sprites.Breaking; import cz.jzitnik.game.sprites.Window; +import cz.jzitnik.game.ui.Inventory; import cz.jzitnik.tui.ScreenMovingCalculationProvider; import cz.jzitnik.tui.ScreenRenderer; import lombok.Getter; diff --git a/src/main/java/cz/jzitnik/game/Generation.java b/src/main/java/cz/jzitnik/game/Generation.java index ad62045..02aced8 100644 --- a/src/main/java/cz/jzitnik/game/Generation.java +++ b/src/main/java/cz/jzitnik/game/Generation.java @@ -1,36 +1,14 @@ package cz.jzitnik.game; import cz.jzitnik.game.items.Item; +import cz.jzitnik.game.items.ItemBlockGenerator; import cz.jzitnik.game.items.ItemType; -import cz.jzitnik.game.items.ToolVariant; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Random; public class Generation { - public static Block dirt() { - var block = new Block("dirt", SpriteLoader.SPRITES.DIRT, 1, ItemType.SHOVEL, new ArrayList<>()); - block.setDrops(List.of(new Item("dirt", "Dirt block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, block))); - return block; - } - private static Block grass() { - var block = new Block("grass", SpriteLoader.SPRITES.GRASS, 1, ItemType.SHOVEL, new ArrayList<>()); - block.setDrops(List.of(new Item("dirt", "Dirt block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, dirt()))); - return block; - } - private static Block stone() { - var block = new Block("stone", SpriteLoader.SPRITES.STONE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList()); - block.setDrops(List.of(new Item("stone", "Stone block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, block))); - return block; - } - private static Block oakLog() { - var block = new Block("oak_log", SpriteLoader.SPRITES.OAK_LOG, 3, ItemType.AXE, new ArrayList<>()); - block.setDrops(List.of(new Item("oak_log", "Oak log", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_OAK_LOG, block))); - return block; - } - public static void generateWorld(Game game) { var world = game.getWorld(); initializeWorld(world); @@ -76,16 +54,16 @@ public class Generation { for (int i = 0; i < 512; i++) { int hillHeight = terrainHeight[i]; - world[hillHeight][i].add(grass()); + world[hillHeight][i].add(ItemBlockGenerator.Blocks.grass()); for (int j = 1; j <= 4; j++) { if (hillHeight + j < 256) { - world[hillHeight + j][i].add(dirt()); + world[hillHeight + j][i].add(ItemBlockGenerator.Blocks.dirt()); } } for (int j = hillHeight + 5; j < 250; j++) { - world[j][i].add(stone()); + world[j][i].add(ItemBlockGenerator.Blocks.stone()); } world[255][i].add(new Block("bedrock", SpriteLoader.SPRITES.BEDROCK)); @@ -109,7 +87,7 @@ public class Generation { for (int j = 0; j < 3; j++) { if (treeBase - j >= 0) { - world[treeBase - j - 1][i].add(oakLog()); + world[treeBase - j - 1][i].add(ItemBlockGenerator.Blocks.oakLog()); } } diff --git a/src/main/java/cz/jzitnik/game/MouseHandler.java b/src/main/java/cz/jzitnik/game/MouseHandler.java index e030090..4cdc15e 100644 --- a/src/main/java/cz/jzitnik/game/MouseHandler.java +++ b/src/main/java/cz/jzitnik/game/MouseHandler.java @@ -37,6 +37,7 @@ public class MouseHandler { scroll(mouseEvent); } } + private void scroll(MouseEvent mouseEvent) { } diff --git a/src/main/java/cz/jzitnik/game/crafting/CraftingRecipe.java b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipe.java new file mode 100644 index 0000000..5b73073 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipe.java @@ -0,0 +1,12 @@ +package cz.jzitnik.game.crafting; + +import cz.jzitnik.game.items.Item; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public class CraftingRecipe { + private String[] recipe; + private Item item; +} diff --git a/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java new file mode 100644 index 0000000..d1ae117 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/crafting/CraftingRecipeList.java @@ -0,0 +1,7 @@ +package cz.jzitnik.game.crafting; + +import java.util.List; + +public class CraftingRecipeList { + private List recipes; +} diff --git a/src/main/java/cz/jzitnik/game/items/ItemBlockGenerator.java b/src/main/java/cz/jzitnik/game/items/ItemBlockGenerator.java new file mode 100644 index 0000000..1c33987 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/items/ItemBlockGenerator.java @@ -0,0 +1,59 @@ +package cz.jzitnik.game.items; + +import cz.jzitnik.game.SpriteLoader; +import cz.jzitnik.game.Block; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ItemBlockGenerator { + // This is necessary to not get infinite recursion + private static class Helper { + public static Item dirt(Block ref) { + return new Item("dirt", "Dirt block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, ref); + } + public static Item stone(Block ref) { + return new Item("stone", "Stone block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, ref); + } + public static Item oakLog(Block ref) { + return new Item("oak_log", "Oak log", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_OAK_LOG, ref); + } + } + + public static class Blocks { + public static Block dirt() { + var block = new Block("dirt", SpriteLoader.SPRITES.DIRT, 1, ItemType.SHOVEL, new ArrayList<>()); + block.setDrops(List.of(Helper.dirt(block))); + return block; + } + public static Block grass() { + var block = new Block("grass", SpriteLoader.SPRITES.GRASS, 1, ItemType.SHOVEL, new ArrayList<>()); + block.setDrops(List.of(Items.dirt())); + return block; + } + public static Block stone() { + var block = new Block("stone", SpriteLoader.SPRITES.STONE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList()); + block.setDrops(List.of(Helper.stone(block))); + return block; + } + public static Block oakLog() { + var block = new Block("oak_log", SpriteLoader.SPRITES.OAK_LOG, 3, ItemType.AXE, new ArrayList<>()); + block.setDrops(List.of(Helper.oakLog(block))); + return block; + } + } + + // I hate this but whatever + public static class Items { + public static Item dirt() { + return Helper.dirt(Blocks.dirt()); + } + public static Item stone() { + return Helper.stone(Blocks.stone()); + } + public static Item oakLog() { + return Helper.stone(Blocks.stone()); + } + } +} diff --git a/src/main/java/cz/jzitnik/game/Inventory.java b/src/main/java/cz/jzitnik/game/ui/Inventory.java similarity index 73% rename from src/main/java/cz/jzitnik/game/Inventory.java rename to src/main/java/cz/jzitnik/game/ui/Inventory.java index 9d7eda5..9e1a37a 100644 --- a/src/main/java/cz/jzitnik/game/Inventory.java +++ b/src/main/java/cz/jzitnik/game/ui/Inventory.java @@ -1,5 +1,6 @@ -package cz.jzitnik.game; +package cz.jzitnik.game.ui; +import cz.jzitnik.game.Game; import cz.jzitnik.game.items.InventoryItem; import cz.jzitnik.game.items.Item; import cz.jzitnik.tui.ScreenRenderer; @@ -23,6 +24,7 @@ public class Inventory { private InventoryItem[] items = new InventoryItem[20]; private InventoryItem[] hotbar = new InventoryItem[9]; + private SmallCraftingTable smallCraftingTable = new SmallCraftingTable( this); @Setter private int itemInhHandIndex = 0; @@ -147,34 +149,7 @@ public class Inventory { int termWidth = terminal.getWidth(); int startLeft = (termWidth / 2) - (INVENTORY_SIZE_PX / 2); - List sprites = new ArrayList<>(); - - for (int i = 0; i < hotbar.length; i++) { - var item = hotbar[i]; - - if (item == null) { - if (i == itemInhHandIndex && !isFull) { - sprites.add(getHotbarBackground()); - continue; - } - - sprites.add(null); - continue; - } - - if (i == (isFull ? selectedItemInv - 20 : itemInhHandIndex)) { - sprites.add(SpriteCombiner.combineTwoSprites(getHotbarBackground(), SpriteCombiner.combineTwoSprites( - spriteList.getSprite(item.getItem().getSprite()).getSprite(), - getNumberSprite(item.getAmount()) - ))); - continue; - } - - sprites.add(SpriteCombiner.combineTwoSprites( - spriteList.getSprite(item.getItem().getSprite()).getSprite(), - getNumberSprite(item.getAmount()) - )); - } + List sprites = getSprites(hotbar, spriteList, (isFull ? selectedItemInv - 20 : itemInhHandIndex)); for (int i = 0; i < 26; i++) { // Empty left space @@ -206,34 +181,7 @@ public class Inventory { int moveLeft = (terminal.getWidth() / 2) - (widthPixels / 2); int moveTop = (terminal.getHeight() / 2) - (heightPixels / 2); - List sprites = new ArrayList<>(); - - for (int i = 0; i < items.length; i++) { - var item = items[i]; - - if (item == null) { - if (i == selectedItemInv) { - sprites.add(getHotbarBackground()); - continue; - } - - sprites.add(null); - continue; - } - - if (i == selectedItemInv) { - sprites.add(SpriteCombiner.combineTwoSprites(getHotbarBackground(), SpriteCombiner.combineTwoSprites( - spriteList.getSprite(item.getItem().getSprite()).getSprite(), - getNumberSprite(item.getAmount()) - ))); - continue; - } - - sprites.add(SpriteCombiner.combineTwoSprites( - spriteList.getSprite(item.getItem().getSprite()).getSprite(), - getNumberSprite(item.getAmount()) - )); - } + List sprites = getSprites(items, spriteList, selectedItemInv); // Top center buffer.append("\n".repeat(Math.max(0, moveTop))); @@ -241,28 +189,46 @@ public class Inventory { buffer.append("\033[0m ".repeat(moveLeft)); buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)).append("\033[0m\n"); + String[] craftingTable = smallCraftingTable.render(spriteList).toString().split("\n"); + int spacesFromTop = (ROW_AMOUNT - SmallCraftingTable.ROW_AMOUNT) / 2; for (int i = 0; i < ROW_AMOUNT; i++) { - for (int j = 0; j < 25; j++) { + for (int j = 0; j < 26; j++) { buffer.append("\033[0m ".repeat(moveLeft)); - buffer.append("\033[38;5;231;48;5;231m▓"); - for (int k = 0; k < COLUMN_AMOUNT; k++) { - buffer.append("\033[38;5;231;48;5;231m▓".repeat(2)); - var item = items[i * COLUMN_AMOUNT + k]; - if (item == null) { - buffer.append("\033[0m ".repeat(50)); + if (j < 25) { + buffer.append("\033[38;5;231;48;5;231m▓"); + for (int k = 0; k < COLUMN_AMOUNT; k++) { + buffer.append("\033[38;5;231;48;5;231m▓".repeat(2)); + var item = items[i * COLUMN_AMOUNT + k]; + if (item == null) { + buffer.append("\033[0m ".repeat(50)); + buffer.append("\033[38;5;231;48;5;231m▓".repeat(2)); + continue; + } + var sprite = sprites.get(i * COLUMN_AMOUNT + k).split("\n"); + buffer.append(sprite[j]); buffer.append("\033[38;5;231;48;5;231m▓".repeat(2)); - continue; } - var sprite = sprites.get(i * COLUMN_AMOUNT + k).split("\n"); - buffer.append(sprite[j]); - buffer.append("\033[38;5;231;48;5;231m▓".repeat(2)); + buffer.append("\033[38;5;231;48;5;231m▓"); + } else { + buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)); + if (i == 0) { + buffer.append("\033[0m").append(" ".repeat(20)); + buffer.append("\033[38;5;231;48;5;231m▓".repeat(106)); + } } - buffer.append("\033[38;5;231;48;5;231m▓"); + + if (i + 1 > spacesFromTop) { + int craftingIndex = ((i - spacesFromTop) * 26) + j; + + if (craftingIndex >= 0 && craftingIndex < craftingTable.length) { + buffer.append("\033[0m").append(" ".repeat(20)); + buffer.append(craftingTable[craftingIndex]); + } + } + buffer.append("\n"); } - buffer.append("\033[0m ".repeat(moveLeft)); - buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)).append("\n"); } buffer.append("\n".repeat(10)); @@ -290,17 +256,19 @@ public class Inventory { int startLeftHotbar = (terminal.getWidth() / 2) - (INVENTORY_SIZE_PX / 2); int startTopHotbar = moveTop + heightPixels + 10; + int startLeftCrafting = moveLeft + widthPixels + 20; + int startTopCrafting = moveTop + 26; + + if (x >= startLeftCrafting && y >= startTopCrafting && y <= startTopCrafting + 52 && x <= startLeftCrafting + 106 + 54 + 7) { + smallCraftingTable.click(mouseEvent.getX() - startLeftCrafting, mouseEvent.getY() - startTopCrafting); + screenRenderer.render(game); + return; + } + if (x >= startLeftHotbar && y >= startTopHotbar && x <= startLeftHotbar + INVENTORY_SIZE_PX && y <= startTopHotbar + 26) { int index = (x - startLeftHotbar) / 51; if (hotbar[index] == null && selectedItemInv != -1) { - if (selectedItemInv < 20) { - hotbar[index] = items[selectedItemInv]; - items[selectedItemInv] = null; - } else { - int in = selectedItemInv - 20; - hotbar[index] = hotbar[in]; - hotbar[in] = null; - } + hotbar[index] = getSelectedItem(); } else if (hotbar[index] != null) { selectedItemInv = 20 + index; } @@ -319,22 +287,68 @@ public class Inventory { int blockY = fy / 26; InventoryItem inventoryItem = items[blockY * COLUMN_AMOUNT + blockX]; - if (inventoryItem != null) { - selectedItemInv = blockY * COLUMN_AMOUNT + blockX; - } - if (inventoryItem == null && selectedItemInv != -1) { - if (selectedItemInv < 20) { - items[blockY * COLUMN_AMOUNT + blockX] = items[selectedItemInv]; - items[selectedItemInv] = null; - } else { - int index = selectedItemInv - 20; - items[blockY * COLUMN_AMOUNT + blockX] = hotbar[index]; - hotbar[index] = null; - } - } + if (inventoryItem != null) { + selectedItemInv = blockY * COLUMN_AMOUNT + blockX; + } + if (inventoryItem == null && selectedItemInv != -1) { + items[blockY * COLUMN_AMOUNT + blockX] = getSelectedItem(); + } } } screenRenderer.render(game); } + + public List getSprites(InventoryItem[] items, SpriteList spriteList, int selectedItem) { + List sprites = new ArrayList<>(); + + for (int i = 0; i < items.length; i++) { + var item = items[i]; + + if (item == null) { + if (i == selectedItem) { + sprites.add(getHotbarBackground()); + continue; + } + + sprites.add(null); + continue; + } + + if (i == selectedItem) { + sprites.add(SpriteCombiner.combineTwoSprites(getHotbarBackground(), SpriteCombiner.combineTwoSprites( + spriteList.getSprite(item.getItem().getSprite()).getSprite(), + getNumberSprite(item.getAmount()) + ))); + continue; + } + + sprites.add(SpriteCombiner.combineTwoSprites( + spriteList.getSprite(item.getItem().getSprite()).getSprite(), + getNumberSprite(item.getAmount()) + )); + } + + return sprites; + } + + public InventoryItem getSelectedItem() { + InventoryItem temp; + if (selectedItemInv < 20) { + temp = items[selectedItemInv]; + items[selectedItemInv] = null; + } else if (selectedItemInv >= 29) { + int index = selectedItemInv - 29; + temp = smallCraftingTable.getItems()[index]; + smallCraftingTable.getItems()[index] = null; + } else { + int index = selectedItemInv - 20; + temp = hotbar[index]; + hotbar[index] = null; + } + + selectedItemInv = -1; + + return temp; + } } diff --git a/src/main/java/cz/jzitnik/game/ui/SmallCraftingTable.java b/src/main/java/cz/jzitnik/game/ui/SmallCraftingTable.java new file mode 100644 index 0000000..67ae7fd --- /dev/null +++ b/src/main/java/cz/jzitnik/game/ui/SmallCraftingTable.java @@ -0,0 +1,102 @@ +package cz.jzitnik.game.ui; + +import cz.jzitnik.game.Generation; +import cz.jzitnik.game.SpriteLoader; +import cz.jzitnik.game.items.InventoryItem; +import cz.jzitnik.game.items.Item; +import cz.jzitnik.game.items.ItemBlockGenerator; +import cz.jzitnik.game.items.ItemType; +import cz.jzitnik.tui.SpriteList; +import lombok.Getter; + +import java.util.List; +import java.util.Optional; + +public class SmallCraftingTable { + public static final int ROW_AMOUNT = 2; + public static final int COLUMN_AMOUNT = 2; + + private Inventory inventory; + @Getter + private InventoryItem[] items = new InventoryItem[4]; + + public void click(int x, int y) { + if (x > 106) { + if (y > 10 && y < 37) { + // Pickup item from crafting table + + return; + } + + return; + } + + int blockX = x / 53; + int blockY = y / 26; + + int blockIndex = blockY * COLUMN_AMOUNT + blockX; + + if (items[blockIndex] == null && inventory.getSelectedItemInv() != -1) { + items[blockIndex] = inventory.getSelectedItem(); + } else if (items[blockIndex] != null) { + inventory.setSelectedItemInv(blockIndex + 29); + } + } + + public StringBuilder render(SpriteList spriteList) { + var buf = new StringBuilder(); + + List sprites = inventory.getSprites(items, spriteList, inventory.getSelectedItemInv() - 29); + + Optional craftedItem = Optional.of(ItemBlockGenerator.Items.dirt()); + + String[] craftedSprite = craftedItem.isPresent() ? spriteList.getSprite(craftedItem.get().getSprite()).getSprite().split("\n") : null; + + int counter = 0; + for (int i = 0; i < ROW_AMOUNT; i++) { + for (int j = 0; j < 26; j++) { + if (j == 25) { + buf.append("\033[38;5;231;48;5;231m▓".repeat(106)); + } else { + for (int k = 0; k < COLUMN_AMOUNT; k++) { + buf.append("\033[38;5;231;48;5;231m▓".repeat(2)); + String sprite = sprites.get(i * 2 + k); + if (sprite == null) { + buf.append("\033[0m ".repeat(50)); + } else { + String[] spriteLines = sprite.split("\n"); + buf.append(spriteLines[j]); + } + } + buf.append("\033[38;5;231;48;5;231m▓".repeat(2)); + } + + if (i == 0 && j > 10 || i == 1 && j < 12) { + buf.append("\033[0m").append(" ".repeat(7)); + if (i == 0 && j - 11 == 0 || i == 1 && j == 11) { + buf.append("\033[38;5;231;48;5;231m▓".repeat(54)); + } else { + buf.append("\033[38;5;231;48;5;231m▓".repeat(2)); + if (craftedItem.isEmpty()) { + buf.append("\033[0m ".repeat(50)); + } else { + buf.append(craftedSprite[counter]); + counter++; + } + buf.append("\033[38;5;231;48;5;231m▓".repeat(2)); + } + } + + buf.append("\n"); + } + } + + buf.append("\033[0m"); + + return buf; + } + + public SmallCraftingTable(Inventory inventory) { + this.inventory = inventory; + } +}