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