diff --git a/src/main/java/cz/jzitnik/events/RenderStats.java b/src/main/java/cz/jzitnik/events/RenderStats.java new file mode 100644 index 0000000..b44b62b --- /dev/null +++ b/src/main/java/cz/jzitnik/events/RenderStats.java @@ -0,0 +1,6 @@ +package cz.jzitnik.events; + +import cz.jzitnik.utils.events.Event; + +public class RenderStats implements Event { +} diff --git a/src/main/java/cz/jzitnik/events/handlers/FullRoomDrawHandler.java b/src/main/java/cz/jzitnik/events/handlers/FullRoomDrawHandler.java index 010dffa..e64025f 100644 --- a/src/main/java/cz/jzitnik/events/handlers/FullRoomDrawHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/FullRoomDrawHandler.java @@ -19,6 +19,7 @@ import cz.jzitnik.states.RenderState; import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.states.TerminalState; import cz.jzitnik.ui.Inventory; +import cz.jzitnik.ui.Stats; import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.utils.UIClickHandlerRepository; @@ -58,6 +59,8 @@ public class FullRoomDrawHandler extends AbstractEventHandler { private UIClickHandlerRepository uiClickHandlerRepository; @InjectDependency private Inventory inventory; + @InjectDependency + private Stats stats; public FullRoomDrawHandler(DependencyManager dm) { super(dm); @@ -86,6 +89,7 @@ public class FullRoomDrawHandler extends AbstractEventHandler { RerenderUtils.rerenderPart(0, width - 1, 0, height - 1, startX, startY, currentRoom, room, player, playerTexture, screenBuffer, resourceManager, debugging); if (event.isFullRerender()) { inventory.renderInventoryRerender(); + stats.rerender(); uiClickHandlerRepository.registerGlobalHandler(inventory); } diff --git a/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java index 52040ed..5a49ea6 100644 --- a/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/PlayerMoveEventHandler.java @@ -21,6 +21,7 @@ import cz.jzitnik.states.RenderState; import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.states.PlayerMovementState; import cz.jzitnik.states.TerminalState; +import cz.jzitnik.ui.Stats; import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.utils.RerenderUtils; import cz.jzitnik.utils.events.AbstractEventHandler; @@ -52,6 +53,8 @@ public class PlayerMoveEventHandler extends AbstractEventHandler { + @InjectDependency + private EventManager eventManager; + + @InjectDependency + private Stats stats; + + public RenderStatsHandler(DependencyManager dm) { + super(dm); + } + + @Override + public void handle(RenderStats event) { + stats.rerender(); + eventManager.emitEvent(new RerenderScreen(new RerenderScreen.ScreenPart( + new TerminalPosition(Stats.OFFSET_X, Stats.OFFSET_X), + new TerminalPosition(Stats.OFFSET_X + Stats.WIDTH, Stats.OFFSET_Y + Stats.HEIGHT) + ))); + } +} diff --git a/src/main/java/cz/jzitnik/events/handlers/RoomChangeEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/RoomChangeEventHandler.java index a74f241..27fc873 100644 --- a/src/main/java/cz/jzitnik/events/handlers/RoomChangeEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/RoomChangeEventHandler.java @@ -49,10 +49,10 @@ public class RoomChangeEventHandler extends AbstractEventHandler playerCords.updateCords(155, 60); - case RIGHT -> playerCords.updateCords(30, 50); - case TOP -> playerCords.updateCords(90, 110); - case BOTTOM -> playerCords.updateCords(90, 10); + case LEFT -> playerCords.updateCords(155, playerCords.getY()); + case RIGHT -> playerCords.updateCords(30, playerCords.getY()); + case TOP -> playerCords.updateCords(playerCords.getX(), 110); + case BOTTOM -> playerCords.updateCords(playerCords.getX(), 10); } gameState.setCurrentRoom(newRoom); diff --git a/src/main/java/cz/jzitnik/game/Player.java b/src/main/java/cz/jzitnik/game/Player.java index 8987650..d5c8d4a 100644 --- a/src/main/java/cz/jzitnik/game/Player.java +++ b/src/main/java/cz/jzitnik/game/Player.java @@ -27,13 +27,11 @@ public class Player { private GameItem selectedItem; private boolean swinging = false; - public int increaseStamina() { - log.debug("Stamina: {}", stamina + 1); - return ++stamina; + public void increaseStamina() { + stamina++; } - public int decreaseStamina() { - log.debug("Stamina: {}", stamina - 1); - return --stamina; + public void decreaseStamina() { + stamina--; } public int getDamageDeal() { diff --git a/src/main/java/cz/jzitnik/game/objects/Chest.java b/src/main/java/cz/jzitnik/game/objects/Chest.java index 8ce176a..bd440fe 100644 --- a/src/main/java/cz/jzitnik/game/objects/Chest.java +++ b/src/main/java/cz/jzitnik/game/objects/Chest.java @@ -250,7 +250,7 @@ public final class Chest extends GameObject implements UIClickHandler { } @Override - public void handleClick(MouseAction mouseAction) { + public boolean handleClick(MouseAction mouseAction) { int mouseX = mouseAction.getPosition().getColumn(); int mouseY = mouseAction.getPosition().getRow(); @@ -262,21 +262,23 @@ public final class Chest extends GameObject implements UIClickHandler { int itemIndex = grid.getItemIndexAt(localX, localY); if (itemIndex == -1 || itemIndex >= items.size()) { - return; + return false; } GameItem item = items.get(itemIndex); boolean added = gameState.getPlayer().addItem(item); if (!added) { - return; + return true; } eventManager.emitEvent(new InventoryRerender()); items.remove(item); if (items.isEmpty()) { - uiClickHandlerRepository.removeHandlerForCurrentRoom(listenerHashCode, this); + uiClickHandlerRepository.removeHandlerForCurrentRoom(listenerHashCode); } render(true); + + return true; } } diff --git a/src/main/java/cz/jzitnik/game/objects/UIClickHandler.java b/src/main/java/cz/jzitnik/game/objects/UIClickHandler.java index ae24249..f3775af 100644 --- a/src/main/java/cz/jzitnik/game/objects/UIClickHandler.java +++ b/src/main/java/cz/jzitnik/game/objects/UIClickHandler.java @@ -3,8 +3,12 @@ package cz.jzitnik.game.objects; import cz.jzitnik.events.MouseAction; public interface UIClickHandler { - void handleClick(MouseAction mouseAction); + boolean handleClick(MouseAction mouseAction); - default void handleMove(MouseAction ignoredMouseAction) {} - default void handleElse(MouseAction ignoredMouseAction) {} + default boolean handleMove(MouseAction ignoredMouseAction) { + return false; + } + default boolean handleElse(MouseAction ignoredMouseAction) { + return false; + } } diff --git a/src/main/java/cz/jzitnik/tasks/StaminaIncreaseTask.java b/src/main/java/cz/jzitnik/tasks/StaminaIncreaseTask.java index 74b85f1..55fb3df 100644 --- a/src/main/java/cz/jzitnik/tasks/StaminaIncreaseTask.java +++ b/src/main/java/cz/jzitnik/tasks/StaminaIncreaseTask.java @@ -5,11 +5,13 @@ import cz.jzitnik.annotations.injectors.InjectConfig; import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.config.PlayerConfig; +import cz.jzitnik.events.RenderStats; import cz.jzitnik.game.GameState; import cz.jzitnik.game.Player; import cz.jzitnik.states.PlayerMovementState; import cz.jzitnik.utils.DependencyManager; import cz.jzitnik.utils.ScheduledTaskManager; +import cz.jzitnik.utils.events.EventManager; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -55,6 +57,9 @@ public class StaminaIncreaseTask implements Runnable { @InjectConfig private PlayerConfig playerConfig; + @InjectDependency + private EventManager eventManager; + @Override public void run() { long nowTime = System.currentTimeMillis(); @@ -68,6 +73,7 @@ public class StaminaIncreaseTask implements Runnable { } player.increaseStamina(); + eventManager.emitEvent(new RenderStats()); } } } diff --git a/src/main/java/cz/jzitnik/ui/Stats.java b/src/main/java/cz/jzitnik/ui/Stats.java new file mode 100644 index 0000000..5a9a8e8 --- /dev/null +++ b/src/main/java/cz/jzitnik/ui/Stats.java @@ -0,0 +1,51 @@ +package cz.jzitnik.ui; + +import com.googlecode.lanterna.TextColor; +import cz.jzitnik.annotations.Dependency; +import cz.jzitnik.annotations.injectors.InjectState; +import cz.jzitnik.game.GameState; +import cz.jzitnik.game.Player; +import cz.jzitnik.states.ScreenBuffer; +import cz.jzitnik.ui.pixels.ColoredPixel; +import cz.jzitnik.ui.pixels.Empty; +import cz.jzitnik.ui.pixels.Pixel; +import lombok.Getter; + +@Getter +@Dependency +public class Stats { + public static final int BARS_COUNT = 1; + public static final int BAR_WIDTH = 72; + public static final int BAR_HEIGHT = 8; + public static final int BAR_PADDING = 2; + public static final int HEIGHT = BAR_HEIGHT * BARS_COUNT + (BAR_PADDING * (BARS_COUNT - 1)); + public static final int WIDTH = BAR_WIDTH; + + public static final int OFFSET_X = 5; + public static final int OFFSET_Y = 5; + + private static final Pixel STAMINA_COLOR = new ColoredPixel(new TextColor.RGB(207, 175, 89)); + + @InjectState + private GameState gameState; + + @InjectState + private ScreenBuffer screenBuffer; + + public void rerender() { + var buffer = screenBuffer.getRenderedBuffer(); + + float staminaDelta = (float) gameState.getPlayer().getStamina() / Player.MAX_STAMINA; + float staminaAmount = (BAR_WIDTH - 2) * staminaDelta; + + for (int x = 0; x < BAR_WIDTH; x++) { + for (int y = 0; y < BAR_HEIGHT; y++) { + if (x == 0 || y == 0 || x == BAR_WIDTH - 1 || y == BAR_HEIGHT - 1 || x - 1 < staminaAmount) { + buffer[y + OFFSET_Y][x + OFFSET_X] = STAMINA_COLOR; + } else { + buffer[y + OFFSET_Y][x + OFFSET_X] = new Empty(); + } + } + } + } +} diff --git a/src/main/java/cz/jzitnik/utils/UIClickHandlerRepository.java b/src/main/java/cz/jzitnik/utils/UIClickHandlerRepository.java index 45d3b85..5caa79e 100644 --- a/src/main/java/cz/jzitnik/utils/UIClickHandlerRepository.java +++ b/src/main/java/cz/jzitnik/utils/UIClickHandlerRepository.java @@ -48,15 +48,16 @@ public class UIClickHandlerRepository { public boolean handleClick(MouseAction mouseAction) { if (roomSpecificHandlers.containsKey(gameState.getCurrentRoom())) { Map handlers = roomSpecificHandlers.get(gameState.getCurrentRoom()); + TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); for (var entry : handlers.entrySet()) { RerenderScreen.ScreenPart part = entry.getKey(); UIClickHandler uiClickHandler = entry.getValue(); - TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); if (part.isWithin(position)) { - uiClickHandler.handleClick(mouseAction); - return true; + if (uiClickHandler.handleClick(mouseAction)) { + return true; + } } } } @@ -73,15 +74,16 @@ public class UIClickHandlerRepository { public boolean handleElse(MouseAction mouseAction) { if (roomSpecificHandlers.containsKey(gameState.getCurrentRoom())) { Map handlers = roomSpecificHandlers.get(gameState.getCurrentRoom()); + TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); for (var entry : handlers.entrySet()) { RerenderScreen.ScreenPart part = entry.getKey(); UIClickHandler uiClickHandler = entry.getValue(); - TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); if (part.isWithin(position)) { - uiClickHandler.handleElse(mouseAction); - return true; + if (uiClickHandler.handleElse(mouseAction)) { + return true; + } } } } @@ -98,14 +100,15 @@ public class UIClickHandlerRepository { public boolean handleMove(MouseAction mouseAction) { if (roomSpecificHandlers.containsKey(gameState.getCurrentRoom())) { Map handlers = roomSpecificHandlers.get(gameState.getCurrentRoom()); + TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); for (var entry : handlers.entrySet()) { RerenderScreen.ScreenPart part = entry.getKey(); UIClickHandler uiClickHandler = entry.getValue(); - TerminalPosition position = new TerminalPosition(mouseAction.getPosition().getColumn(), mouseAction.getPosition().getRow() * 2); if (part.isWithin(position)) { - uiClickHandler.handleMove(mouseAction); - return true; + if (uiClickHandler.handleMove(mouseAction)) { + return true; + } } } } @@ -119,14 +122,14 @@ public class UIClickHandlerRepository { return false; } - public void removeHandlerForCurrentRoom(int screenPartHashCode, UIClickHandler uiClickHandler) { + public void removeHandlerForCurrentRoom(int screenPartHashCode) { GameRoom currentRoom = gameState.getCurrentRoom(); if (!roomSpecificHandlers.containsKey(currentRoom)) return; Map handlers = roomSpecificHandlers.get(currentRoom); for (var key : handlers.keySet()) { if (key.hashCode() == screenPartHashCode) { - handlers.remove(key, uiClickHandler); + handlers.remove(key); } } }