001package com.fs.starfarer.api.impl.campaign.velfield;
002
003import java.awt.Color;
004import java.util.ArrayList;
005import java.util.Iterator;
006import java.util.List;
007
008import org.lwjgl.input.Keyboard;
009import org.lwjgl.input.Mouse;
010import org.lwjgl.opengl.GL11;
011import org.lwjgl.opengl.GL14;
012import org.lwjgl.util.vector.Vector2f;
013
014import com.fs.starfarer.api.Global;
015import com.fs.starfarer.api.campaign.CampaignEngineLayers;
016import com.fs.starfarer.api.campaign.SectorEntityToken;
017import com.fs.starfarer.api.combat.ViewportAPI;
018import com.fs.starfarer.api.graphics.SpriteAPI;
019import com.fs.starfarer.api.impl.campaign.BaseCustomEntityPlugin;
020import com.fs.starfarer.api.impl.campaign.velfield.TurbulenceCalc2.TurbulenceParams;
021import com.fs.starfarer.api.util.FaderUtil;
022import com.fs.starfarer.api.util.Misc;
023
024public class TurbulenceEntityPlugin extends BaseCustomEntityPlugin {
025
026        public static class PointParticle {
027                float size = 6f;
028                float mass = 0.0001f;
029                Vector2f loc = new Vector2f();
030                Vector2f vel = new Vector2f();
031                Color color;
032                float remaining;
033                float elapsed;
034        }
035        
036        public static class ParticleData {
037                public SpriteAPI sprite;
038                public Vector2f offset = new Vector2f();
039                public Vector2f vel = new Vector2f();
040                public float scale = 1f;
041                public float scaleIncreaseRate = 1f;
042                public float turnDir = 1f;
043                public float angle = 1f;
044                
045                public float maxDur;
046                public FaderUtil fader;
047                public float elapsed = 0f;
048                public float baseSize;
049                public float mass;
050                protected Color color;
051                
052                public ParticleData(float baseSize, float mass, float durIn, float durOut, float endSizeMult, float maxAngVel, Color color, String spriteSheetKey) {
053                        this.color = color;
054                        if (spriteSheetKey == null) {
055                                spriteSheetKey = "nebula_particles";
056                        }
057                        sprite = Global.getSettings().getSprite("misc", spriteSheetKey);
058                        //sprite = Global.getSettings().getSprite("graphics/fx/hit_glow.png");
059                        //sprite = Global.getSettings().getSprite("graphics/fx/particlealpha32sq.png");
060                        //sprite = Global.getSettings().getSprite("graphics/fx/particlealpha64linear.png");
061//                      queueResource(Type.TEXTURE, "graphics/fx/particlealpha32sq.png", 1);
062//                      queueResource(Type.TEXTURE, "graphics/fx/particleline32ln.png", 1);
063                        //sprite = Global.getSettings().getSprite("misc", "dust_particles");
064                        float i = Misc.random.nextInt(4);
065                        float j = Misc.random.nextInt(4);
066                        sprite.setTexWidth(0.25f);
067                        sprite.setTexHeight(0.25f);
068                        sprite.setTexX(i * 0.25f);
069                        sprite.setTexY(j * 0.25f);
070                        sprite.setAdditiveBlend();
071                        
072                        this.mass = mass;
073                        angle = (float) Math.random() * 360f;
074                        
075                        this.maxDur = durIn + durOut;
076                        scaleIncreaseRate = endSizeMult / maxDur;
077                        if (endSizeMult < 1f) {
078                                scaleIncreaseRate = -1f * endSizeMult;
079                        }
080                        scale = 1f;
081                        
082                        this.baseSize = baseSize;
083                        turnDir = Math.signum((float) Math.random() - 0.5f) * maxAngVel * (float) Math.random();
084                        
085                        fader = new FaderUtil(0f, durIn, durOut);
086                        fader.setBounceDown(true);
087                        fader.forceOut();
088                        fader.fadeIn();
089                }
090                
091                public void advance(float amount, VelocityField field, float fieldX, float fieldY, float fieldFacing) {
092                        if (field.isInsideField(offset.x, offset.y, new Vector2f(fieldX, fieldY), fieldFacing)) {
093                                Vector2f fVel = field.getVelocity(offset.x, offset.y, new Vector2f(fieldX, fieldY), fieldFacing);
094                                float accelAmount = 1f / mass;
095                                if (accelAmount > 1f) accelAmount = 1f;
096                                accelAmount *= 60f;
097                                //p.vel.set(vel);
098                                Vector2f diff = Vector2f.sub(fVel, vel, new Vector2f());
099                                vel.x += diff.x * accelAmount * amount;
100                                vel.y += diff.y * accelAmount * amount;
101                        } else {
102                                fader.fadeOut();
103//                              if (p.elapsed > 0.5f) {
104//                                      p.remaining = Math.min(p.remaining, 0.5f);
105//                              }
106                        }
107                        
108                        scale += scaleIncreaseRate * amount;
109                        
110                        offset.x += vel.x * amount;
111                        offset.y += vel.y * amount;
112                                
113                        angle += turnDir * amount;
114                        
115                        elapsed += amount;
116//                      if (maxDur - elapsed <= fader.getDurationOut() + 0.1f) {
117//                              fader.fadeOut();
118//                      }
119                        fader.advance(amount);
120                }
121        }
122        
123        protected List<ParticleData> particles = new ArrayList<ParticleData>();
124        protected List<ParticleData> darkParticles = new ArrayList<ParticleData>();
125        
126        protected VelocityField field;
127        protected List<PointParticle> testParticles = new ArrayList<PointParticle>();
128        
129        protected int frame = 0;
130        protected float distanceTravelled;
131 
132        public VelocityField getField() {
133                return field;
134        }
135
136        public void setField(VelocityField field) {
137                this.field = field;
138        }
139
140        public void init(SectorEntityToken entity, Object pluginParams) {
141                super.init(entity, pluginParams);
142                readResolve();
143        }
144        
145        Object readResolve() {
146                return this;
147        }
148        
149        public float getRenderRange() {
150                float cells = Math.max(field.field.length, field.field[0].length);
151                return cells * 1.5f * field.cellSize;
152        }
153        
154        public void advance(float amount) {
155                //float days = Global.getSector().getClock().convertToDays(amount);
156                
157                //field.getField()[10][10].set(0, 1000f);
158                //if (field.getField()[10][0].y == 0) {
159                if (Keyboard.isKeyDown(Keyboard.KEY_P) || true) {
160                        //field.getField()[10][0].set(0, 21f * 21f * 100f);
161                        //field.getField()[10][10].set(0, 100f);
162                        
163                        for (int i = 0; i < field.getField()[0].length; i++) {
164                                //field.getField()[5][i].set((float) Math.random() * 20f - 10f, 100f + i * 10);
165                                //field.getField()[5][i].set((float) Math.random() * 20f - 10f, 1000f);
166//                              field.getField()[4][i].set(500f, 500f);
167//                              field.getField()[6][i].set(-500f, 500f);
168                                //field.getField()[5][i].set(0, 1000f);
169                                //field.getField()[10][i].set(0, 1000f);
170                                
171//                              if (i % 4 == 0) {
172//                                      field.getField()[4][i].set(200f, 500f + (20 - i) * 10f);
173//                              } else if (i % 4 == 2){
174//                                      field.getField()[6][i].set(-200f, 500f + (20 - i) * 10f);
175//                              } else {
176//                                      field.getField()[5][i].set(0, 500f + (20 - i) * 10f);
177//                              }
178                                //field.getField()[5][i].set(0, 500f + (20 - i) * 10f);
179                                int x = field.getField().length / 2;
180                                field.getField()[x][i].set(0, 500f);
181                                
182                                
183//                              field.getField()[4][i].set(500f, 500f);
184//                              field.getField()[6][i].set(-500f, 500f);
185                                //field.getField()[5][i].y += 2000f * amount;
186                                
187//                              field.getField()[1][i].set(-200f, -200f);
188//                              field.getField()[9][i].set(200f, -200f);
189//                              field.getField()[3][i].set((float) Math.random() * 20f - 10f - 0, 100f + i * 20);
190//                              field.getField()[7][i].set((float) Math.random() * 20f - 10f + 0, 100f + i * 20);
191                        }
192                        
193//                      for (int i = 1; i < 20; i++) {
194//                              if (i % 2 == 0) {
195//                                      field.getField()[0][i].set(200f, 0);
196//                              } else {
197//                                      field.getField()[10][i].set(-200f, 0);
198//                              }
199//                      }
200                        
201//                      for (int i = 15; i <= 20; i++) {
202//                              field.getField()[8][i].set((float) Math.random() * 20f - 10f - 20, -100f);
203//                              field.getField()[12][i].set((float) Math.random() * 20f - 10f + 20, -100f);
204//                      }
205//                      field.getField()[10][1].set(0, 1000f);
206//                      field.getField()[10][2].set(0, 1000f);
207//                      field.getField()[9][0].set(0, 1000f);
208//                      field.getField()[11][0].set(0, 1000f);
209                }
210                
211                frame++;
212                
213                TurbulenceParams params = new TurbulenceParams();
214                params.field = field;
215                params.effectWidth = 210f;
216                params.effectLength = 410f;
217                params.maxDispersionAngle = 120f;
218                params.energyTransferMult = 5f;
219                params.dampenFactor = 0.2f;
220                params.maxVelocity = 1000f;
221                
222//              params.maxDispersionAngle = 180f;
223//              params.maxDispersionAngle = 160f;
224                params.maxDispersionAngle = 0f;
225                params.maxVelocity = 1000f;
226                params.energyTransferMult = 6f;
227//              params.effectWidth = 410f;
228//              params.effectLength = 810f;
229                
230                params.propagationAmount = 6f * amount;
231//              if (frame % 2 == 0) {
232//                      params.propagationAmount = 12f * amount;
233                        TurbulenceCalc2.advance(params);
234//              }
235                        
236//              for (int i = 0; i < 10; i++) {
237//                      TurbulenceCalc2.advance(field, 210f, 410f, 6f * amount);
238//              }
239                //TurbulenceCalc2.advance(field, 410f, 620f, 1f);
240                
241                
242                float facing = entity.getFacing();
243                float x = entity.getLocation().x;
244                float y = entity.getLocation().y;
245                float w = field.getCellSize() * (field.getField().length - 1);
246                float h = field.getCellSize() * (field.getField()[0].length - 1);
247                
248                //while (testParticles.size() < 5000) {
249                while (testParticles.size() < 500) {
250                        Vector2f loc = new Vector2f();
251                        //loc.x = w * (float) Math.random() + x;
252                        loc.x = w * 0.4f + w * 0.2f * (float) Math.random() ;
253                        loc.y = h * (1f - (float) Math.random()) ;
254                        loc = Misc.rotateAroundOrigin(loc, entity.getFacing());
255                        loc.x += x;
256                        loc.y += y;
257                        //float size = 3f + 2f * (float) Math.random();
258                        float size = 2f;
259                        float mass = 0.0001f;
260                        //mass = (float) Math.random() * 10f;
261                        mass = (float) Math.random() * 10f;
262                        //mass = 100f;
263                        float dur = 0f + 4f * Misc.random.nextFloat();
264                        addTestParticle(loc, getRandomColor(), size, mass, dur);
265                        
266                }
267                
268//              while (particles.size() < 1000) {
269//                      Vector2f loc = new Vector2f();
270//                      //loc.x = w * (float) Math.random() + x;
271//                      loc.x = w * 0.49f + w * 0.02f * (float) Math.random() + x;
272//                      loc.x = w * 0.4f + w * 0.2f * (float) Math.random() + x;
273//                      loc.x = w * 0.2f + w * 0.6f * (float) Math.random() + x;
274//                      //loc.y = h * (1f - (float) Math.random() * (float) Math.random()) + y;
275//                      loc.y = h * (1f - (float) Math.random()) + y;
276//                      float size = 250f + 20f * (float) Math.random();
277//                      size = 6f + 2f * (float) Math.random();
278//                      size = 12f;
279//                      size = 100f;
280//                      float mass = 0.0001f;
281//                      mass = (float) Math.random() * 10f;
282//                      //mass = 100f;
283//                      float dur = 0.5f + 3.5f * Misc.random.nextFloat();
284//                      Color c = getRandomColor();
285//                      //c = Misc.scaleAlpha(c, 0.25f);
286//                      addTexturedParticle(loc, c, mass, size, 10f, 0.5f, dur - 0.5f);
287//              }
288                
289                Iterator<PointParticle> iter = testParticles.iterator();
290                while (iter.hasNext()) {
291                        PointParticle p = iter.next();
292                        p.remaining -= amount;
293                        p.elapsed += amount;
294                        if (p.remaining <= 0) {
295                                iter.remove();
296                                continue;
297                        }
298                        
299                        if (field.isInsideField(p.loc.x, p.loc.y, new Vector2f(x, y), facing)) {
300                                Vector2f vel = field.getVelocity(p.loc.x, p.loc.y, new Vector2f(x, y), facing);
301                                float accelAmount = 1f / p.mass;
302                                if (accelAmount > 1f) accelAmount = 1f;
303                                accelAmount *= 60f;
304                                //p.vel.set(vel);
305                                Vector2f diff = Vector2f.sub(vel, p.vel, new Vector2f());
306                                p.vel.x += diff.x * accelAmount * amount;
307                                p.vel.y += diff.y * accelAmount * amount;
308                        } else {
309                                if (p.elapsed > 0.5f) {
310                                        p.remaining = Math.min(p.remaining, 0.5f);
311                                }
312//                              iter.remove();
313//                              continue;
314                        }
315                        
316                        p.loc.x += p.vel.x * amount;
317                        p.loc.y += p.vel.y * amount;
318                }
319                
320
321                List<ParticleData> remove = new ArrayList<ParticleData>();
322                for (ParticleData p : particles) {
323                        p.advance(amount, field, x, y, facing);
324                        if (p.elapsed >= p.maxDur) {
325                                remove.add(p);
326                        }
327                }
328                particles.removeAll(remove);
329                
330                remove = new ArrayList<ParticleData>();
331                for (ParticleData p : darkParticles) {
332                        p.advance(amount, field, x, y, facing);
333                        if (p.elapsed >= p.maxDur) {
334                                remove.add(p);
335                        }
336                }
337                darkParticles.removeAll(remove);
338                
339                
340                Vector2f vel = new Vector2f(0f, Misc.getSpeedForBurnLevel(30f));
341                Vector2f dv = new Vector2f(vel.x * amount, vel.y * amount);
342                
343                distanceTravelled += dv.length();
344                
345//              while (distanceTravelled > field.getCellSize()) {
346//                      dv = Misc.normalise(dv);
347//                      dv.scale(distanceTravelled);
348////                    entity.getLocation().x += dv.x;
349////                    entity.getLocation().y += dv.y;
350//                      field.shiftDown();
351//                      
352//                      distanceTravelled -= field.getCellSize();
353//              }
354        }
355
356        public void render(CampaignEngineLayers layer, ViewportAPI viewport) {
357        
358                float mx = Mouse.getX();
359                float my = Mouse.getY();
360                
361                float wmx = Global.getSector().getViewport().convertScreenXToWorldX(mx);
362                float wmy = Global.getSector().getViewport().convertScreenYToWorldY(my);
363                
364                entity.setFacing(0f);
365                
366                float facing = entity.getFacing();
367                float x = entity.getLocation().x;
368                float y = entity.getLocation().y;
369                
370                GL11.glDisable(GL11.GL_TEXTURE_2D);
371                GL11.glEnable(GL11.GL_BLEND);
372                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
373                
374                if (false || Keyboard.isKeyDown(Keyboard.KEY_O)) {
375                        GL11.glPushMatrix();
376                        GL11.glTranslatef(x, y, 0);
377                        GL11.glRotatef(facing, 0, 0, 1);
378                        
379                        GL11.glPointSize(20f);
380                        GL11.glEnable(GL11.GL_POINT_SMOOTH);
381                        GL11.glBegin(GL11.GL_POINTS);
382                        GL11.glColor4f(1f,0,0,0.75f);
383                        for (int i = 0; i < field.field.length; i++) {
384                                for (int j = 0; j < field.field[0].length; j++) {
385                                        float cx = i * field.cellSize;
386                                        float cy = j * field.cellSize;
387                                        GL11.glVertex2f(cx, cy);
388                                }
389                        }
390                        GL11.glEnd();
391                        
392                        GL11.glLineWidth(1);
393                        GL11.glEnable(GL11.GL_LINE_SMOOTH);
394                        GL11.glDisable(GL11.GL_BLEND);
395                        GL11.glBegin(GL11.GL_LINES);
396                        
397                        GL11.glColor4f(1f,1f,0,1f);
398                        float scale = 1f;
399                        for (int i = 0; i < field.field.length; i++) {
400                                for (int j = 0; j < field.field[0].length; j++) {
401                                        Vector2f vel = field.field[i][j];
402                                        
403        //                              float cx = x + i * field.cellSize;
404        //                              float cy = y + j * field.cellSize;
405                                        float cx = i * field.cellSize;
406                                        float cy = j * field.cellSize;
407                                        
408                                        GL11.glVertex2f(cx, cy);
409                                        GL11.glVertex2f(cx + vel.x * scale, cy + vel.y * scale);
410                                }
411                        }
412                        
413                        GL11.glEnd();
414                        
415                        
416                        GL11.glPopMatrix();
417        
418                        
419        
420                        GL11.glPointSize(6f);
421                        GL11.glEnable(GL11.GL_POINT_SMOOTH);
422                        GL11.glBegin(GL11.GL_POINTS);
423                        GL11.glColor4f(1,1,0,1);
424                        GL11.glVertex2f(wmx, wmy);
425                        GL11.glEnd();
426                        GL11.glLineWidth(1);
427                        GL11.glEnable(GL11.GL_LINE_SMOOTH);
428                        GL11.glBegin(GL11.GL_LINES);
429                        
430                        GL11.glColor4f(1,1,0,1);
431                        Vector2f vel = field.getVelocity(wmx, wmy, new Vector2f(x, y), facing);
432                        GL11.glVertex2f(wmx, wmy);
433                        GL11.glVertex2f(wmx + vel.x, wmy + vel.y);
434                        
435                        GL11.glEnd();
436                }
437                
438                
439                
440                GL11.glEnable(GL11.GL_POINT_SMOOTH);
441                GL11.glEnable(GL11.GL_BLEND);
442                GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
443                float zoom = Global.getSector().getViewport().getViewMult(); 
444                //System.out.println(zoom);
445                GL11.glPointSize(2f / zoom);
446                GL11.glBegin(GL11.GL_POINTS);
447                for (PointParticle p : testParticles) {
448                        if (true) break;
449                        if (!viewport.isNearViewport(p.loc, 5)) continue;
450                        float a = 1f;
451                        if (p.remaining <= 0.5f) {
452                                a = p.remaining / 0.5f;
453                        } else if (p.elapsed < 0.5f) {
454                                a = p.elapsed / 0.5f;
455                        }
456                        //a *= 0.5f;
457                        Misc.setColor(p.color, a);
458                        GL11.glVertex2f(p.loc.x, p.loc.y);
459                        
460                        float zf = 1f;
461                        if (zoom < 1.75f && false) {
462//                              float zf = (1.75f - zoom) / 0.25f;
463//                              if (zf < 0) zf = 0;
464//                              if (zf > 1) zf = 1;
465                                Vector2f dir = Misc.normalise(new Vector2f(p.vel));
466                                float spread = 0.5f;
467                                //spread = 1f;
468                                a *= 0.65f;
469                                Misc.setColor(p.color, a * zf);
470                                GL11.glVertex2f(p.loc.x + dir.x * spread, p.loc.y + dir.y * spread);
471                                if (zoom < 1.5f) {
472//                                      zf = (1.5f - zoom) / 0.25f;
473//                                      if (zf < 0) zf = 0;
474//                                      if (zf > 1) zf = 1;
475                                        Misc.setColor(p.color, a * zf);
476                                        GL11.glVertex2f(p.loc.x - dir.x * spread, p.loc.y - dir.y * spread);
477                                }
478                                
479                                if (zoom < 1.25f) {
480                                        spread *= 2f;
481                                        a *= 0.65f;
482//                                      zf = (1.25f - zoom) / 0.25f;
483//                                      if (zf < 0) zf = 0;
484//                                      if (zf > 1) zf = 1;
485                                        Misc.setColor(p.color, a * zf);
486                                        GL11.glVertex2f(p.loc.x + dir.x * spread, p.loc.y + dir.y * spread);
487                                        if (zoom < 1f) {
488//                                              zf = (1f - zoom) / 0.25f;
489//                                              if (zf < 0) zf = 0;
490//                                              if (zf > 1) zf = 1;
491                                                Misc.setColor(p.color, a * zf);
492                                                GL11.glVertex2f(p.loc.x - dir.x * spread, p.loc.y - dir.y * spread);
493                                        }
494                                }
495                        }
496                        
497//                      for (int i = 0; i < 4; i++) {
498//                              a *= 0.75f;
499//                              Misc.setColor(p.color, a);
500//                              GL11.glVertex2f(p.loc.x - dir.x * spread/zoom, p.loc.y - dir.y * spread/zoom);
501//                              spread += 0.5f;
502//                      }
503                        
504                }
505                GL11.glEnd();
506                
507                GL11.glLineWidth(3.5f);
508                GL11.glLineWidth(2f);
509                //GL11.glLineWidth(1.5f);
510                GL11.glEnable(GL11.GL_LINE_SMOOTH);
511                GL11.glBegin(GL11.GL_LINES);
512                for (PointParticle p : testParticles) {
513                        //if (true) break;
514                        if (!viewport.isNearViewport(p.loc, 500)) continue;
515                        float a = 1f;
516                        if (p.remaining <= 0.5f) {
517                                a = p.remaining / 0.5f;
518                        } else if (p.elapsed < 0.5f) {
519                                a = p.elapsed / 0.5f;
520                        }
521                        
522//                      Vector2f currVel = new Vector2f(p.loc);
523//                      Vector2f currLoc = new Vector2f(p.vel);
524                        //Vector2f prevVel = new Vector2f(p.vel);
525                        Vector2f prev = new Vector2f(p.loc);
526                        float prevAlpha = 0f;
527                        float interval = 1/60f;
528                        float iter = 15f;
529                        
530                        for (int i = 0; i < iter; i++) {
531                                //boolean inField = field.isInsideField(p.loc.x, p.loc.y, new Vector2f(x, y), facing);
532                                //boolean inField = true;
533                                Vector2f vel = field.getVelocity(prev.x, prev.y, new Vector2f(x, y), facing);
534                                //Vector2f vel = new Vector2f(100f, 0f);
535                                Vector2f loc = new Vector2f(prev);
536                                loc.x -= vel.x * interval;
537                                loc.y -= vel.y * interval;
538                                
539//                              float velDelta = Vector2f.sub(vel, prevVel, new Vector2f()).length();
540//                              float baseAlpha = 1f;
541                                float baseAlpha = 0.5f;
542//                              baseAlpha += 0.5f * velDelta / 50f;
543//                              baseAlpha *= 0.5f;
544//                              //baseAlpha = 0.5f;
545//                              if (baseAlpha > 1f) baseAlpha = 1f;
546                                
547                                float alpha = baseAlpha * a * (iter - i) / iter;
548                                //if (!inField) alpha = 0f;
549                                
550                                Misc.setColor(p.color, prevAlpha);
551                                GL11.glVertex2f(prev.x, prev.y);
552                                Misc.setColor(p.color, alpha);
553                                GL11.glVertex2f(loc.x, loc.y);
554                                
555                                prevAlpha = alpha;
556                                prev = loc;
557                                //prevVel = vel;
558                        }
559
560//                      Vector2f dir = Misc.normalise(new Vector2f(p.vel));
561//                      float len = 5f;
562//                      len = p.vel.length() / 10f;
563//                      if (len > 30) len = 30;
564//                      //a *= 0.75f;
565//                      Misc.setColor(p.color, a);
566//                      GL11.glVertex2f(p.loc.x, p.loc.y);
567//                      Misc.setColor(p.color, 0f);
568//                      GL11.glVertex2f(p.loc.x - dir.x * len, p.loc.y - dir.y * len);
569                }
570                GL11.glEnd();
571                
572                renderTextureParticles(layer, viewport);
573        }
574        
575        public void renderTextureParticles(CampaignEngineLayers layer, ViewportAPI viewport) {
576                float b = viewport.getAlphaMult();
577                
578                CampaignEngineLayers normalLayer = layer;
579                CampaignEngineLayers darkLayer = layer;
580                if (layer == normalLayer) {
581                        for (ParticleData p : particles) {
582                                float size = p.baseSize * p.scale;
583                                Vector2f loc = p.offset;
584                                
585                                float alphaMult = 1f;
586                                
587                                p.sprite.setAngle(p.angle);
588                                p.sprite.setSize(size, size);
589                                p.sprite.setAlphaMult(b * alphaMult * p.fader.getBrightness());
590                                p.sprite.setColor(p.color);
591                                p.sprite.renderAtCenter(loc.x, loc.y);
592                        }
593                } 
594                if (layer == darkLayer) {
595                        GL14.glBlendEquation(GL14.GL_FUNC_REVERSE_SUBTRACT);
596                        
597                        for (ParticleData p : darkParticles) {
598                                //float size = proj.getProjectileSpec().getWidth() * 0.6f;
599                                float size = p.baseSize * p.scale;
600                                
601                                Vector2f loc = p.offset;
602                                
603                                float alphaMult = 1f;
604                                
605                                p.sprite.setAngle(p.angle);
606                                p.sprite.setSize(size, size);
607                                p.sprite.setAlphaMult(b * alphaMult * p.fader.getBrightness());
608                                p.sprite.setColor(p.color);
609                                p.sprite.renderAtCenter(loc.x, loc.y);
610                        }
611                        
612                        GL14.glBlendEquation(GL14.GL_FUNC_ADD);
613                }
614        }
615        public void addTestParticle(Vector2f loc, Color color, float size, float mass, float dur) {
616                PointParticle p = new PointParticle();
617                p.loc.set(loc);
618                p.mass = mass;
619                p.remaining = dur;
620                p.size = size;
621                p.color = color;
622                testParticles.add(p);
623        }
624        
625        public void addTexturedParticle(Vector2f loc, Color color, float mass, float size, float endSizeMult, float durIn, float durOut) {
626                ParticleData p = new ParticleData(size, mass, durIn, durOut, endSizeMult, 30f, color, null);
627                p.offset.set(loc);
628                particles.add(p);
629//              p = new ParticleData(size * 0.8f, mass, durIn, durOut, endSizeMult, 30f, color, null);
630//              p.offset.set(loc);
631//              darkParticles.add(p);
632        }
633
634        public Color getRandomColor() {
635//              if (true) {
636//                      return new Color(0.5f, 1f, 0.8f, 1f);
637//              }
638                float r = 0.5f;
639                float g = 0.3f + 0.3f * (float) Math.random();
640                float b = 0.75f + 0.25f * (float) Math.random();
641                float a = 0.85f + 0.15f * (float) Math.random();
642                if (r < 0) r = 0;
643                if (r > 1) r = 1;
644                if (g < 0) g = 0;
645                if (g > 1) g = 1;
646                if (b < 0) b = 0;
647                if (b > 1) b = 1;
648                if (a < 0) a = 0;
649                if (a > 1) a = 1;
650                a *= 0.33f;
651                a = 1f;
652                Color c = new Color(r, g, b, a);
653                return c;
654        }
655}
656
657
658
659
660
661
662