View Javadoc

1   /*
2    *    Magic-Project is a turn based strategy simulator
3    *   Copyright (C) 2003-2007 Fabrice Daugan
4    *
5    *   This program is free software; you can redistribute it and/or modify it 
6    * under the terms of the GNU General Public License as published by the Free 
7    * Software Foundation; either version 2 of the License, or (at your option) any
8    * later version.
9    *
10   *   This program is distributed in the hope that it will be useful, but WITHOUT 
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
13   * details.
14   *
15   *   You should have received a copy of the GNU General Public License along  
16   * with this program; if not, write to the Free Software Foundation, Inc., 
17   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   * 
19   * Repeat.java
20   * Created on 20 févr. 2004
21   */
22  package net.sf.magicproject.action;
23  
24  import java.io.IOException;
25  import java.io.InputStream;
26  
27  import net.sf.magicproject.action.context.ActionContextWrapper;
28  import net.sf.magicproject.action.context.Int;
29  import net.sf.magicproject.action.handler.InitAction;
30  import net.sf.magicproject.action.handler.StandardAction;
31  import net.sf.magicproject.clickable.ability.Ability;
32  import net.sf.magicproject.clickable.targetable.Targetable;
33  import net.sf.magicproject.deckbuilder.MdbLoader;
34  import net.sf.magicproject.event.context.ContextEventListener;
35  import net.sf.magicproject.expression.Expression;
36  import net.sf.magicproject.expression.ExpressionFactory;
37  import net.sf.magicproject.stack.StackManager;
38  
39  /***
40   * Repeat the next action n times. If the value is negative or zero, the next
41   * action would be skipped.
42   * 
43   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
44   * @since 0.54
45   */
46  public class Repeat extends UserAction implements StandardAction, InitAction {
47  
48  	/***
49  	 * Create an instance of Repeat by reading a file Offset's file must pointing
50  	 * on the first byte of this action <br>
51  	 * <ul>
52  	 * Structure of InputStream : Data[size]
53  	 * <li>idNumber [2]</li>
54  	 * </ul>
55  	 * 
56  	 * @param inputFile
57  	 *          file containing this action
58  	 * @throws IOException
59  	 *           if error occurred during the reading process from the specified
60  	 *           input stream
61  	 */
62  	Repeat(InputStream inputFile) throws IOException {
63  		super(inputFile);
64  		valueExpr = ExpressionFactory.readNextExpression(inputFile);
65  	}
66  
67  	/***
68  	 * return the id of this action. This action has been read from the mdb file.
69  	 * 
70  	 * @see Actiontype
71  	 * @return the id of this action
72  	 */
73  	@Override
74  	public final Actiontype getIdAction() {
75  		return Actiontype.REPEAT_ACTION;
76  	}
77  
78  	public boolean init(ActionContextWrapper actionContext,
79  			ContextEventListener context, Ability ability) {
80  		actionContext.actionContext = new Int(getRepeatValue(context, ability));
81  		if (((Int) actionContext.actionContext).getInt() == 0) {
82  			StackManager.actionManager.setHop(2);
83  		} else {
84  			StackManager.actionManager.setRepeat(((Int) actionContext.actionContext)
85  					.getInt());
86  		}
87  		return true;
88  	}
89  
90  	public boolean replay(ActionContextWrapper actionContext,
91  			ContextEventListener context, Ability ability) {
92  		// Ignored since the counter is present in context of all replayable actions
93  		return true;
94  	}
95  
96  	/***
97  	 * Replay the next action the amount of context times.
98  	 * 
99  	 * @param actionContext
100 	 *          the context containing data saved by this action during the
101 	 *          'choose" proceess.
102 	 * @param ability
103 	 *          is the ability owning this test. The card component of this
104 	 *          ability should correspond to the card owning this test too.
105 	 * @param context
106 	 *          is the context attached to this action.
107 	 */
108 	public void replayOnDemand(ActionContextWrapper actionContext,
109 			ContextEventListener context, Ability ability) {
110 		StackManager.actionManager.setRepeat(((Int) actionContext.actionContext)
111 				.getInt());
112 	}
113 
114 	public boolean play(ContextEventListener context, Ability ability) {
115 		if (getRepeatValue(context, ability) == 0) {
116 			StackManager.actionManager.setHop(2);
117 		} else {
118 			StackManager.actionManager.setRepeat(getRepeatValue(context, ability));
119 		}
120 		return true;
121 	}
122 
123 	private int getRepeatValue(ContextEventListener context, Ability ability) {
124 		final int value = valueExpr.getValue(ability, null, context);
125 		if (value > 0) {
126 			// enter in the loop
127 			return value;
128 		}
129 		// we would never enter into the loop
130 		return 0;
131 	}
132 
133 	/***
134 	 * return the string representation of this action
135 	 * 
136 	 * @param ability
137 	 *          is the ability owning this test. The card component of this
138 	 *          ability should correspond to the card owning this test too.
139 	 * @return the string representation of this action
140 	 * @see Object#toString()
141 	 */
142 	@Override
143 	public String toString(Ability ability) {
144 		try {
145 			return " x " + valueExpr.getValue(ability, null, null);
146 		} catch (Exception e) {
147 			return " x (*)";
148 		}
149 	}
150 
151 	@Override
152 	public String toHtmlString(Ability ability, ContextEventListener context) {
153 		try {
154 			return " x " + valueExpr.getValue(ability, null, context);
155 		} catch (Exception e) {
156 			return " x " + MdbLoader.unknownSmlManaHtml;
157 		}
158 	}
159 
160 	/***
161 	 * Return nb times to repeat the next action exactly as it will be when the
162 	 * ability will be executed..Return <code>-1</code> if value cannot be
163 	 * pre-empted.
164 	 * 
165 	 * @param ability
166 	 *          is the ability owning this test. The card component of this
167 	 *          ability should correspond to the card owning this test too.
168 	 * @param tested
169 	 *          the tested card
170 	 * @return nb times to repeat the next action.Return <code>-1</code> if
171 	 *         value is not static.
172 	 */
173 	public int getPreemptionTimes(Ability ability, Targetable tested) {
174 		try {
175 			return valueExpr.getPreemptionValue(ability, tested, null);
176 		} catch (Exception e) {
177 			return -1;
178 		}
179 	}
180 
181 	/***
182 	 * represents the number of times to repeat the next action. The complex
183 	 * expression to use for the right value. Is null if the IdToken number is not
184 	 * a complex expression.
185 	 */
186 	private Expression valueExpr;
187 
188 }