1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.magicproject.action;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23
24 import net.sf.magicproject.action.context.ActionContextWrapper;
25 import net.sf.magicproject.action.context.BooleanArray;
26 import net.sf.magicproject.action.handler.FollowAction;
27 import net.sf.magicproject.action.handler.StandardAction;
28 import net.sf.magicproject.clickable.ability.Ability;
29 import net.sf.magicproject.clickable.targetable.Targetable;
30 import net.sf.magicproject.clickable.targetable.card.MCard;
31 import net.sf.magicproject.event.FacedDown;
32 import net.sf.magicproject.event.FacedUp;
33 import net.sf.magicproject.event.context.ContextEventListener;
34 import net.sf.magicproject.stack.StackManager;
35 import net.sf.magicproject.token.Visibility;
36 import net.sf.magicproject.token.VisibilityChange;
37 import net.sf.magicproject.tools.Log;
38
39 /***
40 * Action used to face up or down cards referenced by the target-list.
41 *
42 * @author <a href="mailto:hoani.cross@gmail.com">Hoani CROSS</a>
43 * @since 0.90
44 * @since 0.91 'for' constraint attribute, default [everyone] is added.
45 */
46 class Face extends UserAction implements StandardAction, FollowAction {
47
48 /***
49 * Create an instance of Face action.
50 * <ul>
51 * Structure of stream :
52 * <li>idAction [1]</li>
53 * <li>int8 : 0 means face-down, >0 means face-up [1]</li>
54 * <li>visibility [1]</li>
55 * </ul>
56 *
57 * @param inputFile
58 * the file to read the action from
59 * @throws IOException
60 * if an IO error occurred
61 * @see Actiontype
62 */
63 Face(InputStream inputFile) throws IOException {
64 super(inputFile);
65 faceUpFlag = inputFile.read() > 0;
66 visibilityChange = VisibilityChange.deserialize(inputFile);
67 }
68
69 @Override
70 public Actiontype getIdAction() {
71 return Actiontype.FACE;
72 }
73
74 public boolean play(ContextEventListener context, Ability ability) {
75 for (Targetable targetable : StackManager.getInstance().getTargetedList().list) {
76 if (targetable.isCard()) {
77 final MCard card = (MCard) targetable;
78 if (checkTimeStamp(context, card)) {
79 if (faceUpFlag) {
80 FacedUp.dispatchEvent(card);
81 card.returnCard(card.visibility.increaseFor(card.getController(),
82 visibilityChange));
83 } else {
84 FacedDown.dispatchEvent(card);
85 card.returnCard(card.visibility.decreaseFor(card.getController(),
86 visibilityChange));
87 }
88 } else {
89 Log.error("In FACE action, erreur timestamp for card " + card);
90 }
91 } else {
92 Log
93 .warn("In FACE action, target list contains non 'Card' object. Ignored");
94 }
95 }
96 return true;
97 }
98
99 public void rollback(ActionContextWrapper actionContext,
100 ContextEventListener context, Ability ability) {
101 final BooleanArray bContext = (BooleanArray) actionContext.actionContext;
102 for (int i = StackManager.getInstance().getTargetedList().size(); i-- > 0;) {
103 if (StackManager.getInstance().getTargetedList().get(i).isCard()) {
104 final MCard card = (MCard) StackManager.getInstance().getTargetedList()
105 .get(i);
106 if (bContext.getBoolean(i)) {
107 card.tap(!faceUpFlag);
108 if (faceUpFlag) {
109 card.returnCard(Visibility.HIDDEN);
110 } else {
111 card.returnCard(Visibility.PUBLIC);
112 }
113 }
114 } else {
115 Log
116 .warn("In FACE action, target list contains non 'Card' object. Ignored");
117 }
118 }
119 }
120
121 public void simulate(ActionContextWrapper actionContext,
122 ContextEventListener context, Ability ability) {
123 final BooleanArray bContext = new BooleanArray(StackManager.getInstance()
124 .getTargetedList().size());
125 actionContext.actionContext = bContext;
126 for (int i = StackManager.getInstance().getTargetedList().size(); i-- > 0;) {
127 if (StackManager.getInstance().getTargetedList().get(i).isCard()) {
128 final MCard card = (MCard) StackManager.getInstance().getTargetedList()
129 .get(i);
130 if (card.visibility == Visibility.PUBLIC && !faceUpFlag
131 || card.visibility != Visibility.PUBLIC && faceUpFlag) {
132 bContext.setBoolean(i, true);
133 if (faceUpFlag) {
134 card.returnCard(Visibility.PUBLIC);
135 } else {
136 card.returnCard(Visibility.HIDDEN);
137 }
138 }
139 } else {
140 Log
141 .warn("In FACE action, target list contains non 'Card' object. Ignored");
142 }
143 }
144 }
145
146 @Override
147 public String toString(Ability ability) {
148 return "face-" + (faceUpFlag ? "up" : "down");
149 }
150
151 /***
152 * <code>true</code> if the action if to face cards up, <code>false</code>
153 * if the action if to face them down.
154 */
155 private final boolean faceUpFlag;
156
157 /***
158 * The visibility to set.
159 */
160 private final VisibilityChange visibilityChange;
161 }