17 Commits

Author SHA1 Message Date
Lukas Bauer
66798eb3e4 Improved code documentation 2024-10-11 15:22:20 +02:00
Lukas Bauer
edff9e1ad9 Improved code documentation and clarify comments for better readability and understanding 2024-10-11 15:06:09 +02:00
Lukas Bauer
bf16a18b71 Aufgabe 13
edited class BattleState in order to implement the 2D map feature
edited class GameSound to add the Missile launch sound
edited class MapViewSynchronizer in order to implement the 2D map feature
edited class ImpactEffectManager removed unused import
edited class SeaSynchronizer removed unused code
edited class Shell in order to implement the 2D map feature
edited class ShellControl in order to implement the 2D map feature
edited Sound added Missile launch enum
edited FloatMath to improve the animation for the 2D projectile
added missileLaunch.wav
2024-10-11 14:23:49 +02:00
Lukas Bauer
6100e95e76 Aufgabe 13
added class Shell for the feature Airstrike
added class ShellControl for the feature Airstrike
added new Model Bomb to implement the feature Airstrike
added README´S to the Models to show the free to use license
edited class ShipMap for the feature Airstrike
edited class ImpactEffectManager to improve the Fire and Water Particles
edited class MapViewSynchronizer for the feature Airstrike
edited class BattleState for the feature Airstrike
edited class BattleshipApp for the feature Airstrike
2024-10-09 21:10:31 +02:00
Lukas Bauer
1b7b842ca7 JavaDoc adjustments 2024-10-08 19:46:23 +02:00
Lukas Bauer
865b0fc33c Aufgabe 12
added class ImpactEffectManager to implement the funktionality with hit or miss particles
added map4 for particle testing purposes
edited class SeaSynchronizer in order to implement the particle feature
edited class ShipControl in order to implement the particle feature
edited settings.gradle in order to implement the particle feature
2024-10-08 19:43:07 +02:00
Lukas Bauer
5a9b0b1de0 fix Aufgabe 11
edited class NetworkDialog
to change the logic that the checkbox works now as intended
moved BattleshipServer and ReceivedMessage into own folders to separate server from client
2024-10-07 20:11:15 +02:00
Lukas Bauer
8650fa5b58 fix edited class EditorState
fix edited battleship.properties with the right Key to fix an exception
fix edited battleship_de.properties with the right Key to fix an exception
2024-10-05 13:09:05 +02:00
Lukas Bauer
113da79df6 fix edited class NetworkDialog changed Button to Checklist 2024-10-04 18:42:47 +02:00
Lukas Bauer
e41d21584a Aufgabe 11.
added class BattleshipServer, ReceivedMessage
to implement the feature that a client is able to start an server
edited NetworkDialog to implement the logic to start an server and overhauled the GUI to be appropriate for the new features
2024-10-04 18:33:13 +02:00
Lukas Bauer
5e773ca1ba Aufgabe 10.
added class BackgroundMusic
edited BattleshipApp, GameSound, Menu
implemented a Slider for the Gui in order to change the Volume
Quality of Life
implemented feature to Safe the Sound settings to keep them even after shutting down the game
implemented feature to mute Sounds/effects
implemented feature to mute Music
2024-10-03 19:11:53 +02:00
Lukas Bauer
b2b3bc23bf Aufgabe 10.
added class BackgroundMusic
edited BattleshipApp, GameSound, Menu
implemented a Slider for the Gui in order to change the Volume
Quality of Life
implemented feature to Safe the Sound settings to keep them even after shutting down the game
implemented feature to mute Sounds/effects
implemented feature to mute Music
2024-10-03 19:10:36 +02:00
Lukas Bauer
ce490fb877 Aufgabe 10.
added class BackgroundMusic
edited BattleshipApp, GameSound, Menu
implemented a Slider for the Gui in order to change the Volume
Quality of Life
implemented feature to Safe the Sound settings to keep them even after shutting down the game
implemented feature to mute Sounds/effects
implemented feature to mute Music
2024-10-03 19:07:27 +02:00
Lukas Bauer
ce5e908349 edited SeaSynchronizer , EditorState, ServerGameLogic
added JavaDocs for the new and adapted functions
added a new invalid map for testing purposes
fixed implemented the logic to check for invalid maps in the method received in ServerGameLogic
2024-10-03 13:28:41 +02:00
Lukas Bauer
07e922d01e Aufgabe 9.
edited SeaSynchronizer
added 3 Ship Models Small Ship, Medium Ship and Big Ship and tweaked the scaling of all Models
2024-10-02 20:23:05 +02:00
Lukas Bauer
42b442e937 Aufgabe 8.
edited class EditorState and ServerGameLogic
 to check for invalid maps in which ships overlap or are out of the map boundries for clientside and serverside
2024-10-02 18:24:27 +02:00
Lukas Bauer
93ade34282 Aufgabe 7.
fix: in class ShipMap
function remove
hierbei wurde nach dem entfernen eines Items dass Event ItemAddedEvent ausgelöst hierbei sollte aber logischerweiße dass Event ItemRemovedEvent ausgelöst werden.

fix: in class BattleState
function receivedEffect
hierbei wurde die eigene map für die Bedingung isGameOver verglichen wobei man für isGameOver die OpponentMap auf remainingShips untersuchen muss.
2024-10-02 00:31:40 +02:00
115 changed files with 711897 additions and 639584 deletions

View File

@@ -1,528 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="2409" dy="1838" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="LkLulIeU9eejG4ewMiHC-0" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Config&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="205" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-1" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Abstract Message&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="60" y="200" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-2" value="«interface»&lt;br&gt;&lt;b&gt;ServerSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="630" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-3" value="«interface»&lt;br&gt;&lt;b&gt;ClientInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-4" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="370" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-8" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="410" y="585" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-9" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-4" target="LkLulIeU9eejG4ewMiHC-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="660" y="535" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-10" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="130" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="480" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-11" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;MapMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-430" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-13" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShootMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-14" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationEndMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-90" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-16" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-13" target="LkLulIeU9eejG4ewMiHC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="195" y="390" as="sourcePoint" />
<mxPoint y="230" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-17" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="205" y="400" as="sourcePoint" />
<mxPoint x="10" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-18" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="785" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-20" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-3">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="480" y="310" as="sourcePoint" />
<mxPoint x="640" y="310" as="targetPoint" />
<Array as="points">
<mxPoint x="855" y="220" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-21" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.445;entryY=1.008;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-2">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="720" y="320" as="sourcePoint" />
<mxPoint x="880" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="680" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-22" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-23">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1226" y="340" as="sourcePoint" />
<mxPoint x="1070" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-23" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-24" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-23" target="LkLulIeU9eejG4ewMiHC-0">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1009" y="355" as="sourcePoint" />
<mxPoint x="1009" y="200" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-25" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipClientConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="400" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-26" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-25" target="LkLulIeU9eejG4ewMiHC-23">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="904" y="520" as="sourcePoint" />
<mxPoint x="709" y="360" as="targetPoint" />
<Array as="points">
<mxPoint x="1030" y="370" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-27" value="«enum»&lt;br&gt;&lt;b&gt;ServerState&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="660" y="450" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-28" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-27">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="746" y="370" as="sourcePoint" />
<mxPoint x="560" y="200" as="targetPoint" />
<Array as="points">
<mxPoint x="820" y="390" />
<mxPoint x="743" y="390" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-29" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Player&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="810" y="465" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-31" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-29">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="330" as="sourcePoint" />
<mxPoint x="870" y="460" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-32" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMap&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="810" y="550" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-33" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-29" target="LkLulIeU9eejG4ewMiHC-32">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="280" as="sourcePoint" />
<mxPoint x="865" y="425" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-34" value="«interface»&lt;br&gt;&lt;b&gt;GameEventBroker&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="535" width="120" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-35" value="«interface»&lt;br&gt;&lt;b&gt;ServerInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1110" y="535" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-36" value="«interface»&lt;br&gt;&lt;b&gt;ClientSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1112" y="735" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-37" value="«interface»&lt;br&gt;&lt;b&gt;gameEventListener&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1112" y="805" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-38" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="750" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-39" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-44">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="445" as="sourcePoint" />
<mxPoint x="865" y="560" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-40" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-36">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="867" y="755" as="sourcePoint" />
<mxPoint x="867" y="625" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-41" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-37">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="765" as="sourcePoint" />
<mxPoint x="877" y="635" as="targetPoint" />
<Array as="points">
<mxPoint x="883" y="830" />
<mxPoint x="1062" y="830" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-42" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-34">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1015" y="550" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="660" />
<mxPoint x="1020" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-43" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-35">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1190" y="640" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="660" />
<mxPoint x="1020" y="660" />
<mxPoint x="1176" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-44" value="3" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="840" y="570" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-45" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="827" y="435" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-47" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="848" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-48" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="790" as="sourcePoint" />
<mxPoint x="830" y="820" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-49" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-47" target="LkLulIeU9eejG4ewMiHC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="892" y="865" as="sourcePoint" />
<mxPoint x="852" y="815" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-50" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameDetails&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="580" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-51" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-50">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="740" y="835" as="sourcePoint" />
<mxPoint x="740" y="715" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-52" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;StartBattleMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="420" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-54" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationStartMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="250" y="750" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-55" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BackToBattleStateMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="45" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-56" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-52" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="827" y="470" as="sourcePoint" />
<mxPoint x="477" y="310" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-57" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-54" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="510" y="710" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="320" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-58" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-55" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="360" y="710" as="sourcePoint" />
<mxPoint x="490" y="280" as="targetPoint" />
<Array as="points">
<mxPoint x="130" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-59" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-50" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="510" y="710" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="640" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-60" value="«interface»&lt;br&gt;&lt;b&gt;Item&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-220" y="535" width="140" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-61" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EffectMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-140" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-62" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="30" y="680" as="sourcePoint" />
<mxPoint x="384" y="250" as="targetPoint" />
<Array as="points">
<mxPoint x="-55" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-63" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shot&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-170" y="650" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-64" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShip&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="650" width="113" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-65" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shell&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="650" width="70" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-66" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-32" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="270" y="485" as="sourcePoint" />
<mxPoint x="270" y="365" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-67" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-85" y="528" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-68" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-20" y="470" as="sourcePoint" />
<mxPoint x="-190" y="390" as="targetPoint" />
<Array as="points">
<mxPoint x="-20" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-69" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-63" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-70.42000000000007" y="750" as="sourcePoint" />
<mxPoint x="-70.42000000000007" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-125" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-70" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="660" as="sourcePoint" />
<mxPoint x="-150" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-333" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-71" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-65" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-233" y="660" as="sourcePoint" />
<mxPoint x="-175" y="595" as="targetPoint" />
<Array as="points">
<mxPoint x="-225" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-72" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.088;exitY=0.02;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-63">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="370" y="690" as="sourcePoint" />
<mxPoint x="-70" y="570" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-73" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="760" as="sourcePoint" />
<mxPoint x="-115" y="680" as="targetPoint" />
<Array as="points">
<mxPoint x="-305" y="760" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-74" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-335" y="668" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-75" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-393.5" y="535" as="sourcePoint" />
<mxPoint x="-586.5" y="445" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="560" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-76" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="620" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-79" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;WaitState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="930" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-80" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="660" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-81" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;InitialState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="795" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-82" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="930" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-83" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameOverState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1060" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-84" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EditorState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="400" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-85" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-81" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="820" y="1020" as="sourcePoint" />
<mxPoint x="940" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-86" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-80" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="860" y="940" as="sourcePoint" />
<mxPoint x="940" y="860" as="targetPoint" />
<Array as="points">
<mxPoint x="715" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-87" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-79" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="628" y="925" as="sourcePoint" />
<mxPoint x="890" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="590" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-89" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-82" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="950" as="sourcePoint" />
<mxPoint x="920" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="985" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-90" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-83" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1120" y="920" as="sourcePoint" />
<mxPoint x="840" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="1120" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-91" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="503" y="910" as="sourcePoint" />
<mxPoint x="800" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="460" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-92" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="380" y="830" as="sourcePoint" />
<mxPoint x="40" y="870" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="940" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-93" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="680" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-94" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1085" y="838" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-95" value="«enum»&lt;br&gt;&lt;b&gt;Rotation&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="635" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-96" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShipDTO&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="735" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-97" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMaoDTO&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="800" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-98" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-96" target="LkLulIeU9eejG4ewMiHC-95">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-420.8" y="778" as="sourcePoint" />
<mxPoint x="-420.8" y="698" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-99" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-97" target="LkLulIeU9eejG4ewMiHC-96">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-100" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-495" y="760" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-101" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-95">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,527 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1192" dy="424" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="LkLulIeU9eejG4ewMiHC-0" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Config&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="205" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-1" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Abstract Message&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="60" y="200" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-2" value="«interface»&lt;br&gt;&lt;b&gt;ServerSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="630" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-3" value="«interface»&lt;br&gt;&lt;b&gt;ClientInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-4" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="370" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-8" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="410" y="585" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-9" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-4" target="LkLulIeU9eejG4ewMiHC-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="660" y="535" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-10" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="130" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="480" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-11" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;MapMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-430" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-13" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShootMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-14" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationEndMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-90" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-16" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-13" target="LkLulIeU9eejG4ewMiHC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="195" y="390" as="sourcePoint" />
<mxPoint y="230" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-17" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="205" y="400" as="sourcePoint" />
<mxPoint x="10" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-18" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="785" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-20" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-3">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="480" y="310" as="sourcePoint" />
<mxPoint x="640" y="310" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-21" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.445;entryY=1.008;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-2">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="720" y="320" as="sourcePoint" />
<mxPoint x="880" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="680" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-22" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-23">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1226" y="340" as="sourcePoint" />
<mxPoint x="1070" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-23" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-24" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-23" target="LkLulIeU9eejG4ewMiHC-0">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1009" y="355" as="sourcePoint" />
<mxPoint x="1009" y="200" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-25" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipClientConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="400" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-26" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-25" target="LkLulIeU9eejG4ewMiHC-23">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="904" y="520" as="sourcePoint" />
<mxPoint x="709" y="360" as="targetPoint" />
<Array as="points">
<mxPoint x="1030" y="370" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-27" value="«enum»&lt;br&gt;&lt;b&gt;ServerState&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="660" y="450" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-28" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-27">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="746" y="370" as="sourcePoint" />
<mxPoint x="560" y="200" as="targetPoint" />
<Array as="points">
<mxPoint x="820" y="390" />
<mxPoint x="743" y="390" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-29" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Player&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="810" y="465" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-31" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-29">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="330" as="sourcePoint" />
<mxPoint x="870" y="460" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-32" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMap&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="810" y="550" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-33" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-29" target="LkLulIeU9eejG4ewMiHC-32">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="280" as="sourcePoint" />
<mxPoint x="865" y="425" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-34" value="«interface»&lt;br&gt;&lt;b&gt;GameEventBroker&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="960" y="535" width="120" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-35" value="«interface»&lt;br&gt;&lt;b&gt;ServerInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1110" y="535" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-36" value="«interface»&lt;br&gt;&lt;b&gt;ClientSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1112" y="735" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-37" value="«interface»&lt;br&gt;&lt;b&gt;gameEventListener&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1112" y="805" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-38" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="750" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-39" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-44">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="445" as="sourcePoint" />
<mxPoint x="865" y="560" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-40" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-36">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="867" y="755" as="sourcePoint" />
<mxPoint x="867" y="625" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-41" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-37">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="765" as="sourcePoint" />
<mxPoint x="877" y="635" as="targetPoint" />
<Array as="points">
<mxPoint x="883" y="830" />
<mxPoint x="1062" y="830" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-42" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-34">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1015" y="550" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="660" />
<mxPoint x="1020" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-43" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-35">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1190" y="640" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="660" />
<mxPoint x="1020" y="660" />
<mxPoint x="1176" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-44" value="3" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="840" y="570" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-45" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="827" y="435" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-47" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="800" y="848" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-48" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="790" as="sourcePoint" />
<mxPoint x="830" y="820" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-49" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-47" target="LkLulIeU9eejG4ewMiHC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="892" y="865" as="sourcePoint" />
<mxPoint x="852" y="815" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-50" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameDetails&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="580" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-51" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-50">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="740" y="835" as="sourcePoint" />
<mxPoint x="740" y="715" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-52" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;StartBattleMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="420" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-54" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationStartMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="250" y="750" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-55" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BackToBattleStateMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="45" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-56" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-52" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="827" y="470" as="sourcePoint" />
<mxPoint x="477" y="310" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-57" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#FF0000;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-54" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="280" y="700" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="320" y="690" />
<mxPoint x="320" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-58" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-55" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="360" y="710" as="sourcePoint" />
<mxPoint x="490" y="280" as="targetPoint" />
<Array as="points">
<mxPoint x="130" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-59" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-50" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="510" y="710" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="640" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-60" value="«interface»&lt;br&gt;&lt;b&gt;Item&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-220" y="535" width="140" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-61" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EffectMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-140" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-62" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="30" y="680" as="sourcePoint" />
<mxPoint x="384" y="250" as="targetPoint" />
<Array as="points">
<mxPoint x="-55" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-63" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shot&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-170" y="650" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-64" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShip&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="650" width="113" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-65" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shell&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-260" y="650" width="70" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-66" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-32" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="270" y="485" as="sourcePoint" />
<mxPoint x="270" y="365" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-67" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-85" y="528" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-68" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-20" y="470" as="sourcePoint" />
<mxPoint x="-190" y="390" as="targetPoint" />
<Array as="points">
<mxPoint x="-20" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-69" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-63" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-70.42000000000007" y="750" as="sourcePoint" />
<mxPoint x="-70.42000000000007" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-125" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-70" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="660" as="sourcePoint" />
<mxPoint x="-150" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-333" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-71" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-65" target="LkLulIeU9eejG4ewMiHC-60">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-233" y="660" as="sourcePoint" />
<mxPoint x="-175" y="595" as="targetPoint" />
<Array as="points">
<mxPoint x="-225" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-72" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.088;exitY=0.02;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-63">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="370" y="690" as="sourcePoint" />
<mxPoint x="-70" y="570" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-73" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="760" as="sourcePoint" />
<mxPoint x="-115" y="680" as="targetPoint" />
<Array as="points">
<mxPoint x="-305" y="760" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-74" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-335" y="668" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-75" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-393.5" y="535" as="sourcePoint" />
<mxPoint x="-586.5" y="445" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="560" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-76" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="620" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-79" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;WaitState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="930" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-80" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="660" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-81" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;InitialState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="795" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-82" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="930" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-83" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameOverState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1060" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-84" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EditorState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="400" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-85" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-81" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="820" y="1020" as="sourcePoint" />
<mxPoint x="940" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-86" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-80" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="860" y="940" as="sourcePoint" />
<mxPoint x="940" y="860" as="targetPoint" />
<Array as="points">
<mxPoint x="715" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-87" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-79" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="628" y="925" as="sourcePoint" />
<mxPoint x="890" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="590" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-89" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#FF0000;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-82" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="950" as="sourcePoint" />
<mxPoint x="920" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="985" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-90" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-83" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1120" y="920" as="sourcePoint" />
<mxPoint x="840" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="1120" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-91" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-47">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="503" y="910" as="sourcePoint" />
<mxPoint x="800" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="460" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-92" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-64">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="380" y="830" as="sourcePoint" />
<mxPoint x="40" y="870" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="940" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-93" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-390" y="680" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-94" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1085" y="838" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-95" value="«enum»&lt;br&gt;&lt;b&gt;Rotation&lt;/b&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="635" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-96" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShipDTO&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="735" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-97" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMaoDTO&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-550" y="800" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-98" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-96" target="LkLulIeU9eejG4ewMiHC-95">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-420.8" y="778" as="sourcePoint" />
<mxPoint x="-420.8" y="698" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-99" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-97" target="LkLulIeU9eejG4ewMiHC-96">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-100" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="-495" y="760" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-101" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-95">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,174 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram name="Seite-1" id="CSCMTvoyx8GfkIWIgrj5">
<mxGraphModel dx="2171" dy="1811" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="8jlTEtXbO0kP9G_WUDS2-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-2" target="8jlTEtXbO0kP9G_WUDS2-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-2" target="8jlTEtXbO0kP9G_WUDS2-12">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-2" value="" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="70" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-6" value="addPlayer(id)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="130" y="290" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-7" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="-10" y="358" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-8" target="8jlTEtXbO0kP9G_WUDS2-16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-8" target="8jlTEtXbO0kP9G_WUDS2-16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-8" value="Set up" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="72.5" y="450" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-11" value="[players.size()=2]/send GameDetail messages" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="125" y="360" width="270" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-12" target="8jlTEtXbO0kP9G_WUDS2-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-12" value="" style="ellipse;fillColor=strokeColor;html=1;" vertex="1" parent="1">
<mxGeometry x="15" y="260" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-16" target="8jlTEtXbO0kP9G_WUDS2-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-16" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="170" y="520" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-19" value="received MapMessage&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="220" y="470" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-20" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="50" y="588" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-21" target="8jlTEtXbO0kP9G_WUDS2-24">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-21" value="Battle" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="172.5" y="640" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-23" value="[readyPlayers.size() = 2]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="220" y="585" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-24">
<mxGeometry relative="1" as="geometry">
<mxPoint x="342.3548387096773" y="830" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-24" value="Animation wait" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="285" y="680" width="115" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-29" target="8jlTEtXbO0kP9G_WUDS2-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-29" target="8jlTEtXbO0kP9G_WUDS2-31">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-29" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="302.5" y="830" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-31" value="Game over" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="285" y="960" width="115" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-33" value="[game over]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="345" y="888" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-34" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="205" y="860" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-35" target="8jlTEtXbO0kP9G_WUDS2-38">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-35" value="" style="ellipse;fillColor=strokeColor;html=1;" vertex="1" parent="1">
<mxGeometry x="550" y="260" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-41" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-38" target="8jlTEtXbO0kP9G_WUDS2-40">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-38" value="Initial State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="265" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-44" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-40" target="8jlTEtXbO0kP9G_WUDS2-43">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-40" value="Editor State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="670" y="358" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-42" value="receivedGameDetails(details)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="720" y="298" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-45" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-43" target="8jlTEtXbO0kP9G_WUDS2-40">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-43" target="8jlTEtXbO0kP9G_WUDS2-50">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-43" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="780" y="470" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-46" value="mapFinished" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="815" y="368" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-47" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="680" y="498" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-50" target="8jlTEtXbO0kP9G_WUDS2-52">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-50" value="Wait Stata" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="782.5" y="575" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-54" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-52" target="8jlTEtXbO0kP9G_WUDS2-53">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-52" value="Battle State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="782.5" y="690" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-57" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-53" target="8jlTEtXbO0kP9G_WUDS2-56">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-53" value="Animation State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="940" y="760" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-55" value="receivedAnimationMessage(msg)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="900" y="660" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-59" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-56" target="8jlTEtXbO0kP9G_WUDS2-52">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="8jlTEtXbO0kP9G_WUDS2-56" target="8jlTEtXbO0kP9G_WUDS2-61">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-56" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="955" y="878" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-60" value="receivedBackToBattleStateMessage(msg)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1030" y="810" width="250" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-61" value="game over" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="940" y="970" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-63" value="[game over]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1005" y="930" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-64" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="832" y="918" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-66" value="[horbor&amp;nbsp; empty] / send MapMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="832" y="525" width="220" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-67" value="receivedStartBattle(msg)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="827" y="610" width="160" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,654 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram name="Page-1" id="2a216829-ef6e-dabb-86c1-c78162f3ba2b">
<mxGraphModel dx="2009" dy="2329" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Sf4z-aHPgcdhoojVuiNO-13" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="300" y="280" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="7a84cebc1def654-34" value="" style="shape=message;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="310" y="295" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-1" target="Sf4z-aHPgcdhoojVuiNO-27">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-1" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="100" y="180" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-2" value="start client 1" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="110" y="260" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-3" target="Sf4z-aHPgcdhoojVuiNO-10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-3" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="100" y="340" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-4" value="start server" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="110" y="420" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-5" target="Sf4z-aHPgcdhoojVuiNO-23">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-5" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="100" y="500" width="80" height="80" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-8" value="start cleint 2" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="110" y="580" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-10" target="Sf4z-aHPgcdhoojVuiNO-14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-10" target="Sf4z-aHPgcdhoojVuiNO-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-10" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="240" y="355" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-13" target="Sf4z-aHPgcdhoojVuiNO-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-14" target="Sf4z-aHPgcdhoojVuiNO-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-14" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="300" y="420" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-17" target="Sf4z-aHPgcdhoojVuiNO-31">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-17" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="390" y="355" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-22" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="310" y="435" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-23" target="Sf4z-aHPgcdhoojVuiNO-42">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-23" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="300" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-24" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="310" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-27" target="Sf4z-aHPgcdhoojVuiNO-44">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-27" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="300" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-28" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="310" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-31" target="Sf4z-aHPgcdhoojVuiNO-33">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-31" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="470" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-32" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="480" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-33" target="Sf4z-aHPgcdhoojVuiNO-35">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-33" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="600" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-34" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="610" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-55" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-35" target="Sf4z-aHPgcdhoojVuiNO-52">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-57" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-35" target="Sf4z-aHPgcdhoojVuiNO-50">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-35" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="730" y="355" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-40" target="Sf4z-aHPgcdhoojVuiNO-60">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-40" value="edit ship map" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="600" y="190" width="90" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-41" target="Sf4z-aHPgcdhoojVuiNO-58">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-41" value="edit ship map" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="730" y="510" width="90" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-49" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-42" target="Sf4z-aHPgcdhoojVuiNO-41">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-42" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="600" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-43" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="610" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-47" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-44" target="Sf4z-aHPgcdhoojVuiNO-40">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-44" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="470" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-45" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="480" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-67" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-50" target="Sf4z-aHPgcdhoojVuiNO-64">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-50" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="865" y="280" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-51" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="875" y="295" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-52" target="Sf4z-aHPgcdhoojVuiNO-65">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-52" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="865" y="420" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-53" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="875" y="435" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-89" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-58" target="Sf4z-aHPgcdhoojVuiNO-87">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-58" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="865" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-59" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="875" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-60" target="Sf4z-aHPgcdhoojVuiNO-85">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-60" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="865" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-61" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="875" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-64" target="Sf4z-aHPgcdhoojVuiNO-68">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-64" value="save player 1 map" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="980" y="280" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-70" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-65" target="Sf4z-aHPgcdhoojVuiNO-68">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-65" value="save player 2 map" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="980" y="420" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-68" target="Sf4z-aHPgcdhoojVuiNO-77">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-68" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="1160" y="355" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-76" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-77" target="Sf4z-aHPgcdhoojVuiNO-79">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-77" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1260" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-78" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1270" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-108" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-79" target="Sf4z-aHPgcdhoojVuiNO-103">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-79" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1390" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-80" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1400" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-107" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-85" target="Sf4z-aHPgcdhoojVuiNO-105">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-85" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1260" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-86" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1270" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-156" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-87" target="Sf4z-aHPgcdhoojVuiNO-147">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-87" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1390" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-88" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1400" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-145" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-91" target="Sf4z-aHPgcdhoojVuiNO-141">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-91" value="process shot" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1650" y="350" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-92" value="connect" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="300" y="570" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-93" value="connect" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="300" y="160" width="70" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-94" value="send GameDetails" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="440" y="410" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-95" value="send GameDetails" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="570" y="320" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-96" value="send MapMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="835" y="570" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-97" value="send MapMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="835" y="160" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-100" value="send StartBattleMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1210" y="410" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-101" value="send StartBattleMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1340" y="320" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-103" target="Sf4z-aHPgcdhoojVuiNO-91">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-103" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1520" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-104" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1530" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-155" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-105" target="Sf4z-aHPgcdhoojVuiNO-149">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-105" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1520" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-106" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1530" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-110" value="send ShotMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1485" y="160" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-112" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="325" y="500" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-116" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-112" target="Sf4z-aHPgcdhoojVuiNO-14">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="350" y="490" as="sourcePoint" />
<mxPoint x="510" y="490" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-119" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="495" y="340" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-120" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-119">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="520" y="330" as="sourcePoint" />
<mxPoint x="500" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-121" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="890" y="500" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-122" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-121">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="915" y="490" as="sourcePoint" />
<mxPoint x="895" y="480" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-127" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="625" y="410" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-129" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-127" target="Sf4z-aHPgcdhoojVuiNO-42">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="410" y="400" as="sourcePoint" />
<mxPoint x="570" y="400" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-131" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="325" y="250" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-132" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-131">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="110" y="240" as="sourcePoint" />
<mxPoint x="330" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-133" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="890" y="250" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-134" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-133">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="675" y="240" as="sourcePoint" />
<mxPoint x="895" y="280" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-135" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1415" y="410" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-136" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-135">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1200" y="400" as="sourcePoint" />
<mxPoint x="1420" y="510" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-137" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1545" y="250" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-138" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-137">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1330" y="240" as="sourcePoint" />
<mxPoint x="1550" y="350" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-139" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1285" y="340" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-140" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-139" target="Sf4z-aHPgcdhoojVuiNO-85">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1070" y="330" as="sourcePoint" />
<mxPoint x="1290" y="440" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-146" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-141" target="Sf4z-aHPgcdhoojVuiNO-143">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-141" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1830" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-142" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1840" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-188" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-143" target="Sf4z-aHPgcdhoojVuiNO-178">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-143" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1970" y="350" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-144" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1980" y="365" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-163" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-147" target="Sf4z-aHPgcdhoojVuiNO-161">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-147" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1970" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-148" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1980" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-162" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-149" target="Sf4z-aHPgcdhoojVuiNO-160">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-149" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1830" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-150" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1840" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-151" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1995" y="410" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-152" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-151">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1780" y="400" as="sourcePoint" />
<mxPoint x="2000" y="510" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-154" value="send AnimationStartMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1910" y="320" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-157" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="1855" y="340" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-158" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-157">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1865" y="336.07000000000016" as="sourcePoint" />
<mxPoint x="1859.88" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-159" value="send AnimationStartMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1770" y="428" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-196" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-160" target="Sf4z-aHPgcdhoojVuiNO-194">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-160" value="Animate the shot" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="1960" y="190" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-199" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-161">
<mxGeometry relative="1" as="geometry">
<mxPoint x="2260" y="539.8947368421054" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-161" value="Animate the shot" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2090" y="510" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-176" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-178" target="Sf4z-aHPgcdhoojVuiNO-182">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-191" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-178" target="Sf4z-aHPgcdhoojVuiNO-189">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-178" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="2130" y="355" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-179" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="2325" y="310" as="sourcePoint" />
<mxPoint x="2380" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-181" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-182">
<mxGeometry relative="1" as="geometry">
<mxPoint x="2380" y="450" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-182" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2265" y="420" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-183" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2275" y="435" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-189" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2265" y="280" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-190" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2275" y="295" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-210" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-194" target="Sf4z-aHPgcdhoojVuiNO-206">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-194" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2265" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-195" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2275" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-211" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-197" target="Sf4z-aHPgcdhoojVuiNO-208">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-197" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2265" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-198" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2275" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-225" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-202" target="Sf4z-aHPgcdhoojVuiNO-215">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-202" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2380" y="420" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-203" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2390" y="435" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-224" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-204" target="Sf4z-aHPgcdhoojVuiNO-217">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-204" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2380" y="280" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-205" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2390" y="295" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-223" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-206" target="Sf4z-aHPgcdhoojVuiNO-219">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-206" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2380" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-207" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2390" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-226" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-208" target="Sf4z-aHPgcdhoojVuiNO-221">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-208" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2380" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-209" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2390" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-229" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-215" target="Sf4z-aHPgcdhoojVuiNO-227">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-215" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2540" y="420" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-216" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2550" y="435" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-228" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-217" target="Sf4z-aHPgcdhoojVuiNO-227">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-217" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2540" y="280" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-218" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2550" y="295" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-219" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2540" y="190" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-220" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2550" y="205" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-221" value="" style="ellipse;shape=doubleEllipse;html=1;dashed=0;whiteSpace=wrap;aspect=fixed;" vertex="1" parent="1">
<mxGeometry x="2540" y="510" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-222" value="" style="shape=message;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2550" y="525" width="40" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-227" value="" style="shape=mxgraph.bpmn.shape;html=1;verticalLabelPosition=bottom;labelBackgroundColor=#ffffff;verticalAlign=top;perimeter=rhombusPerimeter;background=gateway;outline=none;symbol=parallelGw;" vertex="1" parent="1">
<mxGeometry x="2720" y="345" width="50" height="50" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-230" value="send animationEndMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2200" y="160" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-231" value="send animationEndMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2210" y="570" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-232" value="send Effect Message" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2340" y="340" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-234" value="send Effect Message" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2340" y="390" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-235" value="send BackToBattleStateMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2480" y="340" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-236" value="send BackToBattleStateMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="2490" y="390" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-244" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2290" y="500" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-245" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-244">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2315" y="490" as="sourcePoint" />
<mxPoint x="2295" y="480" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-248" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2409.71" y="269.9999999999998" as="sourcePoint" />
<mxPoint x="2409.71" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-250" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2565" y="270" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-251" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-250">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2590" y="260" as="sourcePoint" />
<mxPoint x="2570" y="250" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-253" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-247">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2294.71" y="260" as="sourcePoint" />
<mxPoint x="2294.71" y="279.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-254" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2405" y="270" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-256" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" target="Sf4z-aHPgcdhoojVuiNO-247">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2294.71" y="260" as="sourcePoint" />
<mxPoint x="2294.71" y="279.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-247" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2290" y="250" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-257" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-258">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2409.71" y="490" as="sourcePoint" />
<mxPoint x="2409.71" y="509.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-258" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2405" y="480" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-259" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-260">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2569.71" y="490" as="sourcePoint" />
<mxPoint x="2569.71" y="509.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-260" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2565" y="480" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-261" value="Game Play" style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="2870" y="110" width="120" height="490" as="geometry" />
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-265" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-227">
<mxGeometry relative="1" as="geometry">
<mxPoint x="2870" y="370" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-267" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-219">
<mxGeometry relative="1" as="geometry">
<mxPoint x="2870" y="220" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="Sf4z-aHPgcdhoojVuiNO-268" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.018;entryY=0.878;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="Sf4z-aHPgcdhoojVuiNO-221" target="Sf4z-aHPgcdhoojVuiNO-261">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

View File

@@ -1,475 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1538" dy="866" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="TwrB0rHwIU3CN8L-tBzC-1" value="«interface»&lt;br&gt;&lt;b&gt;GameEventBroker&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1140" y="535" width="120" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-2" value="«interface»&lt;br&gt;&lt;b&gt;ServerInterpreter&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="954.5" y="535" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-3" value="«interface»&lt;br&gt;&lt;b&gt;ClientSender&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="320" y="720" width="150" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-4" value="«interface»&lt;br&gt;&lt;b&gt;gameEventListener&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="790" y="800" width="131" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-5" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientGameLogic&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from Model)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="965" y="730" width="110" height="40" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-6" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-5" target="TwrB0rHwIU3CN8L-tBzC-16">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="445" as="sourcePoint" />
<mxPoint x="865" y="560" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-7" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-5" target="TwrB0rHwIU3CN8L-tBzC-3">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="867" y="755" as="sourcePoint" />
<mxPoint x="690" y="750" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-8" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-5" target="TwrB0rHwIU3CN8L-tBzC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="765" as="sourcePoint" />
<mxPoint x="877" y="635" as="targetPoint" />
<Array as="points">
<mxPoint x="993" y="830" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-9" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-5" target="TwrB0rHwIU3CN8L-tBzC-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1015" y="550" as="targetPoint" />
<Array as="points">
<mxPoint x="1020" y="660" />
<mxPoint x="1200" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-10" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-5" target="TwrB0rHwIU3CN8L-tBzC-2">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1190" y="640" as="targetPoint" />
<Array as="points">
<mxPoint x="1020" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-11" value="3" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1594" y="720" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-15" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="921" y="830" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-16" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b style=&quot;background-color: initial;&quot;&gt;ShipMap&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b style=&quot;background-color: initial;&quot;&gt;(from Model)&lt;/b&gt;&lt;br&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1660" y="730" width="110" height="40" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-20" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-16" target="TwrB0rHwIU3CN8L-tBzC-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1300" y="630" as="sourcePoint" />
<mxPoint x="1585" y="630" as="targetPoint" />
<Array as="points">
<mxPoint x="1715" y="560" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-21" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleshipAppState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="600" y="920" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-22" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleshipApp&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="930" y="920" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-23" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameSound&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="740" y="920" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-24" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleshipAppConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1170" y="920" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-25" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;SeaSynchronizer&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1400" y="1020" width="130" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-26" value="«interface»&lt;br&gt;&lt;b&gt;BattleshipClient&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1180" y="800" width="131" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-27" value="«interface»&lt;br&gt;&lt;div&gt;&lt;b&gt;Visitor &amp;lt;Spatial&amp;gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;(from model)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1329" y="800" width="131" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-28" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ModelViewSynchronizer&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&amp;lt;Item&amp;gt;&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from JME-Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1494" y="800" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-29" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;SimpleApplication&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b style=&quot;background-color: initial;&quot;&gt;(from JME)&lt;/b&gt;&lt;br&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1040" y="800" width="121" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-31" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMapSynchronizer&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1464" y="920" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-32" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;MapViewSynchronizer&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1530" y="1020" width="160" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-33" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EditorAppState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="560" y="1020" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-34" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleAppState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="670" y="1020" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-35" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;SeaAppState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="790" y="1020" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-36" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;MapView&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="727" y="1120" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-37" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;DialogManager&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from LME-Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1080" y="1100" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-38" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Dialog&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from LME-Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1257.5" y="1100" width="125" height="40" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-39" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;NetworkDialog&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1250" y="1300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-41" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;SimpleDialog&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from LME-Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1260" y="1200" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-42" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Menu&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1120" y="1200" width="117.5" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-43" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;NetworkSupport&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="240" y="1349" width="130" height="20" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-44" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Abstract&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AppState&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="600" y="800" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-45" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-29">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1080" y="970" as="sourcePoint" />
<mxPoint x="1240" y="970" as="targetPoint" />
<Array as="points">
<mxPoint x="1101" y="890" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-49" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-21" target="TwrB0rHwIU3CN8L-tBzC-44">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1070" y="990" as="sourcePoint" />
<mxPoint x="1230" y="990" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-50" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-41" target="TwrB0rHwIU3CN8L-tBzC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1080" y="1000" as="sourcePoint" />
<mxPoint x="1240" y="1000" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-51" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-42" target="TwrB0rHwIU3CN8L-tBzC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1090" y="1010" as="sourcePoint" />
<mxPoint x="1250" y="1010" as="targetPoint" />
<Array as="points">
<mxPoint x="1290" y="1180" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-52" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-39" target="TwrB0rHwIU3CN8L-tBzC-41">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1100" y="1020" as="sourcePoint" />
<mxPoint x="1260" y="1020" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-53" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-31" target="TwrB0rHwIU3CN8L-tBzC-28">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1110" y="1030" as="sourcePoint" />
<mxPoint x="1270" y="1030" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-54" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-33" target="TwrB0rHwIU3CN8L-tBzC-21">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1120" y="1040" as="sourcePoint" />
<mxPoint x="1280" y="1040" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-55" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-34" target="TwrB0rHwIU3CN8L-tBzC-21">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1130" y="1050" as="sourcePoint" />
<mxPoint x="1290" y="1050" as="targetPoint" />
<Array as="points">
<mxPoint x="660" y="990" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-56" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-35" target="TwrB0rHwIU3CN8L-tBzC-21">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1140" y="1060" as="sourcePoint" />
<mxPoint x="1300" y="1060" as="targetPoint" />
<Array as="points">
<mxPoint x="690" y="990" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-57" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-32" target="TwrB0rHwIU3CN8L-tBzC-31">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1520" y="1055" as="sourcePoint" />
<mxPoint x="1560" y="955" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-58" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-25" target="TwrB0rHwIU3CN8L-tBzC-31">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1470" y="995" as="sourcePoint" />
<mxPoint x="1480" y="955" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-59" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-23" target="TwrB0rHwIU3CN8L-tBzC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1075" y="1010" as="sourcePoint" />
<mxPoint x="1235" y="1010" as="targetPoint" />
<Array as="points">
<mxPoint x="856" y="900" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-61" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1085" y="1020" as="sourcePoint" />
<mxPoint x="1245" y="1020" as="targetPoint" />
<Array as="points">
<mxPoint x="890" y="900" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-62" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-26">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1095" y="1030" as="sourcePoint" />
<mxPoint x="1255" y="1030" as="targetPoint" />
<Array as="points">
<mxPoint x="1246" y="880" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-63" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-31" target="TwrB0rHwIU3CN8L-tBzC-4">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1105" y="1040" as="sourcePoint" />
<mxPoint x="1265" y="1040" as="targetPoint" />
<Array as="points">
<mxPoint x="1370" y="930" />
<mxPoint x="1370" y="910" />
<mxPoint x="1240" y="910" />
<mxPoint x="960" y="860" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-64" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-31" target="TwrB0rHwIU3CN8L-tBzC-27">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1115" y="1050" as="sourcePoint" />
<mxPoint x="1275" y="1050" as="targetPoint" />
<Array as="points">
<mxPoint x="1395" y="880" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-65" value="«interface»&lt;br&gt;&lt;b&gt;ServerConnection&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="312" y="1237" width="120" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-66" value="«interface»&lt;br&gt;&lt;b&gt;ClientStateListener&lt;/b&gt;&lt;div&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="270" y="1169" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-67" value="«interface»&lt;br&gt;&lt;div&gt;&lt;b&gt;MessageListener &amp;lt;Client&amp;gt; (from JME)&lt;/b&gt;&lt;/div&gt;" style="html=1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="130" y="1247" width="171" height="50" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-69" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-65" target="TwrB0rHwIU3CN8L-tBzC-3">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="480" y="850" as="sourcePoint" />
<mxPoint x="546" y="790" as="targetPoint" />
<Array as="points">
<mxPoint x="430" y="1230" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-72" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-5">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="940" y="990" as="sourcePoint" />
<mxPoint x="1100" y="990" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-73" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-24">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="950" y="1000" as="sourcePoint" />
<mxPoint x="1110" y="1000" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-74" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-65">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="960" y="1010" as="sourcePoint" />
<mxPoint x="570" y="1130" as="targetPoint" />
<Array as="points">
<mxPoint x="960" y="1260" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-75" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-22" target="TwrB0rHwIU3CN8L-tBzC-37">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="970" y="1020" as="sourcePoint" />
<mxPoint x="1130" y="1020" as="targetPoint" />
<Array as="points">
<mxPoint x="1050" y="1120" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-76" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-37" target="TwrB0rHwIU3CN8L-tBzC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="980" y="1030" as="sourcePoint" />
<mxPoint x="1140" y="1030" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-77" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1215" y="1118" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-78" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-35" target="TwrB0rHwIU3CN8L-tBzC-25">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="990" y="1040" as="sourcePoint" />
<mxPoint x="1150" y="1040" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-79" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-25" target="TwrB0rHwIU3CN8L-tBzC-22">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1000" y="1050" as="sourcePoint" />
<mxPoint x="1090" y="960" as="targetPoint" />
<Array as="points">
<mxPoint x="1330" y="1020" />
<mxPoint x="1120" y="940" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-80" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-36" target="TwrB0rHwIU3CN8L-tBzC-22">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1010" y="1060" as="sourcePoint" />
<mxPoint x="1170" y="1060" as="targetPoint" />
<Array as="points">
<mxPoint x="930" y="1130" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-81" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-43" target="TwrB0rHwIU3CN8L-tBzC-22">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1020" y="1070" as="sourcePoint" />
<mxPoint x="1180" y="1070" as="targetPoint" />
<Array as="points">
<mxPoint x="990" y="1360" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-82" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-42" target="TwrB0rHwIU3CN8L-tBzC-22">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1030" y="1080" as="sourcePoint" />
<mxPoint x="1190" y="1080" as="targetPoint" />
<Array as="points">
<mxPoint x="1020" y="1210" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-83" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-33" target="TwrB0rHwIU3CN8L-tBzC-36">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="630" y="1070" as="sourcePoint" />
<mxPoint x="790" y="1070" as="targetPoint" />
<Array as="points">
<mxPoint x="605" y="1130" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-84" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="695" y="1128" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-85" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-34" target="TwrB0rHwIU3CN8L-tBzC-36">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1050" y="1100" as="sourcePoint" />
<mxPoint x="1210" y="1100" as="targetPoint" />
<Array as="points">
<mxPoint x="720" y="1100" />
<mxPoint x="777" y="1100" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-87" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-39" target="TwrB0rHwIU3CN8L-tBzC-43">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1070" y="1120" as="sourcePoint" />
<mxPoint x="1230" y="1120" as="targetPoint" />
<Array as="points">
<mxPoint x="1320" y="1390" />
<mxPoint x="305" y="1390" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-88" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-43">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="379" y="1329" as="sourcePoint" />
<mxPoint x="340" y="1287" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-89" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-43" target="TwrB0rHwIU3CN8L-tBzC-66">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="399" y="1359" as="sourcePoint" />
<mxPoint x="406" y="1134" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-90" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-43" target="TwrB0rHwIU3CN8L-tBzC-67">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="409" y="1369" as="sourcePoint" />
<mxPoint x="416" y="1144" as="targetPoint" />
<Array as="points">
<mxPoint x="258" y="1339" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-92" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.53;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-36" target="TwrB0rHwIU3CN8L-tBzC-16">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="837" y="1140" as="sourcePoint" />
<mxPoint x="1740" y="820" as="targetPoint" />
<Array as="points">
<mxPoint x="780" y="1440" />
<mxPoint x="1715" y="1440" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-93" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-31" target="TwrB0rHwIU3CN8L-tBzC-16">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1620" y="940" as="sourcePoint" />
<mxPoint x="1730" y="940" as="targetPoint" />
<Array as="points">
<mxPoint x="1688" y="930" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-94" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="TwrB0rHwIU3CN8L-tBzC-23" target="TwrB0rHwIU3CN8L-tBzC-44">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="670" y="930" as="sourcePoint" />
<mxPoint x="670" y="870" as="targetPoint" />
<Array as="points">
<mxPoint x="690" y="900" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-96" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="TwrB0rHwIU3CN8L-tBzC-36">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1610" y="1150" as="sourcePoint" />
<mxPoint x="1220" y="1631" as="targetPoint" />
<Array as="points">
<mxPoint x="1610" y="1420" />
<mxPoint x="802" y="1420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="TwrB0rHwIU3CN8L-tBzC-97" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" target="TwrB0rHwIU3CN8L-tBzC-32">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1610" y="1150" as="sourcePoint" />
<mxPoint x="1540" y="1068" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

View File

@@ -1,527 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="2288" dy="823" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="LkLulIeU9eejG4ewMiHC-0" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Config&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from Common)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="960" y="205" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-1" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Abstract Message&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;(from JME)&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="60" y="200" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-2" value="«interface»&lt;br&gt;&lt;b&gt;ServerSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="630" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-3" value="«interface»&lt;br&gt;&lt;b&gt;ClientInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="800" y="200" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-4" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-260" y="370" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-8" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="410" y="585" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-9" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-4" target="LkLulIeU9eejG4ewMiHC-1" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="660" y="535" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-10" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="500" y="535" as="sourcePoint" />
<mxPoint x="130" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="480" y="310" />
<mxPoint x="130" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-11" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;MapMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-430" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-13" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShootMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-260" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-14" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationEndMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-90" y="470" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-16" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-13" target="LkLulIeU9eejG4ewMiHC-4" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="195" y="390" as="sourcePoint" />
<mxPoint y="230" as="targetPoint" />
<Array as="points">
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-17" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-4" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="205" y="400" as="sourcePoint" />
<mxPoint x="10" y="240" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-18" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ServerGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="785" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-20" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-3" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="480" y="310" as="sourcePoint" />
<mxPoint x="640" y="310" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-21" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.445;entryY=1.008;entryDx=0;entryDy=0;entryPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-2" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="720" y="320" as="sourcePoint" />
<mxPoint x="880" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="680" y="310" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-22" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-23" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1226" y="340" as="sourcePoint" />
<mxPoint x="1070" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-23" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="960" y="300" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-24" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-23" target="LkLulIeU9eejG4ewMiHC-0" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1009" y="355" as="sourcePoint" />
<mxPoint x="1009" y="200" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-25" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BallteshipClientConfig&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="960" y="400" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-26" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-25" target="LkLulIeU9eejG4ewMiHC-23" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="904" y="520" as="sourcePoint" />
<mxPoint x="709" y="360" as="targetPoint" />
<Array as="points">
<mxPoint x="1030" y="370" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-27" value="«enum»&lt;br&gt;&lt;b&gt;ServerState&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="610" y="370" width="110" height="40" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-28" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-27" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="746" y="370" as="sourcePoint" />
<mxPoint x="680" y="390" as="targetPoint" />
<Array as="points">
<mxPoint x="820" y="390" />
<mxPoint x="743" y="390" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-29" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Player&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="810" y="465" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-31" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-18" target="LkLulIeU9eejG4ewMiHC-29" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="330" as="sourcePoint" />
<mxPoint x="870" y="460" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-32" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMap&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="810" y="550" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-33" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-29" target="LkLulIeU9eejG4ewMiHC-32" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="280" as="sourcePoint" />
<mxPoint x="865" y="425" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-34" value="«interface»&lt;br&gt;&lt;b&gt;GameEventBroker&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="960" y="535" width="120" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-35" value="«interface»&lt;br&gt;&lt;b&gt;ServerInterpreter&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="1110" y="535" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-36" value="«interface»&lt;br&gt;&lt;b&gt;ClientSender&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="1112" y="735" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-37" value="«interface»&lt;br&gt;&lt;b&gt;gameEventListener&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="1112" y="805" width="131" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-38" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientGameLogic&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="800" y="750" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-39" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-44" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="865" y="445" as="sourcePoint" />
<mxPoint x="865" y="560" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-40" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-36" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="867" y="755" as="sourcePoint" />
<mxPoint x="867" y="625" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-41" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-37" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="765" as="sourcePoint" />
<mxPoint x="877" y="635" as="targetPoint" />
<Array as="points">
<mxPoint x="883" y="830" />
<mxPoint x="1062" y="830" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-42" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-34" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1015" y="550" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="660" />
<mxPoint x="1020" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-43" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=1;exitY=0;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" target="LkLulIeU9eejG4ewMiHC-35" edge="1" source="LkLulIeU9eejG4ewMiHC-38">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="880" y="750" as="sourcePoint" />
<mxPoint x="1190" y="640" as="targetPoint" />
<Array as="points">
<mxPoint x="910" y="710" />
<mxPoint x="1176" y="710" />
<mxPoint x="1176" y="660" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-44" value="3" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="840" y="570" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-45" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="827" y="435" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-47" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ClientState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="800" y="848" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-48" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="830" y="790" as="sourcePoint" />
<mxPoint x="830" y="820" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-49" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-47" target="LkLulIeU9eejG4ewMiHC-38" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="892" y="865" as="sourcePoint" />
<mxPoint x="852" y="815" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-50" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameDetails&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="580" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-51" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-38" target="LkLulIeU9eejG4ewMiHC-50" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="740" y="835" as="sourcePoint" />
<mxPoint x="740" y="715" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-52" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;StartBattleMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="420" y="750" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-54" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationStartMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="250" y="750" width="140" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-55" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BackToBattleStateMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="45" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-56" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-52" target="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="827" y="470" as="sourcePoint" />
<mxPoint x="477" y="310" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-57" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#FF0000;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-54" target="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="280" y="700" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="320" y="690" />
<mxPoint x="320" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-58" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-55" target="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="360" y="710" as="sourcePoint" />
<mxPoint x="490" y="280" as="targetPoint" />
<Array as="points">
<mxPoint x="130" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-59" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-50" target="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="510" y="710" as="sourcePoint" />
<mxPoint x="488" y="285" as="targetPoint" />
<Array as="points">
<mxPoint x="640" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-60" value="«interface»&lt;br&gt;&lt;b&gt;Item&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-220" y="535" width="140" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-61" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EffectMessage&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-140" y="750" width="170" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-62" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-8" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="30" y="680" as="sourcePoint" />
<mxPoint x="384" y="250" as="targetPoint" />
<Array as="points">
<mxPoint x="-55" y="640" />
<mxPoint x="480" y="640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-63" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shot&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-170" y="650" width="90" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-64" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShip&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-390" y="650" width="113" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-65" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;Shell&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-260" y="650" width="70" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-66" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-32" target="LkLulIeU9eejG4ewMiHC-60" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="270" y="485" as="sourcePoint" />
<mxPoint x="270" y="365" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-67" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-85" y="528" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-68" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-20" y="470" as="sourcePoint" />
<mxPoint x="-190" y="390" as="targetPoint" />
<Array as="points">
<mxPoint x="-20" y="420" />
<mxPoint x="-190" y="420" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-69" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-63" target="LkLulIeU9eejG4ewMiHC-60" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-70.42000000000007" y="750" as="sourcePoint" />
<mxPoint x="-70.42000000000007" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-125" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-70" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-60" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="660" as="sourcePoint" />
<mxPoint x="-150" y="590" as="targetPoint" />
<Array as="points">
<mxPoint x="-333" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-71" value="" style="endArrow=block;dashed=1;endFill=0;endSize=12;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-65" target="LkLulIeU9eejG4ewMiHC-60" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-233" y="660" as="sourcePoint" />
<mxPoint x="-175" y="595" as="targetPoint" />
<Array as="points">
<mxPoint x="-225" y="630" />
<mxPoint x="-150" y="630" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-72" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.088;exitY=0.02;exitDx=0;exitDy=0;exitPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-63" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="370" y="690" as="sourcePoint" />
<mxPoint x="-70" y="570" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-73" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-61" target="LkLulIeU9eejG4ewMiHC-64" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-115" y="760" as="sourcePoint" />
<mxPoint x="-115" y="680" as="targetPoint" />
<Array as="points">
<mxPoint x="-305" y="760" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-74" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-335" y="668" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-75" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-11" target="LkLulIeU9eejG4ewMiHC-64" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-393.5" y="535" as="sourcePoint" />
<mxPoint x="-586.5" y="445" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="560" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-76" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-390" y="620" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-79" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;WaitState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="540" y="930" width="100" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-80" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="660" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-81" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;InitialState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="795" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-82" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;AnimationState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;fillColor=default;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="930" y="930" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-83" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;GameOverState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="1060" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-84" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;EditorState&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="400" y="930" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-85" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-81" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="820" y="1020" as="sourcePoint" />
<mxPoint x="940" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-86" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-80" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="860" y="940" as="sourcePoint" />
<mxPoint x="940" y="860" as="targetPoint" />
<Array as="points">
<mxPoint x="715" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-87" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-79" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="628" y="925" as="sourcePoint" />
<mxPoint x="890" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="590" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-89" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;fillColor=#FF0000;strokeColor=#FF0000;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-82" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="877" y="950" as="sourcePoint" />
<mxPoint x="920" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="985" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-90" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-83" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1120" y="920" as="sourcePoint" />
<mxPoint x="840" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="1120" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-91" value="" style="endArrow=block;endSize=16;endFill=0;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-47" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="503" y="910" as="sourcePoint" />
<mxPoint x="800" y="890" as="targetPoint" />
<Array as="points">
<mxPoint x="460" y="910" />
<mxPoint x="855" y="910" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-92" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-84" target="LkLulIeU9eejG4ewMiHC-64" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="380" y="830" as="sourcePoint" />
<mxPoint x="40" y="870" as="targetPoint" />
<Array as="points">
<mxPoint x="-360" y="940" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-93" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-390" y="680" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-94" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="1085" y="838" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-95" value="«enum»&lt;br&gt;&lt;b&gt;Rotation&lt;/b&gt;" style="html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-550" y="635" width="110" height="50" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-96" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;BattleShipDTO&lt;/b&gt;&lt;/p&gt;&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-550" y="735" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-97" value="&lt;p style=&quot;margin:0px;margin-top:4px;text-align:center;&quot;&gt;&lt;b&gt;ShipMaoDTO&lt;/b&gt;&lt;/p&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-550" y="800" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-98" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-96" target="LkLulIeU9eejG4ewMiHC-95" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-420.8" y="778" as="sourcePoint" />
<mxPoint x="-420.8" y="698" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-99" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-97" target="LkLulIeU9eejG4ewMiHC-96" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-100" value="*" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="-495" y="760" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="LkLulIeU9eejG4ewMiHC-101" value="" style="endArrow=open;endFill=1;endSize=12;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="LkLulIeU9eejG4ewMiHC-64" target="LkLulIeU9eejG4ewMiHC-95" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-485" y="745" as="sourcePoint" />
<mxPoint x="-485" y="695" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

View File

@@ -1,96 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram name="Seite-1" id="CSCMTvoyx8GfkIWIgrj5">
<mxGraphModel dx="2914" dy="1176" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="8jlTEtXbO0kP9G_WUDS2-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-2" target="8jlTEtXbO0kP9G_WUDS2-8" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-2" target="8jlTEtXbO0kP9G_WUDS2-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-2" value="" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="70" y="320" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-6" value="addPlayer(id)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="130" y="290" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-7" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-10" y="358" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-8" target="8jlTEtXbO0kP9G_WUDS2-16" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-8" target="8jlTEtXbO0kP9G_WUDS2-16" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-8" value="Set up" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="72.5" y="450" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-11" value="[players.size()=2]/send GameDetail messages" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="125" y="360" width="270" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-12" target="8jlTEtXbO0kP9G_WUDS2-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-12" value="" style="ellipse;fillColor=strokeColor;html=1;" parent="1" vertex="1">
<mxGeometry x="15" y="260" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-16" target="8jlTEtXbO0kP9G_WUDS2-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-16" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="170" y="520" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-19" value="received MapMessage&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="220" y="470" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-20" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="50" y="588" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FF0000;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-21" target="8jlTEtXbO0kP9G_WUDS2-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-21" value="Battle" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="172.5" y="640" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-23" value="[readyPlayers.size() = 2]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="220" y="585" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-24" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="342.3548387096773" y="830" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-24" value="Animation wait" style="rounded=1;whiteSpace=wrap;html=1;strokeColor=#FF0000;" parent="1" vertex="1">
<mxGeometry x="285" y="680" width="115" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-29" target="8jlTEtXbO0kP9G_WUDS2-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="8jlTEtXbO0kP9G_WUDS2-29" target="8jlTEtXbO0kP9G_WUDS2-31" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-29" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="302.5" y="830" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-31" value="Game over" style="rounded=1;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="285" y="960" width="115" height="20" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-33" value="[game over]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="345" y="888" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="8jlTEtXbO0kP9G_WUDS2-34" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="205" y="860" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="EPEOK_vwsi3Ha1gNdRhl-1" value="sendAnimationStartMessage(pos)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=#FF0000;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="350" y="615" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="EPEOK_vwsi3Ha1gNdRhl-2" value="shoot(pos)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="340" y="758" width="80" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -1,94 +0,0 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1461" dy="823" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="ec3Q6cWicWv9khViEyFp-0" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-1" target="ec3Q6cWicWv9khViEyFp-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-1" value="" style="ellipse;fillColor=strokeColor;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="550" y="260" width="30" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-3" target="ec3Q6cWicWv9khViEyFp-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-3" value="Initial State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="670" y="265" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-5" target="ec3Q6cWicWv9khViEyFp-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-5" value="Editor State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="670" y="358" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-6" value="receivedGameDetails(details)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="720" y="298" width="180" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-9" target="ec3Q6cWicWv9khViEyFp-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-9" target="ec3Q6cWicWv9khViEyFp-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-9" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="780" y="470" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-10" value="mapFinished" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="815" y="368" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-11" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="680" y="498" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-13" target="ec3Q6cWicWv9khViEyFp-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-13" value="Wait State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="782.5" y="575" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=#FF0000;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-15" target="ec3Q6cWicWv9khViEyFp-17">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-15" value="Battle State" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="782.5" y="690" width="75" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-17" target="ec3Q6cWicWv9khViEyFp-21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-17" value="Animation State" style="rounded=1;whiteSpace=wrap;html=1;strokeColor=#FF0000;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="940" y="760" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-18" value="receivedAnimationStartMessage(msg)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=#FF0000;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="885" y="660" width="230" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-21" target="ec3Q6cWicWv9khViEyFp-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="ec3Q6cWicWv9khViEyFp-21" target="ec3Q6cWicWv9khViEyFp-23">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-21" value="&lt;span style=&quot;color: rgba(0, 0, 0, 0); font-family: monospace; font-size: 0px; text-align: start; text-wrap: nowrap;&quot;&gt;%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%22%20style%3D%22rhombus%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22170%22%20y%3D%22530%22%20width%3D%2280%22%20height%3D%2240%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E&lt;/span&gt;" style="rhombus;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="955" y="878" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-22" value="sendAnimationEndMessage(pos)&lt;div&gt;receivedEffectMessage(msg)&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1060" y="805" width="200" height="40" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-23" value="game over" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="940" y="970" width="110" height="20" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-24" value="[game over]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="1005" y="930" width="90" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-25" value="[otherwise]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="832" y="918" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-26" value="[horbor&amp;nbsp; empty] / send MapMessage" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="832" y="525" width="220" height="30" as="geometry" />
</mxCell>
<mxCell id="ec3Q6cWicWv9khViEyFp-27" value="receivedStartBattle(msg)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="827" y="610" width="160" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -1,18 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="BattleshipApp (Mac)" type="Application" factoryName="Application"
singleton="false">
<option name="MAIN_CLASS_NAME" value="pp.battleship.client.BattleshipApp"/>
<module name="Projekte.battleship.client.main"/>
<option name="VM_PARAMETERS" value="-XstartOnFirstThread"/>
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$"/>
<extension name="coverage">
<pattern>
<option name="PATTERN" value="pp.battleship.client.*"/>
<option name="ENABLED" value="true"/>
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true"/>
</method>
</configuration>
<configuration default="false" name="BattleshipApp (Mac)" type="Application" factoryName="Application" singleton="false">
<option name="MAIN_CLASS_NAME" value="pp.battleship.client.BattleshipApp" />
<module name="Projekte.battleship.client.main" />
<option name="VM_PARAMETERS" value="-XstartOnFirstThread" />
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="pp.battleship.client.server.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -1,18 +1,19 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="BattleshipApp" type="Application" factoryName="Application" singleton="false"
nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="pp.battleship.client.BattleshipApp"/>
<module name="Projekte.battleship.client.main"/>
<option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties"/>
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$"/>
<configuration default="false" name="BattleshipApp" type="Application" factoryName="Application" singleton="false" nameIsGenerated="true">
<option name="ALTERNATIVE_JRE_PATH" value="temurin-20" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="MAIN_CLASS_NAME" value="pp.battleship.client.BattleshipApp" />
<module name="Gruppe-01" />
<option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties" />
<option name="WORKING_DIRECTORY" value="$MODULE_WORKING_DIR$" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="pp.battleship.client.*"/>
<option name="ENABLED" value="true"/>
<option name="PATTERN" value="pp.battleship.client.server.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true"/>
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -9,6 +9,7 @@ implementation project(":jme-common")
implementation project(":battleship:model")
implementation libs.jme3.desktop
implementation libs.jme3.effects
runtimeOnly libs.jme3.awt.dialogs
runtimeOnly libs.jme3.plugins

View File

@@ -9,7 +9,7 @@
#
# Specifies the map used by the opponent in single mode.
# Single mode is activated if this property is set.
#git map.opponent=maps/map2.json
#map.opponent=maps/map2.json
#
# Specifies the map used by the player in single mode.
# The player must define their own map if this property is not set.

View File

@@ -0,0 +1,66 @@
{
"width": 10,
"height": 10,
"ships": [
{
"length": 4,
"x": 2,
"y": 8,
"rot": "RIGHT"
},
{
"length": 3,
"x": 2,
"y": 5,
"rot": "DOWN"
},
{
"length": 3,
"x": 5,
"y": 6,
"rot": "RIGHT"
},
{
"length": 2,
"x": 4,
"y": 4,
"rot": "RIGHT"
},
{
"length": 2,
"x": 7,
"y": 4,
"rot": "RIGHT"
},
{
"length": 2,
"x": 7,
"y": 4,
"rot": "RIGHT"
},
{
"length": 1,
"x": 6,
"y": 2,
"rot": "RIGHT"
},
{
"length": 1,
"x": 8,
"y": 2,
"rot": "RIGHT"
},
{
"length": 1,
"x": 6,
"y": 0,
"rot": "RIGHT"
},
{
"length": 1,
"x": 8,
"y": 0,
"rot": "RIGHT"
}
]
}

View File

@@ -0,0 +1,66 @@
{
"width": 10,
"height": 10,
"ships": [
{
"length": 1,
"x": 9,
"y": 0,
"rot": "RIGHT"
},
{
"length": 1,
"x": 9,
"y": 1,
"rot": "RIGHT"
},
{
"length": 1,
"x": 8,
"y": 0,
"rot": "RIGHT"
},
{
"length": 1,
"x": 8,
"y": 1,
"rot": "RIGHT"
},
{
"length": 2,
"x": 8,
"y": 2,
"rot": "RIGHT"
},
{
"length": 2,
"x": 6,
"y": 0,
"rot": "RIGHT"
},
{
"length": 2,
"x": 6,
"y": 1,
"rot": "RIGHT"
},
{
"length": 3,
"x": 5,
"y": 2,
"rot": "RIGHT"
},
{
"length": 3,
"x": 7,
"y": 3,
"rot": "RIGHT"
},
{
"length": 4,
"x": 6,
"y": 4,
"rot": "RIGHT"
}
]
}

View File

@@ -7,117 +7,89 @@
import java.util.prefs.Preferences;
/**
* this class is used to control the background-music in the game
*/
public class BackgroundMusic {
/**
* this attribute ist the keyword to save the last volume, that was set
*/
private static final String VOLUME_PREV = "BackgroundVolume";
/**
* this attribute ist the keyword to save the state, whether the music was on or off in the last session
*/
private static final String BACKGROUND_MUSIC_ENABLED_PREV = "BackgroundMusicEnabled";
/**
* this attribute holds the last set values for on/off and the volume, with the keywords "BackgroundVolume" and "BackgroundMusicEnabled"
*/
private static final String VOLUME_PREF = "volume";
private static final String MUSIC_ENABLED_PREF = "musicEnabled";
private Preferences prefs = Preferences.userNodeForPackage(BackgroundMusic.class);
/**
* this attribute holds the Music-node, which is used to play the music
*/
private final AudioNode backgroundMusic;
private boolean musicEnabled;
private float volume;
/**
* this boolean holds, whether the music is enabled or not at this state
* Constuctor for the BackgroundMusic
* @param app for synchronising and saving data with the application
* @param musicFilePath the filepath for the BackgroundMusic
*/
private boolean backgroundMusicEnabled;
public BackgroundMusic(Application app, String musicFilePath) {
this.volume = prefs.getFloat(VOLUME_PREF, 1.0f);
this.musicEnabled = prefs.getBoolean(MUSIC_ENABLED_PREF, true);
/**
* this attribute holds the current volume
*/
private float backgroundVolume;
/**
* this is the constructor of this class, is used to set the current values to the values stored in the preferences
*
* @param app the application the Background-music uis used in
* @param backGroundMusicPath the path, where the Background-music is stored in
*/
public BackgroundMusic(Application app, String backGroundMusicPath) {
this.backgroundVolume = prefs.getFloat(VOLUME_PREV, 1.0f); // sets the volume to the value stored in pref,or 1.0f if it is not accessible
this.backgroundMusicEnabled = prefs.getBoolean(BACKGROUND_MUSIC_ENABLED_PREV, true); // sets the enabled to the value stored in pref,or true if it is not accessible
backgroundMusic = new AudioNode(app.getAssetManager(), backGroundMusicPath, DataType.Stream); // initialize the Audio-node
backgroundMusic.setLooping(true); // sets looping true, so it is played always, when enabled
backgroundMusic = new AudioNode(app.getAssetManager(), musicFilePath, DataType.Stream);
backgroundMusic.setLooping(true);
backgroundMusic.setPositional(false);
backgroundMusic.setVolume(backgroundVolume);
backgroundMusic.setVolume(1.0f);
if (backgroundMusicEnabled) { //starts playing, when enabled
if (musicEnabled) {
play();
}
}
/**
* this method plays the background sound, if it is enabled
* Checks if the condition is met to play BackgroundMusic
*/
public void play() {
if (backgroundMusicEnabled && (backgroundMusic.getStatus() == Status.Stopped || backgroundMusic.getStatus() == Status.Paused)) { //checks, if it is enabled and stopped or paused
if (musicEnabled && (backgroundMusic.getStatus() == Status.Stopped || backgroundMusic.getStatus() == Status.Paused)) {
backgroundMusic.play();
}
}
/**
* this method stops the background-music
* function to stop the BackgroundMusic
*/
public void stop() { //stops the music, when it is playing
if (backgroundMusic.getStatus() == Status.Playing) backgroundMusic.stop();
public void stop() {
if (backgroundMusic.getStatus() == Status.Playing) {
backgroundMusic.stop();
}
}
/**
* function to toggle the Background-music ,so if it was disabled it is now enabled and other way around
* function to toggle the Backgroundmusic also sets the volume to the previous session
*/
public void toggleMusic() {
this.backgroundMusicEnabled = !this.backgroundMusicEnabled;
if (backgroundMusicEnabled) {
public void toogleMusic() {
this.musicEnabled = !this.musicEnabled;
if (musicEnabled) {
play();
}
else {
} else {
stop();
}
prefs.putBoolean(BACKGROUND_MUSIC_ENABLED_PREV, backgroundMusicEnabled); //puts in new enabled to the pref
prefs.putFloat(VOLUME_PREF, volume);
}
/**
* this method sets the
*
* @param volume is the volume the music is set to
* Setter for the Volume also safes the volume from the previous session
* @param volume variable for the volume of the BackgroundMusic
*/
public void setBackgroundVolume(float volume) {
this.backgroundVolume = volume;
backgroundMusic.setVolume(backgroundVolume);
prefs.putFloat(VOLUME_PREV, volume);
public void setVolume(float volume) {
this.volume = volume;
backgroundMusic.setVolume(volume);
prefs.putFloat(VOLUME_PREF, volume);
}
/**
* this method returns the BackgroundVolume
*
* @return backgroundVolume
* Getter for Volume
* @return a float value of the volume
*/
public float getBackgroundVolume() {
return backgroundVolume;
public float getVolume() {
return volume;
}
/**
* return, if the background-music is enabled
*
* @return true if the music is enabled
* Getter for musicEnabled
* @return if the music is enabled return true, false otherwise
*/
public boolean isBackgroundMusicEnabled() {
return backgroundMusicEnabled;
public boolean isMusicEnabled() {
return musicEnabled;
}
}
}

View File

@@ -121,9 +121,8 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
* Listener for handling actions triggered by the Escape key.
*/
private final ActionListener escapeListener = (name, isPressed, tpf) -> escape(isPressed);
/**
* this is the object, responsible for the background-music and to control it
*
*/
private BackgroundMusic backgroundMusic;
@@ -146,6 +145,7 @@ public class BattleshipApp extends SimpleApplication implements BattleshipClient
*/
public static void main(String[] args) {
new BattleshipApp().start();
}
/**
@@ -230,7 +230,7 @@ public void simpleInitApp() {
setupStates();
setupGui();
serverConnection.connect();
backgroundMusic = new BackgroundMusic(this, "Sound/Background/backgroundMusic.ogg"); //initialise backgroundMusic and sets the backgroundMusic-path
backgroundMusic = new BackgroundMusic(this, "Sound/Effects/BackgroundMusic/boss_battle_#2_metal_opening.wav");
}
/**
@@ -434,8 +434,8 @@ void errorDialog(String errorMessage) {
}
/**
* this method returns Background-Music
* @return background-music
* Getter for the BackgroundMusic
* @return the BackgroundMusic
*/
public BackgroundMusic getBackgroundMusic(){
return backgroundMusic;

View File

@@ -30,10 +30,11 @@ public class GameSound extends AbstractAppState implements GameEventListener {
private static final Logger LOGGER = System.getLogger(GameSound.class.getName());
private static final Preferences PREFERENCES = getPreferences(GameSound.class);
private static final String ENABLED_PREF = "enabled"; //NON-NLS
private AudioNode splashSound;
private AudioNode shipDestroyedSound;
private AudioNode explosionSound;
private AudioNode rocketSound;
private AudioNode missileLaunch;
/**
* Checks if sound is enabled in the preferences.
@@ -44,13 +45,6 @@ public static boolean enabledInPreferences() {
return PREFERENCES.getBoolean(ENABLED_PREF, true);
}
/**
* Toggles the game sound on or off.
*/
public void toggleSound() {
setEnabled(!isEnabled());
}
/**
* Sets the enabled state of this AppState.
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
@@ -78,7 +72,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
rocketSound = loadSound(app, "Sound/Effects/rocket-loop-99748.wav");
missileLaunch = loadSound(app, "Sound/Effects/missileLaunch.wav");
}
/**
@@ -100,6 +94,13 @@ private AudioNode loadSound(Application app, String name) {
return null;
}
/**
* Plays the missile launch sound effect.
*/
public void missileLaunch() {
missileLaunch.playInstance();
}
/**
* Plays the splash sound effect.
*/
@@ -125,8 +126,7 @@ public void shipDestroyed() {
}
/**
* when triggered, though a sound-event,it decides, which sound should be played
*
* Checks the according case for the soundeffect
* @param event the received event
*/
@Override
@@ -135,25 +135,7 @@ public void receivedEvent(SoundEvent event) {
case EXPLOSION -> explosion();
case SPLASH -> splash();
case DESTROYED_SHIP -> shipDestroyed();
case ROCKET -> rocket();
case ROCKET_STOP -> rocketStopped();
case MISSILE_LAUNCH -> missileLaunch();
}
}
/**
* this method plays the sound of the rocket
*/
private void rocket() {
if (isEnabled() && splashSound != null)
rocketSound.play();
}
/**
* this method stops the sound of the rocket
*/
private void rocketStopped() {
rocketSound.stop();
}
}

View File

@@ -9,14 +9,15 @@
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Checkbox;
import com.simsilica.lemur.DefaultRangedValueModel;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.Slider;
import com.simsilica.lemur.core.VersionedReference;
import com.simsilica.lemur.style.ElementId;
import pp.dialog.Dialog;
import pp.dialog.StateCheckboxModel;
import pp.dialog.TextInputDialog;
import com.simsilica.lemur.DefaultRangedValueModel;
import com.simsilica.lemur.Slider;
import com.simsilica.lemur.core.VersionedReference;
import java.io.File;
import java.io.IOException;
@@ -50,17 +51,17 @@ public Menu(BattleshipApp app) {
addChild(new Checkbox(lookup("menu.sound-enabled"),
new StateCheckboxModel(app, GameSound.class)));
//this sets the checkbox,to disable/enable the background-music
Checkbox backgroundMusicEnabled = new Checkbox(lookup("background.music.checkbox"));
backgroundMusicEnabled.setChecked(app.getBackgroundMusic().isBackgroundMusicEnabled());
backgroundMusicEnabled.addClickCommands(s -> app.getBackgroundMusic().toggleMusic());
addChild(backgroundMusicEnabled);
Checkbox musicToggle = new Checkbox(lookup("menu.music.toggle"));
musicToggle.setChecked(app.getBackgroundMusic().isMusicEnabled());
musicToggle.addClickCommands(s -> toggleMusic());
//this sets the volume-slider for the volume of the background-music
Slider volumeSlider = new Slider(lookup("background.music.volume"));
volumeSlider.setModel(new DefaultRangedValueModel(0.0, 2.0, app.getBackgroundMusic().getBackgroundVolume()));
addChild(musicToggle);
Slider volumeSlider = new Slider();
volumeSlider.setModel(new DefaultRangedValueModel(0.0 , 2.0, app.getBackgroundMusic().getVolume()));
volumeSlider.setDelta(0.1);
addChild(volumeSlider);
volumeRef = volumeSlider.getModel().createReference();
addChild(loadButton)
@@ -71,22 +72,36 @@ public Menu(BattleshipApp app) {
.addClickCommands(s -> ifTopDialog(this::close));
addChild(new Button(lookup("menu.quit")))
.addClickCommands(s -> ifTopDialog(app::closeApp));
update();
}
/**
* updates the background-volume
*
* @param tmp
* Updates the volume if there is a change and adjusts it accordingly.
* @param tmp unused time parameter
*/
@Override
public void update(float tmp) {
if (volumeRef.update()) {
app.getBackgroundMusic().setBackgroundVolume((float) (double) volumeRef.get()); //sets new background-volume
public void update(float tmp){
if(volumeRef.update()) {
double newVolume = volumeRef.get();
adjustVolume(newVolume);
}
}
/**
* Adjusts the background music volume to the specified value.
* @param newVolume the new volume level
*/
private void adjustVolume(double newVolume) {
app.getBackgroundMusic().setVolume((float) newVolume);
}
/**
* Toggles the background music on or off.
*/
private void toggleMusic(){
app.getBackgroundMusic().toogleMusic();
}
/**
* Updates the state of the load and save buttons based on the game logic.
*/

View File

@@ -7,13 +7,9 @@
package pp.battleship.client;
import com.simsilica.lemur.Checkbox;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.TextField;
import com.simsilica.lemur.*;
import com.simsilica.lemur.component.SpringGridLayout;
import pp.battleship.client.server.BattleshipLocalServer;
import pp.battleship.client.server.BattleshipLocalServer;
import pp.battleship.client.server.BattleshipServer;
import pp.dialog.Dialog;
import pp.dialog.DialogBuilder;
import pp.dialog.SimpleDialog;
@@ -40,7 +36,10 @@ class NetworkDialog extends SimpleDialog {
private int portNumber;
private Future<Object> connectionFuture;
private Dialog progressDialog;
private boolean localServer = false;
private BattleshipServer battleshipServer;
private boolean GUI = true;
private Container menu;
private boolean serverToggle = false;
/**
* Constructs a new NetworkDialog.
@@ -54,29 +53,64 @@ class NetworkDialog extends SimpleDialog {
host.setPreferredWidth(400f);
port.setSingleLine(true);
final BattleshipApp app = network.getApp();
final Container input = new Container(new SpringGridLayout());
input.addChild(new Label(lookup("host.name") + ": "));
input.addChild(host, 1);
input.addChild(new Label(lookup("port.number") + ": "));
input.addChild(port, 1);
this.menu = new Container();
menu();
addChild(menu);
}
/*
* this checkbox controls, whether it will connect to an existing server or create a separate server
*/
Checkbox localServerCb = new Checkbox(lookup("local.server"));
localServerCb.setChecked(false);
localServerCb.addClickCommands(s -> localServer = !localServer);
/**
* Main Menu creation
*/
private void menu() {
DialogBuilder.simple(app.getDialogManager())
.setTitle(lookup("server.dialog"))
.setExtension(d -> d.addChild(input))
.setOkButton(lookup("button.connect"), d -> connect())
.setNoButton(lookup("button.cancel"), app::closeApp)
.setOkClose(false)
.setNoClose(false)
.build(this);
addChild(localServerCb); // adds the checkbox to the network dialog at the bottom
Button connectGame = new Button("Multiplayer");
connectGame.addClickCommands(source -> serverConnectGUI());
Checkbox serverHost = new Checkbox("Host own Game");
serverHost.addClickCommands(source -> toggleServer());
menu.addChild(serverHost);
menu.addChild(connectGame);
}
/**
* Logic for the ServerGUI
*/
private void serverConnectGUI() {
LOGGER.log(Level.INFO, "Hosting Server...");
if (GUI) {
host.setSingleLine(true);
host.setPreferredWidth(400f);
port.setSingleLine(true);
final BattleshipApp app = network.getApp();
final Container input = new Container(new SpringGridLayout());
input.addChild(new Label(lookup("host.name") + ": "));
input.addChild(host, 1);
input.addChild(new Label(lookup("port.number") + ": "));
input.addChild(port, 1);
DialogBuilder.simple(app.getDialogManager())
.setTitle(lookup("server.dialog"))
.setExtension(d -> d.addChild(input))
.setOkButton(lookup("button.connect"), d -> connect())
.setOkClose(false)
.build(this);
GUI = false;
}
}
/**
* Connect to server if serverToggle is false hosts otherwise
*/
private void connect(){
if (serverToggle) {
hostServer();
} else {
connectServer();
}
}
/**
@@ -90,44 +124,47 @@ private void connectServer() {
portNumber = Integer.parseInt(port.getText());
openProgressDialog();
connectionFuture = network.getApp().getExecutor().submit(this::initNetwork);
}
catch (NumberFormatException e) {
} catch (NumberFormatException e) {
network.getApp().errorDialog(lookup("port.must.be.integer"));
}
}
/**
* connects to the server, creates one, if no server is up
* Checks if the Server is running or starts the Server and handles Exceptions *
*/
public void connect() {
if (localServer) {
startLocalServer(); //starts a local server
private void hostServer() {
if (battleshipServer == null) {
startServer(); // Starts the server in a new thread
try {
Thread.sleep(1000); // waits, to ensure, that the server in the separate Thread has enough time to start properly
}
catch (Exception e) {
Thread.sleep(1000); // Wait for the server to start
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, e.getMessage(), e);
}
connectServer(); // connects to the server, that was just created
}
else {
connectServer(); // connects to existing server, when the server si not running, or not started by one of the clients
}
// Proceed with connecting to the server
connectServer();
}
/**
*starts a local server, in another thread
* Toggle Method for Boolean
*/
private void startLocalServer() {
new Thread(() -> { //creates new Thread
private void toggleServer(){
serverToggle = !serverToggle;
}
/**
* Allows Client to Start a Server in a new Thread
*/
private void startServer() {
new Thread(() -> {
try {
BattleshipLocalServer battleshipLocalServer = new BattleshipLocalServer(Integer.parseInt(port.getText())); // creates local server, with the given port numbers
battleshipLocalServer.run(); // runs the local server
// Initialize and run the server
battleshipServer = new BattleshipServer();
battleshipServer.run(Integer.parseInt(port.getText()));
} catch (Exception e) {
LOGGER.log(Level.ERROR, e);
}
catch (Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
}
}).start(); // starts the thread
}).start();
}
/**
@@ -135,8 +172,8 @@ private void startLocalServer() {
*/
private void openProgressDialog() {
progressDialog = DialogBuilder.simple(network.getApp().getDialogManager())
.setText(lookup("label.connecting"))
.build();
.setText(lookup("label.connecting"))
.build();
progressDialog.open();
}
@@ -149,8 +186,7 @@ private Object initNetwork() {
try {
network.initNetwork(hostname, portNumber);
return null;
}
catch (Exception e) {
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@@ -165,11 +201,9 @@ public void update(float delta) {
try {
connectionFuture.get();
success();
}
catch (ExecutionException e) {
} catch (ExecutionException e) {
failure(e.getCause());
}
catch (InterruptedException e) {
} catch (InterruptedException e) {
LOGGER.log(Level.WARNING, "Interrupted!", e); //NON-NLS
Thread.currentThread().interrupt();
}

View File

@@ -0,0 +1,155 @@
package pp.battleship.client.gui;
import com.jme3.asset.AssetManager;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.control.AbstractControl;
import pp.battleship.client.BattleshipApp;
import pp.battleship.model.Shot;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
/**
* Manages the visual effects for impact events such as hits and misses.
*/
public class ImpactEffectManager {
private final AssetManager assetManager;
private static final Logger LOGGER = System.getLogger(ImpactEffectManager.class.getName());
private Material particleMaterial;
private BattleshipApp app;
/**
* Constructor to initialize the asset manager via the main application.
*
* @param app The main application instance.
*/
public ImpactEffectManager(BattleshipApp app) {
this.app = app;
this.assetManager = app.getAssetManager();
this.particleMaterial = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
}
/**
* Generates a visual effect for a hit at the specified position.
*
* @param battleshipNode The node where the effect should be attached.
* @param shot The details of the shot where the hit occurred.
*/
public void triggerHitEffect(Node battleshipNode, Shot shot) {
ParticleEmitter hitEffect = createParticleEmitter("HitEffect", 50, ColorRGBA.Orange, ColorRGBA.Red, 0.45f, 0.1f, 1f, 2f);
hitEffect.setLocalTranslation(shot.getY() + 0.5f, 0, shot.getX() + 0.5f);
LOGGER.log(Level.DEBUG, "Hit effect created at position: {0}", hitEffect.getLocalTranslation().toString());
// hitEffect.emitAllParticles();
hitEffect.addControl(new EffectCleanupControl(hitEffect));
app.getRootNode().attachChild(hitEffect);
}
/**
* Creates a visual effect for a missed shot at the specified location.
*
* @param shot The details of the missed shot.
* @return The particle emitter representing the miss effect.
*/
public ParticleEmitter triggerMissEffect(Shot shot) {
ParticleEmitter missEffect = createParticleEmitter("MissEffect", 50, ColorRGBA.Blue, ColorRGBA.Cyan, 0.3f, 0.05f, 0.5f, 1.5f);
missEffect.setLocalTranslation(shot.getY() + 0.5f, 0, shot.getX() + 0.5f);
missEffect.addControl(new EffectCleanupControl(missEffect));
return missEffect;
}
/**
* Helper method to create a particle emitter with predefined parameters.
*
* @param name The name of the particle emitter.
* @param count The number of particles to emit.
* @param startColor The initial color of the particles.
* @param endColor The final color of the particles.
* @param startSize The initial size of the particles.
* @param endSize The final size of the particles.
* @param lowLife The minimum lifetime of the particles.
* @param highLife The maximum lifetime of the particles.
* @return The configured ParticleEmitter instance.
*/
private ParticleEmitter createParticleEmitter(String name, int count, ColorRGBA startColor, ColorRGBA endColor, float startSize, float endSize, float lowLife, float highLife) {
ParticleEmitter emitter = new ParticleEmitter(name, Type.Triangle, count);
emitter.setNumParticles(0);
emitter.setMaterial(particleMaterial);
emitter.setImagesX(2);
emitter.setImagesY(2);
emitter.setStartColor(startColor);
emitter.setEndColor(endColor);
emitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0, 1, 0));
emitter.setStartSize(startSize);
emitter.setEndSize(endSize);
emitter.setGravity(0, -0.5f, 0);
emitter.setLowLife(lowLife);
emitter.setHighLife(highLife);
return emitter;
}
/**
* Custom control class to handle the cleanup of particle effects once they are no longer visible.
*/
private static class EffectCleanupControl extends AbstractControl {
private final ParticleEmitter emitter;
private float currentTime = 0;
private final float duration = 3.5f;
/**
* Constructor for managing cleanup of a standalone particle emitter.
*
* @param emitter The particle emitter to manage.
*/
public EffectCleanupControl(ParticleEmitter emitter) {
this.emitter = emitter;
}
/**
* Removes the emitter when all particles are no longer visible.
*
* @param tpf Time per frame.
*/
@Override
protected void controlUpdate(float tpf) {
currentTime += tpf;
if (currentTime <= duration) {
}
if (currentTime >= 1f && currentTime <= 1.1) {
//Start
emitter.setNumParticles(50);
emitter.setParticlesPerSec(50);
}
if (currentTime >= duration){
emitter.setParticlesPerSec(0);
}
if (currentTime >= duration+1f) {
//Ende
spatial.removeFromParent();
emitter.emitAllParticles();
}
}
/**
* No custom rendering needed; particle behavior is handled in controlUpdate.
* @param rm handles rendering, and ViewPort
* @param vp defines the view where the scene is displayed.
*/
@Override
protected void controlRender(com.jme3.renderer.RenderManager rm, com.jme3.renderer.ViewPort vp) {
// No rendering-specific behavior needed for this control.
}
}
}

View File

@@ -15,7 +15,6 @@
import pp.battleship.model.Shell;
import pp.battleship.model.Shot;
import pp.util.Position;
import java.lang.System.Logger;
/**
@@ -24,14 +23,13 @@
* whenever changes occur in the model.
*/
class MapViewSynchronizer extends ShipMapSynchronizer {
private static final Logger LOGGER = System.getLogger(MapViewSynchronizer.class.getName());
// Constants for rendering properties
private static final float SHIP_LINE_WIDTH = 6f;
private static final float SHOT_DEPTH = -2f;
private static final float SHIP_DEPTH = 0f;
private static final float INDENT = 4f;
private static final float SHELL_DEPTH = 8f;
private static final float SHELL_IN_GRID = 0.1f;
// Colors used for different visual elements
private static final ColorRGBA HIT_COLOR = ColorRGBA.Red;
@@ -71,9 +69,9 @@ public Spatial visit(Shot shot) {
// 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);
SHOT_DEPTH,
p2.getX() - p1.getX(), p2.getY() - p1.getY(),
color);
}
/**
@@ -116,34 +114,23 @@ public Spatial visit(Battleship ship) {
}
/**
* this method will create a representation of a shell in the map
*
* @param shell the Shell element to visit
* @return the node the representation is attached to
* Creates a visual representation (Spatial) for the given shell, attaching a control for its behavior.
* @param shell the shell to visit and visualize
* @return the constructed shell node (Spatial)
*/
@Override
public Spatial visit(Shell shell) {
LOGGER.log(Logger.Level.DEBUG, "Visiting {0}", shell);
final Node shellNode = new Node("shell");
final Position target = view.modelToView(shell.getX(), shell.getY());
final Position startPosition = view.modelToView(SHELL_IN_GRID, SHELL_IN_GRID);
shellNode.attachChild(createShell());
shellNode.setLocalTranslation(startPosition.getX(), startPosition.getY(), SHELL_DEPTH);
shellNode.scale(18f);
shellNode.addControl(new ShellMapControl(view.getApp(), target, shell));
final Position startPosition = view.modelToView(shell.getCurrentPosition().x,shell.getCurrentPosition().z);
shellNode.attachChild(view.getApp().getDraw().makeRectangle(startPosition.getX(),startPosition.getY(), SHELL_DEPTH, 30, 30, ColorRGBA.Black));
shellNode.addControl(new ShellControl(shell, this.view, shell.getLogic()));
return shellNode;
}
/**
* returns the red dot for the shell in the MapViewSynchronizer
*
* @return Spatial
*/
private Spatial createShell() {
return view.getApp().getDraw().makeFilledCircle(ColorRGBA.Red);
}
/**
* Creates a line geometry representing part of the ship's border.
*

View File

@@ -7,26 +7,17 @@
package pp.battleship.client.gui;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh.Type;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.ShadowMode;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Cylinder;
import pp.battleship.client.BattleshipApp;
import pp.battleship.model.Battleship;
import pp.battleship.model.Rotation;
import pp.battleship.model.Shell;
import pp.battleship.model.ShipMap;
import pp.battleship.model.Shot;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import pp.battleship.model.*;
import static java.util.Objects.requireNonNull;
import static pp.util.FloatMath.HALF_PI;
@@ -39,21 +30,22 @@
* logic for the sea map.
*/
class SeaSynchronizer extends ShipMapSynchronizer {
private static final Logger LOGGER = System.getLogger(SeaSynchronizer.class.getName());
private static final String UNSHADED = "Common/MatDefs/Misc/Unshaded.j3md"; //NON-NLS
private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o"; //NON-NLS
private static final String SUBMARINE = "Models/Submarine/submarine.j3o";
private static final String DESTROYER = "Models/Destroyer/10619_Battleship.j3o";
private static final String SMALL_SHIP = "Models/SmallShip/10634_SpeedBoat_v01_LOD3.obj";
private static final String PARTICLE = "Common/MatDefs/Misc/Particle.j3md";
private static final String KING_GEORGE_V_MODEL = "Models/KingGeorgeV/KingGeorgeV.j3o";//NON-NLS
private static final String DESTROYER = "Models/Destroyer/Destroyer.j3o";
private static final String FERRY = "Models/Ferry/13922_Staten_Island_Ferry_V1_l1.obj";
private static final String SMALL = "Models/Small/10634_SpeedBoat_v01_LOD3.obj";
private static final String BOMB = "Models/Bomb/BombGBU.j3o";
private static final String COLOR = "Color"; //NON-NLS
private static final String SHIP = "ship"; //NON-NLS
private static final String ROCKET = "Models/Rocket/rocket.j3o";
private static final String SHOT = "shot"; //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);
private final ShipMap map;
private final BattleshipApp app;
private ImpactEffectManager effectHandler;
/**
* Constructs a {@code SeaSynchronizer} object with the specified application, root node, and ship map.
@@ -66,6 +58,7 @@ public SeaSynchronizer(BattleshipApp app, Node root, ShipMap map) {
super(app.getGameLogic().getOwnMap(), root);
this.app = app;
this.map = map;
effectHandler = new ImpactEffectManager(app);
addExisting();
}
@@ -79,20 +72,7 @@ public SeaSynchronizer(BattleshipApp app, Node root, ShipMap map) {
*/
@Override
public Spatial visit(Shot shot) {
return shot.isHit() ? handleHit(shot) : handleMiss(shot);
}
/**
* Handles a miss
*
* @param shot a hit
* @return always null to prevent the representation from being attached
* to the items node as well
*/
private Spatial handleMiss(Shot shot) {
final ParticleEmitter emitter = createMissParticle(shot);
return emitter;
return shot.isHit() ? handleHit(shot) : effectHandler.triggerMissEffect(shot);
}
/**
@@ -106,112 +86,33 @@ private Spatial handleMiss(Shot shot) {
private Spatial handleHit(Shot shot) {
final Battleship ship = requireNonNull(map.findShipAt(shot), "Missing ship");
final Node shipNode = requireNonNull((Node) getSpatial(ship), "Missing ship node");
final ParticleEmitter particleEmitter = createHitParticle(shot);
particleEmitter.getLocalTranslation().subtractLocal(shipNode.getLocalTranslation());
shipNode.attachChild(particleEmitter);
final ParticleEmitter fire = createFire(shot);
shipNode.attachChild(fire);
System.out.println(shot.getX() + " " + shot.getY());
effectHandler.triggerHitEffect(shipNode, shot);
return null;
}
/**
* this method attach fire to the ship, if it is hit
* Creates a cylinder geometry representing the specified shot.
* The appearance of the cylinder depends on whether the shot is a hit or a miss.
*
* @param shot the shot, that hit the ship
* @return the Fire
* @param shot the shot to be represented
* @return the geometry representing the shot
*/
private ParticleEmitter createFire(Shot shot) {
ParticleEmitter hitEffect = new ParticleEmitter("fire", Type.Triangle, 5000);
hitEffect.setMaterial(new Material(app.getAssetManager(), PARTICLE));
hitEffect.setImagesX(2);
hitEffect.setImagesY(2);
hitEffect.setStartColor(ColorRGBA.Orange);
hitEffect.setEndColor(ColorRGBA.Red);
hitEffect.setStartSize(0.1f);
hitEffect.setEndSize(0.05f);
hitEffect.getParticleInfluencer().setInitialVelocity(new Vector3f(0,1,0));
hitEffect.setParticlesPerSec(5);
hitEffect.setLowLife(1f);
hitEffect.setHighLife(1f);
final Node shipNode = requireNonNull((Node) getSpatial(map.findShipAt(shot.getX(), shot.getY())), "Missing ship node");
hitEffect.setGravity(0, -0.9f, 0);
Vector3f shipNodePos = shipNode.getLocalTranslation();
Vector3f shotWorld = mapToWorldCord(shot.getX(), shot.getY());
Vector3f firePos = shotWorld.subtract(shipNodePos);
if (map.findShipAt(shot.getX(), shot.getY()).getLength() == 2) {
hitEffect.setLocalTranslation(firePos.x, 0.15f, firePos.z);
} else {
hitEffect.setLocalTranslation(firePos.x, 0.3f, firePos.z);
}
return hitEffect;
}
private Geometry createCylinder(Shot shot) {
final ColorRGBA color = shot.isHit() ? HIT_COLOR : SPLASH_COLOR;
final float height = shot.isHit() ? 1.2f : 0.1f;
/**
* this method converts 2d to 3d positions
*
* @param x x-Coordinate
* @param y-Coordinate
* @return the Position as a 3d Vector
*/
final Cylinder cylinder = new Cylinder(2, 20, 0.45f, height, true);
final Geometry geometry = new Geometry(SHOT, cylinder);
private Vector3f mapToWorldCord(int x, int y) {
return new Vector3f(y + 0.5f, 0, x + 0.5f);
}
geometry.setMaterial(createColoredMaterial(color));
geometry.rotate(HALF_PI, 0f, 0f);
/**
* this method creates the particles, when the shot misses
*
* @param shot is the parameter, where was shot
* @return the particle
*/
geometry.setLocalTranslation(shot.getY() + 0.5f, 0f, shot.getX() + 0.5f);
private ParticleEmitter createMissParticle(Shot shot) {
ParticleEmitter hitEffect = new ParticleEmitter("HitEffect", Type.Triangle, 30);
hitEffect.setMaterial(new Material(app.getAssetManager(), PARTICLE));
hitEffect.setImagesX(2);
hitEffect.setImagesY(2);
hitEffect.setStartColor(ColorRGBA.Cyan);
hitEffect.setEndColor(ColorRGBA.Blue);
hitEffect.getParticleInfluencer().setInitialVelocity(new Vector3f(0.1f, 0.1f, 0.1f));
hitEffect.move(0, -2, 0);
hitEffect.setStartSize(0.45f);
hitEffect.setEndSize(0.45f);
hitEffect.setGravity(0, -0.5f, 0);
hitEffect.setLowLife(1f);
hitEffect.setHighLife(1f);
hitEffect.setParticlesPerSec(0);
hitEffect.setLocalTranslation(shot.getY() + 0.5f, 0, shot.getX() + 0.5f);
hitEffect.emitAllParticles();
return hitEffect;
}
/**
* this method creates the particles, when a ship is hit
*
* @param shot says, where was shot
* @return the particle
*/
private ParticleEmitter createHitParticle(Shot shot) {
ParticleEmitter hitEffect = new ParticleEmitter("HitEffect", Type.Triangle, 30);
hitEffect.setMaterial(new Material(app.getAssetManager(), PARTICLE));
hitEffect.setImagesX(2);
hitEffect.setImagesY(2);
hitEffect.setStartColor(ColorRGBA.Orange);
hitEffect.setEndColor(ColorRGBA.Red);
hitEffect.getParticleInfluencer().setInitialVelocity(new Vector3f(1, 1, 1));
hitEffect.setStartSize(0.45f);
hitEffect.setEndSize(0.1f);
hitEffect.setGravity(0, -0.5f, 0);
hitEffect.setLowLife(1f);
hitEffect.setHighLife(2f);
hitEffect.setParticlesPerSec(0);
hitEffect.setLocalTranslation(shot.getY() + 0.5f, 0, shot.getX() + 0.5f);
hitEffect.emitAllParticles();
return hitEffect;
return geometry;
}
/**
@@ -230,58 +131,46 @@ public Spatial visit(Battleship ship) {
final float x = 0.5f * (ship.getMinY() + ship.getMaxY() + 1f);
final float z = 0.5f * (ship.getMinX() + ship.getMaxX() + 1f);
node.setLocalTranslation(x, 0f, z);
node.addControl(new ShipControl(ship, map));
node.addControl(new ShipControl(ship));
return node;
}
/**
* Visits a {@link Shell} and creates a graphical representation of it.
* The representation is a 3D model
*
* @param shell the shell to be represented
* @return the node containing the graphical representation of the shell
*/
@Override
public Spatial visit(Shell shell) {
LOGGER.log(Level.INFO, "was visited by SeaSynchronizer");
final Node node = new Node("Shell");
node.attachChild(createShell());
node.setLocalTranslation(shell.getY() + 0.5f, 10, shell.getX() + 0.5f);
node.addControl(new ShellControl(shell, app));
return node;
}
final Spatial bombModel = app.getAssetManager().loadModel(BOMB);
/**
* this method loads the Model
*
* @return model
*/
private Spatial createShell() {
LOGGER.log(Level.INFO, "created Shell");
final Spatial model = app.getAssetManager().loadModel(ROCKET);
model.rotate(PI, PI, 0);
model.scale(0.0002f);
model.move(0, 0, 0);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
// Apply transformations to the bomb model (scale, rotate, etc. if needed)
bombModel.scale(0.05f);
bombModel.rotate(-HALF_PI, 0f, 0f);
// Set the position of the bomb at the shell's current position
bombModel.setLocalTranslation(shell.getCurrentPosition());
// Add a control to animate the bomb's movement (similar to the previous cylinder animation)
bombModel.addControl(new ShellControl(shell,shell.getLogic()));
return bombModel;
}
/**
* 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.
* The representation is a detailed model based on the length of the ship.
*
* @param ship the battleship to be represented
* @return the spatial representing the battleship
*/
private Spatial createShip(Battleship ship) {
//return ship.getLength() == 4 ? createBattleship(ship) : createBox(ship);
return switch (ship.getLength()) {
case (1) -> createSmallShip(ship);
case (2) -> createSubmarine(ship);
case (3) -> createDestroyer(ship);
case (4) -> createBattleship(ship);
default -> createBox(ship);
};
// return ship.getLength() == 4 ? createBattleship(ship) : createBox(ship);
if (ship.getLength() == 4) {
return createBattleship(ship);
} else if (ship.getLength() == 3) {
return createBigShip(ship);
} else if (ship.getLength() == 2) {
return createMediumShip(ship);
} else if (ship.getLength() == 1) {
return createSmallShip(ship);
}
return createBattleship(ship);
}
/**
@@ -292,8 +181,8 @@ private Spatial createShip(Battleship ship) {
*/
private Spatial createBox(Battleship ship) {
final Box box = new Box(0.5f * (ship.getMaxY() - ship.getMinY()) + 0.3f,
0.3f,
0.5f * (ship.getMaxX() - ship.getMinX()) + 0.3f);
0.3f,
0.5f * (ship.getMaxX() - ship.getMinX()) + 0.3f);
final Geometry geometry = new Geometry(SHIP, box);
geometry.setMaterial(createColoredMaterial(BOX_COLOR));
geometry.setShadowMode(ShadowMode.CastAndReceive);
@@ -301,54 +190,6 @@ private Spatial createBox(Battleship ship) {
return geometry;
}
/**
* Creates a Destroyer to represent a battleship that has the length of 3.
*
* @param ship the battleship to be represented
* @return the model representing the battleship
*/
private Spatial createDestroyer(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(DESTROYER);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) - HALF_PI, 0f);
model.scale(0.0001f);
model.move(0, 0.3f, 0);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Creates a Submarine to represent a battleship that has the length 2.
*
* @param ship the battleship to be represented
* @return the model representing the battleship
*/
private Spatial createSubmarine(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(SUBMARINE);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
model.scale(0.25f);
model.move(0, -0.2f, 0);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Creates a SmallShip to represent a battleship that has the length y.
*
* @param ship the battleship to be represented
* @return the model representing the battleship
*/
private Spatial createSmallShip(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(SMALL_SHIP);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) + HALF_PI, 0f);
model.scale(0.001f);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Creates a new {@link Material} with the specified color.
* If the color includes transparency (i.e., alpha value less than 1),
@@ -384,6 +225,53 @@ private Spatial createBattleship(Battleship ship) {
return model;
}
/**
* Creates a detailed 3D model to represent a "Big Ship"
* @param ship The Battleship object with position and rotation info.
* @return the spatial representing the "Big Ship" battleship
*/
private Spatial createBigShip(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(DESTROYER);
model.move(0,0.4f,0);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) + HALF_PI, 0f);
model.scale(0.0001f);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Creates a detailed 3D model to represent a "Medium Ship"
* @param ship The Battleship object with position and rotation info.
* @return the spatial representing the "Medium Ship" battleship
*/
private Spatial createMediumShip(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(FERRY);
model.move(0,0.25f,0);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()), 0f);
model.scale(0.00025f);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Creates a detailed 3D model to represent a "Small Ship"
* @param ship The Battleship object with position and rotation info.
* @return the spatial representing the "Small Ship" battleship
*/
private Spatial createSmallShip(Battleship ship) {
final Spatial model = app.getAssetManager().loadModel(SMALL);
model.rotate(-HALF_PI, calculateRotationAngle(ship.getRot()) + HALF_PI, 0f);
model.scale(0.0009f);
model.setShadowMode(ShadowMode.CastAndReceive);
return model;
}
/**
* Calculates the rotation angle for the specified rotation.
*

View File

@@ -1,68 +1,96 @@
////////////////////////////////////////
// Programming project code
// UniBw M, 2022, 2023, 2024
// www.unibw.de/inf2
// (c) Mark Minas (mark.minas@unibw.de)
////////////////////////////////////////
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.AnimationEndMessage;
import pp.battleship.model.IntPoint;
import pp.battleship.game.client.ClientGameLogic;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.model.Shell;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import pp.battleship.notification.Sound;
import pp.util.Position;
/**
* this class controls the Shell in the view
* Controls the oscillating pitch motion of a battleship model in the game.
* The ship oscillates to simulate a realistic movement on water, based on its orientation and length.
*/
public class ShellControl extends AbstractControl {
class ShellControl extends AbstractControl {
private static final Logger LOGGER = System.getLogger(ShellControl.class.getName());
private final Shell shell;
private MapView view;
private final ClientGameLogic logic;
private final EffectMessage msg;
private boolean hasPlayedSound = false;
/**
* the shell, that is displayed
*/
private Shell shell;
/**
* the Height, when the shell will despawn
*/
private static final Float HEIGHT = 0f;
/**
* the battleship app
*/
private BattleshipApp app;
/**
* the constructor for this class
* Constructs a new ShipControl instance for the specified Battleship.
* The ship's orientation determines the axis of rotation, while its length influences
* the cycle duration and amplitude of the oscillation.
*
* @param shell the shell it displays
* @param app the BattleshipApp
* @param shell the Battleship object to control
*/
public ShellControl(Shell shell, BattleshipApp app) {
LOGGER.log(Level.INFO, "ShellControl has been initialized");
public ShellControl(Shell shell, ClientGameLogic clientGameLogic) {
this.shell = shell;
this.app = app;
this.logic = clientGameLogic;
this.msg = shell.getMsg();
}
/**
* this method controls the movement of the shell in dependent on fpt
* Initializes ShellControl with a shell, map view, and game logic.
* @param shell the shell to be controlled
* @param view the map view to display the shell
* @param clientGameLogic the game logic instance
*/
public ShellControl(Shell shell, MapView view, ClientGameLogic clientGameLogic) {
this.shell = shell;
this.view = view;
this.logic = clientGameLogic;
this.msg = shell.getMsg();
}
/**
* Updates the ship's pitch oscillation each frame. The ship's pitch is adjusted
* to create a continuous tilting motion, simulating the effect of waves.
*
* @param tpf time per frame (in seconds)
* @param tpf time per frame (in seconds), used to calculate the new pitch angle
*/
@Override
protected void controlUpdate(float tpf) {
if (spatial == null) return;
if (spatial.getLocalTranslation().getY() <= HEIGHT) {
spatial.getParent().detachChild(spatial);
app.getGameLogic().send(new AnimationEndMessage(new IntPoint(shell.getX(), shell.getY())));
if (spatial == null)
return;
if (shell.isFinished() && !hasPlayedSound) {
if (!msg.getShot().isHit())
logic.playSound(Sound.SPLASH);
else if (msg.getDestroyedShip() == null)
logic.playSound(Sound.EXPLOSION);
else
logic.playSound(Sound.DESTROYED_SHIP);
hasPlayedSound = true;
}
if (view == null) {
shell.updatePosition(tpf);
spatial.setLocalTranslation(shell.getCurrentPosition());
} else {
spatial.move(0, -1 * 4f * tpf, 0);
shell.updatePosition(tpf);
Position pos2d = view.modelToView(shell.getCurrentPosition().x - 0.3f, shell.getCurrentPosition().z - 0.3f);
spatial.setLocalTranslation(pos2d.getY(), pos2d.getX(), 0);
}
}
/**
* Called during rendering, but no operations are needed as this control only affects spatial transformation.
* @param rm the RenderManager rendering the spatial
* @param vp the ViewPort being rendered
*/
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
//not in use
// No rendering logic is needed for this control
}
}

View File

@@ -1,77 +0,0 @@
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.AnimationEndMessage;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shell;
import pp.battleship.notification.Sound;
import pp.util.Position;
/**
* this class controls the behaviour of a shell in a 2d map
*/
public class ShellMapControl extends AbstractControl {
private static final System.Logger LOGGER = System.getLogger(ShellMapControl.class.getName());
/**
* the position in map-coordinates
*/
private final Position position;
/**
* the vector, the shell is going on the 2d screen
*/
private static final Vector3f vector = new Vector3f();
/**
* the battleship app
*/
private final BattleshipApp app;
/**
* the shell displayed
*/
private final Shell shell;
/**
* the constructor for this class
*
* @param app the Battleship app
* @param position the position shot at in map-coordinates
* @param shell the shell shot
*/
public ShellMapControl(BattleshipApp app, Position position, Shell shell) {
super();
this.position = position;
this.app = app;
this.shell = shell;
vector.set(new Vector3f(position.getX(), position.getY(), 0));
}
/**
* the update loop for this shell
*
* @param tpf time per frame (in seconds)
*/
protected void controlUpdate(float tpf) {
if (spatial.getLocalTranslation().getX() >= position.getX() && spatial.getLocalTranslation().getY() >= position.getY()) {
app.getGameLogic().playSound(Sound.ROCKET_STOP);
spatial.getParent().detachChild(spatial);
app.getGameLogic().send(new AnimationEndMessage(new IntPoint(shell.getX(), shell.getY())));
LOGGER.log(System.Logger.Level.DEBUG, "shell has been deleted", spatial.getLocalTranslation());
} else {
spatial.move(vector.mult(tpf));
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
}
}

View File

@@ -11,13 +11,13 @@
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import pp.battleship.model.Battleship;
import pp.battleship.model.ShipMap;
import static java.util.Objects.requireNonNull;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import static pp.util.FloatMath.DEG_TO_RAD;
import static pp.util.FloatMath.TWO_PI;
import static pp.util.FloatMath.sin;
@@ -51,18 +51,14 @@ class ShipControl extends AbstractControl {
* The current time within the oscillation cycle, used to calculate the ship's pitch angle.
*/
private float time;
/**
* this attribute is the ship, this ShipControl controls
* The current Ship
*/
private final Battleship ship;
private final Battleship battleship;
/**
* this CONST represents the sinking height, when the ship will be removed
* Logger for logging messages related to ShipControl operations.
*/
private static final Float SINKING_HEIGHT = -0.6f;
static final Logger LOGGER = System.getLogger(ShipControl.class.getName());
/**
* Constructs a new ShipControl instance for the specified Battleship.
@@ -71,7 +67,8 @@ class ShipControl extends AbstractControl {
*
* @param ship the Battleship object to control
*/
public ShipControl(Battleship ship, ShipMap map) {
public ShipControl(Battleship ship) {
battleship = ship;
// Determine the axis of rotation based on the ship's orientation
axis = switch (ship.getRot()) {
case LEFT, RIGHT -> Vector3f.UNIT_X;
@@ -79,9 +76,8 @@ public ShipControl(Battleship ship, ShipMap map) {
};
// Set the cycle duration and amplitude based on the ship's length
cycle = ship.getLength() * 2f;
cycle = battleship.getLength() * 2f;
amplitude = 5f * DEG_TO_RAD / ship.getLength();
this.ship = ship;
}
/**
@@ -94,28 +90,24 @@ public ShipControl(Battleship ship, ShipMap map) {
protected void controlUpdate(float tpf) {
// If spatial is null, do nothing
if (spatial == null) return;
if(ship.isDestroyed()){
if(spatial.getLocalTranslation().getY() < SINKING_HEIGHT) { // removes the ship, if it is completely sunk
spatial.getParent().detachChild(spatial);
}
else // sink the ship, if it's not completely sunk
spatial.move(0, tpf * 0.1f * -1, 0);
}
// Update the time within the oscillation cycle
time = (time + tpf) % cycle;
if (battleship.isDestroyed() && spatial.getLocalTranslation().getY() <= -0.6f) {
LOGGER.log(Level.INFO, "Ship removed {0}", spatial.getName());
spatial.getParent().detachChild(spatial);
} else if (battleship.isDestroyed()) {
spatial.move(0, -0.05f * tpf, 0);
} else {
// Update the time within the oscillation cycle
time = (time + tpf) % cycle;
// Calculate the current angle of the oscillation
final float angle = amplitude * sin(time * TWO_PI / cycle);
// Apply the pitch rotation to the spatial
spatial.setLocalRotation(pitch);
}
// Update the pitch Quaternion with the new angle
pitch.fromAngleAxis(angle, axis);
// Apply the pitch rotation to the spatial
spatial.setLocalRotation(pitch);
}
/**

View File

@@ -84,7 +84,6 @@ public void receivedEvent(ItemRemovedEvent event) {
@Override
public void receivedEvent(ItemAddedEvent event) {
if (shipMap == event.map())
add(event.item());
}
}

View File

@@ -7,22 +7,19 @@
package pp.battleship.client.server;
import com.jme3.network.ConnectionListener;
import com.jme3.network.HostedConnection;
import com.jme3.network.Message;
import com.jme3.network.MessageListener;
import com.jme3.network.Network;
import com.jme3.network.Server;
import com.jme3.network.*;
import com.jme3.network.serializing.Serializer;
import pp.battleship.BattleshipConfig;
import pp.battleship.game.server.Player;
import pp.battleship.game.server.ServerGameLogic;
import pp.battleship.game.server.ServerSender;
import pp.battleship.message.client.AnimationEndMessage;
import pp.battleship.message.client.ClientMessage;
import pp.battleship.message.client.MapMessage;
import pp.battleship.message.client.ShootMessage;
import pp.battleship.message.server.*;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.ServerMessage;
import pp.battleship.message.server.StartBattleMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shot;
@@ -39,12 +36,11 @@
/**
* Server implementing the visitor pattern as MessageReceiver for ClientMessages
*/
public class BattleshipLocalServer implements MessageListener<HostedConnection>, ConnectionListener, ServerSender {
private static final Logger LOGGER = System.getLogger(BattleshipLocalServer.class.getName());
public class BattleshipServer implements MessageListener<HostedConnection>, ConnectionListener, ServerSender {
private static final Logger LOGGER = System.getLogger(BattleshipServer.class.getName());
private static final File CONFIG_FILE = new File("server.properties");
private final BattleshipConfig config = new BattleshipConfig();
private Server myServer;
private static int PORT_NUMBER;
private final ServerGameLogic logic;
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
@@ -60,31 +56,35 @@ public class BattleshipLocalServer implements MessageListener<HostedConnection>,
}
}
/**
* this constructs the local battleship server
*
* @param portNumber the port number, the local-host should be accessed at
* Creates the server.
*/
public BattleshipLocalServer(int portNumber) {
public BattleshipServer() {
BattleshipConfig config = new BattleshipConfig();
config.readFromIfExists(CONFIG_FILE);
PORT_NUMBER = portNumber;
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
logic = new ServerGameLogic(this, config);
}
public void run() {
startServer();
/**
* Starts the server on the given port and continuously processes incoming messages.
* @param port the port to start the server on
*/
public void run(int port) {
startServer(port);
while (true)
processNextMessage();
}
/**
* this method is used to start a server
* Initializes and starts the server on the specified port, handling exceptions if the server fails to start.
* @param port the port to start the server on
*/
private void startServer() {
private void startServer(int port) {
try {
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
myServer = Network.createServer(PORT_NUMBER); // creates new server, with the port given before
myServer = Network.createServer(port);
initializeSerializables();
myServer.start();
registerListeners();
@@ -96,6 +96,9 @@ private void startServer() {
}
}
/**
* Retrieves and processes the next message from the queue, handling interruptions during the wait.
*/
private void processNextMessage() {
try {
pendingMessages.take().process(logic);
@@ -106,6 +109,9 @@ private void processNextMessage() {
}
}
/**
* Processes the next message from the queue, handling interruptions during message retrieval.
*/
private void initializeSerializables() {
Serializer.registerClass(GameDetails.class);
Serializer.registerClass(StartBattleMessage.class);
@@ -115,18 +121,22 @@ private void initializeSerializables() {
Serializer.registerClass(Battleship.class);
Serializer.registerClass(IntPoint.class);
Serializer.registerClass(Shot.class);
Serializer.registerClass(AnimationEndMessage.class);
Serializer.registerClass(AnimationStartMessage.class);
Serializer.registerClass(BackToBattleStateMessage.class);
}
/**
* Registers message and connection listeners for the server.
*/
private void registerListeners() {
myServer.addMessageListener(this, MapMessage.class);
myServer.addMessageListener(this, ShootMessage.class);
myServer.addMessageListener(this, AnimationEndMessage.class);
myServer.addConnectionListener(this);
}
/**
* Handles received messages, logging the source and adding client messages to the pending queue.
* @param source the connection the message was received from
* @param message the received message
*/
@Override
public void messageReceived(HostedConnection source, Message message) {
LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS
@@ -134,12 +144,22 @@ public void messageReceived(HostedConnection source, Message message) {
pendingMessages.add(new ReceivedMessage(clientMessage, source.getId()));
}
/**
* Handles a new connection by logging it and adding a new player to the game logic.
* @param server the server receiving the connection
* @param hostedConnection the newly added connection
*/
@Override
public void connectionAdded(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
logic.addPlayer(hostedConnection.getId());
}
/**
* Handles the removal of a connection by logging it, checking if it belongs to an active player, and exiting if necessary.
* @param server the server losing the connection
* @param hostedConnection the removed connection
*/
@Override
public void connectionRemoved(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS
@@ -152,6 +172,10 @@ public void connectionRemoved(Server server, HostedConnection hostedConnection)
}
}
/**
* Closes all client connections and terminates the server with the given exit value.
* @param exitValue the exit code to terminate the application with
*/
private void exit(int exitValue) { //NON-NLS
LOGGER.log(Level.INFO, "close request"); //NON-NLS
if (myServer != null)

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
# Blender MTL File: 'untitletttd.blend'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
map_Kd C:\Users\Convidado.Cliente-JMF-PC\Desktop\ghftht.png

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
based on:
https://free3d.com/3d-model/battleship-v1--611736.html
License: Free Personal Use Only

View File

@@ -1,3 +0,0 @@
This model is from the following website:
https://free3d.com/3d-model/battleship-v1--611736.html
License: Free Personal Use Only

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,64 @@
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 13.03.2012 15:35:28
newmtl metall
Ns 31.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.2431 0.2431 0.2431
Kd 0.2431 0.2431 0.2431
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
newmtl 13922_StatenIslandFerry
Ns 50.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
map_Ka 13922_StatenIslandFerry_diffuse.jpg
map_Kd 13922_StatenIslandFerry_diffuse.jpg
newmtl metall2
Ns 50.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.2118 0.2824 0.3451
Kd 0.2118 0.2824 0.3451
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
newmtl boat
Ns 34.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.6588 0.3059 0.1294
Kd 0.6588 0.3059 0.1294
Ks 0.3600 0.3600 0.3600
Ke 0.0000 0.0000 0.0000
newmtl white
Ns 10.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.9686 0.9686 0.9686
Kd 0.9686 0.9686 0.9686
Ks 0.0000 0.0000 0.0000
Ke 0.0000 0.0000 0.0000

View File

@@ -0,0 +1,3 @@
based on:
https://free3d.com/3d-model/statenislandferry-v1--603882.html
License: Free Personal Use Only

View File

@@ -1,3 +0,0 @@
Rocket origin:
https://free3d.com/3d-model/proton-rocket-31617.html
Licence: free for personal use

View File

@@ -0,0 +1,3 @@
based on:
https://free3d.com/3d-model/speedboat-v01--840133.html
License: Free Personal Use Only

View File

@@ -1,3 +0,0 @@
This model is from following website:
https://free3d.com/3d-model/speedboat-v01--840133.html
License: Free Personal Use Only

View File

@@ -1,3 +0,0 @@
This model is from the following website:
https://free3d.com/3d-model/wwii-ship-german-type-ii-uboat-v2--700733.html
License: Free Personal Use Only

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -1,16 +0,0 @@
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 29.03.2012 14:25:39
newmtl default
Ns 35.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.5400 0.5400 0.5400
Ke 0.0000 0.0000 0.0000
map_Ka 14084_WWII_ship_German_Type_II_U-boat_diff.jpg
map_Kd 14084_WWII_ship_German_Type_II_U-boat_diff.jpg

View File

@@ -1,3 +0,0 @@
The soundtrack for the background-music is from:
https://pixabay.com/music/future-bass-nightfall-future-bass-music-228100/
the soundtrack is free to use

View File

@@ -1,3 +0,0 @@
RocketSound origin:
https://pixabay.com/sound-effects/rocket-loop-99748/
Licence: free to use

Binary file not shown.

View File

@@ -41,7 +41,7 @@ public static void main(String[] args) {
*/
@Override
public void simpleInitApp() {
export("Models/KingGeorgeV/rocket/proton.obj", "proton.j3o"); //NON-NLS
export("Models/Destroyer/10619_Battleship.obj", "Destroyer.j3o"); //NON-NLS
stop();
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
# Blender MTL File: 'untitletttd.blend'
# Material Count: 1
newmtl None
Ns 0
Ka 0.000000 0.000000 0.000000
Kd 0.8 0.8 0.8
Ks 0.8 0.8 0.8
d 1
illum 2
map_Kd C:\Users\Convidado.Cliente-JMF-PC\Desktop\ghftht.png

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,73 @@
newmtl Battleship
illum 4
Kd 0.00 0.00 0.00
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
map_Kd BattleshipC.jpg
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn1SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn2SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.00 0.00 0.00
Ns 256.00
newmtl blinn3SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn4SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn5SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn6SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn7SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00
newmtl blinn8SG
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
Ks 0.50 0.50 0.50
Ns 256.00

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 KiB

View File

@@ -0,0 +1,3 @@
based on:
https://free3d.com/3d-model/battleship-v1--611736.html
License: Free Personal Use Only

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,64 @@
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 13.03.2012 15:35:28
newmtl metall
Ns 31.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.2431 0.2431 0.2431
Kd 0.2431 0.2431 0.2431
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
newmtl 13922_StatenIslandFerry
Ns 50.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 1.0000 1.0000 1.0000
Kd 1.0000 1.0000 1.0000
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
map_Ka 13922_StatenIslandFerry_diffuse.jpg
map_Kd 13922_StatenIslandFerry_diffuse.jpg
newmtl metall2
Ns 50.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.2118 0.2824 0.3451
Kd 0.2118 0.2824 0.3451
Ks 0.5850 0.5850 0.5850
Ke 0.0000 0.0000 0.0000
newmtl boat
Ns 34.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.6588 0.3059 0.1294
Kd 0.6588 0.3059 0.1294
Ks 0.3600 0.3600 0.3600
Ke 0.0000 0.0000 0.0000
newmtl white
Ns 10.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.9686 0.9686 0.9686
Kd 0.9686 0.9686 0.9686
Ks 0.0000 0.0000 0.0000
Ke 0.0000 0.0000 0.0000

View File

@@ -1,116 +0,0 @@
package pp.battleship.game.client;
import pp.battleship.message.client.AnimationEndMessage;
import pp.battleship.message.server.AnimationStartMessage;
import pp.battleship.message.server.BackToBattleStateMessage;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shell;
import pp.battleship.model.ShipMap;
import pp.battleship.notification.Sound;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
public class AnimationState extends ClientState {
private static final Logger LOGGER = System.getLogger(AnimationState.class.getName());
/**
* Constructs a client state of the specified game logic.
*
* @param logic the game logic
*/
AnimationState(ClientGameLogic logic, boolean myTurn, IntPoint pos) {
super(logic);
if (myTurn) {
logic.getOpponentMap().add(new Shell(pos));
logic.playSound(Sound.ROCKET);
} else {
logic.getOwnMap().add(new Shell(pos));
logic.playSound(Sound.ROCKET);
}
}
@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) {
logic.playSound(Sound.ROCKET_STOP);
ClientGameLogic.LOGGER.log(Level.INFO, "report effect: {0}", msg); //NON-NLS
playSound(msg);
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));
}
}
/**
* 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();
}
/**
* receives an AnimationStartMessage and sets the state to AnimationState
*
* @param msg the message received
*/
public void receivedAnimationStart(AnimationStartMessage msg) {
logic.setState(new AnimationState(logic, msg.isMyTurn(), msg.getPosition()));
}
/**
* 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);
}
/**
* receives a BackToBattleStateMessage and sets the state to BattleState
*
* @param msg the message received
*/
@Override
public void receiveBackToBattleState(BackToBattleStateMessage msg) {
logic.setState(new BattleState(logic, msg.isMyTurn()));
}
}

View File

@@ -7,9 +7,15 @@
package pp.battleship.game.client;
import com.jme3.math.Vector3f;
import pp.battleship.message.client.ShootMessage;
import pp.battleship.message.server.AnimationStartMessage;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shell;
import pp.battleship.model.ShipMap;
import pp.battleship.notification.Sound;
import java.lang.System.Logger.Level;
/**
* Represents the state of the client where players take turns to attack each other's ships.
@@ -29,9 +35,8 @@ public BattleState(ClientGameLogic logic, boolean myTurn) {
}
/**
* this return-statement decides, whether the battle will be shown
*
* @return true, so the battle will be displayed
* displays the battle scene.
* @return true to show the battle
*/
@Override
public boolean showBattle() {
@@ -39,9 +44,8 @@ public boolean showBattle() {
}
/**
* the logic, responsible for deciding, whether it was a valid input or not
*
* @param pos the position where the click occurred
* Handles clicking on the opponent's map. If it's the player's turn and the position is valid, a ShootMessage is sent.
* @param pos the clicked position on the opponent's map
*/
@Override
public void clickOpponentMap(IntPoint pos) {
@@ -52,13 +56,43 @@ else if (logic.getOpponentMap().isValid(pos))
}
/**
* Receives an AnimationStartEvent and changes then the client-state to AnimationState
* Reports the effect of a shot based on the server message.
*
* @param msg the message received
* @param msg the message containing the effect of the shot
*/
@Override
public void receivedAnimationStart(AnimationStartMessage msg) {
logic.setState(new AnimationState(logic, msg.isMyTurn(), msg.getPosition()));
public void receivedEffect(EffectMessage msg) {
ClientGameLogic.LOGGER.log(Level.INFO, "report effect: {0}", msg); //NON-NLS
myTurn = msg.isMyTurn();
logic.playSound(Sound.MISSILE_LAUNCH);
logic.setInfoText(msg.getInfoTextKey());
affectedMap(msg).add(msg.getShot());
affectedMap(msg).add(new Shell(new Vector3f(0, 50, 0), new Vector3f(msg.getShot().getY() + 0.5f, -0.4f, msg.getShot().getX() + 0.5f), 1f,msg,logic));
if (destroyedOpponentShip(msg))
logic.getOpponentMap().add(msg.getDestroyedShip());
if (msg.isGameOver()) {
msg.getRemainingOpponentShips().forEach(logic.getOpponentMap()::add);
logic.setState(new GameOverState(logic));
}
}
/**
* 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();
}
}

View File

@@ -8,7 +8,10 @@
package pp.battleship.game.client;
import pp.battleship.message.client.ClientMessage;
import pp.battleship.message.server.*;
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.model.IntPoint;
import pp.battleship.model.ShipMap;
import pp.battleship.model.dto.ShipMapDTO;
@@ -223,26 +226,6 @@ public void received(EffectMessage msg) {
state.receivedEffect(msg);
}
/**
* Reports the AnimationStartMessage based on the server-state
*
* @param animationStartMessage the StartMessage received
*/
@Override
public void received(AnimationStartMessage animationStartMessage) {
state.receivedAnimationStart(animationStartMessage);//TODO
}
/**
* Reports the BackToBattleStateMessage based on the server-state
*
* @param backToBattleStateMessage the Message received
*/
@Override
public void received(BackToBattleStateMessage backToBattleStateMessage) {
state.receiveBackToBattleState(backToBattleStateMessage);
}
/**
* Initializes the player's own map, opponent's map, and harbor based on the game details.
*
@@ -321,7 +304,7 @@ public void saveMap(File file) throws IOException {
*
* @param msg the message to be sent
*/
public void send(ClientMessage msg) {
void send(ClientMessage msg) {
if (clientSender == null)
LOGGER.log(Level.ERROR, "trying to send {0} with sender==null", msg); //NON-NLS
else

View File

@@ -7,7 +7,9 @@
package pp.battleship.game.client;
import pp.battleship.message.server.*;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.StartBattleMessage;
import pp.battleship.model.IntPoint;
import java.io.File;
@@ -163,13 +165,6 @@ void receivedEffect(EffectMessage msg) {
ClientGameLogic.LOGGER.log(Level.ERROR, "receivedEffect not allowed in {0}", getName()); //NON-NLS
}
/**
* @param msg the message received
*/
void receivedAnimationStart(AnimationStartMessage msg) {
ClientGameLogic.LOGGER.log(Level.ERROR, "receivedAnimationStart not allowed in {0}", getName());
}
/**
* Loads a map from the specified file.
*
@@ -198,15 +193,6 @@ boolean maySaveMap() {
return true;
}
/**
* Received a BackToBattleStateMessage and logs it
*
* @param msg the message received
*/
public void receiveBackToBattleState(BackToBattleStateMessage msg) {
ClientGameLogic.LOGGER.log(Level.ERROR, "receivedBackToBattleState not allowed in {0}", getName());
}
/**
* Called once per frame by the update loop if this state is active.
*

View File

@@ -10,14 +10,12 @@
import pp.battleship.message.client.MapMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Rotation;
import pp.battleship.model.ShipMap;
import pp.battleship.model.dto.ShipMapDTO;
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.List;
import static pp.battleship.Resources.lookup;
@@ -114,8 +112,7 @@ private void placeShip(IntPoint cursor) {
harbor().remove(selectedInHarbor);
preview = null;
selectedInHarbor = null;
}
else {
} else {
preview.setStatus(INVALID_PREVIEW);
ownMap().add(preview);
}
@@ -138,8 +135,7 @@ public void clickHarbor(IntPoint pos) {
harbor().add(selectedInHarbor);
preview = null;
selectedInHarbor = null;
}
else if (shipAtCursor != null) {
} else if (shipAtCursor != null) {
selectedInHarbor = shipAtCursor;
selectedInHarbor.setStatus(VALID_PREVIEW);
harbor().remove(selectedInHarbor);
@@ -231,7 +227,7 @@ private ShipMap harbor() {
}
/**
* Loads a map from the specified file.
* Loads a map from the specified file. Also Checks if the map is valid
*
* @param file the file to load the map from
* @throws IOException if the map cannot be loaded
@@ -241,8 +237,8 @@ public void loadMap(File file) throws IOException {
final ShipMapDTO dto = ShipMapDTO.loadFrom(file);
if (!dto.fits(logic.getDetails()))
throw new IOException(lookup("map.doesnt.fit"));
if (!verifyMap(dto)) {
throw new IOException(lookup("player.submitted.invalid.map"));
if(!validMap(dto)){
throw new IOException(lookup("map.is.invalid"));
}
ownMap().clear();
dto.getShips().forEach(ownMap()::add);
@@ -251,50 +247,6 @@ public void loadMap(File file) throws IOException {
selectedInHarbor = null;
}
/**
* this method returns true, if the given map is valid (don't overlap or out of bound)
*
* @param dto the map
* @return true, if the map is valid
*/
private boolean verifyMap(ShipMapDTO dto) { //MapMessage msg, int playerID
return verifyBounds(dto) && verifyOverlap(dto);
}
/**
* checks, whether a ship is out of the grid
*
* @param dto is the Map, where the ships are in
* @return true, if all ships are in bound
*/
private boolean verifyBounds(ShipMapDTO dto) {
int mapWidth = dto.getWidth();
int mapHeight = dto.getHeight();
for (Battleship ship : dto.getShips()) {
if (ship.getMaxX() > mapWidth || ship.getMinX() < 0 || ship.getMaxY() > mapHeight || ship.getMinY() < 0)
return false;
}
return true;
}
/**
* checks whether the ships overlap each other
*
* @param dto ist the map, where the ships are in
* @return true, if no ships overlap
*/
private boolean verifyOverlap(ShipMapDTO dto) {
List<Battleship> ships = dto.getShips();
for (Battleship ship : ships) {
for (Battleship compareShip : ships) {
if (!ship.equals(compareShip)) {
if (ship.collidesWith(compareShip)) return false;
}
}
}
return true;
}
/**
* Checks if the player's own map may be loaded from a file.
*
@@ -314,4 +266,51 @@ public boolean mayLoadMap() {
public boolean maySaveMap() {
return harbor().getItems().isEmpty();
}
/**
* Checks if the map is valid in terms of overlapping and if the ship is within the boundries of the map
* @param dto DataTransferObject is the loaded json file
* @return returns true if the map is valid, false otherwhise
*/
private boolean validMap(ShipMapDTO dto) {
return inBoundsClient(dto) && overLapClient(dto);
}
/**
* Checks if the Ships overlap on the map
* @param dto DataTransferObject is the loaded json file
* @return returns true if the ships arent overlapping, false otherwhise
*/
private boolean overLapClient(ShipMapDTO dto) {
List<Battleship> battleshipList = dto.getShips();
for (int i = 0; i < battleshipList.size(); i++) {
Battleship ship1 = battleshipList.get(i);
for (int j = i + 1; j < battleshipList.size(); j++) {
Battleship ship2 = battleshipList.get(j);
if (ship1.collidesWith(ship2)) {
return false;
}
}
}
return true;
}
/**
* Checks if the Ship is in the map Boundries
* @param dto DataTransferObject is the loaded json file
* @return true if the ship is in the maps boundriess, false otherwhise
*/
private boolean inBoundsClient(ShipMapDTO dto) {
int widht = dto.getWidth();
int height = dto.getHeight();
for (int i = 0; i < dto.getShips().size(); i++) {
Battleship localShip = dto.getShips().get(i);
if (!(localShip.getMaxX() < widht && localShip.getMaxY() < height && localShip.getMinY() >= 0 && localShip.getMinX() >= 0)) {
return false;
}
}
return true;
}
}

View File

@@ -7,7 +7,6 @@
package pp.battleship.game.client;
import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.StartBattleMessage;
import java.lang.System.Logger.Level;
@@ -39,18 +38,4 @@ public void receivedStartBattle(StartBattleMessage msg) {
logic.setInfoText(msg.getInfoTextKey());
logic.setState(new BattleState(logic, msg.isMyTurn()));
}
/**
* Handles the GameDetails message received from the server.
* If the map is invalid, the editor state is set.
*
* @param msg the GameDetails message received
*/
@Override
public void receivedGameDetails(GameDetails msg) {
ClientGameLogic.LOGGER.log(Level.WARNING, "Invalid Map"); //NON-NLS
logic.setInfoText("map.invalid");
logic.setState(new EditorState(logic));
}
}

View File

@@ -8,11 +8,13 @@
package pp.battleship.game.server;
import pp.battleship.BattleshipConfig;
import pp.battleship.message.client.AnimationEndMessage;
import pp.battleship.message.client.ClientInterpreter;
import pp.battleship.message.client.MapMessage;
import pp.battleship.message.client.ShootMessage;
import pp.battleship.message.server.*;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.ServerMessage;
import pp.battleship.message.server.StartBattleMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint;
@@ -36,8 +38,6 @@ public class ServerGameLogic implements ClientInterpreter {
private final ServerSender serverSender;
private Player activePlayer;
private ServerState state = ServerState.WAIT;
private boolean playerOneAnimationReady = false;
private boolean playerTwoAnimationReady = false;
/**
* Constructs a ServerGameLogic with the specified sender and configuration.
@@ -54,6 +54,7 @@ public ServerGameLogic(ServerSender serverSender, BattleshipConfig config) {
* Returns the state of the game.
*/
ServerState getState() {
return state;
}
@@ -133,7 +134,7 @@ public Player addPlayer(int id) {
}
/**
* Handles the reception of a MapMessage.
* Handles the reception of a MapMessage. Also Checks if the given map is valid or invalid
*
* @param msg the received MapMessage
* @param from the ID of the sender client
@@ -142,77 +143,60 @@ 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 (!verifyMap(msg, from)) {
LOGGER.log(Level.ERROR, "player submitted invalid map", state);
send(getPlayerById(from), new GameDetails(config));
} else
else if(!validMap(msg,from)){
LOGGER.log(Level.ERROR, "Map message not valid",state);
}
else
playerReady(getPlayerById(from), msg.getShips());
}
@Override
public void received(AnimationEndMessage msg, int from) {
LOGGER.log(Level.INFO, "AnimationEndMessage was received by ServerGameLogic");
if (state != ServerState.ANIMATION_WAIT_STATE)
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));
playerOneAnimationReady = 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());
playerTwoAnimationReady = true;
shoot(getPlayerById(from), msg.getPosition());
}
if (playerOneAnimationReady && playerTwoAnimationReady) {
setState(ServerState.BATTLE);
for (Player player : players)
send(player, new BackToBattleStateMessage(player == activePlayer));
playerOneAnimationReady = false;
playerTwoAnimationReady = false;
}
/**
* Checks if the map is Valid in terms of boundries and overlaps
* *
* @param msg the received MapMessage
* @param id the ID of the sender client
* @return returns true if the map is valid, false otherwhise
*/
private boolean validMap(MapMessage msg, int id) {
return inBounds(msg, id) && overLap(msg);
}
/**
* this method returns true, if the given map is valid (don't overlap or out of bound)
* Checks if the Ships overLap
*
* @param msg the message, where the map is in
* @param playerID the player, who committed the map
* @return true, if the map is valid
* @param msg the received MapMessage
* @return returns true if the ships arent overlapping, false otherwhise
*/
private boolean verifyMap(MapMessage msg, int playerID) {
return verifyBounds(msg, playerID) && verifyOverlap(msg);
}
private boolean overLap(MapMessage msg) {
List<Battleship> battleshipList = msg.getShips();
/**
* checks, whether a ship is out of the grid
*
* @param msg is the message, where the map is in
* @return true, if all ships are in bound
*/
private boolean verifyBounds(MapMessage msg, int playerID) {
int mapWidth = getPlayerById(playerID).getMap().getWidth();
int mapHeight = getPlayerById(playerID).getMap().getHeight();
for (Battleship ship : msg.getShips()) {
if (ship.getMaxX() > mapWidth || ship.getMinX() < 0 || ship.getMaxY() > mapHeight || ship.getMinY() < 0)
return false;
for (int i = 0; i < battleshipList.size(); i++) {
Battleship ship1 = battleshipList.get(i);
for (int j = i + 1; j < battleshipList.size(); j++) {
Battleship ship2 = battleshipList.get(j);
if (ship1.collidesWith(ship2)) {
return false;
}
}
}
return true;
}
/**
* checks whether the ships overlap each other
* Checks if the Ship is placed in Bounds with the Map
*
* @param msg is the message, where the map is in
* @return true, if no ships overlap
* @param msg the received MapMessage
* @param id the ID of the sender client
* @return returns true if the ship is within the maps boundries, false otherwhise
*/
private boolean verifyOverlap(MapMessage msg) {
List<Battleship> ships = msg.getShips();
for (Battleship ship : ships) {
for (Battleship compareShip : ships) {
if (!ship.equals(compareShip)) {
if (ship.collidesWith(compareShip)) return false;
}
private boolean inBounds(MapMessage msg, int id) {
int widht = getPlayerById(id).getMap().getWidth();
int height = getPlayerById(id).getMap().getHeight();
for (int i = 0; i < msg.getShips().size(); i++) {
Battleship localShip = msg.getShips().get(i);
if (!(localShip.getMaxX() < widht && localShip.getMaxY() < height && localShip.getMinY() >= 0 && localShip.getMinX() >= 0)) {
return false;
}
}
return true;
@@ -228,13 +212,8 @@ private boolean verifyOverlap(MapMessage msg) {
public void received(ShootMessage msg, int from) {
if (state != ServerState.BATTLE)
LOGGER.log(Level.ERROR, "shoot not allowed in {0}", state); //NON-NLS
else {
for (Player player : players) {
send(player, new AnimationStartMessage(msg.getPosition(), player == activePlayer));
setState(ServerState.ANIMATION_WAIT_STATE);
}
}
else
shoot(getPlayerById(from), msg.getPosition());
}
/**
@@ -260,125 +239,35 @@ void playerReady(Player player, List<Battleship> ships) {
/**
* Handles the shooting action by the player.
*
* @param p the player who shot
* @param position the position of the shot
* @param p the player who shot
* @param pos the position of the shot
*/
void shoot(Player p, IntPoint position) {
final Battleship selectedShip;
selectedShip = getSelectedShip(p, position);
void shoot(Player p, IntPoint pos) {
if (p != activePlayer) return;
final Player otherPlayer = getOpponent(activePlayer);
final Battleship selectedShip = otherPlayer.getMap().findShipAt(pos);
if (selectedShip == null) {
nullShip(p, position);
// shot missed
send(activePlayer, EffectMessage.miss(true, pos));
send(otherPlayer, EffectMessage.miss(false, pos));
activePlayer = otherPlayer;
} else {
shootShip(p, position, selectedShip);
}
}
/**
* getter for the selected battleship through the shot
*
* @param p the current player
* @param position the position shot at
* @return the battleship, on the position shot at
*/
private Battleship getSelectedShip(Player p, IntPoint position) {
return (p != activePlayer) ? p.getMap().findShipAt(position) : getOpponent(p).getMap().findShipAt(position);
}
/**
* this method handles the shot logic, if the shot misses
*
* @param p the current player
* @param position the position shot at
*/
private void nullShip(Player p, IntPoint position) {
if (p != activePlayer) {
send(p, EffectMessage.miss(false, position));
} else {
send(activePlayer, EffectMessage.miss(true, position));
}
//switches the active player, when both have finished their animation
if (playerOneAnimationReady && playerTwoAnimationReady) {
LOGGER.log(Level.DEBUG, "switched active player");
if (p != activePlayer) {
activePlayer = p;
// 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()));
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 {
activePlayer = getOpponent(p);
// ship has been hit, but it hasn't been destroyed
send(activePlayer, EffectMessage.hit(true, pos));
send(otherPlayer, EffectMessage.hit(false, pos));
}
}
}
/**
* this method handles the shot logic, if the shot misses
*
* @param p the current player
* @param position the position shot at
* @param selectedShip the ship shot at
*/
private void shootShip(Player p, IntPoint position, Battleship selectedShip) {
selectedShip.hit(position);
if (isGameOver(getOpponent(p))) {
gameOver(p, position, selectedShip);
} else if (selectedShip.isDestroyed()) {
shipDestroys(p, position, selectedShip);
} else {
shipHit(p, position);
}
}
/**
* checks, if the given player ends the game, bc he has no ships
*
* @param p the player
* @return true, if the given player has no shi left
*/
private boolean isGameOver(Player p) {
return p.getMap().getRemainingShips().isEmpty();
}
/**
* handles the shot logic,if the game is over
*
* @param p the player
* @param position the position shot at
* @param selectedShip the current ship, shot at
*/
private void gameOver(Player p, IntPoint position, Battleship selectedShip) {
if (p != activePlayer) {
send(p, EffectMessage.lost(position, selectedShip, activePlayer.getMap().getRemainingShips()));
} else {
send(activePlayer, EffectMessage.won(position, selectedShip));
}
if (playerOneAnimationReady && playerTwoAnimationReady) {
setState(ServerState.GAME_OVER);
}
}
/**
* handles the logic,if the ship is destroyed and it's not gameOver
*
* @param p the player
* @param position the position shot at
* @param selectedShip the ship shot at
*/
private void shipDestroys(Player p, IntPoint position, Battleship selectedShip) {
if (p != activePlayer) {
send(p, EffectMessage.shipDestroyed(false, position, selectedShip));
} else {
send(activePlayer, EffectMessage.shipDestroyed(true, position, selectedShip));
}
}
/**
* handles the logic,if the ship is hit and it's not gameOver
*
* @param p the player
* @param position the position shot at
*/
private void shipHit(Player p, IntPoint position) {
if (p != activePlayer) {
send(p, EffectMessage.hit(false, position));
} else {
send(activePlayer, EffectMessage.hit(true, position));
}
}
}
}

View File

@@ -29,10 +29,5 @@ enum ServerState {
/**
* The game has ended because all the ships of one player have been destroyed.
*/
GAME_OVER,
/**
* The game has paused, cause the clients need time to play their respective animations
*/
ANIMATION_WAIT_STATE
GAME_OVER
}

View File

@@ -7,7 +7,6 @@
package pp.battleship.game.singlemode;
import pp.battleship.message.client.AnimationEndMessage;
import pp.battleship.message.client.ClientInterpreter;
import pp.battleship.message.client.ClientMessage;
import pp.battleship.message.client.MapMessage;
@@ -64,17 +63,6 @@ public void received(MapMessage msg, int from) {
copiedMessage = new MapMessage(msg.getShips().stream().map(Copycat::copy).toList());
}
/**
* Receives an AnimationEndMessage, copies it
*
* @param msg the message
* @param from the connectionID
*/
@Override
public void received(AnimationEndMessage msg, int from) {
copiedMessage = new AnimationEndMessage(msg.getPosition());
}
/**
* Creates a copy of the provided {@link Battleship}.
*

View File

@@ -9,19 +9,19 @@
import pp.battleship.game.client.BattleshipClient;
import pp.battleship.game.client.ClientGameLogic;
import pp.battleship.message.server.*;
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 java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
/**
* A proxy class that interprets messages from the server and forwards them to the BattleshipClient.
* Implements the ServerInterpreter interface to handle specific server messages.
*/
class InterpreterProxy implements ServerInterpreter {
private static final Logger LOGGER = System.getLogger(InterpreterProxy.class.getName());
private final BattleshipClient playerClient;
/**
@@ -55,7 +55,8 @@ private void loadMap() {
final ClientGameLogic clientGameLogic = playerClient.getGameLogic();
try {
clientGameLogic.loadMap(playerClient.getConfig().getOwnMap());
} catch (IOException e) {
}
catch (IOException e) {
throw new RuntimeException("Failed to load PlayerClient map", e);
}
clientGameLogic.mapFinished();
@@ -81,27 +82,6 @@ public void received(EffectMessage msg) {
forward(msg);
}
/**
* Received an AnimationStartMessage, logs it and forwards it
*
* @param animationStartMessage the StartMessage received
*/
@Override
public void received(AnimationStartMessage animationStartMessage) {
LOGGER.log(Level.INFO, "AnimationStartMessage was received by InterpreterProxy");
forward(animationStartMessage);
}
/**
* Received a BackToBattleStateMessage, and forwards it
*
* @param backToBattleStateMessage the Message received
*/
@Override
public void received(BackToBattleStateMessage backToBattleStateMessage) {
forward(backToBattleStateMessage);
}
/**
* Forwards the specified ServerMessage to the client's game logic by enqueuing the message acceptance.
*

View File

@@ -1,10 +1,12 @@
package pp.battleship.game.singlemode;
import pp.battleship.game.client.BattleshipClient;
import pp.battleship.message.client.AnimationEndMessage;
import pp.battleship.message.client.MapMessage;
import pp.battleship.message.client.ShootMessage;
import pp.battleship.message.server.*;
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.model.IntPoint;
import pp.battleship.model.dto.ShipMapDTO;
import pp.util.RandomPositionIterator;
@@ -122,27 +124,4 @@ public void received(EffectMessage msg) {
if (msg.isMyTurn())
shoot();
}
/**
* Received an AnimationStartMessage, logs it, and sends an AnimationEndMessage, bc it can't be displayed
*
* @param msg the StartMessage received
*/
@Override
public void received(AnimationStartMessage msg) {
LOGGER.log(Level.INFO, "AnimationStartMessage was received by RobotClient");
connection.sendRobotMessage(new AnimationEndMessage(msg.getPosition()));
}
/**
* Received an Message, if the BackToBattleState is active, checks, if it's his turn and fires, if it is
*
* @param backToBattleStateMessage the Message received
*/
@Override
public void received(BackToBattleStateMessage backToBattleStateMessage) {
if (backToBattleStateMessage.isMyTurn()) {
shoot();
}
}
}

View File

@@ -1,50 +0,0 @@
package pp.battleship.message.client;
import com.jme3.network.serializing.Serializable;
import pp.battleship.model.IntPoint;
/**
* this class represents the AnimationEndMessage, that is sent from the clients to the server, to say, they are finished with the animation
*/
@Serializable
public class AnimationEndMessage extends ClientMessage {
/**
* the position, where was shot at
*/
private IntPoint position;
/**
* this private constructor is used for the serialization
*/
private AnimationEndMessage() { /* nothing */}
/**
* this is the constructor for this class
*
* @param position IntPoint
*/
public AnimationEndMessage(IntPoint position) {
this.position = position;
}
/**
* the getter for the position
*
* @return IntPoint position
*/
public IntPoint getPosition() {
return position;
}
/**
* the accept-method for the ClientInterpreter
*
* @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);
}
}

View File

@@ -26,12 +26,4 @@ public interface ClientInterpreter {
* @param from the connection ID from which the message was received
*/
void received(MapMessage msg, int from);
/**
* Processes a received AnimationEndMessage
*
* @param animationEndMessage the message processed
* @param from the connectionID
*/
void received(AnimationEndMessage animationEndMessage, int from);
}

View File

@@ -1,67 +0,0 @@
package pp.battleship.message.server;
import com.jme3.network.serializing.Serializable;
import pp.battleship.model.IntPoint;
/**
* This class represents the AnimationStartMessage, which tells the clients, that they should display their animations
*/
@Serializable
public class AnimationStartMessage extends ServerMessage {
private IntPoint position;
private boolean myTurn;
/**
* this empty constructor is needed for the serialization
*/
private AnimationStartMessage() { /* nothing */}
/**
* this is the constructor for the AnimationMessage
*
* @param position the position, where was shot
* @param isTurn of the receiving client
*/
public AnimationStartMessage(IntPoint position, boolean isTurn) {
this.position = position;
this.myTurn = isTurn;
}
/**
* getter for the position
*
* @return IntPoint position
*/
public IntPoint getPosition() {
return position;
}
/**
* getter for myTurn
*
* @return boolean myTurn
*/
public boolean isMyTurn() {
return myTurn;
}
/**
* this method accept ServerInterpreter
*
* @param interpreter the visitor to be used for processing
*/
@Override
public void accept(ServerInterpreter interpreter) {
interpreter.received(this);
}
/**
* getter for the Info text for each state
*
* @return String InfoText
*/
@Override
public String getInfoTextKey() {
return (position + " to be animated");
}
}

View File

@@ -1,59 +0,0 @@
package pp.battleship.message.server;
import com.jme3.network.serializing.Serializable;
/**
* this Message tells the clients, that they should return to the BattleState
*/
@Serializable
public class BackToBattleStateMessage extends ServerMessage {
/**
* the boolean describes, whether it is his turn
*/
private boolean isMyTurn;
/**
* the private constructor is used for the serialization
*/
private BackToBattleStateMessage() { /* nothing */}
/**
* the constructor for the message
*
* @param isMyTurn indicates, whether the client, that receives this message, has his turn
*/
public BackToBattleStateMessage(boolean isMyTurn) {
this.isMyTurn = isMyTurn;
}
/**
* getter for the MyTurn
*
* @return boolean myTurn
*/
public boolean isMyTurn() {
return isMyTurn;
}
/**
* accept-method for ServerInterpreter
*
* @param interpreter the visitor to be used for processing
*/
@Override
public void accept(ServerInterpreter interpreter) {
interpreter.received(this);
}
/**
* returns info text for this Message
*
* @return String
*/
@Override
public String getInfoTextKey() {
return "";
}
}

View File

@@ -33,18 +33,4 @@ public interface ServerInterpreter {
* @param msg the EffectMessage received
*/
void received(EffectMessage msg);
/**
* Handles the AnimationStartMessage
*
* @param animationStartMessage the StartMessage received
*/
void received(AnimationStartMessage animationStartMessage);
/**
* Handles the Message, that sets the clients back in the BattleState
*
* @param backToBattleStateMessage the Message received
*/
void received(BackToBattleStateMessage backToBattleStateMessage);
}

View File

@@ -1,36 +1,65 @@
package pp.battleship.model;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import com.jme3.math.Vector3f;
import pp.battleship.game.client.ClientGameLogic;
import pp.battleship.message.server.EffectMessage;
import pp.util.FloatMath;
/**
* this class is the model for the shell, that hits the Battleships
*/
public class Shell implements Item {
private final Vector3f startPosition; // Startposition des Geschosses
private final Vector3f targetPosition; // Zielposition des Geschosses0
private final Vector3f currentPosition; // Aktuelle Position des Geschosses
private final float speed; // Geschwindigkeit des Geschosses
private final EffectMessage msg;
private final ClientGameLogic logic;
private static final Logger LOGGER = System.getLogger(Shell.class.getName());
private float progress;
/**
* the Target, the Shell will hit
* Initializes a Shell with start position, target position, speed, message, and game logic.
* @param startPosition initial position of the shell
* @param targetPosition target position of the shell
* @param speed movement speed of the shell
* @param msg effect message related to the shell
* @param logic game logic instance
*/
private IntPoint target;
/**
* the constructor for this class
*
* @param target the target, the shell is fired at
*/
public Shell(IntPoint target) {
this.target = target;
LOGGER.log(Level.INFO, "Shell has been initialized");
public Shell(Vector3f startPosition, Vector3f targetPosition, float speed, EffectMessage msg, ClientGameLogic logic) {
this.startPosition = startPosition;
this.targetPosition = targetPosition;
this.currentPosition = new Vector3f(startPosition); // Initiale Position ist die Startposition
this.speed = speed;
this.msg = msg;
this.logic = logic;
}
/**
* Updates the shell's position based on elapsed time, using eased interpolation between start and target positions.
* @param deltaTime time elapsed since last update
*/
public void updatePosition(float deltaTime) {
progress += deltaTime * speed;
progress = FloatMath.clamp(progress, 0.0f, 1.0f);
float t = FloatMath.easeInOutElastic(progress);
// Interpoliere die Position zwischen Start- und Zielposition basierend auf dem Fortschritt
currentPosition.y = FloatMath.extrapolateLinear(t, startPosition.y, targetPosition.y);
currentPosition.x = FloatMath.extrapolateLinear(t, startPosition.x, targetPosition.x);
currentPosition.z = FloatMath.extrapolateLinear(t, startPosition.z, targetPosition.z);
}
/**
* getter for Current Position
* @return current position
*/
public Vector3f getCurrentPosition() {
return currentPosition;
}
/**
* the accept-method for a generic visitor
*
* @param visitor the visitor performing operations on the item
* @param <T> cause it is generic
* @return T
* @param <T> generic type
* @return shell
*/
@Override
public <T> T accept(Visitor<T> visitor) {
@@ -38,9 +67,8 @@ public <T> T accept(Visitor<T> visitor) {
}
/**
* the accept-method for the void visitor
*
* @param visitor the visitor performing operations on the item
* Visitor pattern
* @param visitor the visitor to accept
*/
@Override
public void accept(VoidVisitor visitor) {
@@ -48,20 +76,28 @@ public void accept(VoidVisitor visitor) {
}
/**
* getter for the x coordinate
*
* @return int x coordinate
* getter for the isFinished boolean
* @return true if progress lesser than 1, false otherwise
*/
public int getX() {
return target.getX();
public boolean isFinished() {
return progress >= 1;
}
/**
* getter for the y coordinate
*
* @return int y coordinate
* getter for EffectMessage
* @return EffectMessage
*/
public int getY() {
return target.getY();
public EffectMessage getMsg() {
return msg;
}
/**
* getter for Client logic
* @return Client logic
*/
public ClientGameLogic getLogic() {
return logic;
}
}

Some files were not shown because too many files have changed in this diff Show More