View Javadoc

1   /*
2    * 
3    *   Magic-Project is a turn based strategy simulator
4    *   Copyright (C) 2003-2007 Fabrice Daugan
5    *
6    *   This program is free software; you can redistribute it and/or modify it 
7    * under the terms of the GNU General Public License as published by the Free 
8    * Software Foundation; either version 2 of the License, or (at your option) any
9    * later version.
10   *
11   *   This program is distributed in the hope that it will be useful, but WITHOUT 
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
14   * details.
15   *
16   *   You should have received a copy of the GNU General Public License along  
17   * with this program; if not, write to the Free Software Foundation, Inc., 
18   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   * 
20   */
21  package net.sf.magicproject.action;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import net.sf.magicproject.action.handler.StandardAction;
29  import net.sf.magicproject.clickable.ability.Ability;
30  import net.sf.magicproject.clickable.targetable.Targetable;
31  import net.sf.magicproject.event.context.ContextEventListener;
32  import net.sf.magicproject.stack.EventManager;
33  import net.sf.magicproject.stack.StackManager;
34  import net.sf.magicproject.test.Test;
35  import net.sf.magicproject.test.TestFactory;
36  import net.sf.magicproject.token.IdTokens;
37  import net.sf.magicproject.token.Register;
38  import net.sf.magicproject.tools.Log;
39  import net.sf.magicproject.tools.MToolKit;
40  
41  /***
42   * Add a random valid target in the list following the specified type. No event
43   * is generated. The friendly test, and the type are required to list the valids
44   * targets. The target list is used by the most actions. <br>
45   * For example, if the next action 'damage', a random card/player from the
46   * target list would be damaged. When a new ability is added to the stack, a new
47   * list is created and attached to it. Actions may modify, acceess it until the
48   * ability is completely resolved.
49   * 
50   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
51   * @since 0.90
52   */
53  class TargetRandomNoEvent extends UserAction implements StandardAction {
54  
55  	/***
56  	 * Create an instance by reading a file Offset's file must pointing on the
57  	 * first byte of this action <br>
58  	 * <ul>
59  	 * Structure of InputStream : Data[size]
60  	 * <li>type [Register]</li>
61  	 * <li>test [Test]</li>
62  	 * <li>restriction Zone id [int]</li>
63  	 * <li>can be preempted [boolean]</li>
64  	 * </ul>
65  	 * For the available options, see interface IdTargets
66  	 * 
67  	 * @param inputFile
68  	 *          file containing this action
69  	 * @throws IOException
70  	 *           if error occurred during the reading process from the specified
71  	 *           input stream
72  	 * @see net.sf.magicproject.token.IdTargets
73  	 */
74  	TargetRandomNoEvent(InputStream inputFile) throws IOException {
75  		super(inputFile);
76  		type = Register.deserialize(inputFile).ordinal();
77  		test = TestFactory.readNextTest(inputFile);
78  		restrictionZone = inputFile.read() - 1;
79  		// consume the no needed preemption value
80  		inputFile.read();
81  	}
82  
83  	public final boolean play(ContextEventListener context, Ability ability) {
84  		String targetTxt = null;
85  		Targetable random = null;
86  		switch (type) {
87  		case IdTokens.PLAYER:
88  			// Target is a player
89  			targetTxt = "[random players]";
90  			if (test
91  					.test(ability, StackManager.PLAYERS[StackManager.idCurrentPlayer])) {
92  				if (test.test(ability,
93  						StackManager.PLAYERS[1 - StackManager.idCurrentPlayer])) {
94  					random = StackManager.PLAYERS[MToolKit.getRandom(1)];
95  				} else {
96  					random = StackManager.PLAYERS[StackManager.idCurrentPlayer];
97  				}
98  			} else if (test.test(ability,
99  					StackManager.PLAYERS[1 - StackManager.idCurrentPlayer])) {
100 				random = StackManager.PLAYERS[1 - StackManager.idCurrentPlayer];
101 			}
102 			break;
103 		case IdTokens.CARD:
104 			// Target is a card
105 			targetTxt = "[random cards]";
106 			final List<Targetable> validTargets = new ArrayList<Targetable>();
107 			if (restrictionZone != -1) {
108 				StackManager.PLAYERS[StackManager.idCurrentPlayer].zoneManager
109 						.getContainer(restrictionZone).checkAllCardsOf(test, validTargets,
110 								ability);
111 				StackManager.PLAYERS[1 - StackManager.idCurrentPlayer].zoneManager
112 						.getContainer(restrictionZone).checkAllCardsOf(test, validTargets,
113 								ability);
114 			} else {
115 				StackManager.PLAYERS[StackManager.idCurrentPlayer].zoneManager
116 						.checkAllCardsOf(test, validTargets, ability);
117 				StackManager.PLAYERS[1 - StackManager.idCurrentPlayer].zoneManager
118 						.checkAllCardsOf(test, validTargets, ability);
119 			}
120 			random = validTargets.get(MToolKit.getRandom(validTargets.size()));
121 			break;
122 		default:
123 			throw new InternalError("Unknown type :" + type);
124 		}
125 		Log.debug("random mode, targetable=" + random);
126 		EventManager.moreInfoLbl.setText(targetTxt + " - random mode)");
127 		if (random != null) {
128 			StackManager.getInstance().getTargetedList().list.add(random);
129 		}
130 		// continue the stack process
131 		return true;
132 	}
133 
134 	@Override
135 	public final Actiontype getIdAction() {
136 		return Actiontype.TARGET_RANDOM;
137 	}
138 
139 	@Override
140 	public String toString(Ability ability) {
141 		switch (type) {
142 		case IdTokens.CARD:
143 			return "[random cards]";
144 		case IdTokens.PLAYER:
145 			return "[random players]";
146 		default:
147 			throw new InternalError("Unknown type : " + type);
148 		}
149 	}
150 
151 	/***
152 	 * represents the test applied to target before to be added to the list
153 	 */
154 	protected Test test;
155 
156 	/***
157 	 * represents the type of target (player, card, dealtable)
158 	 * 
159 	 * @see net.sf.magicproject.token.IdTargets
160 	 */
161 	protected int type;
162 
163 	/***
164 	 * The zone identifant where the scan is restricted. If is equal to -1, there
165 	 * would be no restriction zone.
166 	 * 
167 	 * @see net.sf.magicproject.token.IdZones
168 	 */
169 	protected int restrictionZone;
170 }