1 package cz.cuni.amis.pogamut.udk.bot.impl;
2
3 import java.util.Random;
4
5 import cz.cuni.amis.pogamut.base.agent.navigation.IPathExecutor;
6 import cz.cuni.amis.pogamut.base.agent.navigation.IPathPlanner;
7 import cz.cuni.amis.pogamut.base.communication.command.IAct;
8 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.AnnotationListenerRegistrator;
9 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.EventListener;
10 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassEventListener;
11 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectClassListener;
12 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectEventListener;
13 import cz.cuni.amis.pogamut.base.communication.worldview.listener.annotation.ObjectListener;
14 import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
15 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
16 import cz.cuni.amis.pogamut.udk.agent.module.sensomotoric.AgentConfig;
17 import cz.cuni.amis.pogamut.udk.agent.module.sensomotoric.Raycasting;
18 import cz.cuni.amis.pogamut.udk.agent.module.sensomotoric.Weaponry;
19 import cz.cuni.amis.pogamut.udk.agent.module.sensor.AgentInfo;
20 import cz.cuni.amis.pogamut.udk.agent.module.sensor.Game;
21 import cz.cuni.amis.pogamut.udk.agent.module.sensor.ItemDescriptors;
22 import cz.cuni.amis.pogamut.udk.agent.module.sensor.Items;
23 import cz.cuni.amis.pogamut.udk.agent.module.sensor.Players;
24 import cz.cuni.amis.pogamut.udk.agent.module.sensor.Senses;
25 import cz.cuni.amis.pogamut.udk.agent.navigation.UDKAStarPathPlanner;
26 import cz.cuni.amis.pogamut.udk.agent.navigation.UDKPathExecutor;
27 import cz.cuni.amis.pogamut.udk.bot.IUDKBotController;
28 import cz.cuni.amis.pogamut.udk.bot.command.AdvancedLocomotion;
29 import cz.cuni.amis.pogamut.udk.bot.command.AdvancedShooting;
30 import cz.cuni.amis.pogamut.udk.bot.command.CompleteBotCommandsWrapper;
31 import cz.cuni.amis.pogamut.udk.communication.messages.ItemType;
32 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.AutoTraceRay;
33 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange;
34 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage;
35 import cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.Self;
36 import cz.cuni.amis.pogamut.udk.communication.translator.itemdescriptor.ItemDescriptor;
37
38 /**
39 * The most advanced controller that is available. This controller contains all useful modules instantiated.
40 * <p><p>
41 * Modules currently available:<p>
42 * <ol>
43 * <li></li>
44 * </ol>
45 *
46 * @author Jimmy
47 *
48 * @param <BOT>
49 */
50 public class UDKBotModuleController<BOT extends UDKBot> extends UDKBotLogicController<BOT> {
51
52 /**
53 * Random number generator that is usually useful to have during decision making.
54 */
55 protected Random random = new Random(System.currentTimeMillis());
56
57 /**
58 * Memory module specialized on general info about the game - game type, time limit, frag limit, etc.
59 * <p><p>
60 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
61 * is called.
62 * <p><p>
63 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
64 */
65 protected Game game;
66
67 /**
68 * Memory module specialized on general info about the agent whereabouts - location, rotation, health, current weapon, who is enemy/friend, etc.
69 * <p><p>
70 * May be used since first {@link Self} message is received, i.e, since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
71 * is called.
72 * <p><p>
73 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
74 */
75 protected AgentInfo info;
76
77 /**
78 * Memory module specialized on whereabouts of other players - who is visible, enemy / friend, whether bot can see anybody, etc.
79 * <p><p>
80 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
81 * is called.
82 * <p><p>
83 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
84 */
85 protected Players players;
86
87 /**
88 * Sensory module that provides mapping between {@link ItemType} and {@link ItemDescriptor} providing
89 * an easy way to obtain item descriptors for various items in UDK.
90 * <p><p>
91 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
92 * is called.
93 * <p><p>
94 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
95 */
96 protected ItemDescriptors descriptors;
97
98 /**
99 * Memory module specialized on items on the map - which are visible and which are probably spawned.
100 * <p><p>
101 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
102 * is called.
103 * <p><p>
104 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
105 */
106 protected Items items;
107
108 /**
109 * Memory module specialized on agent's senses - whether the bot has been recently killed, collide with level's geometry, etc.
110 * <p><p>
111 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
112 * is called.
113 * <p><p>
114 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
115 */
116 protected Senses senses;
117
118 /**
119 * Memory module specialized on info about the bot's weapon and ammo inventory - it can tell you which weapons are loaded, melee/ranged, etc.
120 * <p><p>
121 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
122 * is called.
123 * <p><p>
124 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
125 */
126 protected Weaponry weaponry;
127
128 /**
129 * Memory module specialized on the agent's configuration inside UDK - name, vision time, manual spawn, cheats (if enabled at GB2004).
130 * <p><p>
131 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
132 * is called.
133 * <p><p>
134 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
135 */
136 protected AgentConfig config;
137
138 /**
139 * Support for creating rays used for raycasting (see {@link AutoTraceRay} that is being utilized).
140 * <p><p>
141 * May be used since {@link IUDKBotController#botInitialized(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.ConfigChange, cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.InitedMessage)}
142 * is called.
143 */
144 protected Raycasting raycasting;
145
146 /**
147 * Wraps all available commands that can be issued to the virtual body of the bot inside UDK.
148 * <p><p>
149 * May be used since since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
150 * is called.
151 * <p><p>
152 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
153 */
154 protected CompleteBotCommandsWrapper body;
155
156 /**
157 * Shortcut for <i>body.getAdvancedShooting()</i> that allows you to shoot at opponent.
158 * <p><p>
159 * Note: more weapon-handling methods are available through {@link UDKBotModuleControllerNew#weaponry}.
160 * <p><p>
161 * May be used since since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
162 * is called.
163 * <p><p>
164 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
165 */
166 protected AdvancedShooting shoot;
167
168 /**
169 * Shortcut for <i>body.getAdvancedLocomotion()</i> that allows you to manually steer the movement through the environment.
170 * <p><p>
171 * Note: navigation is done via {@link UDKBotModuleControllerNew#pathExecutor} that needs {@link PathHandle} from the {@link UDKBotModuleControllerNew#pathPlanner}.
172 * <p><p>
173 * May be used since since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
174 * is called.
175 * <p><p>
176 * Initialized inside {@link UDKBotModuleControllerNew#initializeModules(UDKBot)}.
177 */
178 protected AdvancedLocomotion move;
179
180 /**
181 * Executor is used for following a path in the environment.
182 * <p><p>
183 * May be used since since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
184 * is called.
185 * <p><p>
186 * Initialized inside {@link UDKBotModuleControllerNew#initializePathFinding(UDKBot)}.
187 */
188 protected IPathExecutor<ILocated> pathExecutor = null;
189
190 /**
191 * Planner used to compute the path (consisting of navigation points) inside the map.
192 * <p><p>
193 * May be used since since the first {@link IUDKBotController#botSpawned(cz.cuni.amis.pogamut.udk.communication.messages.gbinfomessages.GameInfo, ConfigChange, InitedMessage, Self)}
194 * is called.
195 * <p><p>
196 * Initialized inside {@link UDKBotModuleControllerNew#initializePathFinding(UDKBot)}.
197 */
198 protected IPathPlanner<ILocated> pathPlanner = null;
199
200 /**
201 * Listener registrator that probes declared methods for the presence of {@link EventListener}, {@link ObjectClassEventListener},
202 * {@link ObjectClassListener}, {@link ObjectEventListener} and {@link ObjectListener} annotations and automatically registers
203 * them as listeners on a specific events.
204 * <p><p>
205 * Note that this registrator is usable for 'this' object only! It will work only for 'this' object.
206 */
207 protected AnnotationListenerRegistrator listenerRegistrator;
208
209 /**
210 * Shortcut for the {@link UDKBotModuleControllerNew#getWorldView()}.
211 */
212 protected IVisionWorldView world;
213
214 /**
215 * Shortcut for the {@link UDKBotModuleControllerNew#getAct()}.
216 */
217 protected IAct act;
218
219 @Override
220 public void initializeController(BOT bot) {
221 super.initializeController(bot);
222 world = getWorldView();
223 act = getAct();
224 initializeModules(bot);
225 initializePathFinding(bot);
226 initializeListeners(bot);
227 }
228
229 /**
230 * Initializes {@link UDKBotModuleControllerNew#listenerRegistrator} and calls {@link AnnotationListenerRegistrator#addListeners()} method
231 * to probe all declared methods for event-annotation presence.
232 * @param bot
233 */
234 protected void initializeListeners(BOT bot) {
235 listenerRegistrator = new AnnotationListenerRegistrator(this, getWorldView(), bot.getLogger().getCategory("Listeners"));
236 listenerRegistrator.addListeners();
237 }
238
239 /**
240 * Initializes path-finding modules: {@link UDKBotModuleControllerNew#pathPlanner} and {@link UDKBotModuleControllerNew#pathExecutor}.
241 * If you need different path planner / path executor - override this method and initialize your own modules.
242 * @param bot
243 */
244 protected void initializePathFinding(BOT bot) {
245 pathPlanner = new UDKAStarPathPlanner(bot);
246 pathExecutor = new UDKPathExecutor<ILocated>(bot);
247 }
248
249 /**
250 * Initializes memory/command modules of the bot.
251 *
252 * @param bot
253 */
254 protected void initializeModules(BOT bot) {
255 game = new Game(bot);
256 info = new AgentInfo(bot, game);
257 players = new Players(bot);
258 descriptors = new ItemDescriptors(bot);
259 items = new Items(bot, info);
260 senses = new Senses(bot, info, players);
261 weaponry = new Weaponry(bot, descriptors);
262 config = new AgentConfig(bot);
263 raycasting = new Raycasting(bot);
264 body = new CompleteBotCommandsWrapper(bot);
265 shoot = body.getShooting();
266 move = body.getLocomotion();
267 }
268
269 }