1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.magicproject.action;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.util.HashMap;
25
26 import net.sf.magicproject.action.context.ActionContextWrapper;
27 import net.sf.magicproject.action.context.Int;
28 import net.sf.magicproject.action.handler.ChoosenAction;
29 import net.sf.magicproject.action.handler.InitAction;
30 import net.sf.magicproject.action.handler.RollBackAction;
31 import net.sf.magicproject.clickable.ability.Ability;
32 import net.sf.magicproject.clickable.targetable.Targetable;
33 import net.sf.magicproject.clickable.targetable.card.MCard;
34 import net.sf.magicproject.clickable.targetable.player.Player;
35 import net.sf.magicproject.event.ModifiedRegister;
36 import net.sf.magicproject.event.context.ContextEventListener;
37 import net.sf.magicproject.expression.Expression;
38 import net.sf.magicproject.expression.IntValue;
39 import net.sf.magicproject.operation.Any;
40 import net.sf.magicproject.operation.Operation;
41 import net.sf.magicproject.stack.StackManager;
42 import net.sf.magicproject.test.Test;
43 import net.sf.magicproject.test.TestOn;
44 import net.sf.magicproject.token.IdConst;
45 import net.sf.magicproject.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 ChoosenAction, 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 occured 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(
104 ability, null, context), ((Int) actionContext.actionContext)
105 .getInt(), op);
106 }
107
108 public void rollback(ActionContextWrapper actionContext,
109 ContextEventListener context, Ability ability) {
110
111 }
112
113 public String toHtmlString(Ability ability, ContextEventListener context,
114 ActionContextWrapper actionContext) {
115 return toHtmlString(ability, context);
116 }
117
118 @Override
119 public boolean play(ContextEventListener context, Ability ability) {
120 return modifyRegister(StackManager.getRealSource(ability.getCard()),
121 register.getTargetable(ability, null), index.getValue(
122 ability, null, context), getValue(ability, null, context), op);
123 }
124
125 /***
126 * Generate event associated to this action. Only one or several events are
127 * generated and may be collected by event listeners. Then play this action
128 *
129 * @param source
130 * the source, and the concerned card to this modification
131 * @param targetable
132 * the component to modify
133 * @param index
134 * the register's index
135 * @param value
136 * right value of operation
137 * @param op
138 * identifiant of the operation applied to the specified card
139 * @return true
140 */
141 public static boolean modifyRegister(MCard source, Targetable targetable,
142 int index, int value, Operation op) {
143 if (targetable.isPlayer())
144 return modifyRegister(source, (Player) targetable, index, op, value);
145 return modifyRegister(source, (MCard) targetable, index, op, value);
146 }
147
148 private static boolean modifyRegister(MCard source, Player player, int index,
149 Operation op, int rightValue) {
150 if (index == IdTokens.MANA_POOL) {
151
152 player.mana.setToZero();
153 return true;
154 }
155
156
157 if (!op.isUselessWith(index, rightValue)) {
158 if (!ModifiedRegister.tryAction(player, source, IdTokens.PLAYER, index,
159 op, rightValue)) {
160
161 return false;
162 }
163
164 player.setValue(index, op, rightValue);
165 ModifiedRegister.dispatchEvent(player, source, IdTokens.PLAYER, index,
166 op, rightValue);
167 }
168 return true;
169 }
170
171 private static boolean modifyRegister(MCard source, MCard card, int index,
172 Operation op, int rightValue) {
173
174 if (op.isUselessWith(card.getValue(index), rightValue)) {
175 return true;
176 }
177 boolean replaced = false;
178 if (index < IdTokens.FIRST_FREE_CARD_INDEX) {
179
180 replaced = !ModifiedRegister.tryAction(card, source, IdTokens.CARD,
181 index, op, rightValue);
182 }
183
184 if (!replaced) {
185
186 card.setValue(index, op, rightValue);
187 if (index < IdTokens.FIRST_FREE_CARD_INDEX) {
188 ModifiedRegister.dispatchEvent(card, source, IdTokens.CARD, index, op,
189 rightValue);
190 }
191 return true;
192 }
193 return false;
194 }
195
196 @Override
197 public Test parseTest(Test test) {
198 final HashMap<String, Expression> values = new HashMap<String, Expression>();
199 values.put("%value", valueExpr);
200 return test.getConstraintTest(values);
201 }
202
203 @Override
204 public boolean equal(MAction constraintAction) {
205 if (!(constraintAction instanceof ModifyTargetableRegister)) {
206 return false;
207 }
208 final ModifyTargetableRegister other = (ModifyTargetableRegister) constraintAction;
209 return (other.op == op || other.op == Any.getInstance())
210 && register == other.register
211 && index instanceof IntValue
212 && ((IntValue) index).value == ((IntValue) index).value
213 && valueExpr instanceof IntValue
214 && (((IntValue) valueExpr).value == IdConst.ALL || ((IntValue) valueExpr).value == ((IntValue) other.valueExpr).value);
215 }
216
217 @Override
218 public String toString(Ability ability) {
219 final int index = this.index.getValue(ability, null, null);
220 String value = null;
221 try {
222 value = "" + valueExpr.getValue(ability, null, null);
223 } catch (Exception e) {
224 value = "?";
225 }
226 return op.getClass().getSimpleName() + " (L=" + index + ",R=" + value + ")";
227 }
228
229 /***
230 * represents the token to modify
231 */
232 protected final TestOn register;
233 }