1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.magicproject.action;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23
24 import net.sf.magicproject.action.context.ActionContextWrapper;
25 import net.sf.magicproject.action.context.MovePlayerCardContext;
26 import net.sf.magicproject.action.handler.FollowAction;
27 import net.sf.magicproject.clickable.ability.Ability;
28 import net.sf.magicproject.clickable.targetable.Targetable;
29 import net.sf.magicproject.clickable.targetable.card.MCard;
30 import net.sf.magicproject.clickable.targetable.player.Player;
31 import net.sf.magicproject.event.UncaughtException;
32 import net.sf.magicproject.event.context.ContextEventListener;
33 import net.sf.magicproject.stack.StackManager;
34 import net.sf.magicproject.test.TestOn;
35 import net.sf.magicproject.token.IdPositions;
36 import net.sf.magicproject.token.IdZones;
37 import net.sf.magicproject.tools.Log;
38 import net.sf.magicproject.tools.MToolKit;
39 import net.sf.magicproject.zone.MZone;
40 import net.sf.magicproject.zone.ZoneManager;
41
42 /***
43 * To move any number of cards or the targeted player from their place to
44 * another. New position within the new zone, and the new controller have to be
45 * specified. <br>
46 *
47 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
48 * @since 0.54
49 */
50 class MovePlayerCard extends UserAction implements LoopAction, FollowAction {
51
52 /***
53 * Create an instance of MovePlayerCard by reading a file Offset's file must
54 * pointing on the first byte of this action <br>
55 * <ul>
56 * Structure of InputStream : Data[size]
57 * <li>new controller [TestOn]</li>
58 * <li>from zone [IdZone]</li>
59 * <li>destination zone [IdZone]</li>
60 * <li>idPosition [int16]</li>
61 * </ul>
62 *
63 * @param inputFile
64 * file containing this action
65 * @throws IOException
66 * if error occurred during the reading process from the specified
67 * input stream
68 */
69 MovePlayerCard(InputStream inputFile) throws IOException {
70 super(inputFile);
71 controller = TestOn.deserialize(inputFile);
72 from = inputFile.read();
73 to = inputFile.read();
74 idPosition = MToolKit.readInt16(inputFile);
75 }
76
77 @Override
78 public final Actiontype getIdAction() {
79 return Actiontype.MOVE_PLAYER_CARD;
80 }
81
82 public boolean continueLoop(ContextEventListener context, int loopingIndex,
83 Ability ability) {
84 final Targetable targetable = StackManager.getInstance().getTargetedList()
85 .get(loopingIndex);
86 if (!targetable.isPlayer()) {
87 Log.fatal("The move-player-card action use "
88 + "the players placed in the target-list, "
89 + "nevertheless a non-player element has been found (" + targetable
90 + ") : \n" + debugData);
91 }
92 final MZone panel = ((Player) targetable).zoneManager.getContainer(from);
93 if (panel.getComponentCount() == 0) {
94 UncaughtException.dispatchEvent((Player) StackManager.getInstance()
95 .getTargetedList().get(loopingIndex), "NoSuchElement");
96 return true;
97 } else if (MoveCard.moveCard(panel.getTop(), controller, to, context,
98 idPosition, ability, false)) {
99 return true;
100 }
101 return false;
102 }
103
104 public void rollback(ActionContextWrapper actionContext,
105 ContextEventListener context, Ability ability) {
106 final MovePlayerCardContext bContext = (MovePlayerCardContext) actionContext.actionContext;
107
108 for (int loopingIndex = bContext.srcZones.length; loopingIndex-- > 0;) {
109 final MZone zoneSrc = bContext.srcZones[loopingIndex];
110 final MCard card = bContext.cards[loopingIndex];
111 if (zoneSrc == null)
112 break;
113 zoneSrc.remove(card);
114 card.setIdZone(zoneSrc.getZoneId());
115 card.controller = bContext.controllers[loopingIndex];
116
117
118 card.isHighLighted = false;
119 card.reversed = card.needReverse();
120 card.getMUI().updateLayout();
121
122
123 switch (zoneSrc.getZoneId()) {
124 case IdZones.PLAY:
125
126 card.tap(bContext.tapPosition[loopingIndex]);
127 card.controller.zoneManager.play.addTop(card);
128 break;
129 case IdZones.NOWHERE:
130
131 break;
132 default:
133 zoneSrc.addTop(card);
134 }
135 }
136 }
137
138 public void simulate(ActionContextWrapper actionContext,
139 ContextEventListener context, Ability ability) {
140 final MovePlayerCardContext bContext = new MovePlayerCardContext(
141 StackManager.getInstance().getTargetedList().size());
142 actionContext.actionContext = bContext;
143 for (int loopingIndex = bContext.srcZones.length; loopingIndex-- > 0;) {
144 final MZone zoneSrc = ((Player) StackManager.getInstance()
145 .getTargetedList().get(loopingIndex)).zoneManager.getContainer(from);
146 if (zoneSrc.getComponentCount() > 0) {
147 final MCard card = zoneSrc.getTop();
148 final Player newController = (Player) controller.getTargetable(ability,
149 card, context, null);
150 final int destinationZone = MCard.getIdZone(to, context);
151 final boolean newIsTapped = (to & IdZones.PLAY_TAPPED) == IdZones.PLAY_TAPPED;
152
153 bContext.tapPosition[loopingIndex] = card.tapped;
154 bContext.controllers[loopingIndex] = card.controller;
155 bContext.srcZones[loopingIndex] = zoneSrc;
156
157
158 zoneSrc.remove(card);
159
160
161 card.controller = newController;
162 card.setIdZone(destinationZone);
163 card.isHighLighted = false;
164 card.reversed = card.needReverse();
165 card.tap(false);
166
167
168 switch (destinationZone) {
169 case IdZones.PLAY:
170
171 card.tap(newIsTapped);
172 newController.zoneManager.play.addBottom(card);
173 break;
174 case IdZones.NOWHERE:
175
176 break;
177 default:
178 switch (idPosition) {
179 case IdPositions.ON_THE_TOP:
180 newController.zoneManager.getContainer(destinationZone)
181 .addTop(card);
182 break;
183 case IdPositions.ON_THE_BOTTOM:
184 default:
185 newController.zoneManager.getContainer(destinationZone).addBottom(
186 card);
187 }
188 }
189 }
190 }
191 }
192
193 /***
194 * Return the first index of this loop.
195 *
196 * @return the first index of this loop.
197 */
198 public int getStartIndex() {
199 return StackManager.getInstance().getTargetedList().size() - 1;
200 }
201
202 @Override
203 public String toString(Ability ability) {
204 if (MCard.getIdZone(to, null) == IdZones.PLAY) {
205 return "Put in play" + (MCard.isTapped(to) ? " tapped" : "");
206 }
207 if (to == IdZones.HAND) {
208 return "Return to graveyard";
209 }
210 return "move from " + ZoneManager.getZoneName(from) + " to "
211 + ZoneManager.getZoneName(MCard.getIdZone(to, null));
212 }
213
214 /***
215 * the destination place
216 */
217 private final int to;
218
219 /***
220 * the source place
221 */
222 private final int from;
223
224 /***
225 * The new controller
226 */
227 private final TestOn controller;
228
229 /***
230 * The position where card would be placed
231 */
232 private final int idPosition;
233
234 }