diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index bfd05391..f7dcbe30 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -437,6 +437,7 @@ public class GameState implements Runnable { } if (hasProgressed) { + yacht.incrementLegNumber(); sendMarkRoundingMessage(yacht); logMarkRounding(yacht); yacht.setHasPassedLine(false); diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index 90d09413..fc4649fd 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -227,7 +227,8 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { for (Player player : GameState.getPlayers()) { ServerYacht y = player.getYacht(); - BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(), 0, + BoatSubMessage m = new BoatSubMessage(y.getSourceId(), y.getBoatStatus(), + y.getLegNumber(), 0, 0, 1234L, 1234L); boatSubMessages.add(m); diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index ff544482..3a609024 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -31,13 +31,13 @@ public class ClientYacht extends Observable { private Logger logger = LoggerFactory.getLogger(ClientYacht.class); - //BOTH AFAIK private String boatType; private Integer sourceId; private String hullID; //matches HullNum in the XML spec. private String shortName; private String boatName; private String country; + private Integer position; private Long estimateTimeAtFinish; private Boolean sailIn = true; @@ -50,7 +50,6 @@ public class ClientYacht extends Observable { private Integer boatStatus; private Double currentVelocity; - //CLIENT SIDE private List locationListeners = new ArrayList<>(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); @@ -189,6 +188,14 @@ public class ClientYacht extends Observable { return location; } + public Integer getPosition() { + return position; + } + + public void setPosition(Integer position) { + this.position = position; + } + public void toggleSail() { sailIn = !sailIn; } diff --git a/src/main/java/seng302/model/RaceState.java b/src/main/java/seng302/model/RaceState.java index d4e71971..2bb60220 100644 --- a/src/main/java/seng302/model/RaceState.java +++ b/src/main/java/seng302/model/RaceState.java @@ -2,7 +2,13 @@ package seng302.model; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Observable; import java.util.TimeZone; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import seng302.model.stream.parser.RaceStartData; import seng302.model.stream.parser.RaceStatusData; @@ -21,8 +27,10 @@ public class RaceState { private long expectedStartTime; private boolean isRaceStarted = false; long timeTillStart; + private ObservableList playerPositions; public RaceState() { + playerPositions = FXCollections.observableArrayList(); } public void updateState (RaceStatusData data) { @@ -69,4 +77,17 @@ public class RaceState { public boolean isRaceStarted () { return isRaceStarted; } + + public void setBoats(Collection clientYachts) { + playerPositions.setAll(clientYachts); + } + + public void sortPlayers() { + playerPositions.sort((yacht1, yacht2) -> Integer.compare(yacht2.getLegNumber(), + yacht1.getLegNumber())); + } + + public ObservableList getPlayerPositions() { + return playerPositions; + } } diff --git a/src/main/java/seng302/model/ServerYacht.java b/src/main/java/seng302/model/ServerYacht.java index 40721137..296f731f 100644 --- a/src/main/java/seng302/model/ServerYacht.java +++ b/src/main/java/seng302/model/ServerYacht.java @@ -40,6 +40,7 @@ public class ServerYacht extends Observable { private Double currentVelocity; private Boolean isAuto; private Double autoHeading; + private Integer legNumber; //Mark Rounding private Integer currentMarkSeqID; @@ -65,6 +66,7 @@ public class ServerYacht extends Observable { this.heading = 120.0; //In degrees this.currentVelocity = 0d; //in mms-1 this.currentMarkSeqID = 0; + this.legNumber = 0; this.hasEnteredRoundingZone = false; this.hasPassedLine = false; @@ -381,5 +383,12 @@ public class ServerYacht extends Observable { return hasPassedLine; } + public void incrementLegNumber() { + legNumber++; + } + + public Integer getLegNumber() { + return legNumber; + } } diff --git a/src/main/java/seng302/utilities/StreamParser.java b/src/main/java/seng302/utilities/StreamParser.java index 304b105d..dccc3ccb 100644 --- a/src/main/java/seng302/utilities/StreamParser.java +++ b/src/main/java/seng302/utilities/StreamParser.java @@ -95,13 +95,8 @@ public class StreamParser { boatID = bytesToLong( Arrays.copyOfRange(payload, 24 + (i * 20), 28 + (i * 20))); boatStatus = (int) payload[28 + (i * 20)]; - -// setBoatLegPosition(boat, (int) payload[29 + (i * 20)]); -// boat.setPenaltiesAwarded((int) payload[30 + (i * 20)]); -// boat.setPenaltiesServed((int) payload[31 + (i * 20)]); estTimeAtNextMark = bytesToLong( Arrays.copyOfRange(payload, 32 + (i * 20), 38 + (i * 20))); -// boat.setEstimateTimeTillNextMark(estTimeAtNextMark); estTimeAtFinish = bytesToLong( Arrays.copyOfRange(payload, 38 + (i * 20), 44 + (i * 20))); leg = (int) payload[29 + (i * 20)]; diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 22559ce8..eb25e53a 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -15,6 +15,7 @@ import javafx.scene.layout.Pane; import seng302.gameServer.GameState; import seng302.gameServer.MainServerThread; import seng302.gameServer.server.messages.BoatAction; +import seng302.gameServer.server.messages.BoatStatus; import seng302.model.ClientYacht; import seng302.model.RaceState; import seng302.model.stream.packets.StreamPacket; @@ -27,6 +28,7 @@ import seng302.model.stream.xml.parser.RaceXMLData; import seng302.model.stream.xml.parser.RegattaXMLData; import seng302.utilities.StreamParser; import seng302.utilities.XMLParser; +import seng302.visualiser.controllers.FinishScreenViewController; import seng302.visualiser.controllers.LobbyController; import seng302.visualiser.controllers.LobbyController.CloseStatus; import seng302.visualiser.controllers.RaceViewController; @@ -195,6 +197,9 @@ public class GameClient { } catch (IOException e) { e.printStackTrace(); } + + FinishScreenViewController controller = fxmlLoader.getController(); + controller.setFinishers(raceState.getPlayerPositions()); } private void parsePackets() { @@ -239,6 +244,7 @@ public class GameClient { allBoatsMap.forEach((id, boat) -> clientLobbyList.add(id + " " + boat.getBoatName()) ); + raceState.setBoats(allBoatsMap.values()); break; case RACE_START_STATUS: @@ -315,32 +321,34 @@ public class GameClient { } boolean raceFinished = true; for (ClientYacht yacht : allBoatsMap.values()) { - if (yacht.getBoatStatus() != 3) { + if (yacht.getBoatStatus() != BoatStatus.FINISHED.getCode()) { raceFinished = false; } } - if (raceFinished == true) { - close(); - loadFinishScreenView(); - } for (long[] boatData : data.getBoatData()) { ClientYacht clientYacht = allBoatsMap.get((int) boatData[0]); clientYacht.setEstimateTimeTillNextMark(raceState.getRaceTime() - boatData[1]); clientYacht.setEstimateTimeAtFinish(boatData[2]); int legNumber = (int) boatData[3]; - clientYacht.setLegNumber(legNumber); clientYacht.setBoatStatus((int) boatData[4]); if (legNumber != clientYacht.getLegNumber()) { - int placing = 1; - for (ClientYacht otherClientYacht : allBoatsMap.values()) { - if (otherClientYacht.getSourceId() != boatData[0] && - clientYacht.getLegNumber() <= otherClientYacht.getLegNumber()) - placing++; - } - clientYacht.setPositionInteger(placing); + clientYacht.setLegNumber(legNumber); + updatePlayerPositions(); } } + + if (raceFinished) { + close(); + loadFinishScreenView(); + } + } + } + + private void updatePlayerPositions() { + raceState.sortPlayers(); + for (ClientYacht yacht : raceState.getPlayerPositions()) { + yacht.setPosition(raceState.getPlayerPositions().indexOf(yacht) + 1); } } diff --git a/src/main/java/seng302/visualiser/controllers/FinishScreenViewController.java b/src/main/java/seng302/visualiser/controllers/FinishScreenViewController.java index a4dc831b..bf518d29 100644 --- a/src/main/java/seng302/visualiser/controllers/FinishScreenViewController.java +++ b/src/main/java/seng302/visualiser/controllers/FinishScreenViewController.java @@ -3,6 +3,7 @@ package seng302.visualiser.controllers; import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.ResourceBundle; @@ -61,7 +62,7 @@ public class FinishScreenViewController implements Initializable { finishOrderTable.refresh(); } - public void setFinishers(List participants) { + public void setFinishers(Collection participants) { List sorted = new ArrayList<>(participants); sorted.sort(Comparator.comparingInt(ClientYacht::getPositionInteger)); finishOrderTable.getItems().setAll(sorted); diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index f2afd3e3..f0bf2688 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -11,6 +11,8 @@ import java.util.concurrent.TimeUnit; import javafx.animation.Timeline; import javafx.application.Platform; import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Point2D; @@ -117,6 +119,15 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel initialiseBoatSelectionComboBox(); initialiseSparkLine(); + raceState.getPlayerPositions().addListener((ListChangeListener) c -> { + while (c.next()) { + if (c.wasPermutated()) { + updateOrder(raceState.getPlayerPositions()); + } + } + }); + + updateOrder(raceState.getPlayerPositions()); gameView = new GameView(); gameView.setFrameRateFXText(fpsDisplay); Platform.runLater(() -> contentAnchorPane.getChildren().add(0, gameView)); @@ -318,7 +329,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel public void run() { updateRaceTime(); updateWind(); - updateOrder(); // updateSparkLine(); } }, 0, 1000); @@ -381,26 +391,20 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel * Updates the order of the yachts as from the StreamParser and sets them in the yacht order * section */ - private void updateOrder() { -// positionVbox.getChildren().removeAll(); -// positionVbox.getStylesheets().add(getClass().getResource("/css/master.css").toString()); - - // list of racing yacht id - List sorted = new ArrayList<>(participants.values()); - sorted.sort(Comparator.comparingInt(ClientYacht::getPositionInteger)); + private void updateOrder(ObservableList yachts) { List vboxEntries = new ArrayList<>(); - for (ClientYacht clientYacht : sorted) { + for (int i = 0; i < yachts.size(); i++) { // System.out.println("yacht == null " + String.valueOf(yacht == null)); - if (clientYacht.getBoatStatus() == 3) { // 3 is finish status - Text textToAdd = new Text(clientYacht.getPositionInteger() + ". " + - clientYacht.getShortName() + " (Finished)"); + if (yachts.get(i).getBoatStatus() == 3) { // 3 is finish status + Text textToAdd = new Text(i + 1 + ". " + + yachts.get(i).getShortName() + " (Finished)"); textToAdd.setFill(Paint.valueOf("#d3d3d3")); vboxEntries.add(textToAdd); } else { - Text textToAdd = new Text(clientYacht.getPositionInteger() + ". " + - clientYacht.getShortName() + " "); + Text textToAdd = new Text(i + 1 + ". " + + yachts.get(i).getShortName() + " "); textToAdd.setFill(Paint.valueOf("#d3d3d3")); textToAdd.setStyle(""); vboxEntries.add(textToAdd);