001package com.fs.starfarer.api.impl.combat;
002
003import java.awt.Color;
004
005import org.lwjgl.opengl.GL11;
006import org.lwjgl.util.vector.Vector2f;
007
008import com.fs.starfarer.api.Global;
009import com.fs.starfarer.api.combat.BaseCombatLayeredRenderingPlugin;
010import com.fs.starfarer.api.combat.CombatEngineLayers;
011import com.fs.starfarer.api.combat.ShipAPI;
012import com.fs.starfarer.api.combat.ViewportAPI;
013import com.fs.starfarer.api.graphics.SpriteAPI;
014import com.fs.starfarer.api.util.FaderUtil;
015import com.fs.starfarer.api.util.Misc;
016
017public class NeuralTransferVisual extends BaseCombatLayeredRenderingPlugin {
018
019        public static float TEX_SCROLL_SPEED = 1f;
020        
021        protected ShipAPI from;
022        protected ShipAPI to;
023        protected float duration;
024        
025        protected FaderUtil fader = new FaderUtil(0f, 0.5f, 0.5f);
026
027        protected SpriteAPI sprite;
028        protected float texProgress = 0f;
029        
030        public NeuralTransferVisual(ShipAPI from, ShipAPI to, float duration) {
031                this.from = from;
032                this.to = to;
033                this.duration = duration;
034                
035                sprite = Global.getSettings().getSprite("misc", "neural_transfer_beam");
036                fader.fadeIn();
037        }
038
039        @Override
040        public void advance(float amount) {
041                super.advance(amount);
042                
043                if (Global.getCombatEngine().isPaused()) return;
044                
045                entity.getLocation().set(to.getShieldCenterEvenIfNoShield());
046                fader.advance(amount);
047                duration -= amount;
048                if (!fader.isFadingOut() && duration <= 0f) {
049                        fader.fadeOut();
050                }
051                
052                texProgress -= TEX_SCROLL_SPEED * amount * 2f;
053        }
054
055        @Override
056        public float getRenderRadius() {
057                return to.getShieldRadiusEvenIfNoShield() * 3f + 200f;
058        }
059
060        @Override
061        public void render(CombatEngineLayers layer, ViewportAPI viewport) {
062                super.render(layer, viewport);
063                
064                
065                //float length = to.getShieldRadiusEvenIfNoShield() * 3f + 100f;
066                float length1 = 500f;
067                length1 = Math.min(length1, Misc.getDistance(from.getLocation(), to.getLocation()));
068                float length2 = to.getShieldRadiusEvenIfNoShield();
069                if (length1 < length2) length1 = length2;
070                length1 += length2;
071                float w1 = to.getShieldRadiusEvenIfNoShield() * 0.3f;
072                float w2 = to.getShieldRadiusEvenIfNoShield() * 1.5f;
073                float w3 = to.getShieldRadiusEvenIfNoShield() * 2.5f;
074                float wMult = 0.33f;
075                w1 *= wMult;
076                w2 *= wMult;
077                w3 *= wMult;
078                //w1 = w2 = 400;
079                
080                float angle = Misc.getAngleInDegrees(from.getLocation(), to.getLocation());
081                
082                Vector2f dest = new Vector2f(to.getShieldCenterEvenIfNoShield());
083                Vector2f src = Misc.getUnitVectorAtDegreeAngle(angle + 180f);
084                src.scale(length1 - length2/2f);
085                Vector2f.add(src, dest, src);
086                
087                Vector2f dir = Misc.getUnitVectorAtDegreeAngle(angle);
088                Vector2f dest2 = new Vector2f(dir);
089                dest2.scale(length2/3f * 1f);
090                Vector2f.add(dest2, dest, dest2);
091                Vector2f dest1 = new Vector2f(dir);
092                dest1.scale(-length2/3f * 2f);
093                Vector2f.add(dest1, dest, dest1);
094                
095                
096                Vector2f perp = Misc.getUnitVectorAtDegreeAngle(angle + 90);
097                
098                GL11.glEnable(GL11.GL_TEXTURE_2D);
099                //GL11.glDisable(GL11.GL_TEXTURE_2D);
100                sprite.bindTexture();
101                GL11.glEnable(GL11.GL_BLEND);
102                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
103                
104                Color color = new Color(0,121,216,255);
105                
106                boolean wireframe = false;
107                //wireframe = true;
108                if (wireframe) {
109                        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
110                        GL11.glDisable(GL11.GL_TEXTURE_2D);
111                        //GL11.glDisable(GL11.GL_BLEND);
112                }
113
114                float alpha = (float) (viewport.getAlphaMult() * Math.sqrt(fader.getBrightness()));
115                alpha *= 0.5f;
116                alpha *= (0.5f + Math.min(0.5f, 0.5f * w2 / 360f));
117                GL11.glBegin(GL11.GL_TRIANGLE_FAN);
118                Misc.setColor(color, alpha * 1f);
119                GL11.glTexCoord2f(0.5f + texProgress, 0.5f);
120                GL11.glVertex2f((src.x + dest1.x)/2f, (src.y + dest1.y)/2f);
121                
122                Misc.setColor(color, alpha * 0f);
123                GL11.glTexCoord2f(0f + texProgress, 0f);
124                GL11.glVertex2f(src.x + perp.x * w1/2f, src.y + perp.y * w1/2f);
125                GL11.glTexCoord2f(0f + texProgress, 1f);
126                GL11.glVertex2f(src.x - perp.x * w1/2f, src.y - perp.y * w1/2f);
127                
128                Misc.setColor(color, alpha * 1f);
129                GL11.glTexCoord2f(1f + texProgress, 1f);
130                GL11.glVertex2f(dest1.x - perp.x * w2/2f, dest1.y - perp.y * w2/2f);
131                GL11.glTexCoord2f(1f + texProgress, 0f);
132                GL11.glVertex2f(dest1.x + perp.x * w2/2f, dest1.y + perp.y * w2/2f);
133                
134                Misc.setColor(color, alpha * 0f);
135                GL11.glTexCoord2f(0f + texProgress, 0f);
136                GL11.glVertex2f(src.x + perp.x * w1/2f, src.y + perp.y * w1/2f);
137                GL11.glEnd();
138                
139                float th = length2 / length1;
140                
141                GL11.glBegin(GL11.GL_TRIANGLE_FAN);
142                Misc.setColor(color, alpha * 1f);
143                GL11.glTexCoord2f(0.5f + texProgress + th, 0.5f);
144                GL11.glVertex2f((dest1.x + dest2.x)/2f, (dest1.y + dest2.y)/2f);
145                
146                Misc.setColor(color, alpha * 1f);
147                GL11.glTexCoord2f(0f + texProgress, 0f);
148                GL11.glVertex2f(dest1.x + perp.x * w2/2f, dest1.y + perp.y * w2/2f);
149                GL11.glTexCoord2f(0f + texProgress, 1f);
150                GL11.glVertex2f(dest1.x - perp.x * w2/2f, dest1.y - perp.y * w2/2f);
151                
152                Misc.setColor(color, alpha * 0f);
153                GL11.glTexCoord2f(1f + texProgress + th, 1f);
154                GL11.glVertex2f(dest2.x - perp.x * w3/2f, dest2.y - perp.y * w3/2f);
155                GL11.glTexCoord2f(1f + texProgress + th, 0f);
156                GL11.glVertex2f(dest2.x + perp.x * w3/2f, dest2.y + perp.y * w3/2f);
157                
158                Misc.setColor(color, alpha * 1f);
159                GL11.glTexCoord2f(0f + texProgress + th, 0f);
160                GL11.glVertex2f(dest1.x + perp.x * w2/2f, dest1.y + perp.y * w2/2f);
161                GL11.glEnd();
162                
163                if (wireframe) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
164                
165        }
166
167        @Override
168        public boolean isExpired() {
169                return fader.isFadedOut() && duration <= 0f;
170        }
171
172        
173        
174        
175        
176}