1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.magicproject.clickable.targetable;
21
22 import java.awt.Color;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.swing.JMenuItem;
30 import javax.swing.JSeparator;
31
32 import net.sf.magicproject.action.listener.WaitingAbility;
33 import net.sf.magicproject.clickable.Clickable;
34 import net.sf.magicproject.clickable.ability.Ability;
35 import net.sf.magicproject.clickable.ability.UserAbility;
36 import net.sf.magicproject.clickable.targetable.card.Damage;
37 import net.sf.magicproject.clickable.targetable.card.MCard;
38 import net.sf.magicproject.modifier.ControllerModifier;
39 import net.sf.magicproject.modifier.RegisterIndirection;
40 import net.sf.magicproject.modifier.RegisterModifier;
41 import net.sf.magicproject.stack.StackManager;
42 import net.sf.magicproject.token.IdCommonToken;
43
44 /***
45 * Represents a target : player or card.
46 *
47 * @see net.sf.magicproject.xml.tbs.Card
48 * @see net.sf.magicproject.clickable.targetable.player.Player
49 * @version 0.91
50 * @since 0.3
51 * @since 0.90 a map of objects {String, Tragetable} is added.
52 * @since 0.91 removered properties instance variable to CardModel
53 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
54 * @author <a href="mailto:kismet-sl@users.sourceforge.net">Stefano "Kismet"
55 * Lenzi</a>
56 */
57 public abstract class Targetable extends Clickable implements ActionListener {
58
59 /***
60 * Private property key "creator"
61 */
62 static final String KEY_CREATOR = "creator";
63
64 /***
65 * Creates a new instance of MTargetable <br>
66 */
67 public Targetable() {
68 super();
69 isHighLighted = false;
70 setBackground(Color.black);
71 }
72
73 /***
74 * remove all damages on this card
75 */
76 public void clearDamages() {
77 for (int i = getComponentCount(); i-- > 0;) {
78 if (getComponent(i) instanceof Damage) {
79 remove(getComponent(i));
80 }
81 registers[IdCommonToken.DAMAGE] = 0;
82 }
83 }
84
85 @Override
86 public abstract String toString();
87
88 /***
89 * return true if this targetable is a player
90 *
91 * @return true if this targetable is a player
92 */
93 public final boolean isPlayer() {
94 return !isCard();
95 }
96
97 /***
98 * indicates if this target is a card
99 *
100 * @return true if this target is a card
101 */
102 public abstract boolean isCard();
103
104 /***
105 * An ActionListener that listens to the ability choice
106 *
107 * @param evt
108 * the event
109 */
110 public void actionPerformed(ActionEvent evt) {
111
112 if (evt.getSource() instanceof JMenuItem) {
113 StackManager.noReplayToken.take();
114 try {
115 if (StackManager.idHandedPlayer == 0) {
116 for (int j = TargetableFactory.abilitiesMenu.getComponentCount(); j-- > 0;) {
117 if (TargetableFactory.abilitiesMenu.getComponent(j) == evt
118 .getSource()) {
119
120 boolean advancedMode = false;
121 for (int i = j; i-- > 0;) {
122 if (TargetableFactory.abilitiesMenu.getComponent(i) instanceof JSeparator) {
123
124 advancedMode = true;
125 ((UserAbility) ((WaitingAbility) StackManager.actionManager.currentAction)
126 .advancedAbilitiesOf(TargetableFactory.triggerTargetable)
127 .get(j - i - 1)).mouseClicked(j - i + 127);
128 break;
129 }
130 }
131 if (!advancedMode) {
132
133 ((UserAbility) ((WaitingAbility) StackManager.actionManager.currentAction)
134 .abilitiesOf(TargetableFactory.triggerTargetable).get(j))
135 .mouseClicked(j);
136 }
137 break;
138 }
139 }
140 }
141 } catch (Throwable t) {
142 t.printStackTrace();
143 } finally {
144 StackManager.noReplayToken.release();
145 }
146 }
147 }
148
149 /***
150 * The border will be highligthed to a color identifying it easily as a token
151 * component.
152 */
153 public final void tokenize() {
154 highLight(TargetableFactory.TOKENIZE_COLOR);
155 }
156
157 /***
158 * The border will be highligthed to a color identifying it easily as a
159 * targetable component.
160 *
161 * @param highlightedZones
162 * the set of highlighted zone.
163 */
164 public void targetize(boolean... highlightedZones) {
165 highLight(TargetableFactory.TARGET_COLOR);
166 }
167
168 /***
169 * Highlight as "targetable" the list of targetable
170 *
171 * @param list
172 * the list of targetable to highlight.
173 * @param highlightedZones
174 * the list of highlighted zones
175 */
176 public static void targetize(List<Targetable> list, boolean[] highlightedZones) {
177 for (Targetable targetable : list) {
178 targetable.targetize(highlightedZones);
179 }
180 }
181
182 /***
183 * Return the value corresponding to the true register index.
184 *
185 * @param index
186 * the register index
187 * @return the value corresponding to the true register index.
188 */
189 public abstract int getValue(int index);
190
191 /***
192 * Return the value corresponding to the true register index.
193 *
194 * @param index
195 * the register index
196 * @return the value corresponding to the true register index.
197 */
198 public int getValueIndirection(int index) {
199 return getValue(index);
200 }
201
202 /***
203 * Add a modifier to this object
204 *
205 * @param modifier
206 * the modifier to add to this object
207 * @param index
208 * is the modifier register index
209 */
210 public void addModifier(RegisterModifier modifier, int index) {
211 if (registerModifiers[index] == null) {
212 registerModifiers[index] = modifier;
213 } else {
214 registerModifiers[index].addModifier(modifier);
215 }
216 }
217
218 /***
219 * Add a modifier to this object
220 *
221 * @param modifier
222 * the indirection modifier to add to this object
223 * @param index
224 * is the modifier register index
225 */
226 public void addModifier(RegisterIndirection modifier, int index) {
227 if (indirections[index] == null) {
228 indirections[index] = modifier;
229 } else {
230 indirections[index].addModifier(modifier);
231 }
232 }
233
234 /***
235 * Is this targetable is an abilty or a spell
236 *
237 * @return true id this targetable is an ability
238 */
239 public abstract boolean isAbility();
240
241 /***
242 * Is this targetable is an abilty or a spell
243 *
244 * @return true id this targetable is a spell
245 */
246 public abstract boolean isSpell();
247
248 /***
249 * Remove a register modifier from this component.
250 *
251 * @param modifier
252 * the register modifier to remove.
253 * @param index
254 * index of register to remove.
255 */
256 public abstract void removeModifier(RegisterModifier modifier, int index);
257
258 /***
259 * Remove a register-indirection modifier from this component.
260 *
261 * @param indirection
262 * the register-indirection modifier to remove.
263 * @param index
264 * index of register indirection to remove.
265 */
266 public abstract void removeModifier(RegisterIndirection indirection, int index);
267
268 /***
269 * Return this targetable as it was at the given timestamp.
270 *
271 * @param timeStamp
272 * the timestamp number.
273 * @return this targetable as it was at the given timestamp.
274 */
275 public abstract Targetable getLastKnownTargetable(int timeStamp);
276
277 /***
278 * Return the original targetable without looking for the timestamp number.
279 *
280 * @return the original targetable without looking for the timestamp number.
281 */
282 public Targetable getOriginalTargetable() {
283 return this;
284 }
285
286 /***
287 * Return the named object. If the object has not been found,
288 * <code>null</code> value is returned.
289 *
290 * @param objectName
291 * the searched object's name
292 * @return the named object.
293 */
294 public Targetable getPrivateNamedObject(String objectName) {
295 if (KEY_CREATOR.equals(objectName)) {
296 return getCreator();
297 }
298 if (privateNamedObjects == null) {
299 return null;
300 }
301 return privateNamedObjects.get(objectName);
302 }
303
304 /***
305 * Return the creator of this targetable component. May be null if has not
306 * been set.
307 *
308 * @return the creator of this targetable component.
309 */
310 public MCard getCreator() {
311 return creator;
312 }
313
314 /***
315 * Set the creator of this targetable component.
316 *
317 * @param creator
318 * the card creating this card. May be null.
319 */
320 public void setCreator(MCard creator) {
321 this.creator = creator;
322 }
323
324 /***
325 * Remove the named object.
326 *
327 * @param objectName
328 * the searched object's name
329 */
330 public void removePrivateNamedObject(String objectName) {
331 if (privateNamedObjects != null) {
332 privateNamedObjects.remove(objectName);
333 }
334 }
335
336 /***
337 * Add an object to this targetable. This object will be accessible with the
338 * specified name.
339 *
340 * @param objectName
341 * the object's name to save.
342 * @param targetable
343 * the targetable to save.
344 */
345 public void addPrivateNamedObject(String objectName, Targetable targetable) {
346 if (privateNamedObjects == null) {
347 privateNamedObjects = new HashMap<String, Targetable>();
348 }
349 privateNamedObjects.put(objectName, targetable);
350 }
351
352 /***
353 * Remove all stored objects.
354 */
355 public void clearPrivateNamedObject() {
356 if (privateNamedObjects != null) {
357 privateNamedObjects.clear();
358 privateNamedObjects = null;
359 }
360 }
361
362 /***
363 * Return a cloned instance of map of objects of this targetable.
364 *
365 * @return a cloned instance of map of objects of this targetable.
366 */
367 public Map<String, Targetable> getPrivateNamedObjects() {
368 if (privateNamedObjects != null) {
369 return null;
370 }
371 return new HashMap<String, Targetable>(privateNamedObjects);
372 }
373
374 /***
375 * Return the id of this component. For instance, this id is only relevant for
376 * players.
377 *
378 * @return the id of this component.
379 */
380 public int getId() {
381 return 0;
382 }
383
384 /***
385 * Return the timstamp value of this targetable.
386 *
387 * @return the timstamp value of this targetable.
388 */
389 public abstract int getTimestamp();
390
391 /***
392 * Add a reference to this targetable.
393 */
394 public abstract void addTimestampReference();
395
396 /***
397 * Decrement the reference counter for the current timestamp of this card.
398 *
399 * @param timestamp
400 * is the reference to decrement.
401 */
402 public abstract void decrementTimestampReference(int timestamp);
403
404 /***
405 * Current regiters of this targetable
406 */
407 public int[] registers;
408
409 /***
410 * The registerModifiers on this object
411 */
412 public RegisterModifier[] registerModifiers;
413
414 /***
415 * The ControllerModifier on this object
416 */
417 public ControllerModifier controllerModifier;
418
419 /***
420 * The registerModifiers on this object
421 */
422 public RegisterIndirection[] indirections;
423
424 /***
425 * Accessible objects of this component. Is <code>null</code> while no
426 * object has been saved. This map is destroyed when this component move.
427 */
428 private Map<String, Targetable> privateNamedObjects;
429
430 /***
431 * The creator of this targetable component.
432 */
433 private MCard creator;
434
435 /***
436 * The cached abilities of this component.
437 */
438 public List<Ability> cachedAbilities;
439 }