View Javadoc

1   package nl.tudelft.pogamut.ut2004.agent.module.shooting.weapon;
2   
3   import nl.tudelft.pogamut.ut2004.agent.module.shooting.AbstractWeaponShooting;
4   import nl.tudelft.pogamut.ut2004.agent.module.shooting.util.FacingUtil;
5   
6   import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
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.agent.module.sensor.WeaponPrefs;
11  import cz.cuni.amis.pogamut.ut2004.bot.command.ImprovedShooting;
12  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
13  import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
15  
16  /**
17   * <p>
18   * Module to work efficiently with the flak cannon.
19   * </p>
20   * 
21   * <p>
22   * To avoid self damage the module won't use the secondary fire mode when it
23   * might blow up in it's face and won't be able to survive the damage. Instead
24   * secondary mode will be used. The effectiveness of this is somewhat limited as
25   * flak cannon projectiles bounce around.
26   * 
27   * Consider using {@link WeaponPrefs} to ban the flak cannon on close range.
28   * <p>
29   * 
30   * @author mpkorstanje
31   * 
32   */
33  public class FlakCannonShooting extends AbstractWeaponShooting {
34  
35  	protected static final WeaponPref FLAK_CANNON_PRIMARY = new WeaponPref(ItemType.FLAK_CANNON, true);
36  
37  	protected static final double FLAK_CANON_SECONDARY_PROJECTILE_SPLASH_RADIUS = 400;
38  
39  	protected static final int FLAK_CANON_SECONDARY_PROJECTILE_DAMAGE = 75;
40  
41  	public FlakCannonShooting(UT2004Bot<?, ?, ?> agent, AgentInfo info, ImprovedShooting shoot, Weaponry weaponry) {
42  		super(agent, info, shoot, weaponry);
43  	}
44  
45  	@Override
46  	protected void shoot() {
47  
48  		// Wrong weapon, wait up.
49  		if (!isWeaponReady()) {
50  			return;
51  		}
52  		
53  		//No target, no shoot.
54  		if(!hasTarget()){
55  			shoot.stopShooting();
56  			return;
57  		}
58  
59  		boolean facing = FacingUtil.isFacing2D(info, target, FACING_ANGLE);
60  		boolean safeToShoot = isSafeToShoot(target);
61  
62  		if (!(target instanceof Player)) {
63  			shootLocation(facing, safeToShoot);
64  			return;
65  		}
66  
67  		Player player = (Player) target;
68  
69  		// Target not visible, hold fire.
70  		if (!player.isVisible()) {
71  			shoot.stopShooting();
72  			return;
73  		}
74  
75  		// Shoot if we are facing the right way.
76  		// Don't want to blow an orb on a wall.
77  		if (facing && safeToShoot) {
78  			shoot.shoot(weaponPref, player);
79  		}
80  		// Player will absorb damage. So fall back to primary.
81  		else if (facing) {
82  			shoot.shootPrimary(player);
83  		} else {
84  			shoot.stopShooting();
85  		}
86  	}
87  
88  	private void shootLocation(boolean facing, boolean safeToShoot) {
89  		if (facing && safeToShoot) {
90  			shoot.shoot(weaponPref, target);
91  		}
92  		// Don't alternate to primary when note safe to shoot. Primary only gets
93  		// absorbed by players.
94  		else {
95  			shoot.stopShooting();
96  		}
97  	}
98  
99  	/**
100 	 * Don't shoot unless we are far away enough to avoid damaging ourselves, or
101 	 * healthy enough to survive the damage.
102 	 * 
103 	 * @param target
104 	 *            to shoot
105 	 * @return true iff we won't kill ourselves.
106 	 */
107 	protected boolean isSafeToShoot(ILocated target) {
108 		double distance = info.getLocation().getDistance(target.getLocation());
109 		boolean safeDistance = distance > FLAK_CANON_SECONDARY_PROJECTILE_SPLASH_RADIUS;
110 		boolean healty = info.getHealth() > FLAK_CANON_SECONDARY_PROJECTILE_DAMAGE;
111 
112 		return (safeDistance || healty);
113 	}
114 
115 	@Override
116 	protected WeaponPref getDefaultWeaponPref() {
117 		return FLAK_CANNON_PRIMARY;
118 	}
119 
120 
121 }