View Javadoc

1   package nl.tudelft.pogamut.unreal.agent.module.shooting;
2   
3   import nl.tudelft.pogamut.unreal.agent.module.shooting.util.FocusProvider;
4   import cz.cuni.amis.pogamut.base.agent.module.SensorModule;
5   import cz.cuni.amis.pogamut.base.communication.worldview.IWorldView;
6   import cz.cuni.amis.pogamut.base.communication.worldview.event.IWorldEventListener;
7   import cz.cuni.amis.pogamut.base3d.worldview.object.ILocated;
8   import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
9   import cz.cuni.amis.pogamut.ut2004.agent.module.sensomotoric.Weaponry;
10  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.AgentInfo;
11  import cz.cuni.amis.pogamut.ut2004.agent.module.sensor.WeaponPref;
12  import cz.cuni.amis.pogamut.ut2004.bot.command.ImprovedShooting;
13  import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
14  import cz.cuni.amis.pogamut.ut2004.communication.messages.ItemType;
15  import cz.cuni.amis.pogamut.ut2004.communication.messages.gbinfomessages.EndMessage;
16  
17  /**
18   * Base class for all shootings. Handles setting of target and weapon prefs and
19   * automates calling of {@link AbstractWeaponShooting#shoot()}.
20   * 
21   * @author mpkorstanje
22   * 
23   */
24  @SuppressWarnings("rawtypes")
25  public abstract class AbstractWeaponShooting extends SensorModule<UT2004Bot> implements WeaponShooting {
26  
27  	protected static final double FACING_ANGLE = 30.0;
28  	/**
29  	 * Half of height of player, aim this much below player to shoot at feet.
30  	 */
31  	protected static final Location BELOW_PLAYER_OFFSET = new Location(0, 0, 44);
32  	/**
33  	 * Height of player, aim this much above player to shoot around shield.
34  	 */
35  	protected static final Location ABOVE_PLAYER_OFFSET = new Location(0, 0, 88);
36  	/**
37  	 * Our target to shoot. May be null, in which case we may charge a weapon.
38  	 */
39  	protected ILocated target = null;
40  	/**
41  	 * Weapon pref indicates which firing mode to use.
42  	 */
43  	protected WeaponPref weaponPref;
44  	/**
45  	 * Reference to {@link ImprovedShooting} module.
46  	 */
47  	protected ImprovedShooting shoot;
48  	/**
49  	 * Reference to {@link Weaponry} module.
50  	 */
51  
52  	protected Weaponry weaponry;
53  	/**
54  	 * Reference to {@link AgentInfo} module.
55  	 */
56  
57  	protected AgentInfo info;
58  	/**
59  	 * If this shooting has been activated.
60  	 */
61  	protected boolean active = false;
62  
63  	/**
64  	 * Where the shooting would like the bot to look.
65  	 */
66  	protected FocusProvider focus = new FocusProvider();
67  
68  	/**
69  	 * Creates an abstract WeaponShooting.
70  	 * 
71  	 * @param agent
72  	 *            the bot that does the shooting.
73  	 * @param info
74  	 *            the info module for the bot.
75  	 * @param shoot
76  	 *            the shooting module for the bot.
77  	 * @param weaponry
78  	 *            the weaponry module for the bot.
79  	 */
80  	public AbstractWeaponShooting(UT2004Bot<?, ?, ?> agent, AgentInfo info, ImprovedShooting shoot, Weaponry weaponry) {
81  		super(agent);
82  		this.shoot = shoot;
83  		this.info = info;
84  		this.weaponry = weaponry;
85  		this.endMessageListener = new EndMessageListener(worldView);
86  	}
87  
88  	/**
89  	 * Set target to shoot at, actual shooting is deferred to next end message.<br>
90  	 * 
91  	 * Callers should ensure that weapon used by is available and has sufficient
92  	 * ammunition.
93  	 * 
94  	 * @param player
95  	 */
96  	@Override
97  	public void shoot(WeaponPref weaponPref, ILocated target) {
98  		if (weaponPref == null || !weaponPref.getWeapon().equals(getWeaponType())) {
99  			throw new IllegalArgumentException(
100 					"Weapon pref must be correct for the weapon associated with this shooting");
101 		}
102 
103 		this.active = true;
104 		this.target = target;
105 		this.focus.setFocus(target);
106 		this.weaponPref = weaponPref;
107 	}
108 
109 	/**
110 	 * @return the default weapon preference.
111 	 */
112 	protected abstract WeaponPref getDefaultWeaponPref();
113 
114 	/**
115 	 * Stops the shooting.
116 	 */
117 	public void stopShoot() {
118 		this.active = false;
119 		this.target = null;
120 		this.focus.clearFocus();
121 		shoot.stopShooting();
122 	}
123 
124 	/**
125 	 * Sets where the shooting would like to look.
126 	 * 
127 	 * @param focus
128 	 *            where we want to look.
129 	 */
130 	protected void setFocus(ILocated focus) {
131 		this.focus.setFocus(focus);
132 	}
133 
134 	/**
135 	 * Where the shooting would like the agent to look.
136 	 */
137 	public ILocated getFocus() {
138 		return focus;
139 	}
140 
141 	/**
142 	 * 
143 	 * @return true iff we have target.
144 	 */
145 	public boolean hasTarget() {
146 		return target != null;
147 	}
148 
149 	/**
150 	 * The weapon type this module can do the shooting for.
151 	 * 
152 	 * @return the weapon type we'll shoot with.
153 	 */
154 	public ItemType getWeaponType() {
155 		return getDefaultWeaponPref().getWeapon();
156 	}
157 
158 	/**
159 	 * @return true if the shooting has been activated.
160 	 */
161 	@Override
162 	public boolean isActive() {
163 		return active;
164 	}
165 
166 	/**
167 	 * @return if we have the {@link WeaponShooting#getWeaponType()}.
168 	 */
169 	protected boolean isWeaponReady() {
170 		// We should have the link gun ready.
171 		if (weaponry.getCurrentWeapon() == null || !weaponry.getCurrentWeapon().getType().equals(getWeaponType())) {
172 			weaponry.changeWeapon(getWeaponType());
173 			return false;
174 		}
175 
176 		return true;
177 	}
178 
179 	/**
180 	 * <p>
181 	 * Shoot will be called after every end message.
182 	 * </p>
183 	 * 
184 	 * <p>
185 	 * Implementing subclasses should make a best effort attempt to shoot the
186 	 * given target using the given weapon preference if possible. Subclasses
187 	 * should take care to note that a target may not always be present. e.g.
188 	 * target == null.
189 	 * </p>
190 	 * 
191 	 */
192 	protected abstract void shoot();
193 
194 	/**
195 	 * {@link EndMessage} listener.
196 	 */
197 	private class EndMessageListener implements IWorldEventListener<EndMessage> {
198 		@Override
199 		public void notify(EndMessage event) {
200 			if (isActive())
201 				shoot();
202 		}
203 
204 		/**
205 		 * Constructor. Registers itself on the given WorldView object.
206 		 * 
207 		 * @param worldView
208 		 *            WorldView object to listen to.
209 		 */
210 		public EndMessageListener(IWorldView worldView) {
211 			worldView.addEventListener(EndMessage.class, this);
212 		}
213 	}
214 
215 	/** {@link EndMessage} listener */
216 	protected EndMessageListener endMessageListener;
217 
218 }