diff --git a/common/src/main/java/cz/jzitnik/common/socket/messages/game/PlayerDeath.java b/common/src/main/java/cz/jzitnik/common/socket/messages/game/PlayerDeath.java new file mode 100644 index 0000000..eee62c6 --- /dev/null +++ b/common/src/main/java/cz/jzitnik/common/socket/messages/game/PlayerDeath.java @@ -0,0 +1,6 @@ +package cz.jzitnik.common.socket.messages.game; + +import cz.jzitnik.common.socket.SocketMessage; + +public record PlayerDeath(int playerId) implements SocketMessage { +} diff --git a/game/src/main/java/cz/jzitnik/client/game/Player.java b/game/src/main/java/cz/jzitnik/client/game/Player.java index 8481c27..e524a97 100644 --- a/game/src/main/java/cz/jzitnik/client/game/Player.java +++ b/game/src/main/java/cz/jzitnik/client/game/Player.java @@ -64,6 +64,8 @@ public class Player implements GamePlayer { public boolean dealDamage(int amount, DependencyManager dependencyManager) { if (health - amount <= 0) { health = 0; + EventManager eventManager = dependencyManager.getDependencyOrThrow(EventManager.class); + eventManager.emitEvent(new cz.jzitnik.client.events.SendSocketMessageEvent(new cz.jzitnik.common.socket.messages.game.PlayerDeath(id))); return true; } diff --git a/game/src/main/java/cz/jzitnik/client/game/setup/scenes/DeathScene.java b/game/src/main/java/cz/jzitnik/client/game/setup/scenes/DeathScene.java new file mode 100644 index 0000000..b536227 --- /dev/null +++ b/game/src/main/java/cz/jzitnik/client/game/setup/scenes/DeathScene.java @@ -0,0 +1,11 @@ +package cz.jzitnik.client.game.setup.scenes; + +import cz.jzitnik.client.screens.DeathScreen; +import cz.jzitnik.client.screens.Screen; +import cz.jzitnik.client.screens.scenes.Scene; + +public class DeathScene extends Scene { + public DeathScene() { + super(new Screen[]{new DeathScreen()}, new OnEndAction.Repeat()); + } +} diff --git a/game/src/main/java/cz/jzitnik/client/screens/DeathScreen.java b/game/src/main/java/cz/jzitnik/client/screens/DeathScreen.java new file mode 100644 index 0000000..a151fa5 --- /dev/null +++ b/game/src/main/java/cz/jzitnik/client/screens/DeathScreen.java @@ -0,0 +1,46 @@ +package cz.jzitnik.client.screens; + +import com.googlecode.lanterna.SGR; +import com.googlecode.lanterna.TextColor; +import com.googlecode.lanterna.graphics.TextGraphics; +import com.googlecode.lanterna.screen.TerminalScreen; +import cz.jzitnik.client.annotations.injectors.InjectState; +import cz.jzitnik.client.events.KeyboardPressEvent; +import cz.jzitnik.client.events.MouseAction; +import cz.jzitnik.client.states.TerminalState; + +import java.io.IOException; + +public class DeathScreen extends Screen { + @InjectState + private TerminalState terminalState; + + @Override + public void fullRender() { + TerminalScreen screen = terminalState.getTerminalScreen(); + screen.clear(); + TextGraphics tg = terminalState.getTextGraphics(); + + int termWidth = screen.getTerminalSize().getColumns(); + int termHeight = screen.getTerminalSize().getRows(); + + String message = "GAME OVER"; + tg.setForegroundColor(TextColor.ANSI.RED); + tg.enableModifiers(SGR.BOLD); + tg.putString((termWidth - message.length()) / 2, termHeight / 2, message); + + try { + screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void handleMouseAction(MouseAction event) { + } + + @Override + public void handleKeyboardAction(KeyboardPressEvent event) { + } +} diff --git a/game/src/main/java/cz/jzitnik/client/socket/events/PlayerDeathHandler.java b/game/src/main/java/cz/jzitnik/client/socket/events/PlayerDeathHandler.java new file mode 100644 index 0000000..231c4a8 --- /dev/null +++ b/game/src/main/java/cz/jzitnik/client/socket/events/PlayerDeathHandler.java @@ -0,0 +1,34 @@ +package cz.jzitnik.client.socket.events; + +import cz.jzitnik.client.annotations.SocketEventHandler; +import cz.jzitnik.client.annotations.injectors.InjectDependency; +import cz.jzitnik.client.annotations.injectors.InjectState; +import cz.jzitnik.client.game.GameState; +import cz.jzitnik.client.game.setup.scenes.DeathScene; +import cz.jzitnik.client.socket.AbstractSocketEventHandler; +import cz.jzitnik.client.utils.DependencyManager; +import cz.jzitnik.common.socket.messages.game.PlayerDeath; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@SocketEventHandler(PlayerDeath.class) +public class PlayerDeathHandler extends AbstractSocketEventHandler { + @InjectState + private GameState gameState; + + @InjectDependency + private DependencyManager dependencyManager; + + @InjectDependency + private cz.jzitnik.client.utils.roomtasks.RoomTaskScheduler roomTaskScheduler; + + @Override + public void handle(PlayerDeath event) { + log.debug("Player death: {}", event.playerId()); + roomTaskScheduler.finalShutdown(); + DeathScene deathScene = new DeathScene(); + dependencyManager.inject(deathScene); + gameState.setScreen(deathScene); + deathScene.fullRender(); + } +} diff --git a/server/src/main/java/cz/jzitnik/server/events/handlers/PlayerDeathHandler.java b/server/src/main/java/cz/jzitnik/server/events/handlers/PlayerDeathHandler.java new file mode 100644 index 0000000..4bae0b9 --- /dev/null +++ b/server/src/main/java/cz/jzitnik/server/events/handlers/PlayerDeathHandler.java @@ -0,0 +1,21 @@ +package cz.jzitnik.server.events.handlers; + +import cz.jzitnik.common.socket.messages.game.PlayerDeath; +import cz.jzitnik.server.annotations.EventHandler; +import cz.jzitnik.server.context.GlobalContext; +import cz.jzitnik.server.events.AbstractEventHandler; +import cz.jzitnik.server.game.Client; + +@EventHandler(PlayerDeath.class) +public class PlayerDeathHandler extends AbstractEventHandler { + public PlayerDeathHandler(GlobalContext globalContext) { + super(globalContext); + } + + @Override + public void handle(PlayerDeath event, Client client) { + for (Client player : client.getGame().getPlayers()) { + player.getSession().sendMessage(new PlayerDeath(event.playerId())); + } + } +}