001package com.fs.starfarer.api.impl.campaign; 002 003import org.lwjgl.util.vector.Vector2f; 004 005import com.fs.starfarer.api.EveryFrameScript; 006import com.fs.starfarer.api.Global; 007import com.fs.starfarer.api.campaign.CampaignFleetAPI; 008import com.fs.starfarer.api.campaign.comm.CommMessageAPI.MessageClickAction; 009import com.fs.starfarer.api.impl.campaign.ids.Sounds; 010import com.fs.starfarer.api.impl.campaign.intel.MessageIntel; 011import com.fs.starfarer.api.impl.campaign.intel.events.ht.HTAbyssalLightFactor; 012import com.fs.starfarer.api.impl.campaign.intel.events.ht.HyperspaceTopographyEventIntel; 013import com.fs.starfarer.api.impl.campaign.terrain.HyperspaceTerrainPlugin; 014import com.fs.starfarer.api.util.Misc; 015 016public class AbyssalLightBonus implements EveryFrameScript { 017 018 public static float BURN_BONUS_MULT = 1f; 019 public static float BURN_BONUS_FLAT = 5f; 020 public static float LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS = 3f; 021 022 public static float SENSOR_BONUS_FLAT = 1000f; 023 public static float LIGHT_YEARS_PER_UNIT_OF_SENSOR_BONUS = 3f; 024 025 026 public static AbyssalLightBonus get(CampaignFleetAPI fleet) { 027 for (EveryFrameScript s : fleet.getScripts()) { 028 if (s instanceof AbyssalLightBonus) { 029 return (AbyssalLightBonus) s; 030 } 031 } 032 AbyssalLightBonus script = new AbyssalLightBonus(fleet); 033 fleet.addScript(script); 034 return script; 035 } 036 037 protected CampaignFleetAPI fleet; 038 protected float burnBonus = 0f; 039 protected float sensorBonus = 0f; 040 041 protected int framesSpentPending = 0; 042 protected float pendingBurnBonus = 0; 043 protected float pendingSensorBonus = 0; 044 protected int pendingTopographyPoints = 0; 045 protected int pendingLightsCount = 0; 046 protected Vector2f prevLoc = null; 047 048 public AbyssalLightBonus(CampaignFleetAPI fleet) { 049 this.fleet = fleet; 050 prevLoc = new Vector2f(fleet.getLocation()); 051 } 052 053 public void advance(float amount) { 054 if (fleet.isPlayerFleet()) { 055 checkPendingAndSendMessages(); 056 } 057 058 float depth = Misc.getAbyssalDepth(fleet); 059 if (depth < 1f) { 060 burnBonus = 0f; 061 sensorBonus = 0f; 062 return; 063 } 064 065 Vector2f loc = fleet.getLocation(); 066 float distLY = Misc.getDistanceLY(loc, prevLoc); 067 prevLoc.set(fleet.getLocation()); 068 069 burnBonus -= distLY / LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS; 070 sensorBonus -= distLY / LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS; 071 072 if (burnBonus < 0) burnBonus = 0; 073 if (sensorBonus < 0) sensorBonus = 0; 074 075 if (burnBonus > 0) { 076 if (BURN_BONUS_MULT != 1f) { 077 float burnMult = BURN_BONUS_MULT; 078 if (burnBonus < 1f) { 079 burnMult = 1f + (burnMult - 1f) * burnBonus; 080 if (burnMult < 1.1f) burnMult = 1.1f; 081 } 082 String ly = Misc.getRoundedValueOneAfterDecimalIfNotWhole(getBurnBonusLYRemaining(burnBonus)); 083 fleet.getStats().addTemporaryModMult(0.1f, "abyssalLight_1", 084 "Abyssal light (for " + ly + " more light-years)", burnMult, 085 fleet.getStats().getFleetwideMaxBurnMod()); 086 } 087 if (BURN_BONUS_FLAT > 0) { 088 float burnFlat = BURN_BONUS_FLAT / HyperspaceTerrainPlugin.ABYSS_BURN_MULT; 089 if (burnBonus < 1f / LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS) { 090 burnFlat *= burnBonus * LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS; 091 } 092 burnFlat = Math.round(burnFlat); 093 if (burnFlat < 1f) burnFlat = 1f; 094 095 String ly = Misc.getRoundedValueOneAfterDecimalIfNotWhole(getBurnBonusLYRemaining(burnBonus)); 096 fleet.getStats().addTemporaryModFlat(0.1f, "abyssalLight_2", 097 "Abyssal light (for " + ly + " more light-years)", burnFlat, 098 fleet.getStats().getFleetwideMaxBurnMod()); 099 } 100 } 101 102 if (sensorBonus > 0) { 103 if (SENSOR_BONUS_FLAT > 0) { 104 float sensorFlat = SENSOR_BONUS_FLAT / HyperspaceTerrainPlugin.ABYSS_SENSOR_RANGE_MULT; 105 if (sensorBonus < 1f / LIGHT_YEARS_PER_UNIT_OF_SENSOR_BONUS) { 106 sensorFlat *= sensorBonus * LIGHT_YEARS_PER_UNIT_OF_SENSOR_BONUS; 107 } 108 sensorFlat = Math.round(sensorFlat); 109 if (sensorFlat < 1f) sensorFlat = 1f; 110 111 String ly = Misc.getRoundedValueOneAfterDecimalIfNotWhole(getSensorBonusLYRemaining(sensorBonus)); 112 fleet.getStats().addTemporaryModFlat(0.1f, "abyssalLight_3", 113 "Abyssal light (for " + ly + " more light-years)", sensorFlat, 114 fleet.getStats().getSensorRangeMod()); 115 } 116 } 117 } 118 119 public float getBurnBonusLYRemaining(float bonus) { 120 return bonus * LIGHT_YEARS_PER_UNIT_OF_BURN_BONUS; 121 } 122 123 public float getSensorBonusLYRemaining(float bonus) { 124 return bonus * LIGHT_YEARS_PER_UNIT_OF_SENSOR_BONUS; 125 } 126 127 public void addBurnBonus(float bonus) { 128 if (fleet.isPlayerFleet()) { 129 pendingBurnBonus += bonus; 130 framesSpentPending = 0; 131 } else { 132 burnBonus += bonus; 133 } 134 } 135 136 public void addSensorBonus(float bonus) { 137 if (fleet.isPlayerFleet()) { 138 pendingSensorBonus += bonus; 139 framesSpentPending = 0; 140 } else { 141 sensorBonus += bonus; 142 } 143 } 144 145 public void addTopographyPoints(int points) { 146 pendingTopographyPoints += points; 147 pendingLightsCount++; 148 framesSpentPending = 0; 149 } 150 151 152 public void checkPendingAndSendMessages() { 153 framesSpentPending++; 154 if (framesSpentPending > 1) { 155 framesSpentPending = 0; 156 157 if (pendingTopographyPoints > 0) { 158 HyperspaceTopographyEventIntel.addFactorCreateIfNecessary( 159 new HTAbyssalLightFactor(pendingTopographyPoints, pendingLightsCount > 1), null); 160 pendingTopographyPoints = 0; 161 pendingLightsCount = 0; 162 } 163 if (pendingBurnBonus > 0) { 164 MessageIntel msg = new MessageIntel(); 165 String ly = Misc.getRoundedValueOneAfterDecimalIfNotWhole(getSensorBonusLYRemaining(pendingBurnBonus)); 166 msg.addLine("Increased burn level for %s light-years", Misc.getTextColor(), 167 new String[] {"+" + ly}, Misc.getHighlightColor()); 168 msg.setSound(Sounds.NONE); 169 Global.getSector().getCampaignUI().addMessage(msg, MessageClickAction.NOTHING); 170 burnBonus += pendingBurnBonus; 171 pendingBurnBonus = 0; 172 } 173 174 if (pendingSensorBonus > 0) { 175 MessageIntel msg = new MessageIntel(); 176 String ly = Misc.getRoundedValueOneAfterDecimalIfNotWhole(getSensorBonusLYRemaining(pendingSensorBonus)); 177 msg.addLine("Increased sensor range for %s light-years", Misc.getTextColor(), 178 new String[] {"+" + ly}, Misc.getHighlightColor()); 179 msg.setSound(Sounds.NONE); 180 Global.getSector().getCampaignUI().addMessage(msg, MessageClickAction.NOTHING); 181 sensorBonus += pendingSensorBonus; 182 pendingSensorBonus = 0; 183 } 184 185 } 186 } 187 188 189 public float getBurnBonus() { 190 return burnBonus; 191 } 192 193 public void setBurnBonus(float burnBonus) { 194 this.burnBonus = burnBonus; 195 } 196 197 public float getSensorBonus() { 198 return sensorBonus; 199 } 200 201 public void setSensorBonus(float sensorBonus) { 202 this.sensorBonus = sensorBonus; 203 } 204 205 public boolean isDone() { 206 return burnBonus <= 0 && sensorBonus <= 0 && 207 pendingBurnBonus <= 0 && pendingSensorBonus <= 0 && pendingTopographyPoints <= 0; 208 } 209 210 public boolean runWhilePaused() { 211 return false; 212 } 213 214}