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}