001package com.fs.starfarer.api.impl.campaign;
002
003import java.awt.Color;
004import java.util.LinkedHashSet;
005
006import org.lwjgl.opengl.GL11;
007import org.lwjgl.util.vector.Vector2f;
008
009import com.fs.starfarer.api.Global;
010import com.fs.starfarer.api.campaign.CampaignEngineLayers;
011import com.fs.starfarer.api.campaign.CampaignFleetAPI;
012import com.fs.starfarer.api.campaign.CargoAPI;
013import com.fs.starfarer.api.campaign.CargoAPI.CargoItemType;
014import com.fs.starfarer.api.campaign.CustomEntitySpecAPI;
015import com.fs.starfarer.api.campaign.SectorEntityToken;
016import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
017import com.fs.starfarer.api.campaign.SpecialItemData;
018import com.fs.starfarer.api.campaign.comm.IntelInfoPlugin;
019import com.fs.starfarer.api.combat.ViewportAPI;
020import com.fs.starfarer.api.graphics.SpriteAPI;
021import com.fs.starfarer.api.impl.campaign.ids.Items;
022import com.fs.starfarer.api.impl.campaign.ids.Tags;
023import com.fs.starfarer.api.impl.campaign.intel.misc.GateIntel;
024import com.fs.starfarer.api.impl.campaign.world.ZigLeashAssignmentAI;
025import com.fs.starfarer.api.ui.TooltipMakerAPI;
026import com.fs.starfarer.api.util.FaderUtil;
027import com.fs.starfarer.api.util.IntervalUtil;
028import com.fs.starfarer.api.util.JitterUtil;
029import com.fs.starfarer.api.util.Misc;
030import com.fs.starfarer.api.util.WarpingSpriteRendererUtil;
031
032public class GateEntityPlugin extends BaseCustomEntityPlugin {
033
034        public static float ACCUMULATED_TRANSIT_DIST_DECAY_RATE = 20f;
035        public static float MOTE_SPAWN_MULT_BASELINE_DIST_LY = 25f;
036        
037        public static String GATE_DATA = "gateData";
038        
039        public static String GATE_SCANNED = "$gateScanned"; // in gate memory
040        public static String CAN_SCAN_GATES = "$canScanGates"; // in global memory
041        public static String GATES_ACTIVE = "$gatesActive"; // in global memory
042        public static String PLAYER_CAN_USE_GATES = "$playerCanUseGates"; // in global memory
043        public static String NUM_GATES_SCANNED = "$numGatesScanned"; // in global memory
044        
045        public static int getNumGatesScanned() {
046                return Global.getSector().getMemoryWithoutUpdate().getInt(NUM_GATES_SCANNED);
047        }
048        public static void addGateScanned() {
049                int num = getNumGatesScanned();
050                num++;
051                Global.getSector().getMemoryWithoutUpdate().set(NUM_GATES_SCANNED, num);
052        }
053        
054        public static class GateData {
055                public LinkedHashSet<SectorEntityToken> scanned = new LinkedHashSet<SectorEntityToken>();
056        }
057        
058        public static GateData getGateData() {
059                Object data = Global.getSector().getPersistentData().get(GATE_DATA);
060                if (!(data instanceof GateData)) {
061                        data = new GateData();
062                        Global.getSector().getPersistentData().put(GATE_DATA, data);
063                }
064                return (GateData) data;
065        }
066        
067        public static boolean isScanned(SectorEntityToken gate) {
068                return gate.getMemoryWithoutUpdate().getBoolean(GATE_SCANNED);
069        }
070        
071        public static boolean isActive(SectorEntityToken gate) {
072                return gate.getCustomPlugin() instanceof GateEntityPlugin &&
073                                ((GateEntityPlugin)gate.getCustomPlugin()).isActive();
074        }
075        
076        public static boolean areGatesActive() {
077                if (Global.getSector().getMemoryWithoutUpdate().getBoolean(GATES_ACTIVE)) {
078                        return true;
079                }
080                CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo();
081                return cargo.getQuantity(CargoItemType.SPECIAL, new SpecialItemData(Items.JANUS, null)) > 0;
082        }
083        
084        public static boolean canUseGates() {
085//              if (true) return true;
086                if (Global.getSector().getMemoryWithoutUpdate().getBoolean(PLAYER_CAN_USE_GATES)) {
087                        return true;
088                }
089                CargoAPI cargo = Global.getSector().getPlayerFleet().getCargo();
090                return cargo.getQuantity(CargoItemType.SPECIAL, new SpecialItemData(Items.JANUS, null)) > 0;
091        }
092        
093        transient protected SpriteAPI baseSprite;
094        transient protected SpriteAPI scannedGlow;
095        
096        transient protected SpriteAPI activeGlow;
097        transient protected SpriteAPI whirl1;
098        transient protected SpriteAPI whirl2;
099        transient protected SpriteAPI starfield;
100        transient protected SpriteAPI rays;
101        transient protected SpriteAPI concentric;
102        
103        transient protected WarpingSpriteRendererUtil warp;
104        
105        protected FaderUtil beingUsedFader = new FaderUtil(0f, 1f, 1f, false, true);
106        protected FaderUtil glowFader = new FaderUtil(0f, 1f, 1f, true, true);
107        protected boolean madeActive = false;
108        protected boolean addedIntel = false;
109        protected float showBeingUsedDur = 0f;
110        protected float accumulatedTransitDistLY = 0f;
111        
112        protected Color jitterColor = null; 
113        protected JitterUtil jitter;
114        protected FaderUtil jitterFader = null;
115        
116        protected IntervalUtil moteSpawn = null;
117        
118        public void init(SectorEntityToken entity, Object pluginParams) {
119                super.init(entity, pluginParams);
120                readResolve();
121        }
122        
123        
124        Object readResolve() {
125                scannedGlow = Global.getSettings().getSprite("gates", "glow_scanned");
126                activeGlow = Global.getSettings().getSprite("gates", "glow_ring_active");
127                concentric = Global.getSettings().getSprite("gates", "glow_concentric");
128                rays = Global.getSettings().getSprite("gates", "glow_rays");
129                whirl1 = Global.getSettings().getSprite("gates", "glow_whirl1");
130                whirl2 = Global.getSettings().getSprite("gates", "glow_whirl2");
131                starfield = Global.getSettings().getSprite("gates", "starfield");
132                
133                //warp = new WarpingSpriteRendererUtil(10, 10, 10f, 20f, 2f); 
134                
135                if (beingUsedFader == null) {
136                        beingUsedFader = new FaderUtil(0f, 1f, 1f, false, true);
137                }
138                if (glowFader == null) {
139                        glowFader = new FaderUtil(0f, 1f, 1f, true, true);
140                        glowFader.fadeIn();
141                }
142                inUseAngle = 0;
143                return this;
144        }
145        
146        public void jitter() {
147                if (jitterFader == null) {
148                        jitterFader = new FaderUtil(0f, 2f, 2f);
149                        jitterFader.setBounceDown(true);
150                }
151                if (jitter == null) {
152                        jitter = new JitterUtil();
153                        jitter.updateSeed();
154                }
155                jitterFader.fadeIn();
156        }
157        
158        public float getJitterLevel() {
159                if (jitterFader != null) return jitterFader.getBrightness();
160                return 0f;
161        }
162
163        public Color getJitterColor() {
164                return jitterColor;
165        }
166
167        public void setJitterColor(Color jitterColor) {
168                this.jitterColor = jitterColor;
169        }
170
171        public boolean isActive() {
172                return madeActive;
173        }
174        
175        public void showBeingUsed(float transitDistLY) {
176                showBeingUsed(10f, transitDistLY);
177        }
178        
179        public void showBeingUsed(float dur, float transitDistLY) {
180                beingUsedFader.fadeIn();
181                showBeingUsedDur = dur;
182                
183                accumulatedTransitDistLY += transitDistLY;
184                
185//              if (withSound && entity.isInCurrentLocation()) {
186//                      Global.getSoundPlayer().playSound("gate_being_used", 1, 1, entity.getLocation(), entity.getVelocity());
187//              }
188        }
189        
190        public float getProximitySoundFactor() {
191                CampaignFleetAPI player = Global.getSector().getPlayerFleet();
192                float dist = Misc.getDistance(player.getLocation(), entity.getLocation());
193                float radSum = entity.getRadius() + player.getRadius();
194                
195                //if (dist < radSum) return 1f;
196                dist -= radSum;
197
198                float f = 1f;
199                if (dist > 300f) {
200                        f = 1f - (dist - 300f) / 100f;
201                }
202
203                //float f = 1f - dist / 300f;
204                if (f < 0) f = 0;
205                if (f > 1) f = 1;
206                return f;
207        }
208        
209        public void playProximityLoop() {
210                if (!isActive() || !entity.isInCurrentLocation()) return;
211                
212                float prox = getProximitySoundFactor();
213                float volumeMult = prox;
214                float suppressionMult = prox;
215                if (volumeMult <= 0) return;
216                volumeMult = (float) Math.sqrt(volumeMult);
217                //volumeMult = 1f;
218                
219                Global.getSector().getCampaignUI().suppressMusic(1f * suppressionMult);
220                
221                float dirToEntity = Misc.getAngleInDegrees(entity.getLocation(), this.entity.getLocation());
222                Vector2f playbackLoc = Misc.getUnitVectorAtDegreeAngle(dirToEntity);
223                playbackLoc.scale(500f);
224                Vector2f.add(entity.getLocation(), playbackLoc, playbackLoc);
225                
226                Global.getSoundPlayer().playLoop("active_gate_loop", entity, 
227                                //volume * 0.25f + 0.75f, volume * volumeMult,
228                                1f, 1f * volumeMult,
229                                playbackLoc, Misc.ZERO);
230                
231                if (!beingUsedFader.isIdle()) {
232                        Global.getSoundPlayer().playLoop("gate_being_used", entity, 
233                                        //volume * 0.25f + 0.75f, volume * volumeMult,
234                                        1f, 1f * volumeMult,
235                                        playbackLoc, Misc.ZERO);
236                }
237        }
238
239        protected float inUseAngle = 0f;
240        public void advance(float amount) {
241                if (showBeingUsedDur > 0 || !beingUsedFader.isIdle()) {
242                        showBeingUsedDur -= amount;
243                        if (showBeingUsedDur > 0) {
244                                beingUsedFader.fadeIn();
245                        } else {
246                                showBeingUsedDur = 0f;
247                        }
248                        inUseAngle += amount * 60f;
249                        if (warp != null) {
250                                warp.advance(amount);
251                        }
252                }
253                glowFader.advance(amount);
254                
255//              if (entity.isInCurrentLocation()) {
256//                      System.out.println("BRIGHTNESS: " + beingUsedFader.getBrightness());
257//              }
258                
259                if (jitterFader != null) {
260                        jitterFader.advance(amount);
261                        if (jitterFader.isFadedOut()) {
262                                jitterFader = null;
263                        }
264                }
265                
266                if (accumulatedTransitDistLY > 0) {
267                        float days = Global.getSector().getClock().convertToDays(amount);
268                        accumulatedTransitDistLY -= days * ACCUMULATED_TRANSIT_DIST_DECAY_RATE;
269                        if (accumulatedTransitDistLY < 0) accumulatedTransitDistLY = 0;
270                }
271                
272                beingUsedFader.advance(amount);
273
274                if (!madeActive) {
275                        if (canUseGates() && isScanned(entity)) {
276                                if (entity.getName().equals(entity.getCustomEntitySpec().getDefaultName())) {
277                                        entity.setName("Active Gate");
278                                }
279                                entity.setCustomDescriptionId("active_gate");
280                                entity.setInteractionImage("illustrations", "active_gate");
281                                entity.removeTag(Tags.NEUTRINO);
282                                entity.addTag(Tags.NEUTRINO_HIGH);
283                                madeActive = true;
284                        }
285                }
286                
287                
288                if (entity.isInCurrentLocation()) {
289                        if (amount > 0) {
290                                playProximityLoop();
291                                
292                                if (jitter != null) {
293                                        jitter.updateSeed();
294                                }
295                                
296//                              if (isScanned(entity)) {
297//                                      float dist = Misc.getDistance(entity, Global.getSector().getPlayerFleet()) - 
298//                                                      entity.getRadius() - Global.getSector().getPlayerFleet().getRadius();
299//                                      if (dist < 300f && canUseGates()) {
300//                                              showBeingUsed();
301//                                      }
302//                              }
303                        
304                                if (!addedIntel && !Global.getSector().isInNewGameAdvance() && 
305                                                !Global.getSector().isInFastAdvance()) {
306                                        boolean alreadyHas = false;
307                                        for (IntelInfoPlugin intel : Global.getSector().getIntelManager().getIntel(GateIntel.class)) {
308                                                if (((GateIntel)intel).getGate() == entity) {
309                                                        alreadyHas = true;
310                                                        break;
311                                                }
312                                        }
313                                        if (!alreadyHas) {
314                                                Global.getSector().getIntelManager().addIntel(new GateIntel(entity));
315                                        }
316                                        addedIntel = true;
317                                }
318                                
319                                if (beingUsedFader.getBrightness() > 0) {
320                                        if (moteSpawn == null) moteSpawn = new IntervalUtil(0.01f, 20f);
321                                        float moteSpawnMult = accumulatedTransitDistLY / MOTE_SPAWN_MULT_BASELINE_DIST_LY; 
322                                        moteSpawn.advance(amount * moteSpawnMult);
323                                        if (moteSpawn.intervalElapsed()) {
324                                                ZigLeashAssignmentAI.spawnMote(entity);
325                                        }
326                                } else {
327                                        moteSpawn = null;
328                                }
329                        } else {
330                                moteSpawn = null;
331                        }
332                }               
333        }
334
335        public float getRenderRange() {
336                return entity.getRadius() + 500f;
337        }
338
339        @Override
340        public void createMapTooltip(TooltipMakerAPI tooltip, boolean expanded) {
341                Color color = entity.getFaction().getBaseUIColor();
342                
343//              boolean inactive = !isScanned(entity) || !areGatesActive();
344//              String gateTypeName = "Active Gate";
345//              if (inactive) gateTypeName = "Inactive Gate";
346//              
347//              if (gateTypeName.equals(entity.getName())) {
348//                      gateTypeName = "";
349//              } else {
350//                      //gateTypeName = " - " + gateTypeName;
351//              }
352                
353                tooltip.addPara(entity.getName(), color, 0);
354                
355                if (isScanned(entity)) {
356                        if (areGatesActive()) {
357                                tooltip.addPara("Active", Misc.getGrayColor(), 3f);
358                        } else {
359                                tooltip.addPara("Scanned", Misc.getGrayColor(), 3f);
360                        }
361                }
362        }
363
364        @Override
365        public boolean hasCustomMapTooltip() {
366                return true;
367        }
368        
369        @Override
370        public void appendToCampaignTooltip(TooltipMakerAPI tooltip, VisibilityLevel level) {
371                if (isScanned(entity)) {
372                        tooltip.setParaFontDefault();
373                        if (areGatesActive()) {
374                                tooltip.addPara("This gate is active.", Misc.getGrayColor(), 10f);
375                        } else {
376                                tooltip.addPara("You've scanned this gate.", Misc.getGrayColor(), 10f);
377                        }
378                }
379        }
380        
381        
382        transient protected boolean scaledSprites = false;
383        protected void scaleGlowSprites() {
384                if (scaledSprites) return;
385                CustomEntitySpecAPI spec = entity.getCustomEntitySpec();
386                if (spec != null) {
387                        baseSprite = Global.getSettings().getSprite(spec.getSpriteName());
388                        baseSprite.setSize(spec.getSpriteWidth(), spec.getSpriteHeight());
389                        
390                        scaledSprites = true;
391                        float scale = spec.getSpriteWidth() / Global.getSettings().getSprite(spec.getSpriteName()).getWidth();
392                        scannedGlow.setSize(scannedGlow.getWidth() * scale, scannedGlow.getHeight() * scale);
393                        activeGlow.setSize(activeGlow.getWidth() * scale, activeGlow.getHeight() * scale);
394                        
395                        rays.setSize(rays.getWidth() * scale, rays.getHeight() * scale);
396                        whirl1.setSize(whirl1.getWidth() * scale, whirl1.getHeight() * scale);
397                        whirl2.setSize(whirl2.getWidth() * scale, whirl2.getHeight() * scale);
398                        starfield.setSize(starfield.getWidth() * scale, starfield.getHeight() * scale);
399                        concentric.setSize(concentric.getWidth() * scale, concentric.getHeight() * scale);
400                }
401        }
402        
403        public void render(CampaignEngineLayers layer, ViewportAPI viewport) {
404                if (layer == CampaignEngineLayers.BELOW_STATIONS) {
405                        boolean beingUsed = !beingUsedFader.isFadedOut();
406                        if (beingUsed) {
407                                float alphaMult = viewport.getAlphaMult();
408                                alphaMult *= entity.getSensorFaderBrightness();
409                                alphaMult *= entity.getSensorContactFaderBrightness();
410                                if (alphaMult <= 0f) return;
411                                
412                                if (warp == null) {
413                                        int cells = 6;
414                                        float cs = starfield.getWidth() / 10f;
415                                        warp = new WarpingSpriteRendererUtil(cells, cells, cs * 0.2f, cs * 0.2f, 2f);
416                                }
417                                
418                                Vector2f loc = entity.getLocation();
419                                
420                                float glowAlpha = 1f;
421                                scaleGlowSprites();
422                                
423                                glowAlpha *= beingUsedFader.getBrightness();
424                                
425                                starfield.setAlphaMult(alphaMult * glowAlpha);
426                                starfield.setAdditiveBlend();
427                                //starfield.renderAtCenter(loc.x + 1.5f, loc.y);
428                                
429                                GL11.glEnable(GL11.GL_BLEND);
430                                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
431                                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
432                                warp.renderNoBlendOrRotate(starfield, loc.x + 1.5f - starfield.getWidth() / 2f,
433                                                                                        loc.y - starfield.getHeight() / 2f, false);
434                        }
435                }
436                if (layer == CampaignEngineLayers.STATIONS) {
437                        float alphaMult = viewport.getAlphaMult();
438                        alphaMult *= entity.getSensorFaderBrightness();
439                        alphaMult *= entity.getSensorContactFaderBrightness();
440                        if (alphaMult <= 0f) return;
441                        
442                        CustomEntitySpecAPI spec = entity.getCustomEntitySpec();
443                        if (spec == null) return;
444                        
445                        float w = spec.getSpriteWidth();
446                        float h = spec.getSpriteHeight();
447                        
448                        float scale = spec.getSpriteWidth() / Global.getSettings().getSprite(spec.getSpriteName()).getWidth(); 
449                        
450                        Vector2f loc = entity.getLocation();
451                        
452                        
453                        Color scannedGlowColor = new Color(255,200,0,255);
454                        Color activeGlowColor = new Color(200,50,255,255);
455                        
456                        scannedGlowColor = Color.white;
457                        activeGlowColor = Color.white;
458                        
459                        float glowAlpha = 1f;
460                        
461                        
462                        float glowMod1 = 0.5f + 0.5f * glowFader.getBrightness();
463                        float glowMod2 = 0.75f + 0.25f * glowFader.getBrightness();
464                        
465                        boolean beingUsed = !beingUsedFader.isFadedOut();
466                        boolean scanned = isScanned(entity);
467                        boolean active = areGatesActive();
468                        
469                        scaleGlowSprites();
470                        
471                        if (jitterFader != null && jitter != null) {
472                                Color c = jitterColor;
473                                if (c == null) c = new Color(255,255,255,255);
474                                baseSprite.setColor(c);
475                                baseSprite.setAlphaMult(alphaMult * jitterFader.getBrightness());
476                                baseSprite.setAdditiveBlend();
477                                jitter.render(baseSprite, loc.x, loc.y, 30f * jitterFader.getBrightness(), 10);
478                                baseSprite.renderAtCenter(loc.x, loc.y);
479                        }
480                        
481                        
482                        if (!active && scanned) {
483                                scannedGlow.setColor(scannedGlowColor);
484                                //scannedGlow.setSize(w, h);
485                                scannedGlow.setAlphaMult(alphaMult * glowAlpha * glowMod1);
486                                scannedGlow.setAdditiveBlend();
487                                scannedGlow.renderAtCenter(loc.x, loc.y);
488                        }
489                        
490                        if (active && scanned) {
491                                activeGlow.setColor(activeGlowColor);
492                                //activeGlow.setSize(w * scale, h * scale);
493                                activeGlow.setAlphaMult(alphaMult * glowAlpha * glowMod2);
494                                activeGlow.setAdditiveBlend();
495                                activeGlow.renderAtCenter(loc.x, loc.y);
496                        }
497                        
498//                      beingUsed = true;
499//                      showBeingUsedDur = 10f;
500                        if (beingUsed) {
501                                if (!active) {
502                                        activeGlow.setColor(activeGlowColor);
503                                        //activeGlow.setSize(w + 20, h + 20);
504                                        activeGlow.setAlphaMult(alphaMult * glowAlpha * beingUsedFader.getBrightness() * glowMod2);
505                                        activeGlow.setAdditiveBlend();
506                                        activeGlow.renderAtCenter(loc.x, loc.y);
507                                }
508                                
509                                glowAlpha *= beingUsedFader.getBrightness();
510                                float angle;
511                                
512                                rays.setAlphaMult(alphaMult * glowAlpha);
513                                rays.setAdditiveBlend();
514                                rays.renderAtCenter(loc.x + 1.5f, loc.y);
515                                
516                                concentric.setAlphaMult(alphaMult * glowAlpha * 1f);
517                                concentric.setAdditiveBlend();
518                                concentric.renderAtCenter(loc.x + 1.5f, loc.y);
519
520                                angle = -inUseAngle * 0.25f;
521                                angle = Misc.normalizeAngle(angle);
522                                whirl1.setAngle(angle);
523                                whirl1.setAlphaMult(alphaMult * glowAlpha);
524                                whirl1.setAdditiveBlend();
525                                whirl1.renderAtCenter(loc.x + 1.5f, loc.y);
526                                
527                                angle = -inUseAngle * 0.33f;
528                                angle = Misc.normalizeAngle(angle);
529                                whirl2.setAngle(angle);
530                                whirl2.setAlphaMult(alphaMult * glowAlpha * 0.5f);
531                                whirl2.setAdditiveBlend();
532                                whirl2.renderAtCenter(loc.x + 1.5f, loc.y);
533                        }
534                }
535        }
536        
537        
538        
539        
540        
541
542//      public void advance(float amount) {
543//              if (entity.isInCurrentLocation()) {
544//                      if (rings != null) {
545//                              for (TempRingData data : rings) {
546//                                      data.advance(amount);
547//                              }
548//                      }
549//                      angleOffset += 30f * amount;
550//              }               
551//      }       
552//      Object readResolve() {
553//              glow = Global.getSettings().getSprite("gates", "glow");
554//              atmosphereTex = Global.getSettings().getSprite("combat", "corona_hard");
555//              
556//              rings = new ArrayList<GateEntityPlugin.TempRingData>();
557//              float baseRadius = 120 * 0.6f;
558//              float thickness = 5;
559//              float max = 30f;
560//              for (float i = 0; i < max; i++ ) {
561//                      //TempRingData data = new TempRingData(baseRadius - i * 1.5f, thickness);
562//                      float mult = 0.5f + 0.5f * (1f - i / max);
563//                      mult = 1f;
564//                      TempRingData data = new TempRingData(baseRadius - i * 1.5f * mult, thickness);
565//                      rings.add(data);
566//              }
567//              
568//              return this;
569//      }
570//      
571//      public void render(CampaignEngineLayers layer, ViewportAPI viewport) {
572//              if (layer == CampaignEngineLayers.STATIONS) {
573//                      float alphaMult = viewport.getAlphaMult();
574//                      alphaMult *= entity.getSensorFaderBrightness();
575//                      alphaMult *= entity.getSensorContactFaderBrightness();
576//                      if (alphaMult <= 0f) return;
577//                      
578//                      CustomEntitySpecAPI spec = entity.getCustomEntitySpec();
579//                      if (spec == null) return;
580//                      
581//                      float w = spec.getSpriteWidth();
582//                      float h = spec.getSpriteHeight();
583//                      
584//                      Vector2f loc = entity.getLocation();
585//                      
586//                      
587//                      Color glowColor = new Color(255,200,0,255);
588//                      float glowAlpha = 1f;
589//                      
590//                      //glow.setColor(Color.white);
591//                      glow.setColor(glowColor);
592//                      
593//                      glow.setSize(w, h);
594//                      glow.setAlphaMult(alphaMult * glowAlpha);
595//                      glow.setAdditiveBlend();
596//                      
597//                      glow.setColor(new Color(100, 100, 255));
598//                      //glow.setAngle(entity.getFacing() - 90f + glowAngle1);
599////                    glow.renderAtCenter(loc.x, loc.y);
600////                    glow.renderAtCenter(loc.x, loc.y);
601////                    glow.renderAtCenter(loc.x, loc.y);
602//                      //glow.renderAtCenter(loc.x, loc.y);
603//                      
604////                    float perSegment = 2f;
605////                    segments = (int) ((entity.getRadius() * 2f * 3.14f) / perSegment);
606////                    if (segments < 8) segments = 8;
607////                    
608////                    if (noise != null) {
609////                            float x = loc.x;
610////                            float y = loc.y;
611////                            float r = entity.getRadius() * 0.6f;
612////                            float tSmall = 10f;
613////                            
614////                            Color color = new Color(100, 100, 255);
615////                            noiseMag = 0.7f;
616////                            float a = 1f;
617////                            a = 1f;
618////                            for (int i = 0; i < 3; i++) {
619////                                    renderAtmosphere(x, y, r - i, tSmall, alphaMult * a, segments, atmosphereTex, noise, color, true);
620////                            }
621//////                          renderAtmosphere(x, y, r, tSmall, alphaMult * a, segments, atmosphereTex, noise, color, true);
622//////                          renderAtmosphere(x, y, r - 2f, tSmall, alphaMult * a, segments, atmosphereTex, noise, color, true);
623//////                          
624////                            float circleAlpha = 1f;
625////                            if (alphaMult < 0.5f) {
626////                                    circleAlpha = alphaMult * 2f;
627////                            }
628//////                          float tCircleBorder = 1f;
629//                      
630////                    float x = loc.x;
631////                    float y = loc.y;
632//                      float a = 0.5f;
633//                      Color color = new Color(100, 100, 255);
634//                      if (rings != null) {
635//                              //float i = rings.size();
636//                              float i = 0f;
637//                              for (TempRingData data : rings) {
638//                                      float r = i / rings.size() * 15f;
639//                                      float angle = i * 5f + angleOffset;
640//                                      Vector2f loc2 = Misc.getUnitVectorAtDegreeAngle(angle);
641//                                      loc2.scale(r);
642//                                      float x = loc.x + loc2.x;
643//                                      float y = loc.y + loc2.y;
644//                                      i++;
645//                                      float bonusThickness = 0f;
646////                                    if (i == 1) bonusThickness = 20f;
647////                                    if (i <= 5) bonusThickness = 20f - i * 3f;
648//                                      renderAtmosphere(x, y, data.radius, data.thickness + bonusThickness, 
649//                                                      alphaMult * a, data.segments, atmosphereTex, data.noise, color, true);
650//
651//                                      if ((int)Math.round(i) == rings.size()) {
652//                                              renderCircle(x, y,  data.radius, 1f, data.segments, data.noise, Color.black);
653//                                      }
654//                              }
655//                              
656//                              float x = loc.x;
657//                              float y = loc.y;
658//                              //renderCircle(x, y,  rings.get(0).radius, 1f, rings.get(0).segments, rings.get(0).noise, Color.black);
659//                      }
660////                            renderAtmosphere(x, y, r, tCircleBorder, circleAlpha, segments, atmosphereTex, noise, Color.black, false);
661////                    }
662//              }
663//      }
664//      
665//      
666//      
667//      
668//      private void renderCircle(float x, float y, float radius, float alphaMult, int segments, float [] noise, Color color) {
669//              //if (fader.isFadingIn()) alphaMult = 1f;
670//              
671//              float startRad = (float) Math.toRadians(0);
672//              float endRad = (float) Math.toRadians(360);
673//              float spanRad = Misc.normalizeAngle(endRad - startRad);
674//              float anglePerSegment = spanRad / segments;
675//              
676//              GL11.glPushMatrix();
677//              GL11.glTranslatef(x, y, 0);
678//              GL11.glRotatef(0, 0, 0, 1);
679//              GL11.glDisable(GL11.GL_TEXTURE_2D);
680//              
681//              GL11.glEnable(GL11.GL_BLEND);
682//              GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
683//              
684//              
685//              GL11.glColor4ub((byte)color.getRed(),
686//                                              (byte)color.getGreen(),
687//                                              (byte)color.getBlue(),
688//                                              (byte)((float) color.getAlpha() * alphaMult));
689//              
690//              GL11.glBegin(GL11.GL_TRIANGLE_FAN);
691//              GL11.glVertex2f(0, 0);
692//              for (float i = 0; i < segments + 1; i++) {
693//                      boolean last = i == segments;
694//                      if (last) i = 0;
695//                      float theta = anglePerSegment * i;
696//                      float cos = (float) Math.cos(theta);
697//                      float sin = (float) Math.sin(theta);
698//                      
699//                      float m1 = 0.9f + 0.1f * noise[(int)i];
700////                    if (noiseMag <= 0) {
701////                            m1 = 1f;
702////                    }
703//                      
704//                      float x1 = cos * radius * m1;
705//                      float y1 = sin * radius * m1;
706//                      
707//                      GL11.glVertex2f(x1, y1);
708//                      
709//                      if (last) break;
710//              }
711//              
712//              
713//              GL11.glEnd();
714//              GL11.glPopMatrix();
715//              
716//      }
717//      
718//      
719//      private void renderAtmosphere(float x, float y, float radius, float thickness, float alphaMult, int segments, SpriteAPI tex, float [] noise, Color color, boolean additive) {
720//              
721//              float startRad = (float) Math.toRadians(0);
722//              float endRad = (float) Math.toRadians(360);
723//              float spanRad = Misc.normalizeAngle(endRad - startRad);
724//              float anglePerSegment = spanRad / segments;
725//              
726//              GL11.glPushMatrix();
727//              GL11.glTranslatef(x, y, 0);
728//              GL11.glRotatef(0, 0, 0, 1);
729//              GL11.glEnable(GL11.GL_TEXTURE_2D);
730//              
731//              tex.bindTexture();
732//
733//              GL11.glEnable(GL11.GL_BLEND);
734//              if (additive) {
735//                      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
736//              } else {
737//                      GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
738//              }
739//              
740////            float zoom = Global.getSector().getViewport().getViewMult();
741//              
742//              float noiseMult = 1f;
743////            if (zoom > 1) {
744////                    noiseMult = 1f / zoom;
745////                    alphaMult *= noiseMult;
746////            }
747//              
748//              GL11.glColor4ub((byte)color.getRed(),
749//                                              (byte)color.getGreen(),
750//                                              (byte)color.getBlue(),
751//                                              (byte)((float) color.getAlpha() * alphaMult));
752//              float texX = 0f;
753//              float incr = 1f / segments;
754//              GL11.glBegin(GL11.GL_QUAD_STRIP);
755//              for (float i = 0; i < segments + 1; i++) {
756//                      boolean last = i == segments;
757//                      if (last) i = 0;
758//                      float theta = anglePerSegment * i;
759//                      float cos = (float) Math.cos(theta);
760//                      float sin = (float) Math.sin(theta);
761//                      
762//                      
763//                      float m1 = 0.9f + 0.1f * noise[(int)i] * noiseMult;
764//                      float m2 = m1;
765//                      //m2 = 1f;
766//                      
767//                      float x1 = cos * radius * m1;
768//                      float y1 = sin * radius * m1;
769//                      float x2 = cos * (radius + thickness * m2 * 5f);
770//                      float y2 = sin * (radius + thickness * m2);
771//                      
772//                      GL11.glTexCoord2f(0.5f, 0.05f);
773//                      GL11.glVertex2f(x1, y1);
774//                      
775//                      GL11.glTexCoord2f(0.5f, 0.95f);
776//                      GL11.glVertex2f(x2, y2);
777//                      
778//                      texX += incr;
779//                      if (last) break;
780//              }
781//              
782//              GL11.glEnd();
783//              GL11.glPopMatrix();
784//      }
785//      
786//      
787//      
788//      
789//      
790//
791//      public static class TempRingData {
792//              protected float [] noise;
793//              protected float [] noise1;
794//              protected float [] noise2;
795//              protected int segments;
796//              protected float noiseElapsed = 0f;
797//              protected float noisePeriod = 0f;
798//              protected float radius;
799//              protected float noiseMag;
800//              protected float thickness;
801//              public TempRingData(float radius, float thickness) {
802//                      this.radius = radius;
803//                      this.thickness = thickness;
804//                      
805//                      float perSegment = 2f;
806//                      segments = (int) ((radius * 2f * 3.14f) / perSegment);
807//                      if (segments < 8) segments = 8;
808//                      
809//                      noiseMag = 0.6f;
810//                      noiseMag = 1f;
811//                      noisePeriod = 1f + Misc.random.nextFloat() * 1f;
812//                      noise1 = Noise.genNoise(segments, noiseMag);
813//                      noise2 = Noise.genNoise(segments, noiseMag);
814//                      noise = Arrays.copyOf(noise1, noise1.length);
815//              }
816//              public void advance(float amount) {
817//                      noiseElapsed += amount;
818//                      if (noiseElapsed > noisePeriod) {
819//                              noiseElapsed = 0;
820//                              noise1 = Arrays.copyOf(noise2, noise2.length);
821//                              noise2 = Noise.genNoise(segments, noiseMag);
822//                      }
823//                      float f = noiseElapsed / noisePeriod;
824//                      for (int i = 0; i < noise.length; i++) {
825//                              float n1 = noise1[i];
826//                              float n2 = noise2[i];
827//                              noise[i] = n1 + (n2 - n1) * f;
828//                      }
829//              }
830//      }
831//      transient protected List<TempRingData> rings;
832//      transient protected SpriteAPI atmosphereTex;
833        
834}
835
836
837
838
839
840
841
842
843