View Javadoc

1   /*
2    * Created on Nov 9, 2004 
3    * Original filename was CreateAbility.java
4    * 
5    *   Magic-Project is a turn based strategy simulator
6    *   Copyright (C) 2003-2007 Fabrice Daugan
7    *
8    *   This program is free software; you can redistribute it and/or modify it 
9    * under the terms of the GNU General Public License as published by the Free 
10   * Software Foundation; either version 2 of the License, or (at your option) any
11   * later version.
12   *
13   *   This program is distributed in the hope that it will be useful, but WITHOUT 
14   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
16   * details.
17   *
18   *   You should have received a copy of the GNU General Public License along  
19   * with this program; if not, write to the Free Software Foundation, Inc., 
20   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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  		// until events
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 		// Intialize registers of this ability. The first 'saved' target is used
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 		// create the delayed card, and put it into the right DBZ
124 		StackManager.getSpellController().zoneManager.delayedBuffer
125 				.add(new DelayedCard(clonedAbility, abilities, parsedRegisters, save1
126 						.getTargetable(ability, owner), save2.getTargetable(ability, owner)));
127 
128 		// create the 'until' triggers of this ability
129 		for (MEventListener event : until) {
130 			abilities.add(new RemoveModifier((TriggeredEvent) event, clonedAbility));
131 		}
132 
133 		// register the created 'until' triggers of this ability
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 }