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