1 package cz.cuni.amis.pogamut.ut2004.agent.module.sensor.visibility;
2
3 import java.io.File;
4 import java.util.Map;
5 import java.util.Set;
6 import java.util.Map.Entry;
7 import java.util.logging.Logger;
8
9 import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
10 import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
11 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
12 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEvent;
13 import cz.cuni.amis.pogamut.base.communication.worldview.object.IWorldObjectEventListener;
14 import cz.cuni.amis.pogamut.base.utils.Pogamut;
15 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
16 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
17 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
18 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.visibility.model.VisibilityLocation;
19 import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.visibility.model.VisibilityMatrix;
20 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
21 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo;
22 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
23 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPointNeighbourLink;
24 import cz.cuni.amis.pogamut.ut2004.communication.translator.shared.events.MapPointListObtained;
25 import cz.cuni.amis.pogamut.ut2004.utils.PogamutUT2004Property;
26 import cz.cuni.amis.utils.ExceptionToString;
27 import cz.cuni.amis.utils.NullCheck;
28 import cz.cuni.amis.utils.SafeEquals;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class Visibility extends SensorModule<UT2004Bot>
43 {
44
45
46
47
48
49
50
51
52 public boolean isInitialized() {
53 return matrix != null;
54 }
55
56
57
58
59
60 public VisibilityMatrix getMatrix() {
61 return matrix;
62 }
63
64
65
66
67
68
69
70
71
72 public VisibilityLocation getNearestVisibilityLocationTo(ILocated located) {
73 if (!isInitialized()) return null;
74 return matrix.getNearest(located);
75 }
76
77
78
79
80
81
82
83
84 public VisibilityLocation getNearestVisibilityLocation() {
85 return getNearestVisibilityLocationTo(info.getLocation());
86 }
87
88
89
90
91
92
93
94 public NavPoint getNearestNavPointTo(ILocated located) {
95 if (!isInitialized()) return null;
96 return matrix.getNearestNavPoint(located);
97 }
98
99
100
101
102
103
104 public NavPoint getNearestNavPopint() {
105 return getNearestNavPointTo(info.getLocation());
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public boolean isVisible(ILocated loc1, ILocated loc2) {
121 if (!isInitialized()) return false;
122 return matrix.isVisible(loc1, loc2);
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136 public boolean isVisible(ILocated target) {
137 return isVisible(info.getLocation(), target);
138 }
139
140
141
142
143
144
145 public Set<VisibilityLocation> getCoverPointsFrom(ILocated loc) {
146 if (!isInitialized()) return null;
147 return matrix.getCoverPoints(loc);
148 }
149
150
151
152
153
154 public Set<VisibilityLocation> getHiddenPoints() {
155 return getCoverPointsFrom(info.getLocation());
156 }
157
158
159
160
161
162
163 public VisibilityLocation getNearestCoverPointFrom(ILocated enemy) {
164 if (!isInitialized()) return null;
165 return matrix.getNearestCoverPoint(info.getLocation(), enemy);
166 }
167
168
169
170
171
172
173
174
175 public Set<VisibilityLocation> getVisiblePointsFrom(ILocated loc) {
176 if (!isInitialized()) return null;
177 return matrix.getVisiblePoints(loc);
178 }
179
180
181
182
183
184 public Set<VisibilityLocation> getVisiblePoints() {
185 return getVisiblePointsFrom(info.getLocation());
186 }
187
188
189
190
191
192
193 public Set<NavPoint> getCoverNavPointsFrom(ILocated loc) {
194 if (!isInitialized()) return null;
195 return matrix.getCoverNavPoints(loc);
196 }
197
198
199
200
201
202 public Set<NavPoint> getHiddenNavPoints() {
203 return getCoverNavPointsFrom(info.getLocation());
204 }
205
206
207
208
209
210
211 public NavPoint getNearestCoverNavPointFrom(ILocated enemy) {
212 if (!isInitialized()) return null;
213 return matrix.getNearestCoverNavPoint(enemy);
214 }
215
216
217
218
219
220
221
222 public Set<NavPoint> getVisibleNavPointsFrom(ILocated loc) {
223 if (!isInitialized()) return null;
224 return matrix.getVisibleNavPoints(loc);
225 }
226
227
228
229
230
231 public Set<NavPoint> getVisibleNavPoints() {
232 if (!isInitialized()) return null;
233 return matrix.getVisibleNavPoints(info.getLocation());
234 }
235
236
237
238
239
240
241 public Set<VisibilityLocation> getCoverPointsFromN(ILocated... enemies) {
242 if (!isInitialized()) return null;
243 return matrix.getCoverPointsN(enemies);
244 }
245
246
247
248
249
250
251
252 public VisibilityLocation getNearestCoverPointFromN(ILocated target, ILocated... enemies) {
253 if (!isInitialized()) return null;
254 return matrix.getNearestCoverPointN(target, enemies);
255 }
256
257
258
259
260
261
262
263 public VisibilityLocation getNearestCoverPointN(ILocated... enemies) {
264 return getNearestCoverPointFromN(info.getLocation(), enemies);
265 }
266
267
268
269
270
271
272 public Set<NavPoint> getCoverNavPointsFromN(ILocated... enemies) {
273 if (!isInitialized()) return null;
274 return matrix.getCoverNavPointsN(enemies);
275 }
276
277
278
279
280
281
282
283 public NavPoint getNearestCoverNavPointFromN(ILocated target, ILocated... enemies) {
284 if (!isInitialized()) return null;
285 return matrix.getNearestCoverNavPointN(target, enemies);
286 }
287
288
289
290
291
292
293 public NavPoint getNearestCoverNavPointN(ILocated... enemies) {
294 return getNearestCoverNavPointFromN(info.getLocation(), enemies);
295 }
296
297
298
299
300
301
302
303
304
305
306
307 private class GameInfoListener implements IWorldObjectEventListener<GameInfo, IWorldObjectEvent<GameInfo>>
308 {
309 @Override
310 public void notify(IWorldObjectEvent<GameInfo> event)
311 {
312 lastGameInfo = event.getObject();
313 }
314
315
316
317
318
319 public GameInfoListener(IWorldView worldView)
320 {
321 worldView.addObjectListener(GameInfo.class, this);
322 }
323 }
324
325
326
327
328 private class MapPointListener implements IWorldEventListener<MapPointListObtained>
329 {
330 @Override
331 public void notify(MapPointListObtained event)
332 {
333 init(lastGameInfo, event);
334 }
335
336
337
338
339
340 public MapPointListener(IWorldView worldView)
341 {
342 worldView.addEventListener(MapPointListObtained.class, this);
343 }
344 }
345
346
347 GameInfoListener gameInfoListener;
348
349 GameInfo lastGameInfo;
350
351 MapPointListener mapPointListener;
352
353
354
355
356
357 VisibilityMatrix matrix = null;
358
359
360
361
362 AgentInfo info;
363
364
365
366
367
368
369 void init(GameInfo gameInfo, MapPointListObtained event) {
370 if (gameInfo == null || event == null) {
371 log.warning("Cannot initialize." + (gameInfo == null ? " GameInfo is NULL." : "") + (event == null ? " MapPoints is NULL." : ""));
372 return;
373 }
374
375 Map<UnrealId, NavPoint> navPoints = event.getNavPoints();
376 if (navPoints == null) {
377 log.warning("Cannot map visibility locations to NavPoints and Links, nav points not exported by GameBots2004...");
378 log.warning("Module cannot be initialized.");
379 return;
380 }
381
382 String mapName = gameInfo.getLevel();
383 log.info("Trying to initialize visibility matrix for map: " + mapName);
384
385 File file1 = VisibilityMatrix.getFile_All(new File("."), mapName);
386 log.info("Looking for file: " + file1.getAbsolutePath());
387
388 VisibilityMatrix visibilityMatrix = tryToLoadVisibilityMatrix(new File("."), mapName);
389 if (visibilityMatrix == null) {
390
391 String dir = Pogamut.getPlatform().getProperty(PogamutUT2004Property.POGAMUT_UT2004_VISIBILITY_DIRECTORY.getKey());
392 if (dir == null) {
393 log.warning("Could not load visibility information for " + mapName + ". File from local dir " + file1.getAbsolutePath() + " not found and property " + PogamutUT2004Property.POGAMUT_UT2004_VISIBILITY_DIRECTORY.getKey() + " not set.");
394 } else {
395 File dirFile = new File(dir);
396 if (dirFile.exists() && dirFile.isDirectory()) {
397 File file2 = VisibilityMatrix.getFile_All(dirFile, mapName);
398 log.info("Looking for file: " + file2.getAbsolutePath());
399 visibilityMatrix = tryToLoadVisibilityMatrix(new File("."), mapName);
400 if (visibilityMatrix == null) {
401 log.warning("Could not load visibility information for " + mapName + ". File from local dir " + file1.getAbsolutePath() + " not found and file from configured dir " + file2.getAbsolutePath() + " was not found as well.");
402 }
403 } else {
404 log.warning("Could not load visibility information for " + mapName + ". File from local dir " + file1.getAbsolutePath() + " not found and property " + PogamutUT2004Property.POGAMUT_UT2004_VISIBILITY_DIRECTORY.getKey() + " leads to non-dir " + dirFile.getAbsolutePath() + ".");
405 }
406 }
407 }
408
409 if (visibilityMatrix == null) {
410 log.warning("Visibility matrix was not loaded, module could not be initialized.");
411 return;
412 }
413
414 log.warning("Visibility matrix loaded successfully.");
415
416 log.info("Mapping navpoints and links...");
417
418 for (Entry<Integer, VisibilityLocation> vLocEntry : visibilityMatrix.getLocations().entrySet()) {
419 VisibilityLocation vLoc = vLocEntry.getValue();
420 if (vLoc.navPoint1Id != null) {
421 if (vLoc.navPoint2Id != null) {
422
423 String navPoint1Id = mapName + "." + vLoc.navPoint1Id;
424 NavPoint np1 = navPoints.get(UnrealId.get(navPoint1Id));
425 if (np1 == null) {
426 log.warning("Could not find navpoint (map changed? / old visibility matrix file?): " + navPoint1Id);
427 continue;
428 }
429 String navPoint2Id = mapName + "." + vLoc.navPoint2Id;
430 NavPoint np2 = navPoints.get(UnrealId.get(navPoint2Id));
431 if (np2 == null) {
432 log.warning("Could not find navpoint (map changed? / old visibility matrix file?): " + navPoint2Id);
433 continue;
434 }
435 NavPointNeighbourLink link = np1.getOutgoingEdges().get(np2.getId());
436 if (link == null) {
437 link = np2.getOutgoingEdges().get(np1.getId());
438 log.warning("Could not find navpoint link (map changed? / old visibility matrix file?): " + navPoint1Id + " <-> " + navPoint2Id);
439 continue;
440 }
441 vLoc.link = link;
442 continue;
443 } else {
444
445 String navPointId = mapName + "." + vLoc.navPoint1Id;
446 vLoc.navPoint = navPoints.get(UnrealId.get(navPointId));
447 if (vLoc.navPoint == null) {
448 log.warning("Could not find navpoint (map changed? / old visibility matrix file?): " + navPointId);
449 continue;
450 }
451 continue;
452 }
453 } else {
454 log.warning("Malformed VisibilityLocation under index " + vLocEntry.getKey() + ", it does not have navPoint1Id specified!");
455 }
456 }
457
458 this.matrix = visibilityMatrix;
459 log.warning("Navpoints and links mapped, module is ready to be used.");
460 }
461
462 private VisibilityMatrix tryToLoadVisibilityMatrix(File directory, String mapName) {
463 File file = VisibilityMatrix.getFile_All(directory, mapName);
464 if (file.exists() && file.isFile()) {
465 try {
466 VisibilityMatrix visibilityMatrix = VisibilityMatrix.load(directory, mapName);
467 if (!SafeEquals.equals(mapName, visibilityMatrix.getMapName())) {
468 log.warning("Expected to load visibility matrix for map " + mapName + ", but matrix for " + visibilityMatrix.getMapName() + " loaded instead! (Misplaced file?) Module cannot be used.");
469 return null;
470 }
471 return visibilityMatrix;
472 } catch (Exception e) {
473 log.warning(ExceptionToString.process("Failed to load visibility matrix from existing file " + file.getAbsolutePath() + ".", e));
474 }
475 }
476 return null;
477 }
478
479
480
481
482
483
484
485
486 public Visibility(UT2004Bot bot, AgentInfo info) {
487 this(bot, info, null);
488 }
489
490
491
492
493
494
495
496 public Visibility(UT2004Bot bot, AgentInfo info, Logger log)
497 {
498 super(bot, log);
499
500 this.info = info;
501 NullCheck.check(this.info, "agentInfo");
502
503
504 gameInfoListener = new GameInfoListener(worldView);
505 mapPointListener = new MapPointListener(worldView);
506
507 cleanUp();
508 }
509
510 @Override
511 protected void cleanUp() {
512 super.cleanUp();
513 matrix = null;
514 }
515
516 }