1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package cz.cuni.amis.pogamut.ut2004.agent.navigation.navmesh.formation;
18
19 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
20 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
21 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
22 import cz.cuni.amis.pogamut.ut2004.agent.navigation.navmesh.NavMesh;
23 import cz.cuni.amis.pogamut.ut2004.agent.navigation.navmesh.NavMeshConstants;
24 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
25 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004BotModuleController;
26 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
27 import cz.cuni.amis.utils.exception.PogamutException;
28 import javax.vecmath.Vector2d;
29
30
31
32
33
34 public class Formation {
35
36
37 UT2004BotModuleController bot;
38
39 Player leader;
40 Location leaderLastSeenLocation;
41 double leaderLastSeenRotation = 0;
42 long leaderLastTimeSeen = 0;
43
44 Vector2d direction;
45 double distance;
46
47 NavMesh navmesh;
48
49
50 boolean relativeRotation = true;
51
52 boolean turnToLeaderAtDestination = true;
53
54 boolean watchLeader = true;
55
56 boolean suicideMode = false;
57
58
59 public Formation(UT2004BotModuleController bot) throws Exception {
60 this.bot = bot;
61 navmesh = bot.getNavMeshModule().getNavMesh();
62 if(navmesh==null) throw new Exception("Formation cannot be instatiated because there is no navmesh.");
63 }
64
65
66
67
68
69
70
71 public void holdFormation() {
72
73 if(leader == null) {
74 System.out.println("No leader - no formation");
75 return;
76 }
77
78
79 updateLeaderInfo();
80
81
82 if(null == bot.getPlayers().getVisiblePlayer(leader.getId())) {
83 if(watchLeader) {
84 System.out.println("I lost the leader from sight. I look where i last saw him.");
85 bot.getMove().turnTo(leaderLastSeenLocation);
86 return;
87 }
88 }
89
90 if(leaderLastSeenLocation == null) {
91 System.out.println("I dont know where my leader is...");
92 return;
93 }
94
95
96 double yaw = NavMeshConstants.transform2DVectorToRotation(direction);
97 if(this.relativeRotation) yaw += leaderLastSeenRotation;
98 Vector2d actualDirection = NavMeshConstants.transformRotationTo2DVector(yaw);
99
100 actualDirection.normalize();
101 actualDirection.x *= distance;
102 actualDirection.y *= distance;
103
104 double x = leaderLastSeenLocation.x + actualDirection.x;
105 double y = leaderLastSeenLocation.y + actualDirection.y;
106 double z = leaderLastSeenLocation.z;
107
108 Location targetLocaton = new Location(x,y,z);
109
110 if(bot.getInfo().atLocation(targetLocaton, NavMeshConstants.StepSize/2)) {
111 System.out.println("I am at the right spot.");
112 if(this.turnToLeaderAtDestination) bot.getMove().turnTo(this.leaderLastSeenLocation);
113 return;
114 }
115
116 Location currenLocation = bot.getInfo().getLocation();
117
118
119 Vector2d mainForce = new Vector2d(targetLocaton.x-currenLocation.x, targetLocaton.y-currenLocation.y);
120 mainForce.normalize();
121 mainForce.x *= NavMeshConstants.ForceToTarget;
122 mainForce.y *= NavMeshConstants.ForceToTarget;
123
124
125
126 yaw = bot.getInfo().getRotation().getYaw();
127 double distance;
128 double force;
129
130 Vector2d frontDirection = NavMeshConstants.transformRotationTo2DVector(yaw);
131 distance = navmesh.getDistanceFromEdge(currenLocation, frontDirection, NavMeshConstants.obstacleMaxDistance);
132 if(0 < distance && distance < NavMeshConstants.obstacleMaxDistance) {
133 force = (distance / NavMeshConstants.obstacleMaxDistance) * NavMeshConstants.obstacleMaxForce;
134 Vector2d frontForce = (Vector2d) frontDirection.clone();
135 frontForce.negate();
136 frontForce.normalize();
137 frontForce.x *= force;
138 frontForce.y *= force;
139 mainForce.add(frontForce);
140 }
141
142
143 Vector2d leftFrontDirection = NavMeshConstants.transformRotationTo2DVector(yaw-NavMeshConstants.UTQuarterAngle/2);
144 distance = navmesh.getDistanceFromEdge(currenLocation, leftFrontDirection, NavMeshConstants.obstacleMaxDistance);
145 if(0 < distance && distance < NavMeshConstants.obstacleMaxDistance) {
146 force = (distance / NavMeshConstants.obstacleMaxDistance) * NavMeshConstants.obstacleMaxForce;
147 Vector2d leftFrontForce = (Vector2d) leftFrontDirection.clone();
148 leftFrontForce.negate();
149 leftFrontForce.normalize();
150 leftFrontForce.x *= force;
151 leftFrontForce.y *= force;
152 mainForce.add(leftFrontForce);
153 }
154
155
156 Vector2d rightFrontDirection = NavMeshConstants.transformRotationTo2DVector(yaw+NavMeshConstants.UTQuarterAngle/2);
157 distance = navmesh.getDistanceFromEdge(currenLocation, rightFrontDirection, NavMeshConstants.obstacleMaxDistance);
158 if(0 < distance && distance < NavMeshConstants.obstacleMaxDistance) {
159 force = (distance / NavMeshConstants.obstacleMaxDistance) * NavMeshConstants.obstacleMaxForce;
160 Vector2d rightFrontForce = (Vector2d) rightFrontDirection.clone();
161 rightFrontForce.negate();
162 rightFrontForce.normalize();
163 rightFrontForce.x *= force;
164 rightFrontForce.y *= force;
165 mainForce.add(rightFrontForce);
166 }
167
168
169
170
171
172
173
174 mainForce.normalize();
175 mainForce.x *= NavMeshConstants.StepSize;
176 mainForce.y *= NavMeshConstants.StepSize;
177 x = currenLocation.x + mainForce.x;
178 y = currenLocation.y + mainForce.y;
179 z = currenLocation.z;
180 Location resultLocation = new Location(x,y,z);
181
182
183 System.out.println("Moving to resultLocation " + resultLocation);
184 bot.getMove().moveTo(resultLocation);
185 }
186
187 public void updateLeaderInfo() {
188 if(bot.getPlayers().getVisiblePlayer(leader.getId())!=null) {
189 System.out.println("Updating leader's location...");
190 leaderLastSeenLocation = leader.getLocation();
191 leaderLastSeenRotation = leader.getRotation().getYaw();
192 leaderLastTimeSeen = System.nanoTime();
193 } else {
194 System.out.println("I cannot see the leader.");
195 }
196 }
197
198
199
200
201
202 public int howLongLeaderNotSeen() {
203 double nano = (System.nanoTime() - this.leaderLastTimeSeen);
204 return (int)(nano / 1000000000);
205 }
206
207
208
209
210 public void setLeader(Player leader) {
211 this.leader = leader;
212 updateLeaderInfo();
213 }
214 public void setDirection(Vector2d direction) {
215 this.direction = direction;
216 }
217 public void setDistance(double distance) {
218 this.distance = distance;
219 }
220
221
222
223
224 public Player getLeader() {
225 return leader;
226 }
227 public Vector2d getDirection() {
228 return direction;
229 }
230 public double getDistance() {
231 return distance;
232 }
233 public Location getLeaderLastSeenLocation() {
234 return leaderLastSeenLocation;
235 }
236 public long getLeaderLastTimeSeen() {
237 return leaderLastTimeSeen;
238 }
239
240 }