001 package com.croftsoft.apps.mars.model.seri;
002
003 import java.awt.Shape;
004 import java.io.Serializable;
005
006 import com.croftsoft.core.lang.NullArgumentException;
007 import com.croftsoft.core.math.geom.Circle;
008
009 import com.croftsoft.apps.mars.model.AmmoDump;
010 import com.croftsoft.apps.mars.model.Damageable;
011 import com.croftsoft.apps.mars.model.World;
012
013 /*********************************************************************
014 * An ammunition dump.
015 *
016 * @version
017 * 2003-05-12
018 * @since
019 * 2003-03-30
020 * @author
021 * <a href="https://www.croftsoft.com/">David Wallace Croft</a>
022 *********************************************************************/
023
024 public final class SeriAmmoDump
025 extends SeriModel
026 implements AmmoDump
027 //////////////////////////////////////////////////////////////////////
028 //////////////////////////////////////////////////////////////////////
029 {
030
031 private static final long serialVersionUID = 0L;
032
033 //////////////////////////////////////////////////////////////////////
034 // static member class
035 //////////////////////////////////////////////////////////////////////
036
037 public static final class Shared
038 implements Serializable
039 //////////////////////////////////////////////////////////////////////
040 //////////////////////////////////////////////////////////////////////
041 {
042
043 private static final long serialVersionUID = 0L;
044
045 //
046
047 public static final double DEFAULT_AMMO_GROWTH_RATE = 0.5;
048
049 public static final double DEFAULT_AMMO_MAX = 30.0;
050
051 public static final double DEFAULT_EXPLOSION_FACTOR = 3.0;
052
053 public static final double DEFAULT_Z = 0.1;
054
055 //
056
057 public final double ammoGrowthRate;
058
059 public final double ammoMax;
060
061 public final double explosionFactor;
062
063 public final double z;
064
065 //////////////////////////////////////////////////////////////////////
066 //////////////////////////////////////////////////////////////////////
067
068 public Shared (
069 double ammoGrowthRate,
070 double ammoMax,
071 double explosionFactor,
072 double z )
073 //////////////////////////////////////////////////////////////////////
074 {
075 this.ammoGrowthRate = ammoGrowthRate;
076
077 this.ammoMax = ammoMax;
078
079 this.explosionFactor = explosionFactor;
080
081 this.z = z;
082 }
083
084 public Shared ( )
085 //////////////////////////////////////////////////////////////////////
086 {
087 this (
088 DEFAULT_AMMO_GROWTH_RATE,
089 DEFAULT_AMMO_MAX,
090 DEFAULT_EXPLOSION_FACTOR,
091 DEFAULT_Z );
092 }
093
094 //////////////////////////////////////////////////////////////////////
095 //////////////////////////////////////////////////////////////////////
096 }
097
098 //////////////////////////////////////////////////////////////////////
099 // instance variables
100 //////////////////////////////////////////////////////////////////////
101
102 private final Circle circle;
103
104 private final Shared shared;
105
106 private final World world;
107
108 private final Circle explosionCircle;
109
110 //
111
112 private double ammo;
113
114 private Damageable [ ] damageables;
115
116 private boolean exploding;
117
118 private boolean updated;
119
120 //////////////////////////////////////////////////////////////////////
121 // constructor method
122 //////////////////////////////////////////////////////////////////////
123
124 public SeriAmmoDump (
125 World world,
126 double centerX,
127 double centerY,
128 double ammo,
129 Shared shared )
130 //////////////////////////////////////////////////////////////////////
131 {
132 NullArgumentException.check ( this.world = world );
133
134 circle = new Circle ( );
135
136 setCenter ( centerX, centerY );
137
138 setAmmo ( ammo );
139
140 NullArgumentException.check ( this.shared = shared );
141
142 damageables = new Damageable [ 0 ];
143
144 explosionCircle = new Circle ( );
145 }
146
147 //////////////////////////////////////////////////////////////////////
148 // interface ModelAccessor methods
149 //////////////////////////////////////////////////////////////////////
150
151 public boolean isActive ( ) { return true; }
152
153 public Shape getShape ( ) { return circle; }
154
155 public boolean isUpdated ( ) { return updated; }
156
157 public double getZ ( ) { return shared.z; }
158
159 //////////////////////////////////////////////////////////////////////
160 // interface Model methods
161 //////////////////////////////////////////////////////////////////////
162
163 public void setCenter (
164 double x,
165 double y )
166 //////////////////////////////////////////////////////////////////////
167 {
168 circle.setCenter ( x, y );
169 }
170
171 public void prepare ( )
172 //////////////////////////////////////////////////////////////////////
173 {
174 updated = false;
175
176 exploding = false;
177 }
178
179 public void update ( double timeDelta )
180 //////////////////////////////////////////////////////////////////////
181 {
182 if ( !exploding )
183 {
184 double newAmmo = ammo + timeDelta * shared.ammoGrowthRate;
185
186 if ( newAmmo > shared.ammoMax )
187 {
188 newAmmo = shared.ammoMax;
189 }
190 else if ( newAmmo < 0.0 )
191 {
192 newAmmo = 0.0;
193 }
194
195 setAmmo ( newAmmo );
196 }
197 }
198
199 //////////////////////////////////////////////////////////////////////
200 // interface Damageable method
201 //////////////////////////////////////////////////////////////////////
202
203 public void addDamage ( double damage )
204 //////////////////////////////////////////////////////////////////////
205 {
206 if ( exploding )
207 {
208 return;
209 }
210
211 updated = true;
212
213 exploding = true;
214
215 explosionCircle.setCenter ( circle.getCenter ( ) );
216
217 explosionCircle.setRadius ( shared.explosionFactor * ammo );
218
219 damageables
220 = world.getDamageables ( explosionCircle, damageables );
221
222 for ( int i = 0; i < damageables.length; i++ )
223 {
224 Damageable damageable = damageables [ i ];
225
226 if ( damageable == null )
227 {
228 break;
229 }
230
231 damageable.addDamage ( ammo );
232 }
233
234 setAmmo ( 0.0 );
235 }
236
237 //////////////////////////////////////////////////////////////////////
238 // interface AmmoDumpAccessor methods
239 //////////////////////////////////////////////////////////////////////
240
241 public double getAmmo ( ) { return ammo; }
242
243 public boolean isExploding ( ) { return exploding; }
244
245 public Shape getExplosionShape ( ) { return explosionCircle; }
246
247 //////////////////////////////////////////////////////////////////////
248 // interface AmmoDump method
249 //////////////////////////////////////////////////////////////////////
250
251 public void setAmmo ( double ammo )
252 //////////////////////////////////////////////////////////////////////
253 {
254 if ( this.ammo == ammo )
255 {
256 return;
257 }
258
259 this.ammo = ammo;
260
261 updated = true;
262
263 if ( ammo > 0.0 )
264 {
265 circle.setRadius ( ammo );
266 }
267 else
268 {
269 circle.setRadius ( 0.0 );
270 }
271 }
272
273 //////////////////////////////////////////////////////////////////////
274 //////////////////////////////////////////////////////////////////////
275 }