001package com.fs.starfarer.api.impl.combat;
002
003import java.awt.Color;
004
005import org.lwjgl.util.vector.Vector2f;
006
007import com.fs.starfarer.api.Global;
008import com.fs.starfarer.api.combat.BeamAPI;
009import com.fs.starfarer.api.combat.BeamEffectPlugin;
010import com.fs.starfarer.api.combat.CombatEngineAPI;
011import com.fs.starfarer.api.combat.MissileAPI;
012import com.fs.starfarer.api.combat.ShipAPI;
013import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
014import com.fs.starfarer.api.util.Misc;
015
016public class RiftLanceEffect implements BeamEffectPlugin { //WithReset {
017
018        public static float MINE_SPAWN_CHANCE = 0f;
019        
020        protected boolean done = false;
021//      public void reset() {
022//              done = false;
023//      }
024        
025        public void advance(float amount, CombatEngineAPI engine, BeamAPI beam) {
026                if (beam.getBrightness() < 1f || done) return;
027                float range = beam.getWeapon().getRange();
028                float length = beam.getLengthPrevFrame();
029        
030                if (length > range - 10f || beam.getDamageTarget() != null) {
031                //if (beam.getDamageTarget() != null) {
032                        done = true;
033                        
034                        Vector2f loc = beam.getRayEndPrevFrame();
035                        
036                        Color color = getColorForDarkening(beam.getFringeColor());
037                        Color undercolor = RiftCascadeEffect.EXPLOSION_UNDERCOLOR;
038                        float a = 1f;
039                        color = Misc.scaleAlpha(color, a);
040                        undercolor = Misc.scaleAlpha(undercolor, a);
041                        float size = 75f;
042                        size *= 0.5f;
043                        float dur = beam.getWeapon().getSpec().getBurstDuration() + beam.getWeapon().getSpec().getBeamChargedownTime();
044                        
045                        if ((float) Math.random() < MINE_SPAWN_CHANCE) {
046                                spawnMine(beam.getSource(), loc);
047                        } else {
048                                Vector2f vel = new Vector2f();
049                                if (beam.getDamageTarget() != null) {
050                                        vel.set(beam.getDamageTarget().getVelocity());
051                                }
052                                spawnHitDarkening(color, undercolor, loc, vel, size, dur);
053                        }
054                }
055        }
056        
057        public void spawnHitDarkening(Color color, Color undercolor, Vector2f point, Vector2f vel, float size, float baseDuration) {
058                CombatEngineAPI engine = Global.getCombatEngine();
059                if (!engine.getViewport().isNearViewport(point, 100f + size * 2f)) return;
060                
061                Color c = color;
062                
063                
064                for (int i = 0; i < 5; i++) {
065                        float dur = baseDuration + baseDuration * (float) Math.random();
066                        //float nSize = size * (1f + 0.0f * (float) Math.random());
067                        //float nSize = size * (0.75f + 0.5f * (float) Math.random());
068                        float nSize = size;
069                        Vector2f pt = Misc.getPointWithinRadius(point, nSize * 0.5f);
070                        Vector2f v = Misc.getUnitVectorAtDegreeAngle((float) Math.random() * 360f);
071                        v.scale(nSize + nSize * (float) Math.random() * 0.5f);
072                        v.scale(0.2f);
073                        Vector2f.add(vel, v, v);
074                        
075                        float maxSpeed = nSize * 1.5f * 0.2f; 
076                        float minSpeed = nSize * 1f * 0.2f; 
077                        float overMin = v.length() - minSpeed;
078                        if (overMin > 0) {
079                                float durMult = 1f - overMin / (maxSpeed - minSpeed);
080                                if (durMult < 0.1f) durMult = 0.1f;
081                                dur *= 0.5f + 0.5f * durMult;
082                        }
083                        engine.addNegativeNebulaParticle(pt, v, nSize * 1f, 2f,
084                                                                                        0.5f / dur, 0f, dur, c);
085                }
086                
087                float dur = baseDuration; 
088                float rampUp = 0f;
089                c = undercolor;
090                for (int i = 0; i < 12; i++) {
091                        Vector2f loc = new Vector2f(point);
092                        loc = Misc.getPointWithinRadius(loc, size * 1f);
093                        float s = size * 3f * (0.5f + (float) Math.random() * 0.5f);
094                        engine.addNebulaParticle(loc, vel, s, 1.5f, rampUp, 0f, dur, c);
095                }
096        }
097        
098        public static Color getColorForDarkening(Color from) {
099                Color c = new Color(255 - from.getRed(),
100                                255 - from.getGreen(),
101                                255 - from.getBlue(), 127);
102                c = Misc.interpolateColor(c, Color.white, 0.4f);
103                return c;
104        }
105        
106        
107        public void spawnMine(ShipAPI source, Vector2f mineLoc) {
108                CombatEngineAPI engine = Global.getCombatEngine();
109                
110                
111                //Vector2f currLoc = mineLoc;
112                MissileAPI mine = (MissileAPI) engine.spawnProjectile(source, null, 
113                                                                                                                          "riftlance_minelayer", 
114                                                                                                                          mineLoc, 
115                                                                                                                          (float) Math.random() * 360f, null);
116                if (source != null) {
117                        Global.getCombatEngine().applyDamageModifiersToSpawnedProjectileWithNullWeapon(
118                                                                                        source, WeaponType.ENERGY, false, mine.getDamage());
119//                      float extraDamageMult = source.getMutableStats().getMissileWeaponDamageMult().getModifiedValue();
120//                      mine.getDamage().setMultiplier(mine.getDamage().getMultiplier() * extraDamageMult);
121                }
122                
123                
124                float fadeInTime = 0.05f;
125                mine.getVelocity().scale(0);
126                mine.fadeOutThenIn(fadeInTime);
127                
128                //Global.getCombatEngine().addPlugin(createMissileJitterPlugin(mine, fadeInTime));
129                
130                //mine.setFlightTime((float) Math.random());
131                float liveTime = 0f;
132                //liveTime = 0.01f;
133                mine.setFlightTime(mine.getMaxFlightTime() - liveTime);
134                mine.addDamagedAlready(source);
135                mine.setNoMineFFConcerns(true);
136        }
137
138}
139
140
141
142
143