diff --git a/Projekte/.run/MdgaApp.run.xml b/Projekte/.run/MdgaApp.run.xml index 123a07af..4c60627e 100644 --- a/Projekte/.run/MdgaApp.run.xml +++ b/Projekte/.run/MdgaApp.run.xml @@ -1,6 +1,5 @@ - - \ No newline at end of file + diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/Asset.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/Asset.java index 1f3da542..a24d9d1c 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/Asset.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/Asset.java @@ -30,14 +30,14 @@ public enum Asset { tank, world(1.2f), shieldRing("Models/shieldRing/shieldRing.j3o", null), - treeSmall, - treeBig, + treeSmall(1.2f), + treeBig(1.2f), turboCard, - turboSymbol("Models/turboCard/turboSymbol.j3o", "Models/turboCard/turboCard_diff.j3o"), + turboSymbol("Models/turboCard/turboSymbol.j3o", "Models/turboCard/turboCard_diff.png"), swapCard, - swapSymbol("Models/swapCard/swapSymbol.j3o", "Models/swapCard/swapCard_diff.j3o"), + swapSymbol("Models/swapCard/swapSymbol.j3o", "Models/swapCard/swapCard_diff.png"), shieldCard, - shieldSymbol("Models/shieldCard/shieldSymbol.j3o", "Models/shieldCard/shieldCard_diff.j3o"), + shieldSymbol("Models/shieldCard/shieldSymbol.j3o", "Models/shieldCard/shieldCard_diff.png"), dice ; 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 b251134f..e0f657da 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 @@ -17,6 +17,7 @@ import pp.mdga.client.board.OutlineControl; import pp.mdga.client.board.PieceControl; import pp.mdga.client.gui.CardControl; +import pp.mdga.client.gui.DiceControl; import pp.mdga.client.view.GameView; import pp.mdga.game.BonusCard; import pp.mdga.game.Color; @@ -26,6 +27,7 @@ import pp.mdga.notification.SelectableCardsNotification; import java.util.List; +import java.util.UUID; public class InputSynchronizer { @@ -93,10 +95,14 @@ public void onAction(String name, boolean isPressed, float tpf) { } if(name.equals("Click") && isPressed) { if (app.getView() instanceof GameView gameView) { + DiceControl diceSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), DiceControl.class); CardControl cardLayerSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), CardControl.class); OutlineControl boardSelect = checkHover(app.getCamera(), app.getRootNode(), OutlineControl.class); - if(cardLayerSelect != null) { + if(diceSelect != null) { + app.getModelSynchronize().rolledDice(); + } + else if(cardLayerSelect != null) { //cardSelect if(cardLayerSelect.isSelectable()) gameView.getGuiHandler().selectCard(cardLayerSelect); } @@ -118,8 +124,21 @@ else if(boardSelect != null) { } if(name.equals("Test") &&isPressed){ if(app.getView() instanceof GameView gameView){ -// app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY)); -// app.getNotificationSynchronizer().addTestNotification(new MovePieceNotification()); +// gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1); +// gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2); +// gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3); +// gameView.getGuiHandler().rollRankingResult(Color.CYBER, 4); +// gameView.getGuiHandler().showDice(); +// UUID p1 = UUID.randomUUID(); + +// gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p1,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID())); +// gameView.getBoardHandler().movePieceStartAnim(p1,0); + gameView.getGuiHandler().drawCard(Color.ARMY); + gameView.getGuiHandler().addCardOwn(BonusCard.SHIELD); + gameView.getGuiHandler().playCardOwn(BonusCard.SHIELD); + + + } } } 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 cb0371c0..69f35012 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 @@ -2,12 +2,18 @@ import com.jme3.app.SimpleApplication; import com.simsilica.lemur.GuiGlobals; +import com.sun.tools.javac.Main; import pp.mdga.client.acoustic.AcousticHandler; import com.jme3.system.AppSettings; import pp.mdga.client.dialog.JoinDialog; import pp.mdga.client.view.*; +import javax.imageio.ImageIO; +import java.awt.GraphicsEnvironment; +import java.awt.image.BufferedImage; +import java.io.File; import java.io.IOException; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.prefs.Preferences; @@ -39,7 +45,7 @@ public class MdgaApp extends SimpleApplication { private MdgaState state = null; /** Scale for rendering images. */ - private float imageScale = prefs.getInt("scale", 1); + private final float imageScale = prefs.getInt("scale", 1); /** The main menu view. */ private MdgaView mainView; @@ -60,7 +66,7 @@ public class MdgaApp extends SimpleApplication { private ServerConnection networkConnection; - private MdgaApp() { + public MdgaApp() { networkConnection = new NetworkSupport(this); this.clientGameLogic = new ClientGameLogic(networkConnection); } @@ -76,12 +82,15 @@ public static void main(String[] args) { settings.setSamples(128); settings.setWidth(prefs.getInt("width", 1280)); settings.setHeight(prefs.getInt("height", 720)); + settings.setFullscreen(prefs.getBoolean("fullscreen", false)); settings.setCenterWindow(true); settings.setVSync(false); - + settings.setTitle("MDGA"); MdgaApp app = new MdgaApp(); app.setSettings(settings); app.setShowSettings(false); + app.setPauseOnLostFocus(false); + app.start(); } @@ -106,7 +115,7 @@ public void simpleInitApp() { gameView = new GameView(this); ceremonyView = new CeremonyView(this); - enter(MdgaState.MAIN); + enter(MdgaState.GAME); } /** @@ -244,30 +253,50 @@ public ServerConnection getNetworkSupport(){ return networkConnection; } - public void updateResolution(int width, int height, float imageFactor) { - prefs.putInt("width", width); - prefs.putInt("height", height); - prefs.putFloat("scale", imageFactor); + public void updateResolution(int width, int height, float imageFactor, boolean isFullscreen) { + if(isFullscreen) { + int baseWidth = 1280; + int baseHeight = 720; + float baseAspectRatio = (float) baseWidth / baseHeight; + float newAspectRatio = (float) width / height; - try { - restartApp(); - } catch (Exception e) { - //nothing + float scaleFactor = Math.max((float) width / baseWidth, (float) height / baseHeight); + + settings.setFullscreen(true); + + prefs.putFloat("scale", scaleFactor); + prefs.putBoolean("fullscreen", true); + } else { + prefs.putInt("width", width); + prefs.putInt("height", height); + prefs.putFloat("scale", imageFactor); + prefs.putBoolean("fullscreen", false); } } - public static void restartApp() throws IOException { - String javaBin = System.getProperty("java.home") + "/bin/java"; - String classPath = System.getProperty("java.class.path"); - String className = System.getProperty("sun.java.command"); + public static void restartApp() { + try { + String javaBin = System.getProperty("java.home") + "/bin/java"; + String classPath = System.getProperty("java.class.path"); + String className = System.getProperty("sun.java.command"); - ProcessBuilder builder = new ProcessBuilder( - javaBin, "-cp", classPath, className - ); + ProcessBuilder builder = new ProcessBuilder( + javaBin, "-cp", classPath, className + ); - builder.start(); + builder.start(); - System.exit(0); + System.exit(0); + } catch (Exception e) { + throw new RuntimeException("restart failed"); + } + } + + public void afterGameCleanup() { + MainView main = (MainView) mainView; + + main.getJoinDialog().disconnect(); + main.getHostDialog().shutdownServer(); } } 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 4e3f64b0..cc7dd0ee 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 @@ -26,32 +26,42 @@ public void addTestNotification(Notification n) { public void update() { Notification n = app.getGameLogic().getNotification(); - - if(n != null) { - switch (app.getState()) { - case MAIN: - handleMain(n); - break; - case LOBBY: - handleLobby(n); - break; - case GAME: - handleGame(n); - break; - case CEREMONY: - handleCeremony(n); - break; - case NONE: - throw new RuntimeException("no notification expected: " + n.toString()); + while (n != null) { + if(n instanceof InfoNotification infoNotification) { + app.getView().showInfo(infoNotification.getMessage(), infoNotification.isError()); + return; } + + if(n != null) { + switch (app.getState()) { + case MAIN: + handleMain(n); + break; + case LOBBY: + handleLobby(n); + break; + case GAME: + handleGame(n); + break; + case CEREMONY: + handleCeremony(n); + break; + case NONE: + throw new RuntimeException("no notification expected: " + n.getClass().getName()); + } + } + + n = app.getGameLogic().getNotification(); } } private void handleMain(Notification notification) { if (notification instanceof LobbyDialogNotification) { app.enter(MdgaState.LOBBY); + } else if (notification instanceof StartDialogNotification) { + //nothing } else { - throw new RuntimeException("notification not expected: "); + throw new RuntimeException("notification not expected in main: "+ notification.getClass().getName()); } } @@ -61,6 +71,7 @@ private void handleLobby(Notification notification) { if (notification instanceof TskSelectNotification n) { lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName()); } else if (notification instanceof StartDialogNotification) { + app.afterGameCleanup(); app.enter(MdgaState.MAIN); } else if (notification instanceof TskUnselectNotification n) { lobbyView.setTaken(n.getColor(), false, false, null); @@ -70,7 +81,7 @@ private void handleLobby(Notification notification) { app.enter(MdgaState.GAME); ((GameView) app.getView()).setOwnColor(n.getOwnColor()); } else { - throw new RuntimeException("notification not expected: " + notification.toString()); + throw new RuntimeException("notification not expected in lobby: " + notification.getClass().getName()); } } @@ -81,7 +92,7 @@ private void handleGame(Notification notification) { ModelSynchronizer modelSynchronizer = app.getModelSynchronize(); if (notification instanceof AcquireCardNotification n) { - guiHandler.addCard(n.getBonusCard()); + guiHandler.addCardOwn(n.getBonusCard()); } else if (notification instanceof ActivePlayerNotification n) { gameView.getGuiHandler().setActivePlayer(n.getColor()); boardHandler.showDice(n.getColor()); @@ -136,18 +147,15 @@ private void handleGame(Notification notification) { } else if (notification instanceof NoShieldNotification n) { boardHandler.unshieldPiece(n.getPieceId()); } else if (notification instanceof PlayCardNotification n) { - switch(n.getCard()){ - case SWAP -> guiHandler.swap(); - case TURBO -> guiHandler.turbo(); - case SHIELD -> guiHandler.shield(); - default -> throw new RuntimeException("invalid card"); - } + if(n.getColor() == gameView.getOwnColor()) guiHandler.playCardOwn(n.getCard()); + else guiHandler.playCardEnemy(n.getColor(), n.getCard()); } else if (notification instanceof PlayerInGameNotification n) { boardHandler.addPlayer(n.getColor(),n.getPiecesList()); guiHandler.addPlayer(n.getColor(),n.getName()); } else if (notification instanceof ResumeNotification) { //ignore } else if (notification instanceof RollDiceNotification n) { + gameView.getGuiHandler().hideText(); if(n.getColor() == gameView.getOwnColor()){ guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1); } @@ -163,6 +171,7 @@ private void handleGame(Notification notification) { } else if (notification instanceof ShieldSuppressedNotification n) { boardHandler.suppressShield(n.getPieceId()); } else if (notification instanceof StartDialogNotification) { + app.afterGameCleanup(); app.enter(MdgaState.MAIN); } else if (notification instanceof SwapPieceNotification n) { // boardHandler.swapPieces(n.getFirstPiece(), n.getSecondPiece()); @@ -183,15 +192,16 @@ private void handleGame(Notification notification) { } else if (notification instanceof FinishNotification n){ guiHandler.finish(n.getColorFinished()); } else { - throw new RuntimeException("notification not expected: " + notification.toString()); + throw new RuntimeException("notification not expected in game: " + notification.getClass().getName()); } } private void handleCeremony(Notification notification) { if (notification instanceof StartDialogNotification) { + app.afterGameCleanup(); app.enter(MdgaState.MAIN); } else { - throw new RuntimeException("notification not expected: " + notification.toString()); + throw new RuntimeException("notification not expected in ceremony: " + notification.getClass().getName()); } } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java index 57da8393..82e333d5 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/CameraHandler.java @@ -7,6 +7,8 @@ import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.FXAAFilter; +import com.jme3.post.ssao.SSAOFilter; import com.jme3.scene.Spatial; import com.jme3.shadow.DirectionalLightShadowFilter; import com.jme3.shadow.EdgeFilteringMode; @@ -37,6 +39,8 @@ public class CameraHandler { private Color ownColor; private boolean init; private boolean initRot; + private SSAOFilter ssaoFilter; + private FXAAFilter fxaaFilter; /** * Constructor for the CameraHandler. Initializes the camera settings and lighting. @@ -65,6 +69,9 @@ public CameraHandler(MdgaApp app, FilterPostProcessor fpp) { dlsf.setEnabled(true); dlsf.setEdgeFilteringMode(EdgeFilteringMode.PCFPOISSON); dlsf.setShadowIntensity(0.7f); + ssaoFilter = new SSAOFilter(6, 10f, 0.33f, 0.61f); +// ssaoFilter = new SSAOFilter(); + fxaaFilter = new FXAAFilter(); sky = SkyFactory.createSky(app.getAssetManager(), "Images/sky/sky.dds", EnvMapType.EquirectMap).rotate(FastMath.HALF_PI*1,0,FastMath.HALF_PI*0.2f); @@ -82,6 +89,8 @@ public void init(Color ownColor) { app.getRootNode().addLight(ambient); app.getRootNode().attachChild(sky); fpp.addFilter(dlsf); + fpp.addFilter(ssaoFilter); + fpp.addFilter(fxaaFilter); init = true; initRot = true; this.ownColor = ownColor; diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java index 9d283f8f..76b286da 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/board/MapLoader.java @@ -107,8 +107,8 @@ private static Asset getLoadedAsset(String assetName) { case "radar" -> Asset.radar; case "ship" -> Asset.ship; case "tank" -> Asset.tank; - case "tree_small" -> Asset.treeSmall; - case "tree_big" -> Asset.treeBig; + case "treeSmall" -> Asset.treeSmall; + case "treeBig" -> Asset.treeBig; default -> throw new IllegalStateException("Unexpected value: " + assetName); }; } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/JoinDialog.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/JoinDialog.java index 067ba3c7..eedd8cb8 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/JoinDialog.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/JoinDialog.java @@ -92,4 +92,16 @@ public void resetPort() { public void connectToServer() { connectServer(); } + + public void disconnect() { + NetworkSupport network = getNetwork(); + if (network != null) { + try { + network.disconnect(); + } catch (Exception e) { + System.err.println("Error while disconnecting: " + e.getMessage()); + } + } + } } + 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 15c680e9..d44de294 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 @@ -14,6 +14,8 @@ public abstract class NetworkDialog extends Dialog { private String hostname; private int portNumber; private Future connectionFuture; + private MdgaServer serverInstance; + private Thread serverThread; public NetworkDialog(MdgaApp app, Node node, NetworkSupport network) { super(app, node); @@ -28,7 +30,6 @@ public void setPortNumber(int portNumber) { this.portNumber = portNumber; } - protected Object initNetwork() { try { this.network.initNetwork(this.hostname, this.portNumber); @@ -39,25 +40,49 @@ protected Object initNetwork() { } protected void connectServer() { - try { connectionFuture = this.network.getApp().getExecutor().submit(this::initNetwork); } catch (NumberFormatException var2) { throw new NumberFormatException("Port must be a number"); } - } protected void startServer() { - (new Thread(() -> { + serverThread = new Thread(() -> { try { - MdgaServer mdgaServer = new MdgaServer(portNumber); - mdgaServer.run(); + serverInstance = new MdgaServer(portNumber); + serverInstance.run(); } catch (Exception e) { throw new RuntimeException(e); } + }); - })).start(); + serverThread.start(); + } + + public void shutdownServer() { + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Thread was interrupted: " + e.getMessage()); + } + + if (serverInstance != null) { + serverInstance.shutdown(); + serverInstance = null; + } + + if (serverThread != null && serverThread.isAlive()) { + serverThread.interrupt(); + try { + serverThread.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + serverThread = null; + } } public void update(float delta) { @@ -65,14 +90,14 @@ public void update(float delta) { try { this.connectionFuture.get(); } catch (ExecutionException ignored) { - // todo: implement + // TODO: implement } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } - public NetworkSupport getNetwork(){ + public NetworkSupport getNetwork() { return network; } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/StartDialog.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/StartDialog.java index 5f70f4d6..870e8ae7 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/StartDialog.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/dialog/StartDialog.java @@ -177,6 +177,109 @@ public String getName() { "CarryPro", "ProBaiter", "GameWarden", + "KartoffelKönig", + "SaufenderWolf", + "WurstGriller", + "Flitzekacke", + "BratwurstBub", + "Hoppeldoppels", + "BananenMensch", + "KlopapierGuru", + "SchnitzelKing", + "NerdNomade", + "Dönertänzer", + "GlitzerGurke", + "SchinkenShrek", + "KäseKalle", + "SchokoSchnecke", + "KeksKämpfer", + "QuarkPiraten", + "Müslimonster", + "KnuddelNase", + "FantaFighter", + "SchnapsSaurier", + "Wackelpudding", + "ZitronenZock", + "FettWurst", + "PlüschPanda", + "Zuckerschnur", + "FluffiKopf", + "DonutDöner", + "VollpfostenX", + "Schraubenschlüssel", + "Witzepumper", + "ToastTraum", + "FroschFighter", + "KrümelTiger", + "RegenWolke", + "PuddingPower", + "KoffeinKrieger", + "SpeckSchlumpf", + "SuperSuppe", + "BierBärchen", + "FischBär", + "Flauschi", + "Schokomonster", + "ChaosKäse", + "FlitzLappen", + "WurstWombat", + "KrümelMensch", + "PuddingBär", + "ZickZack", + "Schwabel", + "Fluffi", + "RülpsFrosch", + "PommesPapa", + "QuarkBär", + "KnusperKönig", + "ToastBrot", + "Ploppster", + "Schleimschwein", + "Äpfelchen", + "Knallbonbon", + "KaffeeKopf", + "WackelWurst", + "RennKeks", + "BröselBub", + "ZockerBrot", + "BierWurm", + "StinkFlummi", + "SchlumpfKing", + "PurzelBär", + "FlinkFluff", + "PloppPudel", + "Schnorchel", + "FliegenKopf", + "PixelPommes", + "SchwipsWürst", + "WutzBär", + "KnuddelKeks", + "FantaFlumm", + "ZockerKäse", + "LachHäufchen", + "GurkenGuru", + "PonySchnitzel", + "NudelNinja", + "VulkanKeks", + "WasserToast", + "MenschSalat", + "KampfKohlenhydrate", + "SockenZirkus", + "SchwimmBärchen", + "TanzenderDachgepäckträger", + "PizzamarktMensch", + "ZahnarztZocker", + "RollerCoasterTester", + "WaschmaschinenPilot", + "WitzigeZwiebel", + "Pillenschlucker", + "ZwiebelReiter", + "HüpfenderKaktus", + "KochenderAsteroid", + "ChaosKarotte", + "WolkenFurz", + "SchnitzelPartikel", + "WackelBiene", }; Random random = new Random(); 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 cc8f39fa..5aa98cfe 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 @@ -3,13 +3,20 @@ import com.jme3.math.Vector2f; import com.jme3.scene.Node; import pp.mdga.client.MdgaApp; +import pp.mdga.client.button.AbstractButton; import pp.mdga.client.button.ButtonLeft; import pp.mdga.client.button.ButtonRight; import pp.mdga.client.button.MenuButton; import pp.mdga.client.view.MdgaView; +import java.util.prefs.Preferences; + public class VideoSettingsDialog extends Dialog { + private static Preferences prefs = Preferences.userNodeForPackage(JoinDialog.class); + + private ButtonRight fullscreenButton; private MenuButton backButton; + private ButtonRight restartButton; private ButtonLeft hdButton9; private ButtonLeft fullHdButton9; @@ -29,20 +36,24 @@ 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 ButtonLeft(app, node, () -> app.updateResolution(1280, 720, 1.0f), "hd 16:9", 10); - fullHdButton9 = new ButtonLeft(app, node, () -> app.updateResolution(1920, 1080, 2.25f), "full hd 16:9", 10); - wqhdButton9 = new ButtonLeft(app, node, () -> app.updateResolution(2560, 1440, 4.0f), "wqhd 16:9", 10); + restartButton = new ButtonRight(app, node, MdgaApp::restartApp, "Neustart", 1); + + fullscreenButton = new ButtonRight(app, node, () -> updateResolution(0, 0, 0, true), "Vollbild", 1); + + hdButton9 = new ButtonLeft(app, node, () -> updateResolution(1280, 720, 1.0f, false), "hd 16:9", 10); + fullHdButton9 = new ButtonLeft(app, node, () -> updateResolution(1920, 1080, 2.25f, false), "full hd 16:9", 10); + wqhdButton9 = new ButtonLeft(app, node, () -> updateResolution(2560, 1440, 4.0f, false), "wqhd 16:9", 10); - hdButton10 = new ButtonRight(app, node, () -> app.updateResolution(1280, 800, 1.0f), "hd 16:10", 10); - fullHdButton10 = new ButtonRight(app, node, () -> app.updateResolution(1920, 1200, 2.25f), "full hd 16:10", 10); - wqhdButton10 = new ButtonRight(app, node, () -> app.updateResolution(2560, 1600, 4.0f), "wqhd 16:10", 10); + hdButton10 = new ButtonRight(app, node, () -> updateResolution(1280, 800, 1.0f, false), "hd 16:10", 10); + fullHdButton10 = new ButtonRight(app, node, () -> updateResolution(1920, 1200, 2.25f, false), "full hd 16:10", 10); + wqhdButton10 = new ButtonRight(app, node, () -> updateResolution(2560, 1600, 4.0f, false), "wqhd 16:10", 10); float offset = 2.8f; hdButton9.setPos(new Vector2f(hdButton9.getPos().x, MenuButton.VERTICAL - offset)); hdButton10.setPos(new Vector2f(hdButton10.getPos().x, MenuButton.VERTICAL - offset)); + fullscreenButton.setPos(new Vector2f(fullscreenButton.getPos().x, MenuButton.VERTICAL - offset)); offset += 1.5f; fullHdButton9.setPos(new Vector2f(fullHdButton9.getPos().x, MenuButton.VERTICAL - offset)); @@ -68,6 +79,7 @@ protected void onShow() { fullHdButton10.show(); wqhdButton10.show(); + fullscreenButton.show(); backButton.show(); } @@ -83,7 +95,9 @@ protected void onHide() { fullHdButton10.hide(); wqhdButton10.hide(); + fullscreenButton.hide(); backButton.hide(); + restartButton.hide(); } public void update() { @@ -91,4 +105,12 @@ public void update() { return; } } + + public void updateResolution(int width, int height, float imageFactor, boolean isFullscreen) { + if(width != prefs.getInt("width", 1280) || height != prefs.getInt("height", 720) || isFullscreen != prefs.getBoolean("fullscreen", false)) { + restartButton.show(); + } + + app.updateResolution(width, height, imageFactor, isFullscreen); + } } 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 4dfa0690..b5bd3571 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 @@ -10,19 +10,20 @@ import pp.mdga.client.animation.ZoomControl; import pp.mdga.game.Color; -public class ActionTextHandler { + class ActionTextHandler { private Node root; private BitmapFont font; private AppSettings appSettings; + private int ranking; - public ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){ + ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){ root = new Node("actionTextRoot"); guiNode.attachChild(root); root.setLocalTranslation(center(appSettings.getWidth(), appSettings.getHeight(), Vector3f.ZERO)); font = assetManager.loadFont("Fonts/Gunplay.fnt"); this.appSettings = appSettings; - + ranking = 0; } private Node createTextWithSpacing(String[] textArr, float spacing, float size, ColorRGBA[] colorArr) { @@ -74,48 +75,48 @@ private Vector3f centerText(float width, float height, Vector3f pos){ return center(-width, height, pos); } - public void activePlayer(String name, Color color){ + void activePlayer(String name, Color color){ createTopText(new String[]{name," ist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); } - public void ownActive(Color color){ + void ownActive(Color color){ createTopText(new String[]{"Du"," bist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); } - public void diceNum(int diceNum, String name, Color color){ + void diceNum(int diceNum, String name, Color color){ createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0); createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 100); } - public void diceNumMult(int diceNum,int mult, String name, Color color){ + void diceNumMult(int diceNum,int mult, String name, Color color){ createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0); createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 100); } - public void ownDice(int diceNum){ + void ownDice(int diceNum){ createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 0); } - public void ownDiceMult(int diceNum, int mult){ + void ownDiceMult(int diceNum, int mult){ createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 0); } - public void drawCard(String name, Color color){ + void drawCard(String name, Color color){ createTopText(new String[]{name," erhält eine Bonuskarte"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); } - public void drawCardOwn(Color color){ + 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){ + 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){ + void finishTextOwn(Color color){ createTopText(new String[]{"Du", " bist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl()); } @@ -131,9 +132,25 @@ private ColorRGBA playerColorToColorRGBA(Color color){ }; } - public void hide(){ - root.detachAllChildren(); + void hide(){ + ranking = 0; + root.detachAllChildren(); } + float paddingRanked = 100; + + void rollRankingResult(String name, Color color, int eye){ + createTopText(new String[]{name,": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking); + ranking++; + } + + void rollRankingResultOwn(Color color, int eye){ + createTopText(new String[]{"Du",": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking); + ranking++; + } + + void diceNow(){ + createTopText("Klicke zum Würfeln", 5, 80, ColorRGBA.White, 0); + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardControl.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardControl.java index f07e7e69..46e47ee6 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardControl.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardControl.java @@ -60,7 +60,7 @@ private Node createNum(){ Material mat = new Material(getApp().getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", ColorRGBA.Black); circle.setMaterial(mat); - root.attachChild(circle); +// root.attachChild(circle); BitmapFont guiFont = getApp().getAssetManager().loadFont("Fonts/Gunplay.fnt"); num = new BitmapText(guiFont); num.setSize(0.3f); diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java index 860e5324..ebf21b6a 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayer.java @@ -86,7 +86,7 @@ public void render(RenderManager rm) { public void update(float tpf) { if (init && !cardBuffer.isEmpty()) { for (Spatial spatial : cardBuffer) { - root.attachChild(spatial); +// root.attachChild(spatial); } cardBuffer.clear(); } @@ -94,7 +94,9 @@ public void update(float tpf) { } public void addSpatial(Spatial card) { - cardBuffer.add(card); +// cardBuffer.add(card); + root.attachChild(card); + root = root; } public void deleteSpatial(Spatial spatial) { diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java index 116e0987..2d5c4d2d 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/CardLayerHandler.java @@ -85,6 +85,19 @@ public void addCard(BonusCard card) { bonusCardControlMap.get(card).setNumCard(newNum); } + public void removeCard(BonusCard card){ + if(bonusCardControlMap.containsKey(card)){ + bonusCardIntegerMap.put(card, bonusCardIntegerMap.get(card) - 1); + + if(bonusCardIntegerMap.get(card) <= 0){ + cardLayer.deleteSpatial(bonusCardControlMap.get(card).getRoot()); + bonusCardIntegerMap.remove(card); + bonusCardControlMap.remove(card); + } + + } + } + public void clearSelectableCards() { for (CardControl control : selectableCards) { control.setSelectable(false); 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 8761e3da..c4024fbe 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 @@ -67,14 +67,38 @@ public void showRolledDice(int rollNum, Color color) { public void showDice() { cardLayerHandler.showDice(); + actionTextHandler.diceNow(); } public void hideDice() { cardLayerHandler.hideDice(); } - public void addCard(BonusCard card) { + //add own handCard + public void addCardOwn(BonusCard card) { cardLayerHandler.addCard(card); + playerNameHandler.addCard(ownColor); + actionTextHandler.drawCardOwn(ownColor); + } + + public void playCardOwn(BonusCard card){ + getEffectByCard(card); + cardLayerHandler.removeCard(card); + playerNameHandler.removeCard(ownColor); + } + + public void playCardEnemy(Color color, BonusCard card) { + getEffectByCard(card); + playerNameHandler.removeCard(color); + } + + private void getEffectByCard(BonusCard bonus){ + switch(bonus){ + case SWAP -> swap(); + case TURBO -> turbo(); + case SHIELD -> shield(); + default -> throw new RuntimeException("invalid card"); + } } public void clearSelectableCards() { @@ -124,9 +148,11 @@ public void hideText(){ actionTextHandler.hide(); } + //addCard Enemy (DrawCardNotification) public void drawCard(Color color) { - if (ownColor == color) actionTextHandler.drawCardOwn(color); - else actionTextHandler.drawCard(playerNameHandler.getName(color), color); + //Color != ownColor + actionTextHandler.drawCard(playerNameHandler.getName(color), color); + playerNameHandler.addCard(color); } public void finish(Color color){ @@ -134,5 +160,12 @@ public void finish(Color color){ else actionTextHandler.finishText(playerNameHandler.getName(color), color); } + public void rollRankingResult(Color color, int eye){ + if(ownColor == color) actionTextHandler.rollRankingResultOwn(color, eye); + else actionTextHandler.rollRankingResult(playerNameHandler.getName(color), color, eye); + } + + + } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java index 1b197d16..e5069eae 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/gui/PlayerNameHandler.java @@ -4,23 +4,27 @@ import com.jme3.font.BitmapFont; import com.jme3.font.BitmapText; import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector3f; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.system.AppSettings; import com.jme3.ui.Picture; +import pp.mdga.game.BonusCard; import pp.mdga.game.Color; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - +import java.util.Vector; public class PlayerNameHandler { private final BitmapFont playerFont; private final Node playerNameNode; private final List playerOrder; private final Map colorNameMap; + private final Map colorCardMap; + private final AppSettings appSettings; private final AssetManager assetManager; private Color ownColor; @@ -43,6 +47,7 @@ public PlayerNameHandler(Node guiNode, AssetManager assetManager, AppSettings ap playerNameNode = new Node("player name node"); playerOrder = new ArrayList<>(); colorNameMap = new HashMap<>(); + colorCardMap = new HashMap<>(); this.appSettings = appSettings; this.assetManager = assetManager; } @@ -64,13 +69,38 @@ private void drawPlayers(){ if(!colorNameMap.containsKey(color)) throw new RuntimeException(color + " isn't mapped to a name"); Node nameParent = new Node("nameParent"); - nameParent.attachChild(createName(colorNameMap.get(color), i == 0, color == ownColor)); nameParent.attachChild(createColor(color)); + BitmapText name = createName(colorNameMap.get(color), i == 0, color == ownColor); + nameParent.attachChild(name); + if(colorCardMap.getOrDefault(color, 0) > 0){ + Picture pic = createHandCard(name.getLineWidth()); + nameParent.attachChild(pic); + nameParent.attachChild(createCardNum(colorCardMap.get(color), pic.getWidth(), pic.getLocalTranslation().getX())); + } nameParent.setLocalTranslation(50,appSettings.getWindowHeight()-PADDING_TOP- MARGIN_NAMES *i,0); playerNameNode.attachChild(nameParent); } } + private Spatial createCardNum(int num, float lastWidth, float lastX ) { + BitmapText hudText = new BitmapText(playerFont); + //renderedSize = 45 + hudText.setSize(TEXT_SIZE); + hudText.setColor(NORMAL_COLOR); + hudText.setText(String.valueOf(num)); + hudText.setLocalTranslation(lastX + lastWidth + 20,hudText.getHeight()/2, 0); + return hudText; + } + + private Picture createHandCard(float width) { + Picture pic = new Picture("HUD Picture"); + pic.setImage(assetManager, "./Images/handcard.png", true); + pic.setWidth(IMAGE_SIZE); + pic.setHeight(IMAGE_SIZE); + pic.setPosition(-pic.getWidth()/2 + width + PADDING_LEFT * 2 ,-pic.getHeight()/2); + return pic; + } + private String imagePath(Color color){ String root = "./Images/name_pictures/"; return switch(color){ @@ -93,7 +123,7 @@ private Spatial createColor(Color color) { - private Spatial createName(String name, boolean first, boolean own){ + private BitmapText createName(String name, boolean first, boolean own){ BitmapText hudText = new BitmapText(playerFont); //renderedSize = 45 hudText.setSize(TEXT_SIZE); @@ -120,8 +150,22 @@ public void setActivePlayer(Color color) { } public String getName(Color color){ + if(!colorNameMap.containsKey(color)) throw new RuntimeException("color is not in colorNameMap"); return colorNameMap.get(color); } + public void addCard(Color color){ + colorCardMap.put(color, colorCardMap.getOrDefault(color, 0) + 1); + drawPlayers(); + } + + public void removeCard(Color color){ + if(colorCardMap.containsKey(color)){ + colorCardMap.put(color, colorCardMap.getOrDefault(color, 0) - 1); + if(colorCardMap.get(color) <= 0) colorCardMap.remove(color); + } + drawPlayers(); + } + } 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 b8e8bfb4..0d54e6e7 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 @@ -3,6 +3,7 @@ import com.jme3.network.*; import com.jme3.network.serializing.Serializer; import com.jme3.network.serializing.serializers.EnumSerializer; +import pp.mdga.Resources; import pp.mdga.game.*; import pp.mdga.message.client.*; import pp.mdga.message.server.*; @@ -135,6 +136,7 @@ private void initializeSerializables() { Serializer.registerClass(UpdateReadyMessage.class); Serializer.registerClass(UpdateTSKMessage.class); Serializer.registerClass(WaitPieceMessage.class); + Serializer.registerClass(IncorrectRequestMessage.class); Serializer.registerClass(Player.class); Serializer.registerClass(Statistic.class); Serializer.registerClass(Board.class); @@ -144,8 +146,10 @@ private void initializeSerializables() { Serializer.registerClass(StartNode.class); Serializer.registerClass(PlayerData.class); Serializer.registerClass(HomeNode.class); - Serializer.registerClass(PlayerDataMessage.class); - Serializer.registerClass(StartBriefingMessage.class); + + Serializer.registerClass(Color.class, new EnumSerializer()); + Serializer.registerClass(PieceState.class, new EnumSerializer()); + Serializer.registerClass(ShieldState.class, new EnumSerializer()); } private void registerListeners() { @@ -198,12 +202,31 @@ private void messageReceived(HostedConnection source, ClientMessage message) { pendingMessages.add(new ReceivedMessage(message, source.getId())); } + /** + * This method will be used to handle all connections which are connected to the server. + * It will check if the maximum number of connected clients are already reached. If yes it will send a + * LobbyDenyMessage to the given hostedConnection parameter and close it, otherwise it will send a + * LobbyAcceptMessage to the given hostedConnection parameter. In Addition, if the number of connected clients is + * equal to 1 it will set the host of the game to the id of the given hostedConnection parameter. + * + * @param server as the server which is contains all connections as a Server object. + * @param hostedConnection as the connection which is added to the server as a HostedConnection object. + */ @Override 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()); + + if (this.myServer.getConnections().size() > Resources.MAX_PLAYERS) { + this.logic.getServerSender().send(hostedConnection.getId(), new LobbyDenyMessage()); + hostedConnection.close(""); + } else { + if (hostedConnection.getAddress().contains("127.0.0.1") && this.logic.getGame().getHost() == -1) { + this.logic.getGame().setHost(hostedConnection.getId()); + this.logic.getServerSender().send(hostedConnection.getId(), new LobbyAcceptMessage(hostedConnection.getId())); + } else { + this.logic.getServerSender().send(hostedConnection.getId(), new LobbyAcceptMessage()); + } } } @@ -278,4 +301,21 @@ public void broadcast(ServerMessage message) { public void disconnectClient(int id) { this.myServer.getConnection(id).close(""); } + + /** + * This method will be used to shut down the server. + * It will iterate threw all connections of myServer attribute and check if they are equal to null. If not they will + * be closed. After that the myServer attribute will be closed and this program will be exited with the exit code 0. + */ + @Override + public void shutdown() { + for (HostedConnection client : this.myServer.getConnections()) { + if (client != null) { + client.close("Host closed the server."); + } + } + + this.myServer.close(); + this.exit(0); + } } 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 665f6212..60a2be45 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 @@ -65,6 +65,13 @@ public void onEnter() { app.getAcousticHandler().playSound(MdgaSound.START); + guiHandler.addPlayer(Color.AIRFORCE, "Cedric"); + guiHandler.addPlayer(Color.ARMY, "Ben"); + guiHandler.addPlayer(Color.CYBER, "Felix"); + guiHandler.addPlayer(Color.NAVY, "Daniel"); + + + } @Override diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java index e96cbbb7..f64623fd 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/LobbyView.java @@ -18,6 +18,7 @@ import pp.mdga.client.button.LobbyButton; import pp.mdga.client.button.SettingsButton; import pp.mdga.game.Color; +import pp.mdga.message.client.StartGameMessage; import pp.mdga.notification.GameNotification; public class LobbyView extends MdgaView { @@ -25,6 +26,7 @@ public class LobbyView extends MdgaView { private ButtonLeft leaveButton; private ButtonRight readyButton; + private ButtonRight startButton; private LobbyButton cyberButton; private LobbyButton airforceButton; @@ -42,6 +44,7 @@ public LobbyView(MdgaApp app) { leaveButton = new ButtonLeft(app, guiNode, this::leaveLobby, "Verlassen", 1); readyButton = new ButtonRight(app, guiNode, this::ready, "Bereit", 1); + startButton = new ButtonRight(app, guiNode, () -> app.getGameLogic().selectStart(), "Starten", 7); cyberButton = new LobbyButton(app, guiNode, rootNode, () -> toggleTsk(Color.CYBER), Color.CYBER); airforceButton = new LobbyButton(app, guiNode, rootNode, () -> toggleTsk(Color.AIRFORCE), Color.AIRFORCE); @@ -61,6 +64,10 @@ public void onEnter() { leaveButton.show(); readyButton.show(); + if(app.getGameLogic().isHost()) { + startButton.show(); + } + cyberButton.show(); airforceButton.show(); armyButton.show(); @@ -95,6 +102,7 @@ public void onEnter() { public void onLeave() { leaveButton.hide(); readyButton.hide(); + startButton.hide(); airforceButton.hide(); armyButton.hide(); @@ -223,6 +231,10 @@ private void toggleTsk(Color color) { break; } + if(isReady) { + setReady(own, false); + } + switch (taken) { case NOT: app.getModelSynchronize().selectTsk(color); 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 6ebf9e33..d5653f6d 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 @@ -1,8 +1,12 @@ package pp.mdga.client.view; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; import com.jme3.scene.Geometry; import pp.mdga.client.MdgaApp; import pp.mdga.client.acoustic.MdgaSound; +import pp.mdga.client.button.AbstractButton; +import pp.mdga.client.button.LabelButton; import pp.mdga.client.dialog.HostDialog; import pp.mdga.client.dialog.JoinDialog; import pp.mdga.client.dialog.StartDialog; @@ -96,6 +100,7 @@ private void mainMenu() { private void tryHost() { int port = 0; String text = hostDialog.getPort(); + app.getGameLogic().selectHost(""); try { port = Integer.parseInt(text); @@ -108,10 +113,6 @@ private void tryHost() { } catch (InterruptedException ignored) { } hostDialog.connectServerAsClient(); - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } app.getModelSynchronize().setHost(port); //app.getAcousticHandler().playSound(MdgaSound.WRONG_INPUT); return; @@ -127,6 +128,7 @@ private void tryJoin() { int port = 0; String ip = joinDialog.getIpt(); String portText = joinDialog.getPort(); + app.getGameLogic().selectJoin(""); try { // Validate the port @@ -140,11 +142,6 @@ private void tryJoin() { app.getModelSynchronize().setName(startDialog.getName()); joinDialog.setHostname(ip); joinDialog.connectToServer(); - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - app.getModelSynchronize().setJoin(ip, port); return; } } catch (IllegalArgumentException e) { @@ -234,5 +231,13 @@ public void back() { break; } } + + public JoinDialog getJoinDialog() { + return joinDialog; + } + + public HostDialog getHostDialog() { + return hostDialog; + } } diff --git a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java index 9dd4f1dc..e9bb1b65 100644 --- a/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java +++ b/Projekte/mdga/client/src/main/java/pp/mdga/client/view/MdgaView.java @@ -2,9 +2,12 @@ import com.jme3.asset.TextureKey; import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Vector2f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; import com.jme3.scene.shape.Quad; +import com.jme3.system.NanoTimer; import com.jme3.texture.Texture; import pp.mdga.client.MdgaApp; import pp.mdga.client.acoustic.MdgaSound; @@ -30,6 +33,9 @@ public enum Overlay { private VideoSettingsDialog videoSettingsDialog; private AudioSettingsDialog audioSettingsDialog; + protected LabelButton infoLabel = null; + protected NanoTimer infoTimer = new NanoTimer(); + private int settingsDepth = 0; public MdgaView(MdgaApp app) { @@ -80,6 +86,11 @@ public void update(float tpf) { videoSettingsDialog.update(); audioSettingsDialog.update(); + if (null != infoLabel && infoTimer.getTimeInSeconds() > 5) { + infoLabel.hide(); + infoLabel = null; + } + onUpdate(tpf); } @@ -193,4 +204,24 @@ public void pressForward() { ceremonyView.forward(); } } + + public void showInfo(String error, boolean isError) { + infoTimer.reset(); + + if(null != infoLabel) { + infoLabel.hide(); + } + + infoLabel = new LabelButton(app, guiNode, error, new Vector2f(5.5f, 2), new Vector2f(0.5f, AbstractButton.VERTICAL - 0.5f), false); + + ColorRGBA color; + + if(isError) { + color = ColorRGBA.Red.clone(); + } else { + color = ColorRGBA.Green.clone(); + } + + infoLabel.setColor(ColorRGBA.Black, color); + } } diff --git a/Projekte/mdga/client/src/main/resources/Images/handcard.png b/Projekte/mdga/client/src/main/resources/Images/handcard.png new file mode 100644 index 00000000..6a30c799 Binary files /dev/null and b/Projekte/mdga/client/src/main/resources/Images/handcard.png differ diff --git a/Projekte/mdga/client/src/main/resources/Maps/map.mdga b/Projekte/mdga/client/src/main/resources/Maps/map.mdga index 5e906521..2989a3af 100644 --- a/Projekte/mdga/client/src/main/resources/Maps/map.mdga +++ b/Projekte/mdga/client/src/main/resources/Maps/map.mdga @@ -1,7 +1,5 @@ world 0,0 90 -#tree_small 1,1 0 -#tree_big 0,0 0 #Marine Pos marine 4,-5 270 @@ -131,3 +129,144 @@ node_home_blue 4,0 0 node_home_blue 3,0 0 node_home_blue 2,0 0 node_home_blue 1,0 0 + +# Randomly Distributed Trees within Radius 12 to 40 + +treeSmall 10,15 180 +treeBig -15,12 45 +treeSmall -8,-22 270 +treeBig 22,8 90 +treeSmall -18,-10 135 +treeBig 9,24 300 +treeSmall 17,-9 60 +treeBig -20,5 330 +treeSmall -14,18 200 +treeBig 25,-7 120 +treeBig -12,-18 150 +treeSmall 19,-16 45 +treeBig 7,10 90 +treeBig -19,-9 270 +treeSmall 21,4 110 +treeBig -11,17 300 +treeSmall 3,-21 360 +treeSmall -23,14 100 +treeBig 4,26 330 +treeSmall 12,13 270 +treeBig -18,8 45 +treeBig 11,-10 135 +treeSmall 16,5 180 +treeBig -13,-17 330 +treeSmall -2,14 270 +#treeBig 7,9 300 +treeSmall 23,-10 240 +treeBig -6,18 180 +treeSmall 5,27 270 +treeBig 14,-11 60 +treeSmall 9,-16 180 +treeBig -12,22 240 +treeBig 18,7 360 +treeSmall -24,-4 200 +treeBig -8,21 300 +treeSmall 12,-19 120 +treeBig 6,-12 180 +treeSmall -11,10 75 +treeBig 9,6 270 +treeSmall 8,-14 150 +treeBig 3,18 30 +treeSmall 17,13 100 +treeBig -9,20 90 +treeBig 6,-22 330 +treeSmall -20,7 45 +treeBig 21,11 150 +treeSmall 15,-18 270 +treeBig -3,-12 200 +treeBig 12,-28 330 +treeSmall -17,-7 120 +treeBig -10,9 300 +treeSmall 2,-14 240 +treeBig 24,2 360 +treeSmall 4,-13 300 +treeBig -19,20 90 +#treeSmall -11,5 45 +treeBig 15,9 180 +treeSmall -6,10 240 +treeBig 3,15 30 +treeSmall 9,-19 150 +treeBig -21,-4 330 +treeSmall 19,11 270 +treeSmall 12,24 110 +treeBig -13,15 45 +treeSmall 7,-15 240 +treeBig 26,-8 300 +treeSmall -16,14 120 +treeBig 14,18 360 +treeSmall 8,21 100 +treeBig -8,-18 240 +treeSmall 9,15 180 +treeBig 10,-20 270 +treeSmall 2,27 90 +treeBig 18,12 300 +treeSmall -10,-14 150 +treeBig -15,16 330 +treeSmall -9,19 45 +treeBig 17,-14 120 +treeSmall 5,-25 180 +treeBig 7,23 30 +treeSmall -14,-12 200 +treeBig 6,-16 300 +treeSmall -20,-8 100 +treeBig 4,11 240 +treeSmall 24,-15 90 +treeSmall -19,-19 360 +treeBig 20,8 45 +treeSmall 3,22 270 +treeBig 13,-9 180 +treeSmall -11,18 150 +treeBig -17,-4 300 +treeSmall 5,-14 240 +treeBig 9,17 330 +treeSmall 15,13 90 +treeBig -21,18 30 +treeSmall 6,20 100 +treeBig -16,22 180 +treeSmall -5,18 360 +treeBig 22,11 45 +treeSmall 10,-23 240 +treeBig -10,-16 300 +treeSmall -17,14 120 +treeBig 20,4 150 +treeSmall 11,-22 180 +treeBig -24,-11 200 +treeSmall 14,17 150 +treeBig -8,-12 300 +treeSmall 7,-18 100 +treeBig -5,16 330 +treeSmall 16,-14 200 +treeBig 18,-8 90 +treeSmall -23,-9 45 +treeBig 24,10 300 +treeSmall -4,19 180 +treeBig 12,-5 330 +treeSmall -19,16 100 +treeBig 14,20 150 +treeSmall 9,12 180 +treeBig -22,8 60 +treeSmall 6,18 360 +treeBig 25,-9 45 +treeBig -10,12 240 +treeSmall 19,-17 100 +treeSmall -13,19 90 +treeSmall 16,-12 120 +treeBig 22,-6 45 +treeSmall -18,15 200 +treeBig 14,-10 300 +treeBig 6,10 330 +treeSmall 17,18 90 +treeBig -20,4 180 +treeBig 19,-16 300 +treeSmall -15,9 270 +treeBig 12,22 360 + + + + diff --git a/Projekte/mdga/client/src/main/resources/Models/treeBig/treeBig_diff.png b/Projekte/mdga/client/src/main/resources/Models/treeBig/treeBig_diff.png index e69de29b..b45e9199 100644 Binary files a/Projekte/mdga/client/src/main/resources/Models/treeBig/treeBig_diff.png and b/Projekte/mdga/client/src/main/resources/Models/treeBig/treeBig_diff.png differ diff --git a/Projekte/mdga/client/src/main/resources/Models/treeSmall/treeSmall_diff.png b/Projekte/mdga/client/src/main/resources/Models/treeSmall/treeSmall_diff.png index e69de29b..c7bc43fb 100644 Binary files a/Projekte/mdga/client/src/main/resources/Models/treeSmall/treeSmall_diff.png and b/Projekte/mdga/client/src/main/resources/Models/treeSmall/treeSmall_diff.png differ diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/Resources.java b/Projekte/mdga/model/src/main/java/pp/mdga/Resources.java new file mode 100644 index 00000000..f1c66018 --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp/mdga/Resources.java @@ -0,0 +1,79 @@ +package pp.mdga; + +import java.util.ResourceBundle; + +/** + * Provides access to the resource bundle of the game. + * + * @see #BUNDLE + */ +public class Resources { + /** + * Create Resources constants. + */ + public static final int MAX_PLAYERS = 4; + public static final int MAX_PIECES = 4; + public static final int MAX_EYES = 6; + + /** + * The resource bundle for the MDGA game. + */ + public static final ResourceBundle BUNDLE = ResourceBundle.getBundle("mdga"); //NON-NLS + + /** + * Gets a string for the given key from the resource bundle in {@linkplain #BUNDLE}. + * + * @param key the key for the desired string + * @return the string for the given key + * @throws NullPointerException if {@code key} is {@code null} + * @throws java.util.MissingResourceException if no object for the given key can be found + * @throws ClassCastException if the object found for the given key is not a string + */ + public static String stringLookup(String key) { + return BUNDLE.getString(key); + } + + /** + * Gets a int for the given key from the resource bundle in {@linkplain #BUNDLE}. + * + * @param key the key for the desired string + * @return the string for the given key + * @throws NullPointerException if {@code key} is {@code null} + * @throws java.util.MissingResourceException if no object for the given key can be found + * @throws ClassCastException if the object found for the given key is not a string + */ + public static int intLookup(String key) { + return Integer.parseInt(BUNDLE.getString(key)); + } + + /** + * Gets a boolean for the given key from the resource bundle in {@linkplain #BUNDLE}. + * + * @param key the key for the desired string + * @return the string for the given key + * @throws NullPointerException if {@code key} is {@code null} + * @throws java.util.MissingResourceException if no object for the given key can be found + * @throws ClassCastException if the object found for the given key is not a string + */ + public static boolean boolLookup(String key) { + return Boolean.parseBoolean(BUNDLE.getString(key)); + } + + /** + * Gets a double for the given key from the resource bundle in {@linkplain #BUNDLE}. + * + * @param key the key for the desired string + * @return the string for the given key + * @throws NullPointerException if {@code key} is {@code null} + * @throws java.util.MissingResourceException if no object for the given key can be found + * @throws ClassCastException if the object found for the given key is not a string + */ + public static double doubleLookup(String key) { + return Double.parseDouble(BUNDLE.getString(key)); + } + + /** + * Private constructor to prevent instantiation. + */ + private Resources() { /* do not instantiate */ } +} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java index 38541512..ae64890b 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/CeremonyState.java @@ -12,35 +12,69 @@ public class CeremonyState extends ClientState { private final PodiumState podiumState = new PodiumState(this, logic); private final StatisticsState statisticsState = new StatisticsState(this, logic); + /** + * Creates a new CeremonyState + * + * @param parent the parent state + * @param logic the game logic + */ public CeremonyState(ClientState parent, ClientGameLogic logic) { super(parent, logic); } + /** + * Enters the new state machine + */ @Override public void enter() { - currentState = podiumState; + setState(podiumState); logic.addNotification(createCeremonyNotification()); } + /** + * exits this state + */ @Override public void exit() { currentState.exit(); } + /** + * This method is used to set a new SubState + * + * @param state the state to be set + */ public void setState(CeremonyStates state){ - this.currentState.exit(); + if(this.currentState != null){ + this.currentState.exit(); + } state.enter(); currentState = state; } + /** + * This method get the PodiumState + * + * @return the PodiumState + */ public PodiumState getPodiumState(){ return podiumState; } + /** + * This method get the StatisticsState + * + * @return the StatisticsState + */ public StatisticsState getStatisticsState(){ return statisticsState; } + /** + * This method is used to get the current State + * + * @return the current State + */ public CeremonyStates getState(){ return currentState; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java index f3a0602b..8829e43f 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientGameLogic.java @@ -1,5 +1,6 @@ package pp.mdga.client; +import pp.mdga.Resources; import pp.mdga.game.BonusCard; import pp.mdga.game.Color; import pp.mdga.game.Game; @@ -13,6 +14,10 @@ import java.util.Map; import java.util.UUID; +/** + * The ClientGameLogic class is the main class for the client side of the game. + * It is responsible for handling the game logic on the client side. + */ public class ClientGameLogic implements ServerInterpreter { static final System.Logger LOGGER = System.getLogger(ClientGameLogic.class.getName()); @@ -21,6 +26,8 @@ public class ClientGameLogic implements ServerInterpreter { private ClientState state; private final ArrayList notifications = new ArrayList<>(); private boolean isHost; + private int ownPlayerID; + private String ownPlayerName; private final DialogsState dialogsState = new DialogsState(null, this); private final GameState gameState = new GameState(null, this); @@ -28,6 +35,11 @@ public class ClientGameLogic implements ServerInterpreter { private final InterruptState interruptState = new InterruptState(null, this); private final SettingsState settingsState = new SettingsState(null, this); + /** + * Creates a new ClientGameLogic + * + * @param clientSender the client sender + */ public ClientGameLogic(ClientSender clientSender) { this.game = new Game(); this.clientSender = clientSender; @@ -35,11 +47,21 @@ public ClientGameLogic(ClientSender clientSender) { state = dialogsState; } + /** + * This method is used to send a message to the server + * + * @param msg the message to be sent + */ public void send(ClientMessage msg){ LOGGER.log(System.Logger.Level.INFO, "send {0}", msg); clientSender.send(msg); } + /** + * This method is used to get a piece by its id + * @param pieceId the UUID of the piece + * @return the piece + */ private Piece getPiece(UUID pieceId){ for(Map.Entry entry : game.getBoard().getPlayerData().entrySet()){ for(Piece piece : entry.getValue().getPieces()){ @@ -51,216 +73,472 @@ private Piece getPiece(UUID pieceId){ return null; } + /** + * This method returns the clientSender + * + * @return the clientSender + */ public ClientSender getClientSender(){ return clientSender; } + /** + * This method is used to get the ownPlayerId + * + * @return the ownPlayerId + */ + public int getOwnPlayerId() { + return ownPlayerID; + } + + /** + * This method is used to get the ownPlayerName + * + * @return the ownPlayerName + */ + public String getOwnPlayerName() { + return ownPlayerName; + } + + /** + * This method is used to set the ownPlayerName + * + * @param ownPlayerName the ownPlayerName to be set + */ + public void setOwnPlayerName(String ownPlayerName) { + this.ownPlayerName = ownPlayerName; + } + + /** + * This method is used to set the ownPlayerId + * + * @param ownPlayerId the ownPlayerId to be set + */ + public void setOwnPlayerId(int ownPlayerId) { + this.ownPlayerID = ownPlayerId; + } + + /** + * This method returns the game + * + * @return the game + */ public Game getGame(){ return game; } + /** + * This method returns the current State + * + * @return the current State + */ public ClientState getState(){ return state; } + /** + * This method returns if the client is a host + * + * @return if the client is a host + */ public boolean isHost(){ return isHost; } + /** + * This method returns the steps you can calculate steps + * + * @return the calculated moves as int + */ public int getCalculatedMoves(){ return game.getDiceEyes() * game.getDiceModifier(); } + /** + * This method sets if the player is a host + * + * @param isHost the boolean value + */ public void setHost(boolean isHost){ this.isHost = isHost; } + /** + * This method calls the method received of the state + * + * @param msg the ActivePlayer message received + */ @Override public void received(ActivePlayerMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the AnyPiece message received + */ @Override public void received(AnyPieceMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the Briefing message received + */ @Override public void received(BriefingMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the Ceremony message received + */ @Override public void received(CeremonyMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the Dice message received + */ @Override public void received(DieMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the DiceAgain message received + */ @Override public void received(DiceAgainMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the DiceNow message received + */ @Override public void received(DiceNowMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the EndOfGame message received + */ @Override public void received(EndOfTurnMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the GameOver message received + */ @Override public void received(LobbyAcceptMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the LobbyDeny message received + */ @Override public void received(LobbyDenyMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the LobbyPlayerJoin message received + */ @Override public void received(LobbyPlayerJoinedMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the LobbyPlayerLeave message received + */ @Override public void received(LobbyPlayerLeaveMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the MoveMessage message received + */ @Override public void received(MoveMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the NoTurn message received + */ @Override public void received(NoTurnMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the PauseGame message received + */ @Override public void received(PauseGameMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the PlayCard message received + */ @Override public void received(PlayCardMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the PossibleCard message received + */ @Override public void received(PossibleCardMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the PossiblePiece message received + */ @Override public void received(PossiblePieceMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the RankingResponse message received + */ @Override public void received(RankingResponseMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the RankingRollAgain message received + */ @Override public void received(RankingRollAgainMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the ReconnectBriefing message received + */ @Override public void received(ReconnectBriefingMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the ResumeGame message received + */ @Override public void received(ResumeGameMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the ServerStartGame message received + */ @Override public void received(ServerStartGameMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the SelectTSK message received. + */ @Override - public void received(ShutdownMessage msg) {state.received(msg);} + public void received(ShutdownMessage msg) { + addNotification(new InfoNotification(Resources.stringLookup("server.shutdown"))); + addNotification(new StartDialogNotification()); + setState(dialogsState); + } + /** + * Handles a IncorrectRequest message received from the server. + * + * @param msg the IncorrectRequest message received. + */ @Override - public void received(StartBriefingMessage msg) { - state.received(msg); - } - - @Override - public void received(PlayerDataMessage msg) { + public void received(IncorrectRequestMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the StartPiece message received + */ @Override public void received(StartPieceMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the UpdateReady message received + */ @Override public void received(UpdateReadyMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the UpdateTSK message received + */ @Override public void received(UpdateTSKMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the WaitPiece message received + */ @Override public void received(WaitPieceMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the Spectator message received. + */ @Override public void received(SpectatorMessage msg) { state.received(msg); } + /** + * This method calls the method received of the state + * + * @param msg the SelectPiece message received. + */ @Override public void received(SelectPieceMessage msg) { state.received(msg); } + /** + * This method calls the method selectPiece + * + * @param pieceId the pieceID + */ public void selectPiece(UUID pieceId){ state.selectPiece(getPiece(pieceId)); } + /** + * This method call the method selectNExt of the state + */ public void selectNext(){ state.selectNext(); } + /** + * This method calls the method selectCard of the state + * + * @param card the BonusCard to selected + */ public void selectCard(BonusCard card){ state.selectCard(card); } + /** + * This method call the method selectTsk of the state + * + * @param color the Color to be selected + */ public void selectTsk(Color color){ state.selectTSK(color); } + /** + * The method calls the method deselectTsk of the state + * + * @param color the color to be deselcted + */ public void deselectTSK(Color color){ state.deselectTSK(color); } + /** + * This method calls the selectDice method of the state + */ public void selectDice(){ state.selectDice(); } + /** + * This method calls the selectName method of the state + * + * @param name the name to be set + */ public void selectName(String name){ state.setName(name); } + /** + * This method calls a method of the state base on the parameter value + * + * @param ready the value if this method should ready or unready + */ public void selectReady(boolean ready){ if(ready){ state.selectReady(); @@ -269,62 +547,122 @@ public void selectReady(boolean ready){ } } + /** + * This method calls the selectHost method of the state + * + * @param name the name of the player hosting + */ public void selectHost(String name){ state.selectHost(name); } + /** + * This method calls the selectLeave method of the state + */ public void selectLeave(){ state.selectLeave(); } + /** + * This method calls the selectJoin method of the state + * + * @param ip the ip to cennect to + */ public void selectJoin(String ip){ state.selectJoin(ip); } + /** + * This method calls the selectAnimationEnd method of the state + */ public void selectAnimationEnd(){ state.selectAnimationEnd(); } + /** + * This method calls the selectStart method of the state + */ public void selectStart(){ state.selectStart(); } + /** + * This method calls the selectResume method of the state + */ public void selectResume(){ state.selectResume(); } + /** + * This method is used to transition between states + * + * @param state the new state + */ public void setState(ClientState state){ this.state.exit(); state.enter(); this.state = state; } + /** + * This method is used to enter the interrupt state and save the previous state + */ public void enterInterrupt(){ interruptState.enter(); interruptState.setPreviousState(state); this.state = interruptState; } + /** + * This method is used to get the GameState + * + * @return the GameState + */ public GameState getGameState(){ return gameState; } + /** + * This method is used to get the CeremonyState + * + * @return the CeremonyState + */ public CeremonyState getCeremony(){ return ceremonyState; } + /** + * This method is used to get the InterruptState + * + * @return the InterruptState + */ public InterruptState getInterrupt(){ return interruptState; } + /** + * This method is used to get the DialogsState + * + * @return the DialogsState + */ public DialogsState getDialogs(){ return dialogsState; } + /** + * This method is used to get the SettingsState + * + * @return the SettingsState + */ public SettingsState getSettings(){ return settingsState; } + /** + * This method is used to get the next notification + * + * @return the next notification + */ public Notification getNotification(){ if(!notifications.isEmpty()){ return notifications.remove(0); @@ -333,6 +671,11 @@ public Notification getNotification(){ } } + /** + * This method is used to add a notification + * + * @param notification the notification to be added + */ public void addNotification(Notification notification){ notifications.add(notification); } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java index ae500c42..998ea5a7 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/ClientState.java @@ -37,159 +37,155 @@ public String toString(){ @Override public void received(ActivePlayerMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(AnyPieceMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(BriefingMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(CeremonyMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(DieMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(DiceAgainMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(DiceNowMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(EndOfTurnMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(LobbyAcceptMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(LobbyDenyMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(LobbyPlayerJoinedMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(LobbyPlayerLeaveMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(MoveMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(NoTurnMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(PauseGameMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(PlayCardMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(PossibleCardMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(PossiblePieceMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(RankingResponseMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(RankingRollAgainMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(ReconnectBriefingMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(ResumeGameMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(ServerStartGameMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override - public void received(ShutdownMessage msg) {LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);} + public void received(ShutdownMessage msg) {LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString());} @Override public void received(StartPieceMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(UpdateReadyMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(UpdateTSKMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(SpectatorMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(SelectPieceMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override public void received(WaitPieceMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } @Override - public void received(StartBriefingMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); - } - - public void received(PlayerDataMessage msg) { - LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg); + public void received(IncorrectRequestMessage msg) { + LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg.toString()); } public void selectPiece(Piece piece) { @@ -252,6 +248,11 @@ public void selectResume(){ LOGGER.log(Level.DEBUG, "Resume not allowed"); } + /** + * This method is used to create a CeremonyNotification + * + * @return the created CeremonyNotification + */ protected CeremonyNotification createCeremonyNotification(){ CeremonyNotification notification = new CeremonyNotification(); for (var player : logic.getGame().getPlayers().entrySet()){ 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 c3f33c97..044be708 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 @@ -11,149 +11,231 @@ public class DialogsState extends ClientState { private DialogStates currentState; - private int ownPlayerID; - private String ownPlayerName; - private final LobbyState lobbyState = new LobbyState(this, logic); private final NetworkDialogState networkDialogState = new NetworkDialogState(this, logic); private final StartDialogState startDialogState = new StartDialogState(this, logic); - + /** + * Creates a new DialogsState + * + * @param parent the parent state + * @param logic the game logic + */ public DialogsState(ClientState parent, ClientGameLogic logic) { super(parent, logic); } + /** + * exits this state + */ @Override public void exit(){ currentState.exit(); } + /** + * Enters the new state machine + */ @Override public void enter(){ - currentState = startDialogState; - ownPlayerID = 0; - ownPlayerName = null; + setState(startDialogState); } + /** + * This method is used to set a new SubState + * + * @param newState the state to be set + */ public void setState(DialogStates newState){ - currentState.exit(); + if(currentState != null){ + currentState.exit(); + } newState.enter(); currentState = newState; } - public int getOwnPlayerId() { - return ownPlayerID; - } - - public String getOwnPlayerName() { - return ownPlayerName; - } - - public void setOwnPlayerName(String ownPlayerName) { - this.ownPlayerName = ownPlayerName; - } - - public void setOwnPlayerId(int ownPlayerId) { - this.ownPlayerID = ownPlayerId; - } - + /** + * This method is used to get the lobbyState + * + * @return the lobbyState + */ public LobbyState getLobby() { return lobbyState; } + /** + * This method is used to get the networkDialogState + * + * @return the networkDialogState + */ public NetworkDialogState getNetworkDialog() { return networkDialogState; } + /** + * This method is used to get the startDialogState + * + * @return the startDialogState + */ public StartDialogState getStartDialog() { return startDialogState; } - public void startGame(){ - exit(); - logic.setState(logic.getGameState()); - } - + /** + * This method is used to call the selectLeave method of the current state + */ @Override public void selectLeave(){ currentState.selectLeave(); } + /** + * This method is used to call the selectName method of the current state + * + * @param name the name to be set + */ @Override public void setName(String name){ currentState.setName(name); } + /** + * This method is used to call the selectTSK method of the current state + * + * @param color the color to be set + */ @Override public void selectTSK(Color color){ currentState.selectTSK(color); } + /** + * This method is used to call the deselectTSK method of the current state + * + * @param color the color to be deselected + */ @Override public void deselectTSK(Color color){ currentState.deselectTSK(color); } + /** + * This method is used to call the selectReady method of the current state + */ @Override public void selectReady(){ currentState.selectReady(); } + /** + * This method is used to call the selectUnready method of the current state + */ @Override public void selectUnready(){ currentState.selectUnready(); } + /** + * This method is used to call the selectStart method of the current state + */ @Override public void selectStart(){ currentState.selectStart(); } + /** + * This method is used to call the selectJoin method of the current state + * + * @param string the string to be set + */ @Override public void selectJoin(String string){ currentState.selectJoin(string); } + /** + * This method is used to call the selectHost method of the current state + * + * @param name the name to be set + */ @Override public void selectHost(String name){ currentState.selectHost(name); } + /** + * This method is used to call the received method of the current state + * + * @param msg the LobbyPlayerJoin message received + */ @Override public void received(LobbyPlayerJoinedMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the LobbyPlayerLeave message received + */ @Override public void received(LobbyPlayerLeaveMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the UpdateTSKMessage message received + */ @Override public void received(UpdateTSKMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the UpdateReady message received + */ @Override public void received(UpdateReadyMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the ServerStartGame message received + */ @Override public void received(ServerStartGameMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the LobbyAccept message received + */ @Override - public void received(PlayerDataMessage msg){ + public void received(LobbyAcceptMessage msg){ currentState.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the LobbyDeny message received + */ @Override - public void received(StartBriefingMessage msg){ + public void received(LobbyDenyMessage msg){ currentState.received(msg); } + /** + * This method is used to get the current state + */ public DialogStates getState() { return currentState; } 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 af449db8..34ad5d44 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 @@ -3,8 +3,10 @@ import pp.mdga.client.gameState.*; import pp.mdga.game.BonusCard; import pp.mdga.game.Piece; +import pp.mdga.message.client.LeaveGameMessage; import pp.mdga.message.server.*; import pp.mdga.notification.InterruptNotification; +import pp.mdga.notification.StartDialogNotification; public class GameState extends ClientState { @@ -27,7 +29,6 @@ public class GameState extends ClientState { */ public GameState(ClientState parent, ClientGameLogic logic) { super(parent, logic); - state = determineStartPlayerState; } /** @@ -35,7 +36,7 @@ public GameState(ClientState parent, ClientGameLogic logic) { */ @Override public void enter() { - + this.setState(this.determineStartPlayerState); } /** @@ -52,137 +53,278 @@ public void exit() { * @param newState the state to be set */ public void setState(GameStates newState){ - state.exit(); - state.enter(); + if(this.state != null){ + this.state.exit(); + } + newState.enter(); state = newState; } + /** + * This method is used to call the selectAnimationEnd method of the current state + */ @Override public void selectAnimationEnd(){ state.selectAnimationEnd(); } + /** + * This method is used to call the selectDice method of the current state + */ @Override public void selectDice(){ state.selectDice(); } + /** + * This method is used to call the selectPiece method of the current state + * + * @param piece the piece to be selected + */ @Override public void selectPiece(Piece piece){ state.selectPiece(piece); } + /** + * This method is used to call the selectCard method of the current state + * + * @param card the card to be selected + */ @Override public void selectCard(BonusCard card){ state.selectCard(card); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(PauseGameMessage msg){ logic.enterInterrupt(); logic.addNotification(new InterruptNotification(logic.getGame().getPlayers().get(msg.getPlayerId()).getColor())); } + @Override + public void selectLeave(){ + logic.send(new LeaveGameMessage()); + logic.addNotification(new StartDialogNotification()); + logic.setState(logic.getDialogs()); + } + + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(DieMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(RankingRollAgainMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(RankingResponseMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(SelectPieceMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(WaitPieceMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(StartPieceMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(NoTurnMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(MoveMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(CeremonyMessage msg){ - state.received(msg); + logic.addNotification(createCeremonyNotification()); + logic.setState(logic.getCeremony()); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(EndOfTurnMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(SpectatorMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(DiceAgainMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(PossibleCardMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(PlayCardMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(DiceNowMessage msg){ state.received(msg); } + /** + * This method is used to call the received method of the current state + * + * @param msg the message to be received + */ @Override public void received(ActivePlayerMessage msg){ state.received(msg); } + /** + * This method returns the current state + * + * @return the current state + */ public GameStates getState(){ return state; } + /** + * This method returns the AnimationState + * + * @return the AnimationState + */ public AnimationState getAnimation() { return animationState; } + /** + * This method returns the DetermineStartPlayerState + * + * @return the DetermineStartPlayerState + */ public DetermineStartPlayerState getDetermineStartPlayer() { return determineStartPlayerState; } + /** + * This method returns the SpectatorState + * + * @return the SpectatorState + */ public SpectatorState getSpectator() { return spectatorState; } + /** + * This method returns the TurnState + * + * @return the TurnState + */ public TurnState getTurn() { return turnState; } + /** + * This method returns the WaitingState + * + * @return the WaitingState + */ public WaitingState getWaiting() { return waitingState; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/SettingsState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/SettingsState.java index 5c399750..343d974b 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/SettingsState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/SettingsState.java @@ -49,14 +49,23 @@ public SettingStates getState(){ return currentState; } + /** + * Returns the main settings state + */ public MainSettingsState getMainSettingsState(){ return mainSettingsState; } + /** + * Returns the audio settings state + */ public AudioSettingsState getAudioSettingsState(){ return audioSettingsState; } + /** + * Returns the video settings state + */ public VideoSettingsState getVideoSettingsState(){ return videoSettingsState; } 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 6d70ba50..06b97e13 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 @@ -10,9 +10,7 @@ import pp.mdga.message.client.*; import pp.mdga.message.server.LobbyPlayerJoinedMessage; import pp.mdga.message.server.LobbyPlayerLeaveMessage; -import pp.mdga.message.server.PlayerDataMessage; import pp.mdga.message.server.ServerStartGameMessage; -import pp.mdga.message.server.StartBriefingMessage; import pp.mdga.message.server.UpdateReadyMessage; import pp.mdga.message.server.UpdateTSKMessage; import pp.mdga.notification.*; @@ -30,7 +28,7 @@ public LobbyState(ClientState parent, ClientGameLogic logic) { @Override public void enter() { - logic.send(new JoinedLobbyMessage(parent.getOwnPlayerName())); + logic.send(new JoinedLobbyMessage(logic.getOwnPlayerName())); } @Override @@ -66,55 +64,46 @@ public void selectUnready(){ @Override public void selectStart(){ - if(logic.isHost() && logic.getGame().allReady()){ + if(logic.isHost() && logic.getGame().areAllReady()){ logic.send(new StartGameMessage(false)); - } else if(logic.isHost() && !logic.getGame().allReady()) { + } else if(logic.isHost() && !logic.getGame().areAllReady()) { logic.send(new StartGameMessage(true)); } else { LOGGER.log(System.Logger.Level.ERROR, "You are not the host"); } } - @Override - public void received(StartBriefingMessage msg){ - logic.getGame().setBoard(msg.getBoard()); - } - - public void received(PlayerDataMessage msg){ - logic.getGame().getBoard().addPlayerData(msg.getColor(), msg.getPlayerData()); - } - @Override public void received(ServerStartGameMessage msg){ - logic.addNotification(new GameNotification(logic.getGame().getPlayerById(parent.getOwnPlayerId()).getColor())); - for (Map.Entry entry : logic.getGame().getBoard().getPlayerData().entrySet()) { - List pieceList = new ArrayList<>(); - for(Piece piece : entry.getValue().getPieces()){ - System.out.println(piece.getUuid()); - pieceList.add(piece.getUuid()); + logic.getGame().setBoard(msg.getBoard()); + logic.addNotification(new GameNotification(logic.getGame().getPlayerById(logic.getOwnPlayerId()).getColor())); + for (Map.Entry entry : logic.getGame().getPlayers().entrySet()) { + List pieces = new ArrayList<>(); + for (Piece piece : logic.getGame().getBoard().getPlayerData().get(entry.getValue().getColor()).getPieces()) { + pieces.add(piece.getUuid()); } - logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceList , logic.getGame().getPlayerByColor(entry.getKey()).getName())); + logic.addNotification(new PlayerInGameNotification(entry.getValue().getColor(), pieces, entry.getValue().getName())); } - parent.startGame(); + logic.setState(logic.getGameState()); } @Override public void received(LobbyPlayerJoinedMessage msg){ - if(msg.getPlayer().getName().equals(parent.getOwnPlayerName())){ - parent.setOwnPlayerId(msg.getId()); + if(msg.getPlayer().getName().equals(logic.getOwnPlayerName())){ + logic.setOwnPlayerId(msg.getId()); } - if (msg.isHost() && msg.getId() == parent.getOwnPlayerId()){ + if (msg.isHost() && msg.getId() == logic.getOwnPlayerId()){ logic.setHost(true); } - logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(parent.getOwnPlayerName()))); + logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(logic.getOwnPlayerName()))); logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer()); } @Override public void received(UpdateTSKMessage msg){ if(msg.isTaken()) { - logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId())); + logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), logic.getOwnPlayerId()== msg.getId())); } else { logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor())); } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java index 98234319..a6a206d6 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/NetworkDialogState.java @@ -1,34 +1,72 @@ package pp.mdga.client.dialogState; +import pp.mdga.Resources; import pp.mdga.client.ClientGameLogic; import pp.mdga.client.ClientState; import pp.mdga.client.DialogsState; +import pp.mdga.message.server.LobbyAcceptMessage; +import pp.mdga.message.server.LobbyDenyMessage; +import pp.mdga.notification.InfoNotification; import pp.mdga.notification.LobbyDialogNotification; public class NetworkDialogState extends DialogStates { private final DialogsState parent; + /** + * Constructor for the NetworkDialogState + * @param parent the parent state + * @param logic the logic + */ public NetworkDialogState(ClientState parent, ClientGameLogic logic) { super(parent, logic); this.parent = (DialogsState) parent; } + /** + * Enter the state + */ @Override public void enter() { + LOGGER.log(System.Logger.Level.INFO, "Entered {0}", this); } + /** + * Exit the state + */ @Override public void exit() { } + /** + * Select the leave option + */ @Override public void selectLeave() { parent.setState(parent.getStartDialog()); } - public void selectJoin(String IP) { + /** + * This method is called when the server accepts the client into the lobby + * + * @param msg the LobbyAcceptMessage + */ + @Override + public void received(LobbyAcceptMessage msg) { + logic.getGame().setHost(msg.getHost()); + logic.setHost(logic.getGame().isHost()); parent.setState(parent.getLobby()); logic.addNotification(new LobbyDialogNotification()); } + + /** + * This method is called when the server denies the client into the lobby + * + * @param msg the LobbyDenyMessage + */ + @Override + public void received(LobbyDenyMessage msg) { + logic.addNotification(new InfoNotification(Resources.stringLookup("lobby.deny.join"))); + parent.setState(parent.getStartDialog()); + } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/StartDialogState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/StartDialogState.java index 47b9944a..6c49408b 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/StartDialogState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/dialogState/StartDialogState.java @@ -8,41 +8,44 @@ public class StartDialogState extends DialogStates { private final DialogsState parent; + /** + * Constructor for the StartDialogState + * @param parent the parent state + * @param logic the logic + */ public StartDialogState(ClientState parent, ClientGameLogic logic) { super(parent, logic); this.parent = (DialogsState) parent; } + /** + * Enter the state + */ @Override public void enter() { - } + /** + * Exit the state + */ @Override public void exit() { - - } - - @Override - public void selectJoin(String name) { - parent.setOwnPlayerName(name); - parent.setState(parent.getNetworkDialog()); - logic.setHost(false); - } - - @Override - public void selectHost(String name) { - parent.setOwnPlayerName(name); - parent.setState(parent.getLobby()); - logic.setHost(true); } + /** + * Set the name + * + * @param name the name + */ @Override public void setName(String name) { + logic.setOwnPlayerName(name); parent.setState(parent.getNetworkDialog()); - parent.setOwnPlayerName(name); } + /** + * Select the leave option + */ @Override public void selectLeave() { parent.exit(); diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java index cf3c48c2..4794785a 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/DetermineStartPlayerState.java @@ -25,7 +25,7 @@ public DetermineStartPlayerState(ClientState parent, ClientGameLogic logic) { @Override public void enter() { - state = rollRankingDiceState; + this.setState(this.rollRankingDiceState); } @Override @@ -34,7 +34,9 @@ public void exit() { } public void setState(DetermineStartPlayerStates state) { - this.state.exit(); + if(this.state != null){ + this.state.exit(); + } state.enter(); this.state = state; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java index b7b80ddc..5bb880d7 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/GameStates.java @@ -36,8 +36,7 @@ protected void handlePowerCard(PlayCardMessage msg){ logic.getGame().getBoard().getInfield()[logic.getGame().getBoard().getInfieldIndexOfPiece(enemyPiece)].setOccupant(ownPiece); logic.getGame().getBoard().getInfield()[ownIndex].setOccupant(enemyPiece); } - logic.getGame().getPlayerByColor(logic.getGame().getActiveColor()).removeHandCard(msg.getCard()); - logic.getGame().getDiscardPile().add(msg.getCard()); + logic.getGame().getDiscardPile().add(logic.getGame().getPlayerByColor(logic.getGame().getActiveColor()).removeHandCard(msg.getCard())); } protected void throwPiece(Piece piece){ diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java index b59a35b8..5f075eff 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/TurnState.java @@ -31,7 +31,7 @@ public TurnState(ClientState parent, ClientGameLogic logic) { @Override public void enter() { - state = powerCardState; + this.setState(this.powerCardState); } @Override @@ -40,7 +40,9 @@ public void exit() { } public void setState(TurnStates state){ - this.state.exit(); + if(this.state != null){ + this.state.exit(); + } state.enter(); this.state = state; } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java index 3c1ec5b9..59cba3ec 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/determineStartPlayerState/RollRankingDiceState.java @@ -6,6 +6,7 @@ import pp.mdga.message.client.RequestDieMessage; import pp.mdga.message.server.DieMessage; import pp.mdga.notification.DiceNowNotification; +import pp.mdga.notification.RollDiceNotification; public class RollRankingDiceState extends DetermineStartPlayerStates { @@ -23,16 +24,17 @@ public void enter() { @Override public void exit() { - } @Override public void selectDice(){ + System.out.println("selectDice"); logic.send(new RequestDieMessage()); } @Override public void received(DieMessage msg){ + logic.addNotification(new RollDiceNotification(logic.getGame().getPlayerById(logic.getOwnPlayerId()).getColor(), msg.getDiceEye(),true)); parent.setState(parent.getWaitRanking()); } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java index b1a0c7e3..47dce439 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/ChoosePieceState.java @@ -24,7 +24,7 @@ public ChoosePieceState(ClientState parent, ClientGameLogic logic) { @Override public void enter() { - currentState = noPieceState; + this.setState(this.noPieceState); } @Override @@ -34,9 +34,11 @@ public void exit() { } public void setState(ChoosePieceStates state){ - currentState.exit(); + if(currentState != null){ + currentState.exit(); + } + state.enter(); currentState = state; - currentState.enter(); } @Override diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java index fd80b68d..5a5fd5c3 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/client/gameState/turnState/PowerCardState.java @@ -31,7 +31,7 @@ public PowerCardState(ClientState parent, ClientGameLogic logic) { @Override public void enter() { - state = choosePowerCardState; + this.setState(this.choosePowerCardState); } public void exit() { @@ -40,7 +40,9 @@ public void exit() { } public void setState(PowerCardStates state) { - this.state.exit(); + if(this.state != null){ + this.state.exit(); + } state.enter(); this.state = state; } 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 b24382fe..b46ef62f 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 @@ -29,7 +29,7 @@ public Board() { } else if (i == 4 || i == 14 || i == 24 || i == 34) { infield[i] = new BonusNode(); } else { - infield[i] = new Node(); + infield[i] = new Node(null); } } } 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 c12f7cab..8ece5b1e 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 @@ -8,6 +8,6 @@ @Serializable public class BonusNode extends Node { BonusNode(){ - super(); + super(null); } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Color.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Color.java index 828450f4..76d4e17b 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Color.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Color.java @@ -1,9 +1,12 @@ package pp.mdga.game; +import com.jme3.network.serializing.Serializable; + /** * This enumeration will be used to show the four different TSK which can be picked from a player. * In Addition, the NONE color will be used to show a none color. */ +@Serializable public enum Color { /** * Represents the air force color. diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Die.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Die.java index 08a378e2..fc013d75 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Die.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Die.java @@ -1,7 +1,11 @@ package pp.mdga.game; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; import java.util.random.RandomGenerator; import java.util.random.RandomGeneratorFactory; +import java.util.stream.IntStream; /** * This class represents a simple die with the possibilities to shuffle and return the roll result. @@ -43,6 +47,14 @@ public class Die { */ private int lastNumberOfDice; + /** + * Predefined rolls for testing. + */ + private Iterator rolls; + + /** + * If the results of the die should be locked. + */ private final boolean lock; /** @@ -65,7 +77,7 @@ public Die(long seed) { /** * Constructor. - * + * * @param roll as the roll which should be returned everytime the shuffle method will be called as an Integer. */ public Die(int roll) { @@ -74,6 +86,17 @@ public Die(int roll) { this.lock = true; } + /** + * Constructor. + * + * @param rolls as a variable list of rolls which will be used by test cases as an Array of Integers. + */ + public Die(int... rolls) { + this.random = RandomGeneratorFactory.of("Random").create(); + this.rolls = IntStream.of(rolls).iterator(); + this.lock = false; + } + /** * This method will be used to return a random number generated by the random attribute of Die class. * @@ -84,6 +107,11 @@ public int shuffle() { return this.lastNumberOfDice; } + if (this.rolls != null && this.rolls.hasNext()) { + this.lastNumberOfDice = this.rolls.next(); + return this.lastNumberOfDice; + } + this.lastNumberOfDice = this.random.nextInt(MAXIMUM_EYES) + 1; return this.lastNumberOfDice; 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 666f1b8b..9f0cee8f 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 @@ -43,14 +43,11 @@ public class Game { private Die die; // The host of this game - private int host; + private int host = -1; // The color of the active player. private Color activeColor; - // A flag indicating whether all players are ready. - private boolean allReady = false; - /** * This constructor creates a new Game object. */ @@ -65,6 +62,7 @@ public Game() { drawPile.add(BonusCard.SHIELD); } board = new Board(); + die = new Die(); } /** @@ -96,6 +94,38 @@ public void updatePlayerActiveState(int id, boolean active) { this.players.get(id).setActive(active); } + /** + * This method will be used to check if the given color parameter is already taken. + * If yes it will return true, otherwise false. + * + * @param color as the color which should be checked if taken as a Color enumeration. + * @return true or false. + */ + public boolean isColorTaken(Color color) { + for (Map.Entry entry : this.players.entrySet()) { + if (entry.getValue().getColor() == color) { + return true; + } + } + + return false; + } + + /** + * This method will be used to return the first unused color if possible. + * + * @return color as a Color enumeration. + */ + public Color getFirstUnusedColor() { + for (Color color : Color.values()) { + if (!isColorTaken(color)) { + return color; + } + } + + return null; + } + /** * This method will be used to return the player which has the given id parameter. * @@ -122,6 +152,32 @@ public Player getPlayerByColor(Color color) { return null; } + /** + * This method will be used to return the id of the active player depending on the activeColor attribute of Game + * class. + * + * @return the id of the active player as an Integer. + */ + public int getActivePlayerId() { + return this.getPlayerIdByColor(this.activeColor); + } + + /** + * This method will be used to return the id of the Player defined by the given color parameter. + * + * @param color as the color of the player as a Color enumeration. + * @return the id of the player as an Integer. + */ + public int getPlayerIdByColor(Color color) { + for (Map.Entry entry : this.players.entrySet()) { + if (entry.getValue().getColor() == color) { + return entry.getKey(); + } + } + + return -1; + } + /** * This method will be used to return the number of active players of this game. * @@ -138,6 +194,22 @@ public int getNumberOfActivePlayers() { return activePlayers; } + /** + * This method will be used to check if all players are ready. + * If yes it will return true, otherwise false. + * + * @return true or false. + */ + public boolean areAllReady() { + for (Map.Entry entry : this.players.entrySet()) { + if (!entry.getValue().isReady()) { + return false; + } + } + + return true; + } + /** * This method will be used to return a piece based on the UUID. * @@ -154,6 +226,15 @@ public Piece getPieceThroughUUID(UUID pieceId) { return null; } + /** + * This method will be used to check if this client is the host for the game. + * + * @return true or false. + */ + public boolean isHost() { + return this.host != -1; + } + /** * This method returns the dice modifier. * @@ -333,22 +414,4 @@ public void setDie(Die die) { public void setHost(int host) { this.host = host; } - - /** - * This method returns the all ready state. - * - * @return the already state - */ - public Boolean allReady() { - return allReady; - } - - /** - * This method sets the all ready state. - * - * @param allReady the new all-ready state - */ - public void setAllReady(Boolean allReady) { - this.allReady = allReady; - } } 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 814abaa5..cb373011 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 @@ -8,6 +8,6 @@ @Serializable public class HomeNode extends Node { public HomeNode() { - super(); + super(null); } } 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 de6530ca..921ea970 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 @@ -9,8 +9,12 @@ public class Node { protected Piece occupant; - public Node(){ + public Node(Piece piece){ + occupant = piece; + } + private Node(){ + occupant = new Piece(Color.AIRFORCE, PieceState.WAITING); } /** @@ -49,4 +53,14 @@ public void clearOccupant() { public boolean isOccupied() { return occupant != null; } + + /** + * This method will be used to check if the node is occupied by a piece of the given color. + * + * @param color as the color of the piece as a Color object. + * @return true or false. + */ + public boolean isOccupied(Color color) { + return this.occupant != null && this.occupant.getColor() == color; + } } 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 dfe36188..8ddb376c 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 @@ -12,17 +12,17 @@ public class Piece { /** * The shield state of the piece. */ - private int shield; + private ShieldState shield; /** * The current state of the piece. */ - private int state; + private PieceState state; /** * The color of the piece. */ - private final int color; + private final Color color; /** * The unique identifier of the piece. @@ -35,16 +35,19 @@ public class Piece { * @param color the color of the piece * @param state the state of the piece */ - public Piece(Color color, PieceState state, int id) { - this.color = color.ordinal(); - this.state = state.ordinal(); - shield = ShieldState.NONE.ordinal(); + public Piece(Color color, PieceState state) { + this.color = color; + this.state = state; + shield = ShieldState.NONE; } + /** + * Constructor. + */ private Piece() { - color = Color.NONE.ordinal(); - state = PieceState.WAITING.ordinal(); - shield = ShieldState.NONE.ordinal(); + color = Color.NONE; + state = PieceState.WAITING; + shield = ShieldState.NONE; } /** @@ -53,7 +56,7 @@ private Piece() { * @return the color of the piece */ public void setShield(ShieldState shield) { - this.shield = shield.ordinal(); + this.shield = shield; } /** @@ -62,7 +65,7 @@ public void setShield(ShieldState shield) { * @return the color of the piece */ public ShieldState getShield() { - return ShieldState.values()[shield]; + return shield; } /** @@ -71,7 +74,7 @@ public ShieldState getShield() { * @param state the state of the piece */ public void setState(PieceState state) { - this.state = state.ordinal(); + this.state = state; } /** @@ -80,7 +83,7 @@ public void setState(PieceState state) { * @return the color of the piece */ public PieceState getState() { - return PieceState.values()[state]; + return state; } /** @@ -89,7 +92,7 @@ public PieceState getState() { * @return the color of the piece */ public boolean isShielded() { - return shield == ShieldState.ACTIVE.ordinal(); + return shield == ShieldState.ACTIVE; } /** @@ -98,7 +101,7 @@ public boolean isShielded() { * @return the color of the piece */ public boolean isSuppressed() { - return shield == ShieldState.SUPPRESSED.ordinal(); + return shield == ShieldState.SUPPRESSED; } /** @@ -107,7 +110,7 @@ public boolean isSuppressed() { * @return the color of the piece */ public Color getColor() { - return Color.values()[color]; + return color; } /** diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java index 780d8df0..3c66f677 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/PieceState.java @@ -5,6 +5,7 @@ /** * Represents the state of a piece. */ +@Serializable public enum PieceState { /** * The piece is active. @@ -22,20 +23,4 @@ public enum PieceState { * The piece is finished. */ HOMEFINISHED; - - PieceState(){ - - } - - public static PieceState getPieceStateByIndex(int index){ - if (index < 0 || index >= values().length) { - throw new IllegalArgumentException(""); - } - return values()[index]; - } - - - public PieceState next() { - return values()[(ordinal() + 1) % values().length]; - } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/Player.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/Player.java index 0dd875f0..baa88d6f 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/Player.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/Player.java @@ -1,6 +1,7 @@ package pp.mdga.game; import com.jme3.network.serializing.Serializable; +import pp.mdga.Resources; import java.util.ArrayList; @@ -17,12 +18,12 @@ public class Player { /** * The statistics of the player. */ - private Statistic playerStatistic; + private Statistic playerStatistic = new Statistic(); /** * The hand cards of the player. */ - private ArrayList handCards; + private ArrayList handCards = new ArrayList<>(); /** * The color of the player. @@ -32,13 +33,21 @@ public class Player { /** * Indicates if the player is ready. */ - private boolean isReady; + private boolean ready = false; /** * Indicates if the player is active. */ private boolean active = true; + /** + * Node and piece attributes + */ + private int startNodeIndex = -1; + private HomeNode[] homeNodes = new HomeNode[Resources.MAX_PIECES]; + private Piece[] waitingArea = new Piece[Resources.MAX_PIECES]; + private Piece[] pieces = new Piece[Resources.MAX_PIECES]; + /** * This constructor constructs a new Player object * @@ -46,8 +55,6 @@ public class Player { */ public Player(String name) { this.name = name; - playerStatistic = new Statistic(); - handCards = new ArrayList<>(); } /** @@ -58,39 +65,14 @@ public Player() { } /** - * This method returns the give name of the Player - * - * @return the name of the player as a String + * This method will be used to initialize all nodes and pieces of the Player class. */ - public String getName() { - return name; - } - - /** - * This method sets the name of the player - * - * @param name the new name of the player - */ - public void setName(String name) { - this.name = name; - } - - /** - * This methode returns the statistics of the player - * - * @return the statistics of the player - */ - public Statistic getPlayerStatistic() { - return playerStatistic; - } - - /** - * This method returns the current handCards of the player - * - * @return the handCards of the player - */ - public ArrayList getHandCards() { - return handCards; + public void initialize() { + for (int index = 0; index < Resources.MAX_PIECES; index++) { + this.homeNodes[index] = new HomeNode(); + this.pieces[index] = new Piece(this.color, PieceState.WAITING); + this.waitingArea[index] = this.pieces[index]; + } } /** @@ -116,6 +98,58 @@ public BonusCard removeHandCard(BonusCard card) { return cardToRemove; } + /** + * This method will be used to add the given piece parameter to the first free slot inside the waitingArea attribute + * of Player class. + * + * @param piece as the piece which should be added to the waitingArea attribute of Player class as a Piece object. + */ + public void addWaitingPiece(Piece piece) { + for (int i = 0; i < Resources.MAX_PIECES; i++) { + if (this.waitingArea[i] == null) { + this.waitingArea[i] = piece; + return; + } + } + } + + /** + * This method will be used to check if the player is finished. + * ToDo: Currently return always false. Implement logic! + * + * @return true or false. + */ + public boolean isFinished() { + return false; + } + + /** + * This method returns the give name of the Player + * + * @return the name of the player as a String + */ + public String getName() { + return name; + } + + /** + * This methode returns the statistics of the player + * + * @return the statistics of the player + */ + public Statistic getPlayerStatistic() { + return playerStatistic; + } + + /** + * This method returns the current handCards of the player + * + * @return the handCards of the player + */ + public ArrayList getHandCards() { + return handCards; + } + /** * This method returns the color of the player * @@ -125,22 +159,13 @@ public Color getColor() { return color; } - /** - * This method sets the color of the player - * - * @param color the new color of the player - */ - public void setColor(Color color) { - this.color = color; - } - /** * This method returns if the player is ready * * @return true if the player is ready, false otherwise */ public boolean isReady() { - return isReady; + return ready; } /** @@ -152,13 +177,67 @@ public boolean isActive() { return this.active; } + /** + * This method will be used to return startNodeIndex of Player class. + * + * @return startNodeIndex as an Integer. + */ + public int getStartNodeIndex() { + return this.startNodeIndex; + } + + /** + * This method will be used to return homeNodes attribute of Player class. + * + * @return homeNodes as an Array of Node objects. + */ + public Node[] getHomeNodes() { + return this.homeNodes; + } + + /** + * This method will be used to return waitingArea attribute of Player class. + * + * @return waitingArea as an Array of Piece objects. + */ + public Piece[] getWaitingArea() { + return this.waitingArea; + } + + /** + * This method will be used to return pieces attribute of Player class. + * + * @return pieces as an Array of Piece objects. + */ + public Piece[] getPieces() { + return this.pieces; + } + + /** + * This method sets the name of the player + * + * @param name the new name of the player + */ + public void setName(String name) { + this.name = name; + } + + /** + * This method sets the color of the player + * + * @param color the new color of the player + */ + public void setColor(Color color) { + this.color = color; + } + /** * This method sets the player to ready * * @param ready true if the player is ready, false otherwise */ public void setReady(boolean ready) { - isReady = ready; + this.ready = ready; } /** 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 8fcc85ae..809b9d66 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,6 +1,7 @@ package pp.mdga.game; import com.jme3.network.serializing.Serializable; +import pp.mdga.Resources; /** * This class is used to represent PlayerData related to the board @@ -33,20 +34,33 @@ public class PlayerData { * @param color the color of the player */ public PlayerData(Color color) { - homeNodes = new HomeNode[4]; - pieces = new Piece[4]; - waitingArea = new Piece[4]; - for (int i = 0; i < 4; i++) { + homeNodes = new HomeNode[Resources.MAX_PIECES]; + pieces = new Piece[Resources.MAX_PIECES]; + waitingArea = new Piece[Resources.MAX_PIECES]; + for (int i = 0; i < Resources.MAX_PIECES; i++) { homeNodes[i] = new HomeNode(); - pieces[i] = new Piece(color, PieceState.WAITING, i); + pieces[i] = new Piece(color, PieceState.WAITING); waitingArea[i] = pieces[i]; } } + /** + * Constructor. + */ private PlayerData() { - homeNodes = null; - waitingArea = null; - pieces = null; + homeNodes = new HomeNode[Resources.MAX_PIECES]; + waitingArea = new Piece[Resources.MAX_PIECES]; + pieces = new Piece[Resources.MAX_PIECES]; + } + + /** + * This method will be used to check if the player is finished. + * ToDo: Currently return always false. Implement logic! + * + * @return true or false. + */ + public boolean isFinished() { + return false; } /** @@ -100,7 +114,7 @@ public Piece[] getPieces() { * @param piece the piece to be added to the waiting area */ public void addWaitingPiece(Piece piece) { - for (int i = 0; i < 4; i++) { + for (int i = 0; i < Resources.MAX_PIECES; i++) { if (waitingArea[i] == null) { waitingArea[i] = piece; return; @@ -114,7 +128,7 @@ public void addWaitingPiece(Piece piece) { * @return the piece that was removed from the waiting area */ public Piece removePieceFromWaitingArea() { - for (int i = 0; i < 4; i++) { + for (int i = 0; i < Resources.MAX_PIECES; i++) { if (waitingArea[i] != null) { Piece piece = waitingArea[i]; waitingArea[i] = null; @@ -135,26 +149,30 @@ public void setPieceInHome(int index, Piece piece) { } /** - * This method returns the homeNodes + * This method will be used to return if the given piece parameter is inside the homNodes attribute of PlayerData + * class. + * If yes it will return true, otherwise false. * - * @return the homeNodes + * @return true or false. */ public boolean homeIncludes(Piece piece) { - for (int i = 0; i < 4; i++) { - if (homeNodes[i].getOccupant() == piece) { + for (Node node : this.homeNodes) { + if (node.getOccupant() == piece) { return true; } } + return false; } /** - * This method returns the homeNodes + * This method will be used to return the index of the given piece parameter in the homeNodes attribute of + * PlayerData class. * - * @return the homeNodes + * @return index as an Integer. */ public int getIndexInHome(Piece piece) { - for (int i = 0; i < 4; i++) { + for (int i = 0; i < Resources.MAX_PIECES; i++) { if (homeNodes[i].getOccupant() == piece) { return i; } @@ -163,9 +181,10 @@ public int getIndexInHome(Piece piece) { } /** - * This method returns the homeNodes + * This method will be usd to check if the waitingArea attribute of PlayerData class is empty. + * If yes it will return false, otherwise true. * - * @return the homeNodes + * @return true or false. */ public boolean hasPieceInWaitingArea() { for (Piece piece : waitingArea) { diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java index 19a09a5d..78eee486 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/game/ShieldState.java @@ -1,11 +1,8 @@ package pp.mdga.game; -import com.jme3.network.serializing.Serializable; - /** * Represents the state of a piece's shield. */ -@Serializable public enum ShieldState { /** * The shield is not active. @@ -19,19 +16,4 @@ public enum ShieldState { * The shield is suppressed, when the piece is on a start node. */ SUPPRESSED; - - ShieldState(){ - - } - - public static ShieldState getShieldStateByIndex(int index){ - if (index < 0 || index >= values().length) { - throw new IllegalArgumentException(""); - } - return values()[index]; - } - - public ShieldState next() { - return values()[(ordinal() + 1) % values().length]; - } } 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 23161ecf..c8c79264 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 @@ -10,7 +10,7 @@ public class StartNode extends Node { /** * The color of the node. */ - private int color; + private Color color; /** * Creates a new start node with the given color. @@ -18,11 +18,13 @@ public class StartNode extends Node { * @param color the color of the node */ public StartNode(Color color) { - this.color = color.ordinal(); + super(null); + this.color = color; } private StartNode() { - color = Color.NONE.ordinal(); + super(null); + color = Color.NONE; } /** @@ -31,7 +33,7 @@ private StartNode() { * @return the color of the node */ public Color getColor() { - return Color.values()[color]; + return color; } /** @@ -40,6 +42,6 @@ public Color getColor() { * @param color the new color of the node */ public void setColor(Color color) { - this.color = color.ordinal(); + this.color = color; } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/IncorrectRequestMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/IncorrectRequestMessage.java new file mode 100644 index 00000000..df51705b --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/IncorrectRequestMessage.java @@ -0,0 +1,58 @@ +package pp.mdga.message.server; + +import com.jme3.network.serializing.Serializable; + +@Serializable +public class IncorrectRequestMessage extends ServerMessage { + /** + * Create IncorrectRequestMessage attributes. + */ + private final int id; + + /** + * Constructor. + * + * @param id as the id of the error message as an Integer. + */ + public IncorrectRequestMessage(int id) { + this.id = id; + } + + /** + * Constructor. + */ + public IncorrectRequestMessage() { + this.id = 0; + } + + /** + * Accepts a visitor to process this message. + * + * @param interpreter the visitor to process this message + */ + @Override + public void accept(ServerInterpreter interpreter) { + interpreter.received(this); + } + + /** + * Gets the bundle key of the informational text to be shown at the client. + * This key is used to retrieve the appropriate localized text for display. + * + * @return the bundle key of the informational text + */ + @Override + public String getInfoTextKey() { + return ""; + } + + /** + * This method will be used to return necessary class information in a more readable format. + * + * @return information as a String. + */ + @Override + public String toString() { + return "IncorrectRequestMessage with id: %d".formatted(this.id); + } +} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyAcceptMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyAcceptMessage.java index f3e16386..fbaf7c56 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyAcceptMessage.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyAcceptMessage.java @@ -7,13 +7,39 @@ */ @Serializable public class LobbyAcceptMessage extends ServerMessage { + /** + * Create LobbyAcceptMessage attributes. + */ + private final int host; + /** * Constructs a new LobbyAccept instance. */ public LobbyAcceptMessage() { super(); + this.host = -1; } + /** + * Constructor. + * + * @param host as the id of the host as an Integer. + */ + public LobbyAcceptMessage(int host) { + super(); + this.host = host; + } + + /** + * This method will be used return host attribute of LobbyAcceptMessage class. + * + * @return host as an Integer. + */ + public int getHost() { + return this.host; + } + + /** * Accepts a visitor to process this message. * @@ -31,7 +57,7 @@ public void accept(ServerInterpreter interpreter) { */ @Override public String toString() { - return ""; + return "Lobby Accept"; } /** diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyDenyMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyDenyMessage.java index e49057b7..ea5299ee 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyDenyMessage.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/LobbyDenyMessage.java @@ -31,7 +31,7 @@ public void accept(ServerInterpreter interpreter) { */ @Override public String toString() { - return ""; + return "LobbyDeny"; } /** diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java deleted file mode 100644 index 03171e73..00000000 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/PlayerDataMessage.java +++ /dev/null @@ -1,40 +0,0 @@ -package pp.mdga.message.server; - -import com.jme3.network.serializing.Serializable; -import pp.mdga.game.Color; -import pp.mdga.game.PlayerData; - -@Serializable -public class PlayerDataMessage extends ServerMessage{ - - private final PlayerData playerData; - private final Color color; - - public PlayerDataMessage(PlayerData playerData, Color color){ - super(); - this.playerData = playerData; - this.color = color; - } - - private PlayerDataMessage(){ - this(null, null); - } - - @Override - public void accept(ServerInterpreter interpreter) { - interpreter.received(this); - } - - @Override - public String getInfoTextKey() { - return ""; - } - - public PlayerData getPlayerData(){ - return playerData; - } - - public Color getColor(){ - return color; - } -} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java index 4491f9c1..edb54c9a 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/ServerInterpreter.java @@ -211,11 +211,14 @@ public interface ServerInterpreter { /** * Handles a SelectTSK message received from the server. * - * @param shutdownMessage the SelectTSK message received. + * @param msg the SelectTSK message received. */ - void received(ShutdownMessage shutdownMessage); + void received(ShutdownMessage msg); - void received(StartBriefingMessage msg); - - void received(PlayerDataMessage msg); + /** + * Handles a IncorrectRequest message received from the server. + * + * @param msg the IncorrectRequest message received. + */ + void received(IncorrectRequestMessage msg); } 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 69e3fb96..fa11b561 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 @@ -8,13 +8,38 @@ */ @Serializable public class ServerStartGameMessage extends ServerMessage { + /** + * Create ServerStartGameMessage attributes. + */ + private final Board board; /** * Constructs a new ServerStartGame instance. */ public ServerStartGameMessage() { super(); + this.board = new Board(); } + + /** + * Constructor. + * + * @param board as the board of the game as a Board object. + */ + public ServerStartGameMessage(Board board) { + super(); + this.board = board; + } + + /** + * This method will return board attribute of ServerStartGameMessage class. + * + * @return board as a Board object. + */ + public Board getBoard() { + return this.board; + } + /** * Accepts a visitor to process this message. * diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java b/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java deleted file mode 100644 index ba465990..00000000 --- a/Projekte/mdga/model/src/main/java/pp/mdga/message/server/StartBriefingMessage.java +++ /dev/null @@ -1,33 +0,0 @@ -package pp.mdga.message.server; - -import com.jme3.network.serializing.Serializable; -import pp.mdga.game.Board; - -@Serializable -public class StartBriefingMessage extends ServerMessage { - - private final Board board; - - public StartBriefingMessage(Board board) { - super(); - this.board = board; - } - - private StartBriefingMessage() { - this(null); - } - - public Board getBoard() { - return this.board; - } - - @Override - public void accept(ServerInterpreter interpreter) { - interpreter.received(this); - } - - @Override - public String getInfoTextKey() { - return ""; - } -} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/InfoNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/InfoNotification.java new file mode 100644 index 00000000..4ccb87d6 --- /dev/null +++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/InfoNotification.java @@ -0,0 +1,33 @@ +package pp.mdga.notification; + +import pp.mdga.game.BonusCard; +/** + * Notification that is to give information to the player. + */ +public class InfoNotification extends Notification{ + + private final String message; + + private boolean isError = false; + + /** + * Constructor. + */ + public InfoNotification(String info) { + this.message = info; + } + + /** + * Constructor. + */ + public InfoNotification(String info, boolean isError) { + this.message = info; + this.isError = isError; + } + + public String getMessage() { + return message; + } + + public boolean isError() { return isError; } +} diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java index 13bf849b..2e6f03e1 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/notification/RollDiceNotification.java @@ -11,6 +11,7 @@ public class RollDiceNotification extends Notification{ private int eyes; private boolean turbo; private int multiplier; + private boolean isRanking; /** * Constructor. @@ -22,6 +23,15 @@ public RollDiceNotification(Color color, int eyes) { this.eyes = eyes; this.turbo = false; this.multiplier = -1; + this.isRanking = false; + } + + public RollDiceNotification(Color color, int eyes, boolean isRanking) { + this.color = color; + this.eyes = eyes; + this.turbo = false; + this.multiplier = -1; + this.isRanking = isRanking; } public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier) { @@ -29,6 +39,7 @@ public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier this.eyes = eyes; this.turbo = turbo; this.multiplier = multiplier; + this.isRanking = false; } /** @@ -54,4 +65,6 @@ public int getMultiplier() { public boolean isTurbo() { return turbo; } + + public boolean isRanking() { return isRanking; } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/ServerSender.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/ServerSender.java index ac0b183d..055d1019 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/ServerSender.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/ServerSender.java @@ -28,4 +28,9 @@ public interface ServerSender { * @param id as the connection id of the client as an Integer. */ void disconnectClient(int id); + + /** + * This method will be used to shut down the server. + */ + void shutdown(); } 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 d9ac8431..c6368f05 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 @@ -4,6 +4,7 @@ import pp.mdga.message.client.DisconnectedMessage; import pp.mdga.message.client.LeaveGameMessage; import pp.mdga.message.client.RequestDieMessage; +import pp.mdga.message.server.CeremonyMessage; import pp.mdga.message.server.PauseGameMessage; import pp.mdga.server.automaton.game.AnimationState; import pp.mdga.server.automaton.game.DetermineStartPlayerState; @@ -82,6 +83,7 @@ public void received(DisconnectedMessage msg, int from) { public void received(LeaveGameMessage msg, int from) { this.logic.getGame().updatePlayerActiveState(from, false); if (this.logic.getGame().getNumberOfActivePlayers() == 1) { + this.logic.getServerSender().broadcast(new CeremonyMessage()); this.logic.setCurrentState(this.logic.getCeremonyState()); } } 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 32b400b6..ad87ba3b 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 @@ -7,7 +7,6 @@ import pp.mdga.message.server.*; import pp.mdga.server.ServerGameLogic; -import java.util.ArrayList; import java.util.Map; /** @@ -49,7 +48,7 @@ public void exit() { * 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()) { + for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) { this.logic.getGame().getBoard().addPlayerData(entry.getValue().getColor(), new PlayerData(entry.getValue().getColor())); } } @@ -80,18 +79,13 @@ public void received(JoinedLobbyMessage msg, int from) { */ @Override public void received(SelectTSKMessage msg, int from) { - for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) { - if (entry.getValue().getColor() == msg.getColor()) { - return; - } + if (msg.getColor() != Color.NONE && !this.logic.getGame().isColorTaken(msg.getColor())) { + this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE, false)); + this.logic.getGame().getPlayerById(from).setColor(msg.getColor()); + this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor(), true)); + } else { + this.logic.getServerSender().send(from, new IncorrectRequestMessage(0)); } - - if(this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) { - this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, this.logic.getGame().getPlayerById(from).getColor(), false)); - } - - this.logic.getGame().getPlayerById(from).setColor(msg.getColor()); - this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor(), true)); } /** @@ -116,44 +110,22 @@ public void received(DeselectTSKMessage msg, int from) { */ @Override public void received(LobbyReadyMessage msg, int from) { - //assign a free color - if(this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) { - ArrayList colors = new ArrayList<>(); - colors.add(Color.ARMY); - colors.add(Color.AIRFORCE); - colors.add(Color.NAVY); - colors.add(Color.CYBER); + if (this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) { + Color color = this.logic.getGame().getFirstUnusedColor(); - for (Map.Entry entry : this.logic.getGame().getPlayers().entrySet()) { - if(colors.contains(entry.getValue().getColor())) { - colors.remove(entry.getValue().getColor()); - } + if (color != null) { + this.logic.getGame().getPlayerById(from).setColor(color); + this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, color, true)); + } else { + this.logic.getServerSender().send(from, new IncorrectRequestMessage(1)); } - - if(colors.size() < 1) { - throw new RuntimeException("can not assign a color"); - } - - this.logic.getGame().getPlayerById(from).setColor(colors.get(0)); - this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, colors.get(0), true)); } - 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().isReady()) { - return; - } - } - - this.logic.getGame().setAllReady(true); - if (this.logic.getGame().allReady()) { - this.logic.getServerSender().broadcast(new StartBriefingMessage(this.logic.getGame().getBoard())); + if (this.logic.getGame().areAllReady()) { this.initializeGame(); - for (Map.Entry entry : logic.getGame().getBoard().getPlayerData().entrySet()) { - this.logic.getServerSender().broadcast(new PlayerDataMessage(entry.getValue(), entry.getKey())); - } - this.logic.getServerSender().broadcast(new ServerStartGameMessage()); + this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard())); + this.logic.setCurrentState(this.logic.getGameState()); } } @@ -167,27 +139,9 @@ public void received(LobbyReadyMessage msg, int from) { @Override public void received(LobbyNotReadyMessage msg, int from) { this.logic.getGame().getPlayerById(from).setReady(false); - this.logic.getGame().setAllReady(false); this.logic.getServerSender().broadcast(new UpdateReadyMessage(from, false)); } - /** - * This method will be called whenever the server received an LeaveGameMessage message. - * It will also get the client id of the player who send this message. - * - * @param msg as the message which was sent by the player as a LeaveGameMessage object. - * @param from as the client id of the player as an Integer. - */ - @Override - public void received(LeaveGameMessage msg, int from) { - if (from == this.logic.getGame().getHost()) { - this.logic.getServerSender().broadcast(new ShutdownMessage()); - } - this.logic.getGame().removePlayer(from); - this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from)); - this.logic.getServerSender().disconnectClient(from); - } - /** * This method will be called whenever the server received a StartGame message. * It will also get the client id of the player who send this message. @@ -197,9 +151,9 @@ public void received(LeaveGameMessage msg, int from) { */ @Override public void received(StartGameMessage msg, int from) { - if (msg.isForceStartGame() || this.logic.getGame().allReady()) { + if (msg.isForceStartGame() || this.logic.getGame().areAllReady()) { this.initializeGame(); - this.logic.getServerSender().broadcast(new ServerStartGameMessage()); + 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/ServerState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/ServerState.java index da9ebc44..0a718927 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/ServerState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/ServerState.java @@ -1,6 +1,8 @@ package pp.mdga.server.automaton; import pp.mdga.message.client.*; +import pp.mdga.message.server.LobbyPlayerLeaveMessage; +import pp.mdga.message.server.ShutdownMessage; import pp.mdga.server.ServerGameLogic; /** @@ -75,7 +77,15 @@ public void received(JoinedLobbyMessage msg, int from) {} * @param msg as the message which was sent by the player as a LeaveGameMessage object. * @param from as the client id of the player as an Integer. */ - public void received(LeaveGameMessage msg, int from) {} + public void received(LeaveGameMessage msg, int from) { + if (from == this.logic.getGame().getHost()) { + this.logic.getServerSender().broadcast(new ShutdownMessage()); + this.logic.getServerSender().shutdown(); + } + this.logic.getGame().removePlayer(from); + this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from)); + this.logic.getServerSender().disconnectClient(from); + } /** * This method will be called whenever the server received a LobbyReadyMessage message. diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/AnimationState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/AnimationState.java index 8d6661b9..c1ba800e 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/AnimationState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/AnimationState.java @@ -11,10 +11,15 @@ */ public class AnimationState extends GameAutomatonState { /** - * Create FirstRollState constants. + * Create AnimationState constants. */ private static final System.Logger LOGGER = System.getLogger(AnimationState.class.getName()); + /** + * Create AnimationState attributes. + */ + private int messageReceived = 0; + /** * Constructs a server state of the specified game logic. * @@ -33,6 +38,7 @@ public void enter() { @Override public void exit() { LOGGER.log(System.Logger.Level.DEBUG, "Exited AnimationState state."); + this.messageReceived = 0; } /** @@ -44,7 +50,11 @@ public void exit() { */ @Override public void received(AnimationEndMessage msg, int from) { - this.logic.getServerSender().send(from, new DiceNowMessage()); - this.gameAutomaton.setCurrentState(this.gameAutomaton.getTurnState()); + if (this.messageReceived == this.logic.getGame().getPlayers().size()) { + this.logic.getServerSender().send(this.logic.getGame().getActivePlayerId(), new DiceNowMessage()); + this.gameAutomaton.setCurrentState(this.gameAutomaton.getTurnState()); + } else { + this.messageReceived++; + } } } 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 42c71629..1c4a23a3 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 @@ -3,6 +3,7 @@ import pp.mdga.game.Player; import pp.mdga.message.client.RequestDieMessage; import pp.mdga.message.server.ActivePlayerMessage; +import pp.mdga.message.server.DiceNowMessage; import pp.mdga.message.server.DieMessage; import pp.mdga.message.server.EndOfTurnMessage; import pp.mdga.server.ServerGameLogic; @@ -48,6 +49,8 @@ public void enter() { @Override public void exit() { LOGGER.log(System.Logger.Level.DEBUG, "Exited DetermineStartPlayerState state."); + this.diceResults.clear(); + this.playersHaveToRoll.clear(); } /** @@ -60,13 +63,12 @@ public void exit() { @Override public void received(RequestDieMessage msg, int from) { int roll = this.logic.getGame().getDie().shuffle(); + this.logic.getServerSender().send(from, new DieMessage(roll)); this.diceResults.put(from, roll); - int maximumRoll = 0; if (this.diceResults.size() == this.logic.getGame().getPlayers().size()) { + int maximumRoll = 0; for (Map.Entry entry: this.diceResults.entrySet()) { - if (maximumRoll == 0) { - maximumRoll = this.diceResults.get(entry.getKey()); - } else if (maximumRoll < entry.getValue()) { + if (maximumRoll <= entry.getValue()) { maximumRoll = entry.getValue(); } else { this.playersHaveToRoll.remove(entry.getKey()); @@ -76,10 +78,12 @@ public void received(RequestDieMessage msg, int from) { if (this.playersHaveToRoll.size() == 1) { this.logic.getServerSender().broadcast(new ActivePlayerMessage(this.logic.getGame().getPlayerById(this.playersHaveToRoll.get(0)).getColor())); + this.gameAutomaton.setCurrentState(this.gameAutomaton.getAnimationState()); } else { for (Integer id: this.playersHaveToRoll) { - this.logic.getServerSender().send(id, new DieMessage(roll)); + this.logic.getServerSender().send(id, new DiceNowMessage()); } + diceResults.clear(); } } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/GameAutomatonState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/GameAutomatonState.java index 56eac48f..958f04bb 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/GameAutomatonState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/GameAutomatonState.java @@ -23,4 +23,13 @@ public GameAutomatonState(GameState gameAutomaton, ServerGameLogic logic) { super(logic); this.gameAutomaton = gameAutomaton; } + + /** + * This method will be used to return gameAutomaton attribute of GameAutomatonState object. + * + * @return gameAutomaton as a GameState object. + */ + public GameState getGameAutomaton() { + return this.gameAutomaton; + } } diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/TurnState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/TurnState.java index 8a8c0f2c..52a38735 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/TurnState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/TurnState.java @@ -36,6 +36,7 @@ public TurnState(GameState gameAutomaton, ServerGameLogic logic) { this.rollDiceState = new RollDiceState(this, logic); this.choosePieceState = new ChoosePieceState(this, logic); this.movePieceState = new MovePieceState(this, logic); + this.setCurrentState(this.powerCardState); } @Override diff --git a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/turn/TurnAutomatonState.java b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/turn/TurnAutomatonState.java index db0b6989..282d2e50 100644 --- a/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/turn/TurnAutomatonState.java +++ b/Projekte/mdga/model/src/main/java/pp/mdga/server/automaton/game/turn/TurnAutomatonState.java @@ -13,11 +13,20 @@ public abstract class TurnAutomatonState extends ServerState { /** * Constructs a server state of the specified game logic. * - * @param turnAutomaton as the automaton of the turn state as a GameState object. + * @param turnAutomaton as the automaton of the turn state as a TurnState object. * @param logic the game logic */ public TurnAutomatonState(TurnState turnAutomaton, ServerGameLogic logic) { super(logic); this.turnAutomaton = turnAutomaton; } + + /** + * This method will be used to return turnAutomaton attribute of TurnAutomatonState object. + * + * @return turnAutomaton as a TurnState object + */ + public TurnState getTurnAutomaton() { + return this.turnAutomaton; + } } diff --git a/Projekte/mdga/model/src/main/resources/mdga.properties b/Projekte/mdga/model/src/main/resources/mdga.properties index e69de29b..ea216f91 100644 --- a/Projekte/mdga/model/src/main/resources/mdga.properties +++ b/Projekte/mdga/model/src/main/resources/mdga.properties @@ -0,0 +1,9 @@ +lobby.deny.join=The lobby is already full. +server.shutdown=The server has shut down. + +incorrect.request.0=The selected TSK is already occupied. +incorrect.request.1=No TSK is available for selection. + + + + diff --git a/Projekte/mdga/model/src/main/resources/mdga_de.properties b/Projekte/mdga/model/src/main/resources/mdga_de.properties index e69de29b..81cc4ad2 100644 --- a/Projekte/mdga/model/src/main/resources/mdga_de.properties +++ b/Projekte/mdga/model/src/main/resources/mdga_de.properties @@ -0,0 +1,5 @@ +lobby.deny.join=Die Lobby ist bereits voll. +server.shutdown=Der Server wurde heruntergefahren. + +incorrect.request.1=Die ausgewählte TSK ist bereits belegt. +incorrect.request.2=Es gibt keine freie TSK mehr, welche ausgewählt werden kann.