001package com.fs.starfarer.api.loading;
002
003import java.awt.Color;
004
005import org.json.JSONException;
006import org.json.JSONObject;
007
008import com.fs.starfarer.api.combat.CollisionClass;
009import com.fs.starfarer.api.combat.DamageType;
010import com.fs.starfarer.api.combat.MutableStat;
011import com.fs.starfarer.api.combat.OnHitEffectPlugin;
012import com.fs.starfarer.api.combat.ShipAPI;
013import com.fs.starfarer.api.impl.campaign.ids.Stats;
014import com.fs.starfarer.api.util.Misc;
015
016public class DamagingExplosionSpec implements Cloneable {
017
018        private float duration;
019        private float radius;
020        private float coreRadius;
021        private float maxDamage;
022        private float minDamage;
023        
024        private float maxEMPDamage;
025        private float minEMPDamage;
026        
027        
028        private float particleSpawnRadius = -1f;
029        
030        private CollisionClass collisionClass;
031        private CollisionClass collisionClassByFighter;
032        
033        
034        private float particleSizeMin = 10f;
035        private float particleSizeRange = 10f;
036        private float particleDuration = 0.5f;
037        private int particleCount = 10;
038        
039        private Color particleColor = new Color(255,255,255,255);
040        private Color explosionColor = new Color(255,255,255,255);
041
042        private DamageType damageType = DamageType.ENERGY;
043        private String soundSetId;
044        private float soundVolume = 1f;
045        
046        private boolean showGraphic = true;
047        private boolean useDetailedExplosion = true;
048        
049        private float detailedExplosionRadius = -1f;
050        private float detailedExplosionFlashRadius = -1f;
051        private Color detailedExplosionFlashColorFringe = null;
052        private Color detailedExplosionFlashColorCore = null;
053        private float detailedExplosionFlashDuration = -1f;
054        
055        private OnHitEffectPlugin effect;
056        
057        private MutableStat modifier = new MutableStat(1f);
058        
059        public static float getShipExplosionRadius(ShipAPI ship) {
060                float mult = ship.getMutableStats().getDynamic().getValue(Stats.EXPLOSION_RADIUS_MULT);
061                //float mult = 1f;
062//              if (ship.isStationModule()) {
063//                      mult = 0.5f;
064//              }
065                float radius = ship.getCollisionRadius() + Math.min(200f, ship.getCollisionRadius()) * mult;
066                return radius;
067        }
068        
069        public static DamagingExplosionSpec explosionSpecForShip(ShipAPI ship) {
070                float radius = getShipExplosionRadius(ship);
071                float coreRadius = ship.getCollisionRadius();
072                
073                float maxDamage = ship.getMaxFlux() * (0.5f + 0.5f * (float) Math.random());
074                float minDamage = 0f;
075
076                float mult = ship.getMutableStats().getDynamic().getValue(Stats.EXPLOSION_DAMAGE_MULT);
077                maxDamage *= mult;
078                
079                DamagingExplosionSpec spec = new DamagingExplosionSpec(0.1f, 
080                                                                                                                          radius,
081                                                                                                                          coreRadius,
082                                                                                                                          maxDamage,
083                                                                                                                          minDamage,
084                                                                                                                          CollisionClass.HITS_SHIPS_AND_ASTEROIDS,
085                                                                                                                          CollisionClass.HITS_SHIPS_AND_ASTEROIDS, // irrelevant - no explosion for fighters
086                                                                                                                          10f,
087                                                                                                                          10f,
088                                                                                                                          1f,
089                                                                                                                          0,
090                                                                                                                          Color.white, Color.white);
091                spec.setShowGraphic(false);
092                spec.setDamageType(DamageType.HIGH_EXPLOSIVE);
093                return spec;
094        }
095        
096        public OnHitEffectPlugin getEffect() {
097                return effect;
098        }
099
100        public void setEffect(OnHitEffectPlugin effect) {
101                this.effect = effect;
102        }
103
104        public String getSoundSetId() {
105                return soundSetId;
106        }
107        public void setSoundSetId(String soundSetId) {
108                this.soundSetId = soundSetId;
109        }
110
111        public static DamagingExplosionSpec loadFromJSON(JSONObject explosionSpecJson) throws JSONException {
112                if (explosionSpecJson != null) {
113                        DamagingExplosionSpec spec = new DamagingExplosionSpec(
114                                        (float) explosionSpecJson.getDouble("duration"),
115                                        (float) explosionSpecJson.getDouble("radius"),
116                                        (float) explosionSpecJson.getDouble("coreRadius"),
117                                        (float) explosionSpecJson.optDouble("maxDamage", 0),
118                                        (float) explosionSpecJson.optDouble("minDamage", 0),
119                                        Misc.mapToEnum(explosionSpecJson, "collisionClass", CollisionClass.class, null),
120                                        Misc.mapToEnum(explosionSpecJson, "collisionClassByFighter", CollisionClass.class, null),                                       
121                                        (float) explosionSpecJson.optDouble("particleSizeMin", 0),
122                                        (float) explosionSpecJson.optDouble("particleSizeRange", 0),
123                                        (float) explosionSpecJson.optDouble("particleDuration", 0),
124                                        explosionSpecJson.optInt("particleCount", 0),
125                                        Misc.getColor(explosionSpecJson, "particleColor"),
126                                        Misc.optColor(explosionSpecJson, "explosionColor", null)
127                        );
128
129                        spec.useDetailedExplosion = explosionSpecJson.optBoolean("useDetailedExplosion", false);
130                        
131                        spec.detailedExplosionRadius = (float) explosionSpecJson.optDouble("detailedExplosionRadius", -1f);
132                        spec.detailedExplosionFlashRadius = (float) explosionSpecJson.optDouble("detailedExplosionFlashRadius", -1f);
133                        spec.detailedExplosionFlashDuration = (float) explosionSpecJson.optDouble("detailedExplosionFlashDuration", -1f);
134                        spec.detailedExplosionFlashColorFringe = Misc.optColor(explosionSpecJson, "detailedExplosionFlashColorFringe", null);
135                        spec.detailedExplosionFlashColorCore = Misc.optColor(explosionSpecJson, "detailedExplosionFlashColorCore", null);
136                        spec.soundVolume = (float) explosionSpecJson.optDouble("soundVolume", 1f);
137                        
138                        spec.particleSpawnRadius = (float) explosionSpecJson.optDouble("particleSpawnRadius", -1f);
139                        
140                        
141                        if (spec.getParticleCount() == 0) {
142                                spec.setShowGraphic(false);
143                        }
144                        spec.setSoundSetId(explosionSpecJson.optString("sound", null));
145                        return spec;
146                }
147                return null;
148        }
149
150        public DamagingExplosionSpec(float duration, float radius, float coreRadius,
151                                                                float maxDamage, float minDamage, CollisionClass collisionClass,
152                                                                CollisionClass collisionClassByFighter,
153                                                                float particleSizeMin, float particleSizeRange,
154                                                                float particleDuration, int particleCount, Color particleColor, Color explosionColor) {
155                this.duration = duration;
156                this.radius = radius;
157                this.coreRadius = coreRadius;
158                this.maxDamage = maxDamage;
159                this.minDamage = minDamage;
160                this.collisionClass = collisionClass;
161                this.collisionClassByFighter = collisionClassByFighter;
162                this.particleSizeMin = particleSizeMin;
163                this.particleSizeRange = particleSizeRange;
164                this.particleDuration = particleDuration;
165                this.particleCount = particleCount;
166                this.particleColor = particleColor;
167                if (explosionColor != null) {
168                        this.explosionColor = explosionColor;
169                } else {
170                        this.explosionColor = particleColor;
171                }
172        }
173        
174        public float getParticleSpawnRadius() {
175                return particleSpawnRadius;
176        }
177
178        public void setParticleSpawnRadius(float particleSpawnRadius) {
179                this.particleSpawnRadius = particleSpawnRadius;
180        }
181
182        public Color getExplosionColor() {
183                return explosionColor;
184        }
185        
186        public void setExplosionColor(Color explosionColor) {
187                this.explosionColor = explosionColor;
188        }
189
190        public DamageType getDamageType() {
191                return damageType;
192        }
193
194        public void setDamageType(DamageType damageType) {
195                this.damageType = damageType;
196        }
197
198        public float getDuration() {
199                return duration;
200        }
201
202        public void setDuration(float duration) {
203                this.duration = duration;
204        }
205
206        public float getRadius() {
207                return radius;
208        }
209
210        public void setRadius(float radius) {
211                this.radius = radius;
212        }
213
214        public float getMaxDamage() {
215                return maxDamage;
216        }
217
218        public void setMaxDamage(float maxDamage) {
219                this.maxDamage = maxDamage;
220        }
221
222        public float getMinDamage() {
223                return minDamage;
224        }
225
226        public void setMinDamage(float minDamage) {
227                this.minDamage = minDamage;
228        }
229
230        public CollisionClass getCollisionClass() {
231                return collisionClass;
232        }
233
234        public void setCollisionClass(CollisionClass collisionClass) {
235                this.collisionClass = collisionClass;
236        }
237
238        public CollisionClass getCollisionClassIfByFighter() {
239                return collisionClassByFighter;
240        }
241
242        public void setCollisionClassByFighter(CollisionClass collisionClassByFighter) {
243                this.collisionClassByFighter = collisionClassByFighter;
244        }
245
246        public float getParticleSizeMin() {
247                return particleSizeMin;
248        }
249
250        public void setParticleSizeMin(float particleSizeMin) {
251                this.particleSizeMin = particleSizeMin;
252        }
253
254        public float getParticleSizeRange() {
255                return particleSizeRange;
256        }
257
258        public void setParticleSizeRange(float particleSizeRange) {
259                this.particleSizeRange = particleSizeRange;
260        }
261
262        public float getParticleDuration() {
263                return particleDuration;
264        }
265
266        public void setParticleDuration(float particleDuration) {
267                this.particleDuration = particleDuration;
268        }
269
270        public int getParticleCount() {
271                return particleCount;
272        }
273
274        public void setParticleCount(int particleCount) {
275                this.particleCount = particleCount;
276        }
277
278        public Color getParticleColor() {
279                return particleColor;
280        }
281
282        public void setParticleColor(Color particleColor) {
283                this.particleColor = particleColor;
284        }
285
286        public float getCoreRadius() {
287                return coreRadius;
288        }
289
290        public void setCoreRadius(float coreRadius) {
291                this.coreRadius = coreRadius;
292        }
293
294
295        public boolean isShowGraphic() {
296                return showGraphic;
297        }
298
299
300        public void setShowGraphic(boolean showGraphic) {
301                this.showGraphic = showGraphic;
302        }
303
304        @Override
305        public DamagingExplosionSpec clone() {
306                try {
307                        return (DamagingExplosionSpec) super.clone();
308                } catch (CloneNotSupportedException e) {
309                        return null; // can't happen
310                }
311        }
312
313        public boolean isUseDetailedExplosion() {
314                return useDetailedExplosion;
315        }
316
317        public void setUseDetailedExplosion(boolean useDetailedExplosion) {
318                this.useDetailedExplosion = useDetailedExplosion;
319        }
320
321        public CollisionClass getCollisionClassByFighter() {
322                return collisionClassByFighter;
323        }
324
325        public MutableStat getModifier() {
326                return modifier;
327        }
328
329        public void setModifier(MutableStat modifier) {
330                this.modifier = modifier;
331        }
332
333        public float getDetailedExplosionRadius() {
334                return detailedExplosionRadius;
335        }
336
337        public void setDetailedExplosionRadius(float detailedExplosionRadius) {
338                this.detailedExplosionRadius = detailedExplosionRadius;
339        }
340
341        public float getDetailedExplosionFlashRadius() {
342                return detailedExplosionFlashRadius;
343        }
344
345        public void setDetailedExplosionFlashRadius(float detailedExplosionFlashRadius) {
346                this.detailedExplosionFlashRadius = detailedExplosionFlashRadius;
347        }
348
349        public Color getDetailedExplosionFlashColorFringe() {
350                return detailedExplosionFlashColorFringe;
351        }
352
353        public void setDetailedExplosionFlashColorFringe(Color detailedExplosionFlashColorFringe) {
354                this.detailedExplosionFlashColorFringe = detailedExplosionFlashColorFringe;
355        }
356
357        public Color getDetailedExplosionFlashColorCore() {
358                return detailedExplosionFlashColorCore;
359        }
360
361        public void setDetailedExplosionFlashColorCore(Color detailedExplosionFlashColorCore) {
362                this.detailedExplosionFlashColorCore = detailedExplosionFlashColorCore;
363        }
364
365        public float getDetailedExplosionFlashDuration() {
366                return detailedExplosionFlashDuration;
367        }
368
369        public void setDetailedExplosionFlashDuration(float detailedExplosionFlashDuration) {
370                this.detailedExplosionFlashDuration = detailedExplosionFlashDuration;
371        }
372
373        public float getSoundVolume() {
374                return soundVolume;
375        }
376
377        public void setSoundVolume(float soundVolume) {
378                this.soundVolume = soundVolume;
379        }
380
381        public float getMaxEMPDamage() {
382                return maxEMPDamage;
383        }
384
385        public void setMaxEMPDamage(float maxEMPDamage) {
386                this.maxEMPDamage = maxEMPDamage;
387        }
388
389        public float getMinEMPDamage() {
390                return minEMPDamage;
391        }
392
393        public void setMinEMPDamage(float minEMPDamage) {
394                this.minEMPDamage = minEMPDamage;
395        }
396}