diff --git a/.idea/misc.xml b/.idea/misc.xml index 8569d1d..3202223 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -20,7 +20,7 @@ - + \ No newline at end of file diff --git a/src/main/java/cz/jzitnik/Main.java b/src/main/java/cz/jzitnik/Main.java index 884a74a..b320606 100644 --- a/src/main/java/cz/jzitnik/Main.java +++ b/src/main/java/cz/jzitnik/Main.java @@ -1,5 +1,7 @@ package cz.jzitnik; +// events/handlers/MouseMoveEventHandler.java + public class Main { public static void main(String[] args) { new Game().start(); diff --git a/src/main/java/cz/jzitnik/events/DroppedItemRerender.java b/src/main/java/cz/jzitnik/events/DroppedItemRerender.java new file mode 100644 index 0000000..df80a81 --- /dev/null +++ b/src/main/java/cz/jzitnik/events/DroppedItemRerender.java @@ -0,0 +1,7 @@ +package cz.jzitnik.events; + +import cz.jzitnik.game.objects.DroppedItem; +import cz.jzitnik.utils.events.Event; + +public record DroppedItemRerender(DroppedItem droppedItem) implements Event { +} diff --git a/src/main/java/cz/jzitnik/events/handlers/DroppedItemRerenderHandler.java b/src/main/java/cz/jzitnik/events/handlers/DroppedItemRerenderHandler.java new file mode 100644 index 0000000..983ea68 --- /dev/null +++ b/src/main/java/cz/jzitnik/events/handlers/DroppedItemRerenderHandler.java @@ -0,0 +1,84 @@ +package cz.jzitnik.events.handlers; + +import com.googlecode.lanterna.TerminalPosition; +import cz.jzitnik.annotations.EventHandler; +import cz.jzitnik.annotations.injectors.InjectConfig; +import cz.jzitnik.annotations.injectors.InjectDependency; +import cz.jzitnik.annotations.injectors.InjectState; +import cz.jzitnik.config.Debugging; +import cz.jzitnik.events.DroppedItemRerender; +import cz.jzitnik.events.RerenderScreen; +import cz.jzitnik.game.GameState; +import cz.jzitnik.game.ResourceManager; +import cz.jzitnik.game.utils.RoomCords; +import cz.jzitnik.states.ScreenBuffer; +import cz.jzitnik.states.TerminalState; +import cz.jzitnik.utils.DependencyManager; +import cz.jzitnik.utils.RerenderUtils; +import cz.jzitnik.utils.events.AbstractEventHandler; +import cz.jzitnik.utils.events.EventManager; + +import java.awt.image.BufferedImage; + +@EventHandler(DroppedItemRerender.class) +public class DroppedItemRerenderHandler extends AbstractEventHandler { + public DroppedItemRerenderHandler(DependencyManager dm) { + super(dm); + } + + @InjectDependency + private EventManager eventManager; + + @InjectDependency + private ResourceManager resourceManager; + + @InjectState + private GameState gameState; + + @InjectState + private TerminalState terminalState; + + @InjectState + private ScreenBuffer screenBuffer; + + @InjectConfig + private Debugging debugging; + + @Override + public void handle(DroppedItemRerender event) { + RoomCords droppedItemCords = event.droppedItem().getCords(); + BufferedImage droppedItemTexture = event.droppedItem().getTexture(); + BufferedImage playerTexture = RerenderUtils.getPlayer(resourceManager, gameState.getPlayer()); + BufferedImage room = resourceManager.getResource(gameState.getCurrentRoom().getTexture()); + RoomCords start = RerenderUtils.getStart(room, terminalState.getTerminalScreen().getTerminalSize()); + + RerenderScreen.ScreenPart part = new RerenderScreen.ScreenPart( + new TerminalPosition( + start.getX() + droppedItemCords.getX(), + start.getY() + droppedItemCords.getY() + ), + new TerminalPosition( + start.getX() + droppedItemCords.getX() + droppedItemTexture.getWidth(), + start.getY() + droppedItemCords.getY() + droppedItemTexture.getHeight() + ) + ); + + RerenderUtils.rerenderPart( + droppedItemCords.getX(), + droppedItemCords.getX() + droppedItemTexture.getWidth(), + droppedItemCords.getY(), + droppedItemCords.getY() + droppedItemTexture.getHeight(), + start.getX(), + start.getY(), + gameState.getCurrentRoom(), + room, + gameState.getPlayer(), + playerTexture, + screenBuffer, + resourceManager, + debugging + ); + + eventManager.emitEvent(new RerenderScreen(part)); + } +} diff --git a/src/main/java/cz/jzitnik/events/handlers/MouseActionEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/MouseActionEventHandler.java index 36a0033..0720465 100644 --- a/src/main/java/cz/jzitnik/events/handlers/MouseActionEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/MouseActionEventHandler.java @@ -66,8 +66,10 @@ public class MouseActionEventHandler extends AbstractEventHandler { } Stream combined = Stream.concat( - gameState.getCurrentRoom().getMobs().stream(), - gameState.getCurrentRoom().getObjects().stream() + Stream.concat( + gameState.getCurrentRoom().getMobs().stream(), + gameState.getCurrentRoom().getObjects().stream()), + gameState.getCurrentRoom().getDroppedItems().stream() ); Optional object = combined.filter(Selectable::isSelected).findFirst(); diff --git a/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java index 41617ea..16b1e93 100644 --- a/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java +++ b/src/main/java/cz/jzitnik/events/handlers/MouseMoveEventHandler.java @@ -14,8 +14,6 @@ import cz.jzitnik.game.GameRoom; import cz.jzitnik.game.GameState; import cz.jzitnik.game.Player; import cz.jzitnik.game.ResourceManager; -import cz.jzitnik.game.objects.GameObject; -import cz.jzitnik.game.utils.Renderable; import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.game.utils.Selectable; import cz.jzitnik.states.ScreenBuffer; @@ -31,6 +29,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -93,8 +92,16 @@ public class MouseMoveEventHandler extends AbstractEventHandler int startX = start.getX(); int startY = start.getY(); - List combinedObjects = Stream - .concat(currentRoom.getObjects().stream(), currentRoom.getMobs().stream()).toList(); + /*List _combinedObjects = Stream.of( + currentRoom.getObjects().stream(), + currentRoom.getMobs().stream(), + currentRoom.getDroppedItems().stream()) + .flatMap(Function.identity()).toList();*/ // For some reason doesn't compile + + List combinedObjects = Stream.concat(Stream.concat( + currentRoom.getObjects().stream(), + currentRoom.getMobs().stream() + ), currentRoom.getDroppedItems().stream()).toList(); Set selectedObjects = combinedObjects.stream().filter(gameObject -> { if (!gameObject.isSelectable()) return false; @@ -123,9 +130,9 @@ public class MouseMoveEventHandler extends AbstractEventHandler return relativeMouseX >= cords.getX() && - relativeMouseX < cords.getX() + texture.getWidth() && - relativeMouseY >= cords.getY() && - relativeMouseY < cords.getY() + texture.getHeight(); + relativeMouseX < cords.getX() + texture.getWidth() && + relativeMouseY >= cords.getY() && + relativeMouseY < cords.getY() + texture.getHeight(); }).collect(Collectors.toSet()); Set changedObjects = new HashSet<>(); diff --git a/src/main/java/cz/jzitnik/game/GameRoom.java b/src/main/java/cz/jzitnik/game/GameRoom.java index 50326eb..53a0869 100644 --- a/src/main/java/cz/jzitnik/game/GameRoom.java +++ b/src/main/java/cz/jzitnik/game/GameRoom.java @@ -1,5 +1,6 @@ package cz.jzitnik.game; +import cz.jzitnik.game.objects.DroppedItem; import cz.jzitnik.game.objects.GameObject; import cz.jzitnik.game.mobs.Mob; import cz.jzitnik.ui.pixels.Empty; @@ -7,7 +8,9 @@ import cz.jzitnik.ui.pixels.Pixel; import lombok.Getter; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; @Getter public class GameRoom { @@ -19,6 +22,7 @@ public class GameRoom { private final ResourceManager.Resource texture; private final List objects = new ArrayList<>(); private final List mobs = new ArrayList<>(); + private final Set droppedItems = new HashSet<>(); private final List colliders = new ArrayList<>(); public GameRoom(ResourceManager.Resource texture) { diff --git a/src/main/java/cz/jzitnik/game/objects/DroppedItem.java b/src/main/java/cz/jzitnik/game/objects/DroppedItem.java new file mode 100644 index 0000000..b0070b0 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/objects/DroppedItem.java @@ -0,0 +1,45 @@ +package cz.jzitnik.game.objects; + +import cz.jzitnik.events.DroppedItemRerender; +import cz.jzitnik.events.InventoryRerender; +import cz.jzitnik.game.GameState; +import cz.jzitnik.game.items.GameItem; +import cz.jzitnik.game.utils.RoomCords; +import cz.jzitnik.game.utils.Selectable; +import cz.jzitnik.utils.DependencyManager; +import cz.jzitnik.utils.StateManager; +import cz.jzitnik.utils.events.EventManager; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +import java.awt.image.BufferedImage; +import java.io.Serializable; + +@Getter +@RequiredArgsConstructor +public final class DroppedItem implements Selectable, Serializable { + private final RoomCords cords; + private final GameItem item; + @Setter + private boolean isSelected = false; + + @Override + public BufferedImage getTexture() { + return item.getTexture(); + } + + @Override + public void interact(DependencyManager dm) { + StateManager stateManager = dm.getDependencyOrThrow(StateManager.class); + GameState gameState = stateManager.getOrThrow(GameState.class); + EventManager eventManager = dm.getDependencyOrThrow(EventManager.class); + var currentRoom = gameState.getCurrentRoom(); + + currentRoom.getDroppedItems().remove(this); + gameState.getPlayer().addItem(item); + + eventManager.emitEvent(new InventoryRerender()); + eventManager.emitEvent(new DroppedItemRerender(this)); + } +} diff --git a/src/main/java/cz/jzitnik/game/setup/rooms/MainRoom.java b/src/main/java/cz/jzitnik/game/setup/rooms/MainRoom.java index db0ca8e..d5a7613 100644 --- a/src/main/java/cz/jzitnik/game/setup/rooms/MainRoom.java +++ b/src/main/java/cz/jzitnik/game/setup/rooms/MainRoom.java @@ -28,6 +28,6 @@ public class MainRoom extends GameRoom { addObject(chest); Zombie zombie = new Zombie(resourceManager, new RoomCords(100, 100)); - //addMob(zombie); + addMob(zombie); } } diff --git a/src/main/java/cz/jzitnik/ui/Inventory.java b/src/main/java/cz/jzitnik/ui/Inventory.java index cdb9566..75a1d49 100644 --- a/src/main/java/cz/jzitnik/ui/Inventory.java +++ b/src/main/java/cz/jzitnik/ui/Inventory.java @@ -7,6 +7,7 @@ import cz.jzitnik.annotations.Dependency; import cz.jzitnik.annotations.injectors.InjectDependency; import cz.jzitnik.annotations.injectors.InjectState; import cz.jzitnik.annotations.ui.*; +import cz.jzitnik.events.DroppedItemRerender; import cz.jzitnik.events.InventoryRerender; import cz.jzitnik.events.KeyboardPressEvent; import cz.jzitnik.events.MouseAction; @@ -14,6 +15,7 @@ import cz.jzitnik.game.GameState; import cz.jzitnik.game.ResourceManager; import cz.jzitnik.game.items.GameItem; import cz.jzitnik.game.items.types.InteractableItem; +import cz.jzitnik.game.objects.DroppedItem; import cz.jzitnik.states.ScreenBuffer; import cz.jzitnik.states.TerminalState; import cz.jzitnik.ui.pixels.ColoredPixel; @@ -113,8 +115,18 @@ public class Inventory { return false; } + var player = gameState.getPlayer(); + var inventory = player.getInventory(); + var currentRoom = gameState.getCurrentRoom(); + DroppedItem droppedItem = new DroppedItem(player.getPlayerCords().clone(), inventory[inventoryState.selectedItem]); + currentRoom.getDroppedItems().add(droppedItem); + inventory[inventoryState.selectedItem] = null; + inventoryState.selectedItem = -1; + + eventManager.emitEvent(new InventoryRerender()); + eventManager.emitEvent(new DroppedItemRerender(droppedItem)); + log.debug("Dropping item!"); - // TODO: Dropping items on a ground return true; } diff --git a/src/main/java/cz/jzitnik/utils/RerenderUtils.java b/src/main/java/cz/jzitnik/utils/RerenderUtils.java index b3dcc85..f5d25d3 100644 --- a/src/main/java/cz/jzitnik/utils/RerenderUtils.java +++ b/src/main/java/cz/jzitnik/utils/RerenderUtils.java @@ -9,6 +9,7 @@ import cz.jzitnik.game.Player; import cz.jzitnik.game.ResourceManager; import cz.jzitnik.game.mobs.HittableMob; import cz.jzitnik.game.mobs.Mob; +import cz.jzitnik.game.objects.DroppedItem; import cz.jzitnik.game.objects.GameObject; import cz.jzitnik.game.utils.RoomCords; import cz.jzitnik.states.ScreenBuffer; @@ -60,9 +61,11 @@ public class RerenderUtils { } } - public record PixelResult(int pixel, boolean isPlayer) {} + public record PixelResult(int pixel, boolean isPlayer) { + } public static PixelResult getPixel(GameRoom currentRoom, BufferedImage room, BufferedImage doors, Set doorPositions, Player player, BufferedImage playerTexture, int x, int y, Debugging debugging) { + float factor = 1.5f; // brightness multiplier if (debugging.isRenderColliders() && currentRoom.getColliders().stream().anyMatch(collider -> collider.isWithin(new RoomCords(x, y)))) { return new PixelResult(0xFFFF0000, false); } @@ -72,7 +75,7 @@ public class RerenderUtils { int relativeY = y - player.getPlayerCords().getY(); - if (debugging.isRenderPlayerCollider() && relativeX == 0 && relativeY == 0){ + if (debugging.isRenderPlayerCollider() && relativeX == 0 && relativeY == 0) { return new PixelResult(0xFFFF0000, false); } @@ -84,7 +87,7 @@ public class RerenderUtils { } } - for (Mob object: currentRoom.getMobs()) { + for (Mob object : currentRoom.getMobs()) { RoomCords startObjectCords = object.getCords(); BufferedImage texture = object.getTexture(); boolean isSelected = object.isSelected(); @@ -96,17 +99,42 @@ public class RerenderUtils { int r = (pixel >> 16) & 0xff; int g = (pixel >> 8) & 0xff; int b = pixel & 0xff; - float factor = 1.5f; // brightness multiplier float redFactor = 2f; if (alpha != 0) { if (object instanceof HittableMob mob && mob.isHitAnimationOn()) { - r = Math.min(255, (int)(r * redFactor)); + r = Math.min(255, (int) (r * redFactor)); pixel = (alpha << 24) | (r << 16) | (g << 8) | b; } else if (isSelected) { - r = Math.min(255, (int)(r * factor)); - g = Math.min(255, (int)(g * factor)); - b = Math.min(255, (int)(b * factor)); + r = Math.min(255, (int) (r * factor)); + g = Math.min(255, (int) (g * factor)); + b = Math.min(255, (int) (b * factor)); + pixel = (alpha << 24) | (r << 16) | (g << 8) | b; + } + + return new PixelResult(pixel, false); + } + } + } + + for (DroppedItem droppedItem : currentRoom.getDroppedItems()) { + RoomCords startDroppedItemCords = droppedItem.getCords(); + BufferedImage texture = droppedItem.getTexture(); + boolean isSelected = droppedItem.isSelected(); + RoomCords endDroppedItemCords = new RoomCords(startDroppedItemCords.getX() + texture.getWidth() - 1, startDroppedItemCords.getY() + texture.getHeight() - 1); + + if (x >= startDroppedItemCords.getX() && x <= endDroppedItemCords.getX() && y >= startDroppedItemCords.getY() && y <= endDroppedItemCords.getY()) { + int pixel = texture.getRGB(x - startDroppedItemCords.getX(), y - startDroppedItemCords.getY()); + int alpha = (pixel >> 24) & 0xff; + int r = (pixel >> 16) & 0xff; + int g = (pixel >> 8) & 0xff; + int b = pixel & 0xff; + + if (alpha != 0) { + if (isSelected) { + r = Math.min(255, (int) (r * factor)); + g = Math.min(255, (int) (g * factor)); + b = Math.min(255, (int) (b * factor)); pixel = (alpha << 24) | (r << 16) | (g << 8) | b; } @@ -127,13 +155,12 @@ public class RerenderUtils { int r = (pixel >> 16) & 0xff; int g = (pixel >> 8) & 0xff; int b = pixel & 0xff; - float factor = 1.5f; // brightness multiplier if (alpha != 0) { if (isSelected) { - r = Math.min(255, (int)(r * factor)); - g = Math.min(255, (int)(g * factor)); - b = Math.min(255, (int)(b * factor)); + r = Math.min(255, (int) (r * factor)); + g = Math.min(255, (int) (g * factor)); + b = Math.min(255, (int) (b * factor)); pixel = (alpha << 24) | (r << 16) | (g << 8) | b; }