001package com.fs.starfarer.api.impl.campaign; 002 003import java.awt.Color; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.EveryFrameScript; 008import com.fs.starfarer.api.Global; 009import com.fs.starfarer.api.SoundAPI; 010import com.fs.starfarer.api.campaign.CampaignEngineLayers; 011import com.fs.starfarer.api.campaign.CampaignEventListener.FleetDespawnReason; 012import com.fs.starfarer.api.campaign.CampaignFleetAPI; 013import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI; 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.combat.ViewportAPI; 018import com.fs.starfarer.api.graphics.SpriteAPI; 019import com.fs.starfarer.api.impl.campaign.abilities.InterdictionPulseAbility; 020import com.fs.starfarer.api.impl.campaign.enc.EncounterManager; 021import com.fs.starfarer.api.impl.campaign.ids.MemFlags; 022import com.fs.starfarer.api.impl.campaign.ids.Tags; 023import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints; 024import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin; 025import com.fs.starfarer.api.util.FaderUtil; 026import com.fs.starfarer.api.util.FlickerUtilV2; 027import com.fs.starfarer.api.util.Misc; 028 029public class AbyssalLightEntityPlugin extends BaseCustomEntityPlugin { 030 031 public static enum DespawnType { 032 FADE_OUT, 033 EXPAND, 034 } 035 036 public static float SENSOR_BURST_TRIGGER_RANGE = 500f; 037 public static float DWELLER_TRIGGER_RANGE = 200f; 038 039 public static float MIN_DURATION = 20f; 040 public static float MAX_DURATION = 30f; 041 042 public static float MIN_SIZE = 600f; 043 public static float MAX_SIZE = 1200f; 044 045 public static float DESPAWN_POOF_THRESHOLD = 0.7f; 046 047 public static float GLOW_FREQUENCY = 0.2f; // on/off cycles per second 048 049 public static float PLAYER_PROXIMITY_MIN_BRIGHTNESS_AT = 2000f; 050 public static float PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT = 300f; 051 public static float PLAYER_PROXIMITY_MIN_BRIGHTNESS = 0.25f; 052 053 054 public static class DwellerEncounterScript implements EveryFrameScript { 055 protected float elapsed = 0f; 056 protected String trigger; 057 protected boolean done = false; 058 protected float triggerDelay; 059 protected SectorEntityToken light; 060 protected CampaignFleetAPI fleet; 061 public DwellerEncounterScript(String trigger, CampaignFleetAPI fleet, SectorEntityToken light) { 062 this.trigger = trigger; 063 this.fleet = fleet; 064 this.light = light; 065 triggerDelay = 1f + (float) Math.random() * 1f; 066 067 } 068 public boolean isDone() { 069 return done; 070 } 071 public boolean runWhilePaused() { 072 return false; 073 } 074 public void advance(float amount) { 075 if (done) return; 076 077 if (Global.getSector().isPaused() || Global.getSector().getCampaignUI().isShowingDialog()) { 078 return; 079 } 080 081 elapsed += amount; 082 083 if (fleet == null || elapsed > 3f || !light.isAlive() || light.hasTag(Tags.FADING_OUT_AND_EXPIRING) || 084 fleet.getContainingLocation() != light.getContainingLocation()) { 085 done = true; 086 return; 087 } 088 089 float dist = Misc.getDistance(fleet, light) - fleet.getRadius() - light.getRadius(); 090 if (dist > DWELLER_TRIGGER_RANGE) { 091 done = true; 092 return; 093 } 094 095 096 if (elapsed > triggerDelay) { 097 if (fleet.isPlayerFleet()) { 098 Misc.showRuleDialog(light, trigger); 099 } else { 100 fleet.despawn(FleetDespawnReason.DESTROYED_BY_BATTLE, light); 101 if (light.getCustomPlugin() instanceof AbyssalLightEntityPlugin) { 102 AbyssalLightEntityPlugin plugin = (AbyssalLightEntityPlugin) light.getCustomPlugin(); 103 plugin.despawn(DespawnType.FADE_OUT); 104 } 105 } 106 done = true; 107 return; 108 } 109 } 110 } 111 public static class AbyssalLightSoundStopper implements EveryFrameScript { 112 protected transient SoundAPI sound = null; 113 protected float elapsed = 0f; 114 public AbyssalLightSoundStopper(SoundAPI sound) { 115 this.sound = sound; 116 } 117 public boolean isDone() { 118 return sound == null; 119 } 120 public boolean runWhilePaused() { 121 return true; 122 } 123 public void advance(float amount) { 124 elapsed += amount; 125 if (sound == null) return; 126 if (!sound.isPlaying() && elapsed > 1f) { 127 sound = null; 128 return; 129 } 130 131 if (Global.getSector().isPaused() && sound != null) { 132 sound.stop(); 133 sound = null; 134 } 135 } 136 } 137 public static class AbyssalLightParams { 138 public Color color = new Color(200,200,255,255); 139 public float frequencyMultMin = 0.5f; 140 public float frequencyMultMax = 1.5f; 141 public float frequencyChangeMult = 1f; 142 public float size; 143 public float detectedRange; 144 public float bonusMult; 145 public float durationDays; 146 public int pointsOverride = 0; 147 148 public AbyssalLightParams() { 149 this(MIN_SIZE, MAX_SIZE); 150 } 151 public AbyssalLightParams(float minSize, float maxSize) { 152 frequencyMultMin = 0.5f; 153 frequencyMultMax = 1.5f; 154 155 float sizeRange = maxSize - minSize; 156 float avgSize = MIN_SIZE + (MAX_SIZE - MIN_SIZE) * 0.5f; 157 158 159 size = minSize + (float) Math.random() * sizeRange; 160 detectedRange = (size * 3f) / HyperspaceTerrainPlugin.ABYSS_SENSOR_RANGE_MULT; 161 162 bonusMult = size / avgSize; 163 164 durationDays = MIN_DURATION + (MAX_DURATION - MIN_DURATION) * (float) Math.random(); 165 } 166 167 public int getTopographyPoints() { 168 if (pointsOverride > 0) return pointsOverride; 169 170 return Math.round(HTPoints.ABYSSAL_LIGHT_MIN + 171 (HTPoints.ABYSSAL_LIGHT_AVG - HTPoints.ABYSSAL_LIGHT_MIN) * bonusMult); 172 } 173 } 174 175 176 transient private SpriteAPI glow; 177 178 179 protected float phase = 0f; 180 protected float frequencyMult = 1f; 181 protected FlickerUtilV2 flicker = new FlickerUtilV2(); 182 protected FaderUtil fader = new FaderUtil(0f, 0.5f, 0.5f); 183 protected AbyssalLightParams params; 184 protected float untilFrequencyChange = 0f; 185 protected float untilSoundPlayed = 0f; 186 protected float flickerDur = 0f; 187 protected float abilityResponseFlickerTimeout = 0f; 188 protected DespawnType despawnType = null; 189 protected boolean playedDespawnSound = false; 190 191 public void init(SectorEntityToken entity, Object pluginParams) { 192 super.init(entity, pluginParams); 193 params = (AbyssalLightParams) pluginParams; 194 195 float radiusMult = params.bonusMult; 196 if (radiusMult > 1f) { 197 radiusMult = 1f + (radiusMult - 1f) * 0.33f; 198 } else if (radiusMult < 1f) { 199 radiusMult = 1f - (1f - radiusMult) * 0.33f; 200 } 201 ((CustomCampaignEntityAPI) entity).setRadius(entity.getRadius() * radiusMult); 202 entity.setSensorProfile(1f); 203 entity.setDiscoverable(false); 204 //entity.setDiscoveryXP(spec.getDiscoveryXP()); 205 206 entity.getDetectedRangeMod().modifyFlat("gen", params.detectedRange); 207 entity.setExtendedDetectedAtRange(2000f); 208 entity.setDetectionRangeDetailsOverrideMult(0.5f); 209 entity.getMemoryWithoutUpdate().set(MemFlags.EXTRA_SENSOR_INDICATORS, 3); 210 211 updateFrequency(0f); 212 updateSoundDelayAndPlaySound(0f); 213 readResolve(); 214 } 215 216 public boolean isDespawning() { 217 return despawnType != null || entity.hasTag(Tags.FADING_OUT_AND_EXPIRING); 218 } 219 220 public void despawn(DespawnType type) { 221 if (isDespawning()) return; 222 223 float dur = 1f; 224 if (type == DespawnType.EXPAND) dur = 2f; 225 Misc.fadeAndExpire(entity, dur); 226 despawnType = type; 227 228 if (type == DespawnType.EXPAND && entity.isInCurrentLocation()) { 229 VisibilityLevel level = entity.getVisibilityLevelToPlayerFleet(); 230 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) { 231 Global.getSoundPlayer().playSound("abyssal_light_expand_despawn_windup", 1f, 1f, entity.getLocation(), Misc.ZERO); 232 } 233 } 234 } 235 236 public void updateSoundDelayAndPlaySound(float amount) { 237 untilSoundPlayed -= amount; 238 if (untilSoundPlayed <= 0f) { 239 //untilSoundPlayed = 0.5f + (float) Math.random() * 20f; 240 untilSoundPlayed = 5f + (float) Math.random() * 30f; 241 242 // don't play sound when called from the constructor with amount == 0f 243 if (amount > 0 && entity.isInCurrentLocation()) { 244 VisibilityLevel level = entity.getVisibilityLevelToPlayerFleet(); 245 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) { 246 float volume = 1f; 247 if (params.bonusMult < 1f) { 248 volume = 1f - (1f - params.bonusMult) * 0.6f; 249 } 250 if (volume > 1f) volume = 1f; 251 if (volume < 0f) volume = 0f; 252 253 float pitchMult = 1f; 254 if (isDweller()) { 255 pitchMult = 0.5f; 256 } 257 258 SoundAPI sound = Global.getSoundPlayer().playSound("abyssal_light_random_sound", 1f * pitchMult, volume, entity.getLocation(), Misc.ZERO); 259 Global.getSector().addScript(new AbyssalLightSoundStopper(sound)); 260 //flickerDur = 3f + 2f * (float) Math.random(); 261 flickerDur = 0.5f + 0.5f * (float) Math.random(); 262 263// too random 264// if (isDweller()) { 265// CampaignFleetAPI fleet = Global.getSector().getPlayerFleet(); 266// if (fleet != null && abilityResponseFlickerTimeout <= 0f) { 267// flickerDur = 0.5f + 0.5f * (float) Math.random(); 268// abilityResponseFlickerTimeout = 3f; 269// float dist = Misc.getDistance(fleet, entity); 270// if (dist < DWELLER_TRIGGER_RANGE + fleet.getRadius() + entity.getRadius()) { 271// Global.getSector().addScript(new DwellerEncounterScript("DwellerAttackAfterAbilityUse", entity)); 272// } 273// } 274// } 275 } 276 } 277 } 278 } 279 public void updateFrequency(float amount) { 280 untilFrequencyChange -= amount * params.frequencyChangeMult; 281 if (untilFrequencyChange <= 0f) { 282 untilFrequencyChange = 1f + (float) Math.random() * 3f; 283 284 frequencyMult = params.frequencyMultMin * 285 (float) Math.random() * (params.frequencyMultMax - params.frequencyMultMin); 286 } 287 } 288 289 Object readResolve() { 290 glow = Global.getSettings().getSprite("campaignEntities", "abyssal_light_glow"); 291 return this; 292 } 293 294 public AbyssalLightParams getParams() { 295 return params; 296 } 297 298 public boolean isDweller() { 299 return entity != null && entity.hasTag(Tags.DWELLER_LIGHT); 300 } 301 302 public void advance(float amount) { 303 if (isDespawning()) { 304 if (!playedDespawnSound && 305 (getDespawnProgress() > DESPAWN_POOF_THRESHOLD || despawnType == DespawnType.FADE_OUT)) { 306 playedDespawnSound = true; 307 if (entity.isInCurrentLocation()) { 308 VisibilityLevel level = entity.getVisibilityLevelToPlayerFleet(); 309 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) { 310 String soundId = "abyssal_light_despawn_disrupted"; 311 if (despawnType == DespawnType.FADE_OUT) { 312 soundId = "abyssal_light_despawn_expired"; 313 } 314 Global.getSoundPlayer().playSound(soundId, 1f, 1f, entity.getLocation(), Misc.ZERO); 315 } 316 } 317 } 318 319 return; 320 } 321 322 //boolean dweller = isDespawning(); 323 324 float days = Misc.getDays(amount); 325 params.durationDays -= days; 326 if (params.durationDays <= 0f || Misc.getAbyssalDepth(entity) < 1f) { 327 despawn(DespawnType.FADE_OUT); 328 return; 329 } 330 331 updateFrequency(amount); 332 updateSoundDelayAndPlaySound(amount); 333 334 phase += amount * GLOW_FREQUENCY * frequencyMult; 335 while (phase > 1) phase --; 336 337 if (flickerDur > 0) { 338 flickerDur -= amount; 339 if (flickerDur < 0) flickerDur = 0; 340 } 341 if (abilityResponseFlickerTimeout > 0) { 342 abilityResponseFlickerTimeout -= amount; 343 if (abilityResponseFlickerTimeout < 0) abilityResponseFlickerTimeout = 0; 344 //System.out.println("Timeout: " + abilityResponseFlickerTimeout); 345 } 346 347 flicker.advance(amount * 10f); 348 fader.advance(amount); 349 350 if (Global.getSector().getMemoryWithoutUpdate().getBoolean(MemFlags.GLOBAL_INTERDICTION_PULSE_JUST_USED_IN_CURRENT_LOCATION)) { 351 if (entity.getContainingLocation() != null) { 352 for (CampaignFleetAPI fleet : entity.getContainingLocation().getFleets()) { 353 float range = InterdictionPulseAbility.getRange(fleet); 354 float dist = Misc.getDistance(fleet.getLocation(), entity.getLocation()); 355 if (dist > range) continue; 356 357 358 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.JUST_DID_INTERDICTION_PULSE)) { 359 if (isDweller()) { 360 if (abilityResponseFlickerTimeout <= 0f) { 361 flickerDur = 0.5f + 0.5f * (float) Math.random(); 362 abilityResponseFlickerTimeout = 6f; 363 if (dist < DWELLER_TRIGGER_RANGE + fleet.getRadius() + entity.getRadius()) { 364 Global.getSector().addScript(new DwellerEncounterScript("DwellerAttackAfterAbilityUse", fleet, entity)); 365 } 366 } 367 } else { 368 AbyssalLightBonus bonus = AbyssalLightBonus.get(fleet); 369 370 float brightness = getProximityBasedBrightnessFactor(fleet, entity.getLocation()); 371 bonus.addBurnBonus(params.bonusMult * brightness); 372 373 if (fleet.isPlayerFleet()) { 374 bonus.addTopographyPoints(params.getTopographyPoints()); 375 } 376 377 despawn(DespawnType.EXPAND); 378 } 379 } 380 } 381 } 382 if (isDespawning()) return; 383 } 384 385 if (Global.getSector().getMemoryWithoutUpdate().getBoolean(MemFlags.GLOBAL_SENSOR_BURST_JUST_USED_IN_CURRENT_LOCATION)) { 386 if (entity.getContainingLocation() != null) { 387 for (CampaignFleetAPI fleet : entity.getContainingLocation().getFleets()) { 388 float range = SENSOR_BURST_TRIGGER_RANGE + fleet.getRadius() + entity.getRadius(); 389 float dist = Misc.getDistance(fleet.getLocation(), entity.getLocation()); 390 if (dist > range) continue; 391 392 393 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.JUST_DID_SENSOR_BURST)) { 394 if (isDweller()) { 395 if (abilityResponseFlickerTimeout <= 0f) { 396 flickerDur = 0.5f + 0.5f * (float) Math.random(); 397 abilityResponseFlickerTimeout = 6f; 398 if (dist < DWELLER_TRIGGER_RANGE + fleet.getRadius() + entity.getRadius()) { 399 Global.getSector().addScript(new DwellerEncounterScript("DwellerAttackAfterAbilityUse", fleet, entity)); 400 } 401 } 402 } else { 403 AbyssalLightBonus bonus = AbyssalLightBonus.get(fleet); 404 405 float brightness = getProximityBasedBrightnessFactor(fleet, entity.getLocation()); 406 bonus.addSensorBonus(params.bonusMult * brightness); 407 408 if (fleet.isPlayerFleet()) { 409 bonus.addTopographyPoints(params.getTopographyPoints()); 410 411 // can cause overlapping gravity wells etc 412 //EncounterManager.getInstance().getPointTimeout().clear(); 413 EncounterManager.getInstance().getCreatorTimeout().clear(); 414 } 415 416 despawn(DespawnType.EXPAND); 417 } 418 } 419 } 420 } 421 if (isDespawning()) return; 422 } 423 } 424 425 public float getFlickerBasedMult() { 426 if (flickerDur <= 0f) return 1f; 427 428 float mult = 1f; 429 if (flickerDur < 1f) mult = flickerDur; 430 431 if (isDweller()) { 432 mult *= 0.75f; 433 } else { 434 mult *= 0.25f; 435 } 436 437 float f = 1f - flicker.getBrightness() * mult; 438 return f; 439 } 440 441 public float getGlowAlpha() { 442 float glowAlpha = 0f; 443 if (phase < 0.5f) glowAlpha = phase * 2f; 444 if (phase >= 0.5f) glowAlpha = (1f - (phase - 0.5f) * 2f); 445 glowAlpha = 0.75f + glowAlpha * 0.25f; 446 447 if (glowAlpha < 0) glowAlpha = 0; 448 if (glowAlpha > 1) glowAlpha = 1; 449 return glowAlpha; 450 } 451 452 453 454 public float getRenderRange() { 455 return entity.getRadius() + params.size * 0.75f; 456 } 457 458 public float getDespawnProgress() { 459 if (!isDespawning()) return 0f; 460 float f = entity.getSensorFaderBrightness(); 461 return 1 - f; 462 } 463 464 public void render(CampaignEngineLayers layer, ViewportAPI viewport) { 465 float alphaMult = viewport.getAlphaMult(); 466 467 if (!isDespawning() || despawnType == DespawnType.FADE_OUT) { 468 alphaMult *= entity.getSensorFaderBrightness(); 469 } 470 471 if (alphaMult <= 0) return; 472 473 float f = getDespawnProgress(); 474 if (despawnType == DespawnType.FADE_OUT) { 475 f = 0f; 476 } 477 478 if (f > DESPAWN_POOF_THRESHOLD) { 479 float fadeOut = (1f - f) / (1f - DESPAWN_POOF_THRESHOLD); 480 alphaMult *= fadeOut; 481 } 482 483 VisibilityLevel level = entity.getVisibilityLevelToPlayerFleet(); 484 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) { 485 fader.fadeIn(); 486 } else { 487 fader.fadeOut(); 488 } 489 490 alphaMult *= fader.getBrightness(); 491 492 float b = getPlayerProximityBasedBrightnessFactor(entity); 493 alphaMult *= b; 494 495 496// if (Misc.getDistanceToPlayerLY(entity) > 0.1f) { 497// Misc.fadeAndExpire(entity); 498// return; 499// } 500// if (!Global.getSector().isPaused()) { 501// System.out.println("Alpha: " + alphaMult); 502// } 503 504 CustomEntitySpecAPI spec = entity.getCustomEntitySpec(); 505 if (spec == null) return; 506 507 float w = spec.getSpriteWidth(); 508 float h = spec.getSpriteHeight(); 509 510 Vector2f loc = entity.getLocation(); 511 512 float glowAlpha = getGlowAlpha(); 513 514 glow.setColor(params.color); 515 516 w = params.size; 517 h = params.size; 518 519 float scale = 0.25f + alphaMult * 0.75f; 520 if (f > DESPAWN_POOF_THRESHOLD) { 521 scale *= 1.5f; 522 } 523 524 float fringeScale = 1f; 525 //fringeScale = 1.5f; 526 527 glow.setAdditiveBlend(); 528 529 if (layer == CampaignEngineLayers.TERRAIN_8) { 530 //float flicker = getFlickerBasedMult(); 531 glow.setAlphaMult(alphaMult * glowAlpha * 0.5f); 532 glow.setSize(w * scale * fringeScale, h * scale * fringeScale); 533 534 glow.renderAtCenter(loc.x, loc.y); 535 } 536 537 if (layer == CampaignEngineLayers.STATIONS) { 538 if (f > 0f) { 539 float extra = 1f + f * 1.33f; 540 if (f > DESPAWN_POOF_THRESHOLD) extra = 0f; 541 scale *= extra; 542 } 543 float flicker = getFlickerBasedMult(); 544 for (int i = 0; i < 5; i++) { 545 if (i != 0) flicker = 1f; 546 547 w *= 0.3f; 548 h *= 0.3f; 549 glow.setSize(w * scale, h * scale); 550 glow.setAlphaMult(alphaMult * glowAlpha * 0.67f * flicker); 551 glow.renderAtCenter(loc.x, loc.y); 552 } 553 } 554 } 555 556 557 public static float getPlayerProximityBasedBrightnessFactor(SectorEntityToken entity) { 558 return getPlayerProximityBasedBrightnessFactor(entity.getLocation()); 559 } 560 public static float getPlayerProximityBasedBrightnessFactor(Vector2f loc) { 561 CampaignFleetAPI player = Global.getSector().getPlayerFleet(); 562 if (player == null) { 563 return PLAYER_PROXIMITY_MIN_BRIGHTNESS; 564 } 565 return getProximityBasedBrightnessFactor(player, loc); 566 } 567 568 public static float getProximityBasedBrightnessFactor(CampaignFleetAPI from, Vector2f loc) { 569 570 float dist = Misc.getDistance(from.getLocation(), loc) - from.getRadius(); 571 572 if (dist <= PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT) { 573 return 1f; 574 //return Math.max(PLAYER_PROXIMITY_MIN_BRIGHTNESS, dist / PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT); 575 } 576 dist -= PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT; 577 578 float f = 1f - dist / (PLAYER_PROXIMITY_MIN_BRIGHTNESS_AT - PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT); 579 if (f < 0f) f = 0f; 580 581 float b = PLAYER_PROXIMITY_MIN_BRIGHTNESS + f * (1f - PLAYER_PROXIMITY_MIN_BRIGHTNESS); 582 583 return b; 584 } 585 586 587// @Override 588// public void createMapTooltip(TooltipMakerAPI tooltip, boolean expanded) { 589// String post = ""; 590// Color color = entity.getFaction().getBaseUIColor(); 591// Color postColor = color; 592// if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.DESTROYED.getBeaconFlag())) { 593// post = " - Low"; 594// postColor = Misc.getPositiveHighlightColor(); 595// } else if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.SUPPRESSED.getBeaconFlag())) { 596// post = " - Medium"; 597// postColor = Misc.getHighlightColor(); 598// } else if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.RESURGENT.getBeaconFlag())) { 599// post = " - High"; 600// postColor = Misc.getNegativeHighlightColor(); 601// } 602// 603// tooltip.addPara(entity.getName() + post, 0f, color, postColor, post.replaceFirst(" - ", "")); 604// } 605// 606// @Override 607// public boolean hasCustomMapTooltip() { 608// return true; 609// } 610// 611// @Override 612// public void appendToCampaignTooltip(TooltipMakerAPI tooltip, VisibilityLevel level) { 613// if (level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS || 614// level == VisibilityLevel.COMPOSITION_DETAILS) { 615// 616// String post = ""; 617// Color color = Misc.getTextColor(); 618// Color postColor = color; 619// if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.DESTROYED.getBeaconFlag())) { 620// post = "low"; 621// postColor = Misc.getPositiveHighlightColor(); 622// } else if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.SUPPRESSED.getBeaconFlag())) { 623// post = "medium"; 624// postColor = Misc.getHighlightColor(); 625// } else if (entity.getMemoryWithoutUpdate().getBoolean(RemnantSystemType.RESURGENT.getBeaconFlag())) { 626// post = "high"; 627// postColor = Misc.getNegativeHighlightColor(); 628// } 629// if (!post.isEmpty()) { 630// tooltip.setParaFontDefault(); 631// tooltip.addPara(BaseIntelPlugin.BULLET + "Danger level: " + post, 10f, color, postColor, post); 632// } 633// } 634// 635// } 636} 637 638 639 640 641 642 643 644 645