001package com.fs.starfarer.api.impl.campaign.abilities; 002 003import java.awt.Color; 004 005import org.lwjgl.util.vector.Vector2f; 006 007import com.fs.starfarer.api.Global; 008import com.fs.starfarer.api.campaign.BattleAPI; 009import com.fs.starfarer.api.campaign.CampaignFleetAPI; 010import com.fs.starfarer.api.fleet.FleetMemberViewAPI; 011import com.fs.starfarer.api.impl.campaign.ids.Stats; 012import com.fs.starfarer.api.ui.LabelAPI; 013import com.fs.starfarer.api.ui.TooltipMakerAPI; 014import com.fs.starfarer.api.util.Misc; 015 016public class SustainedBurnAbility extends BaseToggleAbility { 017 018 public static String SB_NO_STOP = "$sb_active"; 019 public static String SB_NO_SLOW = "$sb_no_slow"; 020 //public static float SENSOR_RANGE_MULT = 0.75f; 021 public static float DETECTABILITY_PERCENT = 100f; 022 //public static float MAX_BURN_MOD = 10f; 023 public static float MAX_BURN_PERCENT = 100f; 024 public static float ACCELERATION_MULT = 0.2f; 025 026// public String getSpriteName() { 027// return Global.getSettings().getSpriteName("abilities", Abilities.SUSTAINED_BURN); 028// } 029 030 031 @Override 032 protected String getActivationText() { 033 return super.getActivationText(); 034 //return "Engaging sustained burn"; 035 } 036 037 038 @Override 039 protected void activateImpl() { 040 CampaignFleetAPI fleet = getFleet(); 041 if (fleet == null) return; 042 043 if (!fleet.getMemoryWithoutUpdate().is(SB_NO_STOP, true)) { 044 fleet.setVelocity(0, 0); 045 } 046 } 047 048 @Override 049 protected void applyEffect(float amount, float level) { 050 CampaignFleetAPI fleet = getFleet(); 051 if (fleet == null) return; 052 053 //System.out.println("Level: " + level); 054 //level = 0.01f; 055 056 if (level > 0 && !fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 057 fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) { 058 deactivate(); 059 return; 060 } 061 062 fleet.getMemoryWithoutUpdate().set(SB_NO_STOP, true, 0.3f); 063 064 if (level > 0 && level < 1 && amount > 0 && !fleet.getMemoryWithoutUpdate().is(SB_NO_SLOW, true)) { 065 float activateSeconds = getActivationDays() * Global.getSector().getClock().getSecondsPerDay(); 066 float speed = fleet.getVelocity().length(); 067 float acc = Math.max(speed, 200f)/activateSeconds + fleet.getAcceleration(); 068 float ds = acc * amount; 069 if (ds > speed) ds = speed; 070 Vector2f dv = Misc.getUnitVectorAtDegreeAngle(Misc.getAngleInDegrees(fleet.getVelocity())); 071 dv.scale(ds); 072 fleet.setVelocity(fleet.getVelocity().x - dv.x, fleet.getVelocity().y - dv.y); 073 return; 074 } 075 076 //fleet.getStats().getSensorRangeMod().modifyMult(getModId(), 1f + (SENSOR_RANGE_MULT - 1f) * level, "Sustained burn"); 077 fleet.getStats().getDetectedRangeMod().modifyPercent(getModId(), DETECTABILITY_PERCENT * level, "Sustained burn"); 078 079 //int burnModifier = (int)(MAX_BURN_MOD * level) - (int)(INITIAL_BURN_PENALTY * (1f - level)); 080 //int burnModifier = (int)(MAX_BURN_MOD * level); 081 int burnModifier = 0; 082 float burnMult = 1f; 083 084 float b = fleet.getStats().getDynamic().getValue(Stats.SUSTAINED_BURN_BONUS, 0f); 085 //burnModifier = (int)((MAX_BURN_MOD + b) * level); 086 burnModifier = (int)((b) * level); 087 088// if (level > 0.5f) { 089// burnModifier = (int)(MAX_BURN_MOD * (level - 0.5f) / 0.5f); 090// } else { 091// //burnModifier = -1 * (int)(INITIAL_BURN_PENALTY * (1f - level / 0.5f)); 092// burnMult = 1f + ((INITIAL_BURN_PENALTY - 1f) * (1f - level / 0.5f)); 093// } 094 fleet.getStats().getFleetwideMaxBurnMod().modifyFlat(getModId(), burnModifier, "Sustained burn"); 095 fleet.getStats().getFleetwideMaxBurnMod().modifyMult(getModId(), burnMult, "Sustained burn"); 096 fleet.getStats().getFleetwideMaxBurnMod().modifyPercent(getModId(), MAX_BURN_PERCENT, "Sustained burn"); 097 098 099 float accImpact = 0f; 100 float burn = Misc.getBurnLevelForSpeed(fleet.getVelocity().length()); 101 if (burn > 1) { 102 float dir = Misc.getDesiredMoveDir(fleet); 103// if (fleet.isPlayerFleet()) { 104// System.out.println("DIR: " + dir); 105// } 106 float velDir = Misc.getAngleInDegrees(fleet.getVelocity()); 107 float diff = Misc.getAngleDiff(dir, velDir); 108 //float pad = 90f; 109 float pad = 120f; 110 diff -= pad; 111 if (diff < 0) diff = 0; 112 accImpact = 1f - 0.5f * Math.min(1f, (diff / (180f - pad))); 113 } 114 115// if (fleet.isPlayerFleet()) { 116// System.out.println("Acc mult: " + (1f - (1f - ACCELERATION_MULT) * accImpact)); 117// } 118 fleet.getStats().getAccelerationMult().modifyMult(getModId(), 1f - (1f - ACCELERATION_MULT) * accImpact); 119 //fleet.getStats().getAccelerationMult().modifyMult(getModId(), 1f + (ACCELERATION_MULT - 1f) * level); 120 121 for (FleetMemberViewAPI view : fleet.getViews()) { 122 //view.getContrailColor().shift(getModId(), new Color(50,50,50,155), 1f, 1f, .5f); 123 view.getContrailColor().shift(getModId(), view.getEngineColor().getBase(), 1f, 1f, 0.5f * level); 124 view.getEngineGlowSizeMult().shift(getModId(), 1.5f, 1f, 1f, 1f * level); 125 view.getEngineHeightMult().shift(getModId(), 3f, 1f, 1f, 1f * level); 126 view.getEngineWidthMult().shift(getModId(), 2f, 1f, 1f, 1f * level); 127 } 128 129 130 if (level <= 0) { 131 cleanupImpl(); 132 } 133 } 134 135 @Override 136 protected void deactivateImpl() { 137 //cleanupImpl(); 138 } 139 140 @Override 141 protected void cleanupImpl() { 142 CampaignFleetAPI fleet = getFleet(); 143 if (fleet == null) return; 144 145 //fleet.getStats().getSensorRangeMod().unmodify(getModId()); 146 fleet.getStats().getDetectedRangeMod().unmodify(getModId()); 147 fleet.getStats().getFleetwideMaxBurnMod().unmodify(getModId()); 148 fleet.getStats().getAccelerationMult().unmodify(getModId()); 149 } 150 151 @Override 152 public boolean showProgressIndicator() { 153 return super.showProgressIndicator(); 154 //return false; 155 } 156 157 @Override 158 public boolean showActiveIndicator() { 159 //super.showActiveIndicator() 160 return isActive(); 161 } 162 163 @Override 164 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) { 165 Color gray = Misc.getGrayColor(); 166 Color highlight = Misc.getHighlightColor(); 167 168 String status = " (off)"; 169 if (turnedOn) { 170 status = " (on)"; 171 } 172 173 if (!Global.CODEX_TOOLTIP_MODE) { 174 LabelAPI title = tooltip.addTitle("Sustained Burn" + status); 175 title.highlightLast(status); 176 title.setHighlightColor(gray); 177 } else { 178 tooltip.addSpacer(-10f); 179 } 180 181 float pad = 10f; 182 183 184 tooltip.addPara("Switch the drives of all ships in the fleet to a mode suited for long-distance travel. " + 185 "The fleet has to stop briefly to make the switch-over. ", pad); 186 187// public static final float SENSOR_RANGE_MULT = 0.75f; 188// public static final float DETECTABILITY_PERCENT = 50f; 189// public static final float MAX_BURN_MOD = 10f; 190// private static final float ACCELERATION_MULT = 0.25f; 191 tooltip.addPara("Increases the maximum burn level by %s, at the expense of lower acceleration, " + 192 "especially in the direction of the fleet's movement. " + 193 "Also increases the range at which the fleet can be detected by %s.", pad, 194 highlight, 195 //"" + (int) MAX_BURN_MOD, 196 "" + (int) Math.round(MAX_BURN_PERCENT) + "%", 197 "" + (int)(DETECTABILITY_PERCENT) + "%" 198 ); 199 200 tooltip.addPara("The burn level increase does not apply to flat burn bonuses, " + 201 "such as those from Nav Buoys or tugs.", pad); 202 203 if (!Global.CODEX_TOOLTIP_MODE) { 204 CampaignFleetAPI fleet = getFleet(); 205 if (fleet != null) { 206 if (!fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 207 fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) { 208 tooltip.addPara("Out of fuel.", Misc.getNegativeHighlightColor(), pad); 209 } 210 } 211 } 212 213// tooltip.addPara("Increases the maximum burn level by %s, Acceleration is greatly reduced, and " + 214// "higher drive emissions interfere with sensors, decreasing their range by %s. " + 215// "The fleet is also %s easier to detect.", pad, 216// highlight, 217// "" + (int) MAX_BURN_MOD, 218// "" + (int)((1f - SENSOR_RANGE_MULT) * 100f) + "%", 219// "" + (int)(DETECTABILITY_PERCENT) + "%" 220// ); 221 //tooltip.addPara("Disables the transponder when activated.", pad); 222 addIncompatibleToTooltip(tooltip, expanded); 223 } 224 225 public boolean isUsable() { 226 if (!super.isUsable()) return false; 227 if (getFleet() == null) return false; 228 229 CampaignFleetAPI fleet = getFleet(); 230 if (!fleet.isAIMode() && fleet.getCargo().getFuel() <= 0 && 231 fleet.getContainingLocation() != null && fleet.getContainingLocation().isHyperspace()) { 232 return false; 233 } 234 235 return true; 236 } 237 238 public boolean hasTooltip() { 239 return true; 240 } 241 242 243 @Override 244 public void fleetLeftBattle(BattleAPI battle, boolean engagedInHostilities) { 245// if (battle.isPlayerInvolved() && engagedInHostilities) { 246// deactivate(); 247// } 248 } 249 250 251 @Override 252 public void fleetJoinedBattle(BattleAPI battle) { 253 if (!battle.isPlayerInvolved()) { 254 deactivate(); 255 } 256 } 257 258} 259 260 261 262 263