1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.firemox.xml.tbs;
20
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.Stack;
32
33 import net.sf.firemox.modifier.ModifierType;
34 import net.sf.firemox.operation.IdOperation;
35 import net.sf.firemox.token.IdPropertyType;
36 import net.sf.firemox.token.IdTokens;
37 import net.sf.firemox.token.IdZones;
38 import net.sf.firemox.tools.MToolKit;
39 import net.sf.firemox.tools.PairStringInt;
40 import net.sf.firemox.ui.component.CardPropertiesPanel;
41 import net.sf.firemox.xml.XmlAction;
42 import net.sf.firemox.xml.XmlConfiguration;
43 import net.sf.firemox.xml.XmlModifier;
44 import net.sf.firemox.xml.XmlParser;
45 import net.sf.firemox.xml.XmlTbs;
46 import net.sf.firemox.xml.XmlTest;
47 import net.sf.firemox.xml.XmlToMDB;
48 import net.sf.firemox.xml.XmlTools;
49 import net.sf.firemox.xml.XmlParser.Node;
50
51 import org.apache.commons.io.FilenameUtils;
52
53 /***
54 * This class represents an implementation of the XmlToMDB interface that
55 * converts a XML tbs node to its binary form to the given OutputSource.
56 *
57 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan</a>
58 * @since 0.82
59 * @since 0.83 damage types are exported
60 */
61 public class Tbs implements XmlToMDB {
62
63 /***
64 * Converts the given tbs XML node to its binary form writing in the given
65 * OutputStream.
66 *
67 * @see net.sf.firemox.token.IdTokens#PLAYER_REGISTER_SIZE
68 * @see net.sf.firemox.stack.phasetype.PhaseType
69 * @see net.sf.firemox.clickable.ability.SystemAbility
70 * @see net.sf.firemox.tools.StatePicture
71 * @param node
72 * the XML card structure
73 * @param out
74 * output stream where the card structure will be saved
75 * @return the amount of written action in the output.
76 * @throws IOException
77 * error during the writing.
78 * @see net.sf.firemox.deckbuilder.MdbLoader#loadMDB(String, int)
79 */
80 public final int buildMdb(Node node, OutputStream out) throws IOException {
81 final FileOutputStream fileOut = (FileOutputStream) out;
82 referencedTest = new HashMap<String, Node>();
83 referencedAbilities = new HashMap<String, Node>();
84 referencedActions = new HashMap<String, List<Node>>();
85 referencedAttachments = new HashMap<String, Node>();
86 referencedNonMacroActions = new HashSet<String>();
87 referencedNonMacroAttachments = new HashSet<String>();
88 macroActions = new Stack<List<Node>>();
89 resolveReferences = false;
90
91 MToolKit.writeString(out, node.getAttribute("name"));
92 System.out.println("Building " + node.getAttribute("name") + " rules...");
93 MToolKit.writeString(out, node.getAttribute("version"));
94 MToolKit.writeString(out, node.getAttribute("author"));
95 MToolKit.writeString(out, node.getAttribute("comment"));
96
97
98 final Node database = node.get("database-properties");
99 Map<String, IdPropertyType> properties = new HashMap<String, IdPropertyType>();
100 for (java.lang.Object obj : database) {
101 if (obj instanceof Node) {
102 Node nodePriv = (Node) obj;
103 String propertyType = nodePriv.getAttribute("type");
104 IdPropertyType propertyId;
105 if (propertyType == null || propertyType.equals(String.class.getName())) {
106 if ("true".equalsIgnoreCase(nodePriv.getAttribute("translate"))) {
107 propertyId = IdPropertyType.SIMPLE_TRANSLATABLE_PROPERTY;
108 } else {
109 propertyId = IdPropertyType.SIMPLE_PROPERTY;
110 }
111 } else if ("java.util.List".equals(propertyType)) {
112 if ("true".equalsIgnoreCase(nodePriv.getAttribute("translate"))) {
113 propertyId = IdPropertyType.COLLECTION_TRANSLATABLE_PROPERTY;
114 } else {
115 propertyId = IdPropertyType.COLLECTION_PROPERTY;
116 }
117 } else {
118 throw new InternalError("Unknow property type '" + propertyType + "'");
119 }
120 properties.put(nodePriv.getAttribute("name"), propertyId);
121 }
122 }
123 out.write(properties.size());
124 for (Map.Entry<String, IdPropertyType> entry : properties.entrySet()) {
125 entry.getValue().serialize(out);
126 MToolKit.writeString(out, entry.getKey());
127 }
128
129 MToolKit.writeString(out, node.getAttribute("art-url"));
130 MToolKit.writeString(out, node.getAttribute("back-picture"));
131 MToolKit.writeString(out, node.getAttribute("damage-picture"));
132 MToolKit.writeString(out, (String) node.get("licence").get(0));
133
134
135 final Node manas = node.get("mana-symbols");
136
137
138 final Node colored = manas.get("colored");
139 MToolKit.writeString(out, colored.getAttribute("url"));
140 MToolKit.writeString(out, colored.getAttribute("big-url"));
141 for (java.lang.Object obj : colored) {
142 if (obj instanceof Node) {
143 Node nodePriv = (Node) obj;
144 out.write(XmlTools.getValue(nodePriv.getAttribute("name")));
145 MToolKit.writeString(out, nodePriv.getAttribute("picture"));
146 MToolKit.writeString(out, nodePriv.getAttribute("big-picture"));
147 }
148 }
149
150
151 final Node colorless = manas.get("colorless");
152 MToolKit.writeString(out, colorless.getAttribute("url"));
153 MToolKit.writeString(out, colorless.getAttribute("big-url"));
154 MToolKit.writeString(out, colorless.getAttribute("unknown"));
155 out.write(colorless.getNbNodes());
156 for (java.lang.Object obj : colorless) {
157 if (obj instanceof Node) {
158 final Node nodePriv = (Node) obj;
159 out.write(Integer.parseInt(nodePriv.getAttribute("amount")));
160 MToolKit.writeString(out, nodePriv.getAttribute("picture"));
161 }
162 }
163
164
165 final long shortcutCardBytes = fileOut.getChannel().position();
166 MToolKit.writeInt24(out, 0);
167
168
169 final Set<String> definedConstraints = new HashSet<String>();
170 final Node deckConstraintRoot = XmlTools.getExternalizableNode(node,
171 "deck-constraints");
172 final List<Node> deckConstraints = deckConstraintRoot
173 .getNodes("deck-constraint");
174 XmlTools.writeAttrOptions(deckConstraintRoot, "deckbuilder-min-property",
175 out);
176 XmlTools.writeAttrOptions(deckConstraintRoot, "deckbuilder-max-property",
177 out);
178 XmlTools.writeAttrOptions(deckConstraintRoot, "master", out);
179 out.write(deckConstraints.size());
180 for (Node deckConstraint : deckConstraints) {
181
182 String deckName = deckConstraint.getAttribute("name");
183 MToolKit.writeString(out, deckName);
184
185
186 String extend = deckConstraint.getAttribute("extends");
187 MToolKit.writeString(out, extend);
188 if (extend != null && extend.length() > 0
189 && !definedConstraints.contains(extend)) {
190 throw new RuntimeException(
191 "'"
192 + deckName
193 + "' is supposed extending '"
194 + extend
195 + "' but has not been found. Note that declaration order is important.");
196 }
197
198
199 XmlTools.defaultOnMeTag = false;
200 XmlTest.getTest("test").buildMdb(deckConstraint, out);
201 definedConstraints.add(deckName);
202 }
203
204
205
206 final List<XmlParser.Node> additionalZones = node.get("layouts").get(
207 "zones").get("additional-zones").getNodes("additional-zone");
208 out.write(additionalZones.size());
209 int zoneId = IdZones.FIRST_ADDITIONAL_ZONE;
210 for (XmlParser.Node additionalZone : additionalZones) {
211 final String zoneName = additionalZone.getAttribute("name");
212 if (zoneId > IdZones.LAST_ADDITIONAL_ZONE) {
213 throw new RuntimeException("Cannot add more additional-zone ("
214 + zoneName + "), increase core limitation");
215 }
216 XmlTools.zones.put(zoneName, zoneId++);
217 MToolKit.writeString(out, zoneName);
218 MToolKit.writeString(out, additionalZone.getAttribute("layout-class"));
219 MToolKit.writeString(out, additionalZone.getAttribute("constraint-you"));
220 MToolKit.writeString(out, additionalZone
221 .getAttribute("constraint-opponent"));
222 }
223
224
225 out.write(XmlTools.getZone(node.get("layouts").get("zones").getAttribute(
226 "default-zone")));
227
228
229 final Node references = XmlTools.getExternalizableNode(node, "references");
230
231
232 System.out.println("\tshared tests...");
233 XmlTools.defaultOnMeTag = true;
234 final Node tests = references.get("tests");
235 if (tests == null) {
236 out.write(0);
237 } else {
238 out.write(tests.getNbNodes());
239 for (java.lang.Object obj : tests) {
240 if (obj instanceof Node) {
241 String ref = ((Node) obj).getAttribute("reference-name").toString();
242 referencedTest.put(ref, (Node) obj);
243 MToolKit.writeString(out, ref);
244 for (java.lang.Object objTest : (Node) obj) {
245 if (objTest instanceof Node) {
246 final Node node1 = (Node) objTest;
247 try {
248 XmlTest.getTest(node1.getTag()).buildMdb(node1, out);
249 } catch (Throwable ie) {
250 XmlConfiguration.error("In referenced test '" + ref + "' : "
251 + ie.getMessage() + ". Context=" + objTest);
252 }
253 break;
254 }
255 }
256 }
257 }
258 }
259
260
261 final Node actions = references.get("actions");
262 System.out.print("\tactions : references (inlined in MDB)");
263 if (actions != null) {
264 for (java.lang.Object obj : actions) {
265 if (obj instanceof Node) {
266 final String ref = ((Node) obj).getAttribute("reference-name");
267 final String globalName = ((Node) obj).getAttribute("name");
268
269 if ("false".equals(((Node) obj).getAttribute("macro"))) {
270 referencedNonMacroActions.add(ref);
271 }
272 final List<Node> actionList = new ArrayList<Node>();
273 boolean firstIsDone = false;
274 for (java.lang.Object actionI : (Node) obj) {
275 if (actionI instanceof Node) {
276 final Node action = (Node) actionI;
277
278
279 if (action.getAttribute("name") == null) {
280 if (globalName != null) {
281 if (firstIsDone) {
282 action.addAttribute(new XmlParser.Attribute("name", "%"
283 + globalName));
284 } else {
285 action.addAttribute(new XmlParser.Attribute("name",
286 globalName));
287 firstIsDone = true;
288 }
289 } else if (firstIsDone) {
290 action
291 .addAttribute(new XmlParser.Attribute("name", "%" + ref));
292 } else {
293 action.addAttribute(new XmlParser.Attribute("name", ref));
294 firstIsDone = true;
295 }
296 } else if (!firstIsDone) {
297 firstIsDone = true;
298 }
299 actionList.add((Node) actionI);
300 }
301 }
302
303 referencedActions.put(ref, actionList);
304
305 }
306 }
307 }
308
309
310 final Node attachments = references.get("attachments");
311 System.out.print(", attachments");
312 if (attachments != null) {
313 for (java.lang.Object obj : attachments) {
314 if (obj instanceof Node) {
315 final String ref = ((Node) obj).getAttribute("reference-name");
316
317 if ("false".equals(((Node) obj).getAttribute("macro"))) {
318 referencedNonMacroAttachments.add(ref);
319 }
320
321 referencedAttachments.put(ref, (Node) obj);
322 }
323 }
324 }
325
326
327 final Node actionsPictures = node.get("action-pictures");
328 System.out.print(", pictures");
329 if (actionsPictures == null) {
330 out.write(0);
331 out.write('\0');
332 } else {
333 MToolKit.writeString(out, actionsPictures.getAttribute("url"));
334 out.write(actionsPictures.getNbNodes());
335 for (java.lang.Object obj : actionsPictures) {
336 if (obj instanceof Node) {
337 final Node actionPicture = (Node) obj;
338 MToolKit.writeString(out, actionPicture.getAttribute("name"));
339 MToolKit.writeString(out, actionPicture.getAttribute("picture"));
340 }
341 }
342 }
343
344
345 final Node constraints = node.get("action-constraints");
346 System.out.println(", constraints");
347 if (constraints == null) {
348 out.write(0);
349 } else {
350 out.write(constraints.getNbNodes());
351 for (java.lang.Object obj : constraints) {
352 if (obj instanceof Node) {
353 final Node constraint = (Node) obj;
354 for (java.lang.Object objA : constraint.get("actions")) {
355 if (objA instanceof Node) {
356 XmlAction.getAction(((Node) objA).getTag()).buildMdb((Node) objA,
357 out);
358 break;
359 }
360 }
361 if ("or".equals(constraint.getAttribute("operation"))) {
362 IdOperation.OR.serialize(out);
363 } else {
364 IdOperation.AND.serialize(out);
365 }
366 XmlTest.getTest("test").buildMdb(constraint.get("test"), out);
367 }
368 }
369 }
370
371
372 System.out.println("\tobjects...");
373 final List<Node> objects = node.get("objects").getNodes("object");
374 out.write(objects.size());
375 for (Node object : objects) {
376
377 final XmlParser.Attribute objectName = new XmlParser.Attribute("name",
378 object.getAttribute("name"));
379 boolean onePresent = false;
380 for (java.lang.Object modifierTmp : object) {
381 if (modifierTmp instanceof Node) {
382
383 if (onePresent) {
384 out.write(1);
385 }
386
387
388 final Node modifier = (Node) modifierTmp;
389 modifier.addAttribute(objectName);
390 XmlModifier.getModifier(modifier.getTag()).buildMdb(modifier, out);
391
392
393 if (onePresent) {
394 out.write(0);
395 } else {
396 out.write(1);
397 }
398 onePresent = true;
399 }
400 }
401 if (!onePresent) {
402
403 ModifierType.REGISTER_MODIFIER.serialize(out);
404 XmlModifier.buildMdbModifier(object, out);
405
406
407 XmlTools.writeConstant(out, 0);
408 XmlTools.writeConstant(out, 0);
409 IdOperation.ADD.serialize(out);
410
411
412 out.write(1);
413 }
414
415
416 out.write(0);
417 }
418
419
420 System.out.println("\tshared abilities...");
421 Node abilities = references.get("abilities");
422 out.write(abilities.getNbNodes());
423 macroActions.push(null);
424 for (Node ability : abilities.getNodes("ability")) {
425 String ref = ability.getAttribute("reference-name").toString();
426 referencedAbilities.put(ref, ability);
427 MToolKit.writeString(out, ref);
428 try {
429 Node node1 = (Node) ability.get(1);
430 XmlTbs.getTbsComponent(node1.getTag()).buildMdb(node1, out);
431 } catch (Throwable ie) {
432 XmlConfiguration.error("Error In referenced ability '" + ref + "' : "
433 + ie.getMessage() + "," + ie + ". Context=" + ability);
434 }
435 }
436 macroActions.pop();
437
438
439 System.out.println("\tdamage types...");
440 Collections.sort(XmlConfiguration.EXPORTED_DAMAGE_TYPES);
441 int count = XmlConfiguration.EXPORTED_DAMAGE_TYPES.size();
442 out.write(count);
443 for (int i = 0; i < count; i++) {
444 final PairStringInt pair = XmlConfiguration.EXPORTED_DAMAGE_TYPES.get(i);
445 MToolKit.writeString(out, pair.text);
446 MToolKit.writeInt16(out, pair.value);
447 }
448
449 /***
450 * <ul>
451 * CARD'S PART :
452 * <li>state pictures
453 * <li>tooltip filters
454 * <li>exported types name
455 * <li>exported sorted properties name
456 * <li>implemented cards
457 * </ul>
458 */
459
460
461 System.out.println("\tstates");
462 final Node states = node.get("state-pictures");
463 if (states == null) {
464 out.write(0);
465 } else {
466 out.write(states.getNbNodes());
467 for (java.lang.Object obj : states) {
468 if (obj instanceof Node) {
469 final Node ns = (Node) obj;
470 MToolKit.writeString(out, ns.getAttribute("picture"));
471 MToolKit.writeString(out, ns.getAttribute("name"));
472 MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("state")));
473 out.write(XmlTools.getInt(ns.getAttribute("index")));
474 final int x = XmlTools.getInt(ns.getAttribute("x"));
475 final int y = XmlTools.getInt(ns.getAttribute("y"));
476 if (MToolKit.getConstant(x) == -1 && MToolKit.getConstant(y) != -1
477 || MToolKit.getConstant(x) != -1 && MToolKit.getConstant(y) == -1) {
478 XmlConfiguration
479 .error("In state-picture '-1' value is allowed if and only if x AND y have this value.");
480 }
481 MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("x")));
482 MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("y")));
483 MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("width")));
484 MToolKit.writeInt16(out, XmlTools.getInt(ns.getAttribute("height")));
485 XmlTest.getTest("test").buildMdb(node.get("display-test"), out);
486 }
487 }
488 }
489
490
491 System.out.println("\ttooltip filters...");
492 final Node ttFilters = node.get("tooltip-filters");
493 XmlTools.defaultOnMeTag = false;
494 if (ttFilters == null) {
495 out.write(0);
496 } else {
497 out.write(ttFilters.getNbNodes());
498 for (java.lang.Object obj : ttFilters) {
499 if (obj instanceof Node) {
500 buildMdbTooltipFilter((Node) obj, out);
501 }
502 }
503 }
504
505
506 System.out.println("\texported type...");
507 Collections.sort(XmlConfiguration.EXPORTED_TYPES);
508 int nbTypes = XmlConfiguration.EXPORTED_TYPES.size();
509 out.write(nbTypes);
510 for (int i = 0; i < nbTypes; i++) {
511 final PairStringInt pair = XmlConfiguration.EXPORTED_TYPES.get(i);
512 MToolKit.writeString(out, pair.text);
513 MToolKit.writeInt16(out, pair.value);
514 }
515
516
517 System.out.println("\tproperties...");
518 Collections.sort(XmlConfiguration.EXPORTED_PROPERTIES);
519 final int nbProperties = XmlConfiguration.EXPORTED_PROPERTIES.size();
520 MToolKit.writeInt16(out, nbProperties);
521 for (int i = 0; i < nbProperties; i++) {
522 final PairStringInt pair = XmlConfiguration.EXPORTED_PROPERTIES.get(i);
523 MToolKit.writeInt16(out, pair.value);
524 MToolKit.writeString(out, pair.text);
525 }
526 MToolKit.writeInt16(out, XmlConfiguration.PROPERTY_PICTURES.size());
527 for (Map.Entry<Integer, String> entry : XmlConfiguration.PROPERTY_PICTURES
528 .entrySet()) {
529 MToolKit.writeInt16(out, entry.getKey());
530 MToolKit.writeString(out, entry.getValue());
531 }
532
533 /***
534 * <ul>
535 * STACK MANAGER'S PART :
536 * <li>first player registers
537 * <li>second player registers
538 * <li>abortion zone
539 * </ul>
540 */
541
542 System.out.println("\tinitial registers...");
543 Node registers = node.get("registers-first-player");
544 final byte[] registersBytes = new byte[IdTokens.PLAYER_REGISTER_SIZE];
545 if (registers != null) {
546 final List<Node> list = registers.getNodes("register");
547 for (Node register : list) {
548 registersBytes[XmlTools.getInt(register.getAttribute("index"))] = (byte) XmlTools
549 .getInt(register.getAttribute("value"));
550 }
551 }
552 out.write(registersBytes);
553 registers = node.get("registers-second-player");
554 final byte[] registersBytes2 = new byte[IdTokens.PLAYER_REGISTER_SIZE];
555 if (registers != null) {
556 final List<Node> list = registers.getNodes("register");
557 for (Node register : list) {
558 registersBytes2[XmlTools.getInt(register.getAttribute("index"))] = (byte) XmlTools
559 .getInt(register.getAttribute("value"));
560 }
561 }
562 out.write(registersBytes2);
563
564
565
566
567 final Node refAbilities = node.get("abilities");
568 out.write(XmlTools.getZone(refAbilities.getAttribute("abortionzone")));
569
570
571 System.out.println("\tadditional-costs...");
572 final List<Node> additionalCosts = node.get("additional-costs").getNodes(
573 "additional-cost");
574 out.write(additionalCosts.size());
575 for (Node additionalCost : additionalCosts) {
576 XmlTest.getTest("test").buildMdb(additionalCost.get("test"), out);
577 XmlTbs.writeActionList(additionalCost.get("cost"), out);
578 }
579
580 /***
581 * <ul>
582 * EVENT MANAGER'S PART :
583 * <li>phases
584 * <li>turn-structure
585 * <li>first phase index
586 * </ul>
587 */
588
589 System.out.println("\tphases...");
590 final Node phases = node.get("phases");
591 out.write(phases.getNbNodes());
592 for (java.lang.Object obj : phases) {
593 if (obj instanceof Node) {
594 buildMdbPhaseType((Node) obj, out);
595 }
596 }
597
598
599 final String list = phases.getAttribute("turn-structure");
600 System.out.println("\tturn structure...");
601 final String[] arrayid = list.split(" ");
602 out.write(arrayid.length);
603 for (String id : arrayid) {
604 out.write(XmlTools.getAliasValue(id));
605 }
606
607
608 out.write(Integer.parseInt(phases.getAttribute("start")));
609
610
611 System.out.println("\trule abilities...");
612 out.write(refAbilities.getNbNodes());
613 for (java.lang.Object obj : refAbilities) {
614 if (obj instanceof Node) {
615 try {
616 XmlTbs.getTbsComponent(((Node) obj).getTag()).buildMdb((Node) obj,
617 out);
618 } catch (Throwable ie) {
619 XmlConfiguration.error("Error in system ability '"
620 + ((Node) obj).getAttribute("name") + "' : " + ie.getMessage()
621 + ". Context=" + obj);
622 break;
623 }
624 }
625 }
626
627
628 System.out.println("\tstatic-modifiers...");
629 final Node modifiers = node.get("static-modifiers");
630 if (modifiers == null) {
631 out.write(0);
632 } else {
633 out.write(modifiers.getNbNodes());
634 for (java.lang.Object obj : modifiers) {
635 if (obj instanceof Node) {
636 XmlModifier.getModifier("static-modifier").buildMdb((Node) obj, out);
637 }
638 }
639 }
640
641
642 System.out.println("\tlayouts...");
643 final Node layouts = node.get("layouts");
644
645
646 writeTaskPaneElement(layouts.get("common-panel").get("card-details").get(
647 "properties"), out);
648
649
650 List<Node> sectors = layouts.get("zones").get("play").getNodes("sector");
651 out.write(sectors.size());
652 for (XmlParser.Node sector : sectors) {
653 XmlTest.getTest("test").buildMdb(sector, out);
654 MToolKit.writeString(out, sector.getAttribute("constraint"));
655 }
656
657
658 final long cardBytesPosition = fileOut.getChannel().position();
659 fileOut.getChannel().position(shortcutCardBytes);
660 MToolKit.writeInt24(out, (int) cardBytesPosition);
661 fileOut.getChannel().position(cardBytesPosition);
662
663
664 resolveReferences = true;
665 System.out.println("Processing cards...");
666 String xmlFile = node.getAttribute("xmlFile");
667 try {
668 final String baseName = FilenameUtils.getBaseName(xmlFile);
669 XmlTbs.updateMdb(baseName, out);
670 } catch (Throwable e2) {
671 XmlConfiguration.error("Error found in cards parsing of rule '" + xmlFile
672 + "' : " + e2.getMessage());
673 }
674
675 System.out.println(node.getAttribute("name") + " rules finished");
676 return 0;
677 }
678
679 private void writeTaskPaneElement(Node node, OutputStream out)
680 throws IOException {
681 final List<Node> elements = node.getNodes("menu-element");
682 final List<Node> attributes = node.getNodes("menu-attribute");
683 out.write((elements == null ? 0 : elements.size())
684 + (attributes == null ? 0 : attributes.size()));
685 for (java.lang.Object nestedNode : node) {
686 if (nestedNode instanceof Node) {
687 final Node task = (Node) nestedNode;
688 if ("menu-element".equals(task.getTag())) {
689 out.write(CardPropertiesPanel.NESTED_ELEMENT);
690 MToolKit.writeString(out, task.getAttribute("name"));
691 writeTaskPaneElement(task, out);
692 } else if ("menu-attribute".equals(task.getTag())) {
693 out.write(CardPropertiesPanel.ATTRIBUTE);
694 MToolKit.writeString(out, task.getAttribute("type").toLowerCase());
695 MToolKit.writeString(out, task.getAttribute("name"));
696 MToolKit.writeString(out, task.getAttribute("value"));
697 } else {
698 XmlConfiguration
699 .warning("non supported task type : " + task.getTag());
700 }
701 }
702 }
703
704 }
705
706 /***
707 * <ul>
708 * Structure of stream : Data[size]
709 * <li>phase name + '\0' [...]</li>
710 * <li>phase identifier [1]</li>
711 * <li>empty stack playable, idCards for current player [2]</li>
712 * <li>empty stack playable, idCards for non-current player [2]</li>
713 * <li>middle resolution, playable idCards for current player [2]</li>
714 * <li>middle resolution, playable idCards for non-current player [2]</li>
715 * </ul>
716 *
717 * @param node
718 * the XML phase type structure
719 * @param out
720 * output stream where the card structure will be saved
721 * @throws IOException
722 * error during the
723 * @see net.sf.firemox.stack.phasetype.PhaseType
724 */
725 public static final void buildMdbPhaseType(Node node, OutputStream out)
726 throws IOException {
727 MToolKit.writeString(out, node.getAttribute("name"));
728 out.write(XmlTools.getAliasValue(node.getAttribute("name")));
729 MToolKit.writeInt16(out, XmlTools.getIdCards(node
730 .getAttribute("playable-empty-stack-you")));
731 MToolKit.writeInt16(out, XmlTools.getIdCards(node
732 .getAttribute("playable-empty-stack-opponent")));
733 MToolKit.writeInt16(out, XmlTools.getIdCards(node
734 .getAttribute("playable-middle-resolution-you")));
735 MToolKit.writeInt16(out, XmlTools.getIdCards(node
736 .getAttribute("playable-middle-resolution-opponent")));
737 }
738
739 /***
740 * <ul>
741 * Structure of stream : Data[size]
742 * <li>display powerANDtoughness yes=1,no=0 [1]</li>
743 * <li>display states yes=1,no=0 [1]</li>
744 * <li>display types yes=1,no=0 [1]</li>
745 * <li>display colors yes=1,no=0 [1]</li>
746 * <li>display properties yes=1,no=0 [1]</li>
747 * <li>display damage yes=1,no=0 [1]</li>
748 * <li>filter [...]</li>
749 * </ul>
750 *
751 * @param node
752 * the XML structure
753 * @param out
754 * output stream where the card structure will be saved
755 * @throws IOException
756 * error during the writing.
757 */
758 public static final void buildMdbTooltipFilter(Node node, OutputStream out)
759 throws IOException {
760
761 out.write("true".equals(node.getAttribute("powerANDtoughness")) ? 1 : 0);
762 out.write("true".equals(node.getAttribute("states")) ? 1 : 0);
763 out.write("true".equals(node.getAttribute("types")) ? 1 : 0);
764 out.write("true".equals(node.getAttribute("colors")) ? 1 : 0);
765 out.write("true".equals(node.getAttribute("properties")) ? 1 : 0);
766 out.write("true".equals(node.getAttribute("damage")) ? 1 : 0);
767 XmlTest.getTest("test").buildMdb(node.get("filter"), out);
768 }
769
770 /***
771 * Push an action (accepting <code>null</code>) for macro.
772 *
773 * @param node
774 * the node to give to the next macro.
775 */
776 public static void pushMacroAction(List<Node> node) {
777 macroActions.push(node);
778 }
779
780 /***
781 * Return the last given action to a macro.
782 *
783 * @return the last given action to a macro.
784 */
785 public static List<Node> peekMacroAction() {
786 return macroActions.peek();
787 }
788
789 /***
790 * Remove the last given action to a macro.
791 */
792 public static void popMacroAction() {
793 macroActions.pop();
794 }
795
796 /***
797 * Available ability references of this TBS
798 */
799 public static Map<String, Node> referencedAbilities = null;
800
801 /***
802 * Available test references of this TBS
803 */
804 public static Map<String, Node> referencedTest = null;
805
806 /***
807 * Available actions references of this TBS
808 */
809 public static Map<String, List<Node>> referencedActions = null;
810
811 /***
812 * Available actions references of this TBS do not accepting macro
813 */
814 public static Set<String> referencedNonMacroActions = null;
815
816 /***
817 * Available attachments references of this TBS do not accepting macro
818 */
819 public static Set<String> referencedNonMacroAttachments = null;
820
821 /***
822 * Available attachments references of this TBS.
823 */
824 public static Map<String, Node> referencedAttachments = null;
825
826 /***
827 * Available node for action of macro.
828 */
829 public static Stack<List<Node>> macroActions = null;
830
831 /***
832 * Are the references must be resolved.
833 */
834 public static boolean resolveReferences;
835 }