View Javadoc

1   /*
2    *   Firemox 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  package net.sf.firemox.event;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import net.sf.firemox.clickable.ability.Ability;
27  import net.sf.firemox.clickable.target.card.AbstractCard;
28  import net.sf.firemox.clickable.target.card.MCard;
29  import net.sf.firemox.clickable.target.card.TriggeredCard;
30  import net.sf.firemox.clickable.target.player.Player;
31  import net.sf.firemox.event.context.ContextEventListener;
32  import net.sf.firemox.network.ConnectionManager;
33  import net.sf.firemox.network.MSocketListener;
34  import net.sf.firemox.network.message.CoreMessageType;
35  import net.sf.firemox.stack.StackManager;
36  import net.sf.firemox.test.Test;
37  import net.sf.firemox.tools.IntegerWrapper;
38  import net.sf.firemox.tools.Log;
39  import net.sf.firemox.ui.MagicUIComponents;
40  import net.sf.firemox.ui.i18n.LanguageManagerMDB;
41  import net.sf.firemox.ui.wizard.Replacement;
42  
43  /***
44   * An event triggered on a game or player event.
45   * 
46   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
47   * @since 0.54
48   */
49  public abstract class TriggeredEvent extends MEventListener {
50  
51  	/***
52  	 * Create an instance of MEventTriggered by reading a file Offset's file must
53  	 * pointing on the first byte of this event <br>
54  	 * <ul>
55  	 * Structure of InputStream : Data[size]
56  	 * <li>idZone [1]</li>
57  	 * <li>test [...]</li>
58  	 * </ul>
59  	 * 
60  	 * @param inputFile
61  	 *          is the file containing this event
62  	 * @param card
63  	 *          is the card owning this event
64  	 * @throws IOException
65  	 *           if error occurred during the reading process from the specified
66  	 *           input stream
67  	 */
68  	public TriggeredEvent(InputStream inputFile, MCard card) throws IOException {
69  		super(inputFile, card);
70  	}
71  
72  	/***
73  	 * Creates a new instance of MEventTriggered specifying all attributes of this
74  	 * class. All parameters are copied, not cloned. So this new object shares the
75  	 * card and the specified codes
76  	 * 
77  	 * @param idZone
78  	 *          the place constraint to activate this event
79  	 * @param test
80  	 *          the additional test of this event
81  	 * @param card
82  	 *          is the card owning this card
83  	 */
84  	protected TriggeredEvent(int idZone, Test test, MCard card) {
85  		super(idZone, test, card);
86  	}
87  
88  	@Override
89  	public abstract MEventListener clone(MCard card);
90  
91  	@Override
92  	public abstract Event getIdEvent();
93  
94  	@Override
95  	public void registerToManager(Ability ability) {
96  		if (TRIGGRED_ABILITIES.get(getIdEvent()) == null) {
97  			TRIGGRED_ABILITIES.put(getIdEvent(), new ArrayList<Ability>(20));
98  			// add this event listener
99  			TRIGGRED_ABILITIES.get(getIdEvent()).add(ability);
100 		} else {
101 			ability.optimizeRegisterToManager();
102 		}
103 	}
104 
105 	/*
106 	 * Create and returns an union of this event and the specified one. Both event
107 	 * must have the same type. Test(s) and events attributes may be grouped
108 	 * depending instance of this event. If no possible append is possible <code>null</code>
109 	 * is returned. @param other the event to append with 'or' operator. @return a
110 	 * new event representing 'this' or 'other'
111 	 */
112 	// TODO public abstract MEventListener appendOr(MEventListener other);
113 	@Override
114 	public void removeFromManager(Ability ability) {
115 		if (TRIGGRED_ABILITIES.get(getIdEvent()) != null) {
116 			// remove this event listener
117 			TRIGGRED_ABILITIES.get(getIdEvent()).remove(ability);
118 		}
119 	}
120 
121 	@Override
122 	public final boolean isActivated() {
123 		return false;
124 	}
125 
126 	@Override
127 	public final boolean isTriggered() {
128 		return true;
129 	}
130 
131 	@Override
132 	public String toHtmlString(Ability ability, ContextEventListener context) {
133 		return LanguageManagerMDB.getString("event-"
134 				+ getClass().getSimpleName().toLowerCase());
135 	}
136 
137 	/***
138 	 * Return true if the current event has not been replaced. If only one
139 	 * replacement ability has been found, it should be used. If several
140 	 * replacement abilities have been found a form containing choice would be
141 	 * displaced.
142 	 * 
143 	 * @param source
144 	 *          the event source.
145 	 * @param result
146 	 *          the found replacement abilities.
147 	 * @param eventName
148 	 *          the current event name.
149 	 * @return true if the current event has not been replaced. False otherwise.
150 	 */
151 	protected static final boolean manageReplacement(MCard source,
152 			List<AbstractCard> result, String eventName) {
153 		if (result != null) {
154 			if (result.size() > 1) {
155 				final Player controller = source.getController();
156 				replacement = new IntegerWrapper(-1);
157 				controller.setHandedPlayer();
158 				if (controller.isYou()) {
159 					Log.debug("You choose a replacement ability to use");
160 					new Replacement(eventName, result).setVisible(true);
161 					ConnectionManager.send(CoreMessageType.REPLACEMENT_ANSWER,
162 							(byte) (Replacement.replacement / 256),
163 							(byte) (Replacement.replacement % 256));
164 				} else {
165 					MagicUIComponents.logListing.append(1,
166 							"choosing a replacement ability to use");
167 					StackManager.noReplayToken.release();
168 					Log.debug("Opponent chooses a replacement ability to use");
169 					// Currently a simple "telnet-like" minimal code treating :
170 					Replacement.replacement = MSocketListener.getInstance()
171 							.readReplacementAnswer();
172 					Log.debug("Replacement : virtual mouseClick");
173 					MagicUIComponents.logListing.append(1, "Chosen replacement : "
174 							+ result.get(Replacement.replacement).toString());
175 				}
176 			} else {
177 				Replacement.replacement = 0;
178 			}
179 
180 			if (StackManager.newSpell((TriggeredCard) result
181 					.get(Replacement.replacement))) {
182 				StackManager.resolveStack();
183 			}
184 			return false;
185 		}
186 		return true;
187 	}
188 
189 	/***
190 	 * The selected replacement ability to use
191 	 */
192 	public static IntegerWrapper replacement;
193 }