1 package cz.cuni.amis.pogamut.ut2004.bot.command; 2 3 import java.util.logging.Logger; 4 5 import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener; 6 import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated; 7 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot; 8 import cz.cuni.amis.pogamut.unreal.communication.messages.UnrealId; 9 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Shoot; 10 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.StopShooting; 11 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.BeginMessage; 12 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player; 13 14 /** 15 * Class providing Pogamut2 UT2004 advanced shooting commands for the bot - 16 * shooting in secondary mode, grenade launcher shooting, etc. 17 * 18 * @author Michal 'Knight' Bida 19 */ 20 public class AdvancedShooting extends SimpleShooting { 21 22 /** Here we store current UT time used to issue charge shoot commands */ 23 private double currentTime = 0; 24 /** Time last charge shoot command was issued, -1 for command not issued */ 25 private double lastChargeShootCommandTime = -1; 26 /** Delay of last charge shoot command */ 27 private double lastChargeShootCommandDelay = 0; 28 /** 29 * Listener to begin message - used to get UT04 current time. 30 */ 31 private IWorldEventListener<BeginMessage> myBegListener = new IWorldEventListener<BeginMessage>() { 32 33 @Override 34 public void notify(BeginMessage bm) { 35 currentTime = bm.getTime(); 36 37 // Here we will stop shooting if the charge dealy is exceeded 38 if ((lastChargeShootCommandTime >= 0) 39 && ((currentTime - lastChargeShootCommandTime) > lastChargeShootCommandDelay)) { 40 agent.getAct().act(new StopShooting()); 41 lastChargeShootCommandTime = -1; 42 lastChargeShootCommandDelay = 0; 43 } 44 } 45 }; 46 47 /** 48 * The bot will stop shooting completely (regardless on the mode of shooting). 49 * <p><p> 50 * (issues GB STOPSHOOT command) 51 */ 52 public void stopShooting() { 53 agent.getAct().act(new StopShooting()); 54 } 55 56 /** 57 * Bot will start shooting his current weapon with selected mode. 58 * <p><p> 59 * (issues GB SHOOT command) 60 * 61 * @param secondaryMode 62 * If true secondary firing mode will be issued. 63 * 64 */ 65 public void shootWithMode(boolean secondaryMode) { 66 Shoot shoot = new Shoot(); 67 shoot.setAlt(secondaryMode); 68 agent.getAct().act(shoot); 69 } 70 71 /** 72 * Bot will start shooting his current weapon with selected mode. 73 * <p><p> 74 * (issues GB SHOOT command) 75 * 76 * @param secondaryMode 77 * If true secondary firing mode will be issued. 78 * 79 */ 80 public void shootSecondary() { 81 Shoot shoot = new Shoot(); 82 shoot.setAlt(true); 83 agent.getAct().act(shoot); 84 } 85 86 /** 87 * Bot will start shooting his current weapon with primary firing mode at 88 * the location specified. The bot will shoot on this location even when he 89 * will turn a little bit from the direction to the location. If he turn out 90 * more then approx 15 - 30 degrees he won't be able to hit the location 91 * anymore. 92 * <p><p> 93 * (issues GB SHOOT command) 94 * 95 * @param location 96 * Location we will be shooting at. 97 * 98 * @see shootPrimary(UnrealId) 99 */ 100 public void shootPrimary(ILocated location) { 101 if (location instanceof Player) { 102 shootPrimary((Player)location); 103 return; 104 } 105 Shoot shoot = new Shoot(); 106 shoot.setLocation(location.getLocation()); 107 agent.getAct().act(shoot); 108 } 109 110 /** 111 * Bot will start shooting his current weapon with primary firing mode at 112 * the target specified. The target should exist in the environment. The bot 113 * will track the target in the environment as long as other commands won't 114 * change his focus (strafe(), turnTo()..). If they will the bot will still 115 * shoot on target location until he will turn from target more then approx 116 * 15 - 30 degrees. Then he won't be able to hit the target location 117 * anymore. 118 * <p><p> 119 * (issues GB SHOOT command) 120 * 121 * @param target 122 * Object in the environment we will shoot at. 123 * 124 * @see shootPrimary(ILocated) 125 */ 126 public void shootPrimary(UnrealId target) { 127 Shoot shoot = new Shoot(); 128 shoot.setTarget(target); 129 agent.getAct().act(shoot); 130 } 131 132 /** 133 * Shortcut for 'shootPrimary(player.getId())', see {@link AdvancedShooting#shootPrimary(UnrealId)}. 134 * <p><p> 135 * (issues GB SHOOT command) 136 * 137 * @param target 138 * Player the bot wants to shoot at. 139 */ 140 public void shootPrimary(Player target) { 141 shootPrimary(target.getId()); 142 } 143 144 /** 145 * Bot will start shooting his current weapon with secondary firing mode at 146 * the location specified. The bot will shoot on this location even when he 147 * will turn a little bit from the direction to the location. If he turn out 148 * more then approx 15 - 30 degrees he won't be able to hit the location 149 * anymore. 150 * <p><p> 151 * (issues GB SHOOT command) 152 * 153 * @param location 154 * Location we will be shooting at. 155 * 156 * @see shootSecondary(UnrealId) 157 */ 158 public void shootSecondary(ILocated location) { 159 if (location instanceof Player) { 160 shootSecondary((Player)location); 161 return; 162 } 163 Shoot shoot = new Shoot(); 164 shoot.setLocation(location.getLocation()); 165 shoot.setAlt(true); 166 agent.getAct().act(shoot); 167 } 168 169 /** 170 * Bot will start shooting his current weapon with secondary firing mode at 171 * the target specified. The target should exist in the environment. The bot 172 * will track the target in the environment as long as other commands won't 173 * change his focus (strafe(), turnTo()..). If they will the bot will still 174 * shoot on target location until he will turn from target more then approx 175 * 15 - 30 degrees. Then he won't be able to hit the target location 176 * anymore. 177 * <p><p> 178 * (issues GB SHOOT command) 179 * 180 * @param target 181 * Object in the environment we will shoot at. 182 * 183 * @see shootSecondary(ILocated) 184 */ 185 public void shootSecondary(UnrealId target) { 186 Shoot shoot = new Shoot(); 187 shoot.setTarget(target); 188 shoot.setAlt(true); 189 agent.getAct().act(shoot); 190 } 191 192 /** 193 * Shortcut for 'shootSecondary(player.getId())', see {@link AdvancedShooting#shootSecondary(UnrealId)}. 194 * <p><p> 195 * (issues GB SHOOT command) 196 * 197 * @param target 198 * Player the bot wants to shoot at. 199 */ 200 public void shootSecondary(Player target) { 201 shootSecondary(target.getId()); 202 } 203 204 /** 205 * This method can be used for UT2004 charging weapons. Some weapons in 206 * UT2004 feature charging firing modes. These modes works as follows. To 207 * shoot with a charging firing mode the bot has to start shooting first - 208 * this will trigger the weapon to start charging (it won't fire yet). To 209 * fire the weapon the bot needs to send STOPSHOOT command to stop charging 210 * the weapon and to release the projectile. This method does this 211 * automatically for primary firing mode of the weapon. The time of charging 212 * can be specified too (second parameter in seconds). 213 * <p><p> 214 * This method can be also used for non-charing (primary) firing mode of the 215 * weapon - then it will work as burst fire - the bot will continue firing 216 * for the amout of seconds specified. 217 * <p><p> 218 * So if the current weapon primary firing mode is charging, the bot will 219 * release the projectiles once. With normal primary firing mode the bot 220 * will fire a burst. 221 * <p><p> 222 * Note: We will shoot at location specified. The bot will continue to aim 223 * on the location in the environment (for the time of charging or bursting) 224 * as long as other commands won't change his focus (strafe(), turnTo()..). 225 * If they will the bot will still shoot on location until he will turn from 226 * it more then approx 15 - 30 degrees. Then he won't be able to hit the 227 * location anymore. 228 * <p><p> 229 * (issues GB SHOOT command) 230 * 231 * @param location 232 * Location we will be shooting at. 233 * @param chargeTime 234 * In seconds - how long we will charge the weapon (or how long 235 * will be the burst fire). 236 * 237 * @see shootPrimaryCharged(UnrealId, double) 238 */ 239 public void shootPrimaryCharged(ILocated location, double chargeTime) { 240 if (location instanceof Player) { 241 shootPrimaryCharged((Player)location, chargeTime); 242 return; 243 } 244 Shoot shoot = new Shoot(); 245 shoot.setLocation(location.getLocation()); 246 agent.getAct().act(shoot); 247 248 // Stop shoot command will be issued after delay 249 lastChargeShootCommandTime = currentTime; 250 lastChargeShootCommandDelay = chargeTime; 251 } 252 253 /** 254 * This method can be used for UT2004 charging weapons. Some weapons in 255 * UT2004 feature charging firing modes. These modes works as follows. To 256 * shoot with a charging firing mode the bot has to start shooting first - 257 * this will trigger the weapon to start charging (it won't fire yet). To 258 * fire the weapon the bot needs to send STOPSHOOT command to stop charging 259 * the weapon and to release the projectile. This method does this 260 * automatically for primary firing mode of the weapon. The time of charging 261 * can be specified too (second parameter in seconds). 262 * <p><p> 263 * This method can be also used for non-charing (primary) firing mode of the 264 * weapon - then it will work as burst fire - the bot will continue firing 265 * for the amout of seconds specified. 266 * <p><p> 267 * So if the current weapon primary firing mode is charging, the bot will 268 * release the projectiles once. With normal primary firing mode the bot 269 * will fire a burst. 270 * <p><p> 271 * Note: The target for shooting should exist in the environment. The bot 272 * will track the target in the environment (for the time of charging or 273 * bursting) as long as other commands won't change his focus (strafe(), 274 * turnTo()..). If they will the bot will still shoot on target location 275 * until he will turn from target more then approx 15 - 30 degrees. Then he 276 * won't be able to hit the target location anymore. 277 * <p><p> 278 * (issues GB SHOOT command) 279 * 280 * @param target 281 * Object in the environment we will shoot at (basic tracking 282 * provided). 283 * @param chargeTime 284 * In seconds - how long we will charge the weapon (or how long 285 * will be the burst fire). 286 * 287 * @see shootPrimaryCharged(ILocated, double) 288 * 289 * @todo Implement somehow the charging delay. 290 */ 291 public void shootPrimaryCharged(UnrealId target, double chargeTime) { 292 Shoot shoot = new Shoot(); 293 shoot.setTarget(target); 294 agent.getAct().act(shoot); 295 296 // Stop shoot command will be issued after delay 297 lastChargeShootCommandTime = currentTime; 298 lastChargeShootCommandDelay = chargeTime; 299 } 300 301 /** 302 * Shortcut for 'shootPrimaryCharged(player.getId())', see {@link AdvancedShooting#shootPrimaryCharged(UnrealId, double)}. 303 * <p><p> 304 * (issues GB SHOOT command) 305 * 306 * @param target 307 * Player the bot wants to shoot at. 308 */ 309 public void shootPrimaryCharged(Player target, double chargeTime) { 310 shootPrimaryCharged(target.getId(), chargeTime); 311 } 312 313 /** 314 * This method can be used for UT2004 charging weapons. Some weapons in 315 * UT2004 feature charging firing modes. These modes works as follows. To 316 * shoot with a charging firing mode the bot has to start shooting first - 317 * this will trigger the weapon to start charging (it won't fire yet). To 318 * fire the weapon the bot needs to send STOPSHOOT command to stop charging 319 * the weapon and to release the projectile. This method does this 320 * automatically for secondary firing mode of the weapon. The time of 321 * charging can be specified too (second parameter in seconds). 322 * <p><p> 323 * This method can be also used for non-charing (secondary) firing mode of 324 * the weapon - then it will work as burst fire - the bot will continue 325 * firing for the amout of seconds specified. 326 * <p><p> 327 * So if the current weapon secondary firing mode is charging, the bot will 328 * release the projectiles once. With normal secondary firing mode the bot 329 * will fire a burst. 330 * <p><p> 331 * Note: We will shoot at location specified. The bot will continue to aim 332 * on the location in the environment (for the time of charging or bursting) 333 * as long as other commands won't change his focus (strafe(), turnTo()..). 334 * If they will the bot will still shoot on location until he will turn from 335 * it more then approx 15 - 30 degrees. Then he won't be able to hit the 336 * location anymore. 337 * <p><p> 338 * (issues GB SHOOT command) 339 * 340 * @param location 341 * Location we will be shooting at. 342 * @param chargeTime 343 * In seconds - how long we will charge the weapon (or how long 344 * will be the burst fire). 345 * 346 * @see shootSecondaryCharged(UnrealId, double) 347 * 348 * @todo Implement somehow the charging delay. 349 */ 350 public void shootSecondaryCharged(ILocated location, double chargeTime) { 351 if (location instanceof Player) { 352 shootSecondaryCharged((Player)location, chargeTime); 353 return; 354 } 355 Shoot shoot = new Shoot(); 356 shoot.setLocation(location.getLocation()); 357 shoot.setAlt(true); 358 agent.getAct().act(shoot); 359 360 // Stop shoot command will be issued after delay 361 lastChargeShootCommandTime = currentTime; 362 lastChargeShootCommandDelay = chargeTime; 363 } 364 365 /** 366 * This method can be used for UT2004 charging weapons. Some weapons in 367 * UT2004 feature charging firing modes. These modes works as follows. To 368 * shoot with a charging firing mode the bot has to start shooting first - 369 * this will trigger the weapon to start charging (it won't fire yet). To 370 * fire the weapon the bot needs to send STOPSHOOT command to stop charging 371 * the weapon and to release the projectile. This method does this 372 * automatically for secondary firing mode of the weapon. The time of 373 * charging can be specified too (second parameter in seconds). 374 * <p><p> 375 * This method can be also used for non-charing (secondary) firing mode of 376 * the weapon - then it will work as burst fire - the bot will continue 377 * firing for the amout of seconds specified. 378 * <p><p> 379 * So if the current weapon secondary firing mode is charging, the bot will 380 * release the projectiles once. With normal secondary firing mode the bot 381 * will fire a burst. 382 * <p><p> 383 * Note: The target for shooting should exist in the environment. The bot 384 * will track the target in the environment (for the time of charging or 385 * bursting) as long as other commands won't change his focus (strafe(), 386 * turnTo()..). If they will the bot will still shoot on target location 387 * until he will turn from target more then approx 15 - 30 degrees. Then he 388 * won't be able to hit the target location anymore. 389 * <p><p> 390 * (issues GB SHOOT command) 391 * 392 * @param target 393 * Object in the environment we will shoot at (basic tracking 394 * provided). 395 * @param chargeTime 396 * In seconds - how long we will charge the weapon (or how long 397 * will be the burst fire). 398 * 399 * @see shootSecondaryCharged(ILocated, double) 400 * 401 * @todo Implement somehow the charging delay. 402 */ 403 public void shootSecondaryCharged(UnrealId target, double chargeTime) { 404 Shoot shoot = new Shoot(); 405 shoot.setTarget(target); 406 shoot.setAlt(true); 407 agent.getAct().act(shoot); 408 409 // Stop shoot command will be issued after delay 410 lastChargeShootCommandTime = currentTime; 411 lastChargeShootCommandDelay = chargeTime; 412 } 413 414 /** 415 * Shortcut for 'shootSecondaryCharged(player.getId())', see {@link AdvancedShooting#shootSecondaryCharged(UnrealId, double)}. 416 * <p><p> 417 * (issues GB SHOOT command) 418 * 419 * @param target 420 * Player the bot wants to shoot at. 421 */ 422 public void shootSecondaryCharged(Player target, double chargeTime) { 423 shootSecondaryCharged(target.getId(), chargeTime); 424 } 425 426 /** 427 * Resets the agent module so it may be reused. 428 */ 429 @Override 430 protected void reset() { 431 lastChargeShootCommandTime = -1; 432 lastChargeShootCommandDelay = 0; 433 } 434 435 /** 436 * Constructor. Setups the command module based on given agent and logger. 437 * 438 * @param agent 439 * AbstractUT2004Bot we will send commands for 440 * @param log 441 * Logger to be used for logging runtime/debug info. 442 * 443 * @todo Implement somehow the charging delay. 444 */ 445 public AdvancedShooting(UT2004Bot agent, Logger log) { 446 super(agent, log); 447 agent.getWorldView() 448 .addEventListener(BeginMessage.class, myBegListener); 449 } 450 451 @Override 452 public void shoot() { 453 super.shoot(); 454 } 455 456 @Override 457 public void shoot(UnrealId target) { 458 super.shoot(target); 459 } 460 461 @Override 462 public void shoot(Player target) { 463 super.shoot(target); 464 } 465 466 @Override 467 public void stopShoot() { 468 super.stopShoot(); 469 } 470 471 472 }