diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java index 0c269d1e..e66c6ede 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/InputSynchronizer.java @@ -21,6 +21,7 @@ import pp.mdga.game.BonusCard; import pp.mdga.game.Color; import pp.mdga.game.Piece; +import pp.mdga.notification.FinishNotification; import pp.mdga.notification.SelectableCardsNotification; import java.util.List; @@ -116,7 +117,7 @@ else if(boardSelect != null) { } if(name.equals("Test") &&isPressed){ if(app.getView() instanceof GameView gameView){ - app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD))); + app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY)); } } } @@ -151,6 +152,7 @@ else if (name.equals("MouseLeft") || name.equals("MouseRight") || name.equals("M * Detects the hovered piece and updates its hover state. */ private T checkHover(Camera cam, Node root, Class controlType) { + if(cam == null || root == null || controlType == null) return null; CollisionResults results = new CollisionResults(); Ray ray = new Ray(cam.getLocation(), getMousePos(cam).subtract(cam.getLocation()).normalize()); root.collideWith(ray, results); @@ -164,6 +166,7 @@ private T checkHover(Camera cam, Node root, Class * Detects the hovered card and updates its hover state. */ private T checkHoverOrtho(Camera cam, Node root, Class controlType) { + if(cam == null || root == null || controlType == null) return null; CollisionResults results = new CollisionResults(); Vector3f mousePos = getMousePos(cam); mousePos.setZ(cam.getLocation().getZ()); diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java index 21f305f9..dbe4e702 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/MdgaApp.java @@ -249,8 +249,19 @@ public ExecutorService getExecutor() { return this.executor; } - public ServerConnection getNetworkSupport() { + public ServerConnection getNetworkSupport(){ return networkConnection; } + + public void updateResolution(int width, int height) { + AppSettings settings = getContext().getSettings(); + + settings.setResolution(width, height); + setSettings(settings); + restart(); + + enter(state); + } + } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java index 6493c07e..e1c1b987 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/ModelSynchronizer.java @@ -23,15 +23,22 @@ public class ModelSynchronizer { private UUID a; private UUID b; private BonusCard card; + private boolean swap; ModelSynchronizer(MdgaApp app) { this.app = app; + swap = false; } public void animationEnd() { app.getGameLogic().selectAnimationEnd(); } + public void select(UUID a, UUID b){ + if(swap) selectSwap(a,b); + else selectPiece(a); + } + public void selectSwap(UUID a, UUID b) { // TODO call from somewhere LOGGER.log(Level.INFO, "selectPiece"); @@ -134,4 +141,8 @@ public void enter(MdgaState state) { LOGGER.log(Level.INFO, "enter: {0}", state); //app.enter(state); } + + public void setSwap(boolean swap){ + this.swap = swap; + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java index 00871dfe..a704e3e8 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/NotificationSynchronizer.java @@ -21,10 +21,12 @@ public class NotificationSynchronizer { public void addTestNotification(Notification n) { notifications.add(n); + handleGame(n); } public void update() { Notification n = app.getGameLogic().getNotification(); + if(n != null) { switch (app.getState()) { case MAIN: @@ -43,7 +45,6 @@ public void update() { throw new RuntimeException("no notification expected: " + n.toString()); } } - notifications.clear(); } private void handleMain(Notification notification) { @@ -77,6 +78,7 @@ private void handleGame(Notification notification) { GameView gameView = (GameView) app.getView(); GuiHandler guiHandler = gameView.getGuiHandler(); BoardHandler boardHandler = gameView.getBoardHandler(); + ModelSynchronizer modelSynchronizer = app.getModelSynchronize(); if (notification instanceof AcquireCardNotification n) { guiHandler.addCard(n.getBonusCard()); @@ -111,8 +113,6 @@ private void handleGame(Notification notification) { } } else if (notification instanceof DiceNowNotification) { guiHandler.showDice(); - } else if (notification instanceof DicingNotification n) { - //TODO ??? } else if (notification instanceof DrawCardNotification n) { guiHandler.drawCard(n.getColor()); } else if (notification instanceof HomeMoveNotification home) { @@ -129,6 +129,7 @@ private void handleGame(Notification notification) { //InfieldMove boardHandler.movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex()); } + guiHandler.hideText(); } else if (notification instanceof ThrowPieceNotification n) { boardHandler.throwPiece(n.getPieceId()); } else if (notification instanceof NoShieldNotification n) { @@ -168,12 +169,17 @@ private void handleGame(Notification notification) { //TODO ??? } else if (notification instanceof SelectableMoveNotification n) { boardHandler.outlineMove(n.getPieces(), n.getMoveIndices(), n.getHomeMoves()); + modelSynchronizer.setSwap(false); } else if (notification instanceof SelectableSwapNotification n) { boardHandler.outlineSwap(n.getOwnPieces(), n.getEnemyPieces()); + modelSynchronizer.setSwap(true); } else if (notification instanceof SelectableShieldNotification n) { boardHandler.outlineShield(n.getPieces()); + modelSynchronizer.setSwap(false); } else if (notification instanceof TurboActiveNotification){ guiHandler.turbo(); + } else if (notification instanceof FinishNotification n){ + guiHandler.finish(n.getColorFinished()); } else { throw new RuntimeException("notification not expected: " + notification.toString()); } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java index d3bcbd7b..74a2223d 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/BoardHandler.java @@ -439,6 +439,8 @@ else if(selectableEnemyPieces.contains(pieceSelected)) { } } else throw new RuntimeException("pieceSelected is not in own/enemySelectablePieces"); + + app.getModelSynchronize().select(getKeyByValue(pieces, selectedOwnPiece), getKeyByValue(pieces, selectedEnemyPiece)); } //called when view is no longer needed to select pieces @@ -477,5 +479,13 @@ public void hideDice(){ diceControl.hide(); } + private K getKeyByValue(Map map, V value) { + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().equals(value)) { + return entry.getKey(); + } + } + return null; + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/NetworkDialog.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/NetworkDialog.java index a234fa75..15c680e9 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/NetworkDialog.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/NetworkDialog.java @@ -71,4 +71,8 @@ public void update(float delta) { } } } + + public NetworkSupport getNetwork(){ + return network; + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/VideoSettingsDialog.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/VideoSettingsDialog.java index f1268243..e014e3fd 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/VideoSettingsDialog.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/VideoSettingsDialog.java @@ -9,6 +9,13 @@ public class VideoSettingsDialog extends Dialog { private MenuButton backButton; + private MenuButton hdButton9; + private MenuButton fullHdButton9; + private MenuButton wqhdButton9; + private MenuButton hdButton10; + private MenuButton fullHdButton10; + private MenuButton wqhdButton10; + private final MdgaView view; private boolean active = false; @@ -20,6 +27,15 @@ public VideoSettingsDialog(MdgaApp app, Node node, MdgaView view) { backButton = new MenuButton(app, node, view::leaveVideoSettings, "Zurück"); + // MenuButton für verschiedene Auflösungen erstellen + hdButton9 = new MenuButton(app, node, () -> app.updateResolution(1280, 720), "hd 16:9"); + fullHdButton9 = new MenuButton(app, node, () -> app.updateResolution(1920, 1080), "full hd 16:9"); + wqhdButton9 = new MenuButton(app, node, () -> app.updateResolution(2560, 1440), "wqhd 16:9"); + + hdButton10 = new MenuButton(app, node, () -> app.updateResolution(1280, 800), "hd 16:10"); + fullHdButton10 = new MenuButton(app, node, () -> app.updateResolution(1920, 1200), "full hd 16:10"); + wqhdButton10 = new MenuButton(app, node, () -> app.updateResolution(2560, 1600), "wqhd 16:10"); + float offset = 2.8f; backButton.setPos(new Vector2f(0, 1.8f)); @@ -29,6 +45,14 @@ public VideoSettingsDialog(MdgaApp app, Node node, MdgaView view) { protected void onShow() { active = true; + hdButton9.show(); + fullHdButton9.show(); + wqhdButton9.show(); + + hdButton10.show(); + fullHdButton10.show(); + wqhdButton10.show(); + backButton.show(); } @@ -36,6 +60,14 @@ protected void onShow() { protected void onHide() { active = false; + hdButton9.hide(); + fullHdButton9.hide(); + wqhdButton9.hide(); + + hdButton10.hide(); + fullHdButton10.hide(); + wqhdButton10.hide(); + backButton.hide(); } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java index aa41bdf5..1b868163 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/ActionTextHandler.java @@ -111,6 +111,16 @@ public void drawCardOwn(Color color){ createTopText(new String[]{"Du"," erhälst eine Bonuskarte"}, 5,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); } + public void finishText(String name, Color color){ + createTopText(new String[]{name," ist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); + } + + public void finishTextOwn(Color color){ + createTopText(new String[]{"Du", " bist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); + } + + + private ColorRGBA playerColorToColorRGBA(Color color){ return switch (color){ case ARMY -> ColorRGBA.Green; diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java index 816f0874..8761e3da 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/GuiHandler.java @@ -51,7 +51,7 @@ public void rollDice(int rollNum, int mult) { if(mult == -1) actionTextHandler.ownDice(rollNum); else actionTextHandler.ownDiceMult(rollNum, mult); hideDice(); - //TODO send Model finished + app.getModelSynchronize().animationEnd(); }); } @@ -129,5 +129,10 @@ public void drawCard(Color color) { else actionTextHandler.drawCard(playerNameHandler.getName(color), color); } + public void finish(Color color){ + if(ownColor == color) actionTextHandler.finishTextOwn(color); + else actionTextHandler.finishText(playerNameHandler.getName(color), color); + } + } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java index 02d057e7..533dabd7 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/server/MdgaServer.java @@ -2,9 +2,7 @@ import com.jme3.network.*; import com.jme3.network.serializing.Serializer; -import pp.mdga.game.Game; -import pp.mdga.game.Player; -import pp.mdga.game.Statistic; +import pp.mdga.game.*; import pp.mdga.message.client.*; import pp.mdga.message.server.*; import pp.mdga.server.ServerGameLogic; @@ -138,6 +136,13 @@ private void initializeSerializables() { Serializer.registerClass(WaitPieceMessage.class); Serializer.registerClass(Player.class); Serializer.registerClass(Statistic.class); + Serializer.registerClass(Board.class); + Serializer.registerClass(Node.class); + Serializer.registerClass(Piece.class); + Serializer.registerClass(BonusNode.class); + Serializer.registerClass(StartNode.class); + Serializer.registerClass(PlayerData.class); + Serializer.registerClass(HomeNode.class); } private void registerListeners() { @@ -194,6 +199,9 @@ private void messageReceived(HostedConnection source, ClientMessage message) { public void connectionAdded(Server server, HostedConnection hostedConnection) { System.out.println("new connection " + hostedConnection); //NON-NLS LOGGER.log(Level.DEBUG, "new connection {0}", hostedConnection); //NON-NLS + if (this.myServer.getConnections().size() == 1) { + this.logic.getGame().setHost(hostedConnection.getId()); + } } @Override diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java index 4edaadc5..41a2b412 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/GameView.java @@ -20,6 +20,7 @@ import pp.mdga.notification.RollDiceNotification; import pp.mdga.notification.SelectableCardsNotification; import pp.mdga.notification.SelectableMoveNotification; +import pp.mdga.notification.SelectableSwapNotification; import pp.mdga.notification.ShieldActiveNotification; import java.util.ArrayList; @@ -31,8 +32,6 @@ public class GameView extends MdgaView { private CameraHandler camera; private GuiHandler guiHandler; - private ButtonRight cheatButton; //TODO - private ButtonLeft leaveButton; private ButtonRight confirmButton; @@ -43,7 +42,6 @@ public class GameView extends MdgaView { public GameView(MdgaApp app) { super(app); - cheatButton = new ButtonRight(app, overlayNode, () -> app.getModelSynchronize().enter(MdgaState.CEREMONY), "CHEAT", 1); leaveButton = new ButtonLeft(app, overlayNode, () -> app.getModelSynchronize().leave(), "Spiel verlassen", 1); confirmButton = new ButtonRight(app, guiNode, () -> app.getModelSynchronize().confirm(), "Bestätigen", 1); @@ -66,41 +64,6 @@ public void onEnter() { app.getViewPort().addProcessor(fpp); app.getAcousticHandler().playSound(MdgaSound.START); - - - //Test -// List uuid1 = new ArrayList<>(); -// UUID p1 = UUID.randomUUID(); -// UUID p2 = UUID.randomUUID(); -// uuid1.add(p1); -// uuid1.add(p2); -// uuid1.add(UUID.randomUUID()); -// uuid1.add(UUID.randomUUID()); -// List uuid2 = new ArrayList<>(); -// UUID p1_2 = UUID.randomUUID(); -// UUID p2_2 = UUID.randomUUID(); -// uuid2.add(p1_2); -// uuid2.add(p2_2); -// uuid2.add(UUID.randomUUID()); -// uuid2.add(UUID.randomUUID()); - -// app.getNotificationSynchronizer().addTestNotification(new PlayerInGameNotification(Color.AIRFORCE, uuid1, "Cedric")); -// app.getNotificationSynchronizer().addTestNotification(new PlayerInGameNotification(Color.NAVY, uuid2, "Test")); -// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification(p1, 0, true)); -// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification(p1_2, 30, true)); -// app.getNotificationSynchronizer().addTestNotification(new SelectableMoveNotification(List.of(p1), List.of(4), List.of(false))); -// app.getNotificationSynchronizer().addTestNotification(new AcquireCardNotification(BonusCard.SHIELD)); - -// app.getNotificationSynchronizer().addTestNotification(new SelectableCardsNotification(List.of(BonusCard.SHIELD))); -// app.getNotificationSynchronizer().addTestNotification(new ShieldActiveNotification(p1)); -// app.getNotificationSynchronizer().addTestNotification(new ActivePlayerNotification(Color.NAVY)); - -// app.getNotificationSynchronizer().addTestNotification(new DiceNowNotification()); -// app.getNotificationSynchronizer().addTestNotification(new RollDiceNotification(Color.AIRFORCE, 5, true, 2)); - - //p1 = p1; - - } @Override @@ -124,7 +87,6 @@ public void onUpdate(float tpf) { protected void onEnterOverlay(Overlay overlay) { if(overlay == Overlay.SETTINGS) { leaveButton.show(); - cheatButton.show(); } } @@ -132,7 +94,6 @@ protected void onEnterOverlay(Overlay overlay) { protected void onLeaveOverlay(Overlay overlay) { if(overlay == Overlay.SETTINGS) { leaveButton.hide(); - cheatButton.hide(); } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java index 6aefa85f..6ebf9e33 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MainView.java @@ -106,13 +106,11 @@ private void tryHost() { try { Thread.sleep(1000); } catch (InterruptedException ignored) { - // todo: implement } hostDialog.connectServerAsClient(); try { Thread.sleep(1000); } catch (InterruptedException ignored) { - // todo: implement } app.getModelSynchronize().setHost(port); //app.getAcousticHandler().playSound(MdgaSound.WRONG_INPUT); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java index b72c1294..5f7cf182 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/DialogsState.java @@ -53,6 +53,10 @@ public void setOwnPlayerName(String ownPlayerName) { this.ownPlayerName = ownPlayerName; } + public void setOwnPlayerId(int ownPlayerId) { + this.ownPlayerID = ownPlayerId; + } + public LobbyState getLobby() { return lobbyState; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java index 7f04f8a8..af449db8 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/GameState.java @@ -8,6 +8,9 @@ public class GameState extends ClientState { + /** + * the current substate + */ private GameStates state; private final AnimationState animationState = new AnimationState(this, logic); @@ -16,21 +19,38 @@ public class GameState extends ClientState { private final TurnState turnState = new TurnState(this, logic); private final WaitingState waitingState = new WaitingState(this, logic); + /** + * Constructor for GameState + * + * @param parent the parent of this state + * @param logic the ClientGameLogic + */ public GameState(ClientState parent, ClientGameLogic logic) { super(parent, logic); state = determineStartPlayerState; } + /** + * The method to enter the state + */ @Override public void enter() { } + /** + * the method to exit this state + */ @Override public void exit() { - + state.exit(); } + /** + * This method is used to set a new SubState + * + * @param newState the state to be set + */ public void setState(GameStates newState){ state.exit(); state.enter(); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/InterruptState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/InterruptState.java index 8c8d35d8..33ec5a4f 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/InterruptState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/InterruptState.java @@ -26,19 +26,35 @@ public void enter() { previousState = null; } + /** + * exits this state + */ @Override public void exit() { previousState = null; } + /** + * This method sets the stores the gamestate as previous state + * + * @param previousState + */ public void setPreviousState(ClientState previousState) { this.previousState = previousState; } + /** + * returns teh previous gamestate + * + * @return the previous gamestate + */ public ClientState getPreviousState() { return previousState; } + /** + * The host resumes the game + */ @Override public void selectResume(){ if(logic.isHost()){ @@ -46,6 +62,11 @@ public void selectResume(){ } } + /** + * The server resumes the game + * + * @param msg the ResumeGame message received + */ public void received(ResumeGameMessage msg) { //TODO: logic.addNotification(new ResumeNotification()); logic.setState(previousState); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java index d310436e..7678624a 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/LobbyState.java @@ -4,17 +4,18 @@ import pp.mdga.client.ClientState; import pp.mdga.client.DialogsState; import pp.mdga.game.Color; +import pp.mdga.game.Piece; import pp.mdga.game.Player; +import pp.mdga.game.PlayerData; import pp.mdga.message.client.*; import pp.mdga.message.server.LobbyPlayerJoinedMessage; import pp.mdga.message.server.LobbyPlayerLeaveMessage; import pp.mdga.message.server.ServerStartGameMessage; import pp.mdga.message.server.UpdateReadyMessage; import pp.mdga.message.server.UpdateTSKMessage; -import pp.mdga.notification.LobbyReadyNotification; -import pp.mdga.notification.StartDialogNotification; -import pp.mdga.notification.TskSelectNotification; -import pp.mdga.notification.TskUnselectNotification; +import pp.mdga.notification.*; + +import java.util.*; public class LobbyState extends DialogStates { @@ -74,12 +75,26 @@ public void selectStart(){ @Override public void received(ServerStartGameMessage msg){ - + logic.getGame().setBoard(msg.getBoard()); + logic.addNotification(new GameNotification(logic.getGame().getPlayers().get(parent.getOwnPlayerId()).getColor())); + for(Map.Entry entry : msg.getBoard().getPlayerData().entrySet()){ + List pieceIds = new ArrayList<>(); + for(Piece piece : entry.getValue().getPieces()){ + pieceIds.add(piece.getUuid()); + } + logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceIds, logic.getGame().getPlayerByColor(entry.getKey()).getName())); + } parent.startGame(); } @Override public void received(LobbyPlayerJoinedMessage msg){ + if(msg.getPlayer().getName().equals(parent.getOwnPlayerName())){ + parent.setOwnPlayerId(msg.getId()); + } + if (msg.isHost() && msg.getId() == parent.getOwnPlayerId()){ + logic.setHost(true); + } logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), parent.getOwnPlayerId()== msg.getId())); logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer()); } @@ -99,6 +114,7 @@ public void received(LobbyPlayerLeaveMessage msg){ @Override public void received(UpdateReadyMessage msg){ + //TODO server sendet kein update on UNready logic.addNotification(new LobbyReadyNotification(logic.getGame().getPlayers().get(msg.getPlayerId()).getColor(), msg.isReady())); logic.getGame().getPlayers().get(msg.getPlayerId()).setReady(msg.isReady()); } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Board.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Board.java index 730c9f45..b24382fe 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Board.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Board.java @@ -1,12 +1,16 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + +import java.util.HashMap; import java.util.Map; /** * This class will be used to hold all Board relevant data. */ +@Serializable public class Board { - private Map playerData; + private Map playerData = new HashMap<>(); private final Node[] infield; /** @@ -30,6 +34,17 @@ public Board() { } } + /** + * This method will be used to add the given color and playerData parameters to the playerData attribute of + * Board class. + * + * @param color as the color of the player as a Color enumeration. + * @param playerData as the playerData of the player as a PlayerData object. + */ + public void addPlayerData(Color color, PlayerData playerData) { + this.playerData.put(color, playerData); + } + /** * This method returns the playerData * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/BonusNode.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/BonusNode.java index 157be2a1..c12f7cab 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/BonusNode.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/BonusNode.java @@ -1,7 +1,13 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * This class represents a BonusNode */ +@Serializable public class BonusNode extends Node { + BonusNode(){ + super(); + } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Game.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Game.java index 0ea882ba..ac97b92e 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Game.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Game.java @@ -42,6 +42,9 @@ public class Game { // The die used in the game. private Die die; + // The host of this game + private int host; + // The color of the active player. private Color activeColor; @@ -232,6 +235,15 @@ public Color getActiveColor() { return activeColor; } + /** + * This method will be used to return host attribute of Game class. + * + * @return host as an Integer. + */ + public int getHost() { + return this.host; + } + /** * This method sets the dice modifier. * @@ -304,6 +316,15 @@ public void setActiveColor(Color activeColor) { this.activeColor = activeColor; } + /** + * This method will be used to set host attribute of Game class to the given host parameter. + * + * @param host as the new value of host as an Integer. + */ + public void setHost(int host) { + this.host = host; + } + /** * This method returns the all ready state. * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/HomeNode.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/HomeNode.java index 8faa06b1..814abaa5 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/HomeNode.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/HomeNode.java @@ -1,7 +1,13 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * Represents a home node. */ +@Serializable public class HomeNode extends Node { + public HomeNode() { + super(); + } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Node.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Node.java index 6d42092b..de6530ca 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Node.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Node.java @@ -1,11 +1,18 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * This class will be used the represent a Node on which the pieces can travel along */ +@Serializable public class Node { protected Piece occupant; + public Node(){ + + } + /** * This method is used to get an occupant of the Node. * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java index 15f00498..64b671db 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Piece.java @@ -1,10 +1,13 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + import java.util.UUID; /** * This class will be used to hold all Piece relevant data. */ +@Serializable public class Piece { /** * The shield state of the piece. @@ -38,6 +41,10 @@ public Piece(Color color, PieceState state, int id) { shield = ShieldState.NONE; } + private Piece() { + color = null; + } + /** * This method is used to get the color of the piece * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java index f03559fa..8fcc85ae 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PlayerData.java @@ -1,8 +1,11 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * This class is used to represent PlayerData related to the board */ +@Serializable public class PlayerData { /** * An array of HomeNode objects representing the home nodes of the player. @@ -31,6 +34,7 @@ public class PlayerData { */ public PlayerData(Color color) { homeNodes = new HomeNode[4]; + pieces = new Piece[4]; waitingArea = new Piece[4]; for (int i = 0; i < 4; i++) { homeNodes[i] = new HomeNode(); @@ -39,6 +43,12 @@ public PlayerData(Color color) { } } + private PlayerData() { + homeNodes = null; + waitingArea = null; + pieces = null; + } + /** * This method returns an Array of HomeNodes * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java index 4d2de491..bb203084 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/StartNode.java @@ -1,8 +1,11 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * Represents a start node. */ +@Serializable public class StartNode extends Node { /** * The color of the node. @@ -18,6 +21,10 @@ public StartNode(Color color) { this.color = color; } + private StartNode() { + color = null; + } + /** * This method is used to get the color of the node * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyPlayerJoinedMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyPlayerJoinedMessage.java index cf1be4e6..fdc5ede4 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyPlayerJoinedMessage.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyPlayerJoinedMessage.java @@ -19,16 +19,23 @@ public class LobbyPlayerJoinedMessage extends ServerMessage { */ private final int id; + /** + * The flag is the new player is the host + */ + private final boolean host; + /** * Constructs a new LobbyPlayerJoin instance with the specified player name. * * @param player the player joining the lobby - * @param id the id of the player + * @param id the id of the player + * @param host as the flag if the player is the host as a Boolean. */ - public LobbyPlayerJoinedMessage(int id, Player player) { + public LobbyPlayerJoinedMessage(int id, Player player, boolean host) { super(); this.player = player; this.id = id; + this.host = host; } /** @@ -37,6 +44,7 @@ public LobbyPlayerJoinedMessage(int id, Player player) { private LobbyPlayerJoinedMessage() { player = null; id = 0; + host = false; } /** @@ -57,6 +65,10 @@ public int getId(){ return id; } + public boolean isHost() { + return this.host; + } + /** * Accepts a visitor to process this message. * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java index ac448825..37c22e1e 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerStartGameMessage.java @@ -1,17 +1,33 @@ package pp.mdga.message.server; import com.jme3.network.serializing.Serializable; +import pp.mdga.game.Board; /** * A message indicating that the game shall start. */ @Serializable public class ServerStartGameMessage extends ServerMessage { + /** + * Create ServerStartGameMessage attributes. + */ + private final Board board; + /** * Constructs a new ServerStartGame instance. */ public ServerStartGameMessage() { super(); + this.board = null; + } + + /** + * Constructor. + * + * @param board as the complete board of this game as a Board object. + */ + public ServerStartGameMessage(Board board) { + this.board = board; } /** @@ -24,6 +40,15 @@ public void accept(ServerInterpreter interpreter) { interpreter.received(this); } + /** + * This method will be used to return board attribute of ServerStartGameMessage class. + * + * @return board as a Board object. + */ + public Board getBoard() { + return this.board; + } + /** * Returns a string representation of this message. * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/DicingNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/DicingNotification.java deleted file mode 100644 index b2254605..00000000 --- a/Projekte/mdga/model/src/main/java/pp/mdga/notification/DicingNotification.java +++ /dev/null @@ -1,31 +0,0 @@ -package pp.mdga.notification; - -import pp.mdga.game.Color; - -/** - * Notification that is sent when a player has diced. - */ -public class DicingNotification extends Notification { - /** - * The color of the player that diced. - */ - private final Color color; - - /** - * Constructor. - * - * @param color The color of the player that diced. - */ - public DicingNotification(Color color) { - this.color = color; - } - - /** - * Get the color of the player that diced. - * - * @return The color of the player that diced. - */ - public Color getColor() { - return color; - } -} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/FinishNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/FinishNotification.java new file mode 100644 index 00000000..d51a843f --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/FinishNotification.java @@ -0,0 +1,15 @@ +package pp.mdga.notification; + +import pp.mdga.game.Color; + +public class FinishNotification extends Notification{ + private Color colorFinished; + + public FinishNotification(Color colorFinished){ + this.colorFinished = colorFinished; + } + + public Color getColorFinished() { + return colorFinished; + } +} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/GameState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/GameState.java index 10045e97..d9ac8431 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/GameState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/GameState.java @@ -25,9 +25,9 @@ public class GameState extends ServerState { * Create GameState states. */ private GameAutomatonState currentState; - private final GameAutomatonState determineStartPlayerState; - private final GameAutomatonState animationState; - private final GameAutomatonState turnState; + private final DetermineStartPlayerState determineStartPlayerState; + private final AnimationState animationState; + private final TurnState turnState; /** * Constructor. @@ -122,27 +122,27 @@ public GameAutomatonState getCurrentState() { /** * This method will be used to return determineStartPlayerState attribute of GameState class. * - * @return determineStartPlayerState as a GameAutomatonState object. + * @return determineStartPlayerState as a DetermineStartPlayerState object. */ - public GameAutomatonState getDetermineStartPlayerState() { + public DetermineStartPlayerState getDetermineStartPlayerState() { return this.determineStartPlayerState; } /** * This method will be used to return animationState attribute of GameState class. * - * @return animationState as a GameAutomatonState object. + * @return animationState as a AnimationState object. */ - public GameAutomatonState getAnimationState() { + public AnimationState getAnimationState() { return this.animationState; } /** * This method will be used to return turnState attribute of GameState class. * - * @return turnState as a GameAutomatonState object. + * @return turnState as a TurnState object. */ - public GameAutomatonState getTurnState() { + public TurnState getTurnState() { return this.turnState; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java index d38e7884..6d72dcc5 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/LobbyState.java @@ -2,6 +2,7 @@ import pp.mdga.game.Color; import pp.mdga.game.Player; +import pp.mdga.game.PlayerData; import pp.mdga.message.client.*; import pp.mdga.message.server.*; import pp.mdga.server.ServerGameLogic; @@ -43,6 +44,15 @@ public void exit() { LOGGER.log(System.Logger.Level.DEBUG, "Exited LobbyState state."); } + /** + * This method will be used to initialize the game and all necessary objects. + */ + public void initializeGame() { + for (Map.Entry entry: this.logic.getGame().getPlayers().entrySet()) { + this.logic.getGame().getBoard().addPlayerData(entry.getValue().getColor(), new PlayerData(entry.getValue().getColor())); + } + } + /** * This method will be called whenever the server received a JoinedLobbyMessage message. * It will also get the client id of the player who send this message @@ -55,8 +65,8 @@ public void received(JoinedLobbyMessage msg, int from) { Player player = new Player(msg.getName()); player.setColor(Color.getColorByIndex(this.logic.getGame().getPlayers().size())); this.logic.getGame().addPlayer(from, player); - for (Map.Entry entry: this.logic.getGame().getPlayers().entrySet()) { - this.logic.getServerSender().broadcast(new LobbyPlayerJoinedMessage(entry.getKey(), entry.getValue())); + for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) { + this.logic.getServerSender().broadcast(new LobbyPlayerJoinedMessage(entry.getKey(), entry.getValue(), entry.getKey() == this.logic.getGame().getHost())); } } @@ -103,12 +113,16 @@ public void received(LobbyReadyMessage msg, int from) { this.logic.getGame().getPlayerById(from).setReady(true); this.logic.getServerSender().broadcast(new UpdateReadyMessage(from, true)); for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) { - if (!entry.getValue().isActive()) { + if (!entry.getValue().isReady()) { return; } } this.logic.getGame().setAllReady(true); + if (this.logic.getGame().allReady()) { + this.initializeGame(); + this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard())); + } } /** @@ -149,7 +163,8 @@ public void received(LeaveGameMessage msg, int from) { @Override public void received(StartGameMessage msg, int from) { if (msg.isForceStartGame() || this.logic.getGame().allReady()) { - this.logic.getServerSender().broadcast(new ServerStartGameMessage()); + this.initializeGame(); + this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard())); this.logic.setCurrentState(this.logic.getGameState()); } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java index f6294206..3e76cf70 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/DetermineStartPlayerState.java @@ -2,12 +2,14 @@ import pp.mdga.game.Player; import pp.mdga.message.client.RequestDieMessage; +import pp.mdga.message.server.ActivePlayerMessage; import pp.mdga.message.server.DieMessage; import pp.mdga.server.ServerGameLogic; import pp.mdga.server.automaton.GameState; -import pp.mdga.server.automaton.game.turn.RollDiceState; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -21,7 +23,8 @@ public class DetermineStartPlayerState extends GameAutomatonState { /** * Create DetermineStartPlayerState attributes. */ - private Map diceResults = new HashMap<>(); + private Map diceResults = new HashMap<>(); + private List playersHaveToRoll = new ArrayList<>(); /** * Constructs a server state of the specified game logic. @@ -36,6 +39,9 @@ public DetermineStartPlayerState(GameState gameAutomaton, ServerGameLogic logic) @Override public void enter() { LOGGER.log(System.Logger.Level.DEBUG, "Entered DetermineStartPlayerState state."); + for (Map.Entry entry: this.logic.getGame().getPlayers().entrySet()) { + this.playersHaveToRoll.add(entry.getKey()); + } } @Override @@ -53,23 +59,26 @@ public void exit() { @Override public void received(RequestDieMessage msg, int from) { int roll = this.logic.getGame().getDie().shuffle(); - this.diceResults.put(this.logic.getGame().getPlayerById(from), roll); + this.diceResults.put(from, roll); + int maximumRoll = 0; if (this.diceResults.size() == this.logic.getGame().getPlayers().size()) { - Map frequencyMap = diceResults.values().stream() - .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); - Map.Entry result = frequencyMap.entrySet().stream() - .max(Map.Entry.comparingByKey()) - .orElseThrow(() -> new IllegalStateException("Die Map ist leer")); - } - this.logic.getServerSender().send(from, new DieMessage(roll)); - } + for (Map.Entry entry: this.diceResults.entrySet()) { + if (maximumRoll == 0) { + maximumRoll = this.diceResults.get(entry.getKey()); + } else if (maximumRoll < entry.getValue()) { + maximumRoll = entry.getValue(); + } else { + this.playersHaveToRoll.remove(entry.getKey()); + } + } - /** - * This method will be used to return diceResults attribute of DetermineStartPlayerState class. - * - * @return diceResults as a Map combing Player objects and Integers. - */ - public Map getDiceResults() { - return this.diceResults; + if (this.playersHaveToRoll.size() == 1) { + this.logic.getServerSender().broadcast(new ActivePlayerMessage(this.logic.getGame().getPlayerById(this.playersHaveToRoll.get(0)).getColor())); + } else { + for (Integer id: this.playersHaveToRoll) { + this.logic.getServerSender().send(id, new DieMessage(roll)); + } + } + } } }