1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.firemox.action;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.HashMap;
25
26 import net.sf.firemox.action.context.ActionContextWrapper;
27 import net.sf.firemox.action.context.Int;
28 import net.sf.firemox.action.handler.ChosenAction;
29 import net.sf.firemox.action.handler.InitAction;
30 import net.sf.firemox.action.handler.RollBackAction;
31 import net.sf.firemox.clickable.ability.Ability;
32 import net.sf.firemox.clickable.target.Target;
33 import net.sf.firemox.clickable.target.card.MCard;
34 import net.sf.firemox.clickable.target.player.Player;
35 import net.sf.firemox.event.ModifiedRegister;
36 import net.sf.firemox.event.context.ContextEventListener;
37 import net.sf.firemox.expression.Expression;
38 import net.sf.firemox.expression.IntValue;
39 import net.sf.firemox.operation.Any;
40 import net.sf.firemox.operation.Operation;
41 import net.sf.firemox.stack.StackManager;
42 import net.sf.firemox.test.Test;
43 import net.sf.firemox.test.TestOn;
44 import net.sf.firemox.token.IdConst;
45 import net.sf.firemox.token.IdTokens;
46
47 /***
48 * This action is used to modifiy a register of a player or a card. <br>
49 * This action can use the target list when is played : the address
50 * (idToken=register name + register index) must be IdTokens#TARGET. So the
51 * target list must set before this action would be played.
52 *
53 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
54 * @since 0.71
55 * @since 0.85 useless operation are ignored and not genrated.
56 */
57 public class ModifyTargetableRegister extends ModifyRegister implements
58 ChosenAction, InitAction, RollBackAction {
59
60 /***
61 * Create an instance of ModifyRegister by reading a file Offset's file must
62 * pointing on the first byte of this action <br>
63 * <ul>
64 * Structure of InputStream : Data[size]
65 * <li>[super]</li>
66 * </ul>
67 *
68 * @param inputFile
69 * file containing this action
70 * @throws IOException
71 * if error occurred during the reading process from the specified
72 * input stream
73 */
74 ModifyTargetableRegister(InputStream inputFile) throws IOException {
75 super(inputFile);
76 register = TestOn.deserialize(inputFile);
77 }
78
79 @Override
80 public final Actiontype getIdAction() {
81 return Actiontype.MODIFY_TARGETABLE_REGISTER;
82 }
83
84 public boolean init(ActionContextWrapper actionContext,
85 ContextEventListener context, Ability ability) {
86 actionContext.actionContext = new Int(getValue(ability, null, context));
87 return true;
88 }
89
90 public boolean choose(ActionContextWrapper actionContext,
91 ContextEventListener context, Ability ability) {
92 return true;
93 }
94
95 public void disactivate(ActionContextWrapper actionContext,
96 ContextEventListener context, Ability ability) {
97
98 }
99
100 public boolean replay(ActionContextWrapper actionContext,
101 ContextEventListener context, Ability ability) {
102 return modifyRegister(StackManager.getRealSource(ability.getCard()),
103 register.getTargetable(ability, null), index.getValue(ability, null,
104 context), ((Int) actionContext.actionContext).getInt(), op);
105 }
106
107 public void rollback(ActionContextWrapper actionContext,
108 ContextEventListener context, Ability ability) {
109
110 }
111
112 public String toHtmlString(Ability ability, ContextEventListener context,
113 ActionContextWrapper actionContext) {
114 return toHtmlString(ability, context);
115 }
116
117 @Override
118 public boolean play(ContextEventListener context, Ability ability) {
119 return modifyRegister(StackManager.getRealSource(ability.getCard()),
120 register.getTargetable(ability, null), index.getValue(ability, null,
121 context), getValue(ability, null, context), op);
122 }
123
124 /***
125 * Generate event associated to this action. Only one or several events are
126 * generated and may be collected by event listeners. Then play this action
127 *
128 * @param source
129 * the source, and the concerned card to this modification
130 * @param target
131 * the component to modify
132 * @param index
133 * the register's index
134 * @param value
135 * right value of operation
136 * @param op
137 * identifier of the operation applied to the specified card
138 * @return true
139 */
140 public static boolean modifyRegister(MCard source, Target target, int index,
141 int value, Operation op) {
142 if (target.isPlayer())
143 return modifyRegister(source, (Player) target, index, op, value);
144 return modifyRegister(source, (MCard) target, index, op, value);
145 }
146
147 private static boolean modifyRegister(MCard source, Player player, int index,
148 Operation op, int rightValue) {
149 if (index == IdTokens.MANA_POOL) {
150
151 player.mana.setToZero();
152 return true;
153 }
154
155
156 if (!op.isUselessWith(index, rightValue)) {
157 if (!ModifiedRegister.tryAction(player, source, IdTokens.PLAYER, index,
158 op, rightValue)) {
159
160 return false;
161 }
162
163 player.setValue(index, op, rightValue);
164 ModifiedRegister.dispatchEvent(player, source, IdTokens.PLAYER, index,
165 op, rightValue);
166 }
167 return true;
168 }
169
170 private static boolean modifyRegister(MCard source, MCard card, int index,
171 Operation op, int rightValue) {
172
173 if (op.isUselessWith(card.getValue(index), rightValue)) {
174 return true;
175 }
176 boolean replaced = false;
177 if (index < IdTokens.FIRST_FREE_CARD_INDEX) {
178
179 replaced = !ModifiedRegister.tryAction(card, source, IdTokens.CARD,
180 index, op, rightValue);
181 }
182
183 if (!replaced) {
184
185 card.setValue(index, op, rightValue);
186 if (index < IdTokens.FIRST_FREE_CARD_INDEX) {
187 ModifiedRegister.dispatchEvent(card, source, IdTokens.CARD, index, op,
188 rightValue);
189 }
190 return true;
191 }
192 return false;
193 }
194
195 @Override
196 public Test parseTest(Test test) {
197 final HashMap<String, Expression> values = new HashMap<String, Expression>();
198 values.put("%value", valueExpr);
199 return test.getConstraintTest(values);
200 }
201
202 @Override
203 public boolean equal(MAction constraintAction) {
204 if (!(constraintAction instanceof ModifyTargetableRegister)) {
205 return false;
206 }
207 final ModifyTargetableRegister other = (ModifyTargetableRegister) constraintAction;
208 return (other.op == op || other.op == Any.getInstance())
209 && register == other.register
210 && index instanceof IntValue
211 && ((IntValue) index).value == ((IntValue) index).value
212 && valueExpr instanceof IntValue
213 && (((IntValue) valueExpr).value == IdConst.ALL || ((IntValue) valueExpr).value == ((IntValue) other.valueExpr).value);
214 }
215
216 @Override
217 public String toString(Ability ability) {
218 final int index = this.index.getValue(ability, null, null);
219 String value = null;
220 try {
221 value = "" + valueExpr.getValue(ability, null, null);
222 } catch (Exception e) {
223 value = "?";
224 }
225 return op.getClass().getSimpleName() + " (L=" + index + ",R=" + value + ")";
226 }
227
228 /***
229 * represents the token to modify
230 */
231 protected final TestOn register;
232 }