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