1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.sf.magicproject.action;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import net.sf.magicproject.action.handler.StandardAction;
31 import net.sf.magicproject.clickable.ability.Ability;
32 import net.sf.magicproject.clickable.ability.AbilityFactory;
33 import net.sf.magicproject.clickable.ability.RemoveModifier;
34 import net.sf.magicproject.clickable.ability.TriggeredAbility;
35 import net.sf.magicproject.clickable.targetable.card.DelayedCard;
36 import net.sf.magicproject.clickable.targetable.card.MCard;
37 import net.sf.magicproject.clickable.targetable.card.SystemCard;
38 import net.sf.magicproject.event.EventFactory;
39 import net.sf.magicproject.event.MEventListener;
40 import net.sf.magicproject.event.TriggeredEvent;
41 import net.sf.magicproject.event.context.ContextEventListener;
42 import net.sf.magicproject.expression.Expression;
43 import net.sf.magicproject.expression.ExpressionFactory;
44 import net.sf.magicproject.stack.StackManager;
45 import net.sf.magicproject.test.TestOn;
46 import net.sf.magicproject.token.IdTokens;
47
48 /***
49 * Create a new {@link MCard} component and add it to the current target list.
50 *
51 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
52 * @since 0.80
53 */
54 class CreateAbility extends UserAction implements StandardAction {
55
56 /***
57 * Create an instance of CreateAbility by reading a file Offset's file must
58 * pointing on the first byte of this action
59 * <ul>
60 * Structure of InputStream : Data[size]
61 * <li>super [Action]</li>
62 * <li>nb registers to set [int]</li>
63 * <li>register index i [Expression]</li>
64 * <li>expression i [Expression]</li>
65 * <li>idToken of card to save [TestOn]</li>
66 * <li>idToken of card to save [TestOn]</li>
67 * <li>ability To Add [...]</li>
68 * <li>nb exists until this triggered event [int]</li>
69 * <li>exists until this triggered event i [Event]</li>
70 * </ul>
71 *
72 * @param inputFile
73 * file containing this action
74 * @throws IOException
75 * If some other I/O error occurs
76 */
77 CreateAbility(InputStream inputFile) throws IOException {
78 super(inputFile);
79
80 registers = new Expression[IdTokens.ABILITY_REGISTER_SIZE];
81 indexes = new Expression[registers.length];
82 for (int i = inputFile.read(); i-- > 0;) {
83 indexes[i] = ExpressionFactory.readNextExpression(inputFile);
84 registers[i] = ExpressionFactory.readNextExpression(inputFile);
85 }
86 save1 = TestOn.deserialize(inputFile);
87 save2 = TestOn.deserialize(inputFile);
88
89 abilityToAdd = (TriggeredAbility) AbilityFactory.readAbility(inputFile,
90 SystemCard.instance);
91
92
93 int count = inputFile.read();
94 until = new ArrayList<MEventListener>();
95 while (count-- > 0) {
96 until.add(EventFactory.readNextEvent(inputFile, SystemCard.instance));
97 }
98
99 }
100
101 @Override
102 public final Actiontype getIdAction() {
103 return Actiontype.CREATE_ABILITY;
104 }
105
106 public boolean play(ContextEventListener context, Ability ability) {
107 final List<Ability> abilities = new ArrayList<Ability>();
108 final MCard owner = ability.getCard();
109 final TriggeredAbility clonedAbility = (TriggeredAbility) abilityToAdd
110 .clone(owner);
111
112
113 final int[] parsedRegisters = new int[IdTokens.ABILITY_REGISTER_SIZE];
114 for (Expression exprIndex : indexes) {
115 if (exprIndex != null) {
116 int index = exprIndex.getValue(ability, save1.getTargetable(ability,
117 owner), context);
118 parsedRegisters[index] = registers[index].getValue(ability, save1
119 .getTargetable(ability, owner), context);
120 }
121 }
122
123
124 StackManager.getSpellController().zoneManager.delayedBuffer
125 .add(new DelayedCard(clonedAbility, abilities, parsedRegisters, save1
126 .getTargetable(ability, owner), save2.getTargetable(ability, owner)));
127
128
129 for (MEventListener event : until) {
130 abilities.add(new RemoveModifier((TriggeredEvent) event, clonedAbility));
131 }
132
133
134 for (Ability removerAbility : abilities) {
135 removerAbility.registerToManager();
136 }
137 clonedAbility.registerToManager();
138
139 return true;
140 }
141
142 @Override
143 public String toString(Ability ability) {
144 return "Delayed ability";
145 }
146
147 /***
148 * The ability to add
149 */
150 private final TriggeredAbility abilityToAdd;
151
152 /***
153 * When this event is generated this modifier is removed from the attached
154 * object. If this event is equal to null, this modifier can be removed only
155 * by the attached component.
156 */
157 protected final List<MEventListener> until;
158
159 /***
160 * The private registers of this ability
161 */
162 private final Expression[] registers;
163
164 /***
165 * The private registers of this ability
166 */
167 private final Expression[] indexes;
168
169 /***
170 * The first targetable to save. If is 0, no card is saved.
171 */
172 private final TestOn save1;
173
174 /***
175 * The second targetable to save. If is 0, no card is saved.
176 */
177 private final TestOn save2;
178 }