View Javadoc

1   package cz.cuni.amis.pogamut.ut2004.bot.impl;
2   
3   import java.util.Random;
4   import java.util.logging.Level;
5   
6   import cz.cuni.amis.pathfinding.map.IPFMapView;
7   import cz.cuni.amis.pogamut.base.agent.navigation.IPathPlanner;
8   import cz.cuni.amis.pogamut.base.agent.navigation.PathExecutorState;
9   import cz.cuni.amis.pogamut.base.communication.command.IAct;
10  import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
11  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.AnnotationListenerRegistrator;
12  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.EventListener;
13  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassEventListener;
14  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassListener;
15  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectEventListener;
16  import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectListener;
17  import cz.cuni.amis.pogamut.base.utils.math.DistanceUtils;
18  import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
19  import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
20  import cz.cuni.amis.pogamut.unreal.agent.navigation.IUnrealPathExecutor;
21  import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.AdrenalineCombo;
22  import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.AgentConfig;
23  import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Raycasting;
24  import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Weaponry;
25  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
26  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentStats;
27  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.CTF;
28  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Game;
29  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.ItemDescriptors;
30  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Items;
31  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.NavPoints;
32  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.NavigationGraphBuilder;
33  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Players;
34  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.Senses;
35  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.WeaponPrefs;
36  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.visibility.Visibility;
37  import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004GetBackToNavGraph;
38  import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004Navigation;
39  import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004PathExecutor;
40  import cz.cuni.amis.pogamut.ut2004.agent.navigation.IUT2004RunStraight;
41  import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004AStarPathPlanner;
42  import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004GetBackToNavGraph;
43  import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004Navigation;
44  import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004PathExecutor;
45  import cz.cuni.amis.pogamut.ut2004.agent.navigation.UT2004RunStraight;
46  import cz.cuni.amis.pogamut.ut2004.agent.navigation.astar.UT2004AStar;
47  import cz.cuni.amis.pogamut.ut2004.agent.navigation.floydwarshall.FloydWarshallMap;
48  import cz.cuni.amis.pogamut.ut2004.agent.navigation.loquenavigator.LoqueNavigator;
49  import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004DistanceStuckDetector;
50  import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004PositionStuckDetector;
51  import cz.cuni.amis.pogamut.ut2004.agent.navigation.stuckdetector.UT2004TimeStuckDetector;
52  import cz.cuni.amis.pogamut.ut2004.bot.IUT2004BotController;
53  import cz.cuni.amis.pogamut.ut2004.bot.command.AdvancedLocomotion;
54  import cz.cuni.amis.pogamut.ut2004.bot.command.CompleteBotCommandsWrapper;
55  import cz.cuni.amis.pogamut.ut2004.bot.command.ImprovedShooting;
56  import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
57  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.GetPath;
58  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.AutoTraceRay;
59  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange;
60  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage;
61  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.NavPoint;
62  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.PathList;
63  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Self;
64  import cz.cuni.amis.pogamut.ut2004.communication.translator.itemdescriptor.ItemDescriptor;
65  
66  /**
67   * The most advanced controller that is available. This controller contains all useful modules pre-instantiated.
68   *
69   * @author Jimmy
70   *
71   * @param <BOT>
72   */
73  public class UT2004BotModuleController<BOT extends UT2004Bot> extends UT2004BotLogicController<BOT> {
74  
75  	/**
76  	 * Random number generator that is usually useful to have during decision making.
77  	 */
78  	protected Random random = new Random(System.currentTimeMillis());
79  	
80  	/**
81  	 * Command module that is internally using {@link UT2004PathExecutor} for path-following and {@link FloydWarshallMap}
82  	 * for path planning resulting in unified class that can solely handle navigation of the bot within the environment.
83  	 * <p><p> 
84  	 * In contrast to {@link UT2004PathExecutor} methods
85  	 * of this module may be recalled every {@link UT2004BotModuleController#logic()} iteration even with 
86  	 * the same argument (which is not true for {@link UT2004PathExecutor#followPath(cz.cuni.amis.pogamut.base.agent.navigation.IPathFuture)}.
87  	 * <p><p>
88  	 * Note that this class is actually initialized with instances of {@link UT2004BotModuleController#pathExecutor} and {@link UT2004BotModuleController#fwMap}
89  	 * so you must take care if using add/remove stuck detectors or reinitilize this property to your liking (you can do that in {@link UT2004BotModuleController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
90  	 * method.
91  	 * <p><p>
92  	 * May be used since first {@link UT2004BotModuleController#logic()} is called.
93       * <p><p>
94       * Initialized inside {@link UT2004BotModuleController#initializePathFinding(UT2004Bot)}.
95  	 */
96  	protected IUT2004Navigation navigation;
97  	
98  	/**
99  	 * Memory module specialized on general info about the game - game type, time limit, frag limit, etc.
100 	 * <p><p>
101 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
102      * is called.
103      * <p><p>
104      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
105 	 */
106 	protected Game game;
107 	
108 	/**
109 	 * Memory module specialized on general info about the agent whereabouts - location, rotation, health, current weapon, who is enemy/friend, etc.
110 	 * <p><p>
111 	 * May be used since first {@link Self} message is received, i.e, since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
112      * is called.
113      * <p><p>
114      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
115 	 */
116 	protected AgentInfo info;
117 	
118 	/**
119 	 * Memory module specialized on whereabouts of other players - who is visible, enemy / friend, whether bot can see anybody, etc.
120 	 * <p><p>
121 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
122      * is called.
123      * <p><p>
124      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
125 	 */
126 	protected Players players;
127 	
128 	/**
129 	 * Sensory module that provides mapping between {@link ItemType} and {@link ItemDescriptor} providing
130      * an easy way to obtain item descriptors for various items in UT2004.
131      * <p><p>
132      * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
133      * is called.
134      * <p><p>
135      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
136 	 */
137 	protected ItemDescriptors descriptors;
138 	
139 	/**
140 	 * Memory module specialized on items on the map - which are visible and which are probably spawned.
141 	 * <p><p>
142 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
143      * is called.
144      * <p><p>
145      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
146 	 */
147 	protected Items items;
148 	
149 	/**
150 	 * Memory module specialized on agent's senses - whether the bot has been recently killed, collide with level's geometry, etc.
151 	 * <p><p>
152 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
153      * is called.
154      * <p><p>
155      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
156 	 */
157 	protected Senses senses;
158 	
159 	/**
160 	 * Memory module specialized on info about the bot's weapon and ammo inventory - it can tell you which weapons are loaded, melee/ranged, etc.
161 	 * <p><p>
162 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
163      * is called.
164      * <p><p>
165      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
166 	 */
167 	protected Weaponry weaponry;
168 	
169 	/**
170 	 * Memory module specialized on the agent's configuration inside UT2004 - name, vision time, manual spawn, cheats (if enabled at GB2004).
171 	 * <p><p>
172 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
173      * is called.
174      * <p><p>
175      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
176 	 */
177 	protected AgentConfig config;
178 	
179 	/**
180 	 * Support for creating rays used for raycasting (see {@link AutoTraceRay} that is being utilized).
181 	 * <p><p>
182 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.InitedMessage)}
183      * is called.
184      * <p><p>
185      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
186 	 */
187 	protected Raycasting raycasting;
188 	
189 	/**
190 	 * Wraps all available commands that can be issued to the virtual body of the bot inside UT2004.
191      * <p><p>
192      * May be used since since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
193      * is called.
194      * <p><p>
195      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
196 	 */
197 	protected CompleteBotCommandsWrapper body;
198 	
199 	/**
200 	 * Shortcut for <i>body.getAdvancedShooting()</i> that allows you to shoot at opponent.
201 	 * <p><p>
202 	 * Note: more weapon-handling methods are available through {@link UT2004BotModuleControllerNew#weaponry}.
203 	 * <p><p>
204 	 * May be used since since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
205      * is called.
206      * <p><p>
207 	 * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
208 	 */
209 	protected ImprovedShooting shoot;
210 	
211 	/**
212 	 * Shortcut for <i>body.getAdvancedLocomotion()</i> that allows you to manually steer the movement through the environment.
213 	 * <p><p>
214 	 * Note: navigation is done via {@link UT2004BotModuleControllerNew#pathExecutor} that needs {@link PathHandle} from the {@link UT2004BotModuleControllerNew#pathPlanner}.
215 	 * <p><p>
216 	 * May be used since since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
217      * is called.
218      * <p><p>
219 	 * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
220 	 */
221 	protected AdvancedLocomotion move;
222 	
223 	/**
224 	 * Module specialized on CTF games. Enabled only for CTF games, check {@link CTF#isEnabled()}.
225 	 * <p><p>
226 	 * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
227 	 */
228 	protected CTF ctf;
229 	
230 	/**
231 	 * Module for adrenaline combos.
232 	 */
233 	protected AdrenalineCombo combo;
234 	
235 	/**
236      * Executor is used for following a path in the environment.
237      * <p><p>
238      * May be used since since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
239      * is called.
240      * <p><p>
241      * Initialized inside {@link UT2004BotModuleController#initializePathFinding(UT2004Bot)}.
242      * <p><p>
243      * {@link UT2004PathExecutor#addStuckDetector(cz.cuni.amis.pogamut.base.agent.navigation.IStuckDetector)} is initialized with default stuck detectors:
244      * {@link UT2004TimeStuckDetector}, {@link UT2004PositionStuckDetector}, {@link UT2004DistanceStuckDetector}.
245      * <p><p>
246      * If one of stuck detectors (heuristicly) finds out that the bot has stuck somewhere,
247      * it reports it back to {@link UT2004PathExecutor} and the path executor will stop following the path switching
248      * itself to {@link PathExecutorState#STUCK}, which in turn allows us to issue another follow-path command in the right time.
249      */
250 	protected IUT2004PathExecutor<ILocated> pathExecutor = null;
251 	
252     /**
253      * Planner used to compute the path (consisting of navigation points) inside the map.
254      * <p><p>
255      * May be used since since the first {@link IUT2004BotController#botFirstSpawn(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)} 
256      * is called.
257      * <p><p>
258      * Initialized inside {@link UT2004BotModuleController#initializePathFinding(UT2004Bot)}.
259      */
260     protected IPathPlanner<ILocated> pathPlanner = null;
261     
262     /**
263      * Navigation graph builder that may be used to manually extend the navigation graph of the UT2004.
264      * <p><p>
265      * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
266      * is called.
267      * <p><p>
268      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
269      */
270     protected NavigationGraphBuilder navBuilder = null;
271     
272     /**
273      * Listener registrator that probes declared methods for the presence of {@link EventListener}, {@link ObjectClassEventListener},
274      * {@link ObjectClassListener}, {@link ObjectEventListener} and {@link ObjectListener} annotations and automatically registers
275      * them as listeners on a specific events.
276      * <p><p>
277      * Note that this registrator is usable for 'this' object only! It will work only for 'this' object.
278      */
279     protected AnnotationListenerRegistrator listenerRegistrator;
280     
281     /**
282      * Weapon preferences for your bot. See {@link WeaponPrefs} class javadoc. It allows you to define preferences for
283      * weapons to be used at given distance (together with their firing modes).
284      */
285     protected WeaponPrefs weaponPrefs;
286     
287     /**
288      * Shortcut for the {@link UT2004Bot#getWorldView()}.
289      */
290     protected IVisionWorldView world;
291     
292     /**
293      * Shortcut for the {@link UT2004Bot#getAct()}.
294      */
295     protected IAct act;
296     
297     /**
298      * Module that is providing various statistics about the bot. You may also used it to output these stats (in CSV format)
299      * into some file using {@link AgentStats#startOutput(String)} or {@link AgentStats#startOutput(String, boolean)}.
300      */
301     protected AgentStats stats;
302 
303     /**
304      * Path-planner ({@link IPathPlanner} using {@link NavPoint}s), you may use it to find paths inside the environment wihtout
305      * waiting for round-trip of {@link GetPath} command and {@link PathList}s response from UT2004. It is much faster than 
306      * {@link UT2004BotModuleController#pathPlanner} but you need to pass {@link NavPoint} instances to planner instead of
307      * {@link ILocated} ... to find the nearest {@link NavPoint} instance, {@link DistanceUtils} is a handy, check especially
308      * {@link DistanceUtils#getNearest(java.util.Collection, ILocated)}.
309      */
310 	protected FloydWarshallMap fwMap;
311 	
312 	/**
313 	 * Navigation helper that is able to get your bot back to the nearest navigation graph so you can use {@link UT2004BotModuleController#navigation} 
314 	 * without fear of catastrophe.
315 	 * <p><p>
316 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
317      * is called.
318      * <p><p>
319      * Initialized inside {@link UT2004BotModuleController#initializePathFinding(UT2004Bot)}.
320 	 */
321 	protected IUT2004GetBackToNavGraph getBackToNavGraph;
322 	
323 	/**
324 	 * Navigation helper that can run-straight to some point with stuck detectors.
325 	 * <p><p>
326 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
327      * is called.
328      * <p><p>
329      * Initialized inside {@link UT2004BotModuleController#initializePathFinding(UT2004Bot)}.
330 	 */
331 	protected IUT2004RunStraight runStraight;
332 	
333 	/**
334 	 * Module that provides visibility/cover information for the map.
335 	 * <p><p>
336 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
337      * is called.
338      * <p><p>
339      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
340 	 */
341 	protected Visibility visibility;
342 	
343 	/**
344 	 * Module that provides shortcut for getting {@link NavPoint}s out of {@link IWorldView}.
345 	 * <p><p>
346 	 * May be used since {@link IUT2004BotController#botInitialized(cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage)} 
347      * is called.
348      * <p><p>
349      * Initialized inside {@link UT2004BotModuleController#initializeModules(UT2004Bot)}.
350 	 */
351 	protected NavPoints navPoints;
352 	
353 	/**
354 	 * Class providing A-Star algorithm over the navpoints as they are present within the {@link IWorldView}.
355 	 * <p><p>
356 	 * You may provide custom {@link IPFMapView} over the map in-order to greatly customize the A-Star search.
357 	 */
358 	protected UT2004AStar aStar;
359 	
360     @Override
361 	public void initializeController(BOT bot) {    	
362 		super.initializeController(bot);
363 		world = getWorldView();
364 		act = getAct();
365 		initializeModules(bot);
366 		initializePathFinding(bot);
367 		initializeListeners(bot);
368 	}
369 	
370     /**
371      * Initializes {@link UT2004BotModuleControllerNew#listenerRegistrator} and calls {@link AnnotationListenerRegistrator#addListeners()} method
372      * to probe all declared methods for event-annotation presence.
373      * @param bot
374      */
375 	protected void initializeListeners(BOT bot) {
376 		listenerRegistrator = new AnnotationListenerRegistrator(this, getWorldView(), bot.getLogger().getCategory("Listeners"));
377 		listenerRegistrator.addListeners();
378 	}
379 
380 	/**
381 	 * Initializes path-finding modules: {@link UT2004BotModuleControllerNew#pathPlanner}, {@link UT2004BotModuleController#fwMap} and {@link UT2004BotModuleControllerNew#pathExecutor}.
382 	 * If you need different path planner / path executor - override this method and initialize your own modules.
383 	 * @param bot
384 	 */
385 	protected void initializePathFinding(BOT bot) {
386 		pathPlanner  = new UT2004AStarPathPlanner(bot);
387 		fwMap        = new FloydWarshallMap(bot);
388 		aStar        = new UT2004AStar(bot);		
389 		pathExecutor = 
390         	new UT2004PathExecutor<ILocated>(
391         		bot, 
392         		new LoqueNavigator<ILocated>(bot, bot.getLog()), 
393         		bot.getLog()
394         	);
395 		
396 		// add stuck detectors that watch over the path-following, if it (heuristicly) finds out that the bot has stuck somewhere,
397     	// it reports an appropriate path event and the path executor will stop following the path which in turn allows 
398     	// us to issue another follow-path command in the right time
399         pathExecutor.addStuckDetector(new UT2004TimeStuckDetector(bot, 3000, 100000)); // if the bot does not move for 3 seconds, considered that it is stuck
400         pathExecutor.addStuckDetector(new UT2004PositionStuckDetector(bot));           // watch over the position history of the bot, if the bot does not move sufficiently enough, consider that it is stuck
401         pathExecutor.addStuckDetector(new UT2004DistanceStuckDetector(bot));           // watch over distances to target
402         
403 		getBackToNavGraph = new UT2004GetBackToNavGraph(bot, info, move);
404 		runStraight = new UT2004RunStraight(bot, info, move);
405 		navigation = new UT2004Navigation(bot, pathExecutor, fwMap, getBackToNavGraph, runStraight);                
406 	}
407 
408 	/**
409 	 * Initializes memory/command modules of the bot.
410 	 * 
411 	 * @param bot
412 	 */
413 	protected void initializeModules(BOT bot) {
414 		game        = new Game(bot);
415 		navPoints   = new NavPoints(bot);
416 		players     = new Players(bot);
417 		descriptors = new ItemDescriptors(bot);
418 		config      = new AgentConfig(bot);
419 		raycasting  = new Raycasting(bot);
420 		stats       = new AgentStats(bot);
421 		navBuilder  = new NavigationGraphBuilder(bot);
422 		info        = new AgentInfo(bot, game);
423 		visibility  = new Visibility(bot, info);
424 		ctf         = new CTF(bot, info);
425 		weaponry    = new Weaponry(bot, descriptors);
426 		items       = new Items(bot, info, game, weaponry, null);
427 		senses      = new Senses(bot, info, players);
428 		body        = new CompleteBotCommandsWrapper(bot, weaponry, null);		
429 		shoot       = body.getImprovedShooting();
430 		move        = body.getLocomotion();
431 		weaponPrefs = new WeaponPrefs(weaponry, bot);
432 		combo       = new AdrenalineCombo(bot, info);		
433 	}
434 	
435 	@Override
436 	public void finishControllerInitialization() {
437 		if (navBuilder.isUsed()) {
438 			log.info("Navigation graph has been altered by 'navBuilder', triggering recomputation of Floyd-Warshall path matrix...");
439 			Level oldLevel = fwMap.getLog().getLevel();
440 			fwMap.getLog().setLevel(Level.FINER);
441 			fwMap.refreshPathMatrix();
442 			fwMap.getLog().setLevel(oldLevel);
443 			
444 			aStar.mapChanged();
445 		}
446 	}
447 
448 	//
449 	//
450 	// MODULE GETTERS
451 	//
452 	//
453 	
454 	public Random getRandom() {
455 		return random;
456 	}
457 	
458 	public UT2004AStar getAStar() {
459 		return aStar;
460 	}
461 
462 	public Game getGame() {
463 		return game;
464 	}
465 
466 	public AgentInfo getInfo() {
467 		return info;
468 	}
469 
470 	public Players getPlayers() {
471 		return players;
472 	}
473 
474 	public ItemDescriptors getDescriptors() {
475 		return descriptors;
476 	}
477 
478 	public Items getItems() {
479 		return items;
480 	}
481 
482 	public Senses getSenses() {
483 		return senses;
484 	}
485 
486 	public Weaponry getWeaponry() {
487 		return weaponry;
488 	}
489 
490 	public AgentConfig getConfig() {
491 		return config;
492 	}
493 
494 	public Raycasting getRaycasting() {
495 		return raycasting;
496 	}
497 
498 	public CompleteBotCommandsWrapper getBody() {
499 		return body;
500 	}
501 
502 	public ImprovedShooting getShoot() {
503 		return shoot;
504 	}
505 
506 	public AdvancedLocomotion getMove() {
507 		return move;
508 	}
509 
510 	public IUnrealPathExecutor<ILocated> getPathExecutor() {
511 		return pathExecutor;
512 	}
513 
514 	public IPathPlanner<ILocated> getPathPlanner() {
515 		return pathPlanner;
516 	}
517 	
518 	public AdrenalineCombo getCombo() {
519 		return combo;
520 	}
521 
522 	public NavigationGraphBuilder getNavBuilder() {
523 		return navBuilder;
524 	}
525 
526 	public WeaponPrefs getWeaponPrefs() {
527 		return weaponPrefs;
528 	}
529 
530 	public IVisionWorldView getWorld() {
531 		return world;
532 	}
533 
534 	public AgentStats getStats() {
535 		return stats;
536 	}
537 
538 	public FloydWarshallMap getFwMap() {
539 		return fwMap;
540 	}
541 	
542 	public IUT2004Navigation getNavigation() {
543 		return navigation;
544 	}
545 
546 	public Visibility getVisibility() {
547 		return visibility;
548 	}
549 
550 }