1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.firemox.xml.magic;
20
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.FileReader;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import javax.xml.XMLConstants;
32
33 import net.sf.firemox.token.IdConst;
34 import net.sf.firemox.tools.MToolKit;
35
36 import org.apache.commons.io.FileUtils;
37 import org.apache.commons.io.FilenameUtils;
38 import org.apache.commons.io.IOUtils;
39 import org.apache.commons.lang.StringUtils;
40 import org.kohsuke.args4j.CmdLineException;
41 import org.kohsuke.args4j.CmdLineParser;
42
43 /***
44 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
45 * @since 0.90
46 */
47 public final class Oracle2Xml {
48
49 /***
50 * May the validated cards (recycled directory) be patched by the new ones?
51 */
52 private static final boolean UPDATE_CARD = false;
53
54 /***
55 * Bounds
56 */
57 private static final int MAXI = Integer.MAX_VALUE;
58
59 private static final String TBS_NAME = IdConst.TBS_DEFAULT;
60
61 private static Options options;
62
63 /***
64 * Prevent this class to be instantiated.
65 */
66 private Oracle2Xml() {
67 super();
68 }
69
70 /***
71 * @param oracleFile
72 * the oracle format text file.
73 * @param destinationDir
74 * the directory where built card will be placed.
75 * @param recycledDir
76 * the directory where already built card are placed.
77 */
78 @SuppressWarnings("null")
79 public void serialize(File oracleFile, File destinationDir, File recycledDir) {
80 if (!oracleFile.exists() || !oracleFile.isFile()) {
81 System.err.println("The file '" + oracleFile + "' does not exist");
82 System.exit(-1);
83 return;
84 }
85
86 if (!destinationDir.exists() || !destinationDir.isDirectory()) {
87 System.err.println("The destination directory '" + destinationDir
88 + "' does not exist");
89 System.exit(-1);
90 return;
91 }
92 final StringBuilder cardText = new StringBuilder();
93 int nbCard = 0;
94 MToolKit.tbsName = TBS_NAME;
95 try {
96 final BufferedReader in = new BufferedReader(new FileReader(oracleFile));
97 PrintWriter out = null;
98 while (nbCard < MAXI) {
99 String line = in.readLine();
100 if (line == null)
101 break;
102 String cardName = line.trim();
103 if (cardName.length() == 0) {
104 continue;
105 }
106
107
108 String fileName = MToolKit.getExactKeyName(cardName) + ".xml";
109 if (new File(recycledDir, fileName).exists()) {
110 if (UPDATE_CARD) {
111 File patchFile = MToolKit.getFile("tbs/mtg/recycled/" + fileName);
112 File tempFile = File.createTempFile(fileName, "temp");
113 FileUtils.copyFile(patchFile, tempFile);
114 final BufferedReader inExist = new BufferedReader(new FileReader(
115 tempFile));
116 final PrintWriter outExist = new PrintWriter(new FileOutputStream(
117 patchFile));
118 String lineExist = null;
119 boolean found = false;
120 while ((lineExist = inExist.readLine()) != null) {
121 if (!found && lineExist.contains("name=\"")) {
122 lineExist = lineExist
123 .substring(0, lineExist.indexOf("name=\""))
124 + "name=\""
125 + cardName
126 + lineExist.substring(lineExist.indexOf("\"", lineExist
127 .indexOf("name=\"")
128 + "name=\"".length() + 2));
129 found = true;
130 }
131 outExist.println(lineExist);
132 }
133 IOUtils.closeQuietly(inExist);
134 IOUtils.closeQuietly(outExist);
135
136 if (!found) {
137 System.err.println(">> Error patching card '" + cardName + "'");
138
139
140 }
141 }
142 skipCard(in);
143 continue;
144 }
145
146 out = new PrintWriter(new FileOutputStream(new File(destinationDir,
147 fileName)));
148 int[] manaCost = null;
149
150
151 cardText.setLength(0);
152 cardText.append("<!--\n\t");
153
154 List<String> properties = new ArrayList<String>();
155 String power = null;
156 String toughness = null;
157 isNonBasicLand = false;
158 isLocalEnchantCreature = false;
159 isLocalEnchantLand = false;
160 isLocalEnchantArtifact = false;
161 isEnchantWorld = false;
162 isLocalEnchantCreatureArtifact = false;
163 isLocalEnchantPermanent = false;
164 isLocalEnchantEnchantment = false;
165 isGlobalEnchant = false;
166 isInstant = false;
167 isCreature = false;
168 isArtifact = false;
169 isSorcery = false;
170 isSwamp = false;
171 isIsland = false;
172 isForest = false;
173 isMountain = false;
174 isPlains = false;
175 boolean isTribal = false;
176 boolean isPlaneswalker = false;
177 boolean isEquipment = false;
178
179 line = in.readLine().trim().replaceAll("//(.*//)", "").toLowerCase();
180 cardText.append('\t').append(line).append("\n");
181
182 isArtifact = line.indexOf("artifact") != -1;
183 if (line.startsWith("land") || line.endsWith(" land")) {
184 isNonBasicLand = true;
185 } else {
186 manaCost = extractManaCost(line);
187 line = in.readLine().replaceAll("//(.*//)", "").toLowerCase();
188 cardText.append('\t').append(line).append("\n");
189 isLocalEnchantCreature = line.indexOf("enchant creature") != -1;
190 isEnchantWorld = line.indexOf("world enchantment") != -1;
191 isAura = line.indexOf("aura") != -1;
192 isTribal = line.indexOf("tribal") != -1;
193 isPlaneswalker = line.indexOf("planeswalker") != -1;
194 if (line.indexOf("enchantment") != -1 && !isAura && !isEnchantWorld)
195 isGlobalEnchant = true;
196 if (!isGlobalEnchant && !isAura && !isEnchantWorld
197 && !isLocalEnchantCreature) {
198 isInstant = line.indexOf("instant") != -1;
199 isCreature = line.indexOf("creature") != -1;
200 isSorcery = line.indexOf("sorcery") != -1;
201 isSwamp = line.indexOf("swamp") != -1;
202 isIsland = line.indexOf("island") != -1;
203 isForest = line.indexOf("forest") != -1;
204 isMountain = line.indexOf("mountain") != -1;
205 isArtifact = isArtifact || line.indexOf("artifact") != -1;
206 isPlains = line.indexOf("plains") != -1;
207 }
208 }
209 if (line.indexOf("snow") != -1)
210 properties.add("snow");
211
212 if (line.indexOf("legendary") != -1)
213 properties.add("legend");
214
215 if (line.indexOf("-") != -1) {
216 properties = extractProperties(line.substring(line.indexOf("-") + 1)
217 .trim(), properties);
218 }
219 if (isCreature) {
220 line = in.readLine();
221 cardText.append('\t').append(line).append("\n");
222 if (line.indexOf("/") == -1) {
223 System.err.println("Error reading card '" + cardName
224 + "' : power/toughness, line=" + line);
225 skipCard(in);
226 continue;
227 }
228 power = line.substring(0, line.indexOf('/')).trim();
229 toughness = line.substring(line.indexOf('/') + 1).trim();
230 }
231 if (isEnchantWorld) {
232 properties.add("enchant-world");
233 }
234
235 if (properties.contains("equipment"))
236 isEquipment = true;
237
238 List<String> lineBuffer = new ArrayList<String>();
239 boolean hasBuyBack = false;
240 boolean hasFlashBack = false;
241 boolean hasForecast = false;
242 boolean hasAffinity = false;
243 boolean hasRampage = false;
244 boolean hasTransmute = false;
245 boolean hasDredge = false;
246 boolean hasHaunt = false;
247 boolean hasBloodThirst = false;
248 boolean hasBushido = false;
249 String hasTransmuteCost = null;
250 int hasRampageCount = 1;
251 int hasDredgeCount = 1;
252 int hasBloodThirstCount = 1;
253 int hasBushidoCount = 1;
254 boolean hasFading = false;
255 boolean hasLessToPlay = false;
256 boolean hasMoreToPlay = false;
257 boolean hasVanishing = false;
258 lowerCard = cardName.toLowerCase();
259 String hasBuyBackLine = null;
260 String hasFlashBackLine = null;
261 String hasAffinityLine = null;
262 String hasForecastLine = null;
263 String hasFadingLine = null;
264 String hasVanishingLine = null;
265 String hasSuspendLine = null;
266 boolean hasFlanking = false;
267 boolean hasHaunting = false;
268 boolean hasSuspend = false;
269 boolean hasLifelink = false;
270 boolean hasDeathtouch = false;
271
272 String equipLine = "";
273
274 while (true) {
275 line = in.readLine();
276 if (line == null || line.length() == 0)
277 break;
278 line = line.replaceAll("T ", "T :").replaceAll("//(.*//)", "")
279 .toLowerCase();
280 cardText.append('\t').append(line).append('\n');
281
282 if (isAura && !isLocalEnchantCreature && !isLocalEnchantLand
283 && !isLocalEnchantCreatureArtifact && !isLocalEnchantArtifact
284 && !isLocalEnchantPermanent && !isLocalEnchantEnchantment) {
285 isLocalEnchantCreature = line.indexOf("enchant creature") != -1;
286 isLocalEnchantLand = line.indexOf("enchant land") != -1;
287 isLocalEnchantCreatureArtifact = line
288 .indexOf("enchant artifact creature") != -1;
289 isLocalEnchantArtifact = !isLocalEnchantCreatureArtifact
290 && line.indexOf("enchant artifact") != -1;
291 isLocalEnchantPermanent = line.indexOf("enchant permanent") != -1;
292 isLocalEnchantEnchantment = line.indexOf("enchant enchantment") != -1;
293 }
294
295 if (line.startsWith("buyback")) {
296 hasBuyBack = true;
297 hasBuyBackLine = line.substring("buyback".length()).trim();
298 continue;
299 } else if (line.startsWith("haunt")) {
300 hasHaunt = true;
301 continue;
302 } else if (line.startsWith("flashback")) {
303 hasFlashBack = true;
304 hasFlashBackLine = line.substring("flashback".length()).trim();
305 continue;
306 } else if (line.startsWith("affinity for ")) {
307 hasAffinity = true;
308 hasAffinityLine = line.substring("affinity for ".length()).trim();
309 continue;
310 } else if (line.startsWith("forecast")) {
311 hasForecast = true;
312 hasForecastLine = line.substring("forecast - ".length()).trim();
313 continue;
314 } else if (line.startsWith("rampage ")) {
315 hasRampage = true;
316 hasRampageCount = Integer.parseInt(line.substring(
317 "rampage ".length(), "rampage ".length() + 1).trim());
318 continue;
319 } else if (line.startsWith("transmute ")) {
320 hasTransmute = true;
321 hasTransmuteCost = line.substring("transmute ".length()).trim();
322 continue;
323 } else if (line.startsWith("dredge ")) {
324 hasDredge = true;
325 hasDredgeCount = Integer.parseInt(line.substring(
326 "dredge ".length(), "dredge ".length() + 1).trim());
327 continue;
328 } else if (line.startsWith("bloodthirst ")) {
329 hasBloodThirst = true;
330 String bloodThirst = line.substring("bloodthirst ".length(),
331 "bloodthirst ".length() + 1).trim();
332 if (bloodThirst.compareTo("x") != 0)
333 hasBloodThirstCount = Integer.parseInt(bloodThirst);
334 else
335 hasBloodThirstCount = 0;
336
337 continue;
338 } else if (line.startsWith("bushido ")) {
339 hasBushido = true;
340 hasBushidoCount = Integer.parseInt(line.substring(
341 "bushido ".length(), "bushido ".length() + 1).trim());
342 continue;
343 } else if (line.startsWith("fading")) {
344 hasFading = true;
345 hasFadingLine = line.substring("fading".length()).trim();
346 continue;
347 } else if (line.startsWith("vanishing")) {
348 hasVanishing = true;
349 hasVanishingLine = line.substring("vanishing".length()).trim();
350 continue;
351 } else if (line.startsWith("flanking")) {
352 hasFlanking = true;
353 continue;
354 } else if (line.startsWith("haunt")) {
355 hasHaunting = true;
356 continue;
357 } else if (line.startsWith("suspend")) {
358 hasSuspend = true;
359 hasSuspendLine = line.substring("suspend ".length()).trim();
360 continue;
361 }
362 if (line.contains(" less to play.")) {
363 hasLessToPlay = true;
364 }
365 if (line.contains(" more to play.")) {
366 hasMoreToPlay = true;
367 }
368 if (line.contains("lifelink")) {
369 hasLifelink = true;
370 }
371 if (line.contains("deathtouch")) {
372 hasDeathtouch = true;
373 }
374
375 if (line.indexOf(lowerCard + " doesn't untap during") != -1) {
376 properties.add("does-not-untap");
377 }
378 if (line.indexOf("you may choose not to untap") != -1) {
379 properties.add("may-not-untap");
380 }
381 if (line.indexOf(lowerCard + " can't block") != -1) {
382 properties.add("cannot-block");
383 }
384 if (line.indexOf(lowerCard + " can't attack") != -1) {
385 properties.add("cannot-attack");
386 }
387 if (line.indexOf(lowerCard + " is unblockable.") != -1)
388 properties.add("unblockable");
389
390 if (line.indexOf(lowerCard + " is indestructible.") != -1)
391 properties.add("indestructible");
392
393 if (line.indexOf(lowerCard + " can't be countered.") != -1)
394 properties.add("cannot-be-countered");
395
396 if (line.indexOf(lowerCard + " attacks each turn if able.") != -1)
397 properties.add("attacks-if-able");
398
399 if (line.indexOf(lowerCard + " can't be blocked by walls.") != -1)
400 properties.add("cannot-be-blocked-by-walls");
401
402 if (line.indexOf(lowerCard + " can block only creatures with flying") != -1)
403 properties.add("block-only-flying");
404
405 line = updateProperties(line, properties);
406 lineBuffer.add(line);
407 }
408
409 cardText.append(" -->");
410 out.println("<?xml version='1.0'?>");
411
412 out.print("<card xmlns='");
413 out.println(IdConst.NAME_SPACE + "'");
414 out.print("\txmlns:xsi='");
415 out.print(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
416 out.println("'");
417 out.print("\txsi:schemaLocation='");
418 out.println(IdConst.NAME_SPACE + " ../../" + IdConst.TBS_XSD + "'");
419 out.println("\tname=\"" + cardName + "\">");
420 out.println("<rules-author-comment>Oracle2Xml generator "
421 + IdConst.VERSION + "</rules-author-comment>\n");
422 out.println(cardText.toString());
423 out.println("\n\t<!-- COMPLETE THE CODE OF THIS CARD -->\n");
424 out.println("\t<init>");
425 out.println("\t\t<registers>");
426 if (manaCost != null) {
427 for (int i = 6; i-- > 0;) {
428 if (manaCost[i] > 0) {
429 out.println("\t\t\t<register index='" + extractColor(i)
430 + "' value='" + manaCost[i] + "'/>");
431 }
432 }
433 }
434
435 if (isCreature) {
436 if (power.indexOf("*") != -1) {
437
438 out.println("\t\t\t<register index='power'>");
439 out.println("\t\t\t\t<!-- REPLACE THIS CODE -->");
440 out.println("\t\t\t\t<value><counter restriction-zone='play'>");
441 out.println("\t\t\t\t\t<and>");
442 out.println("\t\t\t\t\t\t<has-idcard idcard='swamp'/>");
443 out.println("\t\t\t\t\t\t<controller player='you'/>");
444 out.println("\t\t\t\t\t</and>");
445 out.println("\t\t\t\t</counter></value>");
446 out.println("\t\t\t</register>");
447 } else {
448 out
449 .println("\t\t\t<register index='power' value='" + power
450 + "'/>");
451 }
452 if (toughness.indexOf("*") != -1) {
453
454 out.println("\t\t\t<register index='toughness'>");
455 out.println("\t\t\t\t<!-- REPLACE THIS CODE -->");
456 out.println("\t\t\t\t<value><counter restriction-zone='play'>");
457 out.println("\t\t\t\t\t<and>");
458 out.println("\t\t\t\t\t\t<has-idcard idcard='swamp'/>");
459 out.println("\t\t\t\t\t\t<controller player='you'/>");
460 out.println("\t\t\t\t\t</and>");
461 out.println("\t\t\t\t</counter></value>");
462 out.println("\t\t\t</register>");
463 } else {
464 out.println("\t\t\t<register index='toughness' value='" + toughness
465 + "'/>");
466 }
467 }
468 out.println("\t\t</registers>");
469
470
471 if (manaCost != null && manaCost.length > 0) {
472 out.print("\t\t<colors>");
473 for (int i = manaCost.length - 1; i-- > 1;) {
474 if (manaCost[i] > 0) {
475 out.print(extractColor(i));
476 if (i > 0) {
477 out.print(" ");
478 }
479 }
480 }
481 out.println("</colors>");
482 }
483
484
485 out.print("\t\t<idcards>");
486 if (isTribal)
487 out.print("tribal ");
488 if (isPlaneswalker)
489 out.print("planeswalker ");
490 else if (isCreature && isArtifact) {
491 out.print("artifact-creature ");
492 } else if (isArtifact)
493 out.print("artifact ");
494 else if (isCreature)
495 out.print("creature ");
496 if (isNonBasicLand) {
497 out.print("land ");
498 } else if (isAura) {
499 out.print("local-enchantment ");
500 } else if (isEnchantWorld) {
501 out.print("enchant-world ");
502 } else if (isGlobalEnchant) {
503 out.print("global-enchantment ");
504 } else if (isInstant) {
505 out.print("instant ");
506 } else if (isSorcery) {
507 out.print("sorcery ");
508 }
509 if (isSwamp) {
510 out.print("swamp ");
511 }
512 if (isIsland) {
513 out.print("island ");
514 }
515 if (isForest) {
516 out.print("forest ");
517 }
518 if (isMountain) {
519 out.print("mountain ");
520 }
521 if (isPlains) {
522 out.print("plains ");
523 }
524 out.println("</idcards>");
525
526
527 if (!properties.isEmpty()) {
528 out.print("\t\t<properties>");
529 for (String property : properties) {
530 out.print(property);
531 out.print(" ");
532 }
533 out.println("</properties>");
534 }
535 out.println("\t</init>");
536
537 if (!lineBuffer.isEmpty()) {
538 line = lineBuffer.get(0);
539 }
540 if (hasFlashBack) {
541 out.println("\t<actions>");
542 out.println("\t\t<action reference-name='main-effects'>");
543
544
545
546
547 writeActions(out, line, true, false);
548 out
549 .println("\t\t\t\t<!-- PUT HERE EFFECTS OF THIS SPELL. THIS WILL BE INCLUDED TO FLASHBACK TOO -->");
550 out.println("\t\t</action>");
551 out.println("\t</actions>");
552 }
553
554
555 out.println("\t<abilities>");
556
557 if (hasLifelink)
558 out.println("\t\t<ability ref='lifelink'/>");
559
560 if (hasDeathtouch)
561 out.println("\t\t<ability ref='deathtouch'/>");
562
563 if (hasSuspend) {
564 out.println("\t\t<ability ref='cast-suspend'>");
565 out.println("\t\t\t<actions>");
566 writeCost(out, hasSuspendLine
567 .substring(hasSuspendLine.indexOf("-") + 1), null);
568 out.println("\t\t\t</actions>");
569 out.println("\t\t\t<actions>");
570 out.println("\t\t\t\t<repeat value='" + hasSuspendLine.charAt(0)
571 + "'/>");
572 out.println("\t\t\t\t<add-object object-name='time'/>");
573 out.println("\t\t\t</actions>");
574 out.println("\t\t</ability>");
575 }
576
577 if (isAura) {
578 out.println("\t\t<ability ref='cast-enchant'/>");
579 } else if (isCreature || isGlobalEnchant || isArtifact
580 || isPlaneswalker) {
581 if (hasAffinity) {
582 out.println("\t\t<ability ref='cast-spell'>");
583 out.println("\t\t\t<actions>");
584 writeAffinity(out, hasAffinityLine);
585 out.println("\t\t\t</actions>");
586 out.println("\t\t</ability>");
587 } else {
588 out.println("\t\t<ability ref='cast-spell'/>");
589 }
590 } else if (isNonBasicLand || isForest || isPlains || isIsland
591 || isSwamp || isMountain) {
592 out.println("\t\t<ability ref='cast-land'/>");
593 }
594
595 if (hasForecast) {
596 out.println("\t\t<ability ref='reset-forecast' />");
597 out.println("\t\t<ability ref='forecast'>");
598 out.println("\t\t\t<actions>");
599 writeCost(out, hasForecastLine, null);
600 out.println("\t\t\t</actions>");
601 out.println("\t\t\t<actions>");
602 out.println("\t\t\t\t<!-- PUT HERE THE EFFECTS OF FORECAST -->");
603 out.println("\t\t\t</actions>");
604 out.println("\t\t</ability>");
605 }
606
607 if (isInstant || isSorcery) {
608 out.println("\t\t<activated-ability "
609 + (hasBuyBack || hasFlashBack ? "reference-name='main-ability' "
610 : "") + "playable='this' name='' zone='hand'>");
611 out.println("\t\t\t<cost>");
612 out.println("\t\t\t\t<pay-mana value='manacost'/>");
613 if (hasAffinity)
614 writeAffinity(out, hasAffinityLine);
615 writeXmanaCost(out, manaCost, false);
616 if (hasFlashBack) {
617 out
618 .println("\t\t\t\t<!-- PUT HERE THE COST OF THIS SPELL. THIS WILL NOT BE INCLUDED TO FLASHBACK COST -->");
619 out.println("\t\t\t</cost>");
620 out.println("\t\t\t<effects>");
621 out.println("\t\t\t\t<action ref='main-effects'/>");
622 out.println("\t\t\t\t<action ref='finish-spell'/>");
623
624 } else {
625 if (line.indexOf("at the beginning of") != -1) {
626 out.println("\t\t<create-ability>");
627 out
628 .println("\t\t\t<!-- UPDATE PHASE NAME, TYPE and RESOLUTION -->");
629 out
630 .println("\t\t\t<triggered-ability resolution='normal' zone='play'>");
631 out.println("\t\t\t\t<beginning-of-phase phase='upkeep'>");
632 out.println("\t\t\t\t\t<test ref='during-your-upkeep'/>");
633 out.println("\t\t\t\t</beginning-of-phase>");
634 out.println("\t\t\t\t<effects>");
635 writeActions(out, line, true, false);
636 out
637 .println("\t\t\t\t\t<!-- PUT HERE EFFECTS OF THIS DELAYED CARD -->");
638 out.println("\t\t\t\t\t<unregister-this/>");
639 out.println("\t\t\t\t</effects>");
640 out.println("\t\t\t</triggered-ability>");
641 out.println("\t\t</create-ability>");
642 }
643 if (line.indexOf(':') != -1) {
644 writeActions(out, line.substring(0, line.indexOf(':')), true,
645 false);
646 } else {
647 line = writeCost(out, "", line);
648 }
649 if (line.indexOf("as an additional cost to play " + lowerCard) != -1) {
650 writeActions(out, line
651 .substring(("as an additional cost to play " + lowerCard)
652 .length()), true, false);
653 line = "";
654 }
655 out.println("\t\t\t\t<!-- PUT HERE THE COST OF THIS SPELL -->");
656 out.println("\t\t\t</cost>");
657 out.println("\t\t\t<effects>");
658 for (String subLine : lineBuffer) {
659 writeActions(out, subLine, false, false);
660 }
661 out.println("\t\t\t\t<!-- PUT HERE EFFECTS OF THIS SPELL -->");
662 out.println("\t\t\t\t<action ref='finish-spell'/>");
663 }
664 out.println("\t\t\t</effects>");
665 out.println("\t\t</activated-ability>");
666 }
667
668
669 if (hasRampage) {
670 out.println("\t\t<ability ref='rampage" + hasRampageCount + "'/>");
671 }
672
673
674 if (hasTransmute) {
675 out.println("\t\t<ability ref='transmute'>");
676 out.println("\t\t\t<actions>");
677 writeCost(out, hasTransmuteCost, null);
678 out.println("\t\t\t</actions>");
679 out.println("\t\t</ability>");
680 }
681
682
683 if (hasDredge) {
684 out.println("\t\t<ability ref='dredge" + hasDredgeCount + "'/>");
685 }
686
687
688 if (hasHaunt) {
689 out.println("\t\t<ability ref='haunting'/>");
690 }
691
692
693 if (hasBloodThirst) {
694 out.println("\t\t<ability ref='bloodthirst" + hasBloodThirstCount
695 + "'/>");
696 }
697
698
699 if (hasBushido) {
700 out.println("\t\t<ability ref='bushido" + hasBushidoCount
701 + "-blocked'/>");
702 out.println("\t\t<ability ref='bushido" + hasBushidoCount
703 + "-blocking'/>");
704 }
705
706
707 if (hasBuyBack) {
708 line = hasBuyBackLine;
709 out
710 .println("\t\t<activated-ability playable='this' name='buyback%a' zone='hand'>");
711 out.println("\t\t\t<cost>");
712 out.println("\t\t\t\t<action ref='buyback'/>");
713 writeCost(out, line, null);
714 out
715 .println("\t\t\t\t<!-- PUT HERE THE COST OF BUYBACK, AND COMPLETE THE MAIN ABILITY OF THE SPELL -->");
716 out.println("\t\t\t\t<insert-ability ref='main-ability'/>");
717 out.println("\t\t\t</cost>");
718 out.println("\t\t</activated-ability>");
719 }
720
721
722 if (hasFlashBack) {
723 line = hasFlashBackLine;
724 out
725 .println("\t\t<activated-ability playable='this' name='flashback%a' zone='graveyard'>");
726 out.println("\t\t\t<cost>");
727 writeCost(out, line, null);
728 out
729 .println("\t\t\t\t<!-- PUT HERE THE COST OF FLASHBACK, AND COMPLETE THE MAIN ABILITY OF THE SPELL -->");
730 out.println("\t\t\t</cost>");
731 out.println("\t\t\t<effects>");
732 out.println("\t\t\t\t<action ref='main-effects'/>");
733 out.println("\t\t\t\t<action ref='flashback'/>");
734 out.println("\t\t\t</effects>");
735 out.println("\t\t</activated-ability>");
736 }
737
738
739 if (hasFlanking) {
740 out.println("\t\t<ability ref='flanking'/>");
741 }
742
743
744 if (hasHaunting) {
745 out.println("\t\t<ability ref='haunting'/>");
746 }
747
748
749 if (hasFading) {
750 out.println("\t\t<ability ref='fading'/>");
751 }
752
753
754 if (hasVanishing) {
755 out.println("\t\t<ability ref='vanishing'/>");
756 }
757
758 for (int k = 0; k < lineBuffer.size(); k++) {
759 line = lineBuffer.get(k);
760
761
762 if (line.contains("equipped creature gets"))
763 equipLine = line.substring(line.indexOf("gets ") + "gets ".length()
764 + 1);
765
766 if (line.indexOf("equip ") != -1 && isEquipment) {
767
768 out.println("\t\t<activated-ability playable='this' zone='play'>");
769 out.println("\t\t\t<cost>");
770 writeCost(out, line.substring("equip".length()), null);
771 out.println("\t\t\t\t<action ref='target-equipable-creature' />");
772 out.println("\t\t\t</cost>");
773 out.println("\t\t\t<effects>");
774 out.println("\t\t\t\t<action ref='equip' />");
775 out.println("\t\t\t</effects>");
776 out.println("\t\t</activated-ability>");
777 }
778
779
780 boolean hasMorph = false;
781
782 if (line.indexOf("morph") == 0) {
783 hasMorph = true;
784 out.println("\t\t<ability ref='cast-morph'/>");
785 out.println("\t\t<ability ref='morph'>");
786 out.println("\t\t\t<actions>");
787 writeCost(out, line.substring("morph".length()), null);
788 out.println("\t\t\t</actions>");
789 out.println("\t\t</ability>");
790 }
791
792 if (line.indexOf(lowerCard + " comes into play tapped") != -1) {
793 out.println("\t\t<ability ref='come-into-play-tapped'/>");
794 }
795
796 if (!isInstant && !isSorcery && line.length() > 0
797 && line.indexOf(':') != -1) {
798
799 out
800 .println("\t\t<activated-ability playable='instant' name='' zone='play'>");
801
802
803 if (hasMorph) {
804 out.println("\t\t\t<test>");
805 out.println("\t\t\t\t<is-faceup card=\"me\"/>");
806 out.println("\t\t\t</test>");
807 }
808
809
810 out.println("\t\t\t<cost>");
811 out.println("\t\t\t\t<!-- PUT HERE THE COST OF THIS ABILITY -->");
812 writeCost(out, line.substring(0, line.indexOf(':')), line
813 .substring(line.indexOf(':') + 1));
814 writeActions(out, line.substring(0, line.indexOf(':')), true, true);
815 if (line.contains("play this ability only once each turn"))
816 out.println("\t\t\t\t<action ref='use-once-each-turn'/>");
817 out.println("\t\t\t</cost>");
818
819
820 out.println("\t\t\t<effects>");
821 out.println("\t\t\t\t<!-- PUT HERE EFFECTS OF THIS ABILITY -->");
822 if (line.indexOf(":") != -1) {
823 writeActions(out, line.substring(line.indexOf(':') + 1), false,
824 false);
825 } else {
826 writeActions(out, line, false, false);
827 }
828 out.println("\t\t\t</effects>");
829 out.println("\t\t</activated-ability>");
830 }
831
832 if (line.indexOf("when") != -1 || line.indexOf("whenever") != -1) {
833 if (line.indexOf("comes into play") != -1) {
834 out.println("\t\t<triggered-ability zone='play'>");
835 out.println("\t\t\t<moved-card>");
836 out.println("\t\t\t\t<source-test>");
837 if (line.indexOf("when " + lowerCard + " comes into play") != -1) {
838 out.println("\t\t\t\t\t<and>");
839 out.println("\t\t\t\t\t\t<is-this/>");
840 out.println("\t\t\t\t\t\t<not>");
841 out
842 .println("\t\t\t\t\t\t\t<in-zone zone='play' card='tested'/>");
843 out.println("\t\t\t\t\t\t</not>");
844 out
845 .println("\t\t\t\t\t\t<!-- PUT HERE ADDITIONAL TEST ON CARD BEFORE IT GOES TO PLAY -->");
846 out.println("\t\t\t\t\t</and>");
847 } else {
848 out
849 .println("\t\t\t\t<!-- PUT HERE ADDITIONAL TEST ON CARD BEFORE IT GOES TO PLAY -->");
850 }
851 out.println("\t\t\t\t</source-test>");
852 out.println("\t\t\t\t<destination-test>");
853 out
854 .println("\t\t\t\t\t<!-- PUT HERE ADDITIONAL TEST ON CARD WHEN IT GOES TO PLAY -->");
855 out.println("\t\t\t\t\t<in-zone zone='play' card='tested'/>");
856 out.println("\t\t\t\t</destination-test>");
857 out.println("\t\t\t</moved-card>");
858 } else if (line.indexOf(" is put into ") < line
859 .indexOf("graveyard from ")) {
860 out.println("\t\t<triggered-ability zone='graveyard'>");
861 out.println("\t\t\t<moved-card>");
862 out.println("\t\t\t\t<source-test>");
863 out
864 .println("\t\t\t\t\t<!-- UPDATE TEST ON CARD BEFORE IT GOES TO GRAVEYARD -->");
865 out.println("\t\t\t\t\t<and>");
866 out.println("\t\t\t\t\t\t<is-this/>");
867 out.println("\t\t\t\t\t\t<in-zone zone='play' card='tested'/>");
868 out.println("\t\t\t\t\t</and>");
869 out.println("\t\t\t\t</source-test>");
870 out.println("\t\t\t\t<destination-test>");
871 out
872 .println("\t\t\t\t\t<!-- PUT HERE ADDITIONAL TEST ON CARD WHEN IT GOES TO GRAVEYARD -->");
873 out
874 .println("\t\t\t\t\t<in-zone zone='graveyard' card='tested'/>");
875 out.println("\t\t\t\t</destination-test>");
876 out.println("\t\t\t</moved-card>");
877 } else if (line.indexOf(" leaves play") != -1) {
878 out.println("\t\t<triggered-ability zone='graveyard'>");
879 out.println("\t\t\t<moved-card>");
880 out.println("\t\t\t\t<source-test>");
881 out
882 .println("\t\t\t\t\t<!-- COMPLETE TEST ON CARD BEFORE IT LEAVE PLAY -->");
883 out.println("\t\t\t\t\t\t\t<in-zone zone='play' card='tested'/>");
884 out.println("\t\t\t\t</source-test>");
885 out.println("\t\t\t</moved-card>");
886 } else if (line.indexOf("blocks") != -1
887 || line.indexOf("becomes blocked") != -1) {
888 out.println("\t\t<triggered-ability zone='play'>");
889 out.println("\t\t\t<declared-blocking>");
890 out.println("\t\t\t\t<blocking-test>");
891 out
892 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON BLOCKING CREATURE -->");
893 out.println("\t\t\t\t</blocking-test>");
894 out.println("\t\t\t\t<attacking-test>");
895 out
896 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON ATTACKING CREATURE -->");
897 out.println("\t\t\t\t</attacking-test>");
898 out.println("\t\t\t</declared-blocking>");
899 } else if (line.indexOf("attacks and isn't blocked") != -1) {
900 out.println("\t\t<triggered-ability zone='play'>");
901 out
902 .println("\t\t\t<modified-register operation='or' register='card' index='state'>");
903 out.println("\t\t\t\t<source-test>");
904 out
905 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON UNBLOCKED CREATURE -->");
906 out.println("\t\t\t\t\t<is-this/>");
907 out.println("\t\t\t\t</source-test>");
908 out.println("\t\t\t</modified-register>");
909 } else if (line.indexOf("deals combat damage to a player") != -1) {
910 out.println("\t\t<triggered-ability zone='play'>");
911 out.println("\t\t\t<assigned-damage type='damage-combat'>");
912 out.println("\t\t\t\t<source-test>");
913 out.println("\t\t\t\t\t<is-this/>");
914 out.println("\t\t\t\t</source-test>");
915 out.println("\t\t\t\t<destination-test>");
916 out.println("\t\t\t\t\t<is-player/>");
917 out.println("\t\t\t\t</destination-test>");
918 out.println("\t\t\t</assigned-damage>");
919 } else if (line.indexOf("deals damage to") != -1) {
920 out.println("\t\t<triggered-ability zone='play'>");
921 out.println("\t\t\t<assigned-damage type='damage-any'>");
922 out.println("\t\t\t\t<source-test>");
923 out.println("\t\t\t\t\t<is-this/>");
924 out.println("\t\t\t\t</source-test>");
925 out.println("\t\t\t\t<destination-test>");
926 out.println("\t\t\t\t\t<and>");
927 out.println("\t\t\t\t\t\t<not>");
928 out.println("\t\t\t\t\t\t<is-player/>");
929 out.println("\t\t\t\t\t\t</not>");
930 out.println("\t\t\t\t\t\t<has-idcard idcard='creature'/>");
931 out.println("\t\t\t\t\t</and>");
932 out.println("\t\t\t\t</destination-test>");
933 out.println("\t\t\t</assigned-damage>");
934 } else if (line.indexOf("deals combat damage to") != -1) {
935 out.println("\t\t<triggered-ability zone='play'>");
936 out.println("\t\t\t<assigned-damage type='damage-combat'>");
937 out.println("\t\t\t\t<source-test>");
938 out.println("\t\t\t\t\t<is-this/>");
939 out.println("\t\t\t\t</source-test>");
940 out.println("\t\t\t\t<destination-test>");
941 out.println("\t\t\t\t\t<and>");
942 out.println("\t\t\t\t\t\t<not>");
943 out.println("\t\t\t\t\t\t\t<is-player/>");
944 out.println("\t\t\t\t\t\t</not>");
945 out.println("\t\t\t\t\t\t<has-idcard idcard='creature'/>");
946 out.println("\t\t\t\t\t</and>");
947 out.println("\t\t\t\t</destination-test>");
948 out.println("\t\t\t</assigned-damage>");
949 } else if (line.indexOf("deals damage to a player") != -1) {
950 out.println("\t\t<triggered-ability zone='play'>");
951 out.println("\t\t\t<assigned-damage type='damage-any'>");
952 out.println("\t\t\t\t<source-test>");
953 out.println("\t\t\t\t\t<is-this/>");
954 out.println("\t\t\t\t</source-test>");
955 out.println("\t\t\t\t<destination-test>");
956 out.println("\t\t\t\t\t<is-player/>");
957 out.println("\t\t\t\t</destination-test>");
958 out.println("\t\t\t</assigned-damage>");
959 } else if (line.indexOf("becomes untapped") != -1) {
960 out.println("\t\t<triggered-ability zone='play'>");
961 out.println("\t\t\t<become-untapped>");
962 out.println("\t\t\t\t<test>");
963 out
964 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON UNTAPPING CARD -->");
965 out.println("\t\t\t\t\t<is-this card='tested'/>");
966 out.println("\t\t\t\t</test>");
967 out.println("\t\t\t</become-untapped>");
968 } else if (line.indexOf("becomes tapped") != -1) {
969 out.println("\t\t<triggered-ability zone='play'>");
970 out.println("\t\t\t<become-tapped>");
971 out.println("\t\t\t\t<test>");
972 out
973 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON TAPPING CARD -->");
974 out.println("\t\t\t\t\t<is-this card='tested'/>");
975 out.println("\t\t\t\t</test>");
976 out.println("\t\t\t</become-tapped>");
977 } else if (line.indexOf("attacks") != -1) {
978 out.println("\t\t<triggered-ability zone='play'>");
979 out.println("\t\t\t<declared-blocking>");
980 out.println("\t\t\t\t<blocking-test>");
981 out.println("\t\t\t\t\t<is-this/>");
982 out
983 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON BLOCKING CREATURE -->");
984 out.println("\t\t\t\t</blocking-test>");
985 out.println("\t\t\t\t<attacking-test>");
986 out
987 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON ATTACKING CREATURE -->");
988 out.println("\t\t\t\t</attacking-test>");
989 out.println("\t\t\t</declared-blocking>");
990 } else if (line.indexOf("is turned face up") != -1) {
991 out.println("\t\t<triggered-ability zone='play'>");
992 out.println("\t\t\t<faced-up>");
993 out.println("\t\t\t\t<test>");
994 out.println("\t\t\t\t<!-- UPDATE TEST ON FACED UP CARD -->");
995 out.println("\t\t\t\t\t<is-this />");
996 out.println("\t\t\t\t</test>");
997 out.println("\t\t\t</faced-up>");
998 } else {
999 out.println("\t\t<triggered-ability zone='play'>");
1000 out
1001 .println("\t\t\t\t\t<!-- UPDATE THE EVENT OF THIS TRIGGERED ABILITY -->");
1002 out.println("\t\t\t<become-tapped>");
1003 out.println("\t\t\t\t<test>");
1004 out
1005 .println("\t\t\t\t\t<!-- COMPLETE THE TEST APPLIED ON TAPPING CARD -->");
1006 out.println("\t\t\t\t\t<is-this card='tested'/>");
1007 out.println("\t\t\t\t</test>");
1008 out.println("\t\t\t</become-tapped>");
1009 }
1010 if (line.contains("target")) {
1011 out.println("\t\t\t<cost>");
1012 writeTarget(out, line, true);
1013 out.println("\t\t\t</cost>");
1014 }
1015 out.println("\t\t\t<effects>");
1016 writeActions(out, line, false, false);
1017 out
1018 .println("\t\t\t\t<!-- PUT HERE EFFECTS OF THIS TRIGGERED ABILITY -->");
1019 out.println("\t\t\t</effects>");
1020 out.println("\t\t</triggered-ability>");
1021 } else if (line.indexOf("cycling") != -1) {
1022
1023 out.println("\t\t<ability ref='cycling'>");
1024 out.println("\t\t\t<actions>");
1025 writeCost(out, line.substring(
1026 line.indexOf("cycling") + "cycling".length()).trim(), null);
1027 out.println("\t\t\t</actions>");
1028 out.println("\t\t</ability>");
1029 } else if (line.indexOf("evoke") != -1) {
1030
1031 out.println("\t\t<ability ref='evoke"
1032 + (properties.contains("flash") ? "-flash" : "") + "'>");
1033 out.println("\t\t\t<actions>");
1034 writeCost(out, line.substring(
1035 line.indexOf("evoke") + "evoke".length()).trim(), null);
1036 out.println("\t\t\t</actions>");
1037 out.println("\t\t</ability>");
1038 } else if (line.indexOf("madness") != -1) {
1039
1040 out.println("\t\t<ability ref='madness'>");
1041 out.println("\t\t\t<actions>");
1042 writeCost(out, line.substring(
1043 line.indexOf("madness") + "madness".length()).trim(), null);
1044 out.println("\t\t\t</actions>");
1045 out.println("\t\t</ability>");
1046 } else if (line.indexOf("soulshift") != -1) {
1047
1048 out.println("\t\t<ability ref='"
1049 + line.substring(line.indexOf("soulshift")).trim().replace(" ",
1050 "") + "'/>");
1051 } else if (line.indexOf("echo") != -1) {
1052
1053 out.println("\t\t<ability ref='echo'>");
1054 out.println("\t\t\t<actions>");
1055 writeCost(out, line.substring(
1056 line.indexOf("echo") + "echo".length()).trim(), null);
1057 out.println("\t\t\t</actions>");
1058 out.println("\t\t</ability>");
1059 } else if (line.indexOf("at the beginning of") != -1) {
1060
1061 if (!isInstant && !isSorcery) {
1062
1063 out
1064 .println("\t\t\t<!-- UPDATE PHASE NAME, TYPE and RESOLUTION -->");
1065 out
1066 .println("\t\t<triggered-ability resolution='normal' zone='play'>");
1067 out.println("\t\t\t<beginning-of-phase phase='upkeep'>");
1068 out.println("\t\t\t\t<test ref='during-your-upkeep'/>");
1069 out.println("\t\t\t</beginning-of-phase>");
1070 if (line.indexOf("unless") != -1) {
1071 out.println("\t\t\t<cost>");
1072 out.println("\t\t\t\t<choice cancel='false'>");
1073 out.println("\t\t\t\t\t<either>");
1074 out.println("\t\t\t\t\t\t<pay-mana colorless='1'/>");
1075 out.println("\t\t\t\t\t</either>");
1076 out.println("\t\t\t\t\t<either>");
1077 out.println("\t\t\t\t\t\t<action ref='sacrifice-this'/>");
1078 out.println("\t\t\t\t\t</either>");
1079 out.println("\t\t\t\t</choice>");
1080 out.println("\t\t\t</cost>");
1081 } else {
1082 out.println("\t\t\t<effects>");
1083 writeActions(out, line, false, false);
1084 out
1085 .println("\t\t\t\t<!-- PUT HERE EFFECTS OF THIS TRIGGERED ABILITY -->");
1086 out.println("\t\t\t</effects>");
1087 }
1088 out.println("\t\t</triggered-ability>");
1089 }
1090 } else if (line.indexOf("cumulative upkeep") != -1) {
1091
1092 out.println("\t\t<ability ref='cumulative-upkeep'/>");
1093 out
1094 .println("\t\t<triggered-ability resolution='normal' zone='play' name='cumulative-upkeep'>");
1095 out.println("\t\t\t<beginning-of-phase phase='upkeep'>");
1096 out.println("\t\t\t\t<test ref='during-your-upkeep'/>");
1097 out.println("\t\t\t</beginning-of-phase>");
1098 out.println("\t\t\t<cost>");
1099 out.println("\t\t\t\t<choice cancel='false'>");
1100 out.println("\t\t\t\t\t<either>");
1101 out.println("\t\t\t\t\t\t<!-- PUT HERE THE ACTION(S) TO PAY -->");
1102 out.println("\t\t\t\t\t\t<action ref='pay-life'>");
1103 out.println("\t\t\t\t\t\t\t<value>");
1104 out
1105 .println("\t\t\t\t\t\t\t\t<counter object-name='age' card='this'/>");
1106 out.println("\t\t\t\t\t\t\t</value>");
1107 out.println("\t\t\t\t\t\t</action>");
1108 out.println("\t\t\t\t\t</either>");
1109 out.println("\t\t\t\t\t<either>");
1110 out.println("\t\t\t\t\t\t<action ref='sacrifice-this'/>");
1111 out.println("\t\t\t\t\t</either>");
1112 out.println("\t\t\t\t</choice>");
1113 out.println("\t\t\t</cost>");
1114 out.println("\t\t</triggered-ability>");
1115 }
1116 }
1117 out.println("\t</abilities>");
1118
1119
1120 if (hasFading || hasVanishing || hasLessToPlay || hasMoreToPlay) {
1121 out.println("\t<modifiers>");
1122
1123 if (hasMoreToPlay) {
1124 out.println("\t\t<additional-cost-modifier linked='true'>");
1125 out.println("\t\t\t<test>");
1126 out.println("\t\t<!-- Complete the additional cost test -->");
1127 out.println("\t\t\t</test>");
1128 out.println("\t\t\t<cost>");
1129 out.println("\t\t<!-- Update the additional cost amount -->");
1130 out.println("\t\t\t\t<pay-mana colorless='1' />");
1131 out.println("\t\t\t</cost>");
1132 out.println("\t\t</additional-cost-modifier>");
1133 }
1134
1135 if (hasLessToPlay) {
1136 out.println("\t\t<additional-cost-modifier linked='true'>");
1137 out.println("\t\t\t<test>");
1138 out.println("\t\t<!-- Complete the cost reduction test -->");
1139 out.println("\t\t\t</test>");
1140 out.println("\t\t\t<cost>");
1141 out.println("\t\t<!-- Update the cost reduction amount -->");
1142 out.println("\t\t\t\t<pay-mana colorless='-1' />");
1143 out.println("\t\t\t</cost>");
1144 out.println("\t\t</additional-cost-modifier>");
1145 }
1146
1147 if (hasFading) {
1148 int fadingCounter = Integer.parseInt(hasFadingLine);
1149 if (fadingCounter == Integer.MIN_VALUE) {
1150 fadingCounter = 1;
1151 }
1152 for (int i = fadingCounter; i-- > 0;) {
1153 out.println("\t\t<object name='fade'/>");
1154 }
1155 }
1156 if (hasVanishing) {
1157 int vanishingCounter;
1158 if (hasVanishingLine.length() != 0)
1159 vanishingCounter = Integer.parseInt(hasVanishingLine);
1160 else {
1161 vanishingCounter = 1;
1162 out.println("\t\t<!-- NEEDS CODE FOR NUMBER OF COUNTERS -->");
1163 }
1164 if (vanishingCounter == Integer.MIN_VALUE) {
1165 vanishingCounter = 1;
1166 }
1167 for (int i = vanishingCounter; i-- > 0;) {
1168 out.println("\t\t<object name='time'/>");
1169 }
1170 }
1171 out.println("\t</modifiers>");
1172 }
1173
1174
1175
1176 if (isEquipment) {
1177 String pow = new String();
1178 String tou = new String();
1179 if (equipLine.length() > 0) {
1180 pow = equipLine.substring(0, equipLine.indexOf("/"));
1181 tou = equipLine.substring(equipLine.indexOf("/") + 2, equipLine
1182 .indexOf("/") + 3);
1183 } else {
1184 out.println("\t<!-- WRITE THE EQUIPMENT MODIFIERS -->");
1185 }
1186
1187 out.println("\t<attachment>");
1188 out.println("\t\t<modifiers>");
1189 if (!pow.contains("0"))
1190 out
1191 .println("\t\t\t<register-modifier index='power' operation='add' linked='true' value='"
1192 + pow + "' />");
1193 if (!tou.contains("0"))
1194 out
1195 .println("\t\t\t<register-modifier index='toughness' operation='add' linked='true' value='"
1196 + tou + "' />");
1197 out.println("\t\t</modifiers>");
1198 out.println("\t\t<valid-target ref='valid-creature-to-equip' />");
1199 out.println("\t\t<valid-attachment ref='valid-equip-creature' />");
1200 out.println("\t</attachment>");
1201 }
1202 if (isAura) {
1203 out.print("\t<attachment");
1204
1205 if (isLocalEnchantCreature) {
1206 if (line.indexOf("you control enchanted creature") != -1) {
1207 out.println(" ref='control'/>");
1208 out.println("\t<!-- Add the additional modifiers here-->");
1209 } else if (line.startsWith("enchanted creature gets")
1210 || line.indexOf("enchanted creature has") != -1) {
1211 if (line.indexOf("gets") != -1) {
1212 String temp = line.substring(line.indexOf("gets")).split(" ")[1]
1213 .replaceFirst("[.,]", "");
1214 out.print(" ref='" + temp);
1215 if (temp.indexOf("x") != -1) {
1216 out
1217 .println("\t<!-- UPDATE X VALUE IN MODIFIERS, SEE CARD: Blanchwood Armor-->");
1218 }
1219 }
1220 if (line.indexOf("has") != -1) {
1221 String property = line.substring(line.indexOf("has"))
1222 .split(" ")[1].replaceFirst("[.,]", "");
1223 if (line.indexOf("gets") != -1) {
1224 out.println("'>");
1225 out.println("\t\t<modifiers>");
1226 out
1227 .println("\t\t\t<!-- UPDATE THE MODIFIER TYPE AND THE LINKED ATTRIBUTE -->");
1228 out.println("\t\t\t<property-modifier property='" + property
1229 + "' linked='true'/>");
1230 out.println("\t\t</modifiers>");
1231 out.println("\t</attachment>");
1232 } else {
1233 out.println(" ref='" + property + "'/>");
1234 }
1235
1236 } else
1237 out.println("'/>");
1238 } else {
1239 out.println(" ref='enchant-creature'/>");
1240 }
1241 } else if (isLocalEnchantLand) {
1242 out.println(" ref='enchant-land'/>");
1243
1244 } else if (isLocalEnchantArtifact) {
1245 out.println(" ref='enchant-artifact'/>");
1246
1247 } else if (isLocalEnchantEnchantment) {
1248 out
1249 .println("\t\t<valid-target ref='valid-enchantment-to-enchant' />");
1250 out
1251 .println("\t\t<valid-attachment ref='valid-enchant-enchantment' />");
1252
1253 } else if (isLocalEnchantCreatureArtifact) {
1254 out.println(" ref='enchant-artifact-creature'/>");
1255
1256 } else if (isLocalEnchantPermanent) {
1257 out.println(" ref='enchant'/>");
1258 }
1259 }
1260 out.println("</card>");
1261 IOUtils.closeQuietly(out);
1262 nbCard++;
1263 }
1264 } catch (FileNotFoundException e) {
1265 System.err.println("Error openning file '" + oracleFile + "' : " + e);
1266 } catch (IOException e) {
1267 System.err.println("IOError reading file '" + oracleFile + "' : " + e);
1268 }
1269 System.out.println("Success Parsing : " + nbCard + " card(s)");
1270 }
1271
1272 /***
1273 * <ul>
1274 * Argument are (in this order :
1275 * <li>Oracle source file
1276 * <li>destination directory
1277 * </ul>
1278 *
1279 * @param args
1280 */
1281 public static void main(String... args) {
1282 options = new Options();
1283 final CmdLineParser parser = new CmdLineParser(options);
1284 try {
1285 parser.parseArgument(args);
1286 } catch (CmdLineException e) {
1287
1288 if (!options.isHelp()) {
1289 System.out.println("Wrong parameters : " + e.getMessage());
1290 } else {
1291 System.out.println("Usage");
1292 }
1293 parser.setUsageWidth(100);
1294 parser.printUsage(System.out);
1295 System.exit(-1);
1296 return;
1297 }
1298
1299 if (options.isVersion()) {
1300
1301 System.out.println("Version is " + IdConst.VERSION);
1302 System.exit(-1);
1303 return;
1304 }
1305
1306 if (options.isHelp()) {
1307
1308 System.out.println("Usage");
1309 parser.setUsageWidth(100);
1310 parser.printUsage(System.out);
1311 System.exit(-1);
1312 return;
1313 }
1314
1315
1316 final String oracle = options.getOracleFile();
1317
1318
1319 String destination = FilenameUtils.separatorsToWindows(options
1320 .getDestination());
1321 if (!destination.endsWith("/")) {
1322 destination += "/";
1323 }
1324
1325
1326 try {
1327 new File(destination).mkdirs();
1328 } catch (Exception e) {
1329
1330 }
1331 new Oracle2Xml().serialize(MToolKit.getFile(oracle), MToolKit
1332 .getFile(destination), MToolKit.getFile("tbs/" + TBS_NAME
1333 + "/recycled/"));
1334 }
1335
1336 /***
1337 * Write X expression for pay-mana action
1338 *
1339 * @param out
1340 * the output were the pay-mana would be written.
1341 * @param manaCost
1342 * the mana cost.
1343 * @param writeFixPart
1344 * is the fixed part of mana cost is written or not.
1345 * @see net.sf.firemox.xml.action.PayMana
1346 */
1347 private void writeXmanaCost(PrintWriter out, int[] manaCost,
1348 boolean writeFixPart) {
1349
1350
1351 if (writeFixPart) {
1352 out.print("\t\t\t\t<pay-mana ");
1353 for (int i = 6; i-- > 0;) {
1354 if (manaCost[i] > 0) {
1355 out.print(extractColor(i) + "='" + manaCost[i] + "' ");
1356 }
1357 }
1358 out.println("/>");
1359 }
1360
1361
1362 if (manaCost[6] > 0) {
1363 out
1364 .println("\t\t\t\t<!-- UPDATE THE TEXT AND AMOUNT OF MIN/MAXI COLORLESS MANA TO PAY -->");
1365 out
1366 .println("\t\t\t\t<input-number min='0' controller='you' operation='set' register='stack' index='0' name='%'>");
1367 out.println("\t\t\t\t\t<text>%x-value</text>");
1368 if (manaCost[6] > 1) {
1369 out.println("\t\t\t\t\t<max register='you' index='manapool'/>");
1370 } else {
1371
1372 out.println("\t\t\t\t\t<max>");
1373 out.println("\t\t\t\t\t\t<div right='" + manaCost[6] + "'>");
1374 out.println("\t\t\t\t\t\t\t<left register='you' index='manapool'>");
1375 out.println("\t\t\t\t\t\t</div>");
1376 out.println("\t\t\t\t\t</max>");
1377 }
1378 out.println("\t\t\t\t</input-number>");
1379 out.println("\t\t\t\t<pay-mana>");
1380 out.println("\t\t\t\t\t<colorless register='stack' index='0'/>");
1381 out.println("\t\t\t\t</pay-mana>");
1382 }
1383 }
1384
1385 /***
1386 * Write X expression for give-mana action
1387 *
1388 * @param out
1389 * the output were the pay-mana would be written.