From 78596ea111c5ed027eb232bffb9e6808400786f2 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 19 Sep 2017 17:47:05 +1200 Subject: [PATCH 01/21] Initial commit for Power Up story Made new preliminary models for each power up. Currently just different colour balls Added new YachtEventTypes in the enum for each pick up to be sent out to clients Tokens now not only randomise location but also randomise which type of token will be sent out Added new methods to the MessageFactory class - Make collision and Make pickup Message Game Client now checks what type of Yacht Event code has come in to respond appropriately rather than just generic collision / token.. although this has not been implemented yet Game View loads appropriate token models depending on what is in XML #story[1245] --- .../java/seng302/gameServer/GameState.java | 27 +- .../seng302/gameServer/MessageFactory.java | 29 ++ .../gameServer/messages/YachtEventType.java | 6 +- src/main/java/seng302/model/token/Token.java | 4 + .../java/seng302/model/token/TokenType.java | 15 +- .../java/seng302/visualiser/GameClient.java | 31 +- .../java/seng302/visualiser/GameView3D.java | 23 +- .../fxObjects/assets_3D/ModelFactory.java | 22 +- .../fxObjects/assets_3D/ModelType.java | 4 + src/main/resources/meshes/bumper_pickup.dae | 147 ++++++++ src/main/resources/meshes/random_pickup.dae | 332 ++++++++++++++++++ src/main/resources/meshes/turning_pickup.dae | 147 ++++++++ .../resources/meshes/wind_walker_pickup.dae | 147 ++++++++ src/main/resources/views/RaceView.fxml | 2 +- 14 files changed, 900 insertions(+), 36 deletions(-) create mode 100644 src/main/resources/meshes/bumper_pickup.dae create mode 100644 src/main/resources/meshes/random_pickup.dae create mode 100644 src/main/resources/meshes/turning_pickup.dae create mode 100644 src/main/resources/meshes/wind_walker_pickup.dae diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 0b495a8e..c5317fa6 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -281,7 +281,13 @@ public class GameState implements Runnable { public static void spawnNewToken() { Random random = new Random(); tokensInPlay.clear(); - tokensInPlay.add(allTokens.get(random.nextInt(allTokens.size()))); + + //Get a random token location + Token token = allTokens.get(random.nextInt(allTokens.size())); + //Set a random type to this token + token.setTokenType(TokenType.values()[random.nextInt(TokenType.values().length)]); + + tokensInPlay.add(token); } /** @@ -397,9 +403,7 @@ public class GameState implements Runnable { collidedYacht.setCurrentVelocity( collidedYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY ); - notifyMessageListeners( - new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION) - ); + notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht)); } //Mark Collision @@ -411,9 +415,7 @@ public class GameState implements Runnable { serverYacht.setCurrentVelocity( serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY ); - notifyMessageListeners( - new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION) - ); + notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht)); } //Boundary Collision @@ -426,22 +428,21 @@ public class GameState implements Runnable { serverYacht.setCurrentVelocity( serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY ); - notifyMessageListeners( - new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION) - ); + notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht)); } //Token Collision Token collidedToken = checkTokenPickUp(serverYacht); if (collidedToken != null) { - sendServerMessage(serverYacht.getSourceId(), serverYacht.getBoatName() + " has picked speed-up token"); + sendServerMessage(serverYacht.getSourceId(), + serverYacht.getBoatName() + " has picked up a " + collidedToken.getTokenType() + .getName() + " token"); tokensInPlay.remove(collidedToken); serverYacht.powerUp(collidedToken.getTokenType()); logger.debug("Yacht: " + serverYacht.getShortName() + " got powerup " + collidedToken .getTokenType()); notifyMessageListeners(MessageFactory.getRaceXML()); - notifyMessageListeners( - new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.TOKEN)); + notifyMessageListeners(MessageFactory.makePickupMessage(serverYacht, collidedToken)); } } diff --git a/src/main/java/seng302/gameServer/MessageFactory.java b/src/main/java/seng302/gameServer/MessageFactory.java index a71733cf..2ef38d29 100644 --- a/src/main/java/seng302/gameServer/MessageFactory.java +++ b/src/main/java/seng302/gameServer/MessageFactory.java @@ -11,11 +11,14 @@ import seng302.gameServer.messages.RaceStatusMessage; import seng302.gameServer.messages.RaceType; import seng302.gameServer.messages.XMLMessage; import seng302.gameServer.messages.XMLMessageSubType; +import seng302.gameServer.messages.YachtEventCodeMessage; +import seng302.gameServer.messages.YachtEventType; import seng302.model.Player; import seng302.model.ServerYacht; import seng302.model.stream.xml.generator.RaceXMLTemplate; import seng302.model.stream.xml.generator.RegattaXMLTemplate; import seng302.model.token.Token; +import seng302.model.token.TokenType; import seng302.utilities.XMLGenerator; /** @@ -128,4 +131,30 @@ public class MessageFactory { XMLMessageSubType.BOAT, xmlGenerator.getBoatsAsXml().length()); } + + public static YachtEventCodeMessage makeCollisionMessage(ServerYacht serverYacht) { + return new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION); + } + + public static YachtEventCodeMessage makePickupMessage(ServerYacht serverYacht, Token token) { + YachtEventType yachtEventType = null; + switch (token.getTokenType()) { + case BOOST: + yachtEventType = YachtEventType.TOKEN_VELOCITY; + break; + case HANDLING: + yachtEventType = YachtEventType.TOKEN_HANDLING; + break; + case WIND_WALKER: + yachtEventType = YachtEventType.TOKEN_WIND_WALKER; + break; + case BUMPER: + yachtEventType = YachtEventType.TOKEN_BUMPER; + break; + case RANDOM: + yachtEventType = YachtEventType.TOKEN_RANDOM; + break; + } + return new YachtEventCodeMessage(serverYacht.getSourceId(), yachtEventType); + } } diff --git a/src/main/java/seng302/gameServer/messages/YachtEventType.java b/src/main/java/seng302/gameServer/messages/YachtEventType.java index b31d45a1..c8a997a0 100644 --- a/src/main/java/seng302/gameServer/messages/YachtEventType.java +++ b/src/main/java/seng302/gameServer/messages/YachtEventType.java @@ -5,7 +5,11 @@ package seng302.gameServer.messages; */ public enum YachtEventType { COLLISION(33), - TOKEN(34); + TOKEN_VELOCITY(34), + TOKEN_BUMPER(35), + TOKEN_HANDLING(36), + TOKEN_WIND_WALKER(37), + TOKEN_RANDOM(38); private int code; diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index 9f8ca619..56536da3 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -18,4 +18,8 @@ public class Token extends GeoPoint { public TokenType getTokenType() { return tokenType; } + + public void setTokenType(TokenType tokenType) { + this.tokenType = tokenType; + } } diff --git a/src/main/java/seng302/model/token/TokenType.java b/src/main/java/seng302/model/token/TokenType.java index d5c2df01..e85c6bec 100644 --- a/src/main/java/seng302/model/token/TokenType.java +++ b/src/main/java/seng302/model/token/TokenType.java @@ -5,19 +5,28 @@ package seng302.model.token; * Created by wmu16 on 28/08/17. */ public enum TokenType { - BOOST(0), - HANDLING(1); + BOOST(0, "Boost"), + HANDLING(1, "Handling"), + BUMPER(2, "Bumper"), + RANDOM(3, "Random"), + WIND_WALKER(4, "Wind Walker"); private int value; + private String name; - TokenType(int value) { + TokenType(int value, String name) { this.value = value; + this.name = name; } public int getValue() { return value; } + public String getName() { + return name; + } + public static TokenType getToken(int value) { switch (value) { case 0: diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 7040d7ee..5cab5040 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -245,12 +245,7 @@ public class GameClient { break; case YACHT_EVENT_CODE: - YachtEventData yachtEventData = StreamParser.extractYachtEventCode(packet); - if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { - showCollisionAlert(StreamParser.extractYachtEventCode(packet)); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN.getCode()) { - showPickUp(); - } + displayYachtEvent(StreamParser.extractYachtEventCode(packet)); break; case CHATTER_TEXT: @@ -407,6 +402,28 @@ public class GameClient { return courseData; } + + /** + * Appropriately displays the event client side given the YachtEventCode (collision / token..) + * + * @param yachtEventData The YachtEvent data packet + */ + private void displayYachtEvent(YachtEventData yachtEventData) { + if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { + showCollisionAlert(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { + showPickUp(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) { + showPickUp(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) { + showPickUp(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) { + showPickUp(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) { + showPickUp(yachtEventData); + } + } + /** * Tells race view to show a collision animation. */ @@ -420,7 +437,7 @@ public class GameClient { } // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user - private void showPickUp() { + private void showPickUp(YachtEventData yachtEventData) { Sounds.playTokenPickupSound(); } diff --git a/src/main/java/seng302/visualiser/GameView3D.java b/src/main/java/seng302/visualiser/GameView3D.java index c5b52286..6af253c9 100644 --- a/src/main/java/seng302/visualiser/GameView3D.java +++ b/src/main/java/seng302/visualiser/GameView3D.java @@ -27,6 +27,7 @@ import seng302.model.mark.CompoundMark; import seng302.model.mark.Corner; import seng302.model.mark.Mark; import seng302.model.token.Token; +import seng302.model.token.TokenType; import seng302.utilities.GeoUtility; import seng302.utilities.Sounds; import seng302.visualiser.fxObjects.MarkArrowFactory; @@ -556,7 +557,27 @@ public class GameView3D { mapTokens = new ArrayList<>(); for (Token token : newTokens) { Point2D location = findScaledXY(token.getLat(), token.getLng()); - Node tokenObject = ModelFactory.importModel(ModelType.VELOCITY_PICKUP).getAssets(); + + ModelType modelType = null; + switch (token.getTokenType()) { + case BOOST: + modelType = ModelType.VELOCITY_PICKUP; + break; + case HANDLING: + modelType = ModelType.HANDLING_PICKUP; + break; + case BUMPER: + modelType = ModelType.BUMPER_PICKUP; + break; + case RANDOM: + modelType = ModelType.RANDOM_PICKUP; + break; + case WIND_WALKER: + modelType = ModelType.WIND_WALKER_PICKUP; + break; + } + + Node tokenObject = ModelFactory.importModel(modelType).getAssets(); tokenObject.setLayoutX(location.getX()); tokenObject.setLayoutY(location.getY()); mapTokens.add(tokenObject); diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java index f0c50abe..8d7ecadf 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelFactory.java @@ -118,7 +118,11 @@ public class ModelFactory { } switch (tokenType) { case VELOCITY_PICKUP: - return makeCoinPickup(assets); + case BUMPER_PICKUP: + case RANDOM_PICKUP: + case HANDLING_PICKUP: + case WIND_WALKER_PICKUP: + return makeTokenPickup(assets); case FINISH_MARKER: case PLAIN_MARKER: case START_MARKER: @@ -147,24 +151,22 @@ public class ModelFactory { } } - private static Model makeCoinPickup(Group assets){ - assets.setRotationAxis(new Point3D(1,0,0)); - assets.setRotate(90); - assets.setTranslateX(0.2); - assets.setTranslateY(1); + private static Model makeTokenPickup(Group assets) { + Rotate animationRotate = new Rotate(0, new Point3D(0, 0, 1)); assets.getTransforms().addAll( - new Translate(0,-1,0), - new Rotate(0 ,new Point3D(1,1,1)) + animationRotate, + new Translate(0, 0, -1) ); + return new Model(new Group(assets), new AnimationTimer() { private double rotation = 0; - private Group group = assets; + private Rotate rotate = animationRotate; @Override public void handle(long now) { rotation += 1; - ((Rotate) group.getTransforms().get(1)).setAngle(rotation); + rotate.setAngle(rotation); } }); } diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelType.java b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelType.java index 1c31a553..06df2eda 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelType.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_3D/ModelType.java @@ -7,6 +7,10 @@ package seng302.visualiser.fxObjects.assets_3D; public enum ModelType { VELOCITY_PICKUP("velocity_pickup.dae"), + HANDLING_PICKUP("turning_pickup.dae"), + WIND_WALKER_PICKUP("wind_walker_pickup.dae"), + BUMPER_PICKUP("bumper_pickup.dae"), + RANDOM_PICKUP("random_pickup.dae"), FINISH_MARKER ("finish_marker.dae"), START_MARKER ("start_marker.dae"), PLAIN_MARKER ("plain_marker.dae"), diff --git a/src/main/resources/meshes/bumper_pickup.dae b/src/main/resources/meshes/bumper_pickup.dae new file mode 100644 index 00000000..efc8503f --- /dev/null +++ b/src/main/resources/meshes/bumper_pickup.dae @@ -0,0 +1,147 @@ + + + + + Blender User + Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22 + + 2017-09-19T15:47:50 + 2017-09-19T15:47:50 + + Z_UP + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 6.87021e-4 0 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + + + + 0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544 + + + + + + + + + + 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 + + + + + + + + + + 0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239

+
+
+
+
+ + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/meshes/random_pickup.dae b/src/main/resources/meshes/random_pickup.dae new file mode 100644 index 00000000..56d830fc --- /dev/null +++ b/src/main/resources/meshes/random_pickup.dae @@ -0,0 +1,332 @@ + + + + + Blender User + Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22 + + 2017-09-19T15:54:38 + 2017-09-19T15:54:38 + + Z_UP + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.8 0.6035923 0 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.8 0.1522076 0 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.01023849 0.004662884 0.64 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0 0.2456551 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 8.07677e-5 0.64 0 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0 0.005309466 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5350354 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8183268 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8183217 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544 + + + + + + + + + + 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.570192 0.7464457 -0.3430743 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.6991799 0.2635454 0.6645987 0.05184978 0.746441 0.6634285 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.185151 0.569826 0.8006358 -0.4685443 0.5765037 0.6694099 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.009833872 0.9466192 0.3222044 -0.2904988 0.9398801 0.1795436 -0.5345759 0.7778646 0.3303867 -0.9071158 0.2635452 0.3281539 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7989099 0.5698285 -0.1924537 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.2925817 0.9466192 -0.1353079 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.8082743 0.5765079 0.1197141 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 + + + + + + + + + + 0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

36 12 36 9 12 37 41 12 38 35 14 42 8 14 43 40 14 44 34 16 48 7 16 49 39 16 50 33 18 54 6 18 55 37 18 56 32 20 60 10 20 61 38 20 62 30 23 69 9 23 70 36 23 71 28 26 78 8 26 79 35 26 80 26 29 87 7 29 88 34 29 89 24 32 96 6 32 97 33 32 98 22 35 105 10 35 106 32 35 107 16 47 141 19 47 142 21 47 143 19 50 150 17 50 151 20 50 152 17 53 159 12 53 160 18 53 161 15 56 168 13 56 169 16 56 170 12 58 174 13 58 175 14 58 176

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 +

23 22 66 30 22 67 36 22 68 31 25 75 28 25 76 35 25 77 29 28 84 26 28 85 34 28 86 27 31 93 24 31 94 33 31 95 25 34 102 22 34 103 32 34 104 30 36 108 21 36 109 31 36 110 28 38 114 20 38 115 29 38 116 26 40 120 18 40 121 27 40 122 24 42 126 14 42 127 25 42 128 22 44 132 15 44 133 23 44 134

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 +

6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 23 21 63 36 21 64 10 21 65 31 24 72 35 24 73 9 24 74 29 27 81 34 27 82 8 27 83 27 30 90 33 30 91 7 30 92 25 33 99 32 33 100 6 33 101

+
+ + + + + 3 3 3 3 3 +

38 11 33 36 11 34 41 11 35 41 13 39 35 13 40 40 13 41 40 15 45 34 15 46 39 15 47 39 17 51 33 17 52 37 17 53 37 19 57 32 19 58 38 19 59

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 +

1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 16 46 138 21 46 139 5 46 140 19 49 147 20 49 148 4 49 149 17 52 156 18 52 157 3 52 158 12 57 171 14 57 172 2 57 173

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 +

21 37 111 4 37 112 31 37 113 20 39 117 3 39 118 29 39 119 18 41 123 2 41 124 27 41 125 14 43 129 1 43 130 25 43 131 15 45 135 5 45 136 23 45 137 19 48 144 4 48 145 21 48 146 17 51 153 3 51 154 20 51 155 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 13 59 177 1 59 178 14 59 179

+
+
+
+
+ + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/meshes/turning_pickup.dae b/src/main/resources/meshes/turning_pickup.dae new file mode 100644 index 00000000..2c4305f5 --- /dev/null +++ b/src/main/resources/meshes/turning_pickup.dae @@ -0,0 +1,147 @@ + + + + + Blender User + Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22 + + 2017-09-19T15:45:46 + 2017-09-19T15:45:46 + + Z_UP + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.004555753 0.0885511 0.003947978 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.1458963 0.001825521 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + + + + 0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544 + + + + + + + + + + 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 + + + + + + + + + + 0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239

+
+
+
+
+ + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/meshes/wind_walker_pickup.dae b/src/main/resources/meshes/wind_walker_pickup.dae new file mode 100644 index 00000000..62292f0e --- /dev/null +++ b/src/main/resources/meshes/wind_walker_pickup.dae @@ -0,0 +1,147 @@ + + + + + Blender User + Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22 + + 2017-09-19T15:46:34 + 2017-09-19T15:46:34 + + Z_UP + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.03920602 0.04758029 0.8 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.5287738 0.5454956 1 + + + 0.25 0.25 0.25 1 + + + 50 + + + 1 + + + + + + + + + + + + + + + + + + + 0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544 + + + + + + + + + + 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 + + + + + + + + + + 0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239 + + + + + + + + + + + + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179

+
+ + + + + 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 +

0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239

+
+
+
+
+ + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index fba9bb27..a2c22e09 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -16,7 +16,7 @@ From 52d3cea592b487ea4af368ec50ee3af4367bfd98 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 19 Sep 2017 23:04:17 +1200 Subject: [PATCH 02/21] Added preliminary icons for pickups RaceView now has a grid pane to contain some icons to display power ups. These are just preliminary ClientYacht now has a power up field that is set from recieveing messages in the Game Client, as well as observed by the RaceViewController to display the relevant icon when the powerup field is changed #story[1245] --- .../java/seng302/gameServer/GameState.java | 4 +- src/main/java/seng302/model/ClientYacht.java | 27 ++++++++ .../java/seng302/visualiser/GameClient.java | 33 ++++++---- .../controllers/RaceViewController.java | 29 +++++++++ src/main/resources/views/RaceView.fxml | 61 +++++++++++++++++++ 5 files changed, 139 insertions(+), 15 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index c5317fa6..be7039fa 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -47,6 +47,7 @@ public class GameState implements Runnable { private static final Double BOUNCE_DISTANCE_MARK = 20.0; public static final Double BOUNCE_DISTANCE_YACHT = 30.0; private static final Double COLLISION_VELOCITY_PENALTY = 0.3; + private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static Long previousUpdateTime; public static Double windDirection; @@ -453,8 +454,7 @@ public class GameState implements Runnable { Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier; if (yacht.getPowerUp() != null) { if (yacht.getPowerUp().equals(TokenType.BOOST)) { - // TODO: 11/09/17 wmu16 CHANGE THIS TO MAGIC NUMBER - maxBoatSpeed *= 2; + maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER; } } diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index 89715852..b1996333 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -12,9 +12,13 @@ import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.ReadOnlyLongProperty; import javafx.beans.property.ReadOnlyLongWrapper; +import javafx.beans.value.ObservableObjectValue; +import javafx.collections.FXCollections; import javafx.scene.paint.Color; +import jdk.nashorn.internal.objects.annotations.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import seng302.model.token.TokenType; /** * Yacht class for the racing boat.

Class created to store more variables (eg. boat statuses) @@ -34,6 +38,12 @@ public class ClientYacht extends Observable { void notifyRounding(ClientYacht yacht, int legNumber); } + @FunctionalInterface + public interface PowerUpListener { + + void notifyPowerUp(ClientYacht yacht, TokenType tokenType); + } + private Logger logger = LoggerFactory.getLogger(ClientYacht.class); @@ -44,6 +54,7 @@ public class ClientYacht extends Observable { private String boatName; private String country; private Integer position; + private TokenType powerUp; private Long estimateTimeAtFinish; private Boolean sailIn = false; @@ -58,6 +69,7 @@ public class ClientYacht extends Observable { private List locationListeners = new ArrayList<>(); private List markRoundingListeners = new ArrayList<>(); + private List powerUpListeners = new ArrayList<>(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper(); @@ -199,6 +211,17 @@ public class ClientYacht extends Observable { this.position = position; } + public void setPowerUp(TokenType tokenType) { + this.powerUp = tokenType; + for (PowerUpListener listener : powerUpListeners) { + listener.notifyPowerUp(this, tokenType); + } + } + + public TokenType getPowerUp() { + return powerUp; + } + public void toggleSail() { sailIn = !sailIn; } @@ -268,6 +291,10 @@ public class ClientYacht extends Observable { markRoundingListeners.add(listener); } + public void addPowerUpListener(PowerUpListener listener) { + powerUpListeners.add(listener); + } + public void removeMarkRoundingListener(MarkRoundingListener listener) { markRoundingListeners.remove(listener); } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 5cab5040..10a682fa 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -37,6 +37,7 @@ import seng302.model.stream.parser.RaceStatusData; import seng302.model.stream.parser.YachtEventData; import seng302.model.stream.xml.parser.RaceXMLData; import seng302.model.stream.xml.parser.RegattaXMLData; +import seng302.model.token.TokenType; import seng302.utilities.Sounds; import seng302.utilities.StreamParser; import seng302.utilities.XMLGenerator; @@ -245,7 +246,7 @@ public class GameClient { break; case YACHT_EVENT_CODE: - displayYachtEvent(StreamParser.extractYachtEventCode(packet)); + processYachtEvent(StreamParser.extractYachtEventCode(packet)); break; case CHATTER_TEXT: @@ -408,19 +409,25 @@ public class GameClient { * * @param yachtEventData The YachtEvent data packet */ - private void displayYachtEvent(YachtEventData yachtEventData) { + private void processYachtEvent(YachtEventData yachtEventData) { if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { showCollisionAlert(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) { - showPickUp(yachtEventData); - } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) { - showPickUp(yachtEventData); + } else { + TokenType tokenType = null; + if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { + tokenType = TokenType.BOOST; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) { + tokenType = TokenType.BUMPER; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) { + tokenType = TokenType.HANDLING; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) { + tokenType = TokenType.RANDOM; + } else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) { + tokenType = TokenType.WIND_WALKER; + } + + showTokenPickUp(tokenType); + allBoatsMap.get(yachtEventData.getSubjectId().intValue()).setPowerUp(tokenType); } } @@ -437,7 +444,7 @@ public class GameClient { } // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user - private void showPickUp(YachtEventData yachtEventData) { + private void showTokenPickUp(TokenType tokenType) { Sounds.playTokenPickupSound(); } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index 2ac06dfb..15c3d8ec 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -20,6 +20,8 @@ import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Point2D; +import javafx.scene.Group; +import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.SubScene; import javafx.scene.chart.LineChart; @@ -47,10 +49,12 @@ import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.stage.StageStyle; import seng302.model.ClientYacht; +import seng302.model.ClientYacht.PowerUpListener; import seng302.model.RaceState; import seng302.model.mark.CompoundMark; import seng302.model.mark.Mark; import seng302.model.stream.xml.parser.RaceXMLData; +import seng302.model.token.TokenType; import seng302.utilities.Sounds; import seng302.visualiser.GameView3D; import seng302.visualiser.controllers.annotations.ImportantAnnotationController; @@ -60,6 +64,8 @@ import seng302.visualiser.controllers.dialogs.FinishDialogController; import seng302.visualiser.fxObjects.ChatHistory; import seng302.visualiser.fxObjects.assets_2D.WindArrow; import seng302.visualiser.fxObjects.assets_3D.BoatObject; +import seng302.visualiser.fxObjects.assets_3D.ModelFactory; +import seng302.visualiser.fxObjects.assets_3D.ModelType; /** * Controller class that manages the display of a race @@ -110,6 +116,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel private Label windSpeedLabel; @FXML private Label positionLabel, boatSpeedLabel, boatHeadingLabel; + @FXML + private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon; //Race Data private Map participants; @@ -222,6 +230,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel return finishScreenDialog; } + public void loadRace ( Map participants, RaceXMLData raceData, RaceState raceState, ClientYacht player) { @@ -241,6 +250,25 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel } }); + player.addPowerUpListener((yacht, tokenType) -> { + if (yacht == player) { + switch (tokenType) { + case BOOST: + velocityIcon.setVisible(true); + break; + case HANDLING: + handlingIcon.setVisible(true); + break; + case WIND_WALKER: + windWalkerIcon.setVisible(true); + break; + case BUMPER: + bumperIcon.setVisible(true); + break; + } + } + }); + updateOrder(raceState.getPlayerPositions()); gameView = new GameView3D(); // gameView.setFrameRateFXText(fpsDisplay); @@ -279,6 +307,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel }); } + /** * The important annotations have been changed, update this view * diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index a2c22e09..03728bde 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -1,5 +1,14 @@ + + + + + + + + + @@ -14,6 +23,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6cde0164011e060d42a596e40ce96850e25184c7 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 20 Sep 2017 12:02:12 +1200 Subject: [PATCH 03/21] Fixed random token assigning and realisation Token class now has two functions: assignRandomType and realiseRandomType The former can be used to assign any random type to the token including the random type The latter can be used to assign a concrete random type to the token (not the random type) #story[1245] --- .../java/seng302/gameServer/GameState.java | 10 ++++---- src/main/java/seng302/model/token/Token.java | 23 +++++++++++++++++-- .../java/seng302/model/token/TokenType.java | 15 ++---------- .../java/seng302/visualiser/GameClient.java | 10 ++++++++ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index be7039fa..1dd9963a 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -283,10 +283,9 @@ public class GameState implements Runnable { Random random = new Random(); tokensInPlay.clear(); - //Get a random token location + //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); - //Set a random type to this token - token.setTokenType(TokenType.values()[random.nextInt(TokenType.values().length)]); + token.assignRandomType(); tokensInPlay.add(token); } @@ -389,6 +388,7 @@ public class GameState implements Runnable { //Yacht Collision ServerYacht collidedYacht = checkYachtCollision(serverYacht); Mark collidedMark = checkMarkCollision(serverYacht); + Token collidedToken = checkTokenPickUp(serverYacht); if (collidedYacht != null) { GeoPoint originalLocation = serverYacht.getLocation(); @@ -433,8 +433,10 @@ public class GameState implements Runnable { } //Token Collision - Token collidedToken = checkTokenPickUp(serverYacht); if (collidedToken != null) { + if (collidedToken.getTokenType() == TokenType.RANDOM) { + collidedToken.realiseRandom(); + } sendServerMessage(serverYacht.getSourceId(), serverYacht.getBoatName() + " has picked up a " + collidedToken.getTokenType() .getName() + " token"); diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index 56536da3..fcdbab5e 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -1,5 +1,9 @@ package seng302.model.token; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; import seng302.model.GeoPoint; /** @@ -9,6 +13,7 @@ import seng302.model.GeoPoint; public class Token extends GeoPoint { private TokenType tokenType; + private Random random = new Random(); public Token(TokenType tokenType, double lat, double lng) { super(lat, lng); @@ -19,7 +24,21 @@ public class Token extends GeoPoint { return tokenType; } - public void setTokenType(TokenType tokenType) { - this.tokenType = tokenType; + /** + * Assigns a random type to the token (including the random type token) + */ + public void assignRandomType() { + tokenType = TokenType.values()[random.nextInt(TokenType.values().length)]; } + + /** + * Assigns a random, concrete type to the token (cannot be the random type) + */ + public void realiseRandom() { + List tokenTypeList = new ArrayList<>(Arrays.asList(TokenType.values())); + tokenTypeList.remove(TokenType.RANDOM); + tokenType = tokenTypeList.get(random.nextInt(tokenTypeList.size())); + } + + } diff --git a/src/main/java/seng302/model/token/TokenType.java b/src/main/java/seng302/model/token/TokenType.java index e85c6bec..82aecc97 100644 --- a/src/main/java/seng302/model/token/TokenType.java +++ b/src/main/java/seng302/model/token/TokenType.java @@ -8,8 +8,8 @@ public enum TokenType { BOOST(0, "Boost"), HANDLING(1, "Handling"), BUMPER(2, "Bumper"), - RANDOM(3, "Random"), - WIND_WALKER(4, "Wind Walker"); + WIND_WALKER(3, "Wind Walker"), + RANDOM(4, "Random"); private int value; private String name; @@ -26,15 +26,4 @@ public enum TokenType { public String getName() { return name; } - - public static TokenType getToken(int value) { - switch (value) { - case 0: - return BOOST; - case 1: - return HANDLING; - default: - return BOOST; - } - } } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 10a682fa..9abf282a 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -446,6 +446,16 @@ public class GameClient { // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user private void showTokenPickUp(TokenType tokenType) { Sounds.playTokenPickupSound(); + switch (tokenType) { + case BOOST: + break; + case HANDLING: + break; + case WIND_WALKER: + break; + case BUMPER: + break; + } } private void formatAndSendChatMessage(String rawChat) { From 034e4c252a7347a7b888d50e7de72a4a197582a6 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 20 Sep 2017 13:09:09 +1200 Subject: [PATCH 04/21] Icons now display, blink when they are about to run off, and turn off after their time out TokenType Enum now also has a timeout construction field #story[1245] --- src/main/java/seng302/model/ClientYacht.java | 1 - .../java/seng302/model/token/TokenType.java | 19 +++-- .../controllers/RaceViewController.java | 76 ++++++++++++++----- 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index b1996333..5cedbfba 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -40,7 +40,6 @@ public class ClientYacht extends Observable { @FunctionalInterface public interface PowerUpListener { - void notifyPowerUp(ClientYacht yacht, TokenType tokenType); } diff --git a/src/main/java/seng302/model/token/TokenType.java b/src/main/java/seng302/model/token/TokenType.java index 82aecc97..8ae60dcc 100644 --- a/src/main/java/seng302/model/token/TokenType.java +++ b/src/main/java/seng302/model/token/TokenType.java @@ -5,18 +5,21 @@ package seng302.model.token; * Created by wmu16 on 28/08/17. */ public enum TokenType { - BOOST(0, "Boost"), - HANDLING(1, "Handling"), - BUMPER(2, "Bumper"), - WIND_WALKER(3, "Wind Walker"), - RANDOM(4, "Random"); + + BOOST(0, "Boost", 10_000), + HANDLING(1, "Handling", 10_000), + BUMPER(2, "Bumper", 10_000), + WIND_WALKER(3, "Wind Walker", 10_000), + RANDOM(4, "Random", 10_000); private int value; private String name; + private int timeout; - TokenType(int value, String name) { + TokenType(int value, String name, int timeout) { this.value = value; this.name = name; + this.timeout = timeout; } public int getValue() { @@ -26,4 +29,8 @@ public enum TokenType { public String getName() { return name; } + + public int getTimeout() { + return timeout; + } } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index 15c3d8ec..e45dd091 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -73,6 +73,8 @@ import seng302.visualiser.fxObjects.assets_3D.ModelType; public class RaceViewController extends Thread implements ImportantAnnotationDelegate { private final int CHAT_LIMIT = 128; + private static final Double ICON_BLINK_TIMEOUT_RATIO = 0.6; + private static final Integer ICON_BLINK_PERIOD = 500; @FXML private Pane basePane; @@ -250,24 +252,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel } }); - player.addPowerUpListener((yacht, tokenType) -> { - if (yacht == player) { - switch (tokenType) { - case BOOST: - velocityIcon.setVisible(true); - break; - case HANDLING: - handlingIcon.setVisible(true); - break; - case WIND_WALKER: - windWalkerIcon.setVisible(true); - break; - case BUMPER: - bumperIcon.setVisible(true); - break; - } - } - }); + player.addPowerUpListener(this::displayPowerUpIcon); updateOrder(raceState.getPlayerPositions()); gameView = new GameView3D(); @@ -307,6 +292,61 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel }); } + /** + * Displays the relevant icon, starts blinking it when it is close to turning off and then + * switches it off after the tokens time out + * + * @param yacht The yacht only for which we are displaying the icon + * @param tokenType The type of token, indicating what icon needs to be displayed + */ + private void displayPowerUpIcon(ClientYacht yacht, TokenType tokenType) { + if (yacht == player) { + final ImageView iconToDisplay; + + switch (tokenType) { + case BOOST: + iconToDisplay = velocityIcon; + break; + case HANDLING: + iconToDisplay = handlingIcon; + break; + case WIND_WALKER: + iconToDisplay = windWalkerIcon; + break; + case BUMPER: + iconToDisplay = bumperIcon; + break; + default: + iconToDisplay = velocityIcon; + } + + //Turn icon on + iconToDisplay.setVisible(true); + + //Start blinking icon towards end + Timer blinkingTimer = new Timer(); + blinkingTimer.schedule(new TimerTask() { + Boolean isVisible = true; + + @Override + public void run() { + isVisible = !isVisible; + iconToDisplay.setVisible(isVisible); + } + }, (int) (tokenType.getTimeout() * ICON_BLINK_TIMEOUT_RATIO), ICON_BLINK_PERIOD); + + //Turn icon off after the time out + Timer switchOffTimer = new Timer(); + switchOffTimer.schedule(new TimerTask() { + @Override + public void run() { + blinkingTimer.cancel(); + iconToDisplay.setVisible(false); + } + }, tokenType.getTimeout()); + } + } + /** * The important annotations have been changed, update this view From 66d9a06f9ef6113579d0cd82a75b408ba5b33050 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 20 Sep 2017 17:19:14 +1200 Subject: [PATCH 05/21] Adding icon files to git #story[1245] --- src/main/resources/icons/bumperIcon.png | Bin 0 -> 3580 bytes src/main/resources/icons/handlingIcon.png | Bin 0 -> 3205 bytes src/main/resources/icons/velocity.png | Bin 0 -> 4328 bytes src/main/resources/icons/windWalkerIcon.png | Bin 0 -> 3939 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/icons/bumperIcon.png create mode 100644 src/main/resources/icons/handlingIcon.png create mode 100644 src/main/resources/icons/velocity.png create mode 100644 src/main/resources/icons/windWalkerIcon.png diff --git a/src/main/resources/icons/bumperIcon.png b/src/main/resources/icons/bumperIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1da6d4cf8d72949af1b64aa7e60335804d5d7b5 GIT binary patch literal 3580 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 Date: Wed, 20 Sep 2017 17:52:02 +1200 Subject: [PATCH 06/21] Adding icon files to git #story[1245] --- src/main/java/seng302/gameServer/GameState.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 1dd9963a..0badbe59 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -38,8 +38,6 @@ public class GameState implements Runnable { static final int PREPATORY_TIME = 5 * -1000; private static final int TIME_TILL_START = 10 * 1000; - private static final Long POWERUP_TIMEOUT_MS = 10_000L; - private static final Integer STATE_UPDATES_PER_SECOND = 60; private static Double ROUNDING_DISTANCE = 50d; // TODO: 14/08/17 wmu16 - Look into this value further private static final Double MARK_COLLISION_DISTANCE = 15d; @@ -327,7 +325,8 @@ public class GameState implements Runnable { private void checkPowerUpTimeout(ServerYacht yacht) { if (yacht.getPowerUp() != null) { - if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > POWERUP_TIMEOUT_MS) { + if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > yacht.getPowerUp() + .getTimeout()) { yacht.powerDown(); sendServerMessage(yacht.getSourceId(), yacht.getBoatName() + "'s power-up token expired"); logger.debug("Yacht: " + yacht.getShortName() + " powered down!"); From 061e49bab96728ad2b84f91cc230ddddcff0da63 Mon Sep 17 00:00:00 2001 From: William Muir Date: Fri, 22 Sep 2017 23:44:03 +1200 Subject: [PATCH 07/21] Implemented wind walker algorithm. Refactored some GameState updating logic to allow for better token logic integration GameState: Moved all token logic into its own function startPoint so that it is dsijoint from other updating logic GameState: Implemented wind walker algorithm. GameState: Changed Generic 'speedMultiplier' to 'serverSpeedMultiplier' to make it obviously disjoint from a boats speed multiplier MessageFactory: Moved some found message creation (Chatter Message) server side into MessageFactory that wasnt already there ServerYacht: Added a speed multiplier and a handling multiplier to the serveryacht class that is set and reset upon powerup / down #story[1293] --- .../java/seng302/gameServer/GameState.java | 172 +++++++++++++----- .../seng302/gameServer/MessageFactory.java | 5 + src/main/java/seng302/model/ServerYacht.java | 24 ++- src/main/java/seng302/model/token/Token.java | 2 - .../gameServer/server/ChatCommandsTest.java | 6 +- 5 files changed, 158 insertions(+), 51 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 3afd76ff..8f772653 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -46,12 +46,14 @@ public class GameState implements Runnable { private static final Double BOUNCE_DISTANCE_MARK = 20.0; public static final Double BOUNCE_DISTANCE_YACHT = 30.0; private static final Double COLLISION_VELOCITY_PENALTY = 0.3; + private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; + private static final Integer HANDLING_BOOST_MULTIPLIER = 2; private static Long previousUpdateTime; public static Double windDirection; private static Double windSpeed; - private static Double speedMultiplier = 1d; + private static Double serverSpeedMultiplier = 1d; private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat. private static Boolean playerHasLeftFlag; @@ -85,7 +87,7 @@ public class GameState implements Runnable { GameState.hostIpAddress = hostIpAddress; customizationFlag = false; playerHasLeftFlag = false; - speedMultiplier = 1.0; + serverSpeedMultiplier = 1.0; currentStage = GameStages.LOBBYING; isRaceStarted = false; //set this when game stage changes to prerace @@ -283,9 +285,11 @@ public class GameState implements Runnable { tokensInPlay.clear(); //Get a random token location with random type - Token token = allTokens.get(random.nextInt(allTokens.size())); + Token token = allTokens.get(random.nextInt(allTokens.size() - 1) + 1); token.assignRandomType(); + logger.debug("Spawned token of type " + token.getTokenType()); + tokensInPlay.add(token); } @@ -308,10 +312,10 @@ public class GameState implements Runnable { } for (ServerYacht yacht : yachts.values()) { updateVelocity(yacht); - checkPowerUpTimeout(yacht); yacht.runAutoPilot(); yacht.updateLocation(timeInterval); checkCollision(yacht); + preformTokenUpdates(yacht); //This update must always be done lsat if (yacht.getBoatStatus() != BoatStatus.FINISHED) { checkForLegProgression(yacht); raceFinished = false; @@ -324,13 +328,77 @@ public class GameState implements Runnable { } - private void checkPowerUpTimeout(ServerYacht yacht) { + /** + * All token functionality entry points is taken care of here. So can be disabled and enabled + * easily + * + * @param yacht The yacht to perform token checks on + */ + private void preformTokenUpdates(ServerYacht yacht) { + checkTokenPickUp(yacht); + if (yacht.getPowerUp() != null) { - if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > yacht.getPowerUp() - .getTimeout()) { - yacht.powerDown(); - sendServerMessage(yacht.getSourceId(), yacht.getBoatName() + "'s power-up token expired"); - logger.debug("Yacht: " + yacht.getShortName() + " powered down!"); + switch (yacht.getPowerUp()) { + case WIND_WALKER: + windWalk(yacht); + break; + case BUMPER: + break; + } + + checkPowerUpTimeout(yacht); + } + + + } + + + /** + * Checks how long a powerup has been active for. If it has exceeded its timeout, it powers the + * yacht down. WARNING. Do not call if the yacht does not have an active power up. Check with + * yacht.getPowerup != null first + * + * @param yacht The yacht to check to power down + */ + private void checkPowerUpTimeout(ServerYacht yacht) { + if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > yacht.getPowerUp() + .getTimeout()) { + yacht.powerDown(); + String logMessage = yacht.getBoatName() + "'s power-up token expired"; + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); + logger.debug("Yacht: " + yacht.getShortName() + " powered down!"); + } + } + + + /** + * This function changes the wind to be at an angle that causes the yacht in question to be at + * VMG. + * + * @param yacht The yacht to fix the wind for + */ + private void windWalk(ServerYacht yacht) { + HashMap upwindOptimal = PolarTable.getOptimalUpwindVMG(windSpeed); + Double optimalAngle = null; + for (Double windAngle : upwindOptimal.keySet()) { + optimalAngle = windAngle; + } + + Double heading = yacht.getHeading(); + if (heading < windDirection) { + Double diff = Math.abs(optimalAngle - (windDirection - heading)); + if (windDirection - heading < optimalAngle) { + windDirection = (double) Math.floorMod(Math.round(windDirection + diff), 360L); + } else { + windDirection = (double) Math.floorMod(Math.round(windDirection - diff), 360L); + } + } else { + Double diff = Math.abs(optimalAngle - (heading - windDirection)); + if (heading - windDirection < optimalAngle) { + windDirection = (double) Math.floorMod(Math.round(windDirection - diff), 360L); + } else { + windDirection = (double) Math.floorMod(Math.round(windDirection + diff), 360L); } } } @@ -357,19 +425,53 @@ public class GameState implements Runnable { } /** - * Checks all tokensInPlay to see if a yacht has picked one up - * @return Token which was collided with - * @param serverYacht The yacht to check for collision with a token + * Checks all tokensInPlay to see if a yacht has picked one up. If so, the yacht is powered up + * in the appropriate way + * @param yacht The yacht to check for collision with a token */ - private static Token checkTokenPickUp(ServerYacht serverYacht) { + private void checkTokenPickUp(ServerYacht yacht) { + Token collidedToken = null; for (Token token : tokensInPlay) { - Double distance = GeoUtility.getDistance(token, serverYacht.getLocation()); + Double distance = GeoUtility.getDistance(token, yacht.getLocation()); if (distance < YACHT_COLLISION_DISTANCE) { - return token; + collidedToken = token; } } - return null; + if (collidedToken != null) { + tokensInPlay.remove(collidedToken); + if (collidedToken.getTokenType() == TokenType.RANDOM) { + collidedToken.realiseRandom(); + } + + TokenType tokenType = collidedToken.getTokenType(); + switch (tokenType) { + case BOOST: + yacht.setSpeedMultiplier(VELOCITY_BOOST_MULTIPLIER); + break; + case BUMPER: + // TODO: 22/09/17 wmu16 + break; + case HANDLING: + yacht.setHandlingMultiplier(HANDLING_BOOST_MULTIPLIER); + break; + case WIND_WALKER: + // TODO: 22/09/17 wmu16 + break; + } + yacht.powerUp(tokenType); + + String logMessage = + yacht.getBoatName() + " has picked up a " + collidedToken.getTokenType().getName() + + " token"; + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); + notifyMessageListeners(MessageFactory.getRaceXML()); + notifyMessageListeners(MessageFactory.makePickupMessage(yacht, collidedToken)); + + logger.debug("Yacht: " + yacht.getShortName() + " got powerup " + collidedToken + .getTokenType()); + } } @@ -388,7 +490,6 @@ public class GameState implements Runnable { //Yacht Collision ServerYacht collidedYacht = checkYachtCollision(serverYacht); Mark collidedMark = checkMarkCollision(serverYacht); - Token collidedToken = checkTokenPickUp(serverYacht); if (collidedYacht != null) { GeoPoint originalLocation = serverYacht.getLocation(); @@ -431,34 +532,14 @@ public class GameState implements Runnable { ); notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht)); } - - //Token Collision - if (collidedToken != null) { - if (collidedToken.getTokenType() == TokenType.RANDOM) { - collidedToken.realiseRandom(); - } - sendServerMessage(serverYacht.getSourceId(), - serverYacht.getBoatName() + " has picked up a " + collidedToken.getTokenType() - .getName() + " token"); - tokensInPlay.remove(collidedToken); - serverYacht.powerUp(collidedToken.getTokenType()); - logger.debug("Yacht: " + serverYacht.getShortName() + " got powerup " + collidedToken - .getTokenType()); - notifyMessageListeners(MessageFactory.getRaceXML()); - notifyMessageListeners(MessageFactory.makePickupMessage(serverYacht, collidedToken)); - } } private void updateVelocity(ServerYacht yacht) { Double trueWindAngle = Math.abs(windDirection - yacht.getHeading()); Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle); - Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier; - if (yacht.getPowerUp() != null) { - if (yacht.getPowerUp().equals(TokenType.BOOST)) { - maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER; - } - } + Double maxBoatSpeed = + GeoUtility.knotsToMMS(boatSpeedInKnots) * serverSpeedMultiplier * yacht.getSpeedMultiplier(); Double currentVelocity = yacht.getCurrentVelocity(); // TODO: 15/08/17 remove magic numbers from these equations. @@ -700,6 +781,7 @@ public class GameState implements Runnable { String name = new String(customizeData); playerYacht.setBoatName(name); } else if (requestType.equals(CustomizeRequestType.COLOR)) { + //This low level stuff shouldnt be here alistair! In fact no logic LIKE THIS should! - wmu16 int red = customizeData[0] & 0xFF; int green = customizeData[1] & 0xFF; int blue = customizeData[2] & 0xFF; @@ -799,7 +881,7 @@ public class GameState implements Runnable { switch (words[2].trim()) { case "/speed": try { - setSpeedMultiplier(Double.valueOf(words[3])); + setServerSpeedMultiplier(Double.valueOf(words[3])); sendServerMessage(chatterMessage.getMessage_type(), "Speed modifier set to x" + words[3]); } catch (Exception e) { @@ -866,11 +948,11 @@ public class GameState implements Runnable { currentStage = GameStages.FINISHED; } - public static void setSpeedMultiplier (double multiplier) { - speedMultiplier = multiplier; + public static void setServerSpeedMultiplier(double multiplier) { + serverSpeedMultiplier = multiplier; } - public static double getSpeedMultiplier () { - return speedMultiplier; + public static double getServerSpeedMultiplier() { + return serverSpeedMultiplier; } } diff --git a/src/main/java/seng302/gameServer/MessageFactory.java b/src/main/java/seng302/gameServer/MessageFactory.java index 2ef38d29..d883d06c 100644 --- a/src/main/java/seng302/gameServer/MessageFactory.java +++ b/src/main/java/seng302/gameServer/MessageFactory.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import seng302.gameServer.messages.BoatLocationMessage; import seng302.gameServer.messages.BoatSubMessage; +import seng302.gameServer.messages.ChatterMessage; import seng302.gameServer.messages.RaceStartNotificationType; import seng302.gameServer.messages.RaceStartStatusMessage; import seng302.gameServer.messages.RaceStatus; @@ -157,4 +158,8 @@ public class MessageFactory { } return new YachtEventCodeMessage(serverYacht.getSourceId(), yachtEventType); } + + public static ChatterMessage makeChatterMessage(Integer messageType, String message) { + return new ChatterMessage(messageType, "SERVER: " + message); + } } diff --git a/src/main/java/seng302/model/ServerYacht.java b/src/main/java/seng302/model/ServerYacht.java index e7d936ca..21508774 100644 --- a/src/main/java/seng302/model/ServerYacht.java +++ b/src/main/java/seng302/model/ServerYacht.java @@ -56,6 +56,8 @@ public class ServerYacht { //PowerUp private TokenType powerUp; private Long powerUpStartTime; + private Integer speedMultiplier; + private Integer handlingMultiplier; public ServerYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName, @@ -77,6 +79,8 @@ public class ServerYacht { this.legNumber = 0; this.boatColor = Colors.getColor(sourceId - 1); this.powerUp = null; + this.speedMultiplier = 1; + this.handlingMultiplier = 1; this.hasEnteredRoundingZone = false; this.hasPassedLine = false; @@ -114,6 +118,8 @@ public class ServerYacht { public void powerDown() { this.powerUp = null; + this.speedMultiplier = 1; + this.handlingMultiplier = 1; } public Long getPowerUpStartTime() { @@ -130,7 +136,7 @@ public class ServerYacht { * @param amount the amount by which to adjust the boat heading. */ public void adjustHeading(Double amount) { - Double newVal = heading + amount; + Double newVal = heading + amount * handlingMultiplier; lastHeading = heading; heading = (double) Math.floorMod(newVal.longValue(), 360L); } @@ -429,4 +435,20 @@ public class ServerYacht { public BoatMeshType getBoatType() { return boatType; } + + public Integer getSpeedMultiplier() { + return speedMultiplier; + } + + public void setSpeedMultiplier(Integer speedMultiplier) { + this.speedMultiplier = speedMultiplier; + } + + public Integer getHandlingMultiplier() { + return handlingMultiplier; + } + + public void setHandlingMultiplier(Integer handlingMultiplier) { + this.handlingMultiplier = handlingMultiplier; + } } diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index fcdbab5e..e1a16bd3 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -39,6 +39,4 @@ public class Token extends GeoPoint { tokenTypeList.remove(TokenType.RANDOM); tokenType = tokenTypeList.get(random.nextInt(tokenTypeList.size())); } - - } diff --git a/src/test/java/seng302/gameServer/server/ChatCommandsTest.java b/src/test/java/seng302/gameServer/server/ChatCommandsTest.java index cb0bc930..5c67c649 100644 --- a/src/test/java/seng302/gameServer/server/ChatCommandsTest.java +++ b/src/test/java/seng302/gameServer/server/ChatCommandsTest.java @@ -110,7 +110,7 @@ public class ChatCommandsTest { } catch (InterruptedException ie) { ie.printStackTrace(); } - Assert.assertEquals(5.0, GameState.getSpeedMultiplier(), 0.00001); + Assert.assertEquals(5.0, GameState.getServerSpeedMultiplier(), 0.00001); mst.terminate(); try { Thread.sleep(200); @@ -150,7 +150,7 @@ public class ChatCommandsTest { ie.printStackTrace(); } mst.terminate(); - Assert.assertEquals(1.0, GameState.getSpeedMultiplier(), 0.00001); + Assert.assertEquals(1.0, GameState.getServerSpeedMultiplier(), 0.00001); try { Thread.sleep(2000); } catch (InterruptedException ie) { @@ -194,7 +194,7 @@ public class ChatCommandsTest { } catch (InterruptedException ie) { ie.printStackTrace(); } - Assert.assertEquals(1.0, GameState.getSpeedMultiplier(), 0.00001); + Assert.assertEquals(1.0, GameState.getServerSpeedMultiplier(), 0.00001); mst.terminate(); host.setSocketToClose(); client.setSocketToClose(); From e61b6d50a13253368af6c2042975a6fd276dbdbd Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 11:33:01 +1200 Subject: [PATCH 08/21] Small refactor. Fixed tokens to spawn on the minute mark. Moved updates of wind and token timers into gamestate from mainserver thread. Now triggered upon GameState change to start #story[1293] --- .../java/seng302/gameServer/GameState.java | 88 +++++++++++++++++-- .../seng302/gameServer/MainServerThread.java | 62 ------------- 2 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 8f772653..59056da6 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -35,25 +35,35 @@ public class GameState implements Runnable { private static Logger logger = LoggerFactory.getLogger(GameState.class); + private static final Integer STATE_UPDATES_PER_SECOND = 60; + + //Scheduling constants static final int WARNING_TIME = 10 * -1000; static final int PREPATORY_TIME = 5 * -1000; private static final int TIME_TILL_START = 10 * 1000; - private static final Integer STATE_UPDATES_PER_SECOND = 60; - private static Double ROUNDING_DISTANCE = 50d; // TODO: 14/08/17 wmu16 - Look into this value further + //Wind Constants + private static final int MAX_WIND_SPEED = 12000; + private static final int MIN_WIND_SPEED = 8000; + + //Rounding Constants + private static final Double ROUNDING_DISTANCE = 50d; // TODO: 14/08/17 wmu16 - Look into this value further + + //Collision constants private static final Double MARK_COLLISION_DISTANCE = 15d; public static final Double YACHT_COLLISION_DISTANCE = 25.0; private static final Double BOUNCE_DISTANCE_MARK = 20.0; public static final Double BOUNCE_DISTANCE_YACHT = 30.0; private static final Double COLLISION_VELOCITY_PENALTY = 0.3; + //Powerup Constants private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static final Integer HANDLING_BOOST_MULTIPLIER = 2; private static Long previousUpdateTime; public static Double windDirection; private static Double windSpeed; - private static Double serverSpeedMultiplier = 1d; + private static Double serverSpeedMultiplier; private static Boolean customizationFlag; // dirty flag to tell if a player has customized their boat. private static Boolean playerHasLeftFlag; @@ -90,7 +100,6 @@ public class GameState implements Runnable { serverSpeedMultiplier = 1.0; currentStage = GameStages.LOBBYING; isRaceStarted = false; - //set this when game stage changes to prerace previousUpdateTime = System.currentTimeMillis(); markOrder = new MarkOrder(); //This could be instantiated at some point with a select map? newMessageListeners = new ArrayList<>(); @@ -242,7 +251,15 @@ public class GameState implements Runnable { } catch (InterruptedException e) { System.out.println("[GameState] interrupted exception"); } - if (currentStage == GameStages.PRE_RACE || currentStage == GameStages.RACING) { + if (currentStage == GameStages.PRE_RACE) { + update(); + if (System.currentTimeMillis() > startTime) { + startSpawningTokens(); + startUpdatingWind(); + GameState.setCurrentStage(GameStages.RACING); + } + } + if (currentStage == GameStages.RACING) { update(); } @@ -252,6 +269,61 @@ public class GameState implements Runnable { } } + /** + * Start spawning coins every 60s after the first minute + */ + private void startSpawningTokens() { + Timer timer = new Timer("Token Spawning Timer"); + timer.schedule(new TimerTask() { + @Override + public void run() { + spawnNewToken(); + notifyMessageListeners(MessageFactory.getRaceXML()); + } + }, 0, 60000); + } + + // TODO: 29/08/17 wmu16 - This sort of update should be in game state + private static void startUpdatingWind() { + Timer timer = new Timer("Wind Updating Timer"); + timer.schedule(new TimerTask() { + @Override + public void run() { + updateWind(); + } + }, 0, 500); + } + + + private static void updateWind() { + Integer direction = GameState.getWindDirection().intValue(); + Integer windSpeed = GameState.getWindSpeedMMS().intValue(); + + Random random = new Random(); + + if (Math.floorMod(random.nextInt(), 2) == 0) { + direction += random.nextInt(4); + windSpeed += random.nextInt(20) + 459; + } else { + direction -= random.nextInt(4); + windSpeed -= random.nextInt(20) + 459; + } + + direction = Math.floorMod(direction, 360); + + if (windSpeed > MAX_WIND_SPEED) { + windSpeed -= random.nextInt(500); + } + + if (windSpeed <= MIN_WIND_SPEED) { + windSpeed += random.nextInt(500); + } + + GameState.setWindSpeed(Double.valueOf(windSpeed)); + GameState.setWindDirection(direction.doubleValue()); + } + + public static void updateBoat(Integer sourceId, BoatAction actionType) { ServerYacht playerYacht = yachts.get(sourceId); switch (actionType) { @@ -285,7 +357,7 @@ public class GameState implements Runnable { tokensInPlay.clear(); //Get a random token location with random type - Token token = allTokens.get(random.nextInt(allTokens.size() - 1) + 1); + Token token = allTokens.get(random.nextInt(allTokens.size())); token.assignRandomType(); logger.debug("Spawned token of type " + token.getTokenType()); @@ -307,9 +379,7 @@ public class GameState implements Runnable { Double timeInterval = (System.currentTimeMillis() - previousUpdateTime) / 1000000.0; previousUpdateTime = System.currentTimeMillis(); - if (System.currentTimeMillis() > startTime) { - GameState.setCurrentStage(GameStages.RACING); - } + for (ServerYacht yacht : yachts.values()) { updateVelocity(yacht); yacht.runAutoPilot(); diff --git a/src/main/java/seng302/gameServer/MainServerThread.java b/src/main/java/seng302/gameServer/MainServerThread.java index b5d8aa25..b4876748 100644 --- a/src/main/java/seng302/gameServer/MainServerThread.java +++ b/src/main/java/seng302/gameServer/MainServerThread.java @@ -37,9 +37,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { private static final int PORT = 4942; private static final Integer CLIENT_UPDATES_PER_SECOND = 60; - private static final int MAX_WIND_SPEED = 12000; - private static final int MIN_WIND_SPEED = 8000; - private boolean terminated; private Thread thread; @@ -101,8 +98,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { GameState.addMessageEventListener(this::broadcastMessage); terminated = false; thread = new Thread(this, "MainServer"); - startUpdatingWind(); - startSpawningTokens(); thread.start(); } @@ -187,63 +182,6 @@ public class MainServerThread implements Runnable, ClientConnectionDelegate { } } - private static void updateWind(){ - Integer direction = GameState.getWindDirection().intValue(); - Integer windSpeed = GameState.getWindSpeedMMS().intValue(); - - Random random = new Random(); - - if (Math.floorMod(random.nextInt(), 2) == 0){ - direction += random.nextInt(4); - windSpeed += random.nextInt(20) + 459; - } - else{ - direction -= random.nextInt(4); - windSpeed -= random.nextInt(20) + 459; - } - - direction = Math.floorMod(direction, 360); - - if (windSpeed > MAX_WIND_SPEED){ - windSpeed -= random.nextInt(500); - } - - if (windSpeed <= MIN_WIND_SPEED){ - windSpeed += random.nextInt(500); - } - - GameState.setWindSpeed(Double.valueOf(windSpeed)); - GameState.setWindDirection(direction.doubleValue()); - } - - - - - // TODO: 29/08/17 wmu16 - This sort of update should be in game state - private static void startUpdatingWind(){ - Timer timer = new Timer(); - timer.schedule(new TimerTask() { - @Override - public void run() { - updateWind(); - } - }, 0, 500); - } - - /** - * Start spawning coins every 60s after the first minute - */ - private void startSpawningTokens() { - Timer timer = new Timer(); - timer.schedule(new TimerTask() { - @Override - public void run() { - GameState.spawnNewToken(); - broadcastMessage(MessageFactory.getRaceXML()); - } - }, 10000, 60000); - } - /** * A client has tried to connect to the server * From ecb3d4ecbf0a349cdbfcf6ae5bbfd6267ab92334 Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 11:49:56 +1200 Subject: [PATCH 09/21] Removed sendServerMessage to be replaced with notifyMessageListeners. Minor structure move arounds #story[1293] --- .../java/seng302/gameServer/GameState.java | 38 +++++++++---------- .../gameServer/messages/ChatterMessage.java | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 59056da6..cfba8af1 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -92,7 +92,6 @@ public class GameState implements Runnable { windSpeed = 10000d; yachts = new HashMap<>(); tokensInPlay = new ArrayList<>(); - players = new ArrayList<>(); GameState.hostIpAddress = hostIpAddress; customizationFlag = false; @@ -688,7 +687,10 @@ public class GameState implements Runnable { if (hasProgressed) { if (currentMarkSeqID != 0 && !markOrder.isLastMark(currentMarkSeqID)) { - sendServerMessage(yacht.getSourceId(), yacht.getBoatName() + " passed leg " + yacht.getLegNumber()); + + String logMessage = yacht.getBoatName() + " passed leg " + yacht.getLegNumber(); + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); } yacht.incrementLegNumber(); sendMarkRoundingMessage(yacht); @@ -724,7 +726,9 @@ public class GameState implements Runnable { if (crossedLine == 2 && isClockwiseCross || crossedLine == 1 && !isClockwiseCross) { yacht.setClosestCurrentMark(mark1); yacht.setBoatStatus(BoatStatus.RACING); - sendServerMessage(yacht.getSourceId(), yacht.getBoatName() + " passed start line"); + String logMessage = yacht.getBoatName() + " passed start line"; + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); return true; } } @@ -828,7 +832,10 @@ public class GameState implements Runnable { if (crossedLine == 1 && isClockwiseCross || crossedLine == 2 && !isClockwiseCross) { yacht.setClosestCurrentMark(mark1); yacht.setBoatStatus(BoatStatus.FINISHED); - sendServerMessage(yacht.getSourceId(), yacht.getBoatName() + " passed finish line"); + + String logMessage = yacht.getBoatName() + " passed finish line"; + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); return true; } } @@ -937,13 +944,6 @@ public class GameState implements Runnable { roundingMark.getSourceID())); } - - public static void sendServerMessage(Integer messageType, String message) { - notifyMessageListeners(new ChatterMessage( - messageType, "SERVER: " + message - )); - } - public static void processChatter(ChatterMessage chatterMessage, boolean isHost) { String chatterText = chatterMessage.getMessage(); String[] words = chatterText.split("\\s+"); @@ -951,17 +951,19 @@ public class GameState implements Runnable { switch (words[2].trim()) { case "/speed": try { - setServerSpeedMultiplier(Double.valueOf(words[3])); - sendServerMessage(chatterMessage.getMessage_type(), - "Speed modifier set to x" + words[3]); + serverSpeedMultiplier = Double.valueOf(words[3]); + String logMessage = "Speed modifier set to x" + words[3]; + notifyMessageListeners(MessageFactory + .makeChatterMessage(chatterMessage.getMessageType(), logMessage)); } catch (Exception e) { Logger logger = LoggerFactory.getLogger(GameState.class); logger.error("cannot parse >speed value"); } return; case "/finish": - sendServerMessage(chatterMessage.getMessage_type(), - "Game will now finish"); + String logMessage = "Game will now finish"; + notifyMessageListeners(MessageFactory + .makeChatterMessage(chatterMessage.getMessageType(), logMessage)); endRace(); return; } @@ -1018,10 +1020,6 @@ public class GameState implements Runnable { currentStage = GameStages.FINISHED; } - public static void setServerSpeedMultiplier(double multiplier) { - serverSpeedMultiplier = multiplier; - } - public static double getServerSpeedMultiplier() { return serverSpeedMultiplier; } diff --git a/src/main/java/seng302/gameServer/messages/ChatterMessage.java b/src/main/java/seng302/gameServer/messages/ChatterMessage.java index 266fca62..4a3aec39 100644 --- a/src/main/java/seng302/gameServer/messages/ChatterMessage.java +++ b/src/main/java/seng302/gameServer/messages/ChatterMessage.java @@ -40,7 +40,7 @@ public class ChatterMessage extends Message { return message; } - public int getMessage_type() { + public int getMessageType() { return message_type; } } From 8c7f9a878db16e5042ab4a8d234d8dbdbaf07956 Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 13:23:16 +1200 Subject: [PATCH 10/21] Created Boat bumper logic. Refactored logic for powering up / dpwn YachtEventType: Added some new events, a generic power down event and a bumper_crash event for an affected boat GameState: Implemented boat bumper logic MessageFactory: Made new messages for powerdown and status effect ClientYacht: Had to create another powerDown functional interface to inform the race view controller when to turn off the icon RaceViewController/GameClient: Now waits for a message about powering down before turning off rather than waiting time client side #story[1293] --- .../java/seng302/gameServer/GameState.java | 66 ++++++++++++++----- .../seng302/gameServer/MessageFactory.java | 39 +++++++++++ .../gameServer/messages/YachtEventType.java | 5 +- src/main/java/seng302/model/ClientYacht.java | 24 +++++++ src/main/java/seng302/model/token/Token.java | 7 ++ .../java/seng302/visualiser/GameClient.java | 9 ++- .../controllers/RaceViewController.java | 27 ++++---- 7 files changed, 147 insertions(+), 30 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index cfba8af1..496c7cb9 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -1,5 +1,6 @@ package seng302.gameServer; +import com.sun.corba.se.spi.activation.Server; import javafx.scene.paint.Color; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,6 +60,7 @@ public class GameState implements Runnable { //Powerup Constants private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static final Integer HANDLING_BOOST_MULTIPLIER = 2; + private static final Long BUMPER_DISABLE_TIME = 5_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -279,7 +281,7 @@ public class GameState implements Runnable { spawnNewToken(); notifyMessageListeners(MessageFactory.getRaceXML()); } - }, 0, 60000); + }, 0, 15_000); } // TODO: 29/08/17 wmu16 - This sort of update should be in game state @@ -351,13 +353,14 @@ public class GameState implements Runnable { * Randomly select a subset of tokensInPlay from a pre defined superset * Broadasts a new race status message to show this update */ - public static void spawnNewToken() { + private void spawnNewToken() { Random random = new Random(); tokensInPlay.clear(); //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); - token.assignRandomType(); +// token.assignRandomType(); + token.assignType(TokenType.BUMPER); logger.debug("Spawned token of type " + token.getTokenType()); @@ -383,8 +386,9 @@ public class GameState implements Runnable { updateVelocity(yacht); yacht.runAutoPilot(); yacht.updateLocation(timeInterval); + preformTokenUpdates( + yacht); //This update must be done before collision. Sorry sorta hacky rn. checkCollision(yacht); - preformTokenUpdates(yacht); //This update must always be done lsat if (yacht.getBoatStatus() != BoatStatus.FINISHED) { checkForLegProgression(yacht); raceFinished = false; @@ -405,38 +409,66 @@ public class GameState implements Runnable { */ private void preformTokenUpdates(ServerYacht yacht) { checkTokenPickUp(yacht); + checkPowerUpTimeout(yacht); + TokenType powerUp = yacht.getPowerUp(); - if (yacht.getPowerUp() != null) { - switch (yacht.getPowerUp()) { + if (powerUp != null) { + switch (powerUp) { case WIND_WALKER: windWalk(yacht); break; case BUMPER: + ServerYacht collidedYacht = checkYachtCollision(yacht); + if (collidedYacht != null) { + yacht.powerDown(); + boatTempShutDown(collidedYacht); + notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); + notifyMessageListeners( + MessageFactory.makeStatusEffectMessage(yacht, powerUp)); + } break; } - - checkPowerUpTimeout(yacht); } + } + // TODO: 23/09/17 wmu16 - This is a hacky way to have the boat power down. Need some sort of separation between token and status effect :/ + /** + * Disables the given boat for BUMPER_DISABLE_TIME ms. + * + * @param yacht The yacht to disable + */ + private void boatTempShutDown(ServerYacht yacht) { + yacht.setSpeedMultiplier(0); + Timer shutDownTimer = new Timer("Shutdown Timer"); + shutDownTimer.schedule(new TimerTask() { + @Override + public void run() { + yacht.powerDown(); //Note this actually resets the boat to normal. + } + }, BUMPER_DISABLE_TIME); } /** * Checks how long a powerup has been active for. If it has exceeded its timeout, it powers the - * yacht down. WARNING. Do not call if the yacht does not have an active power up. Check with - * yacht.getPowerup != null first + * yacht down. * * @param yacht The yacht to check to power down */ private void checkPowerUpTimeout(ServerYacht yacht) { - if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > yacht.getPowerUp() - .getTimeout()) { - yacht.powerDown(); - String logMessage = yacht.getBoatName() + "'s power-up token expired"; - notifyMessageListeners( - MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); - logger.debug("Yacht: " + yacht.getShortName() + " powered down!"); + if (yacht.getPowerUp() != null) { + if (System.currentTimeMillis() - yacht.getPowerUpStartTime() > yacht.getPowerUp() + .getTimeout()) { + String logMessage = + yacht.getBoatName() + "'s " + yacht.getPowerUp().getName() + " expired"; + notifyMessageListeners( + MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); + notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); + logger.debug("Yacht: " + yacht.getShortName() + " powered down!"); + + yacht.powerDown(); + } } } diff --git a/src/main/java/seng302/gameServer/MessageFactory.java b/src/main/java/seng302/gameServer/MessageFactory.java index d883d06c..2bb0d474 100644 --- a/src/main/java/seng302/gameServer/MessageFactory.java +++ b/src/main/java/seng302/gameServer/MessageFactory.java @@ -137,6 +137,14 @@ public class MessageFactory { return new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION); } + + /** + * Constructs a message to be sent out whenever a yacht picks up a boost + * + * @param serverYacht The yacht that has picked up a power up + * @param token The token which they picked up + * @return The corresponding YachtEventCodeMessage + */ public static YachtEventCodeMessage makePickupMessage(ServerYacht serverYacht, Token token) { YachtEventType yachtEventType = null; switch (token.getTokenType()) { @@ -159,6 +167,37 @@ public class MessageFactory { return new YachtEventCodeMessage(serverYacht.getSourceId(), yachtEventType); } + /** + * Constructs a message representing a certain buff / debuff for a given yacht. For now this is + * just for the bumper debuff so the affected boat is aware that it has been crashed. This could + * however be extended to render affects for all boats given a certain debuff. + * + * @param yacht The yacht affected by some status + * @param token The token indicating what status they have + * @return A YachtEventCodeMessage + */ + public static YachtEventCodeMessage makeStatusEffectMessage(ServerYacht yacht, + TokenType token) { + YachtEventType yachtEventType = null; + switch (token) { + case BUMPER: + yachtEventType = YachtEventType.BUMPER_CRASH; + break; + } + return new YachtEventCodeMessage(yacht.getSourceId(), yachtEventType); + } + + + /** + * Constructs a message to be sent out when a given yacht powers down (From a boost of any type) + * + * @param yacht The yacht that is powering down + * @return A YachtEventCodeMessage representing this action + */ + public static YachtEventCodeMessage makePowerDownMessage(ServerYacht yacht) { + return new YachtEventCodeMessage(yacht.getSourceId(), YachtEventType.POWER_DOWN); + } + public static ChatterMessage makeChatterMessage(Integer messageType, String message) { return new ChatterMessage(messageType, "SERVER: " + message); } diff --git a/src/main/java/seng302/gameServer/messages/YachtEventType.java b/src/main/java/seng302/gameServer/messages/YachtEventType.java index c8a997a0..facda84e 100644 --- a/src/main/java/seng302/gameServer/messages/YachtEventType.java +++ b/src/main/java/seng302/gameServer/messages/YachtEventType.java @@ -9,7 +9,10 @@ public enum YachtEventType { TOKEN_BUMPER(35), TOKEN_HANDLING(36), TOKEN_WIND_WALKER(37), - TOKEN_RANDOM(38); + TOKEN_RANDOM(38), + POWER_DOWN(39), + BUMPER_CRASH(40); + private int code; diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index b926f2ff..f626db30 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -39,11 +39,22 @@ public class ClientYacht extends Observable { void notifyRounding(ClientYacht yacht, int legNumber); } + //This notifies RaceViewController so it can display icon - wmu16 @FunctionalInterface public interface PowerUpListener { + void notifyPowerUp(ClientYacht yacht, TokenType tokenType); } + //This notifies RaceViewController so it can remove token icon - wmu16 + @FunctionalInterface + public interface PowerDownListener { + + void notifyPowerDown(ClientYacht yacht); + } + + + private Logger logger = LoggerFactory.getLogger(ClientYacht.class); @@ -70,6 +81,8 @@ public class ClientYacht extends Observable { private List locationListeners = new ArrayList<>(); private List markRoundingListeners = new ArrayList<>(); private List powerUpListeners = new ArrayList<>(); + private List powerDownListeners = new ArrayList<>(); + private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper(); @@ -211,6 +224,13 @@ public class ClientYacht extends Observable { this.position = position; } + public void powerDown() { + this.powerUp = null; + for (PowerDownListener listener : powerDownListeners) { + listener.notifyPowerDown(this); + } + } + public void setPowerUp(TokenType tokenType) { this.powerUp = tokenType; for (PowerUpListener listener : powerUpListeners) { @@ -295,6 +315,10 @@ public class ClientYacht extends Observable { powerUpListeners.add(listener); } + public void addPowerDownListener(PowerDownListener listener) { + powerDownListeners.add(listener); + } + public void removeMarkRoundingListener(MarkRoundingListener listener) { markRoundingListeners.remove(listener); } diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index e1a16bd3..ed8b87eb 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -39,4 +39,11 @@ public class Token extends GeoPoint { tokenTypeList.remove(TokenType.RANDOM); tokenType = tokenTypeList.get(random.nextInt(tokenTypeList.size())); } + + /** + * Exists for testing purposes only + */ + public void assignType(TokenType tokenType) { + this.tokenType = tokenType; + } } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 9abf282a..9947719e 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -410,8 +410,15 @@ public class GameClient { * @param yachtEventData The YachtEvent data packet */ private void processYachtEvent(YachtEventData yachtEventData) { + ClientYacht thisYacht = allBoatsMap.get(yachtEventData.getSubjectId().intValue()); + if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { showCollisionAlert(yachtEventData); + } else if (yachtEventData.getEventId() == YachtEventType.POWER_DOWN.getCode()) { + thisYacht.powerDown(); + Sounds.playTokenPickupSound(); // TODO: 23/09/17 This should be power down sound + } else if (yachtEventData.getEventId() == YachtEventType.BUMPER_CRASH.getCode()) { + // TODO: 23/09/17 notify the client that the yacht has been disabled } else { TokenType tokenType = null; if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { @@ -427,7 +434,7 @@ public class GameClient { } showTokenPickUp(tokenType); - allBoatsMap.get(yachtEventData.getSubjectId().intValue()).setPowerUp(tokenType); + thisYacht.setPowerUp(tokenType); } } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index e45dd091..1819ff48 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -48,6 +48,7 @@ import javafx.scene.shape.Polyline; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.stage.StageStyle; +import javax.swing.ImageIcon; import seng302.model.ClientYacht; import seng302.model.ClientYacht.PowerUpListener; import seng302.model.RaceState; @@ -140,6 +141,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel private JFXDialog finishScreenDialog; private FinishDialogController finishDialogController; + //Icon stuff + private Timer blinkingTimer = new Timer(); + private ImageView iconToDisplay; + public void initialize() { Sounds.stopMusic(); Sounds.playRaceMusic(); @@ -253,6 +258,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel }); player.addPowerUpListener(this::displayPowerUpIcon); + player.addPowerDownListener(this::removeIcon); updateOrder(raceState.getPlayerPositions()); gameView = new GameView3D(); @@ -301,7 +307,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel */ private void displayPowerUpIcon(ClientYacht yacht, TokenType tokenType) { if (yacht == player) { - final ImageView iconToDisplay; switch (tokenType) { case BOOST: @@ -324,7 +329,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel iconToDisplay.setVisible(true); //Start blinking icon towards end - Timer blinkingTimer = new Timer(); + if (blinkingTimer != null) { + blinkingTimer.cancel(); + } + blinkingTimer = new Timer("Blinking Timer"); blinkingTimer.schedule(new TimerTask() { Boolean isVisible = true; @@ -334,16 +342,13 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel iconToDisplay.setVisible(isVisible); } }, (int) (tokenType.getTimeout() * ICON_BLINK_TIMEOUT_RATIO), ICON_BLINK_PERIOD); + } + } - //Turn icon off after the time out - Timer switchOffTimer = new Timer(); - switchOffTimer.schedule(new TimerTask() { - @Override - public void run() { - blinkingTimer.cancel(); - iconToDisplay.setVisible(false); - } - }, tokenType.getTimeout()); + public void removeIcon(ClientYacht yacht) { + if (yacht == player) { + blinkingTimer.cancel(); + iconToDisplay.setVisible(false); } } From c47e5b145019010b5a29629aaaa61a4fa34bc89c Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 16:31:18 +1200 Subject: [PATCH 11/21] Boat now changes color when it is bumped for a time ClientYacht: Added ColorChangeListener from GameView3D to re paint the boat when the color attribute is changed #story[1293] --- .../java/seng302/gameServer/GameState.java | 11 +++--- src/main/java/seng302/model/ClientYacht.java | 24 +++++++++++-- .../java/seng302/visualiser/GameClient.java | 34 ++++++++++++++----- .../java/seng302/visualiser/GameView3D.java | 24 ++++++++++--- 4 files changed, 72 insertions(+), 21 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 496c7cb9..150fd652 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -60,7 +60,7 @@ public class GameState implements Runnable { //Powerup Constants private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static final Integer HANDLING_BOOST_MULTIPLIER = 2; - private static final Long BUMPER_DISABLE_TIME = 5_000L; + public static final Long BUMPER_DISABLE_TIME = 5_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -359,8 +359,8 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); -// token.assignRandomType(); - token.assignType(TokenType.BUMPER); + token.assignRandomType(); +// token.assignType(TokenType.BUMPER); logger.debug("Spawned token of type " + token.getTokenType()); @@ -386,8 +386,7 @@ public class GameState implements Runnable { updateVelocity(yacht); yacht.runAutoPilot(); yacht.updateLocation(timeInterval); - preformTokenUpdates( - yacht); //This update must be done before collision. Sorry sorta hacky rn. + preformTokenUpdates(yacht); //This update must be done before collision. Sorta hacky checkCollision(yacht); if (yacht.getBoatStatus() != BoatStatus.FINISHED) { checkForLegProgression(yacht); @@ -424,7 +423,7 @@ public class GameState implements Runnable { boatTempShutDown(collidedYacht); notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); notifyMessageListeners( - MessageFactory.makeStatusEffectMessage(yacht, powerUp)); + MessageFactory.makeStatusEffectMessage(collidedYacht, powerUp)); } break; } diff --git a/src/main/java/seng302/model/ClientYacht.java b/src/main/java/seng302/model/ClientYacht.java index f626db30..0b5449ae 100644 --- a/src/main/java/seng302/model/ClientYacht.java +++ b/src/main/java/seng302/model/ClientYacht.java @@ -39,17 +39,21 @@ public class ClientYacht extends Observable { void notifyRounding(ClientYacht yacht, int legNumber); } + @FunctionalInterface + public interface ColorChangeListener { + + void notifyColorChange(ClientYacht yacht); + } + //This notifies RaceViewController so it can display icon - wmu16 @FunctionalInterface public interface PowerUpListener { - void notifyPowerUp(ClientYacht yacht, TokenType tokenType); } //This notifies RaceViewController so it can remove token icon - wmu16 @FunctionalInterface public interface PowerDownListener { - void notifyPowerDown(ClientYacht yacht); } @@ -82,6 +86,7 @@ public class ClientYacht extends Observable { private List markRoundingListeners = new ArrayList<>(); private List powerUpListeners = new ArrayList<>(); private List powerDownListeners = new ArrayList<>(); + private List colorChangeListeners = new ArrayList<>(); private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper(); private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper(); @@ -224,6 +229,9 @@ public class ClientYacht extends Observable { this.position = position; } + /** + * Powers down the boat and notifies the raceViewController to display + */ public void powerDown() { this.powerUp = null; for (PowerDownListener listener : powerDownListeners) { @@ -231,6 +239,11 @@ public class ClientYacht extends Observable { } } + /** + * powers up the boat and notifies the raceViewController to display + * + * @param tokenType The type of token that this boat is being powered up with + */ public void setPowerUp(TokenType tokenType) { this.powerUp = tokenType; for (PowerUpListener listener : powerUpListeners) { @@ -290,6 +303,9 @@ public class ClientYacht extends Observable { public void setColour(Color colour) { this.colour = colour; + for (ColorChangeListener listener : colorChangeListeners) { + listener.notifyColorChange(this); + } } @@ -319,6 +335,10 @@ public class ClientYacht extends Observable { powerDownListeners.add(listener); } + public void addColorChangeListener(ColorChangeListener listener) { + colorChangeListeners.add(listener); + } + public void removeMarkRoundingListener(MarkRoundingListener listener) { markRoundingListeners.remove(listener); } diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 9947719e..0e4b4a7a 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -10,6 +10,8 @@ import java.util.Date; import java.util.List; import java.util.Map; import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -19,6 +21,7 @@ import javafx.scene.control.Alert.AlertType; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Pane; +import javafx.scene.paint.Color; import javafx.util.Pair; import seng302.gameServer.GameStages; import seng302.gameServer.GameState; @@ -413,12 +416,12 @@ public class GameClient { ClientYacht thisYacht = allBoatsMap.get(yachtEventData.getSubjectId().intValue()); if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) { - showCollisionAlert(yachtEventData); + showCollisionAlert(thisYacht); } else if (yachtEventData.getEventId() == YachtEventType.POWER_DOWN.getCode()) { thisYacht.powerDown(); Sounds.playTokenPickupSound(); // TODO: 23/09/17 This should be power down sound } else if (yachtEventData.getEventId() == YachtEventType.BUMPER_CRASH.getCode()) { - // TODO: 23/09/17 notify the client that the yacht has been disabled + showDisableAlert(thisYacht); } else { TokenType tokenType = null; if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { @@ -438,16 +441,31 @@ public class GameClient { } } + + /** + * Turns a disabled boat black until the bumper affect wears off + * + * @param yacht The yacht to show as disabled + */ + private void showDisableAlert(ClientYacht yacht) { + Color originalColor = yacht.getColour(); + yacht.setColour(Color.BLACK); + + Timer disableTimer = new Timer("Disable Timer"); + disableTimer.schedule(new TimerTask() { + @Override + public void run() { + yacht.setColour(originalColor); + } + }, GameState.BUMPER_DISABLE_TIME); + } + /** * Tells race view to show a collision animation. */ - private void showCollisionAlert(YachtEventData yachtEventData) { + private void showCollisionAlert(ClientYacht yacht) { Sounds.playCrashSound(); - raceState.storeCollision( - allBoatsMap.get( - yachtEventData.getSubjectId().intValue() - ) - ); + raceState.storeCollision(yacht); } // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user diff --git a/src/main/java/seng302/visualiser/GameView3D.java b/src/main/java/seng302/visualiser/GameView3D.java index 486f0717..3c662dfb 100644 --- a/src/main/java/seng302/visualiser/GameView3D.java +++ b/src/main/java/seng302/visualiser/GameView3D.java @@ -467,11 +467,8 @@ public class GameView3D { wakesGroup.getChildren().add(newBoat.getWake()); wakes.add(newBoat.getWake()); boatObjectGroup.getChildren().add(newBoat); - clientYacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> { - BoatObject bo = boatObjects.get(boat); - Point2D p2d = findScaledXY(lat, lon); - bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir); - }); + clientYacht.addLocationListener(this::updateBoatLocation); + clientYacht.addColorChangeListener(this::updateBoatColor); } Platform.runLater(() -> { gameObjects.getChildren().addAll(wakes); @@ -483,6 +480,23 @@ public class GameView3D { return view; } + /** + * Updates the boatObjects color with that of the clientYachts object. Used in notification from + * a listener on this attribute in clientYacht to re paint the boat mesh + * + * @param clientYacht The yacht to update the colour for + */ + private void updateBoatColor(ClientYacht clientYacht) { + boatObjects.get(clientYacht).setFill(clientYacht.getColour()); + } + + private void updateBoatLocation(ClientYacht boat, Double lat, Double lon, Double heading, + Boolean sailIn, Double velocity) { + BoatObject bo = boatObjects.get(boat); + Point2D p2d = findScaledXY(lat, lon); + bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir); + } + /** * Adds a border to the GameView and rescales to the size of the border, does not rescale if a * border already exists. Assumes the border is larger than the course. From 78259f8e3327d7fe08528c694ee9cbf819e58f0a Mon Sep 17 00:00:00 2001 From: William Muir Date: Sat, 23 Sep 2017 16:54:03 +1200 Subject: [PATCH 12/21] Boat now changes color when it is bumped for a time ClientYacht: Added ColorChangeListener from GameView3D to re paint the boat when the color attribute is changed #story[1293] --- .../java/seng302/visualiser/GameClient.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/main/java/seng302/visualiser/GameClient.java b/src/main/java/seng302/visualiser/GameClient.java index 0e4b4a7a..061b593a 100644 --- a/src/main/java/seng302/visualiser/GameClient.java +++ b/src/main/java/seng302/visualiser/GameClient.java @@ -422,7 +422,7 @@ public class GameClient { Sounds.playTokenPickupSound(); // TODO: 23/09/17 This should be power down sound } else if (yachtEventData.getEventId() == YachtEventType.BUMPER_CRASH.getCode()) { showDisableAlert(thisYacht); - } else { + } else { //Else all token pickup types TokenType tokenType = null; if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) { tokenType = TokenType.BOOST; @@ -436,7 +436,7 @@ public class GameClient { tokenType = TokenType.WIND_WALKER; } - showTokenPickUp(tokenType); + Sounds.playTokenPickupSound(); thisYacht.setPowerUp(tokenType); } } @@ -468,21 +468,6 @@ public class GameClient { raceState.storeCollision(yacht); } - // TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user - private void showTokenPickUp(TokenType tokenType) { - Sounds.playTokenPickupSound(); - switch (tokenType) { - case BOOST: - break; - case HANDLING: - break; - case WIND_WALKER: - break; - case BUMPER: - break; - } - } - private void formatAndSendChatMessage(String rawChat) { if (rawChat.length() > 0) { socketThread.sendChatterMessage( From 29b97a194dca9385ac75be56db3e526a2dcf77f7 Mon Sep 17 00:00:00 2001 From: William Muir Date: Mon, 25 Sep 2017 11:26:44 +1300 Subject: [PATCH 13/21] Merged dev back on #story[1293] --- .../java/seng302/gameServer/GameState.java | 24 +++++---- src/main/java/seng302/model/ServerYacht.java | 54 +++++++++---------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 14550218..5943625d 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -433,7 +433,7 @@ public class GameState implements Runnable { * @param yacht The yacht to disable */ private void boatTempShutDown(ServerYacht yacht) { - yacht.setSpeedMultiplier(0); + yacht.setPowerUpSpeedMultiplier(0); Timer shutDownTimer = new Timer("Shutdown Timer"); shutDownTimer.schedule(new TimerTask() { @Override @@ -542,13 +542,13 @@ public class GameState implements Runnable { TokenType tokenType = collidedToken.getTokenType(); switch (tokenType) { case BOOST: - yacht.setSpeedMultiplier(VELOCITY_BOOST_MULTIPLIER); + yacht.setPowerUpSpeedMultiplier(VELOCITY_BOOST_MULTIPLIER); break; case BUMPER: // TODO: 22/09/17 wmu16 break; case HANDLING: - yacht.setHandlingMultiplier(HANDLING_BOOST_MULTIPLIER); + yacht.setPowerUpHandlingMultiplier(HANDLING_BOOST_MULTIPLIER); break; case WIND_WALKER: // TODO: 22/09/17 wmu16 @@ -634,23 +634,29 @@ public class GameState implements Runnable { Double trueWindAngle = Math.abs(windDirection - yacht.getHeading()); Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle); Double maxBoatSpeed = - GeoUtility.knotsToMMS(boatSpeedInKnots) * serverSpeedMultiplier * yacht.getSpeedMultiplier() * yacht.getMaxSpeedMultiplier(); + GeoUtility.knotsToMMS(boatSpeedInKnots) * serverSpeedMultiplier * yacht + .getPowerUpSpeedMultiplier() * yacht.getBoatTypeSpeedMultiplier(); Double currentVelocity = yacht.getCurrentVelocity(); // TODO: 15/08/17 remove magic numbers from these equations. if (yacht.getSailIn()) { if (currentVelocity < maxBoatSpeed - 500) { - yacht.changeVelocity((maxBoatSpeed / 100) * yacht.getAccelerationMultiplier()); + yacht.changeVelocity( + (maxBoatSpeed / 100) * yacht.getBoatTypeAccelerationMultiplier()); } else if (currentVelocity > maxBoatSpeed + 500) { - yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier()); + yacht.changeVelocity( + (-currentVelocity / 200) * yacht.getBoatTypeAccelerationMultiplier()); } else { - yacht.setCurrentVelocity((maxBoatSpeed) * yacht.getAccelerationMultiplier()); + yacht + .setCurrentVelocity((maxBoatSpeed) * yacht.getBoatTypeAccelerationMultiplier()); } } else { if (currentVelocity > 3000) { - yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier()); + yacht.changeVelocity( + (-currentVelocity / 200) * yacht.getBoatTypeAccelerationMultiplier()); } else if (currentVelocity > 100) { - yacht.changeVelocity((-currentVelocity / 50) * yacht.getAccelerationMultiplier()); + yacht.changeVelocity( + (-currentVelocity / 50) * yacht.getBoatTypeAccelerationMultiplier()); } else if (currentVelocity <= 100) { yacht.setCurrentVelocity(0d); } diff --git a/src/main/java/seng302/model/ServerYacht.java b/src/main/java/seng302/model/ServerYacht.java index d1f36c7c..ee692d63 100644 --- a/src/main/java/seng302/model/ServerYacht.java +++ b/src/main/java/seng302/model/ServerYacht.java @@ -11,10 +11,6 @@ import seng302.utilities.GeoUtility; import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; import java.util.HashMap; -import java.util.Objects; -import java.util.Observable; -import java.util.Observer; -import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; /** * Yacht class for the racing boat.

Class created to store more variables (eg. boat statuses) @@ -28,9 +24,9 @@ public class ServerYacht { //Boat info private BoatMeshType boatType; private Double turnStep = 5.0; - private Double maxSpeedMultiplier = 1.0; - private Double turnStepMultiplier = 1.0; - private Double accelerationMultiplier = 1.0; + private Double boatTypeSpeedMultiplier = 1.0; + private Double boatTypeTurnStepMultiplier = 1.0; + private Double boatTypeAccelerationMultiplier = 1.0; private Integer sourceId; private String hullID; //matches HullNum in the XML spec. private String shortName; @@ -60,8 +56,8 @@ public class ServerYacht { //PowerUp private TokenType powerUp; private Long powerUpStartTime; - private Integer speedMultiplier; - private Integer handlingMultiplier; + private Integer powerUpSpeedMultiplier; + private Integer powerUpHandlingMultiplier; public ServerYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName, @@ -83,8 +79,8 @@ public class ServerYacht { this.legNumber = 0; this.boatColor = Colors.getColor(sourceId - 1); this.powerUp = null; - this.speedMultiplier = 1; - this.handlingMultiplier = 1; + this.powerUpSpeedMultiplier = 1; + this.powerUpHandlingMultiplier = 1; this.hasEnteredRoundingZone = false; this.hasPassedLine = false; @@ -122,8 +118,8 @@ public class ServerYacht { public void powerDown() { this.powerUp = null; - this.speedMultiplier = 1; - this.handlingMultiplier = 1; + this.powerUpSpeedMultiplier = 1; + this.powerUpHandlingMultiplier = 1; } public Long getPowerUpStartTime() { @@ -140,7 +136,7 @@ public class ServerYacht { * @param amount the amount by which to adjust the boat heading. */ public void adjustHeading(Double amount) { - Double newVal = heading + amount * handlingMultiplier * turnStepMultiplier; + Double newVal = heading + amount * powerUpHandlingMultiplier * boatTypeTurnStepMultiplier; lastHeading = heading; heading = (double) Math.floorMod(newVal.longValue(), 360L); } @@ -433,18 +429,18 @@ public class ServerYacht { } public void setBoatType(BoatMeshType boatType) { - this.accelerationMultiplier = boatType.accelerationMultiplier; - this.maxSpeedMultiplier = boatType.maxSpeedMultiplier; - this.turnStepMultiplier = boatType.turnStep; + this.boatTypeAccelerationMultiplier = boatType.accelerationMultiplier; + this.boatTypeSpeedMultiplier = boatType.maxSpeedMultiplier; + this.boatTypeTurnStepMultiplier = boatType.turnStep; this.boatType = boatType; } - public Double getMaxSpeedMultiplier() { - return maxSpeedMultiplier; + public Double getBoatTypeSpeedMultiplier() { + return boatTypeSpeedMultiplier; } - public Double getAccelerationMultiplier(){ - return accelerationMultiplier; + public Double getBoatTypeAccelerationMultiplier() { + return boatTypeAccelerationMultiplier; } @@ -452,19 +448,19 @@ public class ServerYacht { return boatType; } - public Integer getSpeedMultiplier() { - return speedMultiplier; + public Integer getPowerUpSpeedMultiplier() { + return powerUpSpeedMultiplier; } - public void setSpeedMultiplier(Integer speedMultiplier) { - this.speedMultiplier = speedMultiplier; + public void setPowerUpSpeedMultiplier(Integer powerUpSpeedMultiplier) { + this.powerUpSpeedMultiplier = powerUpSpeedMultiplier; } - public Integer getHandlingMultiplier() { - return handlingMultiplier; + public Integer getPowerUpHandlingMultiplier() { + return powerUpHandlingMultiplier; } - public void setHandlingMultiplier(Integer handlingMultiplier) { - this.handlingMultiplier = handlingMultiplier; + public void setPowerUpHandlingMultiplier(Integer powerUpHandlingMultiplier) { + this.powerUpHandlingMultiplier = powerUpHandlingMultiplier; } } From 0211f2df38384c61a5e6c3967c0e74fd25d0f290 Mon Sep 17 00:00:00 2001 From: William Muir Date: Mon, 25 Sep 2017 17:38:09 +1300 Subject: [PATCH 14/21] Merged dev back on #story[1293] --- .../java/seng302/gameServer/GameState.java | 2 + src/main/resources/views/RaceView.fxml | 553 +++++++++--------- 2 files changed, 277 insertions(+), 278 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index fe603783..a8a4c642 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import javafx.scene.paint.Color; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index 03728bde..9a02f517 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -24,285 +24,282 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + \ No newline at end of file From 7a4cdbe0c9b0c47ec46be06391bcb57b2833e617 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 26 Sep 2017 11:12:29 +1300 Subject: [PATCH 15/21] Fixed WindWalker #story[1293] --- .../java/seng302/gameServer/GameState.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index a8a4c642..a7026682 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -81,6 +81,7 @@ public class GameState implements Runnable { private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; private static final Integer HANDLING_BOOST_MULTIPLIER = 2; public static final Long BUMPER_DISABLE_TIME = 5_000L; + private static final Long TOKEN_SPAWN_TIME = 15_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -297,7 +298,7 @@ public class GameState implements Runnable { spawnNewToken(); notifyMessageListeners(MessageFactory.getRaceXML()); } - }, 0, 15_000); + }, 0, TOKEN_SPAWN_TIME); } // TODO: 29/08/17 wmu16 - This sort of update should be in game state @@ -382,7 +383,7 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); token.assignRandomType(); -// token.assignType(TokenType.BUMPER); + token.assignType(TokenType.WIND_WALKER); logger.debug("Spawned token of type " + token.getTokenType()); @@ -508,21 +509,7 @@ public class GameState implements Runnable { } Double heading = yacht.getHeading(); - if (heading < windDirection) { - Double diff = Math.abs(optimalAngle - (windDirection - heading)); - if (windDirection - heading < optimalAngle) { - windDirection = (double) Math.floorMod(Math.round(windDirection + diff), 360L); - } else { - windDirection = (double) Math.floorMod(Math.round(windDirection - diff), 360L); - } - } else { - Double diff = Math.abs(optimalAngle - (heading - windDirection)); - if (heading - windDirection < optimalAngle) { - windDirection = (double) Math.floorMod(Math.round(windDirection - diff), 360L); - } else { - windDirection = (double) Math.floorMod(Math.round(windDirection + diff), 360L); - } - } + windDirection = (double) Math.floorMod(Math.round(heading + optimalAngle), 360L); } From 8ba44d7476a718a964a56d1ea577861333a29b34 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 26 Sep 2017 17:19:45 +1300 Subject: [PATCH 16/21] Minor commit for testing #story[1293] --- .../java/seng302/gameServer/GameState.java | 4 +-- .../gameServer/ServerToClientThread.java | 32 ++----------------- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index a7026682..ec761931 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -382,8 +382,8 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); - token.assignRandomType(); - token.assignType(TokenType.WIND_WALKER); +// token.assignRandomType(); + token.assignType(TokenType.BUMPER); logger.debug("Spawned token of type " + token.getTokenType()); diff --git a/src/main/java/seng302/gameServer/ServerToClientThread.java b/src/main/java/seng302/gameServer/ServerToClientThread.java index eb5a9ad0..09923b57 100644 --- a/src/main/java/seng302/gameServer/ServerToClientThread.java +++ b/src/main/java/seng302/gameServer/ServerToClientThread.java @@ -78,7 +78,6 @@ public class ServerToClientThread implements Runnable { private List connectionListeners = new ArrayList<>(); private DisconnectListener disconnectListener; - private ServerYacht yacht; private Player player; public ServerToClientThread(Socket socket) { @@ -101,33 +100,12 @@ public class ServerToClientThread implements Runnable { } private void setUpPlayer(){ - BufferedReader fn; - String fName = ""; - BufferedReader ln; - String lName = ""; + String shortName = "p" + sourceId; + String longName = "player " + sourceId; - fn = new BufferedReader( - new InputStreamReader( - ServerToClientThread.class.getResourceAsStream( - "/server_config/CSV_Database_of_First_Names.csv" - ) - ) - ); - List all = fn.lines().collect(Collectors.toList()); - fName = all.get(ThreadLocalRandom.current().nextInt(0, all.size())); - ln = new BufferedReader( - new InputStreamReader( - ServerToClientThread.class.getResourceAsStream( - "/server_config/CSV_Database_of_Last_Names.csv" - ) - ) - ); - all = ln.lines().collect(Collectors.toList()); - lName = all.get(ThreadLocalRandom.current().nextInt(0, all.size())); ServerYacht yacht = new ServerYacht( - BoatMeshType.DINGHY, sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ" - ); + BoatMeshType.DINGHY, sourceId, sourceId.toString(), shortName, longName, "NZ"); player = new Player(socket, yacht); GameState.addYacht(sourceId, yacht); @@ -318,10 +296,6 @@ public class ServerToClientThread implements Runnable { return socket; } - public ServerYacht getYacht() { - return yacht; - } - public void addConnectionListener(ConnectionListener listener) { connectionListeners.add(listener); } From b5076bc9762d83a01d625158ce2a7392a2511360 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 26 Sep 2017 18:57:15 +1300 Subject: [PATCH 17/21] Fixed wind walker and bumper Added a hack to bumper so that the collision distance is larger than the regular collision distance Wind walker now makes you go at you max speed rather than VMG speed #story[1293] --- .../java/seng302/gameServer/GameState.java | 29 +++++++------ src/main/java/seng302/model/PolarTable.java | 41 +++++++++++++++++-- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index ec761931..56f01fe1 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -382,8 +382,8 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); -// token.assignRandomType(); - token.assignType(TokenType.BUMPER); + token.assignRandomType(); +// token.assignType(TokenType.WIND_WALKER); logger.debug("Spawned token of type " + token.getTokenType()); @@ -440,8 +440,9 @@ public class GameState implements Runnable { windWalk(yacht); break; case BUMPER: - ServerYacht collidedYacht = checkYachtCollision(yacht); + ServerYacht collidedYacht = checkYachtCollision(yacht, true); if (collidedYacht != null) { + System.out.println("WE OUT HERE"); yacht.powerDown(); boatTempShutDown(collidedYacht); notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); @@ -497,17 +498,12 @@ public class GameState implements Runnable { /** * This function changes the wind to be at an angle that causes the yacht in question to be at - * VMG. + * its fastest velocity * * @param yacht The yacht to fix the wind for */ private void windWalk(ServerYacht yacht) { - HashMap upwindOptimal = PolarTable.getOptimalUpwindVMG(windSpeed); - Double optimalAngle = null; - for (Double windAngle : upwindOptimal.keySet()) { - optimalAngle = windAngle; - } - + Double optimalAngle = PolarTable.getOptimalAngle(); Double heading = yacht.getHeading(); windDirection = (double) Math.floorMod(Math.round(heading + optimalAngle), 360L); } @@ -597,7 +593,7 @@ public class GameState implements Runnable { */ public static void checkCollision(ServerYacht serverYacht) { //Yacht Collision - ServerYacht collidedYacht = checkYachtCollision(serverYacht); + ServerYacht collidedYacht = checkYachtCollision(serverYacht, false); Mark collidedMark = checkMarkCollision(serverYacht); if (collidedYacht != null) { @@ -946,15 +942,22 @@ public class GameState implements Runnable { * Collision detection which iterates through all the yachts and check if any yacht collided * with this yacht. Return collided yacht or null if no collision. * + * UPDATE: HACK!!! wmu16 - forBumperCollision is (the goddamn dirtiest) dirty flag to fix a + * weird bug where the bumper collision would not be registerd but the knock back collision would. + * In other words, only set the 'forBumperCollision' flag true if used for the bumper power up. + * * @return yacht to compare to all other yachts. */ - private static ServerYacht checkYachtCollision(ServerYacht yacht) { + private static ServerYacht checkYachtCollision(ServerYacht yacht, Boolean forBumperCollision) { + Double collisionDistance = + (forBumperCollision) ? YACHT_COLLISION_DISTANCE + 2.5 : YACHT_COLLISION_DISTANCE; for (ServerYacht otherYacht : GameState.getYachts().values()) { if (otherYacht != yacht) { Double distance = GeoUtility .getDistance(otherYacht.getLocation(), yacht.getLocation()); - if (distance < YACHT_COLLISION_DISTANCE) { + ; + if (distance < collisionDistance) { return otherYacht; } } diff --git a/src/main/java/seng302/model/PolarTable.java b/src/main/java/seng302/model/PolarTable.java index 9334cc54..6d91cd71 100644 --- a/src/main/java/seng302/model/PolarTable.java +++ b/src/main/java/seng302/model/PolarTable.java @@ -4,7 +4,9 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Collections; import java.util.HashMap; +import java.util.Map; /** * A static class for parsing and storing the polars. Will parse the whole polar table and also store the optimised @@ -17,6 +19,7 @@ public final class PolarTable { private static HashMap> polarTable; private static HashMap> upwindOptimal; private static HashMap> downwindOptimal; + private static Double optimalAngle; private static int upTwaIndex; private static int dnTwaIndex; @@ -33,11 +36,13 @@ public final class PolarTable { upwindOptimal = new HashMap<>(); downwindOptimal = new HashMap<>(); - String line; + String line = null; + String check; Boolean isHeaderLine = true; try (BufferedReader br = new BufferedReader(new InputStreamReader(polarFile))) { - while ((line = br.readLine()) != null) { + while ((check = br.readLine()) != null) { + line = check; String[] thisLine = line.split(","); //Initial line in file @@ -66,7 +71,10 @@ public final class PolarTable { upwindOptimal.put(thisWindSpeed, thisUpWindPolar); downwindOptimal.put(thisWindSpeed, thisDnWindPolar); } + + } + getMaxSpeedAngle(line); } catch (IOException e) { System.out.println("[PolarTable] IO exception"); @@ -74,6 +82,27 @@ public final class PolarTable { } + /** + * Passes the final line of the polar table and iterates over the speeds for each + * angle, velocity pair to find the angle that produces the highest velocity + * + * @param line The last line of the polar file + */ + private static void getMaxSpeedAngle(String line) { + String[] theLastLine = line.split(","); + Double maxWindVal = Double.parseDouble(theLastLine[0]); + Double optimalAngle = Double.parseDouble(theLastLine[1]); + Double maxSpeed = Double.parseDouble(theLastLine[2]); + for (Map.Entry entry : polarTable.get(maxWindVal).entrySet()) { + if (entry.getValue() > maxSpeed) { + maxSpeed = entry.getValue(); + optimalAngle = entry.getKey(); + } + } + PolarTable.optimalAngle = optimalAngle; + } + + /** * Parses the header line of a polar file @@ -85,14 +114,18 @@ public final class PolarTable { String thisItem = thisLine[i]; if (thisItem.toLowerCase().startsWith("uptwa")) { upTwaIndex = i; - } - else if (thisItem.toLowerCase().startsWith("dntwa")) { + } else if (thisItem.toLowerCase().startsWith("dntwa")) { dnTwaIndex = i; } } } + public static Double getOptimalAngle() { + return optimalAngle; + } + + /** * @return The entire polar table */ From 4b7dfe38c491c9d57e119a26fedc2a4e6b28eabd Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 26 Sep 2017 19:43:32 +1300 Subject: [PATCH 18/21] Fixed Boats powering up and down correctly. Icons respond correctly #story[1293] --- .../java/seng302/gameServer/GameState.java | 18 ++---------------- src/main/java/seng302/model/ServerYacht.java | 18 ++++++++++++++++++ .../controllers/RaceViewController.java | 5 +++++ src/main/resources/meshes/turning_pickup.dae | 14 +++++++------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index 56f01fe1..afd3a4e7 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -78,8 +78,8 @@ public class GameState implements Runnable { private static final Double COLLISION_VELOCITY_PENALTY = 0.3; //Powerup Constants - private static final Integer VELOCITY_BOOST_MULTIPLIER = 2; - private static final Integer HANDLING_BOOST_MULTIPLIER = 2; + public static final Integer VELOCITY_BOOST_MULTIPLIER = 2; + public static final Integer HANDLING_BOOST_MULTIPLIER = 2; public static final Long BUMPER_DISABLE_TIME = 5_000L; private static final Long TOKEN_SPAWN_TIME = 15_000L; @@ -550,20 +550,6 @@ public class GameState implements Runnable { } TokenType tokenType = collidedToken.getTokenType(); - switch (tokenType) { - case BOOST: - yacht.setPowerUpSpeedMultiplier(VELOCITY_BOOST_MULTIPLIER); - break; - case BUMPER: - // TODO: 22/09/17 wmu16 - break; - case HANDLING: - yacht.setPowerUpHandlingMultiplier(HANDLING_BOOST_MULTIPLIER); - break; - case WIND_WALKER: - // TODO: 22/09/17 wmu16 - break; - } yacht.powerUp(tokenType); String logMessage = diff --git a/src/main/java/seng302/model/ServerYacht.java b/src/main/java/seng302/model/ServerYacht.java index 8d77dbda..0b15cb08 100644 --- a/src/main/java/seng302/model/ServerYacht.java +++ b/src/main/java/seng302/model/ServerYacht.java @@ -112,11 +112,29 @@ public class ServerYacht { location = geoPoint; } + /** + * Powers up a yacht with a given yacht, only after powering it down first to avoid double power + * ups + * + * @param powerUp The given power up + */ public void powerUp(TokenType powerUp) { + powerDown(); + switch (powerUp) { + case BOOST: + powerUpSpeedMultiplier = GameState.VELOCITY_BOOST_MULTIPLIER; + break; + case HANDLING: + powerUpHandlingMultiplier = GameState.HANDLING_BOOST_MULTIPLIER; + break; + } this.powerUp = powerUp; powerUpStartTime = System.currentTimeMillis(); } + /** + * Powers down a yacht, returning its power multipliers back to 1 + */ public void powerDown() { this.powerUp = null; this.powerUpSpeedMultiplier = 1; diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index 76de92d3..716bc9fd 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -55,6 +55,7 @@ import seng302.model.RaceState; import seng302.model.mark.CompoundMark; import seng302.model.mark.Mark; import seng302.model.stream.xml.parser.RaceXMLData; +import seng302.model.token.Token; import seng302.model.token.TokenType; import seng302.utilities.Sounds; import seng302.visualiser.GameView3D; @@ -307,6 +308,9 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel */ private void displayPowerUpIcon(ClientYacht yacht, TokenType tokenType) { if (yacht == player) { + if (iconToDisplay != null) { + iconToDisplay.setVisible(false); + } switch (tokenType) { case BOOST: @@ -349,6 +353,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel if (yacht == player) { blinkingTimer.cancel(); iconToDisplay.setVisible(false); + iconToDisplay = null; } } diff --git a/src/main/resources/meshes/turning_pickup.dae b/src/main/resources/meshes/turning_pickup.dae index 2c4305f5..24e9fa08 100644 --- a/src/main/resources/meshes/turning_pickup.dae +++ b/src/main/resources/meshes/turning_pickup.dae @@ -5,8 +5,8 @@ Blender User Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22 - 2017-09-19T15:45:46 - 2017-09-19T15:45:46 + 2017-09-26T19:13:35 + 2017-09-26T19:13:35 Z_UP @@ -23,10 +23,10 @@ 0 0 0 1 - 0.004555753 0.0885511 0.003947978 1 + 0.01630632 0.52949 0.0134405 1 - 0.25 0.25 0.25 1 + 0.125 0.125 0.125 1 50 @@ -49,10 +49,10 @@ 0 0 0 1 - 0.64 0.1458963 0.001825521 1 + 0.64 0.5334254 0 1 - 0.25 0.25 0.25 1 + 0.125 0.125 0.125 1 50 @@ -87,7 +87,7 @@ - 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 + 0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284252 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616992 0.7240421 0.1947362 0.6616954 0.4911194 0.356821 0.7946576 0.4089462 0.6284253 0.6616984 -0.1875943 0.5773454 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875943 -0.5773454 0.7946577 0.03853034 -0.7487788 0.6616992 0.4911193 -0.356821 0.7946577 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875943 0.5773454 -0.7946577 -0.0385304 0.7487789 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911193 0.356821 -0.7946577 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911194 -0.356821 -0.7946576 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487789 -0.6616991 0.1875943 -0.5773454 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150898 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150899 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524 From 330ccd272d6ea129835fb3eca13be3e383c0a796 Mon Sep 17 00:00:00 2001 From: William Muir Date: Tue, 26 Sep 2017 21:13:35 +1300 Subject: [PATCH 19/21] The random token now has a 50% chance of causing your boat to have a speed penalty #story[1293] --- .../java/seng302/gameServer/GameState.java | 71 ++++++----- .../gameServer/messages/YachtEventType.java | 2 +- src/main/java/seng302/model/ServerYacht.java | 10 +- .../java/seng302/visualiser/GameView3D.java | 46 +++---- .../controllers/RaceViewController.java | 5 +- src/main/resources/views/RaceView.fxml | 116 +++++++++--------- 6 files changed, 131 insertions(+), 119 deletions(-) diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index afd3a4e7..dfb8dae4 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -78,10 +78,11 @@ public class GameState implements Runnable { private static final Double COLLISION_VELOCITY_PENALTY = 0.3; //Powerup Constants - public static final Integer VELOCITY_BOOST_MULTIPLIER = 2; + public static final Double VELOCITY_BOOST_MULTIPLIER = 2d; public static final Integer HANDLING_BOOST_MULTIPLIER = 2; + private static final Double BAD_RANDOM_SPEED_PENALTY = 0.3; public static final Long BUMPER_DISABLE_TIME = 5_000L; - private static final Long TOKEN_SPAWN_TIME = 15_000L; + private static final Long TOKEN_SPAWN_TIME = 30_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -383,7 +384,7 @@ public class GameState implements Runnable { //Get a random token location with random type Token token = allTokens.get(random.nextInt(allTokens.size())); token.assignRandomType(); -// token.assignType(TokenType.WIND_WALKER); +// token.assignType(TokenType.RANDOM); logger.debug("Spawned token of type " + token.getTokenType()); @@ -430,7 +431,12 @@ public class GameState implements Runnable { * @param yacht The yacht to perform token checks on */ private void preformTokenUpdates(ServerYacht yacht) { - checkTokenPickUp(yacht); + Token collidedToken = checkTokenPickUp(yacht); + if (collidedToken != null) { + tokensInPlay.remove(collidedToken); + powerUpYacht(yacht, collidedToken); + } + checkPowerUpTimeout(yacht); TokenType powerUp = yacht.getPowerUp(); @@ -442,7 +448,6 @@ public class GameState implements Runnable { case BUMPER: ServerYacht collidedYacht = checkYachtCollision(yacht, true); if (collidedYacht != null) { - System.out.println("WE OUT HERE"); yacht.powerDown(); boatTempShutDown(collidedYacht); notifyMessageListeners(MessageFactory.makePowerDownMessage(yacht)); @@ -450,10 +455,36 @@ public class GameState implements Runnable { MessageFactory.makeStatusEffectMessage(collidedYacht, powerUp)); } break; + case RANDOM: + yacht.setPowerUpSpeedMultiplier(BAD_RANDOM_SPEED_PENALTY); } } } + + /** + * Powers up a yacht with the given token type. + * + * @param yacht The yacht to be powered up + * @param collidedToken The token which this yacht collided with + */ + private void powerUpYacht(ServerYacht yacht, Token collidedToken) { + //The random token has a 50% chance of becoming another token else becoming a speed detriment! + if (collidedToken.getTokenType() == TokenType.RANDOM && new Random().nextBoolean()) { + collidedToken.realiseRandom(); + } + + yacht.powerUp(collidedToken.getTokenType()); + String logMessage = + yacht.getBoatName() + " has picked up a " + collidedToken.getTokenType().getName() + + " token"; + notifyMessageListeners(MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); + notifyMessageListeners(MessageFactory.getRaceXML()); + notifyMessageListeners(MessageFactory.makePickupMessage(yacht, collidedToken)); + logger.debug( + "Yacht: " + yacht.getShortName() + " got powerup " + collidedToken.getTokenType()); + } + // TODO: 23/09/17 wmu16 - This is a hacky way to have the boat power down. Need some sort of separation between token and status effect :/ /** @@ -462,7 +493,7 @@ public class GameState implements Runnable { * @param yacht The yacht to disable */ private void boatTempShutDown(ServerYacht yacht) { - yacht.setPowerUpSpeedMultiplier(0); + yacht.setPowerUpSpeedMultiplier(0d); Timer shutDownTimer = new Timer("Shutdown Timer"); shutDownTimer.schedule(new TimerTask() { @Override @@ -533,36 +564,18 @@ public class GameState implements Runnable { * Checks all tokensInPlay to see if a yacht has picked one up. If so, the yacht is powered up * in the appropriate way * @param yacht The yacht to check for collision with a token + * + * @return The token collided with */ - private void checkTokenPickUp(ServerYacht yacht) { - Token collidedToken = null; + private Token checkTokenPickUp(ServerYacht yacht) { for (Token token : tokensInPlay) { Double distance = GeoUtility.getDistance(token, yacht.getLocation()); if (distance < YACHT_COLLISION_DISTANCE) { - collidedToken = token; + return token; } } - if (collidedToken != null) { - tokensInPlay.remove(collidedToken); - if (collidedToken.getTokenType() == TokenType.RANDOM) { - collidedToken.realiseRandom(); - } - - TokenType tokenType = collidedToken.getTokenType(); - yacht.powerUp(tokenType); - - String logMessage = - yacht.getBoatName() + " has picked up a " + collidedToken.getTokenType().getName() - + " token"; - notifyMessageListeners( - MessageFactory.makeChatterMessage(yacht.getSourceId(), logMessage)); - notifyMessageListeners(MessageFactory.getRaceXML()); - notifyMessageListeners(MessageFactory.makePickupMessage(yacht, collidedToken)); - - logger.debug("Yacht: " + yacht.getShortName() + " got powerup " + collidedToken - .getTokenType()); - } + return null; } diff --git a/src/main/java/seng302/gameServer/messages/YachtEventType.java b/src/main/java/seng302/gameServer/messages/YachtEventType.java index facda84e..9fd5170b 100644 --- a/src/main/java/seng302/gameServer/messages/YachtEventType.java +++ b/src/main/java/seng302/gameServer/messages/YachtEventType.java @@ -1,7 +1,7 @@ package seng302.gameServer.messages; /** - * Created by wmu16 on 11/09/17. + * Enum for different event types for the yacht */ public enum YachtEventType { COLLISION(33), diff --git a/src/main/java/seng302/model/ServerYacht.java b/src/main/java/seng302/model/ServerYacht.java index 0b15cb08..c092447d 100644 --- a/src/main/java/seng302/model/ServerYacht.java +++ b/src/main/java/seng302/model/ServerYacht.java @@ -55,7 +55,7 @@ public class ServerYacht { //PowerUp private TokenType powerUp; private Long powerUpStartTime; - private Integer powerUpSpeedMultiplier; + private Double powerUpSpeedMultiplier; private Integer powerUpHandlingMultiplier; //turning mode @@ -80,7 +80,7 @@ public class ServerYacht { this.legNumber = 0; this.boatColor = Colors.getColor(sourceId - 1); this.powerUp = null; - this.powerUpSpeedMultiplier = 1; + this.powerUpSpeedMultiplier = 1d; this.powerUpHandlingMultiplier = 1; this.hasEnteredRoundingZone = false; this.hasPassedLine = false; @@ -137,7 +137,7 @@ public class ServerYacht { */ public void powerDown() { this.powerUp = null; - this.powerUpSpeedMultiplier = 1; + this.powerUpSpeedMultiplier = 1d; this.powerUpHandlingMultiplier = 1; } @@ -480,11 +480,11 @@ public class ServerYacht { this.continuouslyTurning = continuouslyTurning; } - public Integer getPowerUpSpeedMultiplier() { + public Double getPowerUpSpeedMultiplier() { return powerUpSpeedMultiplier; } - public void setPowerUpSpeedMultiplier(Integer powerUpSpeedMultiplier) { + public void setPowerUpSpeedMultiplier(Double powerUpSpeedMultiplier) { this.powerUpSpeedMultiplier = powerUpSpeedMultiplier; } diff --git a/src/main/java/seng302/visualiser/GameView3D.java b/src/main/java/seng302/visualiser/GameView3D.java index 027e92ad..5978675c 100644 --- a/src/main/java/seng302/visualiser/GameView3D.java +++ b/src/main/java/seng302/visualiser/GameView3D.java @@ -417,28 +417,30 @@ public class GameView3D { public void cameraMovement(KeyEvent event) { GameKeyBind keyBinds = GameKeyBind.getInstance(); KeyAction keyPressed = keyBinds.getKeyAction(event.getCode()); - switch (keyPressed) { - case ZOOM_IN: - ((RaceCamera) view.getCamera()).zoomIn(); - break; - case ZOOM_OUT: - ((RaceCamera) view.getCamera()).zoomOut(); - break; - case FORWARD: - ((RaceCamera) view.getCamera()).panUp(); - break; - case BACKWARD: - ((RaceCamera) view.getCamera()).panDown(); - break; - case LEFT: - ((RaceCamera) view.getCamera()).panLeft(); - break; - case RIGHT: - ((RaceCamera) view.getCamera()).panRight(); - break; - case VIEW: - toggleCamera(); - break; + if (keyPressed != null) { + switch (keyPressed) { + case ZOOM_IN: + ((RaceCamera) view.getCamera()).zoomIn(); + break; + case ZOOM_OUT: + ((RaceCamera) view.getCamera()).zoomOut(); + break; + case FORWARD: + ((RaceCamera) view.getCamera()).panUp(); + break; + case BACKWARD: + ((RaceCamera) view.getCamera()).panDown(); + break; + case LEFT: + ((RaceCamera) view.getCamera()).panLeft(); + break; + case RIGHT: + ((RaceCamera) view.getCamera()).panRight(); + break; + case VIEW: + toggleCamera(); + break; + } } } diff --git a/src/main/java/seng302/visualiser/controllers/RaceViewController.java b/src/main/java/seng302/visualiser/controllers/RaceViewController.java index 716bc9fd..7395d5df 100644 --- a/src/main/java/seng302/visualiser/controllers/RaceViewController.java +++ b/src/main/java/seng302/visualiser/controllers/RaceViewController.java @@ -121,7 +121,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel @FXML private Label positionLabel, boatSpeedLabel, boatHeadingLabel; @FXML - private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon; + private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon, badRandomIcon; //Race Data private Map participants; @@ -325,6 +325,9 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel case BUMPER: iconToDisplay = bumperIcon; break; + case RANDOM: + iconToDisplay = badRandomIcon; + break; default: iconToDisplay = velocityIcon; } diff --git a/src/main/resources/views/RaceView.fxml b/src/main/resources/views/RaceView.fxml index 9a02f517..7e53d81b 100644 --- a/src/main/resources/views/RaceView.fxml +++ b/src/main/resources/views/RaceView.fxml @@ -25,9 +25,8 @@ @@ -48,17 +47,15 @@ valignment="BOTTOM" vgrow="SOMETIMES"/> - + - + - + @@ -90,25 +87,20 @@ - - + + - + - + - + - + @@ -131,18 +123,16 @@ minWidth="90.0" prefWidth="90.0"/> - + - + - + - + - + - \ No newline at end of file + From 6d51ea35745d465db2ccea5a24d2d3422fcfa1a1 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 27 Sep 2017 01:44:01 +1300 Subject: [PATCH 20/21] Created a random place token generator. Generates a location between any leg of the race in a random angle / distance of the radius of the centre point of the two gates to one of the gates #story[1293] --- .../java/seng302/gameServer/GameState.java | 47 +++----------- .../java/seng302/model/mark/MarkOrder.java | 14 ++-- src/main/java/seng302/model/token/Token.java | 13 ++++ .../java/seng302/utilities/RandomSpawn.java | 64 +++++++++++++++++++ 4 files changed, 97 insertions(+), 41 deletions(-) create mode 100644 src/main/java/seng302/utilities/RandomSpawn.java diff --git a/src/main/java/seng302/gameServer/GameState.java b/src/main/java/seng302/gameServer/GameState.java index dfb8dae4..5236a14e 100644 --- a/src/main/java/seng302/gameServer/GameState.java +++ b/src/main/java/seng302/gameServer/GameState.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -38,6 +39,7 @@ import seng302.model.mark.MarkOrder; import seng302.model.token.Token; import seng302.model.token.TokenType; import seng302.utilities.GeoUtility; +import seng302.utilities.RandomSpawn; import seng302.utilities.XMLParser; import seng302.visualiser.fxObjects.assets_3D.BoatMeshType; @@ -82,7 +84,7 @@ public class GameState implements Runnable { public static final Integer HANDLING_BOOST_MULTIPLIER = 2; private static final Double BAD_RANDOM_SPEED_PENALTY = 0.3; public static final Long BUMPER_DISABLE_TIME = 5_000L; - private static final Long TOKEN_SPAWN_TIME = 30_000L; + private static final Long TOKEN_SPAWN_TIME = 15_000L; private static Long previousUpdateTime; public static Double windDirection; @@ -99,13 +101,12 @@ public class GameState implements Runnable { private static GameStages currentStage; private static MarkOrder markOrder; private static long startTime; - private static Set marks; + private static List marks; private static List courseLimit; private static Integer maxPlayers = 8; - - private static List allTokens; private static List tokensInPlay; + private static RandomSpawn randomSpawn; private static List newMessageListeners; @@ -126,14 +127,12 @@ public class GameState implements Runnable { previousUpdateTime = System.currentTimeMillis(); markOrder = new MarkOrder(); //This could be instantiated at some point with a select map? newMessageListeners = new ArrayList<>(); - allTokens = makeTokens(); + marks = new MarkOrder().getAllMarks(); + randomSpawn = new RandomSpawn(markOrder.getOrderedUniqueCompoundMarks()); resetStartTime(); - - new Thread(this, "GameState").start(); //Run the auto updates on the game state - - marks = new MarkOrder().getAllMarks(); setCourseLimit("/server_config/race.xml"); + new Thread(this, "GameState").start(); //Run the auto updates on the game state } private void setCourseLimit(String url) { @@ -151,29 +150,10 @@ public class GameState implements Runnable { courseLimit = XMLParser.parseRace(document).getCourseLimit(); } - - /** - * Make a pre defined set of tokensInPlay. //TODO wmu16 - Should read from some file for each - * race ideally - * - * @return A list of possible tokensInPlay for this race - */ - private ArrayList makeTokens() { - Token token1 = new Token(TokenType.BOOST, 57.66946, 11.83154); - Token token2 = new Token(TokenType.BOOST, 57.66877, 11.83382); - Token token3 = new Token(TokenType.BOOST, 57.66914, 11.83965); - Token token4 = new Token(TokenType.BOOST, 57.66684, 11.83214); - return new ArrayList<>(Arrays.asList(token1, token2, token3, token4)); - } - public static String getHostIpAddress() { return hostIpAddress; } - public static Set getMarks() { - return Collections.unmodifiableSet(marks); - } - public static List getPlayers() { return players; } @@ -378,16 +358,9 @@ public class GameState implements Runnable { * Broadasts a new race status message to show this update */ private void spawnNewToken() { - Random random = new Random(); tokensInPlay.clear(); - - //Get a random token location with random type - Token token = allTokens.get(random.nextInt(allTokens.size())); - token.assignRandomType(); -// token.assignType(TokenType.RANDOM); - + Token token = randomSpawn.getRandomTokenLocation(); logger.debug("Spawned token of type " + token.getTokenType()); - tokensInPlay.add(token); } @@ -912,7 +885,7 @@ public class GameState implements Runnable { } private static Mark checkMarkCollision(ServerYacht yacht) { - Set marksInRace = GameState.getMarks(); + Set marksInRace = new HashSet<>(marks); for (Mark mark : marksInRace) { if (GeoUtility.getDistance(yacht.getLocation(), mark) <= MARK_COLLISION_DISTANCE) { diff --git a/src/main/java/seng302/model/mark/MarkOrder.java b/src/main/java/seng302/model/mark/MarkOrder.java index 0e250e99..7f296aee 100644 --- a/src/main/java/seng302/model/mark/MarkOrder.java +++ b/src/main/java/seng302/model/mark/MarkOrder.java @@ -24,8 +24,9 @@ import java.util.*; */ public class MarkOrder { private List raceMarkOrder; + private List orderedUniqueCompoundMarks; private Logger logger = LoggerFactory.getLogger(MarkOrder.class); - private Set allMarks; + private List allMarks; public MarkOrder(){ loadRaceProperties(); @@ -44,6 +45,10 @@ public class MarkOrder { return Collections.unmodifiableList(raceMarkOrder); } + public List getOrderedUniqueCompoundMarks() { + return orderedUniqueCompoundMarks; + } + /** * @param seqID The seqID of the current mark the boat is heading to * @return A Boolean indicating if this coming mark is the last one (finish line) @@ -75,8 +80,8 @@ public class MarkOrder { return raceMarkOrder.get(currentSeqID + 1); } - public Set getAllMarks(){ - return Collections.unmodifiableSet(allMarks); + public List getAllMarks() { + return Collections.unmodifiableList(allMarks); } /** @@ -89,7 +94,7 @@ public class MarkOrder { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; Document doc; - allMarks = new HashSet<>(); + allMarks = new ArrayList<>(); try { db = dbf.newDocumentBuilder(); @@ -105,6 +110,7 @@ public class MarkOrder { logger.debug("Loaded RaceXML for mark order"); List corners = data.getMarkSequence(); Map marks = data.getCompoundMarks(); + orderedUniqueCompoundMarks = new ArrayList<>(marks.values()); List course = new ArrayList<>(); for (Corner corner : corners){ CompoundMark compoundMark = marks.get(corner.getCompoundMarkID()); diff --git a/src/main/java/seng302/model/token/Token.java b/src/main/java/seng302/model/token/Token.java index ed8b87eb..0e6e86b8 100644 --- a/src/main/java/seng302/model/token/Token.java +++ b/src/main/java/seng302/model/token/Token.java @@ -15,11 +15,24 @@ public class Token extends GeoPoint { private TokenType tokenType; private Random random = new Random(); + //Constructor for creating a specific type client side public Token(TokenType tokenType, double lat, double lng) { super(lat, lng); this.tokenType = tokenType; } + //Making random type server side + public Token(double lat, double lng) { + super(lat, lng); + assignRandomType(); + } + + //Making random type server side + public Token(GeoPoint geoPoint) { + super(geoPoint.getLat(), geoPoint.getLng()); + assignRandomType(); + } + public TokenType getTokenType() { return tokenType; } diff --git a/src/main/java/seng302/utilities/RandomSpawn.java b/src/main/java/seng302/utilities/RandomSpawn.java new file mode 100644 index 00000000..0a0f0702 --- /dev/null +++ b/src/main/java/seng302/utilities/RandomSpawn.java @@ -0,0 +1,64 @@ +package seng302.utilities; + +import java.util.HashMap; +import java.util.List; +import java.util.Random; +import seng302.model.GeoPoint; +import seng302.model.mark.CompoundMark; +import seng302.model.token.Token; + +/** + * A class for generating and spawning tokens in random locations + * Created by wmu16 on 27/09/17. + */ +public class RandomSpawn { + + private static final Integer DEGREES_IN_CIRCLE = 360; + + private HashMap spawnRadii; + private Random random; + + /** + * @param markOrder this must be the ORDERED list of marks. Better yet UNIQUE to avoid over + * computation + */ + public RandomSpawn(List markOrder) { + this.spawnRadii = new HashMap<>(); + random = new Random(); + + spawnRadii = generateSpawnRadii(markOrder); + } + + private HashMap generateSpawnRadii(List markOrder) { + System.out.println(markOrder); + HashMap spawnRadii = new HashMap<>(); + for (int i = 0; i < markOrder.size() - 1; i++) { + GeoPoint spawnCentre = GeoUtility.getDirtyMidPoint( + markOrder.get(i).getMidPoint(), + markOrder.get(i + 1).getMidPoint()); + + Double distance = GeoUtility.getDistance(spawnCentre, markOrder.get(i).getMidPoint()); + spawnRadii.put(spawnCentre, distance); + } + + return spawnRadii; + } + + + /** + * @return A random token type at a random location in a random radii of the set of possible + * radii + */ + public Token getRandomTokenLocation() { + Object[] keys = spawnRadii.keySet().toArray(); + GeoPoint randomSpawnCentre = (GeoPoint) keys[random.nextInt(keys.length)]; + Double spawnRadius = spawnRadii.get(randomSpawnCentre); + Double randomDistance = spawnRadius * random.nextDouble(); + Double randomAngle = random.nextDouble() * DEGREES_IN_CIRCLE; + GeoPoint randomLocation = GeoUtility + .getGeoCoordinate(randomSpawnCentre, randomAngle, randomDistance); + return new Token(randomLocation); + + } + +} From 10fa51a10547481b0c7765374c5743b5334ee8f9 Mon Sep 17 00:00:00 2001 From: William Muir Date: Wed, 27 Sep 2017 02:27:30 +1300 Subject: [PATCH 21/21] Added some testing for the Random spawner #story[1293] --- .../java/seng302/utilities/RandomSpawn.java | 1 - .../seng302/utilities/RandomSpawnTest.java | 50 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/test/java/seng302/utilities/RandomSpawnTest.java diff --git a/src/main/java/seng302/utilities/RandomSpawn.java b/src/main/java/seng302/utilities/RandomSpawn.java index 0a0f0702..929e5766 100644 --- a/src/main/java/seng302/utilities/RandomSpawn.java +++ b/src/main/java/seng302/utilities/RandomSpawn.java @@ -30,7 +30,6 @@ public class RandomSpawn { } private HashMap generateSpawnRadii(List markOrder) { - System.out.println(markOrder); HashMap spawnRadii = new HashMap<>(); for (int i = 0; i < markOrder.size() - 1; i++) { GeoPoint spawnCentre = GeoUtility.getDirtyMidPoint( diff --git a/src/test/java/seng302/utilities/RandomSpawnTest.java b/src/test/java/seng302/utilities/RandomSpawnTest.java new file mode 100644 index 00000000..60966ab8 --- /dev/null +++ b/src/test/java/seng302/utilities/RandomSpawnTest.java @@ -0,0 +1,50 @@ +package seng302.utilities; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import seng302.model.GeoPoint; +import seng302.model.mark.CompoundMark; +import seng302.model.mark.Mark; +import seng302.model.token.Token; + +/** + * Created by wmu16 on 27/09/17. + */ +public class RandomSpawnTest { + + private RandomSpawn randomSpawn; + + Mark mark1 = new Mark("mark1", 0, 57.670333, 11.827833, 0); + Mark mark2 = new Mark("mark2", 1, 57.671829, 11.842049, 1); + CompoundMark compoundMark1 = new CompoundMark(0, "mark1", + new ArrayList<>(Arrays.asList(mark1))); + CompoundMark compoundMark2 = new CompoundMark(0, "mark1", + new ArrayList<>(Arrays.asList(mark2))); + + List markOrder = new ArrayList<>(Arrays.asList(compoundMark1, compoundMark2)); + + @Before + public void setup() { + randomSpawn = new RandomSpawn(markOrder); + } + + @Test + public void testGetRandomTokenLocation() { + GeoPoint testMidPoint = GeoUtility + .getDirtyMidPoint(compoundMark1.getMidPoint(), compoundMark2.getMidPoint()); + Double maxDistance = GeoUtility.getDistance(testMidPoint, compoundMark2.getMidPoint()); + for (int i = 0; i < 1000; i++) { + Token token = randomSpawn.getRandomTokenLocation(); + Double distanceFromCentreRadius = GeoUtility.getDistance(testMidPoint, token); + assertTrue("Out of bounds token", distanceFromCentreRadius <= maxDistance); + } + + + } + +} \ No newline at end of file