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         }