diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java index 7437eb41..36256884 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/GameSound.java @@ -35,6 +35,7 @@ public class GameSound extends AbstractAppState implements GameEventListener { private AudioNode splashSound; private AudioNode shipDestroyedSound; private AudioNode explosionSound; + private AudioNode missileLaunch; /** * Checks if sound is enabled in the preferences. @@ -79,6 +80,7 @@ public void initialize(AppStateManager stateManager, Application app) { shipDestroyedSound = loadSound(app, "Sound/Effects/sunken.wav"); //NON-NLS splashSound = loadSound(app, "Sound/Effects/splash.wav"); //NON-NLS explosionSound = loadSound(app, "Sound/Effects/explosion.wav"); //NON-NLS + missileLaunch = loadSound(app, "Sound/Effects/missilefiring.wav"); //NON-NLS } /** @@ -101,6 +103,14 @@ private AudioNode loadSound(Application app, String name) { return null; } + /** + * Plays the splash sound effect. + */ + public void missileLaunch() { + if (isEnabled() && missileLaunch != null) + missileLaunch.playInstance(); + } + /** * Plays the splash sound effect. */ @@ -131,6 +141,7 @@ public void receivedEvent(SoundEvent event) { case EXPLOSION -> explosion(); case SPLASH -> splash(); case DESTROYED_SHIP -> shipDestroyed(); + case MISSILE_LAUNCH -> missileLaunch(); } } } diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/HitEffectHandler.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/HitEffectHandler.java index cc1c959d..fc930337 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/HitEffectHandler.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/HitEffectHandler.java @@ -70,7 +70,7 @@ public void hitEffect(Node battleshipNode, Shot shot){ debris.setLocalTranslation(shot.getY() + 0.5f, 0 , shot.getX() + 0.5f); debris.emitAllParticles(); - //Fire //TODO Fix creation of fire on the edge of the map + //Fire ParticleEmitter fire = new ParticleEmitter("Fire", Type.Triangle, 30); Material fireMaterial = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md"); fireMaterial.setTexture("Texture", assetManager.loadTexture("Textures/Fire/fire.png")); diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/MapViewSynchronizer.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/MapViewSynchronizer.java index a6075fd8..56b7f02a 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/MapViewSynchronizer.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/MapViewSynchronizer.java @@ -12,9 +12,14 @@ import com.jme3.scene.Node; import com.jme3.scene.Spatial; import pp.battleship.model.Battleship; +import pp.battleship.model.IntPoint; +import pp.battleship.model.Shell; import pp.battleship.model.Shot; import pp.util.Position; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + /** * Synchronizes the visual representation of the ship map with the game model. * It handles the rendering of ships and shots on the map view, updating the view @@ -26,6 +31,9 @@ class MapViewSynchronizer extends ShipMapSynchronizer { private static final float SHOT_DEPTH = -2f; private static final float SHIP_DEPTH = 0f; private static final float INDENT = 4f; + private static final float MISSILE_DEPTH = 6f; + private static final float MISSILE_SIZE = 0.8f; + private static final float MISSILE_CENTERED_IN_MAP_GRID = 0.0625f; // Colors used for different visual elements private static final ColorRGBA HIT_COLOR = ColorRGBA.Red; @@ -37,6 +45,8 @@ class MapViewSynchronizer extends ShipMapSynchronizer { // The MapView associated with this synchronizer private final MapView view; + static final Logger LOGGER = System.getLogger(MapViewSynchronizer.class.getName()); + /** * Constructs a new MapViewSynchronizer for the given MapView. * Initializes the synchronizer and adds existing elements from the model to the view. @@ -58,16 +68,14 @@ public MapViewSynchronizer(MapView view) { */ @Override public Spatial visit(Shot shot) { + LOGGER.log(Level.DEBUG, "visiting" + shot); // Convert the shot's model coordinates to view coordinates final Position p1 = view.modelToView(shot.getX(), shot.getY()); final Position p2 = view.modelToView(shot.getX() + 1, shot.getY() + 1); final ColorRGBA color = shot.isHit() ? HIT_COLOR : MISS_COLOR; // Create and return a rectangle representing the shot - return view.getApp().getDraw().makeRectangle(p1.getX(), p1.getY(), - SHOT_DEPTH, - p2.getX() - p1.getX(), p2.getY() - p1.getY(), - color); + return view.getApp().getDraw().makeRectangle(p1.getX(), p1.getY(), SHOT_DEPTH, p2.getX() - p1.getX(), p2.getY() - p1.getY(), color); } /** @@ -109,6 +117,26 @@ public Spatial visit(Battleship ship) { return shipNode; } + @Override + public Spatial visit(Shell shell) { + LOGGER.log(Logger.Level.DEBUG, "Visiting {0}", shell); + final Node missileNode = new Node("missile"); + final Position p1 = view.modelToView(shell.getX(), shell.getY()); + final Position p2 = view.modelToView(shell.getX() + MISSILE_SIZE, shell.getY() + MISSILE_SIZE); + + final float x1 = p1.getX() + INDENT; + final float y1 = p1.getY() + INDENT; + final float x2 = p2.getX() - INDENT; + final float y2 = p2.getY() - INDENT; + + final Position startPosition = view.modelToView(MISSILE_CENTERED_IN_MAP_GRID, MISSILE_CENTERED_IN_MAP_GRID); + + missileNode.attachChild(view.getApp().getDraw().makeRectangle(startPosition.getX(), startPosition.getY(), MISSILE_DEPTH, p2.getX() - p1.getX(), p2.getY() - p1.getY(), ColorRGBA.DarkGray)); + missileNode.setLocalTranslation(startPosition.getX(), startPosition.getY(), MISSILE_DEPTH); + missileNode.addControl(new ShellMapControl(p1, view.getApp(), new IntPoint(shell.getX(), shell.getY()))); + return missileNode; + } + /** * Creates a line geometry representing part of the ship's border. * @@ -120,6 +148,7 @@ public Spatial visit(Battleship ship) { * @return a Geometry representing the line */ private Geometry shipLine(float x1, float y1, float x2, float y2, ColorRGBA color) { + LOGGER.log(Logger.Level.DEBUG, "created Ship line"); return view.getApp().getDraw().makeFatLine(x1, y1, x2, y2, SHIP_DEPTH, color, SHIP_LINE_WIDTH); } } diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java index d6f4aaf0..eecf8abc 100644 --- a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/SeaSynchronizer.java @@ -8,8 +8,10 @@ package pp.battleship.client.gui; import com.jme3.material.Material; +import com.jme3.material.RenderState; import com.jme3.material.RenderState.BlendMode; import com.jme3.math.ColorRGBA; +import com.jme3.renderer.queue.RenderQueue; import com.jme3.renderer.queue.RenderQueue.ShadowMode; import com.jme3.scene.Geometry; import com.jme3.scene.Node; @@ -18,6 +20,7 @@ import com.jme3.scene.shape.Cylinder; import pp.battleship.client.BattleshipApp; import pp.battleship.model.Battleship; +import pp.battleship.model.Shell; import pp.battleship.model.Rotation; import pp.battleship.model.ShipMap; import pp.battleship.model.Shot; @@ -37,10 +40,14 @@ class SeaSynchronizer extends ShipMapSynchronizer { private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o"; private static final String UBOAT_MODEL = "Models/UBOAT/14084_WWII_Ship_German_Type_II_U-boat_v2_L1.obj"; private static final String PATROL_BOAT_MODEL = "Models/PATROL_BOAT/12219_boat_v2_L2.obj"; - private static final String MODERNBATTLESHIP_MODEL = "Models/BATTLESHIP/10619_Battleship.obj"; + private static final String MODERN_BATTLESHIP_MODEL = "Models/BATTLESHIP/10619_Battleship.obj"; + private static final String MODERN_BATTLESHIP_TEXTURES = "Models/BATTLESHIP/BattleshipC.jpg"; + private static final String MISSILE_MODEL = "Models/Missile/AIM120D.obj"; + private static final String MISSILE_TEXTURE = "Models/Missile/texture.png"; private static final String COLOR = "Color"; //NON-NLS private static final String SHIP = "ship"; //NON-NLS private static final String SHOT = "shot"; //NON-NLS + private static final String MISSILE = "missile"; //NON-NLS private static final ColorRGBA BOX_COLOR = ColorRGBA.Gray; private static final ColorRGBA SPLASH_COLOR = new ColorRGBA(0f, 0f, 1f, 0.4f); private static final ColorRGBA HIT_COLOR = new ColorRGBA(1f, 0f, 0f, 0.4f); @@ -136,6 +143,25 @@ public Spatial visit(Battleship ship) { return node; } + /** + * Visits a Shell and creates a graphical representation of it. + * + * @param shell the battleship to be represented + * @return the node containing the graphical representation of the battleship + */ + @Override + public Spatial visit(Shell shell) { + final Node node = new Node(MISSILE); + node.attachChild(createMissile()); + + final float x = shell.getY(); + final float z = shell.getX(); + node.setLocalTranslation(x+0.5f, 10f, z+0.5f); + node.addControl(new ShellControl(shell, app)); + return node; + } + + /** * Creates the appropriate graphical representation of the specified battleship. * The representation is either a detailed model or a simple box based on the length of the ship. @@ -213,7 +239,13 @@ private Spatial createBattleship(Battleship ship) { */ private Spatial createModernBattleship(Battleship ship) { - final Spatial model = app.getAssetManager().loadModel(MODERNBATTLESHIP_MODEL); + final Spatial model = app.getAssetManager().loadModel(MODERN_BATTLESHIP_MODEL); + Material mat = new Material(app.getAssetManager(), UNSHADED); + mat.setTexture("ColorMap", app.getAssetManager().loadTexture(MODERN_BATTLESHIP_TEXTURES)); + mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Off); + model.setMaterial(mat); + + model.setQueueBucket(RenderQueue.Bucket.Opaque); model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) + HALF_PI, 0f); model.scale(0.000075f); @@ -222,6 +254,30 @@ private Spatial createModernBattleship(Battleship ship) { return model; } + /** + * Creates a detailed 3D model to represent a missile. + * + * @return the spatial representing the missile + */ + + private Spatial createMissile() { + final Spatial model = app.getAssetManager().loadModel(MISSILE_MODEL); + Material mat = new Material(app.getAssetManager(), UNSHADED); + mat.setTexture("ColorMap", app.getAssetManager().loadTexture(MISSILE_TEXTURE)); + mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Off); + model.setMaterial(mat); + + model.setQueueBucket(RenderQueue.Bucket.Opaque); + + model.rotate(-HALF_PI,0,0); + model.scale(0.009f); + model.setShadowMode(ShadowMode.CastAndReceive); + model.move(0,0f,0); + return model; + } + + + /** * Creates a detailed 3D model to represent a Uboat. * diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellControl.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellControl.java new file mode 100644 index 00000000..10eecd6a --- /dev/null +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellControl.java @@ -0,0 +1,41 @@ +package pp.battleship.client.gui; + +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.control.AbstractControl; +import pp.battleship.client.BattleshipApp; +import pp.battleship.message.client.EndAnimationMessage; +import pp.battleship.model.IntPoint; +import pp.battleship.model.Shell; + +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + +public class ShellControl extends AbstractControl { + + private final Shell shell; + private final BattleshipApp app; + private static final float TRAVEL_SPEED = 8.5f; + static final Logger LOGGER = System.getLogger(BattleshipApp.class.getName()); + + public ShellControl(Shell shell, BattleshipApp app) { + this.shell = shell; + this.app = app; + } + + @Override + public void controlUpdate(float tpf) { + //LOGGER.log(Level.DEBUG, "missile at x=" + shell.getX() + ", y=" + shell.getY()); + spatial.move(0, -TRAVEL_SPEED*tpf, 0); + if(spatial.getLocalTranslation().getY() <= 0.2){ + spatial.getParent().detachChild(spatial); + app.getGameLogic().send(new EndAnimationMessage(new IntPoint(shell.getX(), shell.getY()))); + } + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + + } + +} diff --git a/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellMapControl.java b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellMapControl.java new file mode 100644 index 00000000..1cc3fb2e --- /dev/null +++ b/Projekte/battleship/client/src/main/java/pp/battleship/client/gui/ShellMapControl.java @@ -0,0 +1,39 @@ +package pp.battleship.client.gui; + +import com.jme3.math.Vector3f; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.control.AbstractControl; +import pp.battleship.client.BattleshipApp; +import pp.battleship.message.client.EndAnimationMessage; +import pp.battleship.model.IntPoint; +import pp.util.Position; + +public class ShellMapControl extends AbstractControl { + private final Position position; + private final IntPoint pos; + private static final Vector3f vector = new Vector3f(); + private final BattleshipApp app; + + public ShellMapControl(Position position, BattleshipApp app, IntPoint pos) { + super(); + this.position = position; + this.pos = pos; + this.app = app; + vector.set(new Vector3f(position.getX(), position.getY(), 0)); + } + + @Override + protected void controlUpdate(float tpf) { + spatial.move(vector.mult(tpf)); + if (spatial.getLocalTranslation().getX() >= position.getX() && spatial.getLocalTranslation().getY() >= position.getY()) { + spatial.getParent().detachChild(spatial); + app.getGameLogic().send(new EndAnimationMessage(pos)); + } + } + + @Override + protected void controlRender(RenderManager rm, ViewPort vp) { + + } +} diff --git a/Projekte/battleship/client/src/main/java/server/BattleshipServer.java b/Projekte/battleship/client/src/main/java/server/BattleshipServer.java index 95b66bda..5c4d5504 100644 --- a/Projekte/battleship/client/src/main/java/server/BattleshipServer.java +++ b/Projekte/battleship/client/src/main/java/server/BattleshipServer.java @@ -19,12 +19,15 @@ import pp.battleship.game.server.ServerGameLogic; import pp.battleship.game.server.ServerSender; import pp.battleship.message.client.ClientMessage; +import pp.battleship.message.client.EndAnimationMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.GameDetails; import pp.battleship.message.server.ServerMessage; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.SwitchToBattleState; import pp.battleship.model.Battleship; import pp.battleship.model.IntPoint; import pp.battleship.model.Shot; @@ -114,11 +117,15 @@ private void initializeSerializables() { Serializer.registerClass(Battleship.class); Serializer.registerClass(IntPoint.class); Serializer.registerClass(Shot.class); + Serializer.registerClass(StartAnimationMessage.class); + Serializer.registerClass(EndAnimationMessage.class); + Serializer.registerClass(SwitchToBattleState.class); } private void registerListeners() { myServer.addMessageListener(this, MapMessage.class); myServer.addMessageListener(this, ShootMessage.class); + myServer.addMessageListener(this, EndAnimationMessage.class); myServer.addConnectionListener(this); } diff --git a/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.mtl b/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.mtl new file mode 100644 index 00000000..baeaf917 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.mtl @@ -0,0 +1,12 @@ +# Blender MTL File: 'AIM120D.blend' +# Material Count: 1 + +newmtl Material.006 +Ns 96.078431 +Ka 0.000000 0.000000 0.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ni 1.000000 +d 1.000000 +illum 2 +map_Kd texture.png diff --git a/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.obj b/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.obj new file mode 100644 index 00000000..3db456a7 --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Models/Missile/AIM120D.obj @@ -0,0 +1,2244 @@ +# Blender v2.70 (sub 0) OBJ File: 'AIM120D.blend' +# www.blender.org +mtllib AIM120D.mtl +o Cylinder.003_Cylinder.005 +v 3.723455 7.439977 33.111862 +v 3.620776 7.241301 28.837194 +v 3.987608 7.613187 28.836199 +v 5.700150 9.336053 31.835562 +v 3.554407 7.325046 35.663681 +v 5.662526 9.388924 35.949318 +v 3.579212 7.293746 33.112251 +v 3.587776 7.282940 32.231430 +v 3.732019 7.429171 32.231041 +v 3.867561 7.297838 33.115005 +v 3.764881 7.099162 28.840338 +v 4.131713 7.471049 28.839342 +v 5.764544 9.272538 31.836966 +v 3.698512 7.182908 35.666824 +v 5.726921 9.325408 35.950722 +v 3.723318 7.151608 33.115395 +v 3.731882 7.140801 32.234573 +v 3.876125 7.287032 32.234184 +v 4.083515 6.985649 -3.922493 +v 3.980835 6.786972 -8.197156 +v 4.099767 6.907543 -8.197478 +v 6.264812 9.140665 -2.870750 +v 3.914466 6.870718 -1.370670 +v 6.249827 9.164968 -1.085657 +v 3.939272 6.839417 -3.922100 +v 3.947835 6.828612 -4.802925 +v 4.092079 6.974843 -4.803318 +v 4.227621 6.843510 -3.919348 +v 4.124941 6.644834 -8.194011 +v 4.243873 6.765405 -8.194333 +v 6.329206 9.077150 -2.869345 +v 4.058572 6.728580 -1.367525 +v 6.314222 9.101454 -1.084251 +v 4.083378 6.697279 -3.918955 +v 4.091941 6.686473 -4.799780 +v 4.236185 6.832705 -4.800173 +v 3.237399 6.846060 32.981903 +v 3.243541 6.838310 32.350159 +v 3.300674 6.781958 32.351410 +v 3.294532 6.789708 32.983154 +v 3.733697 7.349199 32.980560 +v 3.739839 7.341449 32.348816 +v 3.796972 7.285097 32.350060 +v 3.790830 7.292847 32.981804 +v 3.597261 6.391983 -4.031746 +v 3.603403 6.384233 -4.663490 +v 3.660536 6.327880 -4.662243 +v 3.654394 6.335630 -4.030499 +v 4.093559 6.895122 -4.033092 +v 4.099701 6.887372 -4.664837 +v 4.156834 6.831019 -4.663589 +v 4.150692 6.838769 -4.031845 +v 0.871625 4.358115 32.989426 +v 0.877767 4.350365 32.357681 +v 0.820634 4.406718 32.356438 +v 0.814492 4.414468 32.988182 +v 0.375323 3.854980 32.990776 +v 0.381465 3.847230 32.359032 +v 0.324332 3.903584 32.357780 +v 0.318190 3.911333 32.989525 +v 1.231490 3.904048 -4.024227 +v 1.237632 3.896298 -4.655972 +v 1.180500 3.952651 -4.657217 +v 1.174358 3.960402 -4.025473 +v 0.735188 3.400913 -4.022879 +v 0.741330 3.393163 -4.654623 +v 0.684198 3.449516 -4.655869 +v 0.678056 3.457266 -4.024124 +v 0.382988 3.767453 33.124435 +v 0.568796 3.861239 28.848989 +v 0.201962 3.489354 28.849985 +v -1.568985 1.840181 31.856848 +v 0.502426 3.944983 35.675476 +v -1.611352 1.888242 35.970612 +v 0.527232 3.913683 33.124046 +v 0.535796 3.902878 32.243225 +v 0.391552 3.756648 32.243614 +v 0.238883 3.909593 33.121292 +v 0.424691 4.003378 28.845846 +v 0.057857 3.631493 28.846842 +v -1.633379 1.903696 31.855444 +v 0.358321 4.087122 35.672333 +v -1.675747 1.951758 35.969208 +v 0.383127 4.055823 33.120903 +v 0.391691 4.045017 32.240082 +v 0.247447 3.898787 32.240471 +v 0.743055 3.313133 -3.909916 +v 0.928863 3.406918 -8.185363 +v 0.809931 3.286348 -8.185040 +v -1.458802 1.184055 -2.848232 +v 0.862492 3.490663 -1.358879 +v -1.478528 1.203550 -1.063128 +v 0.887299 3.459363 -3.910309 +v 0.895862 3.448557 -4.791134 +v 0.751618 3.302327 -4.790741 +v 0.598950 3.455272 -3.913061 +v 0.784758 3.549057 -8.188507 +v 0.665826 3.428487 -8.188185 +v -1.523196 1.247571 -2.849638 +v 0.718387 3.632802 -1.362024 +v -1.542923 1.267066 -1.064533 +v 0.743194 3.601502 -3.913454 +v 0.751758 3.590696 -4.794279 +v 0.607513 3.444466 -4.793886 +v 3.889338 3.933746 33.156487 +v 3.784684 4.025524 28.878241 +v 4.156536 3.658745 28.886354 +v 5.813195 1.954087 31.927217 +v 3.718315 4.109268 35.704727 +v 5.775604 2.002182 36.041031 +v 3.743121 4.077969 33.153297 +v 3.751684 4.067163 32.272476 +v 3.897901 3.922941 32.275665 +v 3.747178 3.789628 33.156876 +v 3.642524 3.881406 28.878626 +v 4.014376 3.514627 28.886740 +v 5.749671 1.889688 31.927389 +v 3.576155 3.965150 35.705116 +v 5.712079 1.937782 36.041206 +v 3.600960 3.933851 33.153687 +v 3.609524 3.923045 32.272858 +v 3.755741 3.778822 32.276047 +v 4.249397 3.479425 -3.877865 +v 4.144743 3.571203 -8.156112 +v 4.265303 3.452289 -8.153481 +v 6.380966 1.301124 -2.773447 +v 4.078374 3.654947 -1.329626 +v 6.366014 1.320652 -0.988295 +v 4.103180 3.623648 -3.881056 +v 4.111744 3.612842 -4.761881 +v 4.257961 3.468620 -4.758690 +v 4.107237 3.335307 -3.877480 +v 4.002584 3.427085 -8.155725 +v 4.123143 3.308171 -8.153095 +v 6.317441 1.236724 -2.773275 +v 3.936214 3.510829 -1.329241 +v 6.302490 1.256252 -0.988123 +v 3.961020 3.479530 -3.880671 +v 3.969584 3.468724 -4.761496 +v 4.115801 3.324502 -4.758305 +v 3.298380 4.419384 33.012268 +v 3.304522 4.411634 32.380524 +v 3.248160 4.354497 32.380676 +v 3.242018 4.362247 33.012421 +v 3.801470 3.923157 33.023247 +v 3.807612 3.915407 32.391502 +v 3.751251 3.858270 32.391655 +v 3.745109 3.866019 33.023399 +v 3.658238 3.965318 -4.001383 +v 3.664380 3.957568 -4.633127 +v 3.608019 3.900430 -4.632975 +v 3.601876 3.908180 -4.001230 +v 4.161328 3.469090 -3.990404 +v 4.167470 3.461340 -4.622149 +v 4.111109 3.404203 -4.621996 +v 4.104967 3.411952 -3.990252 +v 0.810644 6.784794 32.959068 +v 0.816786 6.777044 32.327324 +v 0.873147 6.834182 32.327171 +v 0.867005 6.841932 32.958916 +v 0.307550 7.281019 32.948090 +v 0.313692 7.273269 32.316345 +v 0.370054 7.330407 32.316193 +v 0.363911 7.338157 32.947937 +v 1.170509 6.330720 -4.054590 +v 1.176651 6.322970 -4.686335 +v 1.233012 6.380108 -4.686487 +v 1.226870 6.387858 -4.054743 +v 0.667416 6.826945 -4.065569 +v 0.673558 6.819195 -4.697313 +v 0.729919 6.876333 -4.697466 +v 0.723777 6.884083 -4.065722 +v 0.217107 7.273680 33.079811 +v 0.404889 7.077013 28.807943 +v 0.033035 7.443790 28.799829 +v -1.682029 9.222120 31.765188 +v 0.338518 7.160759 35.634430 +v -1.724429 9.274958 35.878891 +v 0.363324 7.129458 33.083000 +v 0.371888 7.118653 32.202179 +v 0.225670 7.262875 32.198990 +v 0.359266 7.417799 33.079430 +v 0.547048 7.221132 28.807558 +v 0.175194 7.587909 28.799444 +v -1.618505 9.286521 31.765017 +v 0.480677 7.304878 35.634048 +v -1.660904 9.339358 35.878723 +v 0.505484 7.273578 33.082619 +v 0.514048 7.262772 32.201790 +v 0.367830 7.406993 32.198601 +v 0.577173 6.819352 -3.954544 +v 0.764955 6.622685 -8.226406 +v 0.644396 6.741599 -8.229037 +v -1.574956 9.023568 -2.945536 +v 0.698585 6.706431 -1.399923 +v -1.594715 9.047838 -1.160490 +v 0.723391 6.675131 -3.951353 +v 0.731955 6.664325 -4.832178 +v 0.585737 6.808547 -4.835369 +v 0.719332 6.963471 -3.954929 +v 0.907115 6.766804 -8.226792 +v 0.786555 6.885718 -8.229424 +v -1.511431 9.087968 -2.945707 +v 0.840744 6.850550 -1.400309 +v -1.531190 9.112238 -1.160662 +v 0.865550 6.819250 -3.951738 +v 0.874114 6.808444 -4.832563 +v 0.727896 6.952665 -4.835754 +v 3.524319 4.155217 37.221954 +v 3.808656 3.796445 7.976980 +v 3.784893 4.477189 37.220535 +v 4.069230 4.118416 7.975565 +v 3.977651 4.843800 37.217911 +v 4.261988 4.485027 7.972940 +v 4.095185 5.240962 37.214180 +v 4.379522 4.882190 7.969212 +v 4.132979 5.653413 37.209488 +v 4.417316 5.294641 7.964520 +v 4.089580 6.065302 37.204018 +v 4.373917 5.706530 7.959044 +v 3.966656 6.460801 37.197968 +v 4.250993 6.102029 7.952997 +v 3.768931 6.824711 37.191582 +v 4.053268 6.465939 7.946608 +v 3.504004 7.143046 37.185104 +v 3.788341 6.784274 7.940125 +v 3.182055 7.403575 37.178772 +v 3.466392 7.044803 7.933800 +v 2.815456 7.596283 37.172844 +v 3.099793 7.237511 7.927872 +v 2.418297 7.713768 37.167542 +v 2.702634 7.354995 7.922567 +v 2.005839 7.751511 37.163063 +v 2.290176 7.392739 7.918095 +v 1.593933 7.708065 37.159592 +v 1.878270 7.349292 7.914623 +v 1.198408 7.585097 37.157257 +v 1.482745 7.226325 7.912287 +v 0.834464 7.387334 37.156143 +v 1.118801 7.028562 7.911175 +v 0.516088 7.122376 37.156303 +v 0.800425 6.763604 7.911329 +v 0.255514 6.800405 37.157715 +v 0.539851 6.441632 7.912746 +v 0.062756 6.433794 37.160339 +v 0.347093 6.075021 7.915369 +v -0.054778 6.036631 37.164070 +v 0.229559 5.677858 7.919098 +v -0.092571 5.624179 37.168762 +v 0.191765 5.265407 7.923790 +v -0.049172 5.212290 37.174240 +v 0.235165 4.853518 7.929266 +v 0.073752 4.816791 37.180283 +v 0.358089 4.458019 7.935314 +v 0.271477 4.452881 37.186668 +v 0.555814 4.094109 7.941700 +v 0.536405 4.134546 37.193161 +v 0.820742 3.775773 7.948181 +v 0.858354 3.874017 37.199478 +v 1.142692 3.515245 7.954508 +v 1.224954 3.681309 37.205406 +v 1.509291 3.322537 7.960436 +v 1.622113 3.563826 37.210716 +v 1.906450 3.205053 7.965742 +v 2.034572 3.526083 37.215187 +v 2.318909 3.167310 7.970215 +v 2.446477 3.569530 37.218658 +v 2.730815 3.210757 7.973686 +v 2.842002 3.692498 37.220993 +v 3.126339 3.333725 7.976023 +v 3.205945 3.890261 37.222107 +v 3.490283 3.531489 7.977137 +v 3.901211 3.679660 -1.542688 +v 4.161785 4.001631 -1.544104 +v 4.354543 4.368242 -1.546728 +v 4.472077 4.765405 -1.550457 +v 4.509871 5.177855 -1.555149 +v 4.466472 5.589745 -1.560625 +v 4.343548 5.985244 -1.566671 +v 4.145823 6.349154 -1.573061 +v 3.880896 6.667489 -1.579544 +v 3.558947 6.928018 -1.585869 +v 3.192348 7.120727 -1.591797 +v 2.795189 7.238210 -1.597101 +v 2.382730 7.275954 -1.601574 +v 1.970825 7.232508 -1.605045 +v 1.575300 7.109540 -1.607382 +v 1.211356 6.911777 -1.608494 +v 0.892980 6.646819 -1.608339 +v 0.632406 6.324847 -1.606922 +v 0.439648 5.958236 -1.604300 +v 0.322114 5.561073 -1.600571 +v 0.284320 5.148623 -1.595879 +v 0.327720 4.736733 -1.590403 +v 0.450644 4.341234 -1.584354 +v 0.648369 3.977324 -1.577969 +v 0.913297 3.658988 -1.571487 +v 1.235247 3.398460 -1.565161 +v 1.601846 3.205752 -1.559233 +v 1.999005 3.088268 -1.553926 +v 2.411464 3.050525 -1.549454 +v 2.823370 3.093972 -1.545982 +v 3.218894 3.216940 -1.543646 +v 3.582838 3.414704 -1.542532 +v 3.968848 3.594317 -8.499368 +v 4.229421 3.916288 -8.500785 +v 4.422179 4.282900 -8.503407 +v 4.539713 4.680062 -8.507137 +v 4.577507 5.092513 -8.511829 +v 4.534109 5.504402 -8.517304 +v 4.411185 5.899901 -8.523352 +v 4.213460 6.263811 -8.529742 +v 3.948532 6.582147 -8.536223 +v 3.626583 6.842675 -8.542549 +v 3.259984 7.035384 -8.548478 +v 2.862825 7.152867 -8.553780 +v 2.450367 7.190611 -8.558253 +v 2.038461 7.147165 -8.561725 +v 1.642936 7.024197 -8.564062 +v 1.278992 6.826434 -8.565175 +v 0.960616 6.561476 -8.565020 +v 0.700042 6.239505 -8.563603 +v 0.507285 5.872893 -8.560980 +v 0.389751 5.475731 -8.557250 +v 0.351957 5.063280 -8.552558 +v 0.395356 4.651390 -8.547083 +v 0.518280 4.255891 -8.541036 +v 0.716006 3.891981 -8.534649 +v 0.980934 3.573646 -8.528169 +v 1.302883 3.313117 -8.521842 +v 1.669482 3.120409 -8.515913 +v 2.066642 3.002926 -8.510608 +v 2.479100 2.965183 -8.506134 +v 2.891006 3.008630 -8.502663 +v 3.286531 3.131598 -8.500325 +v 3.650474 3.329361 -8.499213 +v 3.979527 3.580842 -9.597792 +v 4.240101 3.902813 -9.599209 +v 4.432858 4.269424 -9.601831 +v 4.550393 4.666587 -9.605561 +v 4.588187 5.079038 -9.610253 +v 4.544788 5.490927 -9.615728 +v 4.421864 5.886426 -9.621776 +v 4.224139 6.250336 -9.628166 +v 3.959211 6.568671 -9.634647 +v 3.637263 6.829200 -9.640973 +v 3.270664 7.021909 -9.646902 +v 2.873505 7.139392 -9.652204 +v 2.461046 7.177136 -9.656677 +v 2.049140 7.133689 -9.660149 +v 1.653616 7.010722 -9.662486 +v 1.289672 6.812959 -9.663599 +v 0.971296 6.548001 -9.663444 +v 0.710722 6.226029 -9.662027 +v 0.517964 5.859418 -9.659404 +v 0.400430 5.462255 -9.655674 +v 0.362636 5.049805 -9.650982 +v 0.406036 4.637915 -9.645507 +v 0.528960 4.242416 -9.639460 +v 0.726685 3.878506 -9.633073 +v 0.991613 3.560170 -9.626593 +v 1.313563 3.299642 -9.620266 +v 1.680161 3.106934 -9.614337 +v 2.077321 2.989450 -9.609032 +v 2.489779 2.951707 -9.604558 +v 2.901685 2.995154 -9.601087 +v 3.297210 3.118123 -9.598749 +v 3.661153 3.315886 -9.597637 +v 3.991986 3.565121 -10.879286 +v 4.252560 3.887092 -10.880703 +v 4.445318 4.253703 -10.883326 +v 4.562852 4.650866 -10.887055 +v 4.600646 5.063316 -10.891747 +v 4.557247 5.475206 -10.897223 +v 4.434323 5.870705 -10.903270 +v 4.236598 6.234615 -10.909661 +v 3.971671 6.552950 -10.916142 +v 3.649722 6.813478 -10.922468 +v 3.283123 7.006187 -10.928397 +v 2.885964 7.123671 -10.933699 +v 2.473506 7.161415 -10.938172 +v 2.061600 7.117969 -10.941644 +v 1.666075 6.995001 -10.943981 +v 1.302131 6.797238 -10.945094 +v 0.983755 6.532280 -10.944939 +v 0.723181 6.210309 -10.943522 +v 0.530423 5.843697 -10.940899 +v 0.412889 5.446534 -10.937169 +v 0.375095 5.034083 -10.932477 +v 0.418495 4.622194 -10.927002 +v 0.541419 4.226695 -10.920955 +v 0.739144 3.862785 -10.914568 +v 1.004072 3.544449 -10.908088 +v 1.326022 3.283921 -10.901761 +v 1.692621 3.091213 -10.895832 +v 2.089781 2.973729 -10.890526 +v 2.502239 2.935987 -10.886052 +v 2.914145 2.979434 -10.882581 +v 3.309669 3.102401 -10.880243 +v 3.673613 3.300165 -10.879131 +v 4.150991 3.364491 -27.233587 +v 4.411565 3.686462 -27.235004 +v 4.604322 4.053073 -27.237627 +v 4.721857 4.450235 -27.241356 +v 4.759651 4.862686 -27.246048 +v 4.716252 5.274576 -27.251524 +v 4.593328 5.670074 -27.257570 +v 4.395603 6.033984 -27.263962 +v 4.130675 6.352320 -27.270443 +v 3.808727 6.612848 -27.276770 +v 3.442128 6.805557 -27.282698 +v 3.044969 6.923041 -27.288000 +v 2.632510 6.960784 -27.292473 +v 2.220604 6.917338 -27.295944 +v 1.825080 6.794370 -27.298283 +v 1.461136 6.596608 -27.299395 +v 1.142760 6.331649 -27.299240 +v 0.882186 6.009678 -27.297823 +v 0.689428 5.643067 -27.295200 +v 0.571894 5.245904 -27.291470 +v 0.534100 4.833453 -27.286777 +v 0.577500 4.421564 -27.281303 +v 0.700424 4.026065 -27.275255 +v 0.898149 3.662155 -27.268869 +v 1.163077 3.343819 -27.262388 +v 1.485026 3.083291 -27.256062 +v 1.851625 2.890583 -27.250134 +v 2.248785 2.773099 -27.244827 +v 2.661243 2.735356 -27.240353 +v 3.073149 2.778803 -27.236881 +v 3.468674 2.901771 -27.234545 +v 3.832617 3.099535 -27.233433 +v 4.205062 3.286808 -36.326839 +v 4.459688 3.601431 -36.328224 +v 4.648046 3.959674 -36.330788 +v 4.762898 4.347771 -36.334435 +v 4.799829 4.750808 -36.339020 +v 4.757421 5.153296 -36.344368 +v 4.637303 5.539768 -36.350277 +v 4.444091 5.895372 -36.356522 +v 4.185210 6.206441 -36.362854 +v 3.870610 6.461023 -36.369038 +v 3.512379 6.649333 -36.374832 +v 3.124284 6.764136 -36.380013 +v 2.721240 6.801018 -36.384384 +v 2.318736 6.758564 -36.387775 +v 1.932239 6.638402 -36.390060 +v 1.576602 6.445153 -36.391144 +v 1.265493 6.186243 -36.390995 +v 1.010866 5.871620 -36.389610 +v 0.822508 5.513377 -36.387047 +v 0.707657 5.125279 -36.383400 +v 0.670725 4.722242 -36.378819 +v 0.713134 4.319754 -36.373466 +v 0.833253 3.933282 -36.367558 +v 1.026465 3.577678 -36.361317 +v 1.285346 3.266608 -36.354984 +v 1.599947 3.012027 -36.348801 +v 1.958178 2.823717 -36.343010 +v 2.346273 2.708915 -36.337822 +v 2.749317 2.672033 -36.333450 +v 3.151822 2.714489 -36.330059 +v 3.538319 2.834650 -36.327774 +v 3.893955 3.027900 -36.326691 +v 4.053657 3.430851 -38.308155 +v 4.278723 3.708947 -38.309380 +v 4.445214 4.025601 -38.311646 +v 4.546732 4.368642 -38.314865 +v 4.579375 4.724890 -38.318916 +v 4.541891 5.080651 -38.323647 +v 4.435718 5.422256 -38.328873 +v 4.264936 5.736577 -38.334389 +v 4.036110 6.011533 -38.339989 +v 3.758032 6.236560 -38.345451 +v 3.441390 6.403008 -38.350571 +v 3.098350 6.504483 -38.355148 +v 2.742097 6.537084 -38.359016 +v 2.386321 6.499557 -38.362015 +v 2.044693 6.393346 -38.364029 +v 1.730344 6.222532 -38.364990 +v 1.455352 5.993680 -38.364861 +v 1.230286 5.715582 -38.363632 +v 1.063795 5.398929 -38.361366 +v 0.962277 5.055887 -38.358147 +v 0.929634 4.699640 -38.354095 +v 0.967119 4.343878 -38.349365 +v 1.073292 4.002273 -38.344143 +v 1.244074 3.687953 -38.338627 +v 1.472901 3.412996 -38.333031 +v 1.750979 3.187969 -38.327564 +v 2.067622 3.021521 -38.322445 +v 2.410662 2.920047 -38.317863 +v 2.766915 2.887447 -38.313995 +v 3.122691 2.924973 -38.311001 +v 3.464318 3.031185 -38.308983 +v 3.778667 3.202000 -38.308022 +v 3.877497 3.599972 -40.042759 +v 4.069130 3.836758 -40.043800 +v 4.210889 4.106374 -40.045731 +v 4.297327 4.398458 -40.048473 +v 4.325122 4.701786 -40.051926 +v 4.293205 5.004700 -40.055946 +v 4.202804 5.295561 -40.060398 +v 4.057392 5.563190 -40.065094 +v 3.862556 5.797303 -40.069862 +v 3.625786 5.988903 -40.074516 +v 3.356180 6.130626 -40.078873 +v 3.064098 6.217027 -40.082771 +v 2.760765 6.244784 -40.086063 +v 2.457838 6.212832 -40.088615 +v 2.166958 6.122399 -40.090336 +v 1.899304 5.976959 -40.091156 +v 1.665161 5.782101 -40.091042 +v 1.473528 5.545315 -40.089996 +v 1.331769 5.275699 -40.088070 +v 1.245331 4.983614 -40.085327 +v 1.217536 4.680286 -40.081875 +v 1.249454 4.377372 -40.077850 +v 1.339855 4.086511 -40.073402 +v 1.485268 3.818882 -40.068703 +v 1.680103 3.584769 -40.063938 +v 1.916874 3.393169 -40.059288 +v 2.186481 3.251446 -40.054924 +v 2.478563 3.165046 -40.051025 +v 2.781896 3.137289 -40.047737 +v 3.084823 3.169241 -40.045181 +v 3.375702 3.259675 -40.043465 +v 3.643356 3.405115 -40.042645 +v 3.614609 3.853880 -42.061829 +v 3.757308 4.030203 -42.062607 +v 3.862870 4.230972 -42.064041 +v 3.927235 4.448473 -42.066082 +v 3.947933 4.674346 -42.068653 +v 3.924166 4.899911 -42.071648 +v 3.856849 5.116501 -42.074959 +v 3.748568 5.315791 -42.078461 +v 3.603483 5.490123 -42.082008 +v 3.427173 5.632797 -42.085472 +v 3.226410 5.738332 -42.088722 +v 3.008911 5.802670 -42.091625 +v 2.783034 5.823340 -42.094078 +v 2.557459 5.799547 -42.095978 +v 2.340856 5.732205 -42.097260 +v 2.141547 5.623903 -42.097866 +v 1.967193 5.478803 -42.097778 +v 1.824493 5.302480 -42.097004 +v 1.718932 5.101710 -42.095566 +v 1.654566 4.884210 -42.093529 +v 1.633869 4.658337 -42.090958 +v 1.657636 4.432771 -42.087959 +v 1.724954 4.216182 -42.084648 +v 1.833235 4.016891 -42.081146 +v 1.978320 3.842559 -42.077599 +v 2.154631 3.699884 -42.074135 +v 2.355393 3.594351 -42.070889 +v 2.572892 3.530012 -42.067986 +v 2.798769 3.509343 -42.065533 +v 3.024344 3.533136 -42.063633 +v 3.240947 3.600478 -42.062351 +v 3.440256 3.708780 -42.061745 +v 3.362317 4.098472 -43.656807 +v 3.458632 4.217482 -43.657333 +v 3.529881 4.352992 -43.658302 +v 3.573325 4.499794 -43.659683 +v 3.587295 4.652248 -43.661415 +v 3.571254 4.804494 -43.663437 +v 3.525817 4.950682 -43.665672 +v 3.452733 5.085193 -43.668037 +v 3.354807 5.202859 -43.670429 +v 3.235806 5.299158 -43.672768 +v 3.100301 5.370389 -43.674957 +v 2.953499 5.413814 -43.676918 +v 2.801043 5.427765 -43.678574 +v 2.648790 5.411706 -43.679855 +v 2.502593 5.366254 -43.680721 +v 2.368069 5.293155 -43.681129 +v 2.250388 5.195219 -43.681076 +v 2.154072 5.076209 -43.680550 +v 2.082824 4.940699 -43.679581 +v 2.039380 4.793896 -43.678200 +v 2.025410 4.641442 -43.676468 +v 2.041451 4.489196 -43.674446 +v 2.086888 4.343009 -43.672211 +v 2.159973 4.208497 -43.669849 +v 2.257898 4.090831 -43.667454 +v 2.376899 3.994532 -43.665115 +v 2.512405 3.923302 -43.662926 +v 2.659207 3.879876 -43.660965 +v 2.811663 3.865925 -43.659309 +v 2.963916 3.881985 -43.658028 +v 3.110113 3.927437 -43.657162 +v 3.244637 4.000536 -43.656754 +v 3.111415 4.342165 -45.075150 +v 3.161885 4.404527 -45.075424 +v 3.199220 4.475535 -45.075928 +v 3.221985 4.552462 -45.076653 +v 3.229306 4.632349 -45.077560 +v 3.220900 4.712127 -45.078621 +v 3.197091 4.788731 -45.079792 +v 3.158794 4.859216 -45.081032 +v 3.107480 4.920874 -45.082283 +v 3.045122 4.971335 -45.083511 +v 2.974116 5.008661 -45.084656 +v 2.897191 5.031416 -45.085686 +v 2.817302 5.038727 -45.086552 +v 2.737521 5.030312 -45.087223 +v 2.660912 5.006494 -45.087677 +v 2.590420 4.968190 -45.087891 +v 2.528754 4.916870 -45.087860 +v 2.478284 4.854508 -45.087585 +v 2.440949 4.783500 -45.087078 +v 2.418184 4.706573 -45.086357 +v 2.410864 4.626687 -45.085449 +v 2.419270 4.546908 -45.084389 +v 2.443079 4.470304 -45.083214 +v 2.481376 4.399819 -45.081978 +v 2.532690 4.338161 -45.080727 +v 2.595048 4.287700 -45.079498 +v 2.666054 4.250374 -45.078350 +v 2.742979 4.227619 -45.077324 +v 2.822868 4.220308 -45.076458 +v 2.902649 4.228724 -45.075783 +v 2.979258 4.252541 -45.075333 +v 3.049750 4.290846 -45.075119 +v 2.990009 4.460117 -45.748905 +v 3.018317 4.495094 -45.749062 +v 3.039257 4.534922 -45.749344 +v 3.052026 4.578068 -45.749748 +v 3.056131 4.622875 -45.750259 +v 3.051417 4.667621 -45.750854 +v 3.038063 4.710587 -45.751511 +v 3.016582 4.750120 -45.752205 +v 2.987802 4.784703 -45.752907 +v 2.952826 4.813006 -45.753597 +v 2.913001 4.833941 -45.754242 +v 2.869855 4.846704 -45.754814 +v 2.825047 4.850804 -45.755302 +v 2.780299 4.846085 -45.755676 +v 2.737331 4.832726 -45.755936 +v 2.697793 4.811242 -45.756054 +v 2.663206 4.782457 -45.756035 +v 2.634898 4.747480 -45.755882 +v 2.613958 4.707653 -45.755600 +v 2.601190 4.664506 -45.755196 +v 2.597084 4.619699 -45.754684 +v 2.601799 4.574953 -45.754089 +v 2.615152 4.531988 -45.753433 +v 2.636632 4.492454 -45.752739 +v 2.665413 4.457871 -45.752037 +v 2.700389 4.429568 -45.751347 +v 2.740215 4.408633 -45.750702 +v 2.783360 4.395870 -45.750126 +v 2.828168 4.391770 -45.749641 +v 2.872916 4.396490 -45.749264 +v 2.915884 4.409849 -45.749008 +v 2.955422 4.431333 -45.748886 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 2.829011 4.618254 -45.999676 +v 3.109427 4.564445 37.212898 +v 3.298126 4.797604 37.211876 +v 3.437714 5.063089 37.209969 +v 3.522827 5.350700 37.207275 +v 3.550196 5.649381 37.203873 +v 3.518768 5.947656 37.199905 +v 3.429752 6.234062 37.195534 +v 3.286567 6.497591 37.190903 +v 3.094716 6.728118 37.186211 +v 2.861573 6.916783 37.181633 +v 2.596096 7.056335 37.177338 +v 2.308488 7.141413 37.173500 +v 2.009801 7.168745 37.170258 +v 1.711514 7.137283 37.167747 +v 1.425090 7.048234 37.166054 +v 1.161536 6.905022 37.165245 +v 0.930980 6.713149 37.165359 +v 0.742282 6.479990 37.166382 +v 0.602694 6.214503 37.168289 +v 0.517580 5.926893 37.170990 +v 0.490212 5.628211 37.174385 +v 0.521640 5.329937 37.178352 +v 0.610657 5.043531 37.182724 +v 0.753842 4.780002 37.187355 +v 0.945693 4.549475 37.192047 +v 1.178836 4.360810 37.196625 +v 1.444314 4.221258 37.200920 +v 1.731922 4.136181 37.204758 +v 2.030609 4.108849 37.208000 +v 2.328895 4.140311 37.210518 +v 2.615320 4.229360 37.212204 +v 2.878874 4.372573 37.213013 +v 3.123666 4.546479 35.748711 +v 3.312364 4.779638 35.747681 +v 3.451952 5.045124 35.745781 +v 3.537066 5.332735 35.743080 +v 3.564435 5.631416 35.739685 +v 3.533007 5.929691 35.735718 +v 3.443990 6.216096 35.731339 +v 3.300806 6.479626 35.726715 +v 3.108955 6.710153 35.722023 +v 2.875812 6.898818 35.717438 +v 2.610334 7.038370 35.713150 +v 2.322726 7.123447 35.709305 +v 2.024040 7.150780 35.706070 +v 1.725753 7.119318 35.703552 +v 1.439329 7.030269 35.701859 +v 1.175774 6.887057 35.701057 +v 0.945218 6.695184 35.701164 +v 0.756521 6.462024 35.702194 +v 0.616933 6.196538 35.704094 +v 0.531819 5.908928 35.706795 +v 0.504450 5.610246 35.710197 +v 0.535878 5.311972 35.714157 +v 0.624895 5.025566 35.718536 +v 0.768081 4.762036 35.723160 +v 0.959931 4.531509 35.727859 +v 1.193075 4.342845 35.732437 +v 1.458552 4.203293 35.736725 +v 1.746161 4.118216 35.740570 +v 2.044847 4.090883 35.743813 +v 2.343134 4.122346 35.746323 +v 2.629558 4.211395 35.748016 +v 2.893112 4.354608 35.748817 +vt 0.586829 0.800173 +vt 0.586829 0.787643 +vt 0.507411 0.787643 +vt 0.507411 0.792570 +vt 0.516562 0.858301 +vt 0.486801 0.792570 +vt 0.420308 0.858382 +vt 0.486801 0.787643 +vt 0.427103 0.787643 +vt 0.854654 0.791221 +vt 0.854654 0.786617 +vt 0.764652 0.786617 +vt 0.764652 0.792201 +vt 0.713276 0.875486 +vt 0.741296 0.792201 +vt 0.665942 0.875578 +vt 0.741296 0.786617 +vt 0.673642 0.786617 +vt 0.303596 0.287062 +vt 0.311278 0.287062 +vt 0.311278 0.278470 +vt 0.303596 0.278470 +vt 0.753648 0.287062 +vt 0.761330 0.287062 +vt 0.761330 0.278470 +vt 0.753648 0.278470 +vt 0.105888 0.550362 +vt 0.105888 0.535427 +vt 0.126803 0.537487 +vt 0.126802 0.548303 +vt 0.921376 0.352187 +vt 0.921367 0.344594 +vt 0.977583 0.344542 +vt 0.977616 0.351703 +vt 0.203823 0.469981 +vt 0.217623 0.475696 +vt 0.207717 0.494232 +vt 0.197724 0.490093 +vt 0.230043 0.601792 +vt 0.217623 0.610089 +vt 0.207716 0.591554 +vt 0.216710 0.585544 +vt 0.114518 0.506981 +vt 0.122814 0.494564 +vt 0.139059 0.507894 +vt 0.133051 0.516887 +vt 0.189174 0.618717 +vt 0.174239 0.618717 +vt 0.176299 0.597803 +vt 0.187115 0.597802 +vt 0.145788 0.475704 +vt 0.159587 0.469986 +vt 0.165691 0.490096 +vt 0.155699 0.494236 +vt 0.240606 0.494555 +vt 0.248905 0.506974 +vt 0.230369 0.516882 +vt 0.224360 0.507889 +vt 0.145792 0.610087 +vt 0.133374 0.601789 +vt 0.146707 0.585544 +vt 0.155698 0.591554 +vt 0.257535 0.535424 +vt 0.257535 0.550361 +vt 0.236619 0.548301 +vt 0.236619 0.537484 +vt 0.114516 0.578809 +vt 0.108801 0.565011 +vt 0.128911 0.558911 +vt 0.133050 0.568903 +vt 0.174236 0.467069 +vt 0.189174 0.467068 +vt 0.187116 0.487984 +vt 0.176299 0.487985 +vt 0.248905 0.578811 +vt 0.240606 0.591230 +vt 0.224359 0.577896 +vt 0.230369 0.568902 +vt 0.108803 0.520779 +vt 0.128913 0.526879 +vt 0.203823 0.615804 +vt 0.197723 0.595693 +vt 0.230043 0.483994 +vt 0.216711 0.500241 +vt 0.133373 0.484003 +vt 0.146706 0.500246 +vt 0.159590 0.615803 +vt 0.165691 0.595693 +vt 0.254622 0.520774 +vt 0.234509 0.526875 +vt 0.122813 0.591228 +vt 0.139059 0.577896 +vt 0.254621 0.565011 +vt 0.234509 0.558909 +vt 0.328513 0.469178 +vt 0.338506 0.473317 +vt 0.347499 0.479326 +vt 0.355147 0.486974 +vt 0.361156 0.495967 +vt 0.365295 0.505960 +vt 0.367405 0.516568 +vt 0.367405 0.527384 +vt 0.365295 0.537993 +vt 0.361156 0.547985 +vt 0.355147 0.556979 +vt 0.347499 0.564627 +vt 0.338506 0.570636 +vt 0.328513 0.574775 +vt 0.317905 0.576885 +vt 0.307089 0.576885 +vt 0.296480 0.574775 +vt 0.286488 0.570636 +vt 0.277494 0.564627 +vt 0.269846 0.556979 +vt 0.263837 0.547985 +vt 0.259698 0.537992 +vt 0.257588 0.527384 +vt 0.257588 0.516568 +vt 0.259698 0.505960 +vt 0.263837 0.495967 +vt 0.269846 0.486974 +vt 0.277494 0.479326 +vt 0.286488 0.473317 +vt 0.296480 0.469178 +vt 0.307089 0.467068 +vt 0.317905 0.467068 +vt 0.058860 0.104292 +vt 0.059066 0.111826 +vt 0.003091 0.114686 +vt 0.002954 0.107568 +vt 0.059255 0.187201 +vt 0.059023 0.194441 +vt 0.003509 0.193031 +vt 0.003552 0.185932 +vt 0.921468 0.367396 +vt 0.921410 0.359790 +vt 0.977664 0.358867 +vt 0.977729 0.366032 +vt 0.058177 0.089453 +vt 0.058577 0.096817 +vt 0.002800 0.100456 +vt 0.002630 0.093352 +vt 0.059469 0.172345 +vt 0.059391 0.179816 +vt 0.003580 0.178824 +vt 0.003591 0.171709 +vt 0.921672 0.382603 +vt 0.921554 0.375003 +vt 0.977809 0.373196 +vt 0.977906 0.380357 +vt 0.059523 0.157275 +vt 0.059510 0.164825 +vt 0.003585 0.164588 +vt 0.003564 0.157462 +vt 0.921644 0.314558 +vt 0.921878 0.307288 +vt 0.977664 0.308813 +vt 0.977616 0.315944 +vt 0.922058 0.397750 +vt 0.921835 0.390191 +vt 0.978018 0.387514 +vt 0.978146 0.394665 +vt 0.059476 0.142131 +vt 0.059511 0.149707 +vt 0.003525 0.150333 +vt 0.003471 0.143201 +vt 0.921425 0.329469 +vt 0.921506 0.321971 +vt 0.977583 0.323083 +vt 0.977567 0.330230 +vt 0.922584 0.412689 +vt 0.922373 0.405255 +vt 0.978290 0.401810 +vt 0.978449 0.408945 +vt 0.059334 0.126967 +vt 0.059418 0.134549 +vt 0.003400 0.136069 +vt 0.003314 0.128939 +vt 0.921381 0.337017 +vt 0.977567 0.337383 +vt 0.059219 0.119390 +vt 0.003210 0.121811 +vt 0.058626 0.201386 +vt 0.003456 0.200332 +vt 0.057621 0.082308 +vt 0.002444 0.086256 +vt 0.922279 0.300314 +vt 0.977723 0.301480 +vt 0.923154 0.419781 +vt 0.978622 0.416073 +vt 0.065749 0.079252 +vt 0.343595 0.077108 +vt 0.343611 0.085231 +vt 0.066344 0.087703 +vt 0.343625 0.093351 +vt 0.066719 0.095782 +vt 0.343637 0.101470 +vt 0.066974 0.103678 +vt 0.343648 0.109586 +vt 0.067157 0.111469 +vt 0.343658 0.117701 +vt 0.067292 0.119200 +vt 0.343667 0.125815 +vt 0.067393 0.126895 +vt 0.343674 0.133928 +vt 0.067465 0.134569 +vt 0.343680 0.142041 +vt 0.067511 0.142231 +vt 0.343684 0.150153 +vt 0.067532 0.149887 +vt 0.343687 0.158266 +vt 0.067526 0.157541 +vt 0.343689 0.166378 +vt 0.067487 0.165200 +vt 0.343689 0.174491 +vt 0.067406 0.172872 +vt 0.343688 0.182604 +vt 0.067267 0.180571 +vt 0.343686 0.190720 +vt 0.067040 0.188328 +vt 0.343683 0.198837 +vt 0.066670 0.196201 +vt 0.343675 0.206829 +vt 0.066074 0.204328 +vt 0.915170 0.422842 +vt 0.637644 0.425241 +vt 0.637627 0.417097 +vt 0.914585 0.414445 +vt 0.637611 0.408956 +vt 0.914113 0.406391 +vt 0.637597 0.400817 +vt 0.913866 0.398419 +vt 0.637584 0.392681 +vt 0.913688 0.390577 +vt 0.637572 0.384545 +vt 0.913555 0.382808 +vt 0.637562 0.376411 +vt 0.913457 0.375080 +vt 0.637553 0.368278 +vt 0.913386 0.367377 +vt 0.637544 0.360146 +vt 0.913341 0.359687 +vt 0.637537 0.352014 +vt 0.913322 0.352003 +vt 0.637532 0.343882 +vt 0.913330 0.344322 +vt 0.637527 0.335751 +vt 0.913371 0.336635 +vt 0.637524 0.327618 +vt 0.913454 0.328936 +vt 0.637521 0.319485 +vt 0.913594 0.321208 +vt 0.637521 0.311351 +vt 0.913824 0.313423 +vt 0.641197 0.362707 +vt 0.641206 0.370840 +vt 0.527521 0.370970 +vt 0.527520 0.362850 +vt 0.914196 0.305520 +vt 0.637520 0.303214 +vt 0.637525 0.295203 +vt 0.914794 0.297362 +vt 0.527513 0.322255 +vt 0.527515 0.330373 +vt 0.444536 0.330384 +vt 0.444536 0.322273 +vt 0.340326 0.167237 +vt 0.340325 0.159124 +vt 0.453798 0.158999 +vt 0.453798 0.167110 +vt 0.641177 0.338311 +vt 0.641182 0.346442 +vt 0.527518 0.346611 +vt 0.527517 0.338492 +vt 0.340286 0.102332 +vt 0.340275 0.094216 +vt 0.453786 0.094108 +vt 0.453788 0.102220 +vt 0.340320 0.191583 +vt 0.340323 0.183466 +vt 0.453799 0.183330 +vt 0.453799 0.191440 +vt 0.641167 0.313914 +vt 0.641169 0.322047 +vt 0.527511 0.314137 +vt 0.641254 0.403384 +vt 0.641270 0.411525 +vt 0.527523 0.411577 +vt 0.527523 0.403455 +vt 0.340311 0.126675 +vt 0.340304 0.118562 +vt 0.453791 0.118444 +vt 0.453793 0.126555 +vt 0.641170 0.289632 +vt 0.641166 0.297643 +vt 0.527507 0.297902 +vt 0.527504 0.289785 +vt 0.641216 0.378974 +vt 0.641228 0.387109 +vt 0.527523 0.387212 +vt 0.527522 0.379091 +vt 0.340324 0.151012 +vt 0.340321 0.142900 +vt 0.453796 0.142778 +vt 0.453797 0.150889 +vt 0.641189 0.354574 +vt 0.527519 0.354730 +vt 0.340262 0.086098 +vt 0.340249 0.077978 +vt 0.453781 0.077884 +vt 0.453784 0.085996 +vt 0.340325 0.175351 +vt 0.453799 0.175220 +vt 0.641172 0.330179 +vt 0.340296 0.110448 +vt 0.453790 0.110332 +vt 0.340312 0.199575 +vt 0.453799 0.199550 +vt 0.641166 0.305779 +vt 0.527509 0.306019 +vt 0.641241 0.395246 +vt 0.527523 0.395333 +vt 0.340233 0.069855 +vt 0.453779 0.069769 +vt 0.340317 0.134787 +vt 0.453794 0.134667 +vt 0.641286 0.419669 +vt 0.527522 0.419702 +vt 0.444536 0.306050 +vt 0.444536 0.314162 +vt 0.431444 0.314162 +vt 0.431444 0.306054 +vt 0.444506 0.419638 +vt 0.444511 0.411520 +vt 0.536752 0.110291 +vt 0.536754 0.118407 +vt 0.444533 0.346608 +vt 0.444535 0.338496 +vt 0.536750 0.094059 +vt 0.536751 0.102175 +vt 0.536755 0.183331 +vt 0.536755 0.191446 +vt 0.444530 0.362833 +vt 0.444532 0.354720 +vt 0.536746 0.077827 +vt 0.536748 0.085943 +vt 0.536756 0.167101 +vt 0.536756 0.175216 +vt 0.444525 0.379060 +vt 0.444527 0.370946 +vt 0.536756 0.150870 +vt 0.536756 0.158986 +vt 0.444534 0.297939 +vt 0.444518 0.395288 +vt 0.444522 0.387174 +vt 0.536755 0.134639 +vt 0.536756 0.142754 +vt 0.444515 0.403404 +vt 0.536754 0.126523 +vt 0.536754 0.199560 +vt 0.536744 0.069711 +vt 0.444533 0.289828 +vt 0.431442 0.289839 +vt 0.431443 0.297946 +vt 0.416176 0.297946 +vt 0.416178 0.289842 +vt 0.431413 0.403382 +vt 0.431418 0.395269 +vt 0.549858 0.126520 +vt 0.549859 0.134636 +vt 0.431442 0.330380 +vt 0.431443 0.322271 +vt 0.431401 0.419609 +vt 0.431408 0.411495 +vt 0.549857 0.110286 +vt 0.549857 0.118403 +vt 0.431438 0.346600 +vt 0.431440 0.338490 +vt 0.549854 0.094051 +vt 0.549856 0.102169 +vt 0.549858 0.183336 +vt 0.549857 0.191452 +vt 0.431433 0.362821 +vt 0.431436 0.354711 +vt 0.549851 0.077816 +vt 0.549853 0.085934 +vt 0.549859 0.167102 +vt 0.549859 0.175219 +vt 0.431427 0.379044 +vt 0.431430 0.370933 +vt 0.549859 0.150869 +vt 0.549859 0.158986 +vt 0.431423 0.387156 +vt 0.549859 0.142753 +vt 0.549855 0.199569 +vt 0.549849 0.069697 +vt 0.439471 0.362805 +vt 0.439468 0.370914 +vt 0.282975 0.370552 +vt 0.282985 0.362465 +vt 0.416145 0.387132 +vt 0.416150 0.379022 +vt 0.565147 0.142752 +vt 0.565147 0.150869 +vt 0.416173 0.314158 +vt 0.416175 0.306052 +vt 0.416135 0.403350 +vt 0.416140 0.395241 +vt 0.565147 0.126517 +vt 0.565147 0.134634 +vt 0.416169 0.330373 +vt 0.416172 0.322265 +vt 0.416122 0.419569 +vt 0.416129 0.411460 +vt 0.565146 0.110282 +vt 0.565146 0.118400 +vt 0.416165 0.346588 +vt 0.416167 0.338480 +vt 0.565145 0.094045 +vt 0.565146 0.102164 +vt 0.565147 0.183340 +vt 0.565147 0.191459 +vt 0.416158 0.362805 +vt 0.416161 0.354696 +vt 0.565144 0.077807 +vt 0.565145 0.085926 +vt 0.565148 0.167104 +vt 0.565147 0.175222 +vt 0.416154 0.370914 +vt 0.565147 0.158987 +vt 0.565146 0.199578 +vt 0.565144 0.069686 +vt 0.324118 0.346291 +vt 0.324116 0.354378 +vt 0.258113 0.354078 +vt 0.258101 0.346442 +vt 0.546435 0.077807 +vt 0.546435 0.069686 +vt 0.703340 0.069736 +vt 0.703312 0.077866 +vt 0.546438 0.167104 +vt 0.546438 0.158987 +vt 0.703230 0.158970 +vt 0.703243 0.167079 +vt 0.439487 0.289842 +vt 0.439486 0.297946 +vt 0.282926 0.297729 +vt 0.282903 0.289634 +vt 0.439465 0.379022 +vt 0.439461 0.387132 +vt 0.282940 0.386734 +vt 0.282959 0.378642 +vt 0.546438 0.150869 +vt 0.546437 0.142752 +vt 0.703214 0.142757 +vt 0.703220 0.150863 +vt 0.439485 0.306052 +vt 0.439483 0.314158 +vt 0.282963 0.313931 +vt 0.282946 0.305833 +vt 0.439457 0.395241 +vt 0.439452 0.403350 +vt 0.282890 0.402931 +vt 0.282917 0.394830 +vt 0.546437 0.134634 +vt 0.546437 0.126517 +vt 0.703214 0.126548 +vt 0.703212 0.134653 +vt 0.439482 0.322265 +vt 0.439480 0.330373 +vt 0.282987 0.330116 +vt 0.282977 0.322026 +vt 0.439447 0.411460 +vt 0.439442 0.419569 +vt 0.282827 0.419149 +vt 0.282861 0.411037 +vt 0.546437 0.118400 +vt 0.546436 0.110282 +vt 0.703232 0.110334 +vt 0.703221 0.118442 +vt 0.439478 0.338480 +vt 0.439476 0.346588 +vt 0.282995 0.346291 +vt 0.282993 0.338205 +vt 0.546436 0.102164 +vt 0.546436 0.094045 +vt 0.703265 0.094109 +vt 0.703247 0.102223 +vt 0.546437 0.191459 +vt 0.546438 0.183340 +vt 0.703281 0.183310 +vt 0.703305 0.191432 +vt 0.439474 0.354696 +vt 0.282992 0.354378 +vt 0.546436 0.085926 +vt 0.703287 0.085990 +vt 0.546438 0.175222 +vt 0.703261 0.175192 +vt 0.546437 0.199578 +vt 0.703331 0.199547 +vt 0.257971 0.331120 +vt 0.258054 0.338794 +vt 0.243736 0.340197 +vt 0.243587 0.333259 +vt 0.657920 0.094109 +vt 0.657937 0.085990 +vt 0.724711 0.088336 +vt 0.724515 0.096194 +vt 0.657932 0.183310 +vt 0.657917 0.175192 +vt 0.724491 0.173293 +vt 0.724679 0.181147 +vt 0.324111 0.362465 +vt 0.324103 0.370552 +vt 0.258030 0.369362 +vt 0.258089 0.361714 +vt 0.657956 0.077866 +vt 0.657978 0.069736 +vt 0.725200 0.072348 +vt 0.724940 0.080393 +vt 0.657903 0.167079 +vt 0.657893 0.158970 +vt 0.724214 0.157770 +vt 0.724336 0.165506 +vt 0.324048 0.289634 +vt 0.324065 0.297729 +vt 0.257299 0.299899 +vt 0.257053 0.291892 +vt 0.324091 0.378642 +vt 0.324076 0.386734 +vt 0.257804 0.384748 +vt 0.257934 0.377036 +vt 0.657885 0.150863 +vt 0.657880 0.142757 +vt 0.724077 0.142403 +vt 0.724128 0.150074 +vt 0.324081 0.305833 +vt 0.324094 0.313931 +vt 0.257701 0.315643 +vt 0.257516 0.307812 +vt 0.324058 0.394830 +vt 0.324038 0.402931 +vt 0.257438 0.400348 +vt 0.257638 0.392514 +vt 0.657879 0.134653 +vt 0.657881 0.126548 +vt 0.724082 0.127086 +vt 0.724062 0.134744 +vt 0.324104 0.322026 +vt 0.324112 0.330116 +vt 0.257853 0.323408 +vt 0.324015 0.411037 +vt 0.323989 0.419149 +vt 0.256940 0.416288 +vt 0.257205 0.408267 +vt 0.657886 0.118442 +vt 0.657895 0.110334 +vt 0.724226 0.111721 +vt 0.724134 0.119419 +vt 0.324117 0.338205 +vt 0.657906 0.102223 +vt 0.724353 0.103984 +vt 0.657951 0.191432 +vt 0.724899 0.189083 +vt 0.657971 0.199547 +vt 0.725149 0.197113 +vt 0.243100 0.319292 +vt 0.243376 0.326294 +vt 0.230467 0.330170 +vt 0.230137 0.324194 +vt 0.738854 0.106922 +vt 0.738639 0.113908 +vt 0.739898 0.183795 +vt 0.740387 0.190988 +vt 0.243852 0.354028 +vt 0.243824 0.347117 +vt 0.739479 0.092836 +vt 0.739132 0.099901 +vt 0.739137 0.169596 +vt 0.739483 0.176667 +vt 0.243725 0.367858 +vt 0.243819 0.360939 +vt 0.740385 0.078548 +vt 0.739895 0.085718 +vt 0.738643 0.155583 +vt 0.738858 0.162571 +vt 0.242346 0.305139 +vt 0.241860 0.297970 +vt 0.243352 0.381755 +vt 0.243570 0.374794 +vt 0.738398 0.141678 +vt 0.738490 0.148622 +vt 0.242758 0.312244 +vt 0.242720 0.395791 +vt 0.243070 0.388751 +vt 0.738397 0.127809 +vt 0.738367 0.134744 +vt 0.241806 0.410027 +vt 0.242300 0.402883 +vt 0.738488 0.120868 +vt 0.229240 0.312211 +vt 0.229729 0.318208 +vt 0.214620 0.327301 +vt 0.214167 0.322901 +vt 0.229228 0.395769 +vt 0.229718 0.389783 +vt 0.751361 0.122767 +vt 0.751254 0.128744 +vt 0.230902 0.342098 +vt 0.230722 0.336137 +vt 0.751794 0.110798 +vt 0.751541 0.116786 +vt 0.753049 0.176673 +vt 0.753624 0.182701 +vt 0.231045 0.354006 +vt 0.231010 0.348053 +vt 0.752531 0.098800 +vt 0.752124 0.104804 +vt 0.752145 0.164645 +vt 0.752557 0.170654 +vt 0.230899 0.365913 +vt 0.231008 0.359959 +vt 0.753590 0.086771 +vt 0.753019 0.092789 +vt 0.751554 0.152657 +vt 0.751812 0.158647 +vt 0.228669 0.306206 +vt 0.230460 0.377834 +vt 0.230717 0.371871 +vt 0.751259 0.140696 +vt 0.751370 0.146674 +vt 0.230128 0.383805 +vt 0.751221 0.134720 +vt 0.228655 0.401761 +vt 0.215728 0.362937 +vt 0.215556 0.367396 +vt 0.203448 0.363106 +vt 0.203583 0.360081 +vt 0.215005 0.376282 +vt 0.215315 0.371846 +vt 0.766464 0.134667 +vt 0.766501 0.139156 +vt 0.215313 0.336159 +vt 0.215002 0.331722 +vt 0.214171 0.385100 +vt 0.214623 0.380702 +vt 0.766597 0.125692 +vt 0.766496 0.130178 +vt 0.215727 0.345068 +vt 0.215555 0.340609 +vt 0.767005 0.116741 +vt 0.766766 0.121212 +vt 0.768183 0.165907 +vt 0.768712 0.170300 +vt 0.215865 0.354003 +vt 0.215830 0.349534 +vt 0.767694 0.107842 +vt 0.767314 0.112283 +vt 0.767341 0.157048 +vt 0.767726 0.161488 +vt 0.215831 0.358472 +vt 0.768669 0.099027 +vt 0.768146 0.103421 +vt 0.766782 0.148121 +vt 0.767027 0.152591 +vt 0.213642 0.318527 +vt 0.766607 0.143642 +vt 0.213646 0.389472 +vt 0.203691 0.354007 +vt 0.203664 0.357046 +vt 0.192769 0.355571 +vt 0.192787 0.353985 +vt 0.778811 0.140719 +vt 0.778949 0.143759 +vt 0.202715 0.335956 +vt 0.202363 0.333026 +vt 0.203015 0.369106 +vt 0.203259 0.366116 +vt 0.778699 0.134615 +vt 0.778728 0.137670 +vt 0.203257 0.341904 +vt 0.203013 0.338917 +vt 0.202366 0.375004 +vt 0.202718 0.372071 +vt 0.778803 0.128507 +vt 0.778724 0.131559 +vt 0.203582 0.347935 +vt 0.203446 0.344911 +vt 0.779125 0.122438 +vt 0.778937 0.125465 +vt 0.780043 0.155706 +vt 0.780452 0.158613 +vt 0.203663 0.350968 +vt 0.779664 0.116449 +vt 0.779368 0.119431 +vt 0.779388 0.149784 +vt 0.779689 0.152761 +vt 0.780422 0.110585 +vt 0.780016 0.113498 +vt 0.779141 0.146782 +vt 0.201957 0.330133 +vt 0.201960 0.377899 +vt 0.192722 0.350817 +vt 0.192771 0.352399 +vt 0.187932 0.353181 +vt 0.187895 0.352388 +vt 0.790470 0.123609 +vt 0.790258 0.125130 +vt 0.789933 0.140935 +vt 0.790081 0.142492 +vt 0.192636 0.358731 +vt 0.192719 0.357154 +vt 0.789734 0.137779 +vt 0.789817 0.139363 +vt 0.192202 0.344607 +vt 0.191993 0.343104 +vt 0.192372 0.361846 +vt 0.192520 0.360296 +vt 0.789666 0.134590 +vt 0.789683 0.136186 +vt 0.192526 0.347681 +vt 0.192380 0.346134 +vt 0.191980 0.364887 +vt 0.192192 0.363378 +vt 0.789732 0.131398 +vt 0.789683 0.132992 +vt 0.192640 0.349243 +vt 0.789930 0.128235 +vt 0.789815 0.129811 +vt 0.790471 0.145541 +vt 0.790711 0.147020 +vt 0.790078 0.126673 +vt 0.790260 0.144028 +vt 0.790712 0.122116 +vt 0.191754 0.341635 +vt 0.191738 0.366368 +vt 0.187744 0.350812 +vt 0.187833 0.351597 +vt 0.185500 0.353667 +vt 0.185487 0.353557 +vt 0.794876 0.130619 +vt 0.794757 0.131397 +vt 0.795012 0.139325 +vt 0.795187 0.140089 +vt 0.187929 0.354770 +vt 0.187943 0.353976 +vt 0.795197 0.129096 +vt 0.795022 0.129851 +vt 0.794749 0.137766 +vt 0.794867 0.138550 +vt 0.187824 0.356348 +vt 0.187889 0.355561 +vt 0.794596 0.136178 +vt 0.794659 0.136974 +vt 0.187483 0.349264 +vt 0.187310 0.348506 +vt 0.187614 0.357899 +vt 0.187732 0.357127 +vt 0.794547 0.134576 +vt 0.794558 0.135378 +vt 0.187628 0.350033 +vt 0.187294 0.359406 +vt 0.187468 0.358659 +vt 0.794600 0.132978 +vt 0.794561 0.133776 +vt 0.794666 0.132184 +vt 0.795394 0.140840 +vt 0.795403 0.128355 +vt 0.187106 0.347762 +vt 0.187090 0.360139 +vt 0.188552 0.069641 +vt 0.185353 0.354816 +vt 0.185388 0.354737 +vt 0.797027 0.134193 +vt 0.797013 0.134304 +vt 0.185514 0.353895 +vt 0.185509 0.353780 +vt 0.797068 0.133982 +vt 0.797045 0.134085 +vt 0.797067 0.135202 +vt 0.797094 0.135299 +vt 0.185510 0.354123 +vt 0.185514 0.354009 +vt 0.797132 0.133806 +vt 0.797095 0.133885 +vt 0.797026 0.134991 +vt 0.797044 0.135099 +vt 0.185487 0.354346 +vt 0.185501 0.354236 +vt 0.797003 0.134765 +vt 0.797012 0.134879 +vt 0.185446 0.353348 +vt 0.185419 0.353252 +vt 0.185447 0.354553 +vt 0.185469 0.354452 +vt 0.796999 0.134533 +vt 0.796999 0.134650 +vt 0.185468 0.353450 +vt 0.185420 0.354648 +vt 0.797004 0.134418 +vt 0.797130 0.135378 +vt 0.797167 0.133725 +vt 0.185392 0.353151 +usemtl Material.006 +s off +f 3/1 2/2 8/3 9/4 4/5 +f 1/6 6/7 4/5 9/4 +f 7/8 5/9 6/7 1/6 +f 12/1 13/5 18/4 17/3 11/2 +f 10/6 18/4 13/5 15/7 +f 16/8 10/6 15/7 14/9 +f 9/4 8/3 17/3 18/4 +f 7/8 1/6 10/6 16/8 +f 8/3 2/2 11/2 17/3 +f 4/5 6/7 15/7 13/5 +f 6/7 5/9 14/9 15/7 +f 5/9 7/8 16/8 14/9 +f 2/2 3/1 12/1 11/2 +f 3/1 4/5 13/5 12/1 +f 1/6 9/4 18/4 10/6 +f 21/10 20/11 26/12 27/13 22/14 +f 19/15 24/16 22/14 27/13 +f 25/17 23/18 24/16 19/15 +f 30/10 31/14 36/13 35/12 29/11 +f 28/15 36/13 31/14 33/16 +f 34/17 28/15 33/16 32/18 +f 27/13 26/12 35/12 36/13 +f 25/17 19/15 28/15 34/17 +f 26/12 20/11 29/11 35/12 +f 22/14 24/16 33/16 31/14 +f 24/16 23/18 32/18 33/16 +f 23/18 25/17 34/17 32/18 +f 20/11 21/10 30/10 29/11 +f 21/10 22/14 31/14 30/10 +f 19/15 27/13 36/13 28/15 +f 41/19 42/20 38/21 37/22 +f 42/20 43/20 39/21 38/21 +f 43/20 44/19 40/22 39/21 +f 44/19 41/19 37/22 40/22 +f 37/22 38/21 39/21 40/22 +f 44/19 43/20 42/20 41/19 +f 49/23 50/24 46/25 45/26 +f 50/24 51/24 47/25 46/25 +f 51/24 52/23 48/26 47/25 +f 52/23 49/23 45/26 48/26 +f 45/26 46/25 47/25 48/26 +f 52/23 51/24 50/24 49/23 +f 57/19 58/20 54/21 53/22 +f 58/20 59/20 55/21 54/21 +f 59/20 60/19 56/22 55/21 +f 60/19 57/19 53/22 56/22 +f 53/22 54/21 55/21 56/22 +f 60/19 59/20 58/20 57/19 +f 65/23 66/24 62/25 61/26 +f 66/24 67/24 63/25 62/25 +f 67/24 68/23 64/26 63/25 +f 68/23 65/23 61/26 64/26 +f 61/26 62/25 63/25 64/26 +f 68/23 67/24 66/24 65/23 +f 71/1 70/2 76/3 77/4 72/5 +f 69/6 74/7 72/5 77/4 +f 75/8 73/9 74/7 69/6 +f 80/1 81/5 86/4 85/3 79/2 +f 78/6 86/4 81/5 83/7 +f 84/8 78/6 83/7 82/9 +f 77/4 76/3 85/3 86/4 +f 75/8 69/6 78/6 84/8 +f 76/3 70/2 79/2 85/3 +f 72/5 74/7 83/7 81/5 +f 74/7 73/9 82/9 83/7 +f 73/9 75/8 84/8 82/9 +f 70/2 71/1 80/1 79/2 +f 71/1 72/5 81/5 80/1 +f 69/6 77/4 86/4 78/6 +f 89/10 88/11 94/12 95/13 90/14 +f 87/15 92/16 90/14 95/13 +f 93/17 91/18 92/16 87/15 +f 98/10 99/14 104/13 103/12 97/11 +f 96/15 104/13 99/14 101/16 +f 102/17 96/15 101/16 100/18 +f 95/13 94/12 103/12 104/13 +f 93/17 87/15 96/15 102/17 +f 94/12 88/11 97/11 103/12 +f 90/14 92/16 101/16 99/14 +f 92/16 91/18 100/18 101/16 +f 91/18 93/17 102/17 100/18 +f 88/11 89/10 98/10 97/11 +f 89/10 90/14 99/14 98/10 +f 87/15 95/13 104/13 96/15 +f 107/1 106/2 112/3 113/4 108/5 +f 105/6 110/7 108/5 113/4 +f 111/8 109/9 110/7 105/6 +f 116/1 117/5 122/4 121/3 115/2 +f 114/6 122/4 117/5 119/7 +f 120/8 114/6 119/7 118/9 +f 113/4 112/3 121/3 122/4 +f 111/8 105/6 114/6 120/8 +f 112/3 106/2 115/2 121/3 +f 108/5 110/7 119/7 117/5 +f 110/7 109/9 118/9 119/7 +f 109/9 111/8 120/8 118/9 +f 106/2 107/1 116/1 115/2 +f 107/1 108/5 117/5 116/1 +f 105/6 113/4 122/4 114/6 +f 125/10 124/11 130/12 131/13 126/14 +f 123/15 128/16 126/14 131/13 +f 129/17 127/18 128/16 123/15 +f 134/10 135/14 140/13 139/12 133/11 +f 132/15 140/13 135/14 137/16 +f 138/17 132/15 137/16 136/18 +f 131/13 130/12 139/12 140/13 +f 129/17 123/15 132/15 138/17 +f 130/12 124/11 133/11 139/12 +f 126/14 128/16 137/16 135/14 +f 128/16 127/18 136/18 137/16 +f 127/18 129/17 138/17 136/18 +f 124/11 125/10 134/10 133/11 +f 125/10 126/14 135/14 134/10 +f 123/15 131/13 140/13 132/15 +f 145/19 146/20 142/21 141/22 +f 146/20 147/20 143/21 142/21 +f 147/20 148/19 144/22 143/21 +f 148/19 145/19 141/22 144/22 +f 141/22 142/21 143/21 144/22 +f 148/19 147/20 146/20 145/19 +f 153/23 154/24 150/25 149/26 +f 154/24 155/24 151/25 150/25 +f 155/24 156/23 152/26 151/25 +f 156/23 153/23 149/26 152/26 +f 149/26 150/25 151/25 152/26 +f 156/23 155/24 154/24 153/23 +f 161/19 162/20 158/21 157/22 +f 162/20 163/20 159/21 158/21 +f 163/20 164/19 160/22 159/21 +f 164/19 161/19 157/22 160/22 +f 157/22 158/21 159/21 160/22 +f 164/19 163/20 162/20 161/19 +f 169/23 170/24 166/25 165/26 +f 170/24 171/24 167/25 166/25 +f 171/24 172/23 168/26 167/25 +f 172/23 169/23 165/26 168/26 +f 165/26 166/25 167/25 168/26 +f 172/23 171/24 170/24 169/23 +f 175/1 174/2 180/3 181/4 176/5 +f 173/6 178/7 176/5 181/4 +f 179/8 177/9 178/7 173/6 +f 184/1 185/5 190/4 189/3 183/2 +f 182/6 190/4 185/5 187/7 +f 188/8 182/6 187/7 186/9 +f 181/4 180/3 189/3 190/4 +f 179/8 173/6 182/6 188/8 +f 180/3 174/2 183/2 189/3 +f 176/5 178/7 187/7 185/5 +f 178/7 177/9 186/9 187/7 +f 177/9 179/8 188/8 186/9 +f 174/2 175/1 184/1 183/2 +f 175/1 176/5 185/5 184/1 +f 173/6 181/4 190/4 182/6 +f 193/10 192/11 198/12 199/13 194/14 +f 191/15 196/16 194/14 199/13 +f 197/17 195/18 196/16 191/15 +f 202/10 203/14 208/13 207/12 201/11 +f 200/15 208/13 203/14 205/16 +f 206/17 200/15 205/16 204/18 +f 199/13 198/12 207/12 208/13 +f 197/17 191/15 200/15 206/17 +f 198/12 192/11 201/11 207/12 +f 194/14 196/16 205/16 203/14 +f 196/16 195/18 204/18 205/16 +f 195/18 197/17 206/17 204/18 +f 192/11 193/10 202/10 201/11 +f 193/10 194/14 203/14 202/10 +f 191/15 199/13 208/13 200/15 +f 261/27 263/28 716/29 715/30 +f 714/31 715/32 747/33 746/34 +f 217/35 219/36 694/37 693/38 +f 239/39 241/40 705/41 704/42 +f 267/43 269/44 719/45 718/46 +f 245/47 247/48 708/49 707/50 +f 209/51 211/52 690/53 689/54 +f 223/55 225/56 697/57 696/58 +f 251/59 253/60 711/61 710/62 +f 229/63 231/64 700/65 699/66 +f 257/67 259/68 714/69 713/70 +f 213/71 215/72 692/73 691/74 +f 235/75 237/76 703/77 702/78 +f 263/28 265/79 717/80 716/29 +f 241/40 243/81 706/82 705/41 +f 219/36 221/83 695/84 694/37 +f 269/44 271/85 720/86 719/45 +f 247/48 249/87 709/88 708/49 +f 225/56 227/89 698/90 697/57 +f 253/60 255/91 712/92 711/61 +f 231/64 233/93 701/94 700/65 +f 259/68 261/27 715/30 714/69 +f 215/72 217/35 693/38 692/73 +f 237/76 239/39 704/42 703/77 +f 265/79 267/43 718/46 717/80 +f 243/81 245/47 707/50 706/82 +f 221/83 223/55 696/58 695/84 +f 271/85 209/51 689/54 720/86 +f 249/87 251/59 710/62 709/88 +f 227/89 229/63 699/66 698/90 +f 255/91 257/67 713/70 712/92 +f 211/52 213/71 691/74 690/53 +f 233/93 235/75 702/78 701/94 +f 721/95 722/96 723/97 724/98 725/99 726/100 727/101 728/102 729/103 730/104 731/105 732/106 733/107 734/108 735/109 736/110 737/111 738/112 739/113 740/114 741/115 742/116 743/117 744/118 745/119 746/120 747/121 748/122 749/123 750/124 751/125 752/126 +f 692/127 693/128 725/129 724/130 +f 703/131 704/132 736/133 735/134 +f 712/135 713/136 745/137 744/138 +f 690/139 691/140 723/141 722/142 +f 701/143 702/144 734/145 733/146 +f 710/147 711/148 743/149 742/150 +f 699/151 700/152 732/153 731/154 +f 719/155 720/156 752/157 751/158 +f 708/159 709/160 741/161 740/162 +f 697/163 698/164 730/165 729/166 +f 717/167 718/168 750/169 749/170 +f 706/171 707/172 739/173 738/174 +f 695/175 696/176 728/177 727/178 +f 715/32 716/179 748/180 747/33 +f 693/128 694/181 726/182 725/129 +f 704/132 705/183 737/184 736/133 +f 713/136 714/31 746/34 745/137 +f 691/140 692/127 724/130 723/141 +f 702/144 703/131 735/134 734/145 +f 711/148 712/135 744/138 743/149 +f 689/185 690/139 722/142 721/186 +f 700/152 701/143 733/146 732/153 +f 720/156 689/187 721/188 752/157 +f 709/160 710/147 742/150 741/161 +f 698/164 699/151 731/154 730/165 +f 718/168 719/155 751/158 750/169 +f 707/172 708/159 740/162 739/173 +f 696/176 697/163 729/166 728/177 +f 716/179 717/167 749/170 748/180 +f 705/189 706/171 738/174 737/190 +f 694/181 695/175 727/178 726/182 +s 1 +f 209/191 210/192 212/193 211/194 +f 211/194 212/193 214/195 213/196 +f 213/196 214/195 216/197 215/198 +f 215/198 216/197 218/199 217/200 +f 217/200 218/199 220/201 219/202 +f 219/202 220/201 222/203 221/204 +f 221/204 222/203 224/205 223/206 +f 223/206 224/205 226/207 225/208 +f 225/208 226/207 228/209 227/210 +f 227/210 228/209 230/211 229/212 +f 229/212 230/211 232/213 231/214 +f 231/214 232/213 234/215 233/216 +f 233/216 234/215 236/217 235/218 +f 235/218 236/217 238/219 237/220 +f 237/220 238/219 240/221 239/222 +f 239/222 240/221 242/223 241/224 +f 241/225 242/226 244/227 243/228 +f 243/228 244/227 246/229 245/230 +f 245/230 246/229 248/231 247/232 +f 247/232 248/231 250/233 249/234 +f 249/234 250/233 252/235 251/236 +f 251/236 252/235 254/237 253/238 +f 253/238 254/237 256/239 255/240 +f 255/240 256/239 258/241 257/242 +f 257/242 258/241 260/243 259/244 +f 259/244 260/243 262/245 261/246 +f 261/246 262/245 264/247 263/248 +f 263/248 264/247 266/249 265/250 +f 265/250 266/249 268/251 267/252 +f 267/252 268/251 270/253 269/254 +f 256/255 254/256 295/257 296/258 +f 271/259 272/260 210/261 209/262 +f 269/254 270/253 272/260 271/259 +f 301/263 300/264 332/265 333/266 +f 234/267 232/268 284/269 285/270 +f 262/271 260/272 298/273 299/274 +f 218/275 216/276 276/277 277/278 +f 240/279 238/280 287/281 288/282 +f 268/283 266/284 301/263 302/285 +f 246/286 244/287 290/288 291/289 +f 224/290 222/291 279/292 280/293 +f 210/294 272/295 304/296 273/297 +f 252/298 250/299 293/300 294/301 +f 230/302 228/303 282/304 283/305 +f 258/306 256/255 296/258 297/307 +f 214/308 212/309 274/310 275/311 +f 236/312 234/267 285/270 286/313 +f 264/314 262/271 299/274 300/264 +f 220/315 218/275 277/278 278/316 +f 242/317 240/279 288/282 289/318 +f 270/319 268/283 302/285 303/320 +f 248/321 246/286 291/289 292/322 +f 212/309 210/323 273/324 274/310 +f 226/325 224/290 280/293 281/326 +f 254/256 252/298 294/301 295/257 +f 232/268 230/302 283/305 284/269 +f 260/272 258/306 297/307 298/273 +f 216/276 214/308 275/311 276/277 +f 238/280 236/312 286/313 287/281 +f 266/284 264/314 300/264 301/263 +f 244/287 242/327 289/328 290/288 +f 222/291 220/315 278/316 279/292 +f 272/295 270/319 303/320 304/296 +f 250/299 248/321 292/322 293/300 +f 228/303 226/325 281/326 282/304 +f 335/329 334/330 366/331 367/332 +f 290/288 289/328 321/333 322/334 +f 279/292 278/316 310/335 311/336 +f 299/274 298/273 330/337 331/338 +f 277/278 276/277 308/339 309/340 +f 288/282 287/281 319/341 320/342 +f 297/307 296/258 328/343 329/344 +f 275/311 274/310 306/345 307/346 +f 286/313 285/270 317/347 318/348 +f 295/257 294/301 326/349 327/350 +f 284/269 283/305 315/351 316/352 +f 304/296 303/320 335/329 336/353 +f 293/300 292/322 324/354 325/355 +f 282/304 281/326 313/356 314/357 +f 302/285 301/263 333/266 334/330 +f 291/289 290/288 322/334 323/358 +f 280/293 279/292 311/336 312/359 +f 300/264 299/274 331/338 332/265 +f 278/316 277/278 309/340 310/335 +f 289/318 288/282 320/342 321/360 +f 298/273 297/307 329/344 330/337 +f 276/277 275/311 307/346 308/339 +f 287/281 286/313 318/348 319/341 +f 296/258 295/257 327/350 328/343 +f 274/310 273/324 305/361 306/345 +f 285/270 284/269 316/352 317/347 +f 273/297 304/296 336/353 305/362 +f 294/301 293/300 325/355 326/349 +f 283/305 282/304 314/357 315/351 +f 303/320 302/285 334/330 335/329 +f 292/322 291/289 323/358 324/354 +f 281/326 280/293 312/359 313/356 +f 337/363 368/364 400/365 369/366 +f 324/354 323/358 355/367 356/368 +f 313/356 312/359 344/369 345/370 +f 333/266 332/265 364/371 365/372 +f 322/334 321/333 353/373 354/374 +f 311/336 310/335 342/375 343/376 +f 331/338 330/337 362/377 363/378 +f 309/340 308/339 340/379 341/380 +f 320/342 319/341 351/381 352/382 +f 329/344 328/343 360/383 361/384 +f 307/346 306/345 338/385 339/386 +f 318/348 317/347 349/387 350/388 +f 327/350 326/349 358/389 359/390 +f 316/352 315/351 347/391 348/392 +f 336/353 335/329 367/332 368/364 +f 325/355 324/354 356/368 357/393 +f 314/357 313/356 345/370 346/394 +f 334/330 333/266 365/372 366/331 +f 323/358 322/334 354/374 355/367 +f 312/359 311/336 343/376 344/369 +f 332/265 331/338 363/378 364/371 +f 310/335 309/340 341/380 342/375 +f 321/360 320/342 352/382 353/395 +f 330/337 329/344 361/384 362/377 +f 308/339 307/346 339/386 340/379 +f 319/341 318/348 350/388 351/381 +f 328/343 327/350 359/390 360/383 +f 306/345 305/361 337/396 338/385 +f 317/347 316/352 348/392 349/387 +f 305/362 336/353 368/364 337/363 +f 326/349 325/355 357/393 358/389 +f 315/351 314/357 346/394 347/391 +f 392/397 391/398 423/399 424/400 +f 358/389 357/393 389/401 390/402 +f 347/391 346/394 378/403 379/404 +f 367/332 366/331 398/405 399/406 +f 356/368 355/367 387/407 388/408 +f 345/370 344/369 376/409 377/410 +f 365/372 364/371 396/411 397/412 +f 354/374 353/373 385/413 386/414 +f 343/376 342/375 374/415 375/416 +f 363/378 362/377 394/417 395/418 +f 341/380 340/379 372/419 373/420 +f 352/382 351/381 383/421 384/422 +f 361/384 360/383 392/423 393/424 +f 339/386 338/385 370/425 371/426 +f 350/388 349/387 381/427 382/428 +f 359/390 358/389 390/402 391/429 +f 348/392 347/391 379/404 380/430 +f 368/364 367/332 399/406 400/365 +f 357/393 356/368 388/408 389/401 +f 346/394 345/370 377/410 378/403 +f 366/331 365/372 397/412 398/405 +f 355/367 354/374 386/414 387/407 +f 344/369 343/376 375/416 376/409 +f 364/371 363/378 395/418 396/411 +f 342/375 341/380 373/420 374/415 +f 353/395 352/382 384/422 385/431 +f 362/377 361/384 393/424 394/417 +f 340/379 339/386 371/426 372/419 +f 351/381 350/388 382/428 383/421 +f 360/383 359/390 391/429 392/423 +f 338/385 337/396 369/432 370/425 +f 349/387 348/392 380/430 381/427 +f 426/433 425/434 457/435 458/436 +f 370/437 369/438 401/439 402/440 +f 381/441 380/442 412/443 413/444 +f 369/445 400/446 432/447 401/448 +f 390/449 389/450 421/451 422/452 +f 379/453 378/454 410/455 411/456 +f 399/457 398/458 430/459 431/460 +f 388/461 387/462 419/463 420/464 +f 377/465 376/466 408/467 409/468 +f 397/469 396/470 428/471 429/472 +f 386/473 385/474 417/475 418/476 +f 375/477 374/478 406/479 407/480 +f 395/481 394/482 426/483 427/484 +f 373/485 372/486 404/487 405/488 +f 384/489 383/490 415/491 416/492 +f 393/493 392/397 424/400 425/494 +f 371/495 370/437 402/440 403/496 +f 382/497 381/441 413/444 414/498 +f 391/398 390/449 422/452 423/399 +f 380/442 379/453 411/456 412/443 +f 400/446 399/457 431/460 432/447 +f 389/450 388/461 420/464 421/451 +f 378/454 377/465 409/468 410/455 +f 398/458 397/469 429/472 430/459 +f 387/462 386/473 418/476 419/463 +f 376/466 375/477 407/480 408/467 +f 396/470 395/481 427/484 428/471 +f 374/478 373/485 405/488 406/479 +f 385/499 384/489 416/492 417/500 +f 394/482 393/493 425/494 426/483 +f 372/486 371/495 403/496 404/487 +f 383/490 382/497 414/498 415/491 +f 460/501 459/502 491/503 492/504 +f 404/505 403/506 435/507 436/508 +f 415/509 414/510 446/511 447/512 +f 424/513 423/514 455/515 456/516 +f 402/517 401/518 433/519 434/520 +f 413/521 412/522 444/523 445/524 +f 401/525 432/526 464/527 433/528 +f 422/529 421/530 453/531 454/532 +f 411/533 410/534 442/535 443/536 +f 431/537 430/538 462/539 463/540 +f 420/541 419/542 451/543 452/544 +f 409/545 408/546 440/547 441/548 +f 429/549 428/550 460/501 461/551 +f 418/552 417/553 449/554 450/555 +f 407/556 406/557 438/558 439/559 +f 427/560 426/433 458/436 459/502 +f 405/561 404/505 436/508 437/562 +f 416/563 415/509 447/512 448/564 +f 425/434 424/513 456/516 457/435 +f 403/506 402/517 434/520 435/507 +f 414/510 413/521 445/524 446/511 +f 423/514 422/529 454/532 455/515 +f 412/522 411/533 443/536 444/523 +f 432/526 431/537 463/540 464/527 +f 421/530 420/541 452/544 453/531 +f 410/534 409/545 441/548 442/535 +f 430/538 429/549 461/551 462/539 +f 419/542 418/552 450/555 451/543 +f 408/546 407/556 439/559 440/547 +f 428/550 427/560 459/502 460/501 +f 406/557 405/561 437/562 438/558 +f 417/565 416/563 448/564 449/566 +f 494/567 493/568 525/569 526/570 +f 438/558 437/562 469/571 470/572 +f 449/566 448/564 480/573 481/574 +f 458/436 457/435 489/575 490/576 +f 436/508 435/507 467/577 468/578 +f 447/512 446/511 478/579 479/580 +f 456/516 455/515 487/581 488/582 +f 434/520 433/519 465/583 466/584 +f 445/524 444/523 476/585 477/586 +f 433/528 464/527 496/587 465/588 +f 454/532 453/531 485/589 486/590 +f 443/536 442/535 474/591 475/592 +f 463/540 462/539 494/567 495/593 +f 452/544 451/543 483/594 484/595 +f 441/548 440/547 472/596 473/597 +f 461/551 460/501 492/504 493/568 +f 450/555 449/554 481/598 482/599 +f 439/559 438/558 470/572 471/600 +f 459/502 458/436 490/576 491/503 +f 437/562 436/508 468/578 469/571 +f 448/564 447/512 479/580 480/573 +f 457/435 456/516 488/582 489/575 +f 435/507 434/520 466/584 467/577 +f 446/511 445/524 477/586 478/579 +f 455/515 454/532 486/590 487/581 +f 444/523 443/536 475/592 476/585 +f 464/527 463/540 495/593 496/587 +f 453/531 452/544 484/595 485/589 +f 442/535 441/548 473/597 474/591 +f 462/539 461/551 493/568 494/567 +f 451/543 450/555 482/599 483/594 +f 440/547 439/559 471/600 472/596 +f 528/601 527/602 559/603 560/604 +f 483/594 482/599 514/605 515/606 +f 472/596 471/600 503/607 504/608 +f 492/504 491/503 523/609 524/610 +f 470/572 469/571 501/611 502/612 +f 481/574 480/573 512/613 513/614 +f 490/576 489/575 521/615 522/616 +f 468/578 467/577 499/617 500/618 +f 479/580 478/579 510/619 511/620 +f 488/582 487/581 519/621 520/622 +f 466/584 465/583 497/623 498/624 +f 477/586 476/585 508/625 509/626 +f 465/588 496/587 528/601 497/627 +f 486/590 485/589 517/628 518/629 +f 475/592 474/591 506/630 507/631 +f 495/593 494/567 526/570 527/602 +f 484/595 483/594 515/606 516/632 +f 473/597 472/596 504/608 505/633 +f 493/568 492/504 524/610 525/569 +f 482/599 481/598 513/634 514/605 +f 471/600 470/572 502/612 503/607 +f 491/503 490/576 522/616 523/609 +f 469/571 468/578 500/618 501/611 +f 480/573 479/580 511/620 512/613 +f 489/575 488/582 520/622 521/615 +f 467/577 466/584 498/624 499/617 +f 478/579 477/586 509/626 510/619 +f 487/581 486/590 518/629 519/621 +f 476/585 475/592 507/631 508/625 +f 496/587 495/593 527/602 528/601 +f 485/589 484/595 516/632 517/628 +f 474/591 473/597 505/633 506/630 +f 551/635 550/636 582/637 583/638 +f 517/628 516/632 548/639 549/640 +f 506/630 505/633 537/641 538/642 +f 526/570 525/569 557/643 558/644 +f 515/606 514/605 546/645 547/646 +f 504/608 503/607 535/647 536/648 +f 524/610 523/609 555/649 556/650 +f 502/612 501/611 533/651 534/652 +f 513/614 512/613 544/653 545/654 +f 522/616 521/615 553/655 554/656 +f 500/618 499/617 531/657 532/658 +f 511/620 510/619 542/659 543/660 +f 520/622 519/621 551/635 552/661 +f 498/624 497/623 529/662 530/663 +f 509/626 508/625 540/664 541/665 +f 497/627 528/601 560/604 529/666 +f 518/629 517/628 549/640 550/636 +f 507/631 506/630 538/642 539/667 +f 527/602 526/570 558/644 559/603 +f 516/632 515/606 547/646 548/639 +f 505/633 504/608 536/648 537/641 +f 525/569 524/610 556/650 557/643 +f 514/605 513/634 545/668 546/645 +f 503/607 502/612 534/652 535/647 +f 523/609 522/616 554/656 555/649 +f 501/611 500/618 532/658 533/651 +f 512/613 511/620 543/660 544/653 +f 521/615 520/622 552/661 553/655 +f 499/617 498/624 530/663 531/657 +f 510/619 509/626 541/665 542/659 +f 519/621 518/629 550/636 551/635 +f 508/625 507/631 539/667 540/664 +f 585/669 584/670 616/671 617/672 +f 540/664 539/667 571/673 572/674 +f 560/604 559/603 591/675 592/676 +f 549/640 548/639 580/677 581/678 +f 538/642 537/641 569/679 570/680 +f 558/644 557/643 589/681 590/682 +f 547/646 546/645 578/683 579/684 +f 536/648 535/647 567/685 568/686 +f 556/650 555/649 587/687 588/688 +f 534/652 533/651 565/689 566/690 +f 545/654 544/653 576/691 577/692 +f 554/656 553/655 585/669 586/693 +f 532/658 531/657 563/694 564/695 +f 543/660 542/659 574/696 575/697 +f 552/661 551/635 583/638 584/670 +f 530/663 529/662 561/698 562/699 +f 541/665 540/664 572/674 573/700 +f 529/666 560/604 592/676 561/701 +f 550/636 549/640 581/678 582/637 +f 539/667 538/642 570/680 571/673 +f 559/603 558/644 590/682 591/675 +f 548/639 547/646 579/684 580/677 +f 537/641 536/648 568/686 569/679 +f 557/643 556/650 588/688 589/681 +f 546/645 545/668 577/702 578/683 +f 535/647 534/652 566/690 567/685 +f 555/649 554/656 586/693 587/687 +f 533/651 532/658 564/695 565/689 +f 544/653 543/660 575/697 576/691 +f 553/655 552/661 584/670 585/669 +f 531/657 530/663 562/699 563/694 +f 542/659 541/665 573/700 574/696 +f 619/703 618/704 650/705 651/706 +f 563/694 562/699 594/707 595/708 +f 574/696 573/700 605/709 606/710 +f 583/638 582/637 614/711 615/712 +f 572/674 571/673 603/713 604/714 +f 592/676 591/675 623/715 624/716 +f 581/678 580/677 612/717 613/718 +f 570/680 569/679 601/719 602/720 +f 590/682 589/681 621/721 622/722 +f 579/684 578/683 610/723 611/724 +f 568/686 567/685 599/725 600/726 +f 588/688 587/687 619/703 620/727 +f 566/690 565/689 597/728 598/729 +f 577/692 576/691 608/730 609/731 +f 586/693 585/669 617/672 618/704 +f 564/695 563/694 595/708 596/732 +f 575/697 574/696 606/710 607/733 +f 584/670 583/638 615/712 616/671 +f 562/699 561/698 593/734 594/707 +f 573/700 572/674 604/714 605/709 +f 561/701 592/676 624/716 593/735 +f 582/637 581/678 613/718 614/711 +f 571/673 570/680 602/720 603/713 +f 591/675 590/682 622/722 623/715 +f 580/677 579/684 611/724 612/717 +f 569/679 568/686 600/726 601/719 +f 589/681 588/688 620/727 621/721 +f 578/683 577/702 609/736 610/723 +f 567/685 566/690 598/729 599/725 +f 587/687 586/693 618/704 619/703 +f 565/689 564/695 596/732 597/728 +f 576/691 575/697 607/733 608/730 +f 653/737 652/738 684/739 685/740 +f 597/728 596/732 628/741 629/742 +f 608/730 607/733 639/743 640/744 +f 617/672 616/671 648/745 649/746 +f 595/708 594/707 626/747 627/748 +f 606/710 605/709 637/749 638/750 +f 615/712 614/711 646/751 647/752 +f 604/714 603/713 635/753 636/754 +f 624/716 623/715 655/755 656/756 +f 613/718 612/717 644/757 645/758 +f 602/720 601/719 633/759 634/760 +f 622/722 621/721 653/737 654/761 +f 611/724 610/723 642/762 643/763 +f 600/726 599/725 631/764 632/765 +f 620/727 619/703 651/706 652/738 +f 598/729 597/728 629/742 630/766 +f 609/731 608/730 640/744 641/767 +f 618/704 617/672 649/746 650/705 +f 596/732 595/708 627/748 628/741 +f 607/733 606/710 638/750 639/743 +f 616/671 615/712 647/752 648/745 +f 594/707 593/734 625/768 626/747 +f 605/709 604/714 636/754 637/749 +f 593/735 624/716 656/756 625/769 +f 614/711 613/718 645/758 646/751 +f 603/713 602/720 634/760 635/753 +f 623/715 622/722 654/761 655/755 +f 612/717 611/724 643/763 644/757 +f 601/719 600/726 632/765 633/759 +f 621/721 620/727 652/738 653/737 +f 610/723 609/736 641/770 642/762 +f 599/725 598/729 630/766 631/764 +f 658/771 657/771 688/771 687/771 686/771 685/771 684/771 683/771 682/771 681/771 680/771 679/771 678/771 677/771 676/771 675/771 674/771 673/771 672/771 671/771 670/771 669/771 668/771 667/771 666/771 665/771 664/771 663/771 662/771 661/771 660/771 659/771 +f 642/762 641/770 673/772 674/773 +f 631/764 630/766 662/774 663/775 +f 651/706 650/705 682/776 683/777 +f 629/742 628/741 660/778 661/779 +f 640/744 639/743 671/780 672/781 +f 649/746 648/745 680/782 681/783 +f 627/748 626/747 658/784 659/785 +f 638/750 637/749 669/786 670/787 +f 647/752 646/751 678/788 679/789 +f 636/754 635/753 667/790 668/791 +f 656/756 655/755 687/792 688/793 +f 645/758 644/757 676/794 677/795 +f 634/760 633/759 665/796 666/797 +f 654/761 653/737 685/740 686/798 +f 643/763 642/762 674/773 675/799 +f 632/765 631/764 663/775 664/800 +f 652/738 651/706 683/777 684/739 +f 630/766 629/742 661/779 662/774 +f 641/767 640/744 672/781 673/801 +f 650/705 649/746 681/783 682/776 +f 628/741 627/748 659/785 660/778 +f 639/743 638/750 670/787 671/780 +f 648/745 647/752 679/789 680/782 +f 626/747 625/768 657/802 658/784 +f 637/749 636/754 668/791 669/786 +f 625/769 656/756 688/793 657/803 +f 646/751 645/758 677/795 678/788 +f 635/753 634/760 666/797 667/790 +f 655/755 654/761 686/798 687/792 +f 644/757 643/763 675/799 676/794 +f 633/759 632/765 664/800 665/796 diff --git a/Projekte/battleship/client/src/main/resources/Models/Missile/README.txt b/Projekte/battleship/client/src/main/resources/Models/Missile/README.txt new file mode 100644 index 00000000..be10eedb --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Models/Missile/README.txt @@ -0,0 +1,2 @@ +AIM-120D Missile (Air-to-Air) by https://free3d.com/3d-model/aim-120d-shell-air-to-air-20348.html +License: License for personal use \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Models/Missile/texture.png b/Projekte/battleship/client/src/main/resources/Models/Missile/texture.png new file mode 100644 index 00000000..c86d1e3e Binary files /dev/null and b/Projekte/battleship/client/src/main/resources/Models/Missile/texture.png differ diff --git a/Projekte/battleship/client/src/main/resources/Sound/Effects/README.txt b/Projekte/battleship/client/src/main/resources/Sound/Effects/README.txt new file mode 100644 index 00000000..400f328a --- /dev/null +++ b/Projekte/battleship/client/src/main/resources/Sound/Effects/README.txt @@ -0,0 +1,2 @@ +Missile firing fl by NHMWretched (https://pixabay.com/sound-effects/missile-firing-fl-106655/) +CCO License \ No newline at end of file diff --git a/Projekte/battleship/client/src/main/resources/Sound/Effects/missilefiring.wav b/Projekte/battleship/client/src/main/resources/Sound/Effects/missilefiring.wav new file mode 100644 index 00000000..b0446a42 Binary files /dev/null and b/Projekte/battleship/client/src/main/resources/Sound/Effects/missilefiring.wav differ diff --git a/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java b/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java index 819fc9db..2c9f279d 100644 --- a/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java +++ b/Projekte/battleship/converter/src/main/java/pp/battleship/exporter/ModelExporter.java @@ -41,7 +41,7 @@ public static void main(String[] args) { */ @Override public void simpleInitApp() { - export("Models/KingGeorgeV/King_George_V.obj", "KingGeorgeV.j3o"); //NON-NLS + export("Models/KingGeorgeV/King_George_V.obj", "Models/KingGeorgeV/KingGeorgeV.j3o"); //NON-NLS stop(); } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/AnimationState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/AnimationState.java new file mode 100644 index 00000000..01336fd5 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/AnimationState.java @@ -0,0 +1,94 @@ +package pp.battleship.game.client; + +import pp.battleship.message.client.EndAnimationMessage; +import pp.battleship.message.server.EffectMessage; +import pp.battleship.message.server.SwitchToBattleState; +import pp.battleship.model.IntPoint; +import pp.battleship.model.Shell; +import pp.battleship.model.ShipMap; +import pp.battleship.notification.Music; +import pp.battleship.notification.Sound; + +import java.lang.System.Logger.Level; + +public class AnimationState extends ClientState{ + + private boolean myTurn; + + public AnimationState(ClientGameLogic logic, boolean turn, IntPoint position) { + super(logic); + logic.playMusic(Music.GAME_THEME); + myTurn = turn; + if (myTurn){ + logic.getOpponentMap().add(new Shell(position)); + } + else { + logic.getOwnMap().add(new Shell(position)); + } + } + + @Override + boolean showBattle(){ + return true; + } + + /** + * Reports the effect of a shot based on the server message. + * + * @param msg the message containing the effect of the shot + */ + @Override + public void receivedEffect(EffectMessage msg) { + ClientGameLogic.LOGGER.log(Level.INFO, "report effect: {0}", msg); //NON-NLS + playSound(msg); + myTurn = msg.isMyTurn(); + logic.setInfoText(msg.getInfoTextKey()); + affectedMap(msg).add(msg.getShot()); + if (destroyedOpponentShip(msg)) + logic.getOpponentMap().add(msg.getDestroyedShip()); + if (msg.isGameOver()) { + msg.getRemainingOpponentShips().forEach(logic.getOpponentMap()::add); + logic.setState(new GameOverState(logic, msg.isGameLost())); + } + } + + @Override + public void receivedSwitchToBattleState(SwitchToBattleState msg){ + logic.setState(new BattleState(logic, msg.getTurn())); + } + + /** + * Determines which map (own or opponent's) should be affected by the shot based on the message. + * + * @param msg the effect message received from the server + * @return the map (either the opponent's or player's own map) that is affected by the shot + */ + private ShipMap affectedMap(EffectMessage msg) { + return msg.isOwnShot() ? logic.getOpponentMap() : logic.getOwnMap(); + } + + /** + * Checks if the opponent's ship was destroyed by the player's shot. + * + * @param msg the effect message received from the server + * @return true if the shot destroyed an opponent's ship, false otherwise + */ + private boolean destroyedOpponentShip(EffectMessage msg) { + return msg.getDestroyedShip() != null && msg.isOwnShot(); + } + + /** + * Plays a sound based on the outcome of the shot. Different sounds are played for a miss, hit, + * or destruction of a ship. + * + * @param msg the effect message containing the result of the shot + */ + private void playSound(EffectMessage msg) { + if (!msg.getShot().isHit()) + logic.playSound(Sound.SPLASH); + else if (msg.getDestroyedShip() == null) + logic.playSound(Sound.EXPLOSION); + else + logic.playSound(Sound.DESTROYED_SHIP); + } +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java index ab8a227d..60339373 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/BattleState.java @@ -9,6 +9,7 @@ import pp.battleship.message.client.ShootMessage; import pp.battleship.message.server.EffectMessage; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.model.IntPoint; import pp.battleship.model.ShipMap; import pp.battleship.notification.Music; @@ -47,58 +48,9 @@ else if (logic.getOpponentMap().isValid(pos)) logic.send(new ShootMessage(pos)); } - /** - * Reports the effect of a shot based on the server message. - * - * @param msg the message containing the effect of the shot - */ @Override - public void receivedEffect(EffectMessage msg) { - ClientGameLogic.LOGGER.log(Level.INFO, "report effect: {0}", msg); //NON-NLS - playSound(msg); - myTurn = msg.isMyTurn(); - logic.setInfoText(msg.getInfoTextKey()); - affectedMap(msg).add(msg.getShot()); - if (destroyedOpponentShip(msg)) - logic.getOpponentMap().add(msg.getDestroyedShip()); - if (msg.isGameOver()) { - msg.getRemainingOpponentShips().forEach(logic.getOpponentMap()::add); - logic.setState(new GameOverState(logic, msg.isGameLost())); - } - } - - /** - * Determines which map (own or opponent's) should be affected by the shot based on the message. - * - * @param msg the effect message received from the server - * @return the map (either the opponent's or player's own map) that is affected by the shot - */ - private ShipMap affectedMap(EffectMessage msg) { - return msg.isOwnShot() ? logic.getOpponentMap() : logic.getOwnMap(); - } - - /** - * Checks if the opponent's ship was destroyed by the player's shot. - * - * @param msg the effect message received from the server - * @return true if the shot destroyed an opponent's ship, false otherwise - */ - private boolean destroyedOpponentShip(EffectMessage msg) { - return msg.getDestroyedShip() != null && msg.isOwnShot(); - } - - /** - * Plays a sound based on the outcome of the shot. Different sounds are played for a miss, hit, - * or destruction of a ship. - * - * @param msg the effect message containing the result of the shot - */ - private void playSound(EffectMessage msg) { - if (!msg.getShot().isHit()) - logic.playSound(Sound.SPLASH); - else if (msg.getDestroyedShip() == null) - logic.playSound(Sound.EXPLOSION); - else - logic.playSound(Sound.DESTROYED_SHIP); + public void receivedStartAnimation(StartAnimationMessage msg){ + logic.setState(new AnimationState(logic, msg.isMyTurn(), msg.getPosition() )); + logic.playSound(Sound.MISSILE_LAUNCH); } } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java index ffa17667..e5c7768c 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientGameLogic.java @@ -11,7 +11,9 @@ import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.GameDetails; import pp.battleship.message.server.ServerInterpreter; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.SwitchToBattleState; import pp.battleship.model.IntPoint; import pp.battleship.model.ShipMap; import pp.battleship.model.dto.ShipMapDTO; @@ -228,6 +230,22 @@ public void received(EffectMessage msg) { state.receivedEffect(msg); } + /** + * @param msg + */ + @Override + public void received(StartAnimationMessage msg) { + state.receivedStartAnimation(msg); + } + + /** + * @param msg + */ + @Override + public void received(SwitchToBattleState msg) { + state.receivedSwitchToBattleState(msg); + } + /** * Initializes the player's own map, opponent's map, and harbor based on the game details. * @@ -306,7 +324,7 @@ public void saveMap(File file) throws IOException { * * @param msg the message to be sent */ - void send(ClientMessage msg) { + public void send(ClientMessage msg) { if (clientSender == null) LOGGER.log(Level.ERROR, "trying to send {0} with sender==null", msg); //NON-NLS else diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientState.java index f6b73fcf..b145bdbb 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/ClientState.java @@ -9,7 +9,9 @@ import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.GameDetails; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.SwitchToBattleState; import pp.battleship.model.IntPoint; import java.io.File; @@ -165,6 +167,14 @@ void receivedEffect(EffectMessage msg) { ClientGameLogic.LOGGER.log(Level.ERROR, "receivedEffect not allowed in {0}", getName()); //NON-NLS } + void receivedSwitchToBattleState(SwitchToBattleState msg) { + ClientGameLogic.LOGGER.log(Level.ERROR, "receivedSwitchToBattleState not allowed in {0}", getName()); + } + + void receivedStartAnimation(StartAnimationMessage msg) { + ClientGameLogic.LOGGER.log(Level.ERROR, "receivedStartAnimation not allowed in {0}", getName()); + } + /** * Loads a map from the specified file. * diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java index d19d739c..c5d6db98 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerGameLogic.java @@ -9,12 +9,15 @@ import pp.battleship.BattleshipConfig; import pp.battleship.message.client.ClientInterpreter; +import pp.battleship.message.client.EndAnimationMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.GameDetails; import pp.battleship.message.server.ServerMessage; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.SwitchToBattleState; import pp.battleship.model.Battleship; import pp.battleship.model.IntPoint; @@ -39,6 +42,9 @@ public class ServerGameLogic implements ClientInterpreter { private Player activePlayer; private ServerState state = ServerState.WAIT; + private boolean p1AnimationFinished = false; + private boolean p2AnimationFinished = false; + /** * Constructs a ServerGameLogic with the specified sender and configuration. * @@ -142,17 +148,46 @@ public Player addPlayer(int id) { public void received(MapMessage msg, int from) { if (state != ServerState.SET_UP) LOGGER.log(Level.ERROR, "playerReady not allowed in {0}", state); //NON-NLS - else if(!checkMap(msg, from)) { + else if (!checkMap(msg, from)) { LOGGER.log(Level.ERROR, "The submitted map is not allowed"); send(players.get(from), new GameDetails(config)); } else playerReady(getPlayerById(from), msg.getShips()); } + + /** + * @param msg + */ + @Override + public void received(EndAnimationMessage msg, int from){ + if(state != ServerState.WAIT_ANIMATION) + LOGGER.log(Level.ERROR, "animation not allowed in {0}", state); + else + if(getPlayerById(from) == players.get(0)){ + LOGGER.log(Level.DEBUG, "{0} set to true", getPlayerById(from)); + p1AnimationFinished = true; + shoot(getPlayerById(from), msg.getPosition()); + } + else if (getPlayerById(from) == players.get(1)){ + LOGGER.log(Level.DEBUG, "{0} set to true {1}", getPlayerById(from), getPlayerById(from).toString()); + p2AnimationFinished = true; + shoot(getPlayerById(from), msg.getPosition()); + } + if(p1AnimationFinished && p2AnimationFinished) { + setState(ServerState.BATTLE); + for (Player player : players) + send(player, new SwitchToBattleState(player == activePlayer)); + p1AnimationFinished = false; + p2AnimationFinished = false; + } + } + + /** * Returns true if the map contains correct ship placement and is of the correct size * - * @param msg the received MapMessage of the player + * @param msg the received MapMessage of the player * @param from the ID of the Player * @return a boolean based on if the transmitted map ist correct */ @@ -165,7 +200,7 @@ private boolean checkMap(MapMessage msg, int from) { return false; // check if ship is out of bounds - for (Battleship ship : msg.getShips()){ + for (Battleship ship : msg.getShips()) { if (ship.getMaxX() >= mapWidth || ship.getMinX() < 0 || ship.getMaxY() >= mapHeight || ship.getMinY() < 0) { LOGGER.log(Level.ERROR, "Ship is out of bounds ({0})", ship.toString()); return false; @@ -174,10 +209,10 @@ private boolean checkMap(MapMessage msg, int from) { // check if ships overlap List ships = msg.getShips(); - for(Battleship ship:ships){ - for(Battleship compareShip:ships){ - if(!(ship==compareShip)){ - if(ship.collidesWith(compareShip)){ + for (Battleship ship : ships) { + for (Battleship compareShip : ships) { + if (!(ship == compareShip)) { + if (ship.collidesWith(compareShip)) { return false; } } @@ -197,10 +232,13 @@ public void received(ShootMessage msg, int from) { if (state != ServerState.BATTLE) LOGGER.log(Level.ERROR, "shoot not allowed in {0}", state); //NON-NLS else - shoot(getPlayerById(from), msg.getPosition()); + for (Player player : players) { + send(player, new StartAnimationMessage(msg.getPosition(), player == activePlayer)); + setState(ServerState.WAIT_ANIMATION); + } } - /** + /** * Marks the player as ready and sets their ships. * Transitions the state to PLAY if both players are ready. * @@ -220,41 +258,66 @@ void playerReady(Player player, List ships) { } } - /** - * Handles the shooting action by the player. - * - * @param p the player who shot - * @param pos the position of the shot - */ - void shoot(Player p, IntPoint pos) { - if (p != activePlayer) return; - final Player otherPlayer = getOpponent(activePlayer); - final Battleship selectedShip = otherPlayer.getMap().findShipAt(pos); + void shoot(Player player, IntPoint position) { + final Battleship selectedShip; + selectedShip = getSelectedShip(player, position); if (selectedShip == null) { - // shot missed - send(activePlayer, EffectMessage.miss(true, pos)); - send(otherPlayer, EffectMessage.miss(false, pos)); - activePlayer = otherPlayer; + shotMissed(player, position); } else { - // shot hit a ship - selectedShip.hit(pos); - if (otherPlayer.getMap().getRemainingShips().isEmpty()) { - // game is over - send(activePlayer, EffectMessage.won(pos, selectedShip)); - send(otherPlayer, EffectMessage.lost(pos, selectedShip, activePlayer.getMap().getRemainingShips())); + shotHit(player, position, selectedShip); + } + } + + Battleship getSelectedShip(Player player, IntPoint position) { + if (player != activePlayer) { + return player.getMap().findShipAt(position); + } + else { + return getOpponent(player).getMap().findShipAt(position); + } + } + + void shotMissed(Player player, IntPoint position) { + if (player != activePlayer) { + send(player, EffectMessage.miss(false, position)); + } + else + send(activePlayer, EffectMessage.miss(true, position)); + + if (p1AnimationFinished && p2AnimationFinished) + if (player == activePlayer) + activePlayer = getOpponent(player); + else + activePlayer = player; + } + + void shotHit(Player player, IntPoint position, Battleship ship) { + ship.hit(position); + if (getOpponent(activePlayer).getMap().getRemainingShips().isEmpty()) { + if (player != activePlayer) + send(player, EffectMessage.lost(position, ship, activePlayer.getMap().getRemainingShips())); + else + send(activePlayer, EffectMessage.won(position, ship)); + + if (p1AnimationFinished && p2AnimationFinished) { setState(ServerState.GAME_OVER); } - else if (selectedShip.isDestroyed()) { - // ship has been destroyed, but game is not yet over - send(activePlayer, EffectMessage.shipDestroyed(true, pos, selectedShip)); - send(otherPlayer, EffectMessage.shipDestroyed(false, pos, selectedShip)); + } + else if (ship.isDestroyed()) { + if (player != activePlayer) + send(player, EffectMessage.shipDestroyed(false, position, ship)); + else + send(activePlayer, EffectMessage.shipDestroyed(true, position, ship)); + } + else { + if (player != activePlayer) { + send(player, EffectMessage.hit(false, position)); } else { - // ship has been hit, but it hasn't been destroyed - send(activePlayer, EffectMessage.hit(true, pos)); - send(otherPlayer, EffectMessage.hit(false, pos)); + send(activePlayer, EffectMessage.hit(true, position)); } } } -} + +} \ No newline at end of file diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerState.java index 507aa7ac..074adb2e 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/server/ServerState.java @@ -26,6 +26,11 @@ enum ServerState { */ BATTLE, + /** + * Waits for the Animation to finish + */ + WAIT_ANIMATION, + /** * The game has ended because all the ships of one player have been destroyed. */ diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/Copycat.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/Copycat.java index f6e89bef..a80e8fc1 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/Copycat.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/Copycat.java @@ -9,6 +9,7 @@ import pp.battleship.message.client.ClientInterpreter; import pp.battleship.message.client.ClientMessage; +import pp.battleship.message.client.EndAnimationMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; import pp.battleship.model.Battleship; @@ -63,6 +64,15 @@ public void received(MapMessage msg, int from) { copiedMessage = new MapMessage(msg.getShips().stream().map(Copycat::copy).toList()); } + /** + * @param msg + * @param from + */ + @Override + public void received(EndAnimationMessage msg, int from) { + copiedMessage = new EndAnimationMessage(msg.getPosition()); + } + /** * Creates a copy of the provided {@link Battleship}. * diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/InterpreterProxy.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/InterpreterProxy.java index 51651383..365b5936 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/InterpreterProxy.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/InterpreterProxy.java @@ -9,11 +9,7 @@ import pp.battleship.game.client.BattleshipClient; import pp.battleship.game.client.ClientGameLogic; -import pp.battleship.message.server.EffectMessage; -import pp.battleship.message.server.GameDetails; -import pp.battleship.message.server.ServerInterpreter; -import pp.battleship.message.server.ServerMessage; -import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.*; import java.io.IOException; @@ -24,11 +20,13 @@ class InterpreterProxy implements ServerInterpreter { private final BattleshipClient playerClient; + static final System.Logger LOGGER = System.getLogger(InterpreterProxy.class.getName()); /** * Constructs an InterpreterProxy with the specified BattleshipClient. * * @param playerClient the client to which the server messages are forwarded */ + InterpreterProxy(BattleshipClient playerClient) { this.playerClient = playerClient; } @@ -82,6 +80,27 @@ public void received(EffectMessage msg) { forward(msg); } + /** + * Forwards the received AnimationStartMessage to the client's game logic. + * + * @param msg the AnimationStartMessage received from the server + */ + @Override + public void received(StartAnimationMessage msg) { + forward(msg); + } + + /** + * Forwards the received SwitchBattleState to the client's game logic. + * + * @param msg the SwitchBattleState received from the server + */ + @Override + public void received(SwitchToBattleState msg){ + LOGGER.log(System.Logger.Level.INFO, "Received SwitchBattleState"); + forward(msg); + } + /** * Forwards the specified ServerMessage to the client's game logic by enqueuing the message acceptance. * diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/RobotClient.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/RobotClient.java index d7831a71..729cf41d 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/RobotClient.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/singlemode/RobotClient.java @@ -1,12 +1,10 @@ package pp.battleship.game.singlemode; import pp.battleship.game.client.BattleshipClient; +import pp.battleship.message.client.EndAnimationMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; -import pp.battleship.message.server.EffectMessage; -import pp.battleship.message.server.GameDetails; -import pp.battleship.message.server.ServerInterpreter; -import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.*; import pp.battleship.model.IntPoint; import pp.battleship.model.dto.ShipMapDTO; import pp.util.RandomPositionIterator; @@ -113,15 +111,35 @@ public void received(StartBattleMessage msg) { } /** - * Receives an effect message, logs it, and updates the turn status. - * If it is RobotClient's turn to shoot, schedules a shot using shoot(); + * Receives an effect message, logs it. * * @param msg The effect message */ @Override public void received(EffectMessage msg) { LOGGER.log(Level.INFO, "Received EffectMessage: {0}", msg); //NON-NLS - if (msg.isMyTurn()) + } + + /** + * Receives an AnimationStartMessage, and responds instantly with an AnimationEndMessage + * + * @param msg the AnimationStartMessage received + */ + @Override + public void received(StartAnimationMessage msg) { + LOGGER.log(Level.INFO, "Received AnimationStartMessage: {0}", msg); + connection.sendRobotMessage(new EndAnimationMessage(msg.getPosition())); + } + + /** + * Receives a SwitchBattleState, and shots if it is the robots turn + * + * @param msg the SwitchBattleState received + */ + @Override + public void received(SwitchToBattleState msg){ + LOGGER.log(Level.INFO, "Received SwitchBattleStateMessage: {0}", msg); + if (msg.getTurn()) shoot(); } -} \ No newline at end of file +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/message/client/ClientInterpreter.java b/Projekte/battleship/model/src/main/java/pp/battleship/message/client/ClientInterpreter.java index 6a50c1da..5cfae5d8 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/message/client/ClientInterpreter.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/message/client/ClientInterpreter.java @@ -26,4 +26,6 @@ public interface ClientInterpreter { * @param from the connection ID from which the message was received */ void received(MapMessage msg, int from); + + void received(EndAnimationMessage msg, int from); } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/message/client/EndAnimationMessage.java b/Projekte/battleship/model/src/main/java/pp/battleship/message/client/EndAnimationMessage.java new file mode 100644 index 00000000..d156fb53 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/message/client/EndAnimationMessage.java @@ -0,0 +1,33 @@ +package pp.battleship.message.client; + +import com.jme3.network.serializing.Serializable; +import pp.battleship.model.IntPoint; + +@Serializable +public class EndAnimationMessage extends ClientMessage{ + + private IntPoint position; + + private EndAnimationMessage(){/*do nothing */} + + public EndAnimationMessage(final IntPoint position){ + this.position = position; + } + + /** + * Accepts a visitor for processing this message. + * + * @param interpreter the visitor to be used for processing + * @param from the connection ID of the sender + */ + @Override + public void accept(ClientInterpreter interpreter, int from) { + interpreter.received(this, from); + } + + public IntPoint getPosition() { + return position; + } + + +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/message/server/ServerInterpreter.java b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/ServerInterpreter.java index aa512269..ad66000e 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/message/server/ServerInterpreter.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/ServerInterpreter.java @@ -7,6 +7,8 @@ package pp.battleship.message.server; +import pp.battleship.message.client.EndAnimationMessage; + /** * An interface for processing server messages. * Implementations of this interface can be used to handle different types of server messages. @@ -33,4 +35,8 @@ public interface ServerInterpreter { * @param msg the EffectMessage received */ void received(EffectMessage msg); + + void received(StartAnimationMessage msg); + + void received(SwitchToBattleState msg); } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/message/server/StartAnimationMessage.java b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/StartAnimationMessage.java new file mode 100644 index 00000000..1a91f6e2 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/StartAnimationMessage.java @@ -0,0 +1,45 @@ +package pp.battleship.message.server; + +import com.jme3.network.serializing.Serializable; +import pp.battleship.model.IntPoint; + +@Serializable +public class StartAnimationMessage extends ServerMessage { + + private IntPoint position; + private boolean myTurn; + + private StartAnimationMessage(){/*do nothing */} + + public StartAnimationMessage(IntPoint position, boolean myTurn) { + this.position = position; + this.myTurn = myTurn; + } + + /** + * Accepts a visitor for processing this message. + * + * @param interpreter the visitor to be used for processing + */ + @Override + public void accept(ServerInterpreter interpreter) { + interpreter.received(this); + } + + /** + * Gets the bundle key of the informational text to be shown at the client. + * This key is used to retrieve the appropriate localized text for display. + * + * @return the bundle key of the informational text + */ + @Override + public String getInfoTextKey() { + return "started animation at " + position; + } + + public IntPoint getPosition() {return position;} + + public boolean isMyTurn() {return myTurn;} + + +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/message/server/SwitchToBattleState.java b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/SwitchToBattleState.java new file mode 100644 index 00000000..2de7deca --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/message/server/SwitchToBattleState.java @@ -0,0 +1,40 @@ +package pp.battleship.message.server; + +import com.jme3.network.serializing.Serializable; + +@Serializable +public class SwitchToBattleState extends ServerMessage{ + + private boolean myTurn; + + private SwitchToBattleState(){/*do nothing */} + + public SwitchToBattleState(boolean turn){ + myTurn = turn; + } + + /** + * Accepts a visitor for processing this message. + * + * @param interpreter the visitor to be used for processing + */ + @Override + public void accept(ServerInterpreter interpreter) { + interpreter.received(this); + } + + /** + * Gets the bundle key of the informational text to be shown at the client. + * This key is used to retrieve the appropriate localized text for display. + * + * @return the bundle key of the informational text + */ + @Override + public String getInfoTextKey() { + return "switched to battle state"; + } + + public boolean getTurn(){return myTurn;} + + +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/model/Shell.java b/Projekte/battleship/model/src/main/java/pp/battleship/model/Shell.java new file mode 100644 index 00000000..f4b8c700 --- /dev/null +++ b/Projekte/battleship/model/src/main/java/pp/battleship/model/Shell.java @@ -0,0 +1,77 @@ +package pp.battleship.model; + +/** + * This class represents a shell + */ +public class Shell implements Item { + private int x; + private int y; + + /** + * constructs a new shell object + * + * @param position the end position of the shell + */ + public Shell(IntPoint position) { + x = position.getX(); + y = position.getY(); + } + + /** + * getter for the x coordinate + * + * @return int x coordinate + */ + public int getX() { + return x; + } + + /** + * getter for the y coordinate + * + * @return int y coordinate + */ + public int getY() { + return y; + } + + /** + * setter for x coordinate + * + * @param x the new value of x coordinate + */ + public void setX(int x) { + this.x = x; + } + + /** + * setter for y coordinate + * + * @param y the new value of y coordinate + */ + public void setY(int y) { + this.y = y; + } + + /** + * Accepts a visitor with a return value. + * + * @param visitor the visitor to accept + * @param the type of the return value + * @return the result of the visitor's visit method + */ + @Override + public T accept(Visitor visitor) { + return visitor.visit(this); + } + + /** + * Accepts a visitor without a return value. + * + * @param visitor the visitor to accept + */ + @Override + public void accept(VoidVisitor visitor) { + visitor.visit(this); + } +} diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/model/ShipMap.java b/Projekte/battleship/model/src/main/java/pp/battleship/model/ShipMap.java index 5a162785..79087f78 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/model/ShipMap.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/model/ShipMap.java @@ -91,6 +91,14 @@ public void add(Shot shot) { addItem(shot); } + /** + * Registers a shell on the map + * @param shell the shell to be registered + */ + public void add(Shell shell) { + addItem(shell); + } + /** * Removes an item from the map and triggers an item removal event. * diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/model/Visitor.java b/Projekte/battleship/model/src/main/java/pp/battleship/model/Visitor.java index f490451d..1046142b 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/model/Visitor.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/model/Visitor.java @@ -28,4 +28,6 @@ public interface Visitor { * @return the result of visiting the Battleship element */ T visit(Battleship ship); + + T visit(Shell shell); } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/model/VoidVisitor.java b/Projekte/battleship/model/src/main/java/pp/battleship/model/VoidVisitor.java index 871c0635..3bde11a1 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/model/VoidVisitor.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/model/VoidVisitor.java @@ -25,4 +25,6 @@ public interface VoidVisitor { * @param ship the Battleship element to visit */ void visit(Battleship ship); + + void visit(Shell shell); } diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/notification/Sound.java b/Projekte/battleship/model/src/main/java/pp/battleship/notification/Sound.java index d82ab698..b3acb2c8 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/notification/Sound.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/notification/Sound.java @@ -22,5 +22,9 @@ public enum Sound { /** * Sound of a ship being destroyed. */ - DESTROYED_SHIP + DESTROYED_SHIP, + /** + * Sound of a missile being fired + */ + MISSILE_LAUNCH } diff --git a/Projekte/battleship/server/src/main/java/pp/battleship/server/BattleshipServer.java b/Projekte/battleship/server/src/main/java/pp/battleship/server/BattleshipServer.java index 1ad0a2e0..b4b276bc 100644 --- a/Projekte/battleship/server/src/main/java/pp/battleship/server/BattleshipServer.java +++ b/Projekte/battleship/server/src/main/java/pp/battleship/server/BattleshipServer.java @@ -19,12 +19,15 @@ import pp.battleship.game.server.ServerGameLogic; import pp.battleship.game.server.ServerSender; import pp.battleship.message.client.ClientMessage; +import pp.battleship.message.client.EndAnimationMessage; import pp.battleship.message.client.MapMessage; import pp.battleship.message.client.ShootMessage; import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.GameDetails; import pp.battleship.message.server.ServerMessage; +import pp.battleship.message.server.StartAnimationMessage; import pp.battleship.message.server.StartBattleMessage; +import pp.battleship.message.server.SwitchToBattleState; import pp.battleship.model.Battleship; import pp.battleship.model.IntPoint; import pp.battleship.model.Shot; @@ -118,11 +121,15 @@ private void initializeSerializables() { Serializer.registerClass(Battleship.class); Serializer.registerClass(IntPoint.class); Serializer.registerClass(Shot.class); + Serializer.registerClass(StartAnimationMessage.class); + Serializer.registerClass(EndAnimationMessage.class); + Serializer.registerClass(SwitchToBattleState.class); } private void registerListeners() { myServer.addMessageListener(this, MapMessage.class); myServer.addMessageListener(this, ShootMessage.class); + myServer.addMessageListener(this, EndAnimationMessage.class); myServer.addConnectionListener(this); }