1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.magicproject.modifier;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import net.sf.magicproject.clickable.ability.Ability;
30 import net.sf.magicproject.clickable.targetable.card.MCard;
31 import net.sf.magicproject.clickable.targetable.card.SystemCard;
32 import net.sf.magicproject.event.EventFactory;
33 import net.sf.magicproject.event.MEventListener;
34 import net.sf.magicproject.event.MovedCard;
35 import net.sf.magicproject.event.context.ContextEventListener;
36 import net.sf.magicproject.test.And;
37 import net.sf.magicproject.test.InZone;
38 import net.sf.magicproject.test.IsTested;
39 import net.sf.magicproject.test.Not;
40 import net.sf.magicproject.test.Test;
41 import net.sf.magicproject.test.TestFactory;
42 import net.sf.magicproject.test.True;
43 import net.sf.magicproject.test.TestOn;
44 import net.sf.magicproject.token.IdZones;
45 import net.sf.magicproject.tools.MToolKit;
46
47 /***
48 * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
49 * @since 0.85 Recalculate attribute is supported
50 */
51 public abstract class ModifierModel {
52
53 /***
54 * Creates a new instance of ModifierModel <br>
55 * <ul>
56 * Structure of InputStream : Data[size]
57 * <li>modifier name [String]</li>
58 * <li>initial registers value [IdTokens.MODIFIER_REGISTER_SIZE]</li>
59 * <li>activated while this condition [Test]</li>
60 * <li>linked to creator [boolean]</li>
61 * <li>exists until this triggered event [Event[]]</li>
62 * <li>layer [int]</li>
63 * </ul>
64 * The while condition must not refer to any register value of this modifier
65 *
66 * @param inputFile
67 * @throws IOException
68 * if error occured during the reading process from the specified
69 * input stream
70 */
71 protected ModifierModel(InputStream inputFile) throws IOException {
72 this();
73 name = MToolKit.readString(inputFile);
74 recalculate = inputFile.read() == 1;
75
76
77 whileCondition = TestFactory.readNextTest(inputFile);
78 linkedEvents = new ArrayList<MEventListener>();
79 whileCondition.extractTriggeredEvents(linkedEvents, SystemCard.instance,
80 True.getInstance());
81
82
83 linked = inputFile.read() == 1;
84
85
86 int count = inputFile.read();
87 until = new ArrayList<MEventListener>(count + 1);
88 while (count-- > 0) {
89 until.add(EventFactory.readNextEvent(inputFile, SystemCard.instance));
90 }
91
92
93 until.add(new MovedCard(IdZones.PLAY, And.append(IsTested.TESTED_IS_ME,
94 new InZone(IdZones.PLAY, TestOn.THIS)), new Not(new InZone(
95 IdZones.PLAY, TestOn.THIS)), SystemCard.instance));
96 layer = inputFile.read();
97 }
98
99 /***
100 * Create a new instance from the given model.
101 *
102 * @param other
103 * the instance to copy
104 */
105 protected ModifierModel(ModifierModel other) {
106 name = other.name;
107 linked = other.linked;
108 until = other.until;
109 whileCondition = other.whileCondition;
110 layer = other.layer;
111 recalculate = other.recalculate;
112 if (other.next != null) {
113 next = other.next.clone();
114 }
115 }
116
117 /***
118 * Read the name of this model
119 */
120 protected ModifierModel() {
121 super();
122 }
123
124 /***
125 * Add to the list of modifierModels of the specified card, this instance.
126 *
127 * @param modelToAdd
128 * This new modifier will be added to the tail of modifier list.
129 */
130 public final void addModel(ModifierModel modelToAdd) {
131 if (next == null) {
132 next = modelToAdd;
133 } else {
134 next.addModel(modelToAdd);
135 }
136 }
137
138 @Override
139 public abstract ModifierModel clone();
140
141 /***
142 * Create modifier(s) on the specified target.
143 *
144 * @param ability
145 * is the ability owning causin the creation of this modifier. The
146 * card component of this ability should correspond to the card
147 * owning this test too.
148 * @param target
149 * is the card this new modifier would be attached to.
150 */
151 public abstract void addModifierFromModel(Ability ability, MCard target);
152
153 /***
154 * Return the HTML code representing this action. If this action is named,
155 * it's name will be returned. If not, if existing, the picture associated to
156 * this action is returned. Otherwise, built-in action's text will be
157 * returned.
158 *
159 * @param ability
160 * is the ability owning this test. The card component of this
161 * ability should correspond to the card owning this test too.
162 * @param context
163 * the context needed by event activated
164 * @return the HTML code representing this action. If this action is named,
165 * it's name will be returned. If not, if existing, the picture
166 * associated to this action is returned. Otherwise, built-in action's
167 * text will be returned.
168 * @since 0.86
169 */
170 public abstract String toHtmlString(Ability ability,
171 ContextEventListener context);
172
173 /***
174 * Remove one instance of this object from the given card.
175 *
176 * @param fromCard
177 * @param objectTest
178 * The test applied on specific modifier to be removed.
179 */
180 public void removeObject(MCard fromCard, Test objectTest) {
181 if (next != null) {
182 next.removeObject(fromCard, objectTest);
183 }
184 }
185
186 /***
187 * Add all static modifiers.
188 *
189 * @param ability
190 * is the ability owning this test. The card component of this
191 * ability should correspond to the card owning this test too.
192 */
193 public void addStaticModifierFromModel(Ability ability) {
194 if (next != null) {
195 next.addStaticModifierFromModel(ability);
196 }
197 }
198
199 /***
200 * When this test is true, this modifier is activated. Otherwise this modifier
201 * does nothing.
202 */
203 protected Test whileCondition;
204
205 /***
206 * The modifier name
207 */
208 protected String name;
209
210 /***
211 * When this event is generated this modifier is removed from the attached
212 * object. If this event is equal to null, this modifier can be removed only
213 * by the attached component.
214 */
215 protected List<MEventListener> until;
216
217 /***
218 * Represents the events forcing this event to be refreshed
219 */
220 protected List<MEventListener> linkedEvents;
221
222 /***
223 * The next register modifier
224 */
225 protected ModifierModel next;
226
227 /***
228 * Indicates this modifier must be destroyed if the creator of this modifier
229 * has been destroyed or has moved
230 */
231 protected boolean linked;
232
233 /***
234 * Is the parameters are recalculated.
235 */
236 protected boolean recalculate;
237
238 /***
239 * Is the strategy used to add this modifier within the existing chain
240 */
241 protected int layer;
242
243 }