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.action;
23
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import net.sf.magicproject.Magic;
28 import net.sf.magicproject.action.listener.WaitingAbility;
29 import net.sf.magicproject.action.listener.WaitingCard;
30 import net.sf.magicproject.clickable.ability.Ability;
31 import net.sf.magicproject.clickable.targetable.card.MCard;
32 import net.sf.magicproject.clickable.targetable.player.Player;
33 import net.sf.magicproject.event.CanICast;
34 import net.sf.magicproject.event.context.ContextEventListener;
35 import net.sf.magicproject.stack.ActivatedChoiceList;
36 import net.sf.magicproject.stack.EventManager;
37 import net.sf.magicproject.stack.StackManager;
38 import net.sf.magicproject.ui.component.TableTop;
39 import net.sf.magicproject.zone.MZone;
40 import net.sf.magicproject.zone.ZoneManager;
41
42 /***
43 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
44 * @since 0.60
45 */
46 public final class WaitActivatedChoice extends MAction implements WaitingCard,
47 WaitingAbility {
48
49 /***
50 * Create a new instance of WaitTriggeredBufferChoice
51 */
52 private WaitActivatedChoice() {
53 super();
54 }
55
56 /***
57 * Generate event associated to this action. Only one or several events are
58 * generated and may be collected by event listeners. Then play this action
59 *
60 * @param ability
61 * is the ability owning this test. The card component of this
62 * ability should correspond to the card owning this test too.
63 * @param context
64 * is the context attached to this action.
65 * @return true if the stack resolution can continue. False if the stack
66 * resolution is broken.
67 */
68 public boolean play(ContextEventListener context, Ability ability) {
69 hasDesclined[0] = false;
70 hasDesclined[1] = false;
71 if (!opponentResponse) {
72 hasDesclined[1 - StackManager.idActivePlayer] = true;
73 }
74 zoneList = null;
75 finished();
76 if (waitAbilityChoice(StackManager.activePlayer())) {
77 return finishedActivatedChoice();
78 }
79 return false;
80 }
81
82 public boolean clickOn(MCard card) {
83 return StackManager.idHandedPlayer != 0;
84 }
85
86 public boolean clickOn(Ability ability) {
87 return StackManager.idHandedPlayer == 0;
88 }
89
90 public boolean succeedClickOn(MCard card) {
91 throw new InternalError("Card selection was not expected");
92 }
93
94 public boolean succeedClickOn(Ability ability) {
95 finished();
96 StackManager.newSpell(ability, ability.isMatching());
97 return true;
98 }
99
100 @Override
101 public Actiontype getIdAction() {
102 return Actiontype.WAIT_ACTIVATED_CHOICE;
103 }
104
105 public boolean manualSkip() {
106 finished();
107 hasDesclined[StackManager.oldIdHandedPlayer] = true;
108 if (waitAbilityChoice(StackManager.nonActivePlayer())) {
109 return finishedActivatedChoice();
110 }
111 return false;
112 }
113
114 public void finished() {
115 if (activChoiceList != null) {
116 activChoiceList.disHighLight();
117 activChoiceList.clear();
118 activChoiceList = null;
119 }
120 if (zoneList != null) {
121 for (MZone zone : zoneList) {
122 zone.disHighLight();
123 }
124 zoneList.clear();
125 zoneList = null;
126 StackManager.PLAYERS[0].disHighLight();
127 StackManager.PLAYERS[1].disHighLight();
128 }
129 }
130
131 /***
132 * Called when active player and non-active player have finished their choice
133 * order of their triggered abilities in the stack
134 *
135 * @return true if the stack resolution can continue. False if the stack
136 * resolution is broken.
137 */
138 private boolean finishedActivatedChoice() {
139 StackManager.disableAbort();
140 WaitActivatedChoice.getInstance().finished();
141 if (StackManager.isEmpty()) {
142
143 EventManager.gotoNextPhase();
144 return false;
145 }
146
147 return true;
148 }
149
150 /***
151 * @param firstPlayer
152 * @return true if the stack resolution can continue. False if the stack
153 * resolution is broken.
154 */
155 private boolean waitAbilityChoice(Player firstPlayer) {
156 if (hasDesclined[firstPlayer.idPlayer]) {
157 if (hasDesclined[1 - firstPlayer.idPlayer]) {
158
159 return true;
160 }
161 return waitAbilityChoice(firstPlayer.getOpponent());
162 }
163 final List<Ability> res = new ArrayList<Ability>();
164 final List<Ability> advRes = new ArrayList<Ability>();
165 CanICast.dispatchEvent(firstPlayer.idPlayer, res, advRes);
166 finished();
167 if (!res.isEmpty()) {
168
169
170
171 activChoiceList = new ActivatedChoiceList(res, advRes);
172 res.clear();
173 advRes.clear();
174 if (firstPlayer.isYou() && StackManager.isEmpty()
175 && firstPlayer.declinePlay() || firstPlayer.isYou()
176 && StackManager.currentIsYou() && !StackManager.isEmpty()
177 && firstPlayer.declineResponseMe() || firstPlayer.isYou()
178 && !StackManager.currentIsYou() && !StackManager.isEmpty()
179 && firstPlayer.declineResponseOpponent()) {
180
181 StackManager.idActivePlayer = 0;
182 StackManager.idHandedPlayer = 0;
183 System.out.println(new StringBuilder("You play. Dump [ap :").append(
184 StackManager.idActivePlayer).append(", cp :").append(
185 StackManager.idCurrentPlayer).append(", s# :").append(
186 StackManager.CONTEXTES.size()).append(", action :")
187 .append(
188 StackManager.actionManager.currentAction.getClass()
189 .getSimpleName()).append(", li :").append(
190 StackManager.actionManager.loopingIndex).append(", hop :")
191 .append(StackManager.actionManager.hop).append(
192 "] - (AUTO SKIP IS COMING)"));
193 StackManager.oldIdHandedPlayer = 0;
194 Magic.sendManualSkip();
195 return manualSkip();
196 }
197 if (activChoiceList != null) {
198 zoneList = activChoiceList.highLight();
199 if (zoneList != null && !StackManager.isEmpty()
200 && !zoneList.contains(ZoneManager.stack)) {
201 TableTop.getInstance().tabbedPane
202 .setSelectedComponent(ZoneManager.stack.superPanel);
203 }
204 }
205 firstPlayer.setActivePlayer();
206 return false;
207 }
208
209 hasDesclined[firstPlayer.idPlayer] = true;
210 return waitAbilityChoice(firstPlayer.getOpponent());
211 }
212
213 public List<Ability> abilitiesOf(MCard card) {
214 return activChoiceList == null ? null : activChoiceList.abilitiesOf(card);
215 }
216
217 public List<Ability> advancedAbilitiesOf(MCard card) {
218 return activChoiceList == null ? null : activChoiceList
219 .advancedAbilitiesOf(card);
220 }
221
222 /***
223 * return the string representation of this action
224 *
225 * @param ability
226 * is the ability owning this test. The card component of this
227 * ability should correspond to the card owning this test too.
228 * @return the string representation of this action
229 * @see Object#toString()
230 */
231 @Override
232 public String toString(Ability ability) {
233 return "Wait activated ability choice";
234 }
235
236 /***
237 * Return the unique instance of this class.
238 *
239 * @return the unique instance of this class.
240 */
241 public static WaitActivatedChoice getInstance() {
242 if (instance == null)
243 instance = new WaitActivatedChoice();
244 return instance;
245 }
246
247 /***
248 * The unique instance of this class
249 */
250 private static WaitActivatedChoice instance;
251
252 /***
253 * indicates if this player has already declined to response to current spell
254 * When the active players gets priority, it would be tested to know if we
255 * have to resolve the stack
256 */
257 private boolean[] hasDesclined = new boolean[2];
258
259 /***
260 * This is the list of zone concerned by highlighted cards
261 */
262 private List<MZone> zoneList;
263
264 /***
265 * the current list of choices of active player
266 */
267 private ActivatedChoiceList activChoiceList;
268
269 /***
270 * If true, player can response to opponent effects
271 */
272 public static boolean opponentResponse;
273 }