001package com.fs.starfarer.api.impl.campaign.terrain; 002 003import java.awt.Color; 004import java.util.EnumSet; 005 006import org.lwjgl.opengl.GL11; 007 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.campaign.CampaignEngineLayers; 010import com.fs.starfarer.api.campaign.CampaignFleetAPI; 011import com.fs.starfarer.api.campaign.SectorEntityToken; 012import com.fs.starfarer.api.campaign.TerrainAIFlags; 013import com.fs.starfarer.api.combat.ViewportAPI; 014import com.fs.starfarer.api.impl.combat.BattleCreationPluginImpl.NebulaTextureProvider; 015import com.fs.starfarer.api.loading.Description.Type; 016import com.fs.starfarer.api.ui.Alignment; 017import com.fs.starfarer.api.ui.TooltipMakerAPI; 018import com.fs.starfarer.api.util.Misc; 019 020public class NebulaTerrainPlugin extends BaseTiledTerrain implements NebulaTextureProvider { 021// public static float MIN_BURN_PENALTY = 0.1f; 022// public static float BURN_PENALTY_RANGE = 0.4f; 023 024 025 public static final float TILE_SIZE = 400; 026 public static final float VISIBLITY_MULT = 0.5f; 027 028// public static Map<HullSize, Float> burnPenalty = new HashMap<HullSize, Float>(); 029// static { 030// burnPenalty.put(HullSize.FIGHTER, 3f); 031// burnPenalty.put(HullSize.FRIGATE, 3f); 032// burnPenalty.put(HullSize.DESTROYER, 2f); 033// burnPenalty.put(HullSize.CRUISER, 1f); 034// burnPenalty.put(HullSize.CAPITAL_SHIP, 0f); 035// } 036 037 038 public void init(String terrainId, SectorEntityToken entity, Object param) { 039 super.init(terrainId, entity, param); 040 if (name == null || name.equals("Unknown")) name = "Nebula"; 041 } 042 043 public String getNameForTooltip() { 044 return "Nebula"; 045 } 046 047 protected Object readResolve() { 048 super.readResolve(); 049 layers = EnumSet.of(CampaignEngineLayers.TERRAIN_2, CampaignEngineLayers.TERRAIN_8); 050 return this; 051 } 052 transient private EnumSet<CampaignEngineLayers> layers = EnumSet.of(CampaignEngineLayers.TERRAIN_2, CampaignEngineLayers.TERRAIN_8); 053 public EnumSet<CampaignEngineLayers> getActiveLayers() { 054 return layers; 055 } 056 057 058 public String getNebulaMapTex() { 059 return Global.getSettings().getSpriteName(params.cat, params.key + "_map"); 060 } 061 062 public String getNebulaTex() { 063 return Global.getSettings().getSpriteName(params.cat, params.key); 064 } 065 066 public void advance(float amount) { 067 super.advance(amount); 068 } 069 070 071 private transient CampaignEngineLayers currLayer = null; 072 public void render(CampaignEngineLayers layer, ViewportAPI viewport) { 073 currLayer = layer; 074 super.render(layer, viewport); 075 076 077// float x = entity.getLocation().x; 078// float y = entity.getLocation().y; 079// float size = getTileSize(); 080// float renderSize = getTileRenderSize(); 081// 082// float w = tiles.length * size; 083// float h = tiles[0].length * size; 084// 085// x -= w / 2f; 086// y -= h / 2f; 087// 088// GL11.glDisable(GL11.GL_TEXTURE_2D); 089// GL11.glEnable(GL11.GL_BLEND); 090// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 091// 092// Color color = Color.white; 093// GL11.glColor4ub((byte)color.getRed(), 094// (byte)color.getGreen(), 095// (byte)color.getBlue(), 096// (byte)((float)color.getAlpha() * 0.25f)); 097// 098// GL11.glBegin(GL11.GL_QUADS); 099// { 100// GL11.glVertex2f(x, y); 101// GL11.glVertex2f(x, y + h); 102// GL11.glVertex2f(x + w, y + h); 103// GL11.glVertex2f(x + w, y); 104// } 105// GL11.glEnd(); 106 } 107 108 @Override 109 public float getTileRenderSize() { 110 //return TILE_SIZE + 300f; 111 //return TILE_SIZE + 600f; 112 return TILE_SIZE * 2.5f; 113 } 114 115 @Override 116 public float getTileContainsSize() { 117 //return TILE_SIZE + 200f; 118 return TILE_SIZE * 1.5f; 119 } 120 121 @Override 122 public float getTileSize() { 123 return TILE_SIZE; 124 } 125 126 @Override 127 protected void renderSubArea(float startColumn, float endColumn, 128 float startRow, float endRow, float factor, int samples, 129 float alphaMult) { 130 131// if (currLayer != CampaignEngineLayers.TERRAIN_8) { 132// float size = getTileSize(); 133// float renderSize = getTileRenderSize(); 134// float x = entity.getLocation().x - renderSize / 2f; 135// float y = entity.getLocation().y - renderSize / 2f; 136// 137// float w = tiles.length * size + renderSize; 138// float h = tiles[0].length * size + renderSize; 139// 140// 141// GL11.glColorMask(false, false, false, true); 142// GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ZERO); 143// GL11.glColor4ub((byte)0, 144// (byte)0, 145// (byte)0, 146// (byte)255); 147// GL11.glBegin(GL11.GL_QUADS); 148// { 149// GL11.glVertex2f(x, y); 150// GL11.glVertex2f(x, y + h); 151// GL11.glVertex2f(x + w, y + h); 152// GL11.glVertex2f(x + w, y); 153// } 154// GL11.glEnd(); 155// 156// GL11.glColorMask(true, true, true, false); 157// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA); 158// Color color = getRenderColor(); 159// GL11.glColor4ub((byte)color.getRed(), 160// (byte)color.getGreen(), 161// (byte)color.getBlue(), 162// (byte)((float)color.getAlpha() * alphaMult)); 163// } 164 165 super.renderSubArea(startColumn, endColumn, startRow, endRow, factor, samples, alphaMult); 166 167 168// if (currLayer != CampaignEngineLayers.TERRAIN_8) { 169// float size = getTileSize(); 170// float renderSize = getTileRenderSize(); 171// float x = entity.getLocation().x - renderSize / 2f; 172// float y = entity.getLocation().y - renderSize / 2f; 173// float w = tiles.length * size + renderSize; 174// float h = tiles[0].length * size + renderSize; 175// 176// x -= w/2f; 177// y -= h/2f; 178// 179// 180// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_DST_COLOR); 181// GL11.glColor4ub((byte)0, 182// (byte)0, 183// (byte)0, 184// (byte)255); 185// GL11.glBegin(GL11.GL_QUADS); 186// { 187// GL11.glVertex2f(x, y); 188// GL11.glVertex2f(x, y + h); 189// GL11.glVertex2f(x + w, y + h); 190// GL11.glVertex2f(x + w, y); 191// } 192// GL11.glEnd(); 193// 194// } 195 } 196 197 @Override 198 public void preRender(CampaignEngineLayers layer, float alphaMult) { 199 GL11.glEnable(GL11.GL_BLEND); 200 if (entity.isInHyperspace()) { 201// if (layer == CampaignEngineLayers.TERRAIN_8) { 202// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); 203// } else { 204// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 205// } 206 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 207 } else { 208 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 209 } 210 //GL11.glDisable(GL11.GL_BLEND); 211 212 if (layer == CampaignEngineLayers.TERRAIN_8) { 213 alphaMult *= 0.20f; 214 //alphaMult *= 0.50f; 215 } 216 217 Color color = getRenderColor(); 218 GL11.glColor4ub((byte)color.getRed(), 219 (byte)color.getGreen(), 220 (byte)color.getBlue(), 221 (byte)((float)color.getAlpha() * alphaMult)); 222 } 223 224 @Override 225 public void preMapRender(float alphaMult) { 226 GL11.glEnable(GL11.GL_BLEND); 227 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 228 //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); 229 230 //Color color = new Color(125,125,200,255); 231 //Color color = new Color(100,100,150,255); 232 Color color = getRenderColor(); 233 GL11.glColor4ub((byte)color.getRed(), 234 (byte)color.getGreen(), 235 (byte)color.getBlue(), 236 (byte)((float)color.getAlpha() * alphaMult)); 237 } 238 239 @Override 240 public Color getRenderColor() { 241 return Color.white; 242 //return Color.black; 243 //return Misc.interpolateColor(Color.black, Color.white, 0.1f); 244 //return new Color(255,255,255,150); 245 } 246 247 @Override 248 public void applyEffect(SectorEntityToken entity, float days) { 249 if (entity instanceof CampaignFleetAPI) { 250 CampaignFleetAPI fleet = (CampaignFleetAPI) entity; 251 fleet.getStats().addTemporaryModMult(0.1f, getModId() + "_1", 252 "Inside nebula", VISIBLITY_MULT, 253 fleet.getStats().getDetectedRangeMod()); 254 255 float penalty = Misc.getBurnMultForTerrain(fleet); 256 //float penalty = getBurnPenalty(fleet); 257 fleet.getStats().addTemporaryModMult(0.1f, getModId() + "_2", 258 "Inside nebula", penalty, 259 fleet.getStats().getFleetwideMaxBurnMod()); 260// fleet.getStats().addTemporaryModPercent(0.1f, getModId() + "_2", 261// "Inside nebula", -100f * penalty, 262// fleet.getStats().getFleetwideMaxBurnMod()); 263 264 265// if (fleet.isPlayerFleet()) { 266// System.out.println("23gfgwefwef"); 267// } 268// String buffId = getModId(); 269// float buffDur = 0.1f; 270// for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) { 271// float penalty = burnPenalty.get(member.getHullSpec().getHullSize()); 272// 273// Buff test = member.getBuffManager().getBuff(buffId); 274// if (test instanceof MaxBurnBuff) { 275// MaxBurnBuff buff = (MaxBurnBuff) test; 276// buff.setDur(buffDur); 277// } else { 278// member.getBuffManager().addBuff(new MaxBurnBuff(buffId, -penalty, buffDur)); 279// } 280// } 281 } 282 } 283 284// public static float getBurnPenalty(CampaignFleetAPI fleet) { 285// float min = Global.getSettings().getBaseFleetSelectionRadius() + Global.getSettings().getFleetSelectionRadiusPerUnitSize(); 286// float max = Global.getSettings().getMaxFleetSelectionRadius(); 287// float radius = fleet.getRadius(); 288// 289// float penalty = 1f - (radius - min) / (max - min); 290// if (penalty > 1) penalty = 1; 291// if (penalty < 0) penalty = 0; 292// penalty = MIN_BURN_PENALTY + penalty * BURN_PENALTY_RANGE; 293// 294// float skillMod = fleet.getCommanderStats().getDynamic().getValue(Stats.NAVIGATION_PENALTY_MULT); 295// penalty *= skillMod; 296// 297// return penalty; 298// } 299 300 public boolean hasTooltip() { 301 return true; 302 } 303 304 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) { 305 float pad = 10f; 306 float small = 5f; 307 Color gray = Misc.getGrayColor(); 308 Color highlight = Misc.getHighlightColor(); 309 Color fuel = Global.getSettings().getColor("progressBarFuelColor"); 310 Color bad = Misc.getNegativeHighlightColor(); 311 Color text = Misc.getTextColor(); 312 313 tooltip.addTitle("Nebula"); 314 tooltip.addPara(Global.getSettings().getDescription(getTerrainId(), Type.TERRAIN).getText1(), pad); 315 float nextPad = pad; 316 if (expanded) { 317 tooltip.addSectionHeading("Travel", Alignment.MID, pad); 318 nextPad = small; 319 } 320 tooltip.addPara("Reduces the range at which fleets inside can be detected by %s.", nextPad, 321 highlight, 322 "" + (int) ((1f - VISIBLITY_MULT) * 100) + "%" 323 ); 324 325 tooltip.addPara("Reduces the travel speed of fleets inside by up to %s. Larger fleets are slowed down more.", 326 pad, 327 highlight, 328 "" + (int) ((Misc.BURN_PENALTY_MULT) * 100f) + "%" 329 ); 330 331 float penalty = Misc.getBurnMultForTerrain(Global.getSector().getPlayerFleet()); 332 String penaltyStr = Misc.getRoundedValue(1f - penalty); 333 tooltip.addPara("Your fleet's speed is reduced by %s.", pad, 334 highlight, 335 "" + (int) Math.round((1f - penalty) * 100) + "%" 336 //Strings.X + penaltyStr 337 ); 338 339// tooltip.addPara("Reduces the maximum burn level of ships depending on size. Larger ship classes are able to exploit a higher mass to cross section ratio and suffer a smaller penalty.", pad); 340// tooltip.beginGrid(150, 1); 341// tooltip.addToGrid(0, 0, " Frigates", "" + -burnPenalty.get(HullSize.FRIGATE).intValue()); 342// tooltip.addToGrid(0, 1, " Destroyers", "" + -burnPenalty.get(HullSize.DESTROYER).intValue()); 343// tooltip.addToGrid(0, 2, " Cruisers", "" + -burnPenalty.get(HullSize.CRUISER).intValue()); 344// tooltip.addToGrid(0, 3, " Capital ships", "" + -burnPenalty.get(HullSize.CAPITAL_SHIP).intValue()); 345// tooltip.addGrid(small); 346 347 if (expanded) { 348 tooltip.addSectionHeading("Combat", Alignment.MID, pad); 349 tooltip.addPara("Numerous patches of nebula present on the battlefield, but the medium is not dense enough to affect ships moving at combat speeds.", small); 350// tooltip.addPara("Numerous patches of nebula present on the battlefield, slowing ships down to a percentage of their top speed.", small); 351// tooltip.beginGrid(150, 1); 352// // nebulaSpeedFighter":1, 353// // "nebulaSpeedFrigate":0.7, 354// // "nebulaSpeedDestroyer":0.8, 355// // "nebulaSpeedCruiser":0.9, 356// // "nebulaSpeedCapital":1, 357// tooltip.addToGrid(0, 0, " Frigates", "" + (int)(Global.getSettings().getFloat("nebulaSpeedFrigate") * 100f) + "%"); 358// tooltip.addToGrid(0, 1, " Destroyers", "" + (int)(Global.getSettings().getFloat("nebulaSpeedDestroyer") * 100f) + "%"); 359// tooltip.addToGrid(0, 2, " Cruisers", "" + (int)(Global.getSettings().getFloat("nebulaSpeedCruiser") * 100f) + "%"); 360// //tooltip.addToGrid(0, 3, " Capital ships", "" + (int)(Global.getSettings().getFloat("nebulaSpeedCapital") * 100f) + "%"); 361// tooltip.addGrid(small); 362// 363// tooltip.addPara("Capital ships and fighters are not affected.", pad); 364 } 365 366 //tooltip.addPara("Does not stack with other similar terrain effects.", pad); 367 } 368 369 public boolean isTooltipExpandable() { 370 return true; 371 } 372 373 public float getTooltipWidth() { 374 return 350f; 375 } 376 377 public String getEffectCategory() { 378 return "nebula-like"; 379 } 380 381 public boolean hasAIFlag(Object flag) { 382 return flag == TerrainAIFlags.REDUCES_DETECTABILITY || 383 flag == TerrainAIFlags.REDUCES_SPEED_LARGE|| 384 flag == TerrainAIFlags.TILE_BASED 385 ; 386 } 387} 388 389 390