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