Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package data.scripts.plugins;
- import com.fs.starfarer.api.Global;
- import com.fs.starfarer.api.combat.CombatEngineAPI;
- import com.fs.starfarer.api.combat.EveryFrameCombatPlugin;
- import com.fs.starfarer.api.combat.ShipAPI;
- import com.fs.starfarer.api.combat.ShipAPI.HullSize;
- import com.fs.starfarer.api.input.InputEventAPI;
- import com.fs.starfarer.api.util.IntervalUtil;
- import java.awt.Color;
- import java.util.*;
- import data.scripts.util.AnamorphicFlare;
- import org.dark.shaders.distortion.DistortionShader;
- import org.dark.shaders.distortion.RippleDistortion;
- import org.dark.shaders.light.LightShader;
- import org.dark.shaders.light.StandardLight;
- import org.lwjgl.util.vector.Vector2f;
- import org.lazywizard.lazylib.CollisionUtils;
- import org.lazywizard.lazylib.combat.entities.AnchoredEntity;
- public class ShipDestructionEffects implements EveryFrameCombatPlugin {
- private CombatEngineAPI engine;
- private static final Set<ShipAPI> deadShips = new LinkedHashSet<>(); // Faster for what we're doing
- private static final List<ExplodingShip> explodingShips = new ArrayList<>();
- private static final Map<HullSize, Float> explosionLength = new HashMap<>();
- static {
- explosionLength.put(HullSize.FIGHTER, 0.5f);
- explosionLength.put(HullSize.FRIGATE, 2.5f);
- explosionLength.put(HullSize.DESTROYER, 5f);
- explosionLength.put(HullSize.DEFAULT, 5f);
- explosionLength.put(HullSize.CRUISER, 7.5f);
- explosionLength.put(HullSize.CAPITAL_SHIP, 10f);
- }
- private static final Map<HullSize, Float> explosionSizeMod = new HashMap<>();
- static {
- explosionSizeMod.put(HullSize.FIGHTER, 0.5f);
- explosionSizeMod.put(HullSize.FRIGATE, 0.75f);
- explosionSizeMod.put(HullSize.DESTROYER, 1f);
- explosionSizeMod.put(HullSize.DEFAULT, 1f);
- explosionSizeMod.put(HullSize.CRUISER, 1.25f);
- explosionSizeMod.put(HullSize.CAPITAL_SHIP, 1.5f);
- }
- private static final Map<HullSize, Float> flareBrightness = new HashMap<>();
- static {
- flareBrightness.put(HullSize.FIGHTER, 10f);
- flareBrightness.put(HullSize.FRIGATE, 25f);
- flareBrightness.put(HullSize.DESTROYER, 50f);
- flareBrightness.put(HullSize.DEFAULT, 50f);
- flareBrightness.put(HullSize.CRUISER, 100f);
- flareBrightness.put(HullSize.CAPITAL_SHIP, 250f);
- }
- private static final Map<HullSize, Float> flareThickness = new HashMap<>();
- static {
- flareThickness.put(HullSize.FIGHTER, 0.33f);
- flareThickness.put(HullSize.FRIGATE, 0.10f);
- flareThickness.put(HullSize.DESTROYER, 0.06f);
- flareThickness.put(HullSize.DEFAULT, 0.06f);
- flareThickness.put(HullSize.CRUISER, 0.04f);
- flareThickness.put(HullSize.CAPITAL_SHIP, 0.01f);
- }
- private static final Map<HullSize, Float> lightDuration = new HashMap<>();
- static {
- lightDuration.put(HullSize.FIGHTER, 0f);
- lightDuration.put(HullSize.FRIGATE, 0.5f);
- lightDuration.put(HullSize.DESTROYER, 1f);
- lightDuration.put(HullSize.DEFAULT, 1f);
- lightDuration.put(HullSize.CRUISER, 1.5f);
- lightDuration.put(HullSize.CAPITAL_SHIP, 2f);
- }
- private static final Map<HullSize, Float> lightIntensity = new HashMap<>();
- static {
- lightIntensity.put(HullSize.FIGHTER, 0.5f);
- lightIntensity.put(HullSize.FRIGATE, 1f);
- lightIntensity.put(HullSize.DESTROYER, 1.5f);
- lightIntensity.put(HullSize.DEFAULT, 1.5f);
- lightIntensity.put(HullSize.CRUISER, 1.75f);
- lightIntensity.put(HullSize.CAPITAL_SHIP, 2f);
- }
- private static final Map<HullSize, Float> rippleLength = new HashMap<>();
- static {
- rippleLength.put(HullSize.FIGHTER, 0.5f);
- rippleLength.put(HullSize.FRIGATE, 0.75f);
- rippleLength.put(HullSize.DESTROYER, 1f);
- rippleLength.put(HullSize.DEFAULT, 1f);
- rippleLength.put(HullSize.CRUISER, 1.25f);
- rippleLength.put(HullSize.CAPITAL_SHIP, 1.5f);
- }
- @Override
- public void init(CombatEngineAPI engine) {
- }
- private final IntervalUtil interval = new IntervalUtil(0.1f, 0.1f);
- @Override
- public void advance(float amount, List<InputEventAPI> events) {
- if (engine != Global.getCombatEngine()) {
- deadShips.clear();
- for (ExplodingShip exploder : explodingShips) {
- exploder.flamePoints.clear();
- }
- explodingShips.clear();
- this.engine = Global.getCombatEngine();
- return;
- }
- if (engine.isPaused()) {
- return;
- }
- interval.advance(amount);
- List<ShipAPI> ships = engine.getShips();
- // We run through all the ships and check for newly-destroyed ships, adding them to the graphics loop
- for (ShipAPI ship : ships) {
- if (ship == null) {
- continue;
- }
- if (ship.isHulk() == true) {
- if (!deadShips.contains(ship)) {
- deadShips.add(ship);
- if (ship.getHullSize() != ShipAPI.HullSize.FIGHTER && !ship.isDrone()) {
- float intensity = flareBrightness.get(ship.getHullSize()) / 10f;
- float intensity2 = flareThickness.get(ship.getHullSize()) / 3f;
- AnamorphicFlare.createFlare(ship, new Vector2f(ship.getLocation()), engine, intensity, intensity2, 0f, 15f, 1f, new Color(255, 180, 150), new Color(255, 255, 255));
- }
- if (!ship.isFighter()) {
- RippleDistortion ripple = new RippleDistortion();
- ripple.setSize(ship.getCollisionRadius() * 4.5f);
- ripple.setIntensity(ship.getCollisionRadius() * lightIntensity.get(ship.getHullSize()));
- ripple.setLocation(ship.getLocation());
- ripple.setFrameRate(60f / rippleLength.get(ship.getHullSize()));
- ripple.fadeInSize(rippleLength.get(ship.getHullSize()) * 1.5f);
- ripple.fadeOutIntensity(rippleLength.get(ship.getHullSize()));
- ripple.setSize(ship.getCollisionRadius() * 1.5f);
- DistortionShader.addDistortion(ripple);
- }
- StandardLight light = new StandardLight();
- light.setSize(ship.getCollisionRadius() * explosionSizeMod.get(ship.getHullSize()) * 4f);
- light.setIntensity(lightIntensity.get(ship.getHullSize()));
- light.setColor(1f, 0.7f, 0.6f);
- light.setLocation(ship.getLocation());
- light.setLifetime(lightDuration.get(ship.getHullSize()));
- light.setAutoFadeOutTime(0.5f + lightDuration.get(ship.getHullSize()));
- LightShader.addLight(light);
- if (!ship.isShuttlePod() && !ship.isDrone()) {
- int count = (int) (ship.getCollisionRadius() * explosionSizeMod.get(ship.getHullSize()) / 4f);
- float length = explosionLength.get(ship.getHullSize()) * ((float) Math.random() * 0.5f + 0.75f);
- ExplodingShip exploder = new ExplodingShip(ship, count, length / (float) count);
- explodingShips.add(exploder);
- }
- }
- }
- }
- // If a ship is vaporized, we add some extra effects
- Iterator<ShipAPI> iter = deadShips.iterator();
- while (iter.hasNext()) {
- ShipAPI ship = iter.next();
- if (ship != null && !ships.contains(ship)) {
- //Vector2f velocity = new Vector2f(ship.getVelocity());
- Vector2f velocity = new Vector2f();
- engine.addHitParticle(ship.getLocation(), velocity, ship.getCollisionRadius() * 15f, 0.75f, ship.getCollisionRadius() / 15f, new Color(255, 255, 255, 255));
- engine.addSmoothParticle(ship.getLocation(), velocity, ship.getCollisionRadius() * 10f, 0.25f, ship.getCollisionRadius() / 10f, new Color(255, 255, 255, 50));
- float sizeMod = explosionSizeMod.get(ship.getHullSize());
- int particles = (int) (sizeMod * ship.getCollisionRadius() / 2f * ((float) Math.random() * 0.5f + 0.75f));
- for (int i = 0; i < particles; i++) {
- Vector2f point = new Vector2f(ship.getLocation());
- Vector2f vel = new Vector2f(velocity);
- vel.x += ((float) Math.random() + (float) Math.random() + (float) Math.random()) * 100f / 3f - 50f;
- vel.y += ((float) Math.random() + (float) Math.random() + (float) Math.random()) * 100f / 3f - 50f;
- point.x += ship.getCollisionRadius() * ((float) Math.random() * 1f - 0.5f);
- point.y += ship.getCollisionRadius() * ((float) Math.random() * 1f - 0.5f);
- Color color = new Color((int) ((float) Math.random() * 35f + 220f), (int) ((float) Math.random() * 180f + 40f), (int) ((float) Math.random() * 100f));
- Color color2 = new Color((int) ((float) Math.random() * 35f + 220f), (int) ((float) Math.random() * 140f + 40f), (int) ((float) Math.random() * 40f));
- engine.addHitParticle(point, vel, (float) Math.random() * 5f + 5f, 1f, (ship.getCollisionRadius() / 5f) * ((float) Math.random() * 1.5f + 0.25f), color);
- engine.addHitParticle(point, vel, (float) Math.random() * 15f + 30f, 0.2f, (ship.getCollisionRadius() / 5f) * ((float) Math.random() * 1.5f + 0.25f), color2);
- }
- int fire = (int) (sizeMod * ship.getCollisionRadius() / 25f * ((float) Math.random() * 0.5f + 0.75f));
- for (int i = 0; i < fire; i++) {
- Vector2f point = new Vector2f(ship.getLocation());
- Vector2f vel = new Vector2f(velocity);
- vel.x += (float) Math.random() * 20f - 10f;
- vel.y += (float) Math.random() * 20f - 10f;
- point.x += ship.getCollisionRadius() * ((float) Math.random() * 1.5f - 0.75f);
- point.y += ship.getCollisionRadius() * ((float) Math.random() * 1.5f - 0.75f);
- Color color = new Color((int) ((float) Math.random() * 35f + 220f), (int) ((float) Math.random() * 140f + 40f), (int) ((float) Math.random() * 40f));
- float size = ((float) Math.random() * 30f + 100f) * sizeMod;
- engine.spawnExplosion(point, vel, color, size, (ship.getCollisionRadius() / 25f) * ((float) Math.random() * 0.5f + 0.75f));
- }
- /*int debris = (int) ((Float)(explosionSizeMod.get(ship.getHullSize())) * ship.getCollisionRadius() / 5f * ((float)Math.random() * 0.5f + 0.75f));
- for (int i = 0; i < debris; i++)
- {
- Vector2f point = new Vector2f(ship.getLocation());
- Vector2f vel = new Vector2f(ship.getVelocity());
- vel.x += (float)Math.random() * 20f - 10f;
- vel.y += (float)Math.random() * 20f - 10f;
- point.x += ship.getCollisionRadius() * ((float)Math.random() * 1.5f - 0.75f);
- point.y += ship.getCollisionRadius() * ((float)Math.random() * 1.5f - 0.75f);
- vel.x += (point.x - ship.getLocation().x) * (float)Math.random();
- vel.y += (point.y - ship.getLocation().y) * (float)Math.random();
- CombatEntityAPI chunk = engine.spawnProjectile(engine.getPlayerShip(), null, "debris", point, (float)Math.random() * 360f, vel);
- //chunk.setFacing((float)Math.atan2(vel.y, vel.x) * 180f / (float)Math.PI);
- }*/
- iter.remove();
- }
- }
- // Now for the juicy bit...
- Iterator<ExplodingShip> iter2 = explodingShips.iterator();
- while (iter2.hasNext()) {
- ExplodingShip exploder = iter2.next();
- if (exploder.ship == null) {
- exploder.flamePoints.clear();
- iter2.remove();
- continue;
- }
- // If the ship is vaporized, it gets removed from this graphics loop
- if (!engine.getShips().contains(exploder.ship)) {
- exploder.flamePoints.clear();
- iter2.remove();
- continue;
- }
- // Draw fire contrails from our burning wrecks
- Iterator<FlamePoint> iter3 = exploder.flamePoints.iterator();
- while (iter3.hasNext()) {
- FlamePoint flamePoint = iter3.next();
- // Check if the flame contrail has expired yet
- if (!flamePoint.tick(amount)) {
- // Don't want to generate too many flames...
- if (interval.intervalElapsed()) {
- Vector2f point = new Vector2f(flamePoint.anchor.getLocation());
- Vector2f vel = new Vector2f();
- Vector2f vel2 = new Vector2f();
- Color color = new Color((int) ((float) Math.random() * 35f + 220f), (int) ((float) Math.random() * 140f + 40f), (int) ((float) Math.random() * 40f));
- Color color2 = new Color((int) ((float) Math.random() * 40f + 20f), (int) ((float) Math.random() * 20f + 20f), 20, (int) ((float) Math.random() * 30f + 30f));
- float sizeMod = explosionSizeMod.get(exploder.ship.getHullSize());
- float size = ((float) Math.random() * 25f) * sizeMod * flamePoint.scale;
- float size2 = ((float) Math.random() * 10f + 40f) * sizeMod * flamePoint.scale;
- float size3 = ((float) Math.random() * 40f + 80f) * sizeMod * flamePoint.scale;
- float size4 = ((float) Math.random() * 15f + 5f) * flamePoint.scale;
- vel.x += (float) Math.random() * 40f - 20f;
- vel.y += (float) Math.random() * 40f - 20f;
- vel2.x += (float) Math.random() * 20f - 10f;
- vel2.y += (float) Math.random() * 20f - 10f;
- // Make fewer flames if the wreck is not moving as quickly
- if ((float) Math.random() <= (flamePoint.anchor.getVelocity().length() + 50f) / 75f) {
- engine.addHitParticle(point, flamePoint.anchor.getVelocity(), size4, 0.65f, (float) Math.random() * 0.15f + 0.3f, new Color(255, 225, 175));
- if ((float) Math.random() >= 0.5f) {
- engine.spawnExplosion(point, vel, color, size, (float) Math.random() * 1f + 0.5f);
- engine.addSmokeParticle(point, vel2, size2, (float) Math.random() * 0.025f + 0.1f, (float) Math.random() * 4f + 4f, color2);
- } else {
- engine.addHitParticle(point, vel, size3, (float) Math.random() * 0.05f + 0.05f, (float) Math.random() * 0.5f + 0.25f, color);
- }
- }
- }
- } else {
- iter3.remove();
- }
- }
- // If the ship is an inert wreck, we flag it for removal from the loop
- if (exploder.flamePoints.isEmpty() && exploder.count <= 0) {
- iter2.remove();
- continue;
- }
- if (!exploder.tick(amount)) {
- continue;
- }
- if (exploder.count <= 0) {
- continue;
- }
- ShipAPI ship = exploder.ship;
- // And now we make it explode nicely...
- while (true) {
- Vector2f point = new Vector2f(ship.getLocation());
- point.x += ship.getCollisionRadius() * (((float) Math.random() * 2f) - 1);
- point.y += ship.getCollisionRadius() * (((float) Math.random() * 2f) - 1);
- if (CollisionUtils.isPointWithinBounds(point, ship)) {
- Vector2f vel = new Vector2f(ship.getVelocity());
- Vector2f vel2 = new Vector2f(ship.getVelocity());
- float rand = (float) Math.random() * 0.5f + 0.5f;
- float sizeMod = explosionSizeMod.get(ship.getHullSize());
- float size = (30f + (float) Math.random() * 30f) * sizeMod;
- Color color = new Color((int) ((float) Math.random() * 35f + 220f), (int) ((float) Math.random() * 140f + 40f), (int) ((float) Math.random() * 40f));
- vel.x *= rand;
- vel.y *= rand;
- vel2.x *= rand * 0.5f;
- vel2.y *= rand * 0.5f;
- engine.spawnExplosion(point, vel, color, size, size / 25f);
- engine.addSmokeParticle(point, vel2, size, 0.25f, size / 10f, new Color(50, 40, 30, 90));
- //engine.applyDamage(ship, point, size, DamageType.HIGH_EXPLOSIVE, 0f, true, false, null);
- if ((float) Math.random() >= 0.75) {
- Global.getSoundPlayer().playSound("explosion_from_damage", 0.95f + (float) Math.random() * 0.05f, sizeMod / 2f, point, vel);
- engine.addHitParticle(point, new Vector2f(ship.getVelocity()), size * 3f, 1f, size / 60f, new Color(255, 255, 255, 255));
- float length = explosionLength.get(ship.getHullSize()) * ((float) Math.random() * 5f + 2.5f);
- exploder.flamePoints.add(new FlamePoint(new AnchoredEntity(ship, point), length, (float) Math.random() * 1.3f + 0.35f));
- } else {
- engine.addHitParticle(point, new Vector2f(ship.getVelocity()), size, 0.5f, size / 60f, new Color(255, 255, 255, 255));
- }
- break;
- }
- }
- exploder.count -= 1;
- }
- }
- public static final class ExplodingShip {
- public ShipAPI ship;
- public int count;
- public float interval;
- public float ticker;
- public List<FlamePoint> flamePoints;
- public ExplodingShip(ShipAPI ship, int count, float interval) {
- this.ship = ship;
- this.count = count;
- this.interval = interval;
- this.flamePoints = new ArrayList<>();
- ticker = 0f;
- }
- public boolean tick(float amount) {
- ticker += amount;
- if (ticker >= interval) {
- ticker -= interval;
- return true;
- } else {
- return false;
- }
- }
- }
- public static final class FlamePoint {
- public AnchoredEntity anchor;
- public float time;
- public float scale;
- public float ticker;
- public FlamePoint(AnchoredEntity anchor, float time, float scale) {
- this.anchor = anchor;
- this.time = time;
- this.scale = scale;
- ticker = 0f;
- }
- public boolean tick(float amount) {
- ticker += amount;
- if (ticker >= time) {
- ticker -= time;
- return true;
- } else {
- return false;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement