View Javadoc

1   package nl.tudelft.pogamut.ut2004.agent.module.shooting.weapon;
2   
3   import nl.tudelft.pogamut.unreal.agent.module.sensor.Projectiles;
4   import nl.tudelft.pogamut.unreal.agent.module.shooting.AbstractWeaponShooting;
5   import nl.tudelft.pogamut.unreal.agent.module.shooting.util.FacingUtil;
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.Senses;
10  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.WeaponPref;
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.UT2004ItemType;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.IncomingProjectile;
15  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.Player;
16  
17  /**
18   * <p>
19   * Module to work efficiently with the shield gun.
20   * </p>
21   * 
22   * <p>
23   * When the primary mode is given to the weapon preferences the shield gun will
24   * simply charge up. It's up to other component to run into someone.
25   * </p>
26   * <p>
27   * When the secondary mode is requested by weapon preferences the shield gun
28   * activate for 1 second when ever it detects that it is taking damage, sees an
29   * incoming projectile or sees it's target shooting or sees it's target aiming a
30   * hitscan weapon at it. While doing this the bot will aim in the direction of
31   * its target, potentially bouncing shock cores and link gun projectiles to it's
32   * target.
33   * </p>
34   * 
35   * @author mpkorstanje
36   * 
37   */
38  public class ShieldGunShooting extends AbstractWeaponShooting {
39  
40  	/**
41  	 * Distance at which incoming projectiles can be considered threatening.
42  	 */
43  	protected static final int INCOMMING_PROJECTILE_MIN_THREAT_DISTANCE = 750;
44  
45  	/**
46  	 * Duration in second that the shield gun will fire.
47  	 */
48  	protected static final double SHIELD_GUN_SEC_BURST_DURATION = 1.0;
49  
50  	/**
51  	 * Default is the secondary mode.
52  	 */
53  	protected static final WeaponPref DEFAULT_WEAPON_PREF = new WeaponPref(UT2004ItemType.SHIELD_GUN, false);
54  
55  
56  	/**
57  	 * {@link Projectiles} modules.
58  	 */
59  	protected Projectiles projectiles;
60  	/**
61  	 * Senses module. Note: shared with the main again. Careful with "Once"
62  	 * functions.
63  	 */
64  	protected Senses senses;
65  
66  	public ShieldGunShooting(UT2004Bot<?, ?, ?> bot, AgentInfo info, ImprovedShooting shoot, Weaponry weaponry,
67  			Projectiles projectiles, Senses senses) {
68  		super(bot, info, shoot, weaponry);
69  		this.projectiles = projectiles;
70  		this.senses = senses;
71  	}
72  
73  	@Override
74  	protected void shoot() {
75  
76  		// Wrong weapon, wait up.
77  		if (!isWeaponReady()) {
78  			return;
79  		}
80  
81  		// Reset focus
82  		focus.setFocus(target);
83  
84  		// Primary works by running into people, just keep it charged.
85  		if (weaponPref.isPrimary()) {
86  			shootPrimary();
87  		}
88  		// Secondary should only be used when directly shot at.
89  		else {
90  			shootSecondary();
91  		}
92  
93  	}
94  
95  	protected void shootPrimary() {
96  		if (target == null) {
97  			shoot.shoot();
98  			return;
99  		}
100 
101 		shoot.shootPrimary(target);
102 
103 	}
104 
105 	protected void shootSecondary() {
106 
107 		// Incomming!
108 		IncomingProjectile projectile = projectiles.getNearestProjectile(agent,
109 				INCOMMING_PROJECTILE_MIN_THREAT_DISTANCE);
110 		// System.out.println(projectile);
111 		if (projectile != null) {
112 			ILocated safeTarget = (ILocated) (target == null ? projectile : target);
113 			shoot.shootSecondaryCharged(safeTarget, SHIELD_GUN_SEC_BURST_DURATION);
114 			focus.setFocus(safeTarget);
115 			return;
116 		}
117 
118 		// Oh, no!
119 		if (senses.isShot()) {
120 			ILocated safeTarget = (ILocated) (target == null ? agent : target);
121 			shoot.shootSecondaryCharged(safeTarget, SHIELD_GUN_SEC_BURST_DURATION);
122 			return;
123 		}
124 
125 		// No further reason to consider shooting.
126 		if (!hasTarget()) {
127 			return;
128 		}
129 
130 		// Bit pointless.
131 		if (!(target instanceof Player)) {
132 			shoot.shootSecondaryCharged(target, SHIELD_GUN_SEC_BURST_DURATION);
133 			return;
134 		}
135 
136 		// Dangerous people about
137 		Player player = (Player) target;
138 		boolean hitScanWeapon = player.getWeapon().contains("Shock") || player.getWeapon().contains("Lightning")
139 				|| player.getWeapon().contains("Sniper");
140 		boolean fireDangerous = player.getFiring() > 0 || hitScanWeapon;
141 		if (player.isVisible() && fireDangerous && FacingUtil.isFacing2D(player, agent, FACING_ANGLE)) {
142 			shoot.shootSecondaryCharged(target, SHIELD_GUN_SEC_BURST_DURATION);
143 			return;
144 		}
145 
146 	}
147 
148 	@Override
149 	protected WeaponPref getDefaultWeaponPref() {
150 		return DEFAULT_WEAPON_PREF;
151 	}
152 
153 }