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}