View Javadoc

1   package nl.tudelft.pogamut.ut2004.agent.module.shooting.weapon;
2   
3   import nl.tudelft.pogamut.unreal.agent.module.shooting.AbstractWeaponShooting;
4   import nl.tudelft.pogamut.unreal.agent.module.shooting.util.FacingUtil;
5   import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
6   import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
7   import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Weaponry;
8   import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
9   import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.WeaponPref;
10  import cz.cuni.amis.pogamut.ut2004.bot.command.ImprovedShooting;
11  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
12  import cz.cuni.amis.pogamut.ut2004.communication.messages.UT2004ItemType;
13  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
14  
15  /**
16   * <p>
17   * Module to work efficiently with the rocket launcher.
18   * </p>
19   * <p>
20   * The rocket launcher is fairly hard to use as it effectiveness lies in
21   * predicting where the player will be. Something a little too complex. This
22   * module only provides support for shooting players that are currently visible
23   * or have recently hidden.
24   * </p>
25   * <p>
26   * To avoid self damage, this module won't fire when the target is too close and
27   * the bot survive the blast.
28   * </p>
29   * <p>
30   * When a target hides the bot will shoot a little below its last known
31   * location, trying to flush the target out.
32   * </p>
33   * 
34   * @author mpkorstanje
35   * 
36   */
37  public class RocketLauncherShooting extends AbstractWeaponShooting {
38  
39  	protected static final WeaponPref ROCKET_LAUNCHER_PRIMARY = new WeaponPref(UT2004ItemType.ROCKET_LAUNCHER, true);
40  
41  	protected static final double ROCKET_LAUNCHER_PROJECTILE_SPLASH_RADIUS = 250;
42  
43  	protected static final int ROCKET_LAUNCHER_PROJECTILE_DAMAGE = 80;
44  
45  	protected static final int ROCKET_LAUNCHER_THREE_PROJECTILE_DAMAGE = 3 * ROCKET_LAUNCHER_PROJECTILE_DAMAGE;
46  
47  	protected static final double ROCKET_LAUNCHER_CHARGE_TIME_SECONDS = 1.0;
48  
49  	protected Location lastLocation = null;
50  
51  	public RocketLauncherShooting(UT2004Bot<?, ?, ?> agent, AgentInfo info, ImprovedShooting shoot, Weaponry weaponry) {
52  		super(agent, info, shoot, weaponry);
53  	}
54  
55  	@Override
56  	protected void shoot() {
57  
58  		// Wrong weapon, wait up.
59  		if (!isWeaponReady()) {
60  			return;
61  		}
62  
63  		// No target, no shoot.
64  		if (!hasTarget()) {
65  			shoot.stopShooting();
66  			return;
67  		}
68  
69  		boolean facing = FacingUtil.isFacing2D(info, target, FACING_ANGLE);
70  		boolean safeToShoot = isSafeToShoot(target);
71  
72  		if (!(target instanceof Player)) {
73  			shootLocation(facing, safeToShoot);
74  			return;
75  		}
76  
77  		Player player = (Player) target;
78  
79  		// Target hidden, flush target out.
80  		if (!player.isVisible() && info.isSecondaryShooting()) {
81  			shoot.shootPrimary(lastLocation.sub(BELOW_PLAYER_OFFSET));
82  			// Break of charge.
83  			shoot.stopShooting();
84  			return;
85  		}
86  		// Target not visible, hold fire.
87  		else if (!player.isVisible()) {
88  			shoot.stopShooting();
89  			return;
90  		}
91  
92  		// Store last location so we can flush player out.
93  		lastLocation = player.getLocation();
94  
95  		// Shoot if we are facing the right way.
96  		// Don't want to blow a rocket on a wall.
97  		if (facing && safeToShoot) {
98  			if (weaponPref.isPrimary()) {
99  				shoot.shoot(weaponPref, target);
100 			} else {
101 				shoot.shootSecondaryCharged(target, ROCKET_LAUNCHER_CHARGE_TIME_SECONDS);
102 			}
103 		} else {
104 			shoot.stopShooting();
105 		}
106 	}
107 
108 	private void shootLocation(boolean facing, boolean safeToShoot) {
109 		if (facing && safeToShoot) {
110 			if (weaponPref.isPrimary()) {
111 				shoot.shoot(weaponPref, target);
112 			} else {
113 				shoot.shootSecondaryCharged(target, ROCKET_LAUNCHER_CHARGE_TIME_SECONDS);
114 			}
115 		} else {
116 			shoot.stopShooting();
117 		}
118 	}
119 
120 	/**
121 	 * Don't shoot unless we are far away enough to avoid damaging ourselves, or
122 	 * healthy enough to survive the damage.
123 	 * 
124 	 * @param target
125 	 *            to shoot
126 	 * @return true iff we won't kill ourselves.
127 	 */
128 	protected boolean isSafeToShoot(ILocated target) {
129 
130 		double distance = info.getLocation().getDistance(target.getLocation());
131 		boolean safeDistance = distance > ROCKET_LAUNCHER_PROJECTILE_SPLASH_RADIUS;
132 		double damage = weaponPref.isPrimary() ? ROCKET_LAUNCHER_PROJECTILE_DAMAGE
133 				: ROCKET_LAUNCHER_THREE_PROJECTILE_DAMAGE;
134 		boolean healty = info.getHealth() > damage;
135 
136 		return (safeDistance || healty);
137 	}
138 
139 	@Override
140 	protected WeaponPref getDefaultWeaponPref() {
141 		return ROCKET_LAUNCHER_PRIMARY;
142 	}
143 
144 
145 }