feat: Chest and other changes
This commit is contained in:
@ -3,7 +3,9 @@ package cz.jzitnik;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.MouseHandler;
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.sprites.Window;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.game.ui.CloseHandler;
|
||||
import cz.jzitnik.game.ui.Window;
|
||||
import cz.jzitnik.game.ui.InventoryClickHandler;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import org.jline.terminal.MouseEvent;
|
||||
@ -50,6 +52,7 @@ public class Main {
|
||||
case WORLD -> mouseHandler.handle(mouseEvent);
|
||||
case INVENTORY -> InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.empty(), Optional.empty());
|
||||
case CRAFTING_TABLE -> game.getGameStates().craftingTable.click(mouseEvent, terminal, screenRenderer);
|
||||
case CHEST -> ((Chest) game.getWorld()[game.getGameStates().clickY][game.getGameStates().clickX].stream().filter(i -> i.getBlockId().equals("chest")).toList().getFirst().getData()).click(game, mouseEvent, terminal, screenRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,8 +84,9 @@ public class Main {
|
||||
break;
|
||||
case 'e':
|
||||
if (game.getWindow() != Window.WORLD) {
|
||||
game.setWindow(Window.WORLD);
|
||||
game.getInventory().setSelectedItemInv(-1);
|
||||
CloseHandler.handle(game.getWindow(), game);
|
||||
game.setWindow(Window.WORLD);
|
||||
} else {
|
||||
game.setWindow(Window.INVENTORY);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ public class Block {
|
||||
private Optional<ItemType> tool = Optional.empty();
|
||||
private List<ToolVariant> toolVariants = new ArrayList<>();
|
||||
private List<Item> drops = new ArrayList<>();
|
||||
private Object data = null;
|
||||
|
||||
public Block(String blockId, SpriteLoader.SPRITES sprite) {
|
||||
this.blockId = blockId;
|
||||
@ -44,6 +45,15 @@ public class Block {
|
||||
this.toolVariants = toolVariants;
|
||||
}
|
||||
|
||||
public Block(String blockId, SpriteLoader.SPRITES sprite, int hardness, ItemType tool, List<ToolVariant> toolVariants, Object data) {
|
||||
this.blockId = blockId;
|
||||
this.sprite = sprite;
|
||||
this.hardness = hardness;
|
||||
this.tool = Optional.of(tool);
|
||||
this.toolVariants = toolVariants;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setSpriteState(Enum spriteState) {
|
||||
this.spriteState = Optional.of(spriteState);
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package cz.jzitnik.game;
|
||||
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.sprites.Steve;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.game.ui.Window;
|
||||
import cz.jzitnik.game.ui.Inventory;
|
||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
@ -19,6 +21,8 @@ public class Game {
|
||||
private List<Block>[][] world = new ArrayList[256][512];
|
||||
@Setter
|
||||
private Block player;
|
||||
@Setter
|
||||
private Block player2;
|
||||
private boolean mining = false;
|
||||
@Setter
|
||||
private Window window = Window.WORLD;
|
||||
@ -36,7 +40,7 @@ public class Game {
|
||||
for (int i = 0; i < world.length; i++) {
|
||||
for (int j = 0; j < world[i].length; j++) {
|
||||
for (Block block : world[i][j]) {
|
||||
if (block.getBlockId().equals("steve")) {
|
||||
if (block.getBlockId().equals("steve") && block.getSpriteState().isPresent() && block.getSpriteState().get() == Steve.SteveState.SECOND) {
|
||||
return new int[]{j, i};
|
||||
}
|
||||
}
|
||||
@ -51,12 +55,14 @@ public class Game {
|
||||
}
|
||||
int[] cords = getPlayerCords();
|
||||
|
||||
if (world[cords[1]][cords[0] + 1].stream().anyMatch(block -> !block.isGhost())) {
|
||||
if (world[cords[1]][cords[0] + 1].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] - 1][cords[0] + 1].stream().anyMatch(block -> !block.isGhost())) {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1]][cords[0] + 1].add(player);
|
||||
world[cords[1]][cords[0]].remove(player);
|
||||
world[cords[1]][cords[0] + 1].add(player2);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
world[cords[1]-1][cords[0] + 1].add(player);
|
||||
world[cords[1]-1][cords[0]].remove(player);
|
||||
screenRenderer.render(this);
|
||||
|
||||
update(screenRenderer);
|
||||
@ -68,12 +74,14 @@ public class Game {
|
||||
}
|
||||
int[] cords = getPlayerCords();
|
||||
|
||||
if (world[cords[1]][cords[0] - 1].stream().anyMatch(block -> !block.isGhost())) {
|
||||
if (world[cords[1]][cords[0] - 1].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] - 1][cords[0] - 1].stream().anyMatch(block -> !block.isGhost())) {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1]][cords[0] - 1].add(player);
|
||||
world[cords[1]][cords[0]].remove(player);
|
||||
world[cords[1]][cords[0] - 1].add(player2);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
world[cords[1]-1][cords[0] - 1].add(player);
|
||||
world[cords[1]-1][cords[0]].remove(player);
|
||||
screenRenderer.render(this);
|
||||
|
||||
update(screenRenderer);
|
||||
@ -85,12 +93,14 @@ public class Game {
|
||||
}
|
||||
int[] cords = getPlayerCords();
|
||||
|
||||
if (world[cords[1] - 1][cords[0]].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] + 1][cords[0]].stream().anyMatch(Block::isGhost)) {
|
||||
if (world[cords[1] - 2][cords[0]].stream().anyMatch(block -> !block.isGhost()) || world[cords[1] + 1][cords[0]].stream().anyMatch(Block::isGhost)) {
|
||||
return;
|
||||
}
|
||||
|
||||
world[cords[1] - 1][cords[0]].add(player);
|
||||
world[cords[1]][cords[0]].remove(player);
|
||||
world[cords[1] - 1][cords[0]].remove(player);
|
||||
world[cords[1] - 1][cords[0]].add(player2);
|
||||
world[cords[1] - 2][cords[0]].add(player);
|
||||
world[cords[1]][cords[0]].remove(player2);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
@ -101,8 +111,10 @@ public class Game {
|
||||
int[] cords2 = getPlayerCords();
|
||||
|
||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
||||
world[cords2[1] + 1][cords2[0]].add(player);
|
||||
world[cords2[1]][cords2[0]].remove(player);
|
||||
world[cords2[1] - 1][cords2[0]].remove(player);
|
||||
world[cords2[1]][cords2[0]].add(player);
|
||||
world[cords2[1] + 1][cords2[0]].add(player2);
|
||||
world[cords2[1]][cords2[0]].remove(player2);
|
||||
|
||||
screenRenderer.render(this);
|
||||
}
|
||||
@ -155,13 +167,19 @@ public class Game {
|
||||
|
||||
if (block.getToolVariants().isEmpty()) {
|
||||
// Add to inv
|
||||
block.getDrops().forEach(item -> inventory.addItem(item));
|
||||
block.getDrops().forEach(inventory::addItem);
|
||||
continue;
|
||||
}
|
||||
|
||||
var toolVariants = block.getToolVariants();
|
||||
if (inventory.getItemInHand().isPresent() && inventory.getItemInHand().get().getToolVariant().isPresent() && block.getTool().isPresent() && block.getTool().get().equals(inventory.getItemInHand().get().getType()) && toolVariants.contains(inventory.getItemInHand().get().getToolVariant().get())) {
|
||||
block.getDrops().forEach(item -> inventory.addItem(item));
|
||||
block.getDrops().forEach(inventory::addItem);
|
||||
}
|
||||
}
|
||||
|
||||
for (Block block : blocks) {
|
||||
if (block.getBlockId().equals("chest")) {
|
||||
((Chest) block.getData()).breakChest(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,6 +215,7 @@ public class Game {
|
||||
!blocks.stream().allMatch(block -> block.getBlockId().equals("air"))
|
||||
&& distanceX <= 5 && distanceY <= 5
|
||||
&& !(playerX == x && playerY == y)
|
||||
&& !(playerX == x && playerY - 1 == y)
|
||||
&& blocks.stream().anyMatch(Block::isMineable);
|
||||
}
|
||||
|
||||
@ -210,8 +229,10 @@ public class Game {
|
||||
int[] cords2 = getPlayerCords();
|
||||
|
||||
if (world[cords2[1] + 1][cords2[0]].stream().allMatch(Block::isGhost)) {
|
||||
world[cords2[1] + 1][cords2[0]].add(player);
|
||||
world[cords2[1]][cords2[0]].remove(player);
|
||||
world[cords2[1] - 1][cords2[0]].remove(player);
|
||||
world[cords2[1]][cords2[0]].add(player);
|
||||
world[cords2[1] + 1][cords2[0]].add(player2);
|
||||
world[cords2[1]][cords2[0]].remove(player2);
|
||||
|
||||
screenRenderer.render(this);
|
||||
} else {
|
||||
|
@ -4,6 +4,8 @@ import cz.jzitnik.game.ui.CraftingTable;
|
||||
|
||||
public class GameStates {
|
||||
public CraftingTable craftingTable;
|
||||
public int clickX = -1;
|
||||
public int clickY = -1;
|
||||
|
||||
public GameStates(Game game) {
|
||||
craftingTable = new CraftingTable(game);
|
||||
|
@ -2,6 +2,7 @@ package cz.jzitnik.game;
|
||||
|
||||
import cz.jzitnik.game.items.ItemBlockSupplier;
|
||||
import cz.jzitnik.game.items.ItemType;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -13,14 +14,20 @@ public class Generation {
|
||||
initializeWorld(world);
|
||||
|
||||
Block steveBlock = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||
steveBlock.setSpriteState(Steve.SteveState.FIRST);
|
||||
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
||||
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
||||
|
||||
game.setPlayer(steveBlock);
|
||||
game.setPlayer2(steveBlock2);
|
||||
|
||||
int[] terrainHeight = generateTerrain();
|
||||
populateWorld(world, terrainHeight);
|
||||
plantTrees(world, terrainHeight);
|
||||
|
||||
// Spawn player at a valid starting point
|
||||
world[terrainHeight[256] - 1][256].add(steveBlock);
|
||||
world[terrainHeight[256] - 1][256].add(steveBlock2);
|
||||
world[terrainHeight[256] - 2][256].add(steveBlock);
|
||||
}
|
||||
|
||||
private static void initializeWorld(List<Block>[][] world) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cz.jzitnik.game;
|
||||
|
||||
import cz.jzitnik.game.sprites.Window;
|
||||
import cz.jzitnik.game.ui.Window;
|
||||
import cz.jzitnik.tui.ScreenMovingCalculationProvider;
|
||||
import cz.jzitnik.tui.ScreenRenderer;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cz.jzitnik.game;
|
||||
|
||||
import cz.jzitnik.game.ui.Window;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class RightClickHandler {
|
||||
@ -9,8 +11,16 @@ public class RightClickHandler {
|
||||
}
|
||||
|
||||
public static void handle(int x, int y, Game game) {
|
||||
if (game.isMining()) {
|
||||
return;
|
||||
}
|
||||
|
||||
HashMap<String, Function3<Integer, Integer>> functionMap = new HashMap<>();
|
||||
functionMap.put("crafting_table", game.getGameStates().craftingTable::render);
|
||||
functionMap.put("chest", (Integer ignored, Integer ignored2) -> game.setWindow(Window.CHEST));
|
||||
|
||||
game.getGameStates().clickX = x;
|
||||
game.getGameStates().clickY = y;
|
||||
|
||||
var blocks = game.getWorld()[y][x];
|
||||
for (Block block : blocks) {
|
||||
|
@ -16,9 +16,11 @@ public class SpriteLoader {
|
||||
STONE,
|
||||
BEDROCK,
|
||||
BREAKING,
|
||||
CRAFTING_TABLE,
|
||||
COBBLESTONE,
|
||||
|
||||
CHEST,
|
||||
CRAFTING_TABLE,
|
||||
|
||||
OAK_LOG,
|
||||
OAK_LEAF,
|
||||
OAK_PLANKS,
|
||||
@ -27,14 +29,18 @@ public class SpriteLoader {
|
||||
STONE_PICKAXE,
|
||||
WOODEN_AXE,
|
||||
STONE_AXE,
|
||||
WOODEN_SHOVEL,
|
||||
STONE_SHOVEL,
|
||||
|
||||
// Items
|
||||
ITEM_DIRT,
|
||||
ITEM_OAK_LOG,
|
||||
ITEM_OAK_PLANKS,
|
||||
ITEM_STICK,
|
||||
ITEM_COBBLESTONE,
|
||||
|
||||
ITEM_CRAFTING_TABLE,
|
||||
ITEM_COBBLESTONE
|
||||
ITEM_CHEST
|
||||
}
|
||||
|
||||
public static final HashMap<SPRITES, Sprite> SPRITES_MAP = new HashMap<>();
|
||||
@ -51,18 +57,22 @@ public class SpriteLoader {
|
||||
SPRITES_MAP.put(SPRITES.OAK_LEAF, new SimpleSprite("oak_leaf.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.CHEST, new SimpleSprite("chest.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.WOODEN_SHOVEL, new SimpleSprite("items/wooden_shovel.ans"));
|
||||
SPRITES_MAP.put(SPRITES.STONE_SHOVEL, new SimpleSprite("items/stone_shovel.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_PLANKS, new SimpleSprite("items/oak_planks.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_COBBLESTONE, new SimpleSprite("items/cobblestone.ans"));
|
||||
SPRITES_MAP.put(SPRITES.ITEM_CHEST, new SimpleSprite("items/chest.ans"));
|
||||
}
|
||||
|
||||
public static SpriteList<SPRITES> load() {
|
||||
|
@ -67,20 +67,36 @@ public class CraftingRecipeList {
|
||||
{null, "stick", "cobblestone"},
|
||||
{null, "stick", null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.stoneAxe())));
|
||||
|
||||
// Chest
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{"oak_planks", "oak_planks", "oak_planks"},
|
||||
{"oak_planks", null, "oak_planks"},
|
||||
{"oak_planks", "oak_planks", "oak_planks"}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.chest())));
|
||||
|
||||
// Wooden shovel
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{null, "oak_planks", null},
|
||||
{null, "stick", null},
|
||||
{null, "stick", null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.woodenShovel())));
|
||||
|
||||
// Stone shovel
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{null, "cobblestone", null},
|
||||
{null, "stick", null},
|
||||
{null, "stick", null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.stoneShovel())));
|
||||
|
||||
recipes.add(new CraftingRecipe(new String[][]{
|
||||
{"dirt", null, null},
|
||||
{null, null, null},
|
||||
{null, null, null}
|
||||
}, () -> new InventoryItem(1, ItemBlockSupplier.Items.chest())));
|
||||
}
|
||||
|
||||
// 2x2 crafting
|
||||
public static Optional<CraftingRecipe> getRecipeSmall(String[] r) {
|
||||
for (CraftingRecipe recipe : recipes) {
|
||||
if (matchesByItemSet(recipe.getRecipe(), r)) {
|
||||
return Optional.of(recipe);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// 3x3 crafting
|
||||
public static Optional<CraftingRecipe> getRecipeFull(String[] r) {
|
||||
public static Optional<CraftingRecipe> getRecipe(String[] r) {
|
||||
for (CraftingRecipe recipe : recipes) {
|
||||
if (matchesByItemSet(recipe.getRecipe(), r)) {
|
||||
return Optional.of(recipe);
|
||||
|
@ -2,17 +2,44 @@ package cz.jzitnik.game.items;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@AllArgsConstructor
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class InventoryItem {
|
||||
private int amount;
|
||||
private Item item;
|
||||
private final List<Item> item;
|
||||
|
||||
public InventoryItem(int amount, Item item) {
|
||||
this.amount = amount;
|
||||
this.item = new ArrayList<>();
|
||||
this.item.add(item);
|
||||
}
|
||||
|
||||
public InventoryItem() {
|
||||
this.item = new ArrayList<>();
|
||||
this.amount = 0;
|
||||
}
|
||||
|
||||
public void decrease() {
|
||||
amount--;
|
||||
item.removeLast();
|
||||
}
|
||||
|
||||
public void add(Item i) {
|
||||
amount++;
|
||||
item.add(i);
|
||||
}
|
||||
|
||||
public void setAmount(int amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public InventoryItem(Item item) {
|
||||
this.amount = 1;
|
||||
this.item = item;
|
||||
this.item = new ArrayList<>();
|
||||
this.item.add(item);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package cz.jzitnik.game.items;
|
||||
|
||||
import cz.jzitnik.game.SpriteLoader;
|
||||
import cz.jzitnik.game.Block;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -25,6 +26,9 @@ public class ItemBlockSupplier {
|
||||
public static Item craftingTable(Block ref) {
|
||||
return new Item("crafting_table", "Crafting table", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_CRAFTING_TABLE, ref);
|
||||
}
|
||||
public static Item chest(Block ref) {
|
||||
return new Item("chest", "Chest", ItemType.BLOCK, SpriteLoader.SPRITES.ITEM_CHEST, ref);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Blocks {
|
||||
@ -63,6 +67,11 @@ public class ItemBlockSupplier {
|
||||
block.setDrops(List.of(Helper.craftingTable(block)));
|
||||
return block;
|
||||
}
|
||||
public static Block chest() {
|
||||
var block = new Block("chest", SpriteLoader.SPRITES.CHEST, 3, ItemType.AXE, new ArrayList<>(), new Chest());
|
||||
block.setDrops(List.of(Helper.chest(block)));
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
// I hate this but whatever
|
||||
@ -94,5 +103,14 @@ public class ItemBlockSupplier {
|
||||
public static Item stoneAxe() {
|
||||
return new Item("stone_axe", "Stone axe", ItemType.AXE, SpriteLoader.SPRITES.STONE_AXE, ToolVariant.STONE, 3, 132, false);
|
||||
}
|
||||
public static Item woodenShovel() {
|
||||
return new Item("wooden_shovel", "Wooden shovel", ItemType.SHOVEL, SpriteLoader.SPRITES.WOODEN_SHOVEL, ToolVariant.WOODEN, 0.3, 59, false);
|
||||
}
|
||||
public static Item chest() {
|
||||
return Helper.chest(Blocks.chest());
|
||||
}
|
||||
public static Item stoneShovel() {
|
||||
return new Item("stone_shovel", "Stone shovel", ItemType.SHOVEL, SpriteLoader.SPRITES.STONE_SHOVEL, ToolVariant.STONE, 0.5, 132, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,23 @@ package cz.jzitnik.game.sprites;
|
||||
import cz.jzitnik.tui.ResourceLoader;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Steve extends Sprite {
|
||||
private String fix(String x) {
|
||||
var arr = x.replaceAll("\033\\[38;5;1;48;5;16m", "\033[49m").split("\n");
|
||||
arr = Arrays.copyOf(arr, arr.length - 1); // Remove the last line
|
||||
return ("\033[0m ".repeat(50) + "\n").repeat(3) + Arrays.stream(arr).map(y -> "\033[0m ".repeat(12) + y + " " + "\033[0m ".repeat(12) + "\n").collect(Collectors.joining());
|
||||
public enum SteveState{
|
||||
FIRST,
|
||||
SECOND,
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
return fix(ResourceLoader.loadResource("steve.ans"));
|
||||
throw new RuntimeException("Error");
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
throw new RuntimeException("Imposible state");
|
||||
return ResourceLoader.loadResource(
|
||||
switch (e) {
|
||||
case SteveState.FIRST -> "steve1.ans";
|
||||
case SteveState.SECOND -> "steve2.ans";
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
package cz.jzitnik.game.sprites;
|
||||
|
||||
public enum Window {
|
||||
WORLD,
|
||||
INVENTORY,
|
||||
CRAFTING_TABLE
|
||||
}
|
101
src/main/java/cz/jzitnik/game/ui/Chest.java
Normal file
101
src/main/java/cz/jzitnik/game/ui/Chest.java
Normal file
@ -0,0 +1,101 @@
|
||||
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.tui.ScreenRenderer;
|
||||
import cz.jzitnik.tui.SpriteList;
|
||||
import org.jline.terminal.MouseEvent;
|
||||
import org.jline.terminal.Terminal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Chest {
|
||||
private static final int ROW_AMOUNT = 4;
|
||||
private static final int COLUMN_AMOUNT = 6;
|
||||
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[ROW_AMOUNT * COLUMN_AMOUNT];
|
||||
private int size;
|
||||
|
||||
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<String> sprites = game.getInventory().getSprites(items, spriteList, inventory.getSelectedItemInv() - 50);
|
||||
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipe(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getFirst().getId()).toArray(String[]::new));
|
||||
|
||||
Optional<InventoryItem> craftedItem = recipe.map(craftingRecipe -> craftingRecipe.getItemSupplier().get());
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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 heightPixels = ROW_AMOUNT * (CELL_HEIGHT + 1);
|
||||
int moveLeft = (terminal.getWidth() / 2) - (widthPixels / 2);
|
||||
|
||||
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 void breakChest(Game game) {
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
if (items[i] == null) {
|
||||
continue;
|
||||
}
|
||||
game.getInventory().addItem(items[i]);
|
||||
items[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
26
src/main/java/cz/jzitnik/game/ui/CloseHandler.java
Normal file
26
src/main/java/cz/jzitnik/game/ui/CloseHandler.java
Normal file
@ -0,0 +1,26 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CloseHandler {
|
||||
@FunctionalInterface
|
||||
public interface Function<T> {
|
||||
void call(T t);
|
||||
}
|
||||
|
||||
public static HashMap<Window, Function<Game>> handles = new HashMap<>();
|
||||
|
||||
static {
|
||||
handles.put(Window.CRAFTING_TABLE, game -> game.getGameStates().craftingTable.exit());
|
||||
}
|
||||
|
||||
public static void handle(Window window, Game game) {
|
||||
if (handles.containsKey(window)) {
|
||||
var func = handles.get(window);
|
||||
|
||||
func.call(game);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ 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;
|
||||
@ -24,7 +23,7 @@ public class CraftingTable {
|
||||
private static final int CELL_HEIGHT = 25;
|
||||
private static final int BORDER_SIZE = 2;
|
||||
|
||||
private final InventoryItem[] items = new InventoryItem[9];
|
||||
private final InventoryItem[] items = new InventoryItem[ROW_AMOUNT * COLUMN_AMOUNT];
|
||||
private int size;
|
||||
|
||||
public void render(int ignored, int ignored2) {
|
||||
@ -32,7 +31,7 @@ public class CraftingTable {
|
||||
}
|
||||
|
||||
public void pickup() {
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipeSmall(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getId()).toArray(String[]::new));
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipe(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getFirst().getId()).toArray(String[]::new));
|
||||
|
||||
if (recipe.isPresent()) {
|
||||
InventoryItem item = recipe.get().getItemSupplier().get();
|
||||
@ -47,7 +46,7 @@ public class CraftingTable {
|
||||
if (it.getAmount() == 1) {
|
||||
items[i] = null;
|
||||
} else {
|
||||
it.setAmount(it.getAmount() - 1);
|
||||
it.decrease();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,12 +60,12 @@ public class CraftingTable {
|
||||
|
||||
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<CraftingRecipe> recipe = CraftingRecipeList.getRecipe(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getFirst().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(),
|
||||
spriteList.getSprite(inventoryItem.getItem().getFirst().getSprite()).getSprite(),
|
||||
Numbers.getNumberSprite(inventoryItem.getAmount())
|
||||
).split("\n")).orElse(null);
|
||||
|
||||
@ -146,6 +145,19 @@ public class CraftingTable {
|
||||
InventoryClickHandler.click(mouseEvent, terminal, screenRenderer, game, Optional.of(size + 20), Optional.of(items));
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
// Put all items from crafting to inv
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
InventoryItem item = items[i];
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
game.getInventory().addItem(item);
|
||||
items[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
public CraftingTable(Game game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class Inventory {
|
||||
if (hotbar[itemInhHandIndex] == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(hotbar[itemInhHandIndex].getItem());
|
||||
return Optional.of(hotbar[itemInhHandIndex].getItem().getLast());
|
||||
}
|
||||
|
||||
public void decreaseItemInHand() {
|
||||
@ -47,7 +47,7 @@ public class Inventory {
|
||||
return;
|
||||
}
|
||||
|
||||
hotbar[itemInhHandIndex].setAmount(hotbar[itemInhHandIndex].getAmount() - 1);
|
||||
hotbar[itemInhHandIndex].decrease();
|
||||
}
|
||||
|
||||
private void placeItem(Item item) {
|
||||
@ -74,7 +74,7 @@ public class Inventory {
|
||||
|
||||
public void addItem(InventoryItem item) {
|
||||
for (int i = 0; i < item.getAmount(); i++) {
|
||||
addItem(item.getItem());
|
||||
addItem(item.getItem().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,16 +86,16 @@ public class Inventory {
|
||||
|
||||
// Try to stack in hotbar
|
||||
for (InventoryItem value : hotbar) {
|
||||
if (value != null && value.getItem().equals(item) && value.getAmount() < item.getStackAmount()) {
|
||||
value.setAmount(value.getAmount() + 1);
|
||||
if (value != null && value.getItem().getFirst().equals(item) && value.getAmount() < item.getStackAmount()) {
|
||||
value.add(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to stack in inventory
|
||||
for (InventoryItem inventoryItem : items) {
|
||||
if (inventoryItem != null && inventoryItem.getItem().equals(item) && inventoryItem.getAmount() < item.getStackAmount()) {
|
||||
inventoryItem.setAmount(inventoryItem.getAmount() + 1);
|
||||
if (inventoryItem != null && inventoryItem.getItem().getFirst().equals(item) && inventoryItem.getAmount() < item.getStackAmount()) {
|
||||
inventoryItem.add(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -223,14 +223,14 @@ public class Inventory {
|
||||
|
||||
if (i == selectedItem) {
|
||||
sprites.add(SpriteCombiner.combineTwoSprites(getHotbarBackground(), SpriteCombiner.combineTwoSprites(
|
||||
spriteList.getSprite(item.getItem().getSprite()).getSprite(),
|
||||
spriteList.getSprite(item.getItem().getFirst().getSprite()).getSprite(),
|
||||
Numbers.getNumberSprite(item.getAmount())
|
||||
)));
|
||||
continue;
|
||||
}
|
||||
|
||||
sprites.add(SpriteCombiner.combineTwoSprites(
|
||||
spriteList.getSprite(item.getItem().getSprite()).getSprite(),
|
||||
spriteList.getSprite(item.getItem().getFirst().getSprite()).getSprite(),
|
||||
Numbers.getNumberSprite(item.getAmount())
|
||||
));
|
||||
}
|
||||
@ -272,11 +272,12 @@ public class Inventory {
|
||||
return getSelectedItem(i);
|
||||
}
|
||||
|
||||
item.setAmount(item.getAmount() - 1);
|
||||
|
||||
rightClick = false;
|
||||
|
||||
return new InventoryItem(1, item.getItem());
|
||||
var ij = new InventoryItem(1, item.getItem().getLast());
|
||||
item.decrease();
|
||||
|
||||
return ij;
|
||||
}
|
||||
|
||||
public InventoryItem getHalf(Optional<InventoryItem[]> i) {
|
||||
@ -287,12 +288,18 @@ public class Inventory {
|
||||
}
|
||||
|
||||
int half = item.getAmount() / 2;
|
||||
item.setAmount(item.getAmount() - half);
|
||||
|
||||
var inv = new InventoryItem();
|
||||
|
||||
for (int j = 0; j < half; j++) {
|
||||
inv.add(item.getItem().getLast());
|
||||
item.decrease();
|
||||
}
|
||||
|
||||
selectedItemInv = -1;
|
||||
rightClick = false;
|
||||
|
||||
return new InventoryItem(half, item.getItem());
|
||||
return inv;
|
||||
}
|
||||
|
||||
public boolean hasSelectedItem() {
|
||||
@ -310,22 +317,26 @@ public class Inventory {
|
||||
return; // Nothing to merge
|
||||
}
|
||||
|
||||
if (!fromItem.getItem().isStackable() || !toItem.getItem().isStackable()) {
|
||||
if (!fromItem.getItem().getFirst().isStackable() || !toItem.getItem().getFirst().isStackable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fromItem.getItem().equals(toItem.getItem())) {
|
||||
if (!fromItem.getItem().getFirst().equals(toItem.getItem().getFirst())) {
|
||||
return; // Different items cannot be merged
|
||||
}
|
||||
|
||||
int totalAmount = fromItem.getAmount() + toItem.getAmount();
|
||||
while (true) {
|
||||
if (toItem.getAmount() == 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (totalAmount > 64) {
|
||||
toItem.setAmount(64);
|
||||
fromItem.setAmount(totalAmount - 64);
|
||||
} else {
|
||||
toItem.setAmount(totalAmount);
|
||||
fromData.getObj()[fromData.getIndex()] = null; // Remove the source item after merging
|
||||
if (fromItem.getAmount() == 0) {
|
||||
fromData.getObj()[fromData.getIndex()] = null;
|
||||
break;
|
||||
}
|
||||
|
||||
toItem.add(fromItem.getItem().getLast());
|
||||
fromItem.decrease();
|
||||
}
|
||||
|
||||
selectedItemInv = -1;
|
||||
@ -338,13 +349,13 @@ public class Inventory {
|
||||
InventoryItem fromItem = fromSlot.getObj()[fromSlot.getIndex()];
|
||||
InventoryItem toItem = toSlot.getObj()[toSlot.getIndex()];
|
||||
|
||||
if (fromItem == null || !fromItem.getItem().equals(toItem.getItem()) || toItem.getAmount() >= fromItem.getItem().getStackAmount()) {
|
||||
if (fromItem == null || !fromItem.getItem().getFirst().equals(toItem.getItem().getFirst()) || toItem.getAmount() >= fromItem.getItem().getFirst().getStackAmount()) {
|
||||
return; // Can't merge
|
||||
}
|
||||
|
||||
// Move only one item
|
||||
toItem.setAmount(toItem.getAmount() + 1);
|
||||
fromItem.setAmount(fromItem.getAmount() - 1);
|
||||
toItem.add(fromItem.getItem().getLast());
|
||||
fromItem.decrease();
|
||||
|
||||
// Remove source item if empty
|
||||
if (fromItem.getAmount() <= 0) {
|
||||
|
@ -21,7 +21,7 @@ public class SmallCraftingTable {
|
||||
private InventoryItem[] items = new InventoryItem[4];
|
||||
|
||||
public void pickup() {
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipeSmall(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getId()).toArray(String[]::new));
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipe(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getFirst().getId()).toArray(String[]::new));
|
||||
|
||||
if (recipe.isPresent()) {
|
||||
InventoryItem item = recipe.get().getItemSupplier().get();
|
||||
@ -36,7 +36,7 @@ public class SmallCraftingTable {
|
||||
if (it.getAmount() == 1) {
|
||||
items[i] = null;
|
||||
} else {
|
||||
it.setAmount(it.getAmount() - 1);
|
||||
it.decrease();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,12 +47,12 @@ public class SmallCraftingTable {
|
||||
|
||||
List<String> sprites = inventory.getSprites(items, spriteList, inventory.getSelectedItemInv() - 29);
|
||||
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipeSmall(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getId()).toArray(String[]::new));
|
||||
Optional<CraftingRecipe> recipe = CraftingRecipeList.getRecipe(Arrays.stream(items).map(item -> item == null ? null: item.getItem().getFirst().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(),
|
||||
spriteList.getSprite(inventoryItem.getItem().getFirst().getSprite()).getSprite(),
|
||||
Numbers.getNumberSprite(inventoryItem.getAmount())
|
||||
).split("\n")).orElse(null);
|
||||
|
||||
|
8
src/main/java/cz/jzitnik/game/ui/Window.java
Normal file
8
src/main/java/cz/jzitnik/game/ui/Window.java
Normal file
@ -0,0 +1,8 @@
|
||||
package cz.jzitnik.game.ui;
|
||||
|
||||
public enum Window {
|
||||
WORLD,
|
||||
INVENTORY,
|
||||
CRAFTING_TABLE,
|
||||
CHEST
|
||||
}
|
@ -2,6 +2,8 @@ package cz.jzitnik.tui;
|
||||
|
||||
import cz.jzitnik.game.Block;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
import cz.jzitnik.game.ui.Chest;
|
||||
import cz.jzitnik.tui.utils.SpriteCombiner;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -29,7 +31,7 @@ public class ScreenRenderer {
|
||||
private int[] getPlayerCords(List<Block>[][] world) {
|
||||
for (int i = 0; i < world.length; i++) {
|
||||
for (int j = 0; j < world[i].length; j++) {
|
||||
if (world[i][j].stream().anyMatch(x -> x.getBlockId().equals("steve"))) {
|
||||
if (world[i][j].stream().anyMatch(x -> x.getBlockId().equals("steve") && x.getSpriteState().isPresent() && x.getSpriteState().get() == Steve.SteveState.SECOND)) {
|
||||
return new int[]{j, i};
|
||||
}
|
||||
}
|
||||
@ -45,6 +47,7 @@ public class ScreenRenderer {
|
||||
switch (game.getWindow()) {
|
||||
case INVENTORY -> game.getInventory().renderFull(main, terminal, spriteList, true, Optional.empty());
|
||||
case CRAFTING_TABLE -> game.getGameStates().craftingTable.render(main, terminal, spriteList);
|
||||
case CHEST -> ((Chest) game.getWorld()[game.getGameStates().clickY][game.getGameStates().clickX].stream().filter(i -> i.getBlockId().equals("chest")).toList().getFirst().getData()).render(game, main, terminal, spriteList);
|
||||
case WORLD -> {
|
||||
// World
|
||||
|
||||
|
@ -33,6 +33,7 @@ public class SpriteCombiner {
|
||||
int cursor2 = 0;
|
||||
|
||||
// Ensure we stay within the bounds of both rows.
|
||||
int prev = -1;
|
||||
while (cursor1 < row1.length() && cursor2 < row2.length()) {
|
||||
String color1 = extractColorCode(row1, cursor1);
|
||||
int pixelIndex1 = cursor1 + color1.length();
|
||||
@ -45,8 +46,15 @@ public class SpriteCombiner {
|
||||
char pixel2 = row2.charAt(pixelIndex2);
|
||||
|
||||
if (color2.equals("\033[0m") && pixel2 == ' ' || color2.equals("\033[49m") && pixel2 == ' ') {
|
||||
if (prev != 1 && color1.isEmpty()) {
|
||||
combinedRow.append(getColorCode(row1, cursor1));
|
||||
prev = 1;
|
||||
}
|
||||
combinedRow.append(color1).append(pixel1);
|
||||
} else {
|
||||
if (prev != 2) {
|
||||
prev = 2;
|
||||
}
|
||||
combinedRow.append(color2).append(pixel2);
|
||||
}
|
||||
|
||||
@ -60,6 +68,14 @@ public class SpriteCombiner {
|
||||
return combinedSprite.toString();
|
||||
}
|
||||
|
||||
private static String getColorCode(String row, int index) {
|
||||
if (row.charAt(index) != '\033') {
|
||||
return getColorCode(row, index - 1);
|
||||
}
|
||||
|
||||
return extractColorCode(row, index);
|
||||
}
|
||||
|
||||
private static String extractColorCode(String row, int index) {
|
||||
StringBuilder colorCode = new StringBuilder();
|
||||
|
||||
|
Reference in New Issue
Block a user