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}