1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.magicproject.event;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.List;
27
28 import net.sf.magicproject.action.GiveMana;
29 import net.sf.magicproject.action.MAction;
30 import net.sf.magicproject.clickable.ability.Ability;
31 import net.sf.magicproject.clickable.targetable.card.MCard;
32 import net.sf.magicproject.expression.ExpressionFactory;
33 import net.sf.magicproject.test.Test;
34 import net.sf.magicproject.token.IdTokens;
35
36 /***
37 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
38 * @since 0.54
39 * @since 0.93 recheck the card position during ability matching to avoid
40 * playable spell from stack.
41 */
42 public class CanICast extends MEventListener {
43
44 /***
45 * Create an instance of CanICast by reading a file Offset's file must
46 * pointing on the first byte of this event <br>
47 * <ul>
48 * Structure of InputStream : Data[size]
49 * <li>[super]</li>
50 * <li>idCard [Expression]</li>
51 * </ul>
52 *
53 * @param inputFile
54 * is the file containing this event
55 * @param card
56 * is the card owning this event
57 * @throws IOException
58 * if error occurred during the reading process from the specified
59 * input stream
60 */
61 public CanICast(InputStream inputFile, MCard card) throws IOException {
62 super(inputFile, card);
63
64 idCard = ExpressionFactory.readNextExpression(inputFile).getValue(null,
65 null, null);
66 }
67
68 /***
69 * Creates a new instance of CanICast specifying all attributes of this class.
70 * All parameters are copied, not cloned. So this new object shares the card
71 * and the specified codes
72 *
73 * @param idZone
74 * the place constraint to activate this event
75 * @param test
76 * the test of this event
77 * @param card
78 * is the card owning this card
79 * @param idCard
80 * is the id of card we want to play
81 */
82 protected CanICast(int idZone, Test test, MCard card, int idCard) {
83 super(idZone, test, card);
84 this.idCard = idCard;
85 }
86
87 @Override
88 public MEventListener clone(MCard card) {
89 return new CanICast(idZone, test, card, idCard);
90 }
91
92 @Override
93 public final boolean isActivated() {
94 return true;
95 }
96
97 @Override
98 public final boolean isTriggered() {
99 return false;
100 }
101
102 @Override
103 public final void registerToManager(Ability ability) {
104
105 if (!MEventListener.CAN_I_CAST_ABILITIES[ability.getController().idPlayer]
106 .contains(ability)) {
107 CAN_I_CAST_ABILITIES[ability.getController().idPlayer].add(ability);
108 }
109 }
110
111 @Override
112 public final void removeFromManager(Ability ability) {
113 CAN_I_CAST_ABILITIES[0].remove(ability);
114 CAN_I_CAST_ABILITIES[1].remove(ability);
115 }
116
117 /***
118 * Tell if the current event matches with this event. If there is an
119 * additional code to check, it'would be checked if the main event matches
120 * with the main event
121 *
122 * @param ability
123 * is the ability owning this test. The card component of this
124 * ability should correspond to the card owning this test too.
125 * @param idActivePlayer
126 * id of active player
127 * @return true if the current event match with this event
128 */
129 public boolean isMatching(Ability ability, int idActivePlayer) {
130 return isWellPlaced() && canIcastCondition(idActivePlayer, idCard)
131 && test(ability, card);
132 }
133
134 /***
135 * Tell if the current event matches with this event. If there is an
136 * additional code to check, it'would be checked if the main event matches
137 * with the main event
138 *
139 * @param ability
140 * is the ability owning this test. The card component of this
141 * ability should correspond to the card owning this test too.
142 * @param idActivePlayer
143 * id of active player
144 * @return true if the current event match with this event
145 */
146 public boolean isMatchingManaAbility(Ability ability, int idActivePlayer) {
147 return idCard == IdTokens.MANA_ABILITY && test(ability, card);
148 }
149
150 @Override
151 public boolean isWellPlaced() {
152 return card.playableZone(card.getIdZone(), this.idZone);
153 }
154
155 @Override
156 public boolean isWellPlaced(int idZone) {
157 return card.playableZone(idZone, this.idZone);
158 }
159
160 /***
161 * Dispatch this event to all active event listener able to understand this
162 * event. The listening events able to understand this event are <code>this
163 * </code>
164 * and other multiple event listeners
165 *
166 * @param idActivePlayer
167 * id of active player
168 * @param res
169 * list in which playable abilities would be added
170 * @param advRes
171 * list in which advanced playable abilities would be added
172 * @see #isMatching(Ability, int)
173 */
174 public static void dispatchEvent(int idActivePlayer, List<Ability> res,
175 List<Ability> advRes) {
176 for (Ability ability : CAN_I_CAST_ABILITIES[idActivePlayer]) {
177 if (((CanICast) ability.eventComing())
178 .isMatching(ability, idActivePlayer)
179 && ability.checkTargetActions() && ability.checkObjectActions()) {
180 if (ability.isMatching()) {
181 res.add(ability);
182 } else {
183 advRes.add(ability);
184 }
185 }
186 }
187 }
188
189 /***
190 * Dispatch this event to all active event listener able to understand this
191 * event.
192 *
193 * @param idActivePlayer
194 * id of active player
195 * @param res
196 * list in which playable abilities would be added
197 * @see #isMatching(Ability, int)
198 */
199 public static void dispatchManaAbilityEvent(int idActivePlayer,
200 List<Ability> res) {
201 for (Ability ability : CAN_I_CAST_ABILITIES[idActivePlayer]) {
202 if (((CanICast) ability.eventComing()).isMatchingManaAbility(ability,
203 idActivePlayer)
204 && ability.isMatching()) {
205 res.add(ability);
206 }
207 }
208 }
209
210 /***
211 * Iterate on given actions looking for a 'give mana' action. If one or
212 * several are found, the playable <code>idCard</code> of this event will be
213 * replaced by <code>IdTokens.MANA_ABILITY</code>
214 *
215 * @param actionList
216 * list of actions
217 * @return true if at least one 'give mana' action has been found in the
218 * specified list.
219 */
220 public boolean updateManaAbilityTag(MAction... actionList) {
221 for (MAction action : actionList) {
222 if (action instanceof GiveMana) {
223 idCard = IdTokens.MANA_ABILITY;
224 return true;
225 }
226 }
227 return false;
228 }
229
230 /***
231 * Return set of playable idCard
232 *
233 * @return set of playable idCard
234 */
235 public int getPlayableIdCard() {
236 return idCard;
237 }
238
239 @Override
240 public final Event getIdEvent() {
241 return Event.CAN_CAST_CARD;
242 }
243
244 /***
245 * set of playable idCard
246 */
247 private int idCard;
248
249 }