1 package Steerings;
2
3
4 import SteeringStuff.SteeringManager;
5 import SteeringStuff.RefBoolean;
6 import SteeringProperties.SteeringProperties;
7 import SteeringProperties.WalkAlongProperties;
8 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
9 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
10 import javax.vecmath.Vector3d;
11 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
12 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
13 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
14 import SteeringStuff.ISteering;
15 import SteeringStuff.SteeringTools;
16 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.PlayAnimation;
17 import java.util.Collection;
18 import javax.vecmath.Tuple3d;
19 import javax.vecmath.Vector2d;
20
21
22
23
24
25
26
27 public class WalkAlongSteer implements ISteering {
28
29
30 private UT2004Bot botself;
31
32
33 private Location targetLocation;
34
35 private int partnerForce;
36
37 private int distanceFromThePartner;
38
39 private String partnerName;
40
41 private boolean giveWayToPartner;
42
43 private boolean waitForPartner;
44
45 private boolean turn = true;
46 private boolean newToPartner = false;
47 private boolean newToPartner2 = false;
48 private boolean newWait = false;
49 private boolean truncateToPartner = false;
50 private boolean truncateNextVelocity = false;
51
52 private static int MAX_TO_PARTNER = 500;
53 private static int MAX_NEXT_VELOCITY = 500;
54 private static int WAIT_DISTANCE = 100;
55 private static int NEARLY_THERE_DISTANCE = 200;
56
57 private boolean waiting;
58
59
60 private Player partner;
61
62 private Vector3d forceToTarget;
63 private Vector3d forceToPartner;
64 private Vector3d forceFromPartner;
65
66
67
68
69 public WalkAlongSteer(UT2004Bot bot) {
70 botself = bot;
71 waiting = false;
72 }
73
74
75 public Vector3d run(Vector3d scaledActualVelocity, RefBoolean wantsToGoFaster, RefBoolean wantsToStop, Location focus) {
76
77 Vector3d actualVelocity = botself.getVelocity().getVector3d();
78
79 Vector3d nextVelocity = new Vector3d(0,0,0);
80
81 if (partner == null || partner.getLocation() == null) {
82 partner = getPartner();
83 if (turn) {
84 Vector3d turningVector = new Vector3d(actualVelocity.y, -actualVelocity.x, 0);
85 turningVector.scale(1/(Math.sqrt(2)));
86 Vector3d negativeVector = new Vector3d(-actualVelocity.x,-actualVelocity.y,0);
87 negativeVector.scale(1-1/Math.sqrt(2));
88 turningVector.add((Tuple3d)negativeVector);
89 return turningVector;
90 } else {
91 wantsToStop.setValue(true);
92 if (SteeringManager.DEBUG) {
93 System.out.println("We wait for the partner.");
94 }
95 return nextVelocity;
96 }
97 }
98
99
100
101
102
103 Location middlePoint = new Location((botself.getLocation().x + partner.getLocation().x) / 2, (botself.getLocation().y + partner.getLocation().y) / 2, botself.getLocation().z);
104 Vector2d middlePointToTarget = new Vector2d(targetLocation.x - middlePoint.x, targetLocation.y - middlePoint.y);
105 Vector2d middlePointToTargetNormal = new Vector2d(-middlePointToTarget.y, middlePointToTarget.x);
106 middlePointToTargetNormal.normalize();
107 middlePointToTargetNormal.scale(distanceFromThePartner / 2);
108
109 Location targetA = new Location(targetLocation.x + middlePointToTargetNormal.x, targetLocation.y + middlePointToTargetNormal.y, targetLocation.z);
110 Location targetB = new Location(targetLocation.x - middlePointToTargetNormal.x, targetLocation.y - middlePointToTargetNormal.y, targetLocation.z);
111 Location targetMy;
112 Location targetHis;
113 if (botself.getLocation().getDistance(targetA) < botself.getLocation().getDistance(targetB)) {
114 targetMy = targetA;
115 targetHis = targetB;
116 } else {
117 targetMy = targetB;
118 targetHis = targetA;
119 }
120
121
122 if (SteeringManager.DEBUG) System.out.println("K mému cili "+botself.getLocation().getDistance(targetMy));
123
124 if (botself.getLocation().getDistance(targetMy) < NEARLY_THERE_DISTANCE) {
125 wantsToStop.setValue(true);
126 focus.setTo(partner.getLocation());
127 if (SteeringManager.DEBUG) System.out.println("We reached the target and we stop.");
128 return nextVelocity;
129 }
130
131
132 Vector3d myVectorToTarget = new Vector3d(targetMy.x - botself.getLocation().x, targetMy.y - botself.getLocation().y, targetMy.z - botself.getLocation().z);
133
134 Vector3d partnersVectorToTarget = new Vector3d(targetHis.x - partner.getLocation().x, targetHis.y - partner.getLocation().y, targetHis.z - partner.getLocation().z);
135
136
137 if (SteeringManager.DEBUG) System.out.println("Ja k cili "+myVectorToTarget.length());
138 if (SteeringManager.DEBUG) System.out.println("Partner k cili "+partnersVectorToTarget.length());
139
140 if (partnersVectorToTarget.length() > myVectorToTarget.length()) {
141 if (SteeringManager.DEBUG) System.out.println("Je dal.");
142 } else {
143 if (SteeringManager.DEBUG) System.out.println("Musim ho dohnat.");
144 }
145
146
147
148
149
150
151
152
153 forceToTarget = new Vector3d(targetMy.x - botself.getLocation().x, targetMy.y - botself.getLocation().y, 0);
154 forceToTarget.normalize();
155
156
157
158
159 Vector2d startC = new Vector2d(middlePoint.x, middlePoint.y);
160 Vector2d endC = new Vector2d(targetLocation.x, targetLocation.y);
161 Vector2d myLoc = new Vector2d(botself.getLocation().x, botself.getLocation().y);
162 Vector2d foot = SteeringTools.getNearestPoint(startC, endC, myLoc, false);
163 Vector3d footToBot = new Vector3d(myLoc.x - foot.x, myLoc.y - foot.y, 0);
164 double fromFoot = footToBot.length();
165 Vector3d botToFoot = new Vector3d(-footToBot.x, -footToBot.y, -footToBot.z);
166 footToBot.normalize();
167 botToFoot.normalize();
168 Vector3d footToBotCopy = new Vector3d(footToBot.x, footToBot.y, footToBot.z);
169
170 Vector3d partnerToBot = new Vector3d(botself.getLocation().x - partner.getLocation().x,botself.getLocation().y - partner.getLocation().y,botself.getLocation().z - partner.getLocation().z);
171 double fromPartner = partnerToBot.length();
172 partnerToBot.normalize();
173
174
175
176
177 Vector3d botToPartner = new Vector3d(partner.getLocation().x - botself.getLocation().x,partner.getLocation().y - botself.getLocation().y,partner.getLocation().z - botself.getLocation().z);
178 double toPartner = botToPartner.length();
179 botToPartner.normalize();
180
181
182
183
184
185
186
187 double diff = (myVectorToTarget.length() - partnersVectorToTarget.length())/500;
188 int add = 0;
189 if (diff > 0) {
190 diff = Math.min(diff, 1.5);
191 add = 30;
192 }
193 forceToTarget.scale(partnerForce*Math.pow(2,diff) + add);
194 if (SteeringManager.DEBUG) System.out.println("ToTarget "+forceToTarget.length());
195
196
197 if (giveWayToPartner) {
198 if (fromFoot < distanceFromThePartner/2) {
199 double scale = (distanceFromThePartner - 2*fromFoot) / distanceFromThePartner;
200 footToBot.scale(partnerForce*scale);
201 if (SteeringManager.DEBUG) System.out.println("From foot "+footToBot.length());
202 }else {
203 footToBot.set(0,0,0);
204 }
205 forceFromPartner = footToBot;
206 } else {
207 if (fromPartner < distanceFromThePartner) {
208 double scale = (distanceFromThePartner - fromPartner) / distanceFromThePartner;
209 partnerToBot.scale(partnerForce*scale);
210 if (SteeringManager.DEBUG) System.out.println("From partner "+partnerToBot.length());
211 } else {
212 partnerToBot.set(0,0,0);
213 }
214 forceFromPartner = partnerToBot;
215 }
216
217
218 if (toPartner > distanceFromThePartner) {
219 Vector3d myForceToPartner = new Vector3d(0,0,0);
220
221 double diff2 = partnersVectorToTarget.length() - myVectorToTarget.length();
222 if (waitForPartner && diff2 > 3 * distanceFromThePartner) {
223
224
225 if (fromFoot <= distanceFromThePartner/2) {
226 waiting = true;
227 wantsToStop.setValue(true);
228 focus.setTo(partner.getLocation());
229 if (SteeringManager.DEBUG) {
230 System.out.println("We reached the target and we stop.");
231 if (SteeringManager.Thomas) botself.getAct().act(new PlayAnimation().setName("social_wavefar").setLoop(true));
232 }
233 return nextVelocity;
234 } else {
235 double scale = 2 * fromFoot / distanceFromThePartner;
236 botToFoot.scale(partnerForce * scale);
237 botToPartner.scale(partnerForce * scale);
238 myForceToPartner.add(botToFoot);
239 myForceToPartner.add(botToPartner);
240 }
241 } else {
242 if (newWait && waiting) {
243 double distancesDifference = (partnersVectorToTarget.length() - myVectorToTarget.length());
244 System.out.println("Diff copy: "+distancesDifference);
245 if (distancesDifference > WAIT_DISTANCE) {
246 waiting = true;
247 wantsToStop.setValue(true);
248 focus.setTo(partner.getLocation());
249 if (SteeringManager.DEBUG) {
250 System.out.println("We are waiting, but partner is already near to us.");
251 }
252 return nextVelocity;
253 }
254 }
255
256 double angleToTarget = forceToTarget.angle(botself.getVelocity().asVector3d());
257
258
259
260
261
262
263
264 if (newToPartner && (angleToTarget > Math.PI/2)) {
265 footToBotCopy.normalize();
266 footToBotCopy.scale(distanceFromThePartner / 2);
267 Location nextToPartner = new Location(partner.getLocation().x + footToBotCopy.x, partner.getLocation().y + footToBotCopy.y, partner.getLocation().z);
268 myForceToPartner = new Vector3d(nextToPartner.x - botself.getLocation().x, nextToPartner.y - botself.getLocation().y, nextToPartner.z - botself.getLocation().z);
269 } else {
270 myForceToPartner.add(botToPartner);
271 }
272 double scale = (toPartner - distanceFromThePartner) / distanceFromThePartner;
273 myForceToPartner.normalize();
274 myForceToPartner.scale(partnerForce * scale);
275 if (SteeringManager.DEBUG) {
276 System.out.println("To partner " + myForceToPartner.length());
277 }
278
279
280
281
282
283
284
285 if (newToPartner2 && (angleToTarget > Math.PI / 2)) {
286 if (myForceToPartner.length() < partnerForce) {
287 Location betweenPaT = new Location((partner.getLocation().x + targetLocation.x) / 2, (partner.getLocation().y + targetLocation.y) / 2, (partner.getLocation().z + targetLocation.z) / 2);
288 Vector3d toPointBetween = new Vector3d(betweenPaT.x - botself.getLocation().x, betweenPaT.y - botself.getLocation().y, betweenPaT.z - botself.getLocation().z);
289 toPointBetween.normalize();
290 double scaleBetween = partnerForce - myForceToPartner.length();
291 toPointBetween.scale(scaleBetween);
292 myForceToPartner.add(toPointBetween);
293 forceFromPartner.scale(1 / 2);
294 }
295 }
296 }
297 forceToPartner = myForceToPartner;
298 } else {
299 forceToPartner = new Vector3d(0,0,0);
300 }
301
302 if (truncateToPartner) {
303 if (forceToPartner.length() > MAX_TO_PARTNER) {
304 forceToPartner.normalize();
305 forceToPartner.scale(MAX_TO_PARTNER);
306 }
307 }
308
309
310
311 waiting = false;
312 nextVelocity.add((Tuple3d)forceToTarget);
313 nextVelocity.add((Tuple3d)forceFromPartner);
314 nextVelocity.add((Tuple3d)forceToPartner);
315 if (SteeringManager.DEBUG) System.out.println("Vektor vysledny "+nextVelocity.length());
316
317 if (truncateNextVelocity) {
318 if (nextVelocity.length() > MAX_NEXT_VELOCITY) {
319 nextVelocity.normalize();
320 nextVelocity.scale(MAX_NEXT_VELOCITY);
321 }
322 }
323
324 wantsToGoFaster.setValue(false);
325 return nextVelocity;
326 }
327
328
329 private Player getPartner() {
330 UnrealId myId = botself.getWorldView().getSingle(Self.class).getId();
331 Collection<Player> col = botself.getWorldView().getAll(Player.class).values();
332 for (Player p : col) {
333 if (SteeringManager.DEBUG) System.out.println("Player "+p.getName());
334 if (p.getName().equals(partnerName) && p.getId() != myId) {
335 if (SteeringManager.DEBUG) System.out.println("Got the partner "+p.toString());
336 return p;
337 }
338 }
339 return null;
340 }
341 @Override
342 public void setProperties(SteeringProperties newProperties) {
343 this.partnerForce = ((WalkAlongProperties)newProperties).getPartnerForce();
344 this.partnerName = ((WalkAlongProperties)newProperties).getPartnerName();
345 this.targetLocation = ((WalkAlongProperties)newProperties).getTargetLocation();
346 this.distanceFromThePartner = ((WalkAlongProperties)newProperties).getDistanceFromThePartner();
347 this.giveWayToPartner = ((WalkAlongProperties)newProperties).isGiveWayToPartner();
348 this.waitForPartner = ((WalkAlongProperties)newProperties).isWaitForPartner();
349 }
350
351 public WalkAlongProperties getProperties() {
352 WalkAlongProperties properties = new WalkAlongProperties();
353 properties.setPartnerForce(partnerForce);
354 properties.setPartnerName(partnerName);
355 properties.setTargetLocation(targetLocation);
356 properties.setDistanceFromThePartner(distanceFromThePartner);
357 properties.setGiveWayToPartner(giveWayToPartner);
358 properties.setWaitForPartner(waitForPartner);
359 return properties;
360 }
361
362 public Vector3d getForceToPartner() {
363
364
365
366
367
368
369
370
371
372
373
374
375 return forceFromPartner;
376 }
377
378 public Vector3d getForceToTarget() {
379
380 return forceToPartner;
381 }
382
383 }