1package com.fs.starfarer.api.impl.campaign;
5import org.lwjgl.util.vector.Vector2f;
7import com.fs.starfarer.api.EveryFrameScript;
8import com.fs.starfarer.api.Global;
9import com.fs.starfarer.api.SoundAPI;
10import com.fs.starfarer.api.campaign.CampaignEngineLayers;
11import com.fs.starfarer.api.campaign.CampaignFleetAPI;
12import com.fs.starfarer.api.campaign.CustomCampaignEntityAPI;
13import com.fs.starfarer.api.campaign.CustomEntitySpecAPI;
14import com.fs.starfarer.api.campaign.SectorEntityToken;
15import com.fs.starfarer.api.campaign.SectorEntityToken.VisibilityLevel;
16import com.fs.starfarer.api.combat.ViewportAPI;
17import com.fs.starfarer.api.graphics.SpriteAPI;
18import com.fs.starfarer.api.impl.campaign.abilities.InterdictionPulseAbility;
19import com.fs.starfarer.api.impl.campaign.ids.MemFlags;
20import com.fs.starfarer.api.impl.campaign.ids.Tags;
21import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTPoints;
22import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin;
23import com.fs.starfarer.api.util.FaderUtil;
24import com.fs.starfarer.api.util.FlickerUtilV2;
25import com.fs.starfarer.api.util.Misc;
29 public static enum DespawnType {
50 protected transient SoundAPI sound =
null;
51 protected float elapsed = 0f;
52 public AbyssalLightSoundStopper(
SoundAPI sound) {
55 public boolean isDone() {
58 public boolean runWhilePaused() {
61 public void advance(
float amount) {
63 if (sound ==
null)
return;
75 public static class AbyssalLightParams {
76 public Color color =
new Color(200,200,255,255);
77 public float frequencyMultMin = 0.5f;
78 public float frequencyMultMax = 1.5f;
79 public float frequencyChangeMult = 1f;
81 public float detectedRange;
82 public float bonusMult;
83 public float durationDays;
84 public int pointsOverride = 0;
86 public AbyssalLightParams() {
89 public AbyssalLightParams(
float minSize,
float maxSize) {
90 frequencyMultMin = 0.5f;
91 frequencyMultMax = 1.5f;
93 float sizeRange = maxSize - minSize;
97 size = minSize + (float) Math.random() * sizeRange;
98 detectedRange = (size * 3f) / HyperspaceTerrainPlugin.ABYSS_SENSOR_RANGE_MULT;
100 bonusMult = size / avgSize;
105 public int getTopographyPoints() {
106 if (pointsOverride > 0)
return pointsOverride;
108 return Math.round(HTPoints.ABYSSAL_LIGHT_MIN +
109 (HTPoints.ABYSSAL_LIGHT_AVG - HTPoints.ABYSSAL_LIGHT_MIN) * bonusMult);
114 transient private SpriteAPI glow;
119 protected FlickerUtilV2
flicker =
new FlickerUtilV2();
120 protected FaderUtil
fader =
new FaderUtil(0f, 0.5f, 0.5f);
128 public void init(SectorEntityToken
entity, Object pluginParams) {
129 super.init(
entity, pluginParams);
130 params = (AbyssalLightParams) pluginParams;
132 float radiusMult =
params.bonusMult;
133 if (radiusMult > 1f) {
134 radiusMult = 1f + (radiusMult - 1f) * 0.33f;
135 }
else if (radiusMult < 1f) {
136 radiusMult = 1f - (1f - radiusMult) * 0.33f;
138 ((CustomCampaignEntityAPI)
entity).setRadius(
entity.getRadius() * radiusMult);
139 entity.setSensorProfile(1f);
140 entity.setDiscoverable(
false);
143 entity.getDetectedRangeMod().modifyFlat(
"gen",
params.detectedRange);
144 entity.setExtendedDetectedAtRange(2000f);
145 entity.setDetectionRangeDetailsOverrideMult(0.5f);
146 entity.getMemoryWithoutUpdate().set(MemFlags.EXTRA_SENSOR_INDICATORS, 3);
161 if (type == DespawnType.EXPAND) dur = 2f;
162 Misc.fadeAndExpire(
entity, dur);
165 if (type == DespawnType.EXPAND &&
entity.isInCurrentLocation()) {
166 VisibilityLevel level =
entity.getVisibilityLevelToPlayerFleet();
167 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
180 if (amount > 0 &&
entity.isInCurrentLocation()) {
181 VisibilityLevel level =
entity.getVisibilityLevelToPlayerFleet();
182 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
184 if (
params.bonusMult < 1f) {
185 volume = 1f - (1f -
params.bonusMult) * 0.6f;
187 if (volume > 1f) volume = 1f;
188 if (volume < 0f) volume = 0f;
192 flickerDur = 0.5f + 0.5f * (float) Math.random();
203 (float) Math.random() * (params.frequencyMultMax -
params.frequencyMultMin);
207 Object readResolve() {
222 if (
entity.isInCurrentLocation()) {
223 VisibilityLevel level =
entity.getVisibilityLevelToPlayerFleet();
224 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
225 String soundId =
"abyssal_light_despawn_disrupted";
227 soundId =
"abyssal_light_despawn_expired";
237 float days = Misc.getDays(amount);
238 params.durationDays -= days;
239 if (
params.durationDays <= 0f || Misc.getAbyssalDepth(
entity) < 1f) {
256 fader.advance(amount);
258 if (
Global.
getSector().getMemoryWithoutUpdate().getBoolean(MemFlags.GLOBAL_INTERDICTION_PULSE_JUST_USED_IN_CURRENT_LOCATION)) {
259 if (
entity.getContainingLocation() !=
null) {
260 for (CampaignFleetAPI fleet :
entity.getContainingLocation().getFleets()) {
261 float range = InterdictionPulseAbility.getRange(fleet);
262 float dist = Misc.getDistance(fleet.getLocation(),
entity.getLocation());
263 if (dist > range)
continue;
266 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.JUST_DID_INTERDICTION_PULSE)) {
272 if (fleet.isPlayerFleet()) {
283 if (
Global.
getSector().getMemoryWithoutUpdate().getBoolean(MemFlags.GLOBAL_SENSOR_BURST_JUST_USED_IN_CURRENT_LOCATION)) {
284 if (
entity.getContainingLocation() !=
null) {
285 for (CampaignFleetAPI fleet :
entity.getContainingLocation().getFleets()) {
286 float range = 500f + fleet.getRadius() +
entity.getRadius();
287 float dist = Misc.getDistance(fleet.getLocation(),
entity.getLocation());
288 if (dist > range)
continue;
291 if (fleet.getMemoryWithoutUpdate().getBoolean(MemFlags.JUST_DID_SENSOR_BURST)) {
297 if (fleet.isPlayerFleet()) {
317 float f = 1f -
flicker.getBrightness() * mult;
322 float glowAlpha = 0f;
324 if (
phase >= 0.5f) glowAlpha = (1f - (
phase - 0.5f) * 2f);
325 glowAlpha = 0.75f + glowAlpha * 0.25f;
328 if (glowAlpha < 0) glowAlpha = 0;
329 if (glowAlpha > 1) glowAlpha = 1;
336 return entity.getRadius() + params.size * 0.75f;
341 float f =
entity.getSensorFaderBrightness();
345 public void render(CampaignEngineLayers layer, ViewportAPI viewport) {
346 float alphaMult = viewport.getAlphaMult();
349 alphaMult *=
entity.getSensorFaderBrightness();
352 if (alphaMult <= 0)
return;
361 alphaMult *= fadeOut;
364 VisibilityLevel level =
entity.getVisibilityLevelToPlayerFleet();
365 if (level == VisibilityLevel.COMPOSITION_DETAILS || level == VisibilityLevel.COMPOSITION_AND_FACTION_DETAILS) {
371 alphaMult *=
fader.getBrightness();
385 CustomEntitySpecAPI spec =
entity.getCustomEntitySpec();
386 if (spec ==
null)
return;
388 float w = spec.getSpriteWidth();
389 float h = spec.getSpriteHeight();
391 Vector2f loc =
entity.getLocation();
395 glow.setColor(
params.color);
400 float scale = 0.25f + alphaMult * 0.75f;
405 float fringeScale = 1f;
408 glow.setAdditiveBlend();
410 if (layer == CampaignEngineLayers.TERRAIN_8) {
412 glow.setAlphaMult(alphaMult * glowAlpha * 0.5f);
413 glow.setSize(w * scale * fringeScale, h * scale * fringeScale);
415 glow.renderAtCenter(loc.x, loc.y);
418 if (layer == CampaignEngineLayers.STATIONS) {
420 float extra = 1f + f * 1.33f;
425 for (
int i = 0; i < 5; i++) {
430 glow.setSize(w * scale, h * scale);
431 glow.setAlphaMult(alphaMult * glowAlpha * 0.67f *
flicker);
432 glow.renderAtCenter(loc.x, loc.y);
443 if (player ==
null) {
451 float dist = Misc.getDistance(from.getLocation(), loc) - from.getRadius();
static SettingsAPI getSettings()
static SoundPlayerAPI getSoundPlayer()
static SectorAPI getSector()
void addSensorBonus(float bonus)
static AbyssalLightBonus get(CampaignFleetAPI fleet)
void addTopographyPoints(int points)
void addBurnBonus(float bonus)
static float getPlayerProximityBasedBrightnessFactor(SectorEntityToken entity)
void updateSoundDelayAndPlaySound(float amount)
static float MIN_DURATION
static float DESPAWN_POOF_THRESHOLD
static float PLAYER_PROXIMITY_MAX_BRIGHTNESS_AT
AbyssalLightParams getParams()
static float getProximityBasedBrightnessFactor(CampaignFleetAPI from, Vector2f loc)
static float getPlayerProximityBasedBrightnessFactor(Vector2f loc)
static float GLOW_FREQUENCY
static float MAX_DURATION
void despawn(DespawnType type)
AbyssalLightParams params
float getFlickerBasedMult()
void advance(float amount)
boolean playedDespawnSound
static float PLAYER_PROXIMITY_MIN_BRIGHTNESS_AT
static float PLAYER_PROXIMITY_MIN_BRIGHTNESS
void init(SectorEntityToken entity, Object pluginParams)
void updateFrequency(float amount)
void render(CampaignEngineLayers layer, ViewportAPI viewport)
float getDespawnProgress()
float untilFrequencyChange
SpriteAPI getSprite(String filename)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)