package cz.jzitnik.game.ui; import cz.jzitnik.game.Block; import cz.jzitnik.game.Game; import cz.jzitnik.game.items.InventoryItem; import cz.jzitnik.game.items.Item; import cz.jzitnik.game.smelting.Smelting; import cz.jzitnik.tui.ScreenRenderer; import cz.jzitnik.tui.SpriteList; import cz.jzitnik.tui.utils.Numbers; import cz.jzitnik.tui.utils.SpriteCombiner; import org.jline.terminal.MouseEvent; import org.jline.terminal.Terminal; import java.util.List; import java.util.Optional; public class Furnace { private final Block block; private final InventoryItem[] items = new InventoryItem[2]; private InventoryItem outputItem; private int size; private boolean smelting; private static final int COLUMN_AMOUNT = 3; private static final int CELL_WIDTH = 50; private static final int CELL_HEIGHT = 27; private static final int BORDER_SIZE = 2; public Furnace(Block block) { this.block = block; } public void render(Game game, StringBuilder buffer, Terminal terminal, SpriteList spriteList) { int widthPixels = COLUMN_AMOUNT * (CELL_WIDTH + BORDER_SIZE) + BORDER_SIZE; var inventory = game.getInventory(); int moveLeft = (terminal.getWidth() / 2) - (widthPixels / 2); List sprites = game.getInventory().getSprites(items, spriteList, inventory.getSelectedItemInv() - 50); String[] outputSprite = outputItem == null ? null : SpriteCombiner.combineTwoSprites( spriteList.getSprite(outputItem.getItem().getFirst().getSprite()).getSprite(), Numbers.getNumberSprite(outputItem.getAmount()) ).split("\n"); for (int j = 0; j < CELL_HEIGHT; j++) { buffer.append("\033[0m").append(" ".repeat(moveLeft)); buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); if (j == 0 || j == CELL_HEIGHT - 1) { buffer.append("\033[38;5;231;48;5;231m▓".repeat(CELL_WIDTH)); } else { if (items[0] == null) { buffer.append("\033[0m ".repeat(CELL_WIDTH)); } else { String sprite = sprites.get(0); String[] spriteLines = sprite.split("\n"); buffer.append(spriteLines[j - 1]); } } buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); buffer.append("\n"); } for (int j = 0; j < CELL_HEIGHT; j++) { buffer.append("\033[0m").append(" ".repeat(moveLeft)); buffer.append("\033[0m").append(" ".repeat(2 * (2 * BORDER_SIZE + CELL_WIDTH))); buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); if (j == 0 || j == CELL_HEIGHT - 1) { buffer.append("\033[38;5;231;48;5;231m▓".repeat(CELL_WIDTH)); } else { if (outputItem == null) { buffer.append("\033[0m ".repeat(CELL_WIDTH)); } else { buffer.append(outputSprite[j - 1]); } } buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); buffer.append("\n"); } for (int j = 0; j < CELL_HEIGHT; j++) { buffer.append("\033[0m").append(" ".repeat(moveLeft)); buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); if (j == 0 || j == CELL_HEIGHT - 1) { buffer.append("\033[38;5;231;48;5;231m▓".repeat(CELL_WIDTH)); } else { if (items[1] == null) { buffer.append("\033[0m ".repeat(CELL_WIDTH)); } else { String sprite = sprites.get(1); String[] spriteLines = sprite.split("\n"); buffer.append(spriteLines[j - 1]); } } buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE)); buffer.append("\n"); } buffer.append("\n".repeat(20)); size = buffer.toString().split("\n").length; game.getInventory().renderFull(buffer, terminal, spriteList, false, Optional.of(size)); } public void click(Game game, MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer) { int x = mouseEvent.getX(); int y = mouseEvent.getY(); int widthPixels = COLUMN_AMOUNT * (CELL_WIDTH + BORDER_SIZE) + BORDER_SIZE; int moveLeft = (terminal.getWidth() / 2) - (widthPixels / 2); if (x > moveLeft && x <= moveLeft + CELL_WIDTH + BORDER_SIZE && y > 0 && y < CELL_HEIGHT && mouseEvent.getType() == MouseEvent.Type.Pressed) { InventoryItem selectedItem = game.getInventory().getSelectedItemNo(Optional.of(items)); if (selectedItem != null && !Smelting.smeltingList.containsKey(selectedItem.getItem().getFirst().getId())) { return; } InventoryClickHandler.handleItemClick(mouseEvent, game.getInventory(), items, 0, 50, Optional.of(items)); screenRenderer.render(game); checkSmelt(game, screenRenderer); } else if (x > moveLeft + (2 * (2 * BORDER_SIZE + CELL_WIDTH)) && x <= moveLeft + (3 * (2 * BORDER_SIZE + CELL_WIDTH)) && y > CELL_HEIGHT && y <= 2*CELL_HEIGHT && mouseEvent.getType() == MouseEvent.Type.Pressed) { pickup(game); screenRenderer.render(game); } else if (x > moveLeft && x <= moveLeft + CELL_WIDTH + BORDER_SIZE && y > 2 * CELL_HEIGHT && y < 3 * CELL_HEIGHT && mouseEvent.getType() == MouseEvent.Type.Pressed) { InventoryItem selectedItem = game.getInventory().getSelectedItemNo(Optional.of(items)); if (selectedItem != null && !Smelting.fuelList.containsKey(selectedItem.getItem().getFirst().getId())) { return; } InventoryClickHandler.handleItemClick(mouseEvent, game.getInventory(), items, 1, 50, Optional.of(items)); screenRenderer.render(game); checkSmelt(game, screenRenderer); } else { InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.of(size + 20), Optional.of(items)); } } public void setSmelting(boolean smelting) { this.smelting = smelting; this.block.setSpriteState(smelting ? cz.jzitnik.game.sprites.Furnace.FurnaceState.ON : cz.jzitnik.game.sprites.Furnace.FurnaceState.OFF); } public void checkSmelt(Game game, ScreenRenderer screenRenderer) { if (items[0] == null || items[1] == null) { return; } if (!smelting) { startSmelting(game, screenRenderer); } } public void rerender(Game game, ScreenRenderer screenRenderer) { if (game.getWindow() == Window.FURNACE) { screenRenderer.render(game); } } public void pickup(Game game) { if (outputItem == null) { return; } game.getInventory().addItem(outputItem); outputItem = null; } public void startSmelting(Game game, ScreenRenderer screenRenderer) { setSmelting(true); // Add smelt item Thread thread1 = new Thread(() -> { while (true) { try { Thread.sleep(10000); } catch (InterruptedException e) { throw new RuntimeException(e); } if (smelting) { var supplier = Smelting.smeltingList.get(items[0].getItem().getFirst().getId()); if (outputItem == null) { outputItem = new InventoryItem(1, supplier.get()); } else { outputItem.add(supplier.get()); } items[0].decrease(); if (items[0].getAmount() == 0) { items[0] = null; } rerender(game, screenRenderer); } if (items[0] == null || !smelting) { break; } } }); Thread thread2 = new Thread(() -> { while (true) { Item fuel = items[1].getItem().getFirst(); double smelts = Smelting.fuelList.get(fuel.getId()); items[1].decrease(); if (items[1].getAmount() == 0) { items[1] = null; } rerender(game, screenRenderer); try { Thread.sleep((long) (10000 * smelts)); } catch (InterruptedException e) { throw new RuntimeException(e); } if (items[0] == null || items[1] == null) { setSmelting(false); rerender(game, screenRenderer); break; } rerender(game, screenRenderer); } }); thread1.start(); thread2.start(); } public void breakBlock(Game game) { for (var i = 0; i < items.length; i++) { if (items[i] == null) { continue; } game.getInventory().addItem(items[i]); items[i] = null; } if (outputItem != null) { game.getInventory().addItem(outputItem); outputItem = null; } setSmelting(false); } }