View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.tag.bot;
2   
3   import java.util.Map;
4   
5   import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
6   import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
7   import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId;
8   import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
9   import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Players;
10  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
11  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BeginMessage;
12  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
13  import cz.cuni.amis.pogamut.ut2004.tag.protocol.TagMessagesTranslator;
14  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagGameEnd;
15  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagGameRunning;
16  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagGameStart;
17  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagPassed;
18  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagPlayerImmunity;
19  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagPlayerScoreChanged;
20  import cz.cuni.amis.pogamut.ut2004.tag.protocol.messages.TagPlayerStatusChanged;
21  import cz.cuni.amis.pogamut.ut2004.tag.server.BotTagRecord;
22  import cz.cuni.amis.pogamut.ut2004.tag.server.UT2004TagServer;
23  import cz.cuni.amis.utils.flag.Flag;
24  import cz.cuni.amis.utils.flag.ImmutableFlag;
25  import cz.cuni.amis.utils.maps.LazyMap;
26  
27  public class BotTagModule extends SensorModule<UT2004Bot>{
28  
29  	// =======
30  	// MODULES
31  	// =======
32  	
33  	private AgentInfo info;
34  	
35  	private Players players;
36  	
37  	// ==========
38  	// TAG EVENTS
39  	// ==========
40  	
41  	private TagMessagesTranslator tagTranslator;
42  	
43  	private TagEvents tagEvents;
44  	
45  	private IWorldEventListener<BeginMessage> beginMessageListener = new IWorldEventListener<BeginMessage>() {
46  
47  		@Override
48  		public void notify(BeginMessage event) {
49  			beginMessage(event);
50  		}
51  		
52  	};
53  	
54  	// =============
55  	// TAG GAME DATA
56  	// =============
57  	
58  	private Flag<Boolean> gameRunning = new Flag<Boolean>(false);
59  	
60  	private Map<UnrealId, BotTagRecord<Player>> records = new LazyMap<UnrealId, BotTagRecord<Player>>() {
61  		@Override
62  		protected BotTagRecord<Player> create(UnrealId key) {
63  			return new BotTagRecord<Player>(key);
64  		}
65  	};
66  
67  	private TagGameStart tagSettings;
68  
69  	private long simTimeCurrent;
70  	
71  	public BotTagModule(UT2004Bot agent, AgentInfo info, Players players) {
72  		super(agent);
73  		
74  		this.info = info;
75  		if (info == null) {
76  			info = new AgentInfo(agent);
77  		}
78  		
79  		this.players = players;
80  		if (this.players == null) {
81  			this.players = new Players(agent);
82  		}
83  		
84  		tagTranslator = new TagMessagesTranslator(agent.getWorldView(), false);
85  		
86  		tagEvents = new TagEvents(agent.getWorldView()) {
87  			public void tagGameStart(TagGameStart event) {
88  				BotTagModule.this.tagGameStart(event);
89  			}
90  			
91  			@Override
92  			public void tagGameRunning(TagGameRunning event) {
93  				BotTagModule.this.tagGameRunning(event);
94  			}
95  			
96  			public void tagGameEnd(TagGameEnd event) {
97  				BotTagModule.this.tagGameEnd(event);
98  			}
99  			
100 			public void tagPassed(TagPassed event) {
101 				BotTagModule.this.tagPassed(event);
102 			}
103 			
104 			public void tagPlayerImmunity(TagPlayerImmunity event) {
105 				BotTagModule.this.tagPlayerImmunity(event);
106 			}
107 			
108 			public void tagPlayerScoreChanged(TagPlayerScoreChanged event) {
109 				BotTagModule.this.tagPlayerScoreChanged(event);
110 			}
111 			
112 			public void tagPlayerStatusChanged(TagPlayerStatusChanged event) {
113 				BotTagModule.this.tagPlayerStatusChanged(event);
114 			}
115 		};
116 		
117 		agent.getWorldView().addEventListener(BeginMessage.class, beginMessageListener);
118 	}
119 	
120 	// ==============
121 	// USEFUL GETTERS
122 	// ==============
123 	
124 	/**
125 	 * Your BOT {@link UnrealId}.
126 	 * @return
127 	 */
128 	public UnrealId getId() {
129 		return info.getId();
130 	}
131 	
132 	/**
133 	 * Whether TAG-GAME has been started.
134 	 * @return
135 	 */
136 	public boolean isGameRunning() {
137 		return gameRunning.getFlag();
138 	}
139 	
140 	/**
141 	 * Whether TAG-GAME has been started.
142 	 * @return
143 	 */
144 	public ImmutableFlag<Boolean> getGameRunningFlag() {
145 		return gameRunning.getImmutable();
146 	}
147 	
148 	/**
149 	 * When some bot reached THIS score, the game ends prematurely.
150 	 * @return
151 	 */
152 	public int getGameMaxScore() {
153 		if (tagSettings == null) return -1;
154 		return tagSettings.getGameMaxScore();
155 	}
156 	
157 	/**
158 	 * In seconds, total time that has passed since the game start.
159 	 * @return
160 	 */
161 	public double getGameTime() {
162 		if (tagSettings == null) return -1;
163 		return ((double)(simTimeCurrent - tagSettings.getSimTime())) / (double)1000;
164 	}
165 	
166 	/**
167 	 * In seconds, time remaining before the tag-game ends.
168 	 * @return
169 	 */
170 	public double getRemainingTime() {
171 		if (tagSettings == null) return -1;
172 		return ((double)(tagSettings.getGameTimeUT() * 1000)) - getGameTime();
173 	}
174 	
175 	/**
176 	 * How close you have to get to the bot to pass the tag (and vice versa).
177 	 * @return
178 	 */
179 	public double getTagDistance() {
180 		if (tagSettings == null) return -1;
181 		return tagSettings.getTagPassDistance();
182 	}
183 	
184 	/**
185 	 * Whether YOUR-BOT is immune to other bot (it cannot pass the tag to you).
186 	 * @param botId
187 	 * @return
188 	 */
189 	public boolean isMeImmune(UnrealId botId) {
190 		if (botId == null) return false;
191 		
192 		if (getId() == null) return false;
193 		
194 		return ensureRecord(getId()).getImmunity() == botId;
195 	}
196 	
197 	/**
198 	 * Whether YOUR-BOT is immune to other bot (it cannot pass the tag to you).
199 	 * @param bot
200 	 * @return
201 	 */
202 	public boolean isMeImmune(Player bot) {
203 		if (bot == null) return false;
204 		return isMeImmune(bot.getId());
205 	}
206 	
207 	/**
208 	 * Whether OTHER-BOT is immune to you (you cannot pass the tag to it).
209 	 * @param botId
210 	 * @return
211 	 */
212 	public boolean isImmuneToMe(UnrealId botId) {
213 		if (botId == null) return false;
214 		
215 		if (getId() == null) return false;
216 		
217 		return ensureRecord(botId).getImmunity() == getId();
218 	}
219 	
220 	/**
221 	 * Whether OTHER-BOT is immune to you (you cannot pass the tag to it).
222 	 * @param bot
223 	 * @return
224 	 */
225 	public boolean isImmuneToMe(Player bot) {
226 		if (bot == null) return false;
227 		return isImmuneToMe(bot.getId());
228 	}
229 	
230 	/**
231 	 * How many times YOU-BOT has been tagged by other bot (excluding tags assigned as random by the server).
232 	 * @return
233 	 */
234 	public int getMyScore() {
235 		if (getId() == null) return 0;
236 		return ensureRecord(getId()).getScore();
237 	}
238 	
239 	/**
240 	 * How many times OTHER-BOT has been tagged by yet-another bot (excluding tags assigned as random by the server).
241 	 * @param botId
242 	 * @return
243 	 */
244 	public int getScore(UnrealId botId) {
245 		if (botId == null) return 0;
246 		
247 		return ensureRecord(botId).getScore();
248 	}
249 	
250 	/**
251 	 * Whether YOUR-BOT has the tag (should chase others non-immune-to-you).
252 	 * @return
253 	 */
254 	public boolean hasTag() {
255 		if (getId() == null) return false;
256 		return ensureRecord(getId()).isHasTag();
257 	}
258 	
259 	/**
260 	 * Whether OTHER-BOT has the tag (should chase others non-immune-to-it).
261 	 * @return
262 	 */
263 	public boolean hasTag(UnrealId botId) {
264 		if (botId == null) return false;
265 		if (getId() == null) return false;
266 		
267 		return ensureRecord(botId).isHasTag();
268 	}
269 	
270 	/**
271 	 * Whether OTHER-BOT has the tag (should chase others non-immune-to-it).
272 	 * @return
273 	 */
274 	public boolean hasTag(Player bot) {
275 		return hasTag(bot);
276 	}
277 	
278 	// ==============
279 	// EVENT HANDLERS
280 	// ==============
281 	
282 	protected void beginMessage(BeginMessage event) {
283 		simTimeCurrent = event.getSimTime();
284 	}
285 	
286 	protected void tagGameStart(TagGameStart event) {
287 		resetTagGameData();
288 		tagSettings = event;
289 		gameRunning.setFlag(true);
290 	}
291 	
292 	protected void tagGameRunning(TagGameRunning event) {
293 		if (gameRunning.getFlag()) return;
294 		
295 		resetTagGameData();			
296 		tagSettings = new TagGameStart();
297 		tagSettings.setGameMaxScore(event.getGameMaxScore());
298 		tagSettings.setGameTimeUT(event.getGameTimeUT());
299 		tagSettings.setTagPassDistance(event.getTagPassDistance());
300 		gameRunning.setFlag(true);
301 	}
302 		
303 	protected void tagGameEnd(TagGameEnd event) {
304 		gameRunning.setFlag(false);
305 	}
306 	
307 	protected void tagPassed(TagPassed event) {
308 		if (event.getFromBotId() != null) {
309 			ensureRecord(event.getFromBotId()).tagPassed(event.getToBotId());
310 		}
311 		if (event.getToBotId() != null) {
312 			ensureRecord(event.getToBotId()).tagged(event.getFromBotId());
313 		}
314 	}
315 	
316 	protected void tagPlayerImmunity(TagPlayerImmunity event) {
317 		if (event.getBotId() == null) return;
318 		
319 		BotTagRecord<Player> record = ensureRecord(event.getBotId());
320 		ensureRecord(event.getImmuneFromBotId());
321 				
322 		if (event.getStatus()) {
323 			if (event.getImmuneFromBotId() == null) record.setImmunity(null);
324 			else record.setImmunity(event.getImmuneFromBotId());
325 		} else {
326 			record.setImmunity(null);
327 		}
328 		
329 		if (event.getBotId() == getId()) {
330 			if (event.getStatus()) {
331 				Player plr = players.getPlayer(event.getImmuneFromBotId());
332 				agent.getBotName().setInfo("IMUNE", plr == null ? "???" : players.getPlayerName(event.getImmuneFromBotId(), true));				
333 			} else {
334 				agent.getBotName().deleteInfo("IMUNE");
335 			}
336 		}
337 	}
338 	
339 	protected void tagPlayerScoreChanged(TagPlayerScoreChanged event) {
340 		if (event.getBotId() == null) return;
341 		
342 		BotTagRecord<Player> record = ensureRecord(event.getBotId());
343 		record.setScore(event.getScore());
344 		
345 		if (event.getBotId() == getId()) {
346 			agent.getBotName().setInfo("T", String.valueOf(event.getScore()));
347 		}
348 	}
349 	
350 	protected void tagPlayerStatusChanged(TagPlayerStatusChanged event) {
351 		if (event.getBotId() == null) return;
352 		
353 		BotTagRecord<Player> record = ensureRecord(event.getBotId());
354 		record.setHasTag(event.getTagStatus());
355 		
356 		if (event.getBotId() == getId()) {
357 			if (event.getTagStatus()) {
358 				agent.getBotName().setTag("TAG");
359 			} else {
360 				agent.getBotName().deleteTag("TAG");	
361 			}
362 		}
363 	}
364 	
365 	// =====
366 	// UTILS
367 	// =====
368 	
369 	private BotTagRecord<Player> ensureRecord(UnrealId botId) {
370 		if (botId == null || botId == UT2004TagServer.SERVER_UNREAL_ID) return null;
371 		if (records.containsKey(botId)) return records.get(botId);
372 		BotTagRecord<Player> record = records.get(botId);
373 		record.setInGame(true);
374 		return record;
375 	}
376 	
377 	private void resetTagGameData() {
378 		tagSettings = null;
379 		records.clear();
380 	}
381 
382 	// ==========
383 	// LIFE-CYCLE
384 	// ==========
385 	
386 	@Override
387 	protected void start(boolean startToPaused) {
388 		super.start(startToPaused);
389 		tagTranslator.enable();
390 		tagEvents.enableTagEvents();
391 	}
392 	
393 	@Override
394 	protected void cleanUp() {
395 		super.cleanUp();
396 		tagTranslator.disable();
397 		tagEvents.disableTagEvents();		
398 	}
399 
400 }