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   */
20  package net.sf.firemox.modifier;
21  
22  import java.util.Set;
23  
24  import net.sf.firemox.clickable.target.card.MCard;
25  import net.sf.firemox.expression.Expression;
26  import net.sf.firemox.stack.StackManager;
27  import net.sf.firemox.token.IdConst;
28  
29  /***
30   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
31   * @since 0.86 properties set is calculated as colors/idcard and register : they
32   *        follow timestamp rule.
33   */
34  public class PropertyModifier extends Modifier {
35  
36  	/***
37  	 * Creates a new instance of PropertyModifier without any chain<br>
38  	 * 
39  	 * @param context
40  	 *          the modifier context.
41  	 * @param propertyId
42  	 *          the property to add/remove
43  	 * @param addProperty
44  	 *          Indicates if this modifier remove occurrence of the given
45  	 *          property. If true, it adds one instance.
46  	 */
47  	public PropertyModifier(ModifierContext context, Expression propertyId,
48  			boolean addProperty) {
49  		super(context);
50  		this.propertyId = propertyId;
51  		this.addProperty = addProperty;
52  	}
53  
54  	@Override
55  	public Modifier removeModifier(Modifier modifier) {
56  		if (this == modifier) {
57  			if (activated) {
58  				StackManager.postRefreshProperties(to, propertyId.getValue(ability, to,
59  						null));
60  			}
61  			return next;
62  		}
63  		return super.removeModifier(modifier);
64  	}
65  
66  	@Override
67  	public final void removeFromManager() {
68  		super.removeFromManager();
69  		if (!unregisteredModifier) {
70  			to.removeModifier(this);
71  		}
72  		unregisteredModifier = true;
73  	}
74  
75  	/***
76  	 * Tells if this modifier add/remove the given property.
77  	 * 
78  	 * @param propertyId
79  	 *          the matched property
80  	 * @param found
81  	 *          indicates that the property has been previously found.
82  	 * @return true if this modifier add/remove the given property.
83  	 */
84  	public boolean hasProperty(int propertyId, boolean found) {
85  		if (activated) {
86  			final int newPropertyId = this.propertyId.getValue(ability, to, null);
87  			if (newPropertyId == IdConst.ALL && !addProperty) {
88  				if (next != null) {
89  					return ((PropertyModifier) next).hasProperty(propertyId, false);
90  				}
91  				return false;
92  			}
93  			if (newPropertyId == propertyId) {
94  				if (next != null) {
95  					return ((PropertyModifier) next).hasProperty(propertyId, addProperty);
96  				}
97  				return addProperty;
98  			}
99  		}
100 		if (next != null) {
101 			return ((PropertyModifier) next).hasProperty(propertyId, found);
102 		}
103 		return found;
104 	}
105 
106 	/***
107 	 * Tells if this modifier add/remove the given property ignoring these given
108 	 * by the specified card <code>creator</code>.
109 	 * 
110 	 * @param propertyId
111 	 *          the matched property
112 	 * @param found
113 	 *          indicates that the property has been previously found
114 	 * @param creator
115 	 *          is the card created modifiers would be ignored
116 	 * @return true if this modifier add/remove the given property ignoring these
117 	 *         given by the specified card <code>creator</code>.
118 	 */
119 	public boolean hasPropertyNotFromCreator(int propertyId, boolean found,
120 			MCard creator) {
121 		if (activated && creator != this.ability.getCard()) {
122 			int newPropertyId = this.propertyId.getValue(ability, to, null);
123 			if (newPropertyId == IdConst.ALL && !addProperty) {
124 				if (next != null) {
125 					return ((PropertyModifier) next).hasPropertyNotFromCreator(
126 							propertyId, addProperty, creator);
127 				}
128 				return false;
129 			}
130 			if (newPropertyId == propertyId) {
131 				if (next != null) {
132 					return ((PropertyModifier) next).hasPropertyNotFromCreator(
133 							propertyId, addProperty, creator);
134 				}
135 			}
136 			return addProperty;
137 		}
138 		if (next != null) {
139 			return ((PropertyModifier) next).hasPropertyNotFromCreator(propertyId,
140 					found, creator);
141 		}
142 		return found;
143 	}
144 
145 	/***
146 	 * Add/remove the specified set by the manipulated properties of this
147 	 * modifier.
148 	 * 
149 	 * @param workSet
150 	 *          the set of properties already found
151 	 */
152 	public void fillProperties(Set<Integer> workSet) {
153 		if (activated) {
154 			if (addProperty) {
155 				workSet.add(propertyId.getValue(ability, to, null));
156 			} else {
157 				final int propertyId = this.propertyId.getValue(ability, to, null);
158 				if (IdConst.ALL == propertyId)
159 					workSet.clear();
160 				else {
161 					workSet.remove(propertyId);
162 				}
163 			}
164 		}
165 		if (next != null) {
166 			((PropertyModifier) next).fillProperties(workSet);
167 		}
168 	}
169 
170 	@Override
171 	public void refresh() {
172 		final boolean oldActivated = activated;
173 		activated = whileCondition.test(ability, to);
174 
175 		// this property has changed
176 		if (oldActivated != activated) {
177 			StackManager.postRefreshProperties(to, propertyId.getValue(ability, to,
178 					null));
179 		}
180 	}
181 
182 	/***
183 	 * Indicates if this modifier remove occurrence of the given property. If
184 	 * True, it adds one instance of this property.
185 	 */
186 	protected boolean addProperty;
187 
188 	/***
189 	 * Property to add/remove
190 	 */
191 	protected Expression propertyId;
192 
193 }