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