001package com.fs.starfarer.api.impl.campaign.terrain; 002 003import java.awt.Color; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.EveryFrameScript; 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.campaign.AsteroidAPI; 010import com.fs.starfarer.api.campaign.CampaignFleetAPI; 011import com.fs.starfarer.api.fleet.FleetMemberAPI; 012import com.fs.starfarer.api.util.Misc; 013import com.fs.starfarer.api.util.WeightedRandomPicker; 014 015public class AsteroidImpact implements EveryFrameScript { 016 017 //public static float SAFE_BURN_LEVEL = 5.01f; 018// public static float IMPACT_SPEED_DELTA = Global.getSettings().getSpeedPerBurnLevel(); 019 public static float DURATION_SECONDS = 0.2f; 020 021 protected CampaignFleetAPI fleet; 022 protected float elapsed; 023// protected float angle; 024// protected float impact = IMPACT_SPEED_DELTA; 025 protected Vector2f dV; 026 027 public AsteroidImpact(CampaignFleetAPI fleet, boolean dealDamage) { 028 this.fleet = fleet; 029 030 //System.out.println("ADDING IMPACT TO " + fleet.getName() + " " + fleet.getId()); 031 032 Vector2f v = fleet.getVelocity(); 033 float angle = Misc.getAngleInDegrees(v); 034 float speed = v.length(); 035 if (speed < 10) angle = fleet.getFacing(); 036 037 float mult = Misc.getFleetRadiusTerrainEffectMult(fleet); 038 039 //float arc = 120f; 040 float arc = 120f - 60f * mult; // larger fleets suffer more direct collisions that slow them down more 041 042 angle += (float) Math.random() * arc - arc/2f; 043 angle += 180f; 044 045 //if (fleet.getCurrBurnLevel() <= SAFE_BURN_LEVEL || mult <= 0) { 046 if (Misc.isSlowMoving(fleet) || mult <= 0) { 047 elapsed = DURATION_SECONDS; 048 dV = new Vector2f(); 049 } else if (fleet.isInCurrentLocation()) { 050 if (dealDamage) { 051 WeightedRandomPicker<FleetMemberAPI> targets = new WeightedRandomPicker<FleetMemberAPI>(); 052 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 053 float w = 1f; 054 switch (member.getHullSpec().getHullSize()) { 055 case CAPITAL_SHIP: w = 20f; break; 056 case CRUISER: w = 10f; break; 057 case DESTROYER: w = 5f; break; 058 case FRIGATE: w = 1f; break; 059 } 060 targets.add(member, w); 061 } 062 063 FleetMemberAPI member = targets.pick(); 064 if (member != null) { 065 float damageMult = fleet.getCurrBurnLevel() - Misc.getGoSlowBurnLevel(fleet); 066 if (damageMult < 1) damageMult = 1; 067 Misc.applyDamage(member, null, damageMult, true, "asteroid_impact", "Asteroid impact", 068 true, null, member.getShipName() + " suffers damage from an asteroid impact"); 069 } else { 070 dealDamage = false; 071 } 072 } 073 074 if (!dealDamage && fleet.isPlayerFleet()) { 075 Global.getSector().getCampaignUI().addMessage("Asteroid impact on drive bubble", Misc.getNegativeHighlightColor()); 076 } 077 078 Vector2f test = Global.getSector().getPlayerFleet().getLocation(); 079 float dist = Misc.getDistance(test, fleet.getLocation()); 080 if (dist < HyperspaceTerrainPlugin.STORM_STRIKE_SOUND_RANGE) { 081// float volumeMult = 1f - (dist / HyperspaceTerrainPlugin.STORM_STRIKE_SOUND_RANGE); 082// volumeMult = (float) Math.sqrt(volumeMult); 083 //volumeMult *= 0.75f; 084 float volumeMult = 0.75f; 085 volumeMult *= 0.5f + 0.5f * mult; 086 if (volumeMult > 0) { 087 if (dealDamage) { 088 Global.getSoundPlayer().playSound("hit_heavy", 1f, 1f * volumeMult, fleet.getLocation(), Misc.ZERO); 089 } else { 090 Global.getSoundPlayer().playSound("hit_shield_heavy_gun", 1f, 1f * volumeMult, fleet.getLocation(), Misc.ZERO); 091 } 092 } 093 } 094 095// if (fleet.isPlayerFleet()) { 096// System.out.println("wefwefwef"); 097// } 098 //mult = 2f; 099// if (fleet.isPlayerFleet()) { 100// System.out.println("SPAWNED ---------"); 101// } 102 103// int num = (int) (6f + (float) Math.random() * 5f); 104// for (int i = 0; i < num; i++) { 105// angle = angle + (float) Math.random() * 30f - 15f; 106// float size = 10f + (float) Math.random() * 6f; 107// float size = 10f + (float) Math.random() * 6f; 108// size = 4f + 4f * (float) Math.random(); 109// 110// AsteroidAPI asteroid = fleet.getContainingLocation().addAsteroid(size); 111// asteroid.setFacing((float) Math.random() * 360f); 112// Vector2f av = Misc.getUnitVectorAtDegreeAngle(angle + 180f); 113// av.scale(fleet.getVelocity().length() + (20f + 20f * (float) Math.random()) * mult); 114// asteroid.getVelocity().set(av); 115// Vector2f al = Misc.getUnitVectorAtDegreeAngle(angle + 180f); 116// //al.scale(fleet.getRadius() + asteroid.getRadius()); 117// al.scale(fleet.getRadius()); 118// Vector2f.add(al, fleet.getLocation(), al); 119// asteroid.setLocation(al.x, al.y); 120// 121// float sign = Math.signum(asteroid.getRotation()); 122// asteroid.setRotation(sign * (50f + 50f * (float) Math.random())); 123// 124// Misc.fadeInOutAndExpire(asteroid, 0.2f, 1.5f + 1f * (float) Math.random(), 1f); 125// } 126 127 float size = 10f + (float) Math.random() * 6f; 128 size *= 0.67f; 129 AsteroidAPI asteroid = fleet.getContainingLocation().addAsteroid(size); 130 asteroid.setFacing((float) Math.random() * 360f); 131 Vector2f av = Misc.getUnitVectorAtDegreeAngle(angle + 180f); 132 av.scale(fleet.getVelocity().length() + (20f + 20f * (float) Math.random()) * mult); 133 asteroid.getVelocity().set(av); 134 Vector2f al = Misc.getUnitVectorAtDegreeAngle(angle + 180f); 135 //al.scale(fleet.getRadius() + asteroid.getRadius()); 136 al.scale(fleet.getRadius()); 137 Vector2f.add(al, fleet.getLocation(), al); 138 asteroid.setLocation(al.x, al.y); 139 140 float sign = Math.signum(asteroid.getRotation()); 141 asteroid.setRotation(sign * (50f + 50f * (float) Math.random())); 142 143 Misc.fadeInOutAndExpire(asteroid, 0.2f, 1f + 1f * (float) Math.random(), 1f); 144 145 //mult = 1f; 146 Vector2f iv = fleet.getVelocity(); 147 iv = new Vector2f(iv); 148 iv.scale(0.7f); 149 float glowSize = 100f + 100f * mult + 50f * (float) Math.random(); 150 Color color = new Color(255, 165, 100, 255); 151 Misc.addHitGlow(fleet.getContainingLocation(), al, iv, glowSize, color); 152 } 153 154 dV = Misc.getUnitVectorAtDegreeAngle(angle); 155 156 float impact = speed * 1f * (0.5f + mult * 0.5f); 157 dV.scale(impact); 158 dV.scale(1f / DURATION_SECONDS); 159 160// if (fleet.isPlayerFleet()) { 161// fleet.addFloatingText("Impact!", Misc.getNegativeHighlightColor(), 0.5f); 162// } 163 } 164 165 public void advance(float amount) { 166 167 fleet.setOrbit(null); 168 169// if (fleet.isPlayerFleet()) { 170// System.out.println("wefwefwef"); 171// } 172 173 Vector2f v = fleet.getVelocity(); 174 fleet.setVelocity(v.x + dV.x * amount, v.y + dV.y * amount); 175 176// Vector2f dir = Misc.getUnitVectorAtDegreeAngle(angle); 177// 178// //dir.scale(IMPACT_SPEED_DELTA * mult * amount * 75f * (0.5f + (float) Math.random() * 0.5f)); 179// 180// float mult = Misc.getFleetRadiusTerrainEffectMult(fleet); 181// mult = 1f; 182//// if (mult > 1f || amount ) { 183//// System.out.println("wefwefwefe"); 184//// mult = Misc.getFleetRadiusTerrainEffectMult(fleet); 185//// } 186// dir.scale(IMPACT_SPEED_DELTA * mult * amount * 187// (Math.min(20f, fleet.getCurrBurnLevel()) * 50f) * (0.5f + (float) Math.random() * 0.5f)); 188// 189// Vector2f v = fleet.getVelocity(); 190// fleet.setVelocity(v.x + dir.x, v.y + dir.y); 191// 192//// Vector2f loc = fleet.getLocation(); 193//// fleet.setLocation(loc.x + dir.x, loc.y + dir.y); 194 195 elapsed += amount; 196 197 } 198 199 public boolean isDone() { 200 return elapsed >= DURATION_SECONDS; 201 } 202 203 public boolean runWhilePaused() { 204 return false; 205 } 206 207}