feat: Implemented full crafting

This commit is contained in:
Jakub Žitník 2025-02-24 20:50:15 +01:00
parent 03a663258b
commit 15c5e7fea0
Signed by: jzitnik
GPG Key ID: C577A802A6AF4EF3
22 changed files with 483 additions and 56 deletions

View File

@ -4,6 +4,7 @@ import cz.jzitnik.game.Game;
import cz.jzitnik.game.MouseHandler; import cz.jzitnik.game.MouseHandler;
import cz.jzitnik.game.SpriteLoader; import cz.jzitnik.game.SpriteLoader;
import cz.jzitnik.game.sprites.Window; import cz.jzitnik.game.sprites.Window;
import cz.jzitnik.game.ui.InventoryClickHandler;
import cz.jzitnik.tui.ScreenRenderer; import cz.jzitnik.tui.ScreenRenderer;
import org.jline.terminal.MouseEvent; import org.jline.terminal.MouseEvent;
import org.jline.terminal.Terminal; import org.jline.terminal.Terminal;
@ -12,7 +13,6 @@ import org.jline.terminal.TerminalBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
import static cz.jzitnik.game.ui.InventoryClickHandler.click;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
@ -48,7 +48,8 @@ public class Main {
MouseEvent mouseEvent = terminal.readMouseEvent(); MouseEvent mouseEvent = terminal.readMouseEvent();
switch (game.getWindow()) { switch (game.getWindow()) {
case WORLD -> mouseHandler.handle(mouseEvent); case WORLD -> mouseHandler.handle(mouseEvent);
case INVENTORY -> click(mouseEvent, terminal, screenRenderer, game, Optional.empty()); case INVENTORY -> InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.empty(), Optional.empty());
case CRAFTING_TABLE -> game.getGameStates().craftingTable.click(mouseEvent, terminal, screenRenderer);
} }
} }
} }

View File

@ -23,7 +23,10 @@ public class Game {
@Setter @Setter
private Window window = Window.WORLD; private Window window = Window.WORLD;
private Inventory inventory = new Inventory(); //jsonignore
private final GameStates gameStates = new GameStates(this);
private final Inventory inventory = new Inventory();
public Game() { public Game() {
Generation.generateWorld(this); Generation.generateWorld(this);
@ -235,8 +238,10 @@ public class Game {
return; return;
} }
if (!blocks.stream().allMatch(Block::isGhost)) { if (!blocks.stream().allMatch(block -> block.getBlockId().equals("air"))) {
RightClickHandler.handle(x, y, this); RightClickHandler.handle(x, y, this);
screenRenderer.render(this);
return;
} }
if (!(inventory.getItemInHand().isPresent() && inventory.getItemInHand().get().getType() == ItemType.BLOCK)) { if (!(inventory.getItemInHand().isPresent() && inventory.getItemInHand().get().getType() == ItemType.BLOCK)) {

View File

@ -0,0 +1,11 @@
package cz.jzitnik.game;
import cz.jzitnik.game.ui.CraftingTable;
public class GameStates {
public CraftingTable craftingTable;
public GameStates(Game game) {
craftingTable = new CraftingTable(game);
}
}

View File

@ -1,7 +1,24 @@
package cz.jzitnik.game; package cz.jzitnik.game;
public class RightClickHandler { import java.util.HashMap;
public static void handle(int x, int y, Game game) {
public class RightClickHandler {
@FunctionalInterface
public interface Function3<T, U> {
void apply(T t, U u);
}
public static void handle(int x, int y, Game game) {
HashMap<String, Function3<Integer, Integer>> functionMap = new HashMap<>();
functionMap.put("crafting_table", game.getGameStates().craftingTable::render);
var blocks = game.getWorld()[y][x];
for (Block block : blocks) {
if (functionMap.containsKey(block.getBlockId())) {
functionMap.get(block.getBlockId()).apply(x, y);
return;
}
}
} }
} }

View File

@ -17,17 +17,24 @@ public class SpriteLoader {
BEDROCK, BEDROCK,
BREAKING, BREAKING,
CRAFTING_TABLE, CRAFTING_TABLE,
COBBLESTONE,
OAK_LOG, OAK_LOG,
OAK_LEAF, OAK_LEAF,
OAK_PLANKS, OAK_PLANKS,
WOODEN_PICKAXE,
STONE_PICKAXE,
WOODEN_AXE,
STONE_AXE,
// Items // Items
ITEM_DIRT, ITEM_DIRT,
ITEM_OAK_LOG, ITEM_OAK_LOG,
ITEM_OAK_PLANKS, ITEM_OAK_PLANKS,
ITEM_STICK, ITEM_STICK,
ITEM_CRAFTING_TABLE ITEM_CRAFTING_TABLE,
ITEM_COBBLESTONE
} }
public static final HashMap<SPRITES, Sprite> SPRITES_MAP = new HashMap<>(); public static final HashMap<SPRITES, Sprite> SPRITES_MAP = new HashMap<>();
@ -44,12 +51,18 @@ public class SpriteLoader {
SPRITES_MAP.put(SPRITES.OAK_LEAF, new OakLeaf()); SPRITES_MAP.put(SPRITES.OAK_LEAF, new OakLeaf());
SPRITES_MAP.put(SPRITES.OAK_PLANKS, new SimpleSprite("oak_planks.ans")); SPRITES_MAP.put(SPRITES.OAK_PLANKS, new SimpleSprite("oak_planks.ans"));
SPRITES_MAP.put(SPRITES.CRAFTING_TABLE, new SimpleSprite("crafting_table.ans")); SPRITES_MAP.put(SPRITES.CRAFTING_TABLE, new SimpleSprite("crafting_table.ans"));
SPRITES_MAP.put(SPRITES.COBBLESTONE, new SimpleSprite("cobblestone.ans"));
SPRITES_MAP.put(SPRITES.WOODEN_PICKAXE, new SimpleSprite("items/wooden_pickaxe.ans"));
SPRITES_MAP.put(SPRITES.STONE_PICKAXE, new SimpleSprite("items/stone_pickaxe.ans"));
SPRITES_MAP.put(SPRITES.WOODEN_AXE, new SimpleSprite("items/wooden_axe.ans"));
SPRITES_MAP.put(SPRITES.STONE_AXE, new SimpleSprite("items/stone_axe.ans"));
SPRITES_MAP.put(SPRITES.ITEM_DIRT, new SimpleSprite("items/dirt.ans")); SPRITES_MAP.put(SPRITES.ITEM_DIRT, new SimpleSprite("items/dirt.ans"));
SPRITES_MAP.put(SPRITES.ITEM_OAK_LOG, new SimpleSprite("items/oak_log.ans")); SPRITES_MAP.put(SPRITES.ITEM_OAK_LOG, new SimpleSprite("items/oak_log.ans"));
SPRITES_MAP.put(SPRITES.ITEM_OAK_PLANKS, new SimpleSprite("items/oak_planks.ans")); SPRITES_MAP.put(SPRITES.ITEM_OAK_PLANKS, new SimpleSprite("items/oak_planks.ans"));
SPRITES_MAP.put(SPRITES.ITEM_STICK, new SimpleSprite("items/stick.ans")); SPRITES_MAP.put(SPRITES.ITEM_STICK, new SimpleSprite("items/stick.ans"));
SPRITES_MAP.put(SPRITES.ITEM_CRAFTING_TABLE, new SimpleSprite("items/crafting_table.ans")); SPRITES_MAP.put(SPRITES.ITEM_CRAFTING_TABLE, new SimpleSprite("items/crafting_table.ans"));
SPRITES_MAP.put(SPRITES.ITEM_COBBLESTONE, new SimpleSprite("items/cobblestone.ans"));
} }
public static SpriteList<SPRITES> load() { public static SpriteList<SPRITES> load() {

View File

@ -16,17 +16,57 @@ public class CraftingRecipeList {
{null, null, null} {null, null, null}
}, () -> new InventoryItem(4, ItemBlockSupplier.Items.oakPlanks()))); }, () -> new InventoryItem(4, ItemBlockSupplier.Items.oakPlanks())));
// Crafting table
recipes.add(new CraftingRecipe(new String[][]{ recipes.add(new CraftingRecipe(new String[][]{
{"oak_planks", "oak_planks", null}, {"oak_planks", "oak_planks", null},
{"oak_planks", "oak_planks", null}, {"oak_planks", "oak_planks", null},
{null, null, null} {null, null, null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.craftingTable()))); }, () -> new InventoryItem(1, ItemBlockSupplier.Items.craftingTable())));
// Stick
recipes.add(new CraftingRecipe(new String[][]{ recipes.add(new CraftingRecipe(new String[][]{
{"oak_planks", null, null}, {"oak_planks", null, null},
{"oak_planks", null, null}, {"oak_planks", null, null},
{null, null, null} {null, null, null}
}, () -> new InventoryItem(4, ItemBlockSupplier.Items.stick()))); }, () -> new InventoryItem(4, ItemBlockSupplier.Items.stick())));
// Wooden pickaxe
recipes.add(new CraftingRecipe(new String[][]{
{"oak_planks", "oak_planks", "oak_planks"},
{null, "stick", null},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.woodenPickaxe())));
// Wooden axe
recipes.add(new CraftingRecipe(new String[][]{
{"oak_planks", "oak_planks", null},
{"oak_planks", "stick", null},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.woodenAxe())));
recipes.add(new CraftingRecipe(new String[][]{
{null, "oak_planks", "oak_planks"},
{null, "stick", "oak_planks"},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.woodenAxe())));
// Stone pickaxe
recipes.add(new CraftingRecipe(new String[][]{
{"cobblestone", "cobblestone", "cobblestone"},
{null, "stick", null},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.stonePickaxe())));
// Stone axe
recipes.add(new CraftingRecipe(new String[][]{
{"cobblestone", "cobblestone", null},
{"cobblestone", "stick", null},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.stoneAxe())));
recipes.add(new CraftingRecipe(new String[][]{
{null, "cobblestone", "cobblestone"},
{null, "stick", "cobblestone"},
{null, "stick", null}
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.stoneAxe())));
} }
// 2x2 crafting // 2x2 crafting

View File

@ -17,9 +17,19 @@ public class Item {
private SpriteLoader.SPRITES sprite; private SpriteLoader.SPRITES sprite;
private boolean stackable = true; private boolean stackable = true;
private int durability; private int durability;
private int miningDecrease = 0; private double miningDecrease = 0;
private int stackAmount = 64; private int stackAmount = 64;
private Optional<Block> block; private Optional<Block> block = Optional.empty();
public Item(String id, String name, ItemType type, SpriteLoader.SPRITES sprite, ToolVariant toolVariant, double miningDecrease, int durability) {
this.id = id;
this.name = name;
this.type = type;
this.sprite = sprite;
this.toolVariant = Optional.of(toolVariant);
this.miningDecrease = miningDecrease;
this.durability = durability;
}
public Item(String id, String name, ItemType type, SpriteLoader.SPRITES sprite, Block block) { public Item(String id, String name, ItemType type, SpriteLoader.SPRITES sprite, Block block) {
this.id = id; this.id = id;
@ -34,7 +44,6 @@ public class Item {
this.name = name; this.name = name;
this.type = type; this.type = type;
this.sprite = sprite; this.sprite = sprite;
this.block = Optional.empty();
} }
public void use() { public void use() {

View File

@ -13,8 +13,8 @@ public class ItemBlockSupplier {
public static Item dirt(Block ref) { public static Item dirt(Block ref) {
return new Item("dirt", "Dirt block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, ref); return new Item("dirt", "Dirt block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, ref);
} }
public static Item stone(Block ref) { public static Item cobblestone(Block ref) {
return new Item("stone", "Stone block", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_DIRT, ref); return new Item("cobblestone", "Cobblestone", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_COBBLESTONE, ref);
} }
public static Item oakLog(Block ref) { public static Item oakLog(Block ref) {
return new Item("oak_log", "Oak log", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_OAK_LOG, ref); return new Item("oak_log", "Oak log", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_OAK_LOG, ref);
@ -38,9 +38,14 @@ public class ItemBlockSupplier {
block.setDrops(List.of(Items.dirt())); block.setDrops(List.of(Items.dirt()));
return block; return block;
} }
public static Block cobblestone() {
var block = new Block("cobblestone", SpriteLoader.SPRITES.COBBLESTONE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList());
block.setDrops(List.of(Helper.cobblestone(block)));
return block;
}
public static Block stone() { public static Block stone() {
var block = new Block("stone", SpriteLoader.SPRITES.STONE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList()); var block = new Block("stone", SpriteLoader.SPRITES.STONE, 15, ItemType.PICKAXE, Arrays.stream(ToolVariant.values()).toList());
block.setDrops(List.of(Helper.stone(block))); block.setDrops(List.of(Items.cobblestone()));
return block; return block;
} }
public static Block oakLog() { public static Block oakLog() {
@ -74,5 +79,20 @@ public class ItemBlockSupplier {
public static Item craftingTable() { public static Item craftingTable() {
return Helper.craftingTable(Blocks.craftingTable()); return Helper.craftingTable(Blocks.craftingTable());
} }
public static Item woodenPickaxe() {
return new Item("wooden_pickaxe", "Wooden pickaxe", ItemType.PICKAXE, SpriteLoader.SPRITES.WOODEN_PICKAXE, ToolVariant.WOODEN, 12, 59);
}
public static Item woodenAxe() {
return new Item("wooden_axe", "Wooden axe", ItemType.AXE, SpriteLoader.SPRITES.WOODEN_AXE, ToolVariant.WOODEN, 2, 59);
}
public static Item cobblestone() {
return Helper.cobblestone(Blocks.cobblestone());
}
public static Item stonePickaxe() {
return new Item("stone_pickaxe", "Stone pickaxe", ItemType.PICKAXE, SpriteLoader.SPRITES.STONE_PICKAXE, ToolVariant.STONE, 12.5, 132);
}
public static Item stoneAxe() {
return new Item("stone_axe", "Stone axe", ItemType.AXE, SpriteLoader.SPRITES.STONE_AXE, ToolVariant.STONE, 3, 132);
}
} }
} }

View File

@ -2,5 +2,6 @@ package cz.jzitnik.game.sprites;
public enum Window { public enum Window {
WORLD, WORLD,
INVENTORY INVENTORY,
CRAFTING_TABLE
} }

View File

@ -0,0 +1,152 @@
package cz.jzitnik.game.ui;
import cz.jzitnik.game.Game;
import cz.jzitnik.game.crafting.CraftingRecipe;
import cz.jzitnik.game.crafting.CraftingRecipeList;
import cz.jzitnik.game.items.InventoryItem;
import cz.jzitnik.game.sprites.Window;
import cz.jzitnik.tui.ScreenRenderer;
import cz.jzitnik.tui.utils.SpriteCombiner;
import cz.jzitnik.tui.SpriteList;
import cz.jzitnik.tui.utils.Numbers;
import org.jline.terminal.MouseEvent;
import org.jline.terminal.Terminal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public class CraftingTable {
private Game game;
private static final int ROW_AMOUNT = 3;
private static final int COLUMN_AMOUNT = 3;
private static final int CELL_WIDTH = 50;
private static final int CELL_HEIGHT = 25;
private static final int BORDER_SIZE = 2;
private final InventoryItem[] items = new InventoryItem[9];
private int size;
public void render(int ignored, int ignored2) {
game.setWindow(Window.CRAFTING_TABLE);
}
public void pickup() {
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipeSmall(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getId()).toArray(String[]::new));
if (recipe.isPresent()) {
InventoryItem item = recipe.get().getItemSupplier().get();
game.getInventory().addItem(item);
for (int i = 0; i < items.length; i++) {
InventoryItem it = items[i];
if (it == null) {
continue;
}
if (it.getAmount() == 1) {
items[i] = null;
} else {
it.setAmount(it.getAmount() - 1);
}
}
}
}
public void render(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<String> sprites = game.getInventory().getSprites(items, spriteList, inventory.getSelectedItemInv() - 50);
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipeSmall(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getId()).toArray(String[]::new));
Optional<InventoryItem> craftedItem = recipe.map(craftingRecipe -> craftingRecipe.getItemSupplier().get());
String[] craftedSprite = craftedItem.map(inventoryItem -> SpriteCombiner.combineTwoSprites(
spriteList.getSprite(inventoryItem.getItem().getSprite()).getSprite(),
Numbers.getNumberSprite(inventoryItem.getAmount())
).split("\n")).orElse(null);
for (int i = 0; i < ROW_AMOUNT; i++) {
for (int j = 0; j < CELL_HEIGHT; j++) {
buffer.append("\033[0m").append(" ".repeat(moveLeft));
for (int k = 0; k < COLUMN_AMOUNT; k++) {
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 {
String sprite = sprites.get(i * COLUMN_AMOUNT + k);
if (sprite == null || sprite.isEmpty()) {
buffer.append("\033[0m ".repeat(CELL_WIDTH));
} else {
String[] spriteLines = sprite.split("\n");
buffer.append(spriteLines[j + 1]);
}
}
buffer.append("\033[38;5;231;48;5;231m▓".repeat(BORDER_SIZE));
}
if (i == 1) {
buffer.append("\033[0m ".repeat(7));
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 (craftedItem.isEmpty()) {
buffer.append("\033[0m ".repeat(CELL_WIDTH));
} else {
buffer.append(craftedSprite[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(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 heightPixels = ROW_AMOUNT * (CELL_HEIGHT + 1);
int moveLeft = (terminal.getWidth() / 2) - (widthPixels / 2);
if (x > moveLeft + widthPixels + 7 && x < moveLeft + widthPixels + 7 + CELL_WIDTH + BORDER_SIZE * 2 && y > 26 && y < 52 && mouseEvent.getType() == MouseEvent.Type.Pressed && mouseEvent.getButton() == MouseEvent.Button.Button1) {
pickup();
screenRenderer.render(game);
return;
}
if (x > moveLeft && x <= moveLeft + widthPixels && y > 0 && y <= heightPixels && mouseEvent.getType() == MouseEvent.Type.Pressed) {
if (mouseEvent.getType() != MouseEvent.Type.Pressed) return;
int blockX = (x - moveLeft) / 52;
int blockY = y / 26;
InventoryClickHandler.handleItemClick(mouseEvent, game.getInventory(), items, blockY * COLUMN_AMOUNT + blockX, 50, Optional.of(items));
screenRenderer.render(game);
return;
}
// TODO: Why I need to add 20 here. Like wtf
InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.of(size + 20), Optional.of(items));
}
public CraftingTable(Game game) {
this.game = game;
}
}

View File

@ -2,9 +2,9 @@ package cz.jzitnik.game.ui;
import cz.jzitnik.game.items.InventoryItem; import cz.jzitnik.game.items.InventoryItem;
import cz.jzitnik.game.items.Item; import cz.jzitnik.game.items.Item;
import cz.jzitnik.tui.SpriteCombiner; import cz.jzitnik.tui.utils.SpriteCombiner;
import cz.jzitnik.tui.SpriteList; import cz.jzitnik.tui.SpriteList;
import cz.jzitnik.utils.Numbers; import cz.jzitnik.tui.utils.Numbers;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.jline.terminal.Terminal; import org.jline.terminal.Terminal;
@ -153,7 +153,7 @@ public class Inventory {
List<String> sprites = getSprites(items, spriteList, selectedItemInv); List<String> sprites = getSprites(items, spriteList, selectedItemInv);
// Top center // Top center
buffer.append("\n".repeat(Math.max(0, moveTop))); buffer.append("\n".repeat(Math.max(0, moveTopCustom.isPresent() ? 0 : moveTop)));
buffer.append("\033[0m ".repeat(moveLeft)); buffer.append("\033[0m ".repeat(moveLeft));
buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)).append("\033[0m\n"); buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)).append("\033[0m\n");
@ -181,7 +181,7 @@ public class Inventory {
buffer.append("\033[38;5;231;48;5;231m▓"); buffer.append("\033[38;5;231;48;5;231m▓");
} else { } else {
buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels)); buffer.append("\033[38;5;231;48;5;231m▓".repeat(widthPixels));
if (i == 0) { if (i == 0 && includeCrafting) {
buffer.append("\033[0m").append(" ".repeat(20)); 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▓".repeat(106));
} }
@ -190,7 +190,7 @@ public class Inventory {
if (i + 1 > spacesFromTop && includeCrafting) { if (i + 1 > spacesFromTop && includeCrafting) {
int craftingIndex = ((i - spacesFromTop) * 26) + j; int craftingIndex = ((i - spacesFromTop) * 26) + j;
if (craftingIndex >= 0 && craftingIndex < craftingTable.length) { if (craftingIndex < craftingTable.length) {
buffer.append("\033[0m").append(" ".repeat(20)); buffer.append("\033[0m").append(" ".repeat(20));
buffer.append(craftingTable[craftingIndex]); buffer.append(craftingTable[craftingIndex]);
} }
@ -238,11 +238,12 @@ public class Inventory {
return sprites; return sprites;
} }
public InventoryDTO getItem(int index) { public InventoryDTO getItem(int index, Optional<InventoryItem[]> i) {
InventoryItem temp;
if (index < 20) { if (index < 20) {
// Normal inventory // Normal inventory
return new InventoryDTO(items, index); return new InventoryDTO(items, index);
} else if (index >= 50) {
return new InventoryDTO(i.get(), index - 50);
} else if (index >= 29) { } else if (index >= 29) {
// Small crafting table // Small crafting table
return new InventoryDTO(smallCraftingTable.getItems(), index - 29); return new InventoryDTO(smallCraftingTable.getItems(), index - 29);
@ -252,9 +253,9 @@ public class Inventory {
} }
} }
public InventoryItem getSelectedItem() { public InventoryItem getSelectedItem(Optional<InventoryItem[]> i) {
InventoryItem temp; InventoryItem temp;
InventoryDTO data = getItem(selectedItemInv); InventoryDTO data = getItem(selectedItemInv, i);
temp = data.getObj()[data.getIndex()]; temp = data.getObj()[data.getIndex()];
data.getObj()[data.getIndex()] = null; data.getObj()[data.getIndex()] = null;
@ -264,11 +265,11 @@ public class Inventory {
return temp; return temp;
} }
public InventoryItem getOne() { public InventoryItem getOne(Optional<InventoryItem[]> i) {
InventoryDTO inventoryItem = getItem(selectedItemInv); InventoryDTO inventoryItem = getItem(selectedItemInv, i);
InventoryItem item = inventoryItem.getObj()[inventoryItem.getIndex()]; InventoryItem item = inventoryItem.getObj()[inventoryItem.getIndex()];
if (item.getAmount() == 1) { if (item.getAmount() == 1) {
return getSelectedItem(); return getSelectedItem(i);
} }
item.setAmount(item.getAmount() - 1); item.setAmount(item.getAmount() - 1);
@ -278,11 +279,11 @@ public class Inventory {
return new InventoryItem(1, item.getItem()); return new InventoryItem(1, item.getItem());
} }
public InventoryItem getHalf() { public InventoryItem getHalf(Optional<InventoryItem[]> i) {
InventoryDTO inventoryItem = getItem(selectedItemInv); InventoryDTO inventoryItem = getItem(selectedItemInv, i);
InventoryItem item = inventoryItem.getObj()[inventoryItem.getIndex()]; InventoryItem item = inventoryItem.getObj()[inventoryItem.getIndex()];
if (item.getAmount() == 1) { if (item.getAmount() == 1) {
return getSelectedItem(); return getSelectedItem(i);
} }
int half = item.getAmount() / 2; int half = item.getAmount() / 2;
@ -298,9 +299,9 @@ public class Inventory {
return selectedItemInv != -1; return selectedItemInv != -1;
} }
public void mergeItems(int indexFrom, int indexTo) { public void mergeItems(int indexFrom, int indexTo, Optional<InventoryItem[]> i) {
InventoryDTO fromData = getItem(indexFrom); InventoryDTO fromData = getItem(indexFrom, i);
InventoryDTO toData = getItem(indexTo); InventoryDTO toData = getItem(indexTo, i);
InventoryItem fromItem = fromData.getObj()[fromData.getIndex()]; InventoryItem fromItem = fromData.getObj()[fromData.getIndex()];
InventoryItem toItem = toData.getObj()[toData.getIndex()]; InventoryItem toItem = toData.getObj()[toData.getIndex()];
@ -326,9 +327,9 @@ public class Inventory {
selectedItemInv = -1; selectedItemInv = -1;
} }
public void mergeOne(int fromIndex, int toIndex) { public void mergeOne(int fromIndex, int toIndex, Optional<InventoryItem[]> i) {
InventoryDTO fromSlot = getItem(fromIndex); InventoryDTO fromSlot = getItem(fromIndex, i);
InventoryDTO toSlot = getItem(toIndex); InventoryDTO toSlot = getItem(toIndex, i);
InventoryItem fromItem = fromSlot.getObj()[fromSlot.getIndex()]; InventoryItem fromItem = fromSlot.getObj()[fromSlot.getIndex()];
InventoryItem toItem = toSlot.getObj()[toSlot.getIndex()]; InventoryItem toItem = toSlot.getObj()[toSlot.getIndex()];

View File

@ -1,6 +1,7 @@
package cz.jzitnik.game.ui; package cz.jzitnik.game.ui;
import cz.jzitnik.game.Game; import cz.jzitnik.game.Game;
import cz.jzitnik.game.items.InventoryItem;
import cz.jzitnik.tui.ScreenRenderer; import cz.jzitnik.tui.ScreenRenderer;
import org.jline.terminal.MouseEvent; import org.jline.terminal.MouseEvent;
import org.jline.terminal.Terminal; import org.jline.terminal.Terminal;
@ -10,7 +11,7 @@ import java.util.Optional;
import static cz.jzitnik.game.ui.Inventory.*; import static cz.jzitnik.game.ui.Inventory.*;
public class InventoryClickHandler { public class InventoryClickHandler {
public static void click(MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer, Game game, Optional<Integer> moveTopCustom) { public static void click(MouseEvent mouseEvent, Terminal terminal, ScreenRenderer screenRenderer, Game game, Optional<Integer> moveTopCustom, Optional<InventoryItem[]> i) {
if (mouseEvent.getType() != MouseEvent.Type.Pressed) return; if (mouseEvent.getType() != MouseEvent.Type.Pressed) return;
var inventory = game.getInventory(); var inventory = game.getInventory();
@ -18,11 +19,11 @@ public class InventoryClickHandler {
int y = mouseEvent.getY(); int y = mouseEvent.getY();
int moveLeft = calculateMoveLeft(terminal); int moveLeft = calculateMoveLeft(terminal);
int moveTop = moveTopCustom.orElse(calculateMoveTop(terminal)); int moveTop = moveTopCustom.orElseGet(() -> calculateMoveTop(terminal));
if (handleCraftingTableClick(mouseEvent, x, y, inventory, screenRenderer, game, moveLeft, moveTop)) return; if (handleCraftingTableClick(mouseEvent, x, y, inventory, screenRenderer, game, moveLeft, moveTop, i)) return;
if (handleHotbarClick(mouseEvent, x, y, inventory, screenRenderer, game, terminal, moveTop)) return; if (handleHotbarClick(mouseEvent, x, y, inventory, screenRenderer, game, terminal, moveTop, i)) return;
handleInventoryClick(mouseEvent, x, y, inventory, screenRenderer, game, moveLeft, moveTop); handleInventoryClick(mouseEvent, x, y, inventory, screenRenderer, game, moveLeft, moveTop, i);
} }
private static int calculateMoveLeft(Terminal terminal) { private static int calculateMoveLeft(Terminal terminal) {
@ -33,7 +34,7 @@ public class InventoryClickHandler {
return (terminal.getHeight() / 2) - ((ROW_AMOUNT * (25 + 1)) / 2); return (terminal.getHeight() / 2) - ((ROW_AMOUNT * (25 + 1)) / 2);
} }
private static boolean handleCraftingTableClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, int moveLeft, int moveTop) { private static boolean handleCraftingTableClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, int moveLeft, int moveTop, Optional<InventoryItem[]> i) {
int startLeftCrafting = moveLeft + (COLUMN_AMOUNT * (50 + 4) + 2) + 20; int startLeftCrafting = moveLeft + (COLUMN_AMOUNT * (50 + 4) + 2) + 20;
int startTopCrafting = moveTop + 26; int startTopCrafting = moveTop + 26;
@ -49,24 +50,24 @@ public class InventoryClickHandler {
} }
int blockIndex = (craftY / 26) * 2 + (craftX / 53); int blockIndex = (craftY / 26) * 2 + (craftX / 53);
handleItemClick(mouseEvent, inventory, inventory.getSmallCraftingTable().getItems(), blockIndex, 29); handleItemClick(mouseEvent, inventory, inventory.getSmallCraftingTable().getItems(), blockIndex, 29, i);
screenRenderer.render(game); screenRenderer.render(game);
return true; return true;
} }
private static boolean handleHotbarClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, Terminal terminal, int moveTop) { private static boolean handleHotbarClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, Terminal terminal, int moveTop, Optional<InventoryItem[]> i) {
int startLeftHotbar = (terminal.getWidth() / 2) - (INVENTORY_SIZE_PX / 2) + 2; int startLeftHotbar = (terminal.getWidth() / 2) - (INVENTORY_SIZE_PX / 2) + 2;
int startTopHotbar = moveTop + (ROW_AMOUNT * (25 + 1)) + 10; int startTopHotbar = moveTop + (ROW_AMOUNT * (25 + 1)) + 10;
if (x < startLeftHotbar || y < startTopHotbar || x > startLeftHotbar + INVENTORY_SIZE_PX || y > startTopHotbar + 26) return false; if (x < startLeftHotbar || y < startTopHotbar || x > startLeftHotbar + INVENTORY_SIZE_PX || y > startTopHotbar + 26) return false;
int index = (x - startLeftHotbar) / 52; int index = (x - startLeftHotbar) / 52;
handleItemClick(mouseEvent, inventory, inventory.getHotbar(), index, 20); handleItemClick(mouseEvent, inventory, inventory.getHotbar(), index, 20, i);
screenRenderer.render(game); screenRenderer.render(game);
return true; return true;
} }
private static void handleInventoryClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, int moveLeft, int moveTop) { private static void handleInventoryClick(MouseEvent mouseEvent, int x, int y, Inventory inventory, ScreenRenderer screenRenderer, Game game, int moveLeft, int moveTop, Optional<InventoryItem[]> i) {
int fx = x - moveLeft; int fx = x - moveLeft;
int fy = y - moveTop; int fy = y - moveTop;
@ -76,11 +77,11 @@ public class InventoryClickHandler {
if (fx < 0 || fx > widthPixels || fy < 0 || fy > heightPixels) return; if (fx < 0 || fx > widthPixels || fy < 0 || fy > heightPixels) return;
int blockIndex = (fy / 26) * COLUMN_AMOUNT + (fx / 54); int blockIndex = (fy / 26) * COLUMN_AMOUNT + (fx / 54);
handleItemClick(mouseEvent, inventory, inventory.getItems(), blockIndex, 0); handleItemClick(mouseEvent, inventory, inventory.getItems(), blockIndex, 0, i);
screenRenderer.render(game); screenRenderer.render(game);
} }
private static void handleItemClick(MouseEvent mouseEvent, Inventory inventory, Object[] items, int index, int offset) { public static void handleItemClick(MouseEvent mouseEvent, Inventory inventory, Object[] items, int index, int offset, Optional<InventoryItem[]> i) {
int actualIndex = index + offset; int actualIndex = index + offset;
if (inventory.getSelectedItemInv() == actualIndex) { if (inventory.getSelectedItemInv() == actualIndex) {
@ -90,11 +91,11 @@ public class InventoryClickHandler {
switch (mouseEvent.getButton()) { switch (mouseEvent.getButton()) {
case Button1 -> { case Button1 -> {
if (items[index] == null && inventory.hasSelectedItem()) { if (items[index] == null && inventory.hasSelectedItem()) {
items[index] = inventory.isRightClick() ? inventory.getHalf() : inventory.getSelectedItem(); items[index] = inventory.isRightClick() ? inventory.getHalf(i) : inventory.getSelectedItem(i);
} else if (items[index] != null) { } else if (items[index] != null) {
if (inventory.hasSelectedItem()) { if (inventory.hasSelectedItem()) {
// Merge items // Merge items
inventory.mergeItems(inventory.getSelectedItemInv(), actualIndex); inventory.mergeItems(inventory.getSelectedItemInv(), actualIndex, i);
} else { } else {
inventory.setSelectedItemInv(index + offset); inventory.setSelectedItemInv(index + offset);
} }
@ -104,7 +105,7 @@ public class InventoryClickHandler {
if (items[index] != null) { if (items[index] != null) {
if (inventory.hasSelectedItem()) { if (inventory.hasSelectedItem()) {
// Merge just one item into the stack // Merge just one item into the stack
inventory.mergeOne(inventory.getSelectedItemInv(), actualIndex); inventory.mergeOne(inventory.getSelectedItemInv(), actualIndex, i);
} else { } else {
// Pick up one item // Pick up one item
inventory.setSelectedItemInv(actualIndex); inventory.setSelectedItemInv(actualIndex);
@ -112,7 +113,7 @@ public class InventoryClickHandler {
} }
} else { } else {
// Place one item // Place one item
items[index] = inventory.getOne(); items[index] = inventory.getOne(i);
} }
} }
} }

View File

@ -3,9 +3,9 @@ package cz.jzitnik.game.ui;
import cz.jzitnik.game.crafting.CraftingRecipe; import cz.jzitnik.game.crafting.CraftingRecipe;
import cz.jzitnik.game.crafting.CraftingRecipeList; import cz.jzitnik.game.crafting.CraftingRecipeList;
import cz.jzitnik.game.items.InventoryItem; import cz.jzitnik.game.items.InventoryItem;
import cz.jzitnik.tui.SpriteCombiner; import cz.jzitnik.tui.utils.SpriteCombiner;
import cz.jzitnik.tui.SpriteList; import cz.jzitnik.tui.SpriteList;
import cz.jzitnik.utils.Numbers; import cz.jzitnik.tui.utils.Numbers;
import lombok.Getter; import lombok.Getter;
import java.util.Arrays; import java.util.Arrays;

View File

@ -2,6 +2,7 @@ package cz.jzitnik.tui;
import cz.jzitnik.game.Block; import cz.jzitnik.game.Block;
import cz.jzitnik.game.Game; import cz.jzitnik.game.Game;
import cz.jzitnik.tui.utils.SpriteCombiner;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
@ -43,6 +44,7 @@ public class ScreenRenderer {
switch (game.getWindow()) { switch (game.getWindow()) {
case INVENTORY -> game.getInventory().renderFull(main, terminal, spriteList, true, Optional.empty()); case INVENTORY -> game.getInventory().renderFull(main, terminal, spriteList, true, Optional.empty());
case CRAFTING_TABLE -> game.getGameStates().craftingTable.render(main, terminal, spriteList);
case WORLD -> { case WORLD -> {
// World // World

View File

@ -1,7 +1,6 @@
package cz.jzitnik.utils; package cz.jzitnik.tui.utils;
import cz.jzitnik.game.sprites.ui.Number; import cz.jzitnik.game.sprites.ui.Number;
import cz.jzitnik.tui.SpriteCombiner;
public class Numbers { public class Numbers {
private static Number.NumberState getNumberState(int digit) { private static Number.NumberState getNumberState(int digit) {

View File

@ -1,4 +1,4 @@
package cz.jzitnik.tui; package cz.jzitnik.tui.utils;
public class SpriteCombiner { public class SpriteCombiner {
public static String combineSprites(String[] sprites) { public static String combineSprites(String[] sprites) {

View File

@ -0,0 +1,26 @@
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓


View File

@ -0,0 +1,26 @@
                                                  
                      ▓▓▓▓▓▓▓                     
                  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓                 
              ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓             
          ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓         
      ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓     
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
   ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  
      ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓     
          ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓         
              ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓             
                  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓                 
                      ▓▓▓▓▓▓▓                     


View File

@ -0,0 +1,25 @@
 
   
   
        
       
         
           
        
          
          
          
          
         
        
       
      
      
      
     
     
      
      
    
   
 

View File

@ -0,0 +1,26 @@
                                                  
                                                  
                                                  
                  ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒              
                ▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▓▓▓     
               ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ░░░░▓     
               ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓   ░░░▓     
                  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░   ░     
                  ▒▓▓▒▒░░░░░░░░▒   ▓▓▓▓▓▓   ░     
                           ▒▒▒▒▒   ▓▓▓▓▓▓▓▓▓░░░░  
                           ▒▓   ░░░   ▓▓▓▓▓▓▓▓▓░  
                        ▒░ ░░░░▒   ░░░▓▓▓▓▓▓▓▓▓░  
                      ▒▒▒▒  ░░░▒   ░ ░▓▓▓▓▓▓▓▓▓░  
                     ░   ░░░░   ░░░░░░▓▓▓▓▓▓▓▓▓░  
                  ▒▓▓▓░░░░░░░▒▒▒░    ░▓▓▓▓▓▓▓▓▓░  
                ▒▒▒   ░░░   ▓        ░▓▓▓▓▓▓▓▓▓░  
               ▒   ░░░   ▒░░░        ░▓▓▓▓▓▓▓▓▓░  
            ▒▒▒▒   ░░░   ▒░          ░▓▓▓▓▓▓▓▓▓░  
            ▒   ░░░   ░░               ░░▓▓▓░     
        ▒▒   ░░░   ░░░░                 ░░░░░     
      ▒▒▒▒   ░░░   ░                              
      ▒   ░░░   ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
      ▒      ░░░░                                 
      ░      ░                                    
                                                  


View File

@ -0,0 +1,26 @@
                                                  
                                                  
                            ▒                     
                         ░░░░      ░░░            
                            ░░░░░░░               
                         ░░░░░░░░░░               
                         ░░░░░░░░░░               
                      ░░░░░░░░░░░░░   ░░░         
                      ░░░░░░░░░░░░░░░░            
                      ░░░░░░░░░░░░░░░░            
                                ░░░░░░░░░         
                            ░░░░   ░░░░░░         
                            ░░░░   ░░░░░░         
                         ░░░   ▒                  
                   ▓▓▓░░░    ░░░   ░░░░░░         
                      ░░░   ░                     
                   ░░░                            
                   ░░░                            
                ░░░                               
             ░░░                                  
             ░░░                                  
      ░   ░░░                                     
      ░                                           
      ░                                           
                                                  


View File

@ -0,0 +1,26 @@
                                                  
                                                  
                                                  
                   ░░░░░░░░░░░░░░░░               
                                                  
                   ░░░░░░░░░░░░░░░░      ░░░      
                   ░░░░░░░░░░░░░░░░      ░░░      
                                ░░░░░░░░░         
                               ░   ░░░░░░         
                               ░   ░░░░░░         
                            ▓   ░░░   ░░░░░░      
                            ░░░░         ░░░      
                            ░░░░         ░░░      
                         ░░░   ▒         ░░░      
                   ▓▓▓░░░   ▒░░░         ░░░      
                      ░░░   ░            ░░░      
                   ░░░                   ░░░      
                   ░░░                   ░░░      
                ░░░                               
             ░░░                                  
             ░░░                                  
      ░   ░░░                                     
      ░                                           
      ░