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 import java.net.URL;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.Map;
27
28 import net.sf.magicproject.action.intlist.IntList;
29 import net.sf.magicproject.action.objectmap.ObjectMapFactory;
30 import net.sf.magicproject.action.target.TargetFactory;
31 import net.sf.magicproject.action.targetlist.TargetListFactory;
32 import net.sf.magicproject.modifier.Modifier;
33 import net.sf.magicproject.operation.IdOperations;
34 import net.sf.magicproject.test.And;
35 import net.sf.magicproject.test.Or;
36 import net.sf.magicproject.test.Test;
37 import net.sf.magicproject.test.TestFactory;
38 import net.sf.magicproject.tools.MToolKit;
39 import net.sf.magicproject.tools.Picture;
40
41 /***
42 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
43 * @since 0.85
44 */
45 public final class ActionFactory {
46
47 /***
48 * Create a new instance of this class.
49 */
50 private ActionFactory() {
51 super();
52 }
53
54 /***
55 * Initialize pictures and constraints associted to actions.
56 * <ul>
57 * Structure of InputStream : Data[size]
58 * <li>baseUrl of action pictures [String]
59 * <li>nb associated pictures [int]</li>
60 * <li>action i [MAction]</li>
61 * <li>picture i [String]</li>
62 * <li>nb associated constraints [1]</li>
63 * <li>action i [MAction]</li>
64 * <li>operation for test i [Operation]</li>
65 * <li>constraint i [Test]</li>
66 * </ul>
67 *
68 * @param inputFile
69 * file containing this action
70 * @throws IOException
71 * If some other I/O error occurs
72 */
73 public static void init(InputStream inputFile) throws IOException {
74
75 final String picturesBaseUrl = MToolKit.readString(inputFile);
76 PICTURES.clear();
77 for (int i = inputFile.read(); i-- > 0;) {
78 final String actionName = MToolKit.readString(inputFile);
79 final String pictureName = MToolKit.readString(inputFile);
80 Picture.download(MToolKit.getTbsPicture("actions/" + pictureName, false),
81 new URL(picturesBaseUrl + pictureName));
82 PICTURES.put(actionName, "<img src='file:///"
83 + MToolKit.getTbsHtmlPicture("actions/" + pictureName) + "'> ");
84 }
85
86
87 CONSTRAINTS.clear();
88 for (int i = inputFile.read(); i-- > 0;) {
89 final Object[] constraint = new Object[3];
90
91
92 final MAction action = ActionFactory.readAction(inputFile, null);
93 constraint[0] = action;
94
95
96 constraint[1] = new Integer(inputFile.read());
97
98
99 constraint[2] = TestFactory.readNextTest(inputFile);
100
101
102 CONSTRAINTS.put(action.getIdAction(), constraint);
103 }
104 }
105
106 /***
107 * Read a list a actions from the given input stream.
108 *
109 * @param inputFile
110 * the stream used to create list of actions.
111 * @param modifier
112 * the optional modifier containing the action list.
113 * @return list of actions read from the given stream.
114 * @throws IOException
115 * If some other I/O error occurs
116 */
117 public static MAction[] readActionList(InputStream inputFile,
118 Modifier modifier) throws IOException {
119 final MAction[] res = new MAction[inputFile.read()];
120 try {
121 for (int index = 0; index < res.length; index++) {
122 res[index] = ActionFactory.readAction(inputFile, null);
123 }
124 return res;
125 } catch (Throwable e) {
126 throw new RuntimeException(
127 ">> TBS ERROR reading action. Last known action is : "
128 + currentAction + ", context : " + Arrays.toString(res), e);
129 }
130 }
131
132 /***
133 * Return the constraints to make usable the specified actions list.
134 *
135 * @param cost
136 * is the actions list
137 * @param constraintTest
138 * is the existing constrains
139 * @return the constraints to make usable the specified actions list.
140 */
141 public static Test getConstraints(MAction[] cost, Test constraintTest) {
142 Test res = constraintTest;
143 for (int index = 0; index < cost.length; index++) {
144
145 final Object[] constraint = CONSTRAINTS.get(cost[index].getIdAction());
146 if (constraint != null && cost[index].equal((MAction) constraint[0])) {
147
148 switch (((Integer) constraint[1]).intValue()) {
149 case IdOperations.AND:
150 res = And.append(constraintTest, cost[index]
151 .parseTest((Test) constraint[2]));
152 break;
153 case IdOperations.OR:
154 res = Or.append(constraintTest, (Test) constraint[2]);
155 break;
156 default:
157 throw new InternalError("Unknown constraint operation : "
158 + ((Integer) constraint[1]).intValue());
159 }
160 }
161 }
162 return res;
163 }
164
165 /***
166 * Read and return the next action from specified inputFile
167 *
168 * @param inputFile
169 * the input stream where action will be read.
170 * @param modifier
171 * the modifier that would be used with actions that need it. Can be
172 * null.
173 * @return the next action read into of specified inputFile
174 * @throws IOException
175 * If some other I/O error occurs
176 */
177 public static MAction readAction(InputStream inputFile, Modifier modifier)
178 throws IOException {
179 Actiontype idAction = Actiontype.valueOf(inputFile);
180 switch (idAction) {
181 case ABORT:
182 return Abort.instance;
183 case ADD_ABILITY:
184 return new AddAbility(inputFile);
185 case ADD_MODIFIER:
186 return new AddModifier(inputFile);
187 case ADD_OBJECT:
188 return new AddObject(inputFile);
189 case ATTACH_LIST:
190 return new AttachList(inputFile);
191 case CHOICE:
192 return new InputChoice(inputFile);
193 case CREATE_ABILITY:
194 return new CreateAbility(inputFile);
195 case CREATE_CARD:
196 return new CreateCard(inputFile);
197 case CREATE_MODIFIER:
198 return new CreateModifier(inputFile);
199 case REMOVE_OBJECT:
200 return new RemoveObject(inputFile);
201 case ASSIGN_DAMAGE_TARGET:
202 return new AssignDamageTarget(inputFile);
203 case ASSIGN_DAMAGE_SOURCE_DEST:
204 return new AssignDamageSourceDest(inputFile);
205 case DETACH_ME:
206 return DetachMe.getInstance();
207 case GENERATE_EVENT:
208 return new GenerateEvent(inputFile);
209 case GIVE_MANA_BASIC:
210 return new GiveManaBasic(inputFile);
211 case GIVE_MANA_MULTI:
212 return new GiveManaMulti(inputFile);
213 case HOP:
214 return new Hop(inputFile);
215 case IF_THEN_ELSE:
216 return new IfThenHop(inputFile);
217 case INPUT_COLOR:
218 return new InputColor(inputFile);
219 case INPUT_NUMBER:
220 return new InputNumber(inputFile);
221 case INPUT_ZONE:
222 return new InputZone(inputFile);
223 case INPUT_PROPERTY:
224 return new InputProperty(inputFile);
225 case INT_LIST:
226 return IntList.readNextIntList(inputFile);
227 case LETHAL_DAMAGE:
228 return LethalDamage.instance;
229 case LOSE_GAME:
230 return new LoseGame(inputFile);
231 case MODIFY_ABILITY_REGISTER:
232 return new ModifyAbilityRegister(inputFile);
233 case MODIFY_STACK_REGISTER:
234 return new ModifyStackRegister(inputFile);
235 case MODIFY_TARGET_LIST_REGISTER:
236 return new ModifyTargetListRegister(inputFile);
237 case MODIFY_TARGETABLE_REGISTER:
238 return new ModifyTargetableRegister(inputFile);
239 case MODIFY_STATIC_REGISTER:
240 return new ModifyStaticRegister(inputFile);
241 case MODIFY_REQUIRED_MANA:
242 return new ModifyRequiredMana(inputFile);
243 case MOVE_CARD:
244 return new MoveCard(inputFile);
245 case MOVE_OBJECT:
246 return new MoveObject(inputFile);
247 case MOVE_PLAYER_CARD:
248 return new MovePlayerCard(inputFile);
249 case MSG:
250 return new Input(inputFile);
251 case NEXT_CURRENT_PLAYER:
252 return new NextCurrentPlayer(inputFile);
253 case NEXT_PHASE:
254 return new NextPhase(inputFile);
255 case OBJECT_MAP:
256 return ObjectMapFactory.readNextObjectMap(inputFile);
257 case PAY_MANA:
258 return new PayMana(inputFile);
259 case UNREGISTER_THIS:
260 return UnregisterThis.instance;
261 case REPEAT_ACTION:
262 return new Repeat(inputFile);
263 case RESOLVE_HIDDEN:
264 return ResolveHidden.instance;
265 case SET_ID_CARD:
266 return new SetIdCard(inputFile);
267 case SHUFFLE:
268 return new Shuffle(inputFile);
269 case SKIP_PHASE:
270 return new SkipPhase(inputFile);
271 case SOUND:
272 return new Sound(inputFile);
273 case TAP:
274 return new Tap(inputFile);
275 case TARGET:
276 return TargetFactory.readNextTarget(inputFile);
277 case TARGET_LIST:
278 return TargetListFactory.readNextTargetList(inputFile);
279 case UPDATE_TOUGHNESS:
280 return UpdateToughness.getInstance();
281 case UPDATE_LIFE:
282 return UpdateLife.getInstance();
283 case ZONE_VISIBILITY:
284 return new ZoneVisibility(inputFile);
285 case FORCE_PLAY:
286 return new ForcePlay(inputFile);
287 case TARGET_ALL:
288 return new TargetAllNoEvent(inputFile);
289 case TARGET_RANDOM:
290 return new TargetRandomNoEvent(inputFile);
291 case ATTACH:
292 return new Attach(inputFile);
293 case FACE:
294 return new Face(inputFile);
295 case COPY_CARD:
296 return new CopyCard(inputFile);
297 case RESTORE_CARD:
298 return new RestoreCard(inputFile);
299 default:
300 throw new InternalError("Unknow action: " + idAction);
301 }
302 }
303
304 /***
305 * Associated pictures
306 */
307 protected static final Map<String, String> PICTURES = new HashMap<String, String>();;
308
309 /***
310 * Available action constraints.
311 */
312 private static final Map<Actiontype, Object[]> CONSTRAINTS = new HashMap<Actiontype, Object[]>();
313
314 /***
315 * Is the current action is being to be parsed. Used only while parsing.
316 */
317 static UserAction currentAction;
318
319 }