diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 1f0d743..b10876f 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -4,6 +4,7 @@
+
\ No newline at end of file
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index a45c144..7d36641 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -104,6 +104,7 @@
it.polimi.ingsw.gc14.ClientLauncherGUI
+
@@ -112,6 +113,7 @@
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
+ META-INF/versions/9/module-info.class
diff --git a/pom.xml b/pom.xml
index 4699c9f..428f8b5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -158,6 +158,7 @@
it.polimi.ingsw.gc14.ClientLauncherGUI
+
@@ -166,6 +167,7 @@
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
+ META-INF/versions/9/module-info.class
diff --git a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java
index 3f9e93a..35db3ca 100644
--- a/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java
+++ b/src/main/java/it/polimi/ingsw/gc14/ClientLauncherGUI.java
@@ -15,7 +15,7 @@ public class ClientLauncherGUI {
public static class GUIApp extends Application {
@Override
public void start(Stage stage) throws Exception {
- GUI view = new GUI(stage);
+ GUI view = new GUI();
ClientController controller = new ClientController(view);
view.setController(controller);
view.start(stage);
diff --git a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java
index 97cb658..13edbd4 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Controller/ClientController.java
@@ -38,7 +38,6 @@ public class ClientController {
public ClientController(IView view) {
this.view = view;
this.client = null;
- this.miniModel = new MiniModel();
}
/**
diff --git a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/GameStages.java b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/GameStages.java
index fad51b1..b8326bd 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/GameStages.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Model/GamePackage/GameStages.java
@@ -1,46 +1,69 @@
package it.polimi.ingsw.gc14.Model.GamePackage;
- /**
+/**
* Represents the possible stages of a game.
*/
public enum GameStages {
+
/**
* Stage in which the game is waiting for players to join.
*/
- WAITING,
+ WAITING("Waiting"),
/**
* Stage in which players choose their totems.
*/
- TOTEM_CHOICE,
+ TOTEM_CHOICE("Totem"),
/**
* Stage in which players select their action slots.
*/
- SLOT_CHOICE,
+ SLOT_CHOICE("Slot"),
/**
* Stage in which the mandatory actions associated with the chosen slots are resolved.
*/
- RES_ACTIONS,
+ RES_ACTIONS("Actions"),
/**
* Stage in which an optional card effect can be resolved.
*/
- OPT_CARD_E,
+ OPT_CARD_E("Card Effect"),
/**
* Stage in which an event card is being resolved.
*/
- RES_EVENT,
+ RES_EVENT("Event"),
/**
* Stage in which end-of-round or end-of-game operations are processed.
*/
- ENDING,
+ ENDING("Ending"),
/**
* Stage indicating that the game has ended.
*/
- ENDED
- }
+ ENDED("Ended");
+
+ /** The human-readable name of this stage, used in {@link #toString()}. */
+ private final String displayName;
+
+ /**
+ * Constructs a {@code GameStages} value with the given display name.
+ *
+ * @param displayName the human-readable label for this stage
+ */
+ GameStages(String displayName) {
+ this.displayName = displayName;
+ }
+
+ /**
+ * Returns the human-readable name of this stage.
+ *
+ * @return the display name (e.g. {@code "Slot"} for {@code SLOT_CHOICE})
+ */
+ @Override
+ public String toString() {
+ return displayName;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java
index c61f28d..7809819 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/AddPlayer.java
@@ -46,12 +46,14 @@ public class AddPlayer extends NetworkEvent implements Serializable {
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ApplyNextRound.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ApplyNextRound.java
index 9760b4e..322d0bd 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ApplyNextRound.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ApplyNextRound.java
@@ -59,15 +59,17 @@ public class ApplyNextRound extends NetworkEvent implements Serializable{
}
public boolean apply(MiniModel miniModel)
{
- miniModel.setSlotPlayerMap(slotPlayerMap);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setPlayers(players);
- miniModel.upperListTribeCards=upperListTribeCards;
- miniModel.lowerListTribeCards=lowerListTribeCards;
- miniModel.upperListBuildingCards=upperListBuildingCards;
- miniModel.lowerListBuildingCards=lowerListBuildingCards;
- return true;
+ synchronized (miniModel) {
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setPlayers(players);
+ miniModel.upperListTribeCards = upperListTribeCards;
+ miniModel.lowerListTribeCards = lowerListTribeCards;
+ miniModel.upperListBuildingCards = upperListBuildingCards;
+ miniModel.lowerListBuildingCards = lowerListBuildingCards;
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java
index e73a323..1bcfd53 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DisconnectedPlayer.java
@@ -33,16 +33,17 @@ public class DisconnectedPlayer extends NetworkEvent implements Serializable{
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
- if(miniModel!=null)
- {
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ if (miniModel != null) {
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ }
+ return true;
}
- return true;
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java
index d0cfb5a..03a04ea 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerBuildingCard.java
@@ -39,16 +39,17 @@ public class DrawLowerBuildingCard extends NetworkEvent implements Serializable
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
-
- miniModel.lowerListBuildingCards.remove(pos);
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.lowerListBuildingCards.remove(pos);
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java
index b9b7394..b36f9d1 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawLowerTribeCard.java
@@ -38,16 +38,17 @@ public class DrawLowerTribeCard extends NetworkEvent implements Serializable{
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
-
- miniModel.lowerListTribeCards.remove(pos);
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.lowerListTribeCards.remove(pos);
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java
index 147e7d5..e631ce0 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperBuildingCard.java
@@ -39,15 +39,16 @@ public class DrawUpperBuildingCard extends NetworkEvent implements Serializable
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
-
- miniModel.upperListBuildingCards.remove(pos);
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.upperListBuildingCards.remove(pos);
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java
index 94ee411..9bf23f4 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/DrawUpperTribeCard.java
@@ -38,15 +38,16 @@ public class DrawUpperTribeCard extends NetworkEvent implements Serializable{
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
- miniModel.upperListTribeCards.remove(pos);
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
-
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.upperListTribeCards.remove(pos);
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/EndedGame.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/EndedGame.java
index d42cfed..d2722ae 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/EndedGame.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/EndedGame.java
@@ -48,12 +48,14 @@ public class EndedGame extends NetworkEvent implements Serializable{
}
public boolean apply(MiniModel miniModel)
{
- miniModel.setSlotPlayerMap(slotPlayerMap);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setPlayers(players);
- miniModel.setStandingPlayers(players);
- return true;
+ synchronized (miniModel) {
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setPlayers(players);
+ miniModel.setStandingPlayers(players);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ReconnectPlayer.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ReconnectPlayer.java
index 1ef0305..8cfd706 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ReconnectPlayer.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/ReconnectPlayer.java
@@ -45,16 +45,18 @@ public class ReconnectPlayer extends NetworkEvent implements Serializable {
*/
@Override
public boolean apply(MiniModel miniModel) {
- if (isError)
- return false;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
- if (miniModel != null) {
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
+ if (miniModel != null) {
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ }
+
+ return true;
}
-
- return true;
}
}
\ No newline at end of file
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipTurn.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipTurn.java
index a0e84ae..3358948 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipTurn.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SkipTurn.java
@@ -33,14 +33,15 @@ public class SkipTurn extends NetworkEvent implements Serializable{
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
-
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java
index 612a9c1..c82853c 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/SlotChoice.java
@@ -39,14 +39,15 @@ public class SlotChoice extends NetworkEvent implements Serializable {
//TODO
@Override
public boolean apply(MiniModel miniModel){
- if(isError)
- return false;
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- return true;
-
+ synchronized (miniModel) {
+ if (isError)
+ return false;
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ return true;
+ }
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/TotemChoice.java b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/TotemChoice.java
index fe0aad0..a9c3119 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/TotemChoice.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/NetworkEvents/TotemChoice.java
@@ -69,14 +69,16 @@ public class TotemChoice extends NetworkEvent implements Serializable {
*/
@Override
public boolean apply(MiniModel miniModel) {
- if (isError)
- return false;
+ synchronized (miniModel) {
+ if (isError)
+ return false;
- miniModel.setPlayers(playerList);
- miniModel.setOrderLogicCard(orderLogicCard);
- miniModel.setCurrentState(currentState);
- miniModel.setSlotPlayerMap(slotPlayerMap);
- miniModel.setAvailableTotems(availableTotems);
- return true;
+ miniModel.setPlayers(playerList);
+ miniModel.setOrderLogicCard(orderLogicCard);
+ miniModel.setCurrentState(currentState);
+ miniModel.setSlotPlayerMap(slotPlayerMap);
+ miniModel.setAvailableTotems(availableTotems);
+ return true;
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java
index 74aa52b..e026eaa 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java
@@ -5,6 +5,7 @@ import it.polimi.ingsw.gc14.Model.Game;
import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.NetworkEvent;
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
+import javafx.application.Platform;
import java.io.Serializable;
import java.rmi.RemoteException;
@@ -53,12 +54,12 @@ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCa
*/
@Override
public void onAction(NetworkEvent event) throws RemoteException {
- synchronized (clientController) {
- if(event.getIsError()) {
- clientController.view.showError(event.toString());
- } else {
- clientController.view.applyAndRender(event);
- }
+ if(event.getIsError()) {
+ clientController.view.showError(event.toString());
+ } else {
+ event.apply(clientController.miniModel);
+ clientController.view.render();
}
+
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java
index cc3e337..bca2e27 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java
@@ -30,7 +30,7 @@ import java.rmi.*;
*/
public class RMIServer extends UnicastRemoteObject implements IGameServer {
private String host;
- private GameController controller;
+ private final GameController controller;
private Registry registry;
private int nPort;
@@ -105,23 +105,13 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
System.out.println("(After crash)Reconnected player: " + username);
return true;
}
- if (playerList.containsKey(username) && !playerList.get(username)) {
- playerList.put(username, true);
- clients.put(username, callback);
- System.out.println("Reconnected player: " + username);
- startWatchdog(username);
- Game game = controller.getModel();
- callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(),game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()));
- System.out.println("Model sent: " + username);
- actionQueue.add(new ReconnectPlayer(username));
- return true;
- }
}
else
{
if (playerList.isEmpty()) {
controller.setModel(new Game(preferredInt));
playerList.setLimit(preferredInt);
+ System.out.println("Game Created With :"+preferredInt+" Players");
}
if (controller.addPlayer(username)) {
clients.put(username, callback);
@@ -130,18 +120,17 @@ public class RMIServer extends UnicastRemoteObject implements IGameServer {
System.out.println("Accepted player: " + username);
return true;
}
- // Reconnection: player was offline
- if (playerList.containsKey(username) && !playerList.get(username)) {
- playerList.put(username, true);
- clients.put(username, callback);
- System.out.println("Reconnected player: " + username);
- startWatchdog(username);
- Game game = controller.getModel();
- callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(),game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()));
- System.out.println("Model sent: " + username);
- actionQueue.add(new ReconnectPlayer(username));
- return true;
- }
+ }
+ if (playerList.containsKey(username) && !playerList.get(username)) {
+ playerList.put(username, true);
+ clients.put(username, callback);
+ System.out.println("Reconnected player: " + username);
+ startWatchdog(username);
+ Game game = controller.getModel();
+ callback.onGameInit(new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(),game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()));
+ System.out.println("Model sent: " + username);
+ actionQueue.add(new ReconnectPlayer(username));
+ return true;
}
return false;
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java
index 28598d4..67ae202 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Client/TCPClient.java
@@ -6,6 +6,7 @@ import it.polimi.ingsw.gc14.Model.MiniModel;
import it.polimi.ingsw.gc14.Network.IClient;
import it.polimi.ingsw.gc14.Network.NetworkEvent;
import it.polimi.ingsw.gc14.Network.NetworkEvents.*;
+import javafx.application.Platform;
import java.io.*;
import java.net.*;
@@ -163,14 +164,13 @@ public class TCPClient implements IClient {
if (event.getIsError()) {
controller.view.showError(event.toString());
} else {
- controller.view.applyAndRender(event);
+ event.apply(controller.miniModel);
+ controller.view.render();
}
} else if (read instanceof MiniModel model) {
- synchronized (controller) {
- controller.setModel(model);
- controller.view.render();
- }
+ controller.setModel(model);
+ controller.view.render();
}
} catch (ClassNotFoundException e) {
diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java
index fd73764..9c618ef 100644
--- a/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java
+++ b/src/main/java/it/polimi/ingsw/gc14/Network/TCP/Server/TCPServer.java
@@ -179,12 +179,11 @@ public class TCPServer {
synchronized (controller) {
String username = eventAddPlayer.getUsername();
-
+ //reconnect players after a server crash
if (serverCrashed) {
if (controller.getModel().getPlayers().stream()
.anyMatch(p -> p.getUserName().equals(username))
&& !playerList.containsKey(username)) {
-
playerList.put(username, true);
System.out.println("(After crash)Reconnected player: " + username);
@@ -206,54 +205,18 @@ public class TCPServer {
clientHandlers.add(handler);
connectedPlayers++;
+ return;
- } else if (playerList.containsKey(username)
- && !playerList.get(username)) {
-
- playerList.put(username, true);
- System.out.println("Reconnected player: " + username);
-
- ClientHandler handler = new ClientHandler(
- username,
- clientSocket,
- clientSend,
- clientReceive,
- clientHandlers,
- playerList,
- actionQueue
- );
-
- clientSocket.getOutputStream().write(1);
- pendingHeartbeat.put(username, handler);
-
- Game game = controller.getModel();
- handler.notifyMiniModel(new MiniModel(
- game.getSlotMap(),
- game.orderLogicCard,
- game.getCurrentState(),
- game.getPlayers(),
- game.getAvailableTotems(),
- game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()
- ));
-
- Thread thread = new Thread(handler);
- thread.start();
-
- clientHandlers.add(handler);
- connectedPlayers++;
- actionQueue.add(new ReconnectPlayer(username));
-
- } else {
- clientSocket.getOutputStream().write(-1);
- clientSocket.close();
- System.out.println("Player could not be added. Connection terminated.");
}
- } else {
+ }
+ //manages a new player adding
+ else {
if (playerList.isEmpty()) {
Game model = new Game(eventAddPlayer.getProposedNPlayer());
controller.setModel(model);
playerList.setLimit(eventAddPlayer.getProposedNPlayer());
+ System.out.println("Game Created With :"+eventAddPlayer.getProposedNPlayer()+" Players");
}
if (controller.addPlayer(username)) {
@@ -278,52 +241,55 @@ public class TCPServer {
clientHandlers.add(handler);
connectedPlayers++;
+ return;
- } else if (playerList.containsKey(username)
- && !playerList.get(username)) {
-
- playerList.put(username, true);
- System.out.println("Reconnected player: " + username);
-
- ClientHandler handler = new ClientHandler(
- username,
- clientSocket,
- clientSend,
- clientReceive,
- clientHandlers,
- playerList,
- actionQueue
- );
-
- clientSocket.getOutputStream().write(1);
- pendingHeartbeat.put(username, handler);
-
- Game game = controller.getModel();
- handler.notifyMiniModel(new MiniModel(
- game.getSlotMap(),
- game.orderLogicCard,
- game.getCurrentState(),
- game.getPlayers(),
- game.getAvailableTotems(),
- game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()
-
- ));
-
- Thread thread = new Thread(handler);
- thread.start();
-
- clientHandlers.add(handler);
- connectedPlayers++;
- actionQueue.add(new ReconnectPlayer(username));
-
- } else {
- clientSocket.getOutputStream().write(-1);
- clientSocket.close();
- System.out.println("Player could not be added. Connection terminated.");
}
}
+ //reconnect a previously disconnected player
+ if (playerList.containsKey(username)
+ && !playerList.get(username)) {
+
+ playerList.put(username, true);
+ System.out.println("Reconnected player: " + username);
+
+ ClientHandler handler = new ClientHandler(
+ username,
+ clientSocket,
+ clientSend,
+ clientReceive,
+ clientHandlers,
+ playerList,
+ actionQueue
+ );
+
+ clientSocket.getOutputStream().write(1);
+ pendingHeartbeat.put(username, handler);
+
+ Game game = controller.getModel();
+ handler.notifyMiniModel(new MiniModel(
+ game.getSlotMap(),
+ game.orderLogicCard,
+ game.getCurrentState(),
+ game.getPlayers(),
+ game.getAvailableTotems(),
+ game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding()
+ ));
+
+ Thread thread = new Thread(handler);
+ thread.start();
+
+ clientHandlers.add(handler);
+ connectedPlayers++;
+ actionQueue.add(new ReconnectPlayer(username));
+
+ } else {
+ clientSocket.getOutputStream().write(-1);
+ clientSocket.close();
+ System.out.println("Player could not be added. Connection terminated.");
+ }
}
+
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java
index a986bd6..2138468 100644
--- a/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java
+++ b/src/main/java/it/polimi/ingsw/gc14/ServerLauncher.java
@@ -52,7 +52,7 @@ public class ServerLauncher {
BlockingQueue actionQueue;
/** Game controller. Used to apply events */
- GameController gameController;
+ final GameController gameController;
/** Server RMI. Handles RMI clients */
RMIServer serverRMI;
@@ -106,8 +106,10 @@ public class ServerLauncher {
*/
public boolean doFirstEvent() throws InterruptedException {
NetworkEvent event = actionQueue.take();
- if(gameController.getModel()!=null && !gameController.getModel().getCurrentState().equals(GameStages.ENDED))
+ //Verify that the model exist and if it exists that's not ended
+ if(gameController.getModel()!=null && gameController.getModel().getCurrentState().getGameStage()!=GameStages.ENDED)
{
+ //if there is only one player ignore every event different by reconnection
if(disconnectionTimer!=null && event.getEventType() != EventType.RECONNECT_PLAYER)
{
event.setIsError(true);
@@ -115,16 +117,24 @@ public class ServerLauncher {
serverTCP.notifyAll(event);
return false;
}
+
+ //Cancel the timer if another player is reconnected , so there are more than one player
if (event.getEventType() == EventType.RECONNECT_PLAYER && disconnectionTimer != null && !disconnectionTimer.isDone()) {
disconnectionTimer.cancel(false);
disconnectionTimer = null;
}
+
int roundPrev=gameController.getModel().getCurrentState().getRound();
synchronized(gameController){
+ //applies the event and set if is an error
event.setIsError(!event.apply(gameController));
Game game=gameController.getModel();
+ //if the event wasn't an error , it will be sent to players
if(!event.getIsError())
{
+ if(!this.gameSave() ){
+ System.out.println("\n!!! Save failed !!!\n");
+ }
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER)&& game.getCurrentState().getGameStage().equals(GameStages.WAITING))
{
playerList.remove(event.getUsername());
@@ -132,11 +142,43 @@ public class ServerLauncher {
event.setData(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(), game.getPlayers());
if (event.getEventType().equals(EventType.TOTEM_CHOICE)) {
((TotemChoice) event).setAvailableTotems(gameController.getModel().getAvailableTotems());
- } else if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && game.getCurrentState().equals(GameStages.WAITING)) {
+ } else if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && game.getCurrentState().getGameStage().equals(GameStages.WAITING)) {
playerList.remove(event.getUsername());
}
}
- if(game.getCurrentState().getGameStage() == GameStages.ENDED){
+ //if there is only one player the game will be suspended and starts the forfeit timer
+ if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1&& game.getCurrentState().getGameStage() != GameStages.ENDED) {
+ if (disconnectionTimer != null && !disconnectionTimer.isDone()) {
+ disconnectionTimer.cancel(false);
+ }
+ //schedule endgame for forfeit
+ disconnectionTimer = timerExecutor.schedule(() -> {
+ game.EndGameForFeit();
+ serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
+ serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
+ System.out.println("Timer expired: no player reconnected in 60s.");
+ for(Map.Entry entry:playerList.entrySet()){
+ if(!entry.getValue())
+ playerList.remove(entry.getKey());
+ }
+ if(!this.deleteSave()){
+ System.out.println("\n!!! Couldn't delete save !!!\n");
+ }
+ disconnectionTimer = null;
+ }, 1, TimeUnit.MINUTES);
+ }
+ //if the round is changed send a new next round event , the previous event is ignored and directly sent the next round(also upper and lower lists updated)
+ if(game.getCurrentState().getRound()!=roundPrev)
+ {
+ ApplyNextRound nextRound=new ApplyNextRound(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayers(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding());
+ serverRMI.notifyAll(nextRound);
+ serverTCP.notifyAll(nextRound);
+ }
+ // if the game ends after the event, delete the game. await that all players are disconnected and then create a new game
+ else if(game.getCurrentState().getGameStage().equals(GameStages.ENDED))
+ {
+ serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
+ serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
if(!this.deleteSave()){
System.out.println("\n!!! Couldn't delete save !!!\n");
}
@@ -147,48 +189,26 @@ public class ServerLauncher {
serverRMI.setServerCrashed(false);
serverTCP.setServerCrashed(false);
}
- else if(!this.gameSave() ){
- System.out.println("\n!!! Save failed !!!\n");
+ //notify the event
+ else {
+ serverRMI.notifyAll(event);
+ serverTCP.notifyAll(event);
}
}
- serverRMI.notifyAll(event);
- serverTCP.notifyAll(event);
- if(game.getCurrentState().getRound()!=roundPrev)
- {
- ApplyNextRound nextRound=new ApplyNextRound(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayers(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding());
- serverRMI.notifyAll(nextRound);
- serverTCP.notifyAll(nextRound);
- }
- else if(game.getCurrentState().getGameStage().equals(GameStages.ENDED))
- {
- serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
- serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
- }
- if (event.getEventType().equals(EventType.DISCONNECTED_PLAYER) && playerList.values().stream().filter(x -> x).count() == 1&& game.getCurrentState().getGameStage() != GameStages.ENDED) {
- if (disconnectionTimer != null && !disconnectionTimer.isDone()) {
- disconnectionTimer.cancel(false);
- }
- disconnectionTimer = timerExecutor.schedule(() -> {
- game.EndGameForFeit();
- serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
- serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
- System.out.println("Timer expired: no player reconnected in 60s.");
- if(!this.deleteSave()){
- System.out.println("\n!!! Couldn't delete save !!!\n");
- }
- }, 1, TimeUnit.MINUTES);
- }
return !event.getIsError();
}
}
else{
+ // removes disconneted players when the game is ended
if(event.getEventType().equals(EventType.DISCONNECTED_PLAYER))
{
playerList.remove(event.getUsername());
if(playerList.isEmpty())
{
gameController.setModel(null);
+ System.out.println("\n!!! Player list is now empty, ready for a new game init !!!\n");
}
+ return true;
}
return false;
}
@@ -253,12 +273,12 @@ public class ServerLauncher {
MiniModel miniModel;
synchronized (gameController) {
Game game = gameController.getModel();
- miniModel= new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), new ArrayList<>(List.of(Totems.values())),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding());
+ miniModel= new MiniModel(game.getSlotMap(), game.orderLogicCard,game.getCurrentState(),game.getPlayers(), game.getAvailableTotems(),game.getUpperListTribeCards(),game.getLowerListTribeCards(),game.getUpperListBuilding(),game.getLowerListBuilding());
}
serverRMI.notifyAll(miniModel);
serverTCP.notifyAll(miniModel);
view = new TUI(miniModel);
- view.fullRender();
+ view.render();
}).start();
});
new Thread(()-> {
@@ -290,10 +310,10 @@ public class ServerLauncher {
while (true) {
try{
this.doFirstEvent();
- if(view!=null)
- {
- view.fullRender();
- }
+// if(view!=null)
+// {
+// view.fullRender();
+// }
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java
index f6a9197..550d582 100644
--- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java
+++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/GUI.java
@@ -45,12 +45,10 @@ public class GUI extends Application implements IView {
private ClientController controller;
- public GUI(Stage stage) {
- this.primaryStage = stage;
- }
@Override
public void start(Stage stage) throws Exception {
+ this.primaryStage = stage;
loaderLogin = new FXMLLoader(getClass().getResource("/GUIScene/login.fxml"));
loginScene = new Scene(loaderLogin.load());
controllerLogin = loaderLogin.getController();
@@ -73,7 +71,7 @@ public class GUI extends Application implements IView {
loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml"));
leaderboardScene = new Scene(loaderLeaderboard.load());
controllerLeaderboard = loaderLeaderboard.getController();
- controllerLeaderboard.setController(controller);
+ controllerLeaderboard.setController(controller,primaryStage,loginScene);
mainScene = new Scene(loaderMain.load());
controllerMain = loaderMain.getController();
@@ -81,10 +79,7 @@ public class GUI extends Application implements IView {
showLogin();
- stage.setTitle("Mesos");
- primaryStage.setMaximized(true);
- primaryStage.setMinWidth(1583);
- primaryStage.setMinHeight(734);
+ primaryStage.setTitle("Mesos");
primaryStage.setOnCloseRequest(e -> {
Platform.exit();
System.exit(0);
@@ -106,48 +101,29 @@ public class GUI extends Application implements IView {
this.controller=controller;
}
-
- public void applyAndRender(NetworkEvent event) {
+ public void render() {
Platform.runLater(() -> {
- event.apply(miniModel);
- if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) {
- primaryStage.setScene(totemScene);
- controllerTotem.render();
- } else if (controller.miniModel.currentState.getGameStage() == GameStages.ENDED) {
- boolean sceneChange = primaryStage.getScene() != leaderboardScene;
- primaryStage.setScene(leaderboardScene);
- if (sceneChange) {
- primaryStage.setMaximized(false);
- Platform.runLater(() -> primaryStage.setMaximized(true));
+ synchronized (miniModel) {
+ if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) {
+ primaryStage.setScene(totemScene);
+ controllerTotem.render();
+ } else if (controller.miniModel.currentState.getGameStage() == ENDED) {
+ primaryStage.setScene(leaderboardScene);
+ controllerLeaderboard.render();
+ } else {
+ double w = primaryStage.getWidth();
+ double h = primaryStage.getHeight();
+ primaryStage.setScene(mainScene);
+ primaryStage.setWidth(w);
+ primaryStage.setHeight(h);
+ primaryStage.setMinHeight(h);
+ primaryStage.setMinWidth(w);
+ primaryStage.setResizable(false);
+ controllerMain.render();
}
- controllerLeaderboard.render();
- } else {
- boolean sceneChange = primaryStage.getScene() != mainScene; // ← era un'altra scena?
- primaryStage.setScene(mainScene);
- if (sceneChange) {
- primaryStage.setMaximized(false);
- Platform.runLater(() -> primaryStage.setMaximized(true));
- }
- controllerMain.render(event);
}
});
- }
- public void render() {
- if (!Platform.isFxApplicationThread()) {
- Platform.runLater(this::render);
- return;
- }
- if (controller.miniModel.currentState.getGameStage() == TOTEM_CHOICE) {
- primaryStage.setScene(totemScene);
- controllerTotem.render();
- } else if (controller.miniModel.currentState.getGameStage() == ENDED){
- primaryStage.setScene(leaderboardScene);
- controllerLeaderboard.render();
- }else {
- primaryStage.setScene(mainScene);
- controllerMain.render();
- }
}
@Override
public void showMessage(String message) {
@@ -156,7 +132,12 @@ public class GUI extends Application implements IView {
@Override
public void showError(String message) {
-
+ Platform.runLater(() -> {
+ synchronized (miniModel) {
+ controllerMain.isError = true;
+ controllerMain.render();
+ }
+ });
}
}
\ No newline at end of file
diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java
index 62d3f4a..e49a6c9 100644
--- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java
+++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/LeaderboardFXMLController.java
@@ -6,6 +6,7 @@ import javafx.animation.ScaleTransition;
import it.polimi.ingsw.gc14.Model.PlayableCard;
import javafx.event.Event;
import javafx.fxml.FXML;
+import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.stage.Popup;
import javafx.geometry.Insets;
@@ -23,6 +24,7 @@ import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.CycleMethod;
import javafx.scene.text.Font;
+import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.Duration;
@@ -42,6 +44,8 @@ public class LeaderboardFXMLController {
// Cache condivisa con MainFXMLController
private static final Map imageCache = new HashMap<>();
+ private Scene loginScene;
+ private Stage primaryStage;
private Image loadImage(String path) {
return imageCache.computeIfAbsent(path,
@@ -49,8 +53,10 @@ public class LeaderboardFXMLController {
}
- public void setController(ClientController controller) {
+ public void setController(ClientController controller, Stage primaryStage, Scene loginScene) {
this.controller = controller;
+ this.loginScene=loginScene;
+ this.primaryStage=primaryStage;
}
@@ -356,6 +362,6 @@ public class LeaderboardFXMLController {
// ==== ACTIONS ====
@FXML
private void onNewGame() {
- //controller.requestNewGame();
+ primaryStage.setScene(loginScene);
}
}
diff --git a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java
index 59ca329..3c6efce 100644
--- a/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java
+++ b/src/main/java/it/polimi/ingsw/gc14/View/GUI/MainFXMLController.java
@@ -7,9 +7,8 @@ import it.polimi.ingsw.gc14.Model.Cards.TribeCard;
import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer;
import it.polimi.ingsw.gc14.Network.EventType;
import it.polimi.ingsw.gc14.Network.NetworkEvent;
-import javafx.animation.AnimationTimer;
-import javafx.animation.PauseTransition;
import javafx.animation.ScaleTransition;
+import javafx.animation.TranslateTransition;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
@@ -18,8 +17,11 @@ import javafx.fxml.FXML;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
+import javafx.geometry.Rectangle2D;
import javafx.scene.Cursor;
import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.ColorAdjust;
@@ -31,7 +33,7 @@ import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.stage.Popup;
-import javafx.stage.Stage;
+import javafx.stage.Screen;
import javafx.stage.Window;
import javafx.util.Duration;
@@ -39,22 +41,24 @@ import java.util.*;
public class MainFXMLController {
+ @FXML private ScrollPane playerSide;
@FXML private HBox mainHBox;
+ @FXML private ImageView backgroundImage;
@FXML private HBox board;
@FXML private HBox upperList;
@FXML private HBox lowerList;
@FXML private HBox myHand;
- @FXML private VBox sidePanel;
- @FXML private HBox info;
- @FXML private Label era;
- @FXML private Label round;
- @FXML private Label player;
+ @FXML private Button skipBtn;
+ @FXML private Button detailsBtn;
+ @FXML private Label infoText;
private Popup popup;
private HBox popupCards;
private ClientController controller;
+ public boolean isError;
+
// ==== IMAGE CACHE ====
private static final Map imageCache = new HashMap<>();
@@ -63,43 +67,41 @@ public class MainFXMLController {
p -> new Image(getClass().getResourceAsStream(p)));
}
-
public void setController(ClientController controller) {
this.controller = controller;
}
-
@FXML
public void initialize() {
Font.loadFont(getClass().getResourceAsStream("/Fonts/InknutAntiqua-Regular.ttf"), 14);
+
+ popup = new Popup();
mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -> {
if (newScene != null) {
- newScene.getRoot().applyCss();
newScene.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
if (popup.isShowing()) popup.hide();
});
+ newScene.getRoot().applyCss();
+ newScene.windowProperty().addListener((o2, ow, nw) -> {
+ if (nw != null) {
+ nw.focusedProperty().addListener((o3, wf, nf) -> {
+ if (!nf) popup.hide();
+ });
+ }
+ });
}
- });
- mainHBox.layoutBoundsProperty().addListener(new ChangeListener() {
- @Override
- public void changed(ObservableValue extends Bounds> obs, Bounds ov, Bounds nv) {
- if (nv.getWidth() > 0 && nv.getHeight() > 0 && controller != null) {
- mainHBox.layoutBoundsProperty().removeListener(this);
- render();
- }
+ else {
+ popup.hide();
}
});
initPopup();
renderBackground();
+ isError=false;
}
// ==== RENDER ====
public void render() {
- if (mainHBox.getWidth() == 0 || mainHBox.getHeight() == 0) {
- Platform.runLater(() -> render());
- return;
- }
renderUpper();
renderBoard();
renderLower();
@@ -107,37 +109,15 @@ public class MainFXMLController {
renderSidePanel();
}
- public void render(NetworkEvent event) {
- if (mainHBox.getWidth() == 0 || mainHBox.getHeight() == 0) {
- Platform.runLater(() -> render(event));
- return;
- }
- if (event.getEventType() == EventType.SLOT_CHOICE) {
- renderBoard();
- renderSidePanel();
- } else {
- renderUpper();
- renderBoard();
- renderLower();
- renderSidePanel();
- if (Objects.equals(event.getUsername(), controller.myUsername)
- || event.getEventType() == EventType.NEXT_ROUND) {
- renderMyHand();
- }
- }
- }
-
// ==== EFFECTS ====
private void addClip(ImageView img) {
Rectangle clip = new Rectangle();
clip.setArcWidth(20);
clip.setArcHeight(20);
- clip.heightProperty().bind(img.fitHeightProperty());
- clip.widthProperty().bind(img.fitHeightProperty().multiply(
- img.getImage().getWidth() / img.getImage().getHeight()
- ));
img.setClip(clip);
+ clip.heightProperty().bind(img.layoutBoundsProperty().map(b -> b.getHeight()));
+ clip.widthProperty().bind(img.layoutBoundsProperty().map(b -> b.getWidth()));
}
private void addHoverZoom(Node node) {
@@ -176,7 +156,7 @@ public class MainFXMLController {
// ==== ELEMENTS ====
private StackPane createOrder(String num) {
ImageView img = new ImageView(loadImage("/GUIImages/Orders/order-" + num + ".png"));
- img.fitHeightProperty().bind(board.heightProperty().add(-15));
+ img.fitHeightProperty().bind(board.heightProperty().multiply(0.94));
img.setPreserveRatio(true);
addClip(img);
return new StackPane(img);
@@ -185,7 +165,7 @@ public class MainFXMLController {
private StackPane createSlot(Slot slot, boolean withZoom, boolean withShadow) {
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + slot.getSlotId() + ".png"));
img.setPreserveRatio(true);
- img.fitHeightProperty().bind(board.heightProperty().add(-15));
+ img.fitHeightProperty().bind(board.heightProperty().multiply(0.94)); // TODO perchè è tutto moltiplicato per una costante ma in board facciamo -15?
addClip(img);
StackPane wrapper = new StackPane(img);
@@ -195,10 +175,7 @@ public class MainFXMLController {
totem.fitHeightProperty().bind(img.fitHeightProperty().multiply(0.332));
totem.setPreserveRatio(true);
StackPane.setAlignment(totem, Pos.TOP_LEFT);
- StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight()));
- img.fitHeightProperty().addListener((obs, ov, nv) -> {
- StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * nv.doubleValue()));
- });
+ StackPane.setMargin(totem, new Insets(0, 0, 0, 0.224 * img.getFitHeight())); // TODO perchè margine sx incrementa con altezza e non larghezza?
wrapper.getChildren().add(totem);
}
@@ -210,7 +187,7 @@ public class MainFXMLController {
private StackPane createCard(PlayableCard card, boolean withZoom, boolean withShadow, Region parent) {
ImageView img = new ImageView(loadImage("/GUIImages/Fronts/card-" + card.getIdIMG() + ".png"));
img.setPreserveRatio(true);
- img.fitHeightProperty().bind(parent.heightProperty().multiply(0.85));
+ img.fitHeightProperty().bind(parent.heightProperty().multiply(0.90));
addClip(img);
StackPane wrapper = new StackPane(img);
if (withShadow) addShadow(wrapper);
@@ -218,54 +195,6 @@ public class MainFXMLController {
return wrapper;
}
- private void renderIcons(HBox iconsRow1, HBox iconsRow2, Player player) {
- String[][] iconTypes = {
- {"Artist", "artists"},
- {"Gatherer", "gatherers"},
- {"Inventor", "inventors"},
- {"Builder", "builders"},
- {"Shaman", "shamans"},
- {"Hunter", "hunters"}
- };
-
- for (int i = 0; i < iconTypes.length; i++) {
- String iconName = iconTypes[i][0];
- String fieldName = iconTypes[i][1];
-
- ImageView icon = new ImageView();
- icon.setFitWidth(28);
- icon.setFitHeight(28);
- icon.setPreserveRatio(true);
- icon.setImage(loadImage("/GUIImages/Icons/" + iconName + ".png"));
-
- ArrayList cards = getPlayerCards(player.getUserName(), fieldName);
- if (cards.isEmpty()) {
- ColorAdjust grayscale = new ColorAdjust();
- icon.setEffect(grayscale);
- icon.setOpacity(0.3);
- } else {
- icon.setOnMouseClicked(e -> openPopup(new ArrayList<>(cards)));
- addHoverZoom(icon);
- }
-
- if (i < 3) iconsRow1.getChildren().add(icon);
- else iconsRow2.getChildren().add(icon);
- }
- }
-
- private ArrayList getPlayerCards(String username, String type) {
- Player p = controller.miniModel.players.get(username);
- return switch (type) {
- case "artists" -> new ArrayList<>(p.artists);
- case "gatherers" -> new ArrayList<>(p.gatherers);
- case "inventors" -> new ArrayList<>(p.inventors);
- case "builders" -> new ArrayList<>(p.builders);
- case "shamans" -> new ArrayList<>(p.shamans);
- case "hunters" -> new ArrayList<>(p.hunters);
- case "building" -> new ArrayList<>(p.buildingCards);
- default -> new ArrayList<>();
- };
- }
// ==== GROUPS ====
@@ -331,9 +260,9 @@ public class MainFXMLController {
}
}
- private void drawMyHandList(ArrayList extends PlayableCard> cardList, HBox parent) {
+ private void drawMyHandList(ArrayList extends PlayableCard> cardList) {
if (!cardList.isEmpty()) {
- StackPane img = createCard(cardList.getLast(), true, true, parent);
+ StackPane img = createCard(cardList.getLast(), true, true, myHand);
Label label = new Label(String.valueOf(cardList.size()));
label.setTranslateY(-55);
label.setTranslateX(10);
@@ -341,23 +270,30 @@ public class MainFXMLController {
StackPane.setAlignment(label, Pos.TOP_RIGHT);
img.getChildren().add(label);
img.setOnMouseClicked(e -> openPopup(new ArrayList<>(cardList)));
- parent.getChildren().add(img);
+ myHand.getChildren().add(img);
} else {
Region placeholder = new Region();
- placeholder.prefHeightProperty().bind(parent.heightProperty().multiply(0.85));
+ placeholder.prefHeightProperty().bind(myHand.heightProperty().multiply(0.90));
placeholder.prefWidthProperty().bind(placeholder.prefHeightProperty().multiply(0.675));
placeholder.setStyle("-fx-background-color: transparent;");
- parent.getChildren().add(placeholder);
+ myHand.getChildren().add(placeholder);
}
}
private void renderPlayer(Player player,VBox target) {
VBox card = new VBox(3);
- VBox.setMargin(card, new Insets(15,15,15,15));
+ VBox.setMargin(card, new Insets(8,15,8,15));
card.getStyleClass().add("player-card");
- card.setPadding(new Insets(8));
- addHoverZoom(card);
- addShadow(card);
+ card.setPadding(new Insets(4));
+
+ if(player.getUserName().equals(controller.miniModel.currentState.getCurrentPlayer().getUserName())) {
+ ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), card);
+ scaleUp.setToX(1.1);
+ scaleUp.setToY(1.1);
+ scaleUp.play();
+ }
+
+
// Riga 1: totem + nome
HBox headerRow = new HBox(8);
@@ -369,6 +305,17 @@ public class MainFXMLController {
usernameLabel.getStyleClass().add("label-medium");
if (player.getUserName().equals(controller.myUsername)) {
usernameLabel.setStyle("-fx-text-fill: #9d0208");
+
+ if(isError) {
+ TranslateTransition tt = new TranslateTransition(Duration.millis(50), card);
+ tt.setFromX(0);
+ tt.setByX(10);
+ tt.setCycleCount(6);
+ tt.setAutoReverse(true);
+ tt.play();
+
+ isError=false;
+ }
}
headerRow.getChildren().addAll(totem, usernameLabel);
@@ -425,6 +372,55 @@ public class MainFXMLController {
target.getChildren().add(card);
}
+ private void renderIcons(HBox iconsRow1, HBox iconsRow2, Player player) {
+ String[][] iconTypes = {
+ {"Artist", "artists"},
+ {"Gatherer", "gatherers"},
+ {"Inventor", "inventors"},
+ {"Builder", "builders"},
+ {"Shaman", "shamans"},
+ {"Hunter", "hunters"}
+ };
+
+ for (int i = 0; i < iconTypes.length; i++) {
+ String iconName = iconTypes[i][0];
+ String fieldName = iconTypes[i][1];
+
+ ImageView icon = new ImageView();
+ icon.setFitWidth(28);
+ icon.setFitHeight(28);
+ icon.setPreserveRatio(true);
+ icon.setImage(loadImage("/GUIImages/Icons/" + iconName + ".png"));
+
+ ArrayList cards = getPlayerCards(player.getUserName(), fieldName);
+ if (cards.isEmpty()) {
+ ColorAdjust grayscale = new ColorAdjust();
+ icon.setEffect(grayscale);
+ icon.setOpacity(0.3);
+ } else {
+ icon.setOnMouseClicked(e -> openPopup(new ArrayList<>(cards)));
+ addHoverZoom(icon);
+ }
+
+ if (i < 3) iconsRow1.getChildren().add(icon);
+ else iconsRow2.getChildren().add(icon);
+ }
+ }
+
+ private ArrayList getPlayerCards(String username, String type) {
+ Player p = controller.miniModel.players.get(username);
+ return switch (type) {
+ case "artists" -> new ArrayList<>(p.artists);
+ case "gatherers" -> new ArrayList<>(p.gatherers);
+ case "inventors" -> new ArrayList<>(p.inventors);
+ case "builders" -> new ArrayList<>(p.builders);
+ case "shamans" -> new ArrayList<>(p.shamans);
+ case "hunters" -> new ArrayList<>(p.hunters);
+ case "building" -> new ArrayList<>(p.buildingCards);
+ default -> new ArrayList<>();
+ };
+ }
+
// ==== ABSOLUTES ====
private void renderBackground() {
@@ -458,7 +454,7 @@ public class MainFXMLController {
default -> "/GUIImages/Backs/back-001.png";
};
ImageView back = new ImageView(loadImage(path));
- back.fitHeightProperty().bind(board.heightProperty().add(-15));
+ back.fitHeightProperty().bind(board.heightProperty().multiply(0.94));
back.setPreserveRatio(true);
addClip(back);
addShadow(back);
@@ -476,7 +472,6 @@ public class MainFXMLController {
4, new double[]{0.142, 0.316, 0.503, 0.690},
5, new double[]{0.066, 0.251, 0.433, 0.617, 0.802}
);
-
double[] positions = slotPositions.get(numPlayers);
if (positions == null) return;
@@ -523,17 +518,6 @@ public class MainFXMLController {
card.getChildren().add(overlay);
board.getChildren().add(card);
}
- private Color totemColor(Totems totem) {
- return switch (totem) {
- case ORANGE -> Color.rgb(223, 76, 17);
- case BLUE -> Color.rgb(42, 155, 179);
- case PURPLE -> Color.rgb(65, 20, 42);
- case YELLOW -> Color.rgb(248, 201, 57);
- case WHITE -> Color.rgb(232, 232, 231);
- // aggiungi i tuoi valori reali
- default -> Color.GRAY;
- };
- }
private void renderSlotMap() {
int i = 0;
@@ -553,61 +537,33 @@ public class MainFXMLController {
myHand.setAlignment(Pos.CENTER);
Player me = controller.miniModel.players.get(controller.myUsername);
- drawMyHandList(me.artists,myHand);
- drawMyHandList(me.gatherers,myHand);
- drawMyHandList(me.inventors,myHand);
- drawMyHandList(me.builders,myHand);
- drawMyHandList(me.shamans,myHand);
- drawMyHandList(me.hunters,myHand);
- drawMyHandList(me.buildingCards,myHand);
+ drawMyHandList(me.artists);
+ drawMyHandList(me.gatherers);
+ drawMyHandList(me.inventors);
+ drawMyHandList(me.builders);
+ drawMyHandList(me.shamans);
+ drawMyHandList(me.hunters);
+ drawMyHandList(me.buildingCards);
}
private void renderSidePanel() {
- sidePanel.getChildren().clear();
- sidePanel.setSpacing(6);
-
- era.setText(Integer.toString(controller.miniModel.currentState.getEra()));
- round.setText(Integer.toString(controller.miniModel.currentState.getRound()));
- player.setText(controller.miniModel.currentState.getCurrentPlayer().getUserName());
- VBox.setMargin(info, new Insets(5, 5, 5, 5));
- sidePanel.getChildren().add(info);
-
- HBox buttonRow = new HBox(8);
- buttonRow.setAlignment(Pos.CENTER);
- VBox.setMargin(buttonRow, new Insets(0, 5, 5, 5));
-
- javafx.scene.control.Button skipBtn = new javafx.scene.control.Button("Skip Turn");
- skipBtn.getStyleClass().add("action-button");
+ infoText.setText("Round: "+Integer.toString(controller.miniModel.currentState.getRound()) + " • " + controller.miniModel.currentState.getGameStage().toString());
skipBtn.setOnAction(e -> controller.skipTurn(controller.myUsername));
- addHoverZoom(skipBtn);
-
- javafx.scene.control.Button detailsBtn = new javafx.scene.control.Button("Ending Details");
- detailsBtn.getStyleClass().add("action-button");
detailsBtn.setOnAction(e -> openDetailsPopup());
+
+ addHoverZoom(skipBtn);
addHoverZoom(detailsBtn);
- buttonRow.getChildren().addAll(skipBtn, detailsBtn);
- sidePanel.getChildren().add(buttonRow);
-
- // ← VBox separato solo per i player
- VBox playerList = new VBox(6);
+ VBox playerList = new VBox();
playerList.setFillWidth(true);
for (Player p : controller.miniModel.players.values()) {
- renderPlayer(p, playerList); // ← passa playerList invece di sidePanel
+ renderPlayer(p, playerList);
}
-
- ScrollPane scrollPane = new ScrollPane(playerList);
- scrollPane.setFitToWidth(true);
- scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
- scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
- scrollPane.setStyle("-fx-background: transparent; -fx-background-color: transparent;");
- VBox.setVgrow(scrollPane, Priority.ALWAYS);
-
- sidePanel.getChildren().add(scrollPane);
+ playerSide.setContent(playerList);
}
// ==== POPUP ====
- private void initPopup() {
+ public void initPopup() {
popupCards = new HBox(10);
popupCards.setAlignment(Pos.CENTER);
popupCards.setPadding(new Insets(10));
@@ -619,10 +575,8 @@ public class MainFXMLController {
"-fx-background-radius: 10;"
);
- popup = new Popup();
popup.getContent().add(popupCards);
- popup.setAutoHide(false); // gestito manualmente per permettere click sulle carte
-
+ popup.setAutoHide(false);
popup.addEventHandler(Event.ANY, e -> {
if (popup.getScene() != null) {
popup.getScene().setFill(Color.TRANSPARENT);
@@ -676,6 +630,7 @@ public class MainFXMLController {
}
showPopup();
}
+
private void openDetailsPopup() {
popupCards.getChildren().clear();
ImageView img = new ImageView(loadImage("/GUIImages/Backs/back-118.png"));
diff --git a/src/main/java/it/polimi/ingsw/gc14/View/IView.java b/src/main/java/it/polimi/ingsw/gc14/View/IView.java
index f10b639..dc0aaa4 100644
--- a/src/main/java/it/polimi/ingsw/gc14/View/IView.java
+++ b/src/main/java/it/polimi/ingsw/gc14/View/IView.java
@@ -7,7 +7,6 @@ import it.polimi.ingsw.gc14.Network.NetworkEvent;
public interface IView {
public void setModel(MiniModel miniModel);
public void render();
- public void applyAndRender(NetworkEvent event);
public void showMessage(String message);
public void showError(String message);
diff --git a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java
index c79faa7..6b318fa 100644
--- a/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java
+++ b/src/main/java/it/polimi/ingsw/gc14/View/TUI/TUI.java
@@ -59,10 +59,6 @@ public class TUI implements IView {
this.model = model;
this.username = "";
}
- public void applyAndRender(NetworkEvent event) {
- event.apply(model);
- render();
- }
/**
* Sets the username of the local player.
diff --git a/src/main/resources/GUIScene/login.fxml b/src/main/resources/GUIScene/login.fxml
index ba313ff..b350965 100644
--- a/src/main/resources/GUIScene/login.fxml
+++ b/src/main/resources/GUIScene/login.fxml
@@ -6,7 +6,6 @@
diff --git a/src/main/resources/GUIScene/main.fxml b/src/main/resources/GUIScene/main.fxml
index ebae488..324e2ef 100644
--- a/src/main/resources/GUIScene/main.fxml
+++ b/src/main/resources/GUIScene/main.fxml
@@ -4,15 +4,16 @@
+
+
-
+
-
+
@@ -48,8 +49,7 @@
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/GUIScene/styles.css b/src/main/resources/GUIScene/styles.css
index ca40b10..84733f9 100644
--- a/src/main/resources/GUIScene/styles.css
+++ b/src/main/resources/GUIScene/styles.css
@@ -43,14 +43,8 @@
}
.frame {
- -fx-background-color:
- #8B6914,
- #FFF8DC,
- #8B6914,
- #FFF8DC;
- -fx-background-insets: 0, 5, 10, 15;
- -fx-background-radius: 15, 12, 8, 4;
- -fx-padding: 15 15 15 15;
+ -fx-background-color: rgba(255,255,255,0.35);
+ -fx-background-radius: 15 15 0 0;
}
.action-button {
diff --git a/src/main/resources/GUIScene/totem.fxml b/src/main/resources/GUIScene/totem.fxml
index 40ca776..a251f71 100644
--- a/src/main/resources/GUIScene/totem.fxml
+++ b/src/main/resources/GUIScene/totem.fxml
@@ -9,7 +9,6 @@