Starsector API
Loading...
Searching...
No Matches
EmergencyBurnAbility.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign.abilities;
2
3import java.awt.Color;
4import java.util.ArrayList;
5import java.util.List;
6
7import com.fs.starfarer.api.Global;
8import com.fs.starfarer.api.campaign.BattleAPI;
9import com.fs.starfarer.api.campaign.BuffManagerAPI.Buff;
10import com.fs.starfarer.api.campaign.CampaignFleetAPI;
11import com.fs.starfarer.api.campaign.econ.MarketAPI;
12import com.fs.starfarer.api.fleet.FleetMemberAPI;
13import com.fs.starfarer.api.fleet.FleetMemberViewAPI;
14import com.fs.starfarer.api.impl.campaign.ids.Stats;
15import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
16import com.fs.starfarer.api.impl.campaign.terrain.CRRecoveryBuff;
17import com.fs.starfarer.api.ui.LabelAPI;
18import com.fs.starfarer.api.ui.TooltipMakerAPI;
19import com.fs.starfarer.api.util.Misc;
20import com.fs.starfarer.api.util.Misc.FleetMemberDamageLevel;
21
23
24 public static float SENSOR_RANGE_MULT = 0.5f;
25 //public static final float DETECTABILITY_MULT = 1.25f;
26 public static float DETECTABILITY_PERCENT = 50f;
27 public static float MAX_BURN_MOD = 8f;
28 //public static final float CR_COST_MULT = 1f;
29 public static float CR_COST_MULT = 0.25f;
30 public static float FUEL_USE_MULT = 1f;
31
32 public static float ACCELERATION_MULT = 4f;
33
34 public static float ACTIVATION_DAMAGE_PROB = 0.33f;
35
36// public String getSpriteName() {
37// return Global.getSettings().getSpriteName("abilities", Abilities.EMERGENCY_BURN);
38// }
39
40
41// @Override
42// protected String getActivationText() {
43// return Misc.ucFirst(spec.getName().toLowerCase());
44// }
45
46
47 @Override
48 protected void activateImpl() {
49// if (entity.isInCurrentLocation()) {
50// entity.addFloatingText("Emergency burn", entity.getFaction().getBaseUIColor(), 0.5f);
51// }
52
53// AbilityPlugin goDark = entity.getAbility(Abilities.GO_DARK);
54// if (goDark != null && goDark.isActive()) {
55// goDark.deactivate();
56// }
57// AbilityPlugin sb = entity.getAbility(Abilities.SUSTAINED_BURN);
58// if (sb != null && sb.isActive()) {
59// sb.deactivate();
60// }
61
62 CampaignFleetAPI fleet = getFleet();
63 if (fleet == null) return;
64
65 float crCostFleetMult = fleet.getStats().getDynamic().getValue(Stats.EMERGENCY_BURN_CR_MULT);
66 if (crCostFleetMult > 0) {
67 for (FleetMemberAPI member : getNonReadyShips()) {
68 if ((float) Math.random() < ACTIVATION_DAMAGE_PROB) {
69 Misc.applyDamage(member, null, FleetMemberDamageLevel.LOW, false, null, null,
70 true, null, member.getShipName() + " suffers damage from Emergency Burn activation");
71 }
72 }
73 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
74 float crLoss = member.getDeployCost() * CR_COST_MULT * crCostFleetMult;
75 member.getRepairTracker().applyCREvent(-crLoss, "Emergency burn");
76 }
77 }
78
79 float cost = computeFuelCost();
80 fleet.getCargo().removeFuel(cost);
81
82// float distLY = Misc.getDistanceToPlayerLY(fleet);
83// //if (fleet.isPlayerFleet()) {
84// if (distLY < 4f) {
85// SpatialAnomalyParams params = new SpatialAnomalyParams(fleet, 1f, fleet.getRadius() * 2f + 100f, null);
86// SectorEntityToken anomaly = fleet.getContainingLocation().addTerrain(Terrain.SPATIAL_ANOMALY, params);
87// anomaly.getLocation().set(fleet.getLocation());
88// }
89 }
90
91 @Override
92 protected void applyEffect(float amount, float level) {
93// if (level > 0) {
94// AbilityPlugin goDark = entity.getAbility(Abilities.GO_DARK);
95// if (goDark != null) goDark.forceDisable();
96// AbilityPlugin sb = entity.getAbility(Abilities.SUSTAINED_BURN);
97// if (sb != null) sb.forceDisable();
98//
105// }
106
107 CampaignFleetAPI fleet = getFleet();
108 if (fleet == null) return;
109
110 fleet.getStats().getSensorRangeMod().modifyMult(getModId(), 1f + (SENSOR_RANGE_MULT - 1f) * level, "Emergency burn");
111 fleet.getStats().getDetectedRangeMod().modifyPercent(getModId(), DETECTABILITY_PERCENT * level, "Emergency burn");
112 fleet.getStats().getFleetwideMaxBurnMod().modifyFlat(getModId(), (int)(MAX_BURN_MOD * level), "Emergency burn");
113 fleet.getStats().getAccelerationMult().modifyMult(getModId(), 1f + (ACCELERATION_MULT - 1f) * level);
114 //fleet.getCommanderStats().getDynamic().getStat(Stats.NAVIGATION_PENALTY_MULT).modifyMult(getModId(), 0f);//1f - level);
115
116 for (FleetMemberViewAPI view : fleet.getViews()) {
117 //view.getContrailColor().shift(getModId(), view.getEngineColor().getBase(), 1f, 1f, 0.25f);
118 view.getContrailColor().shift(getModId(), new Color(250,150,100,255), 1f, 1f, .75f);
119 //view.getContrailColor().shift(getModId(), new Color(255,100,255), 1f, 1f, 0.5f);
120 //view.getContrailDurMult().shift(getModId(), 0.5f, 1f, 1f, 1f);
121 //view.getContrailWidthMult().shift(getModId(), 2f, 1f, 1f, 1f);
122 view.getEngineGlowSizeMult().shift(getModId(), 2f, 1f, 1f, 1f);
123 view.getEngineHeightMult().shift(getModId(), 5f, 1f, 1f, 1f);
124 view.getEngineWidthMult().shift(getModId(), 3f, 1f, 1f, 1f);
125 }
126
127 //member.getStats().getBaseCRRecoveryRatePercentPerDay()for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
128 String buffId = getModId();
129 float buffDur = 0.1f;
130 boolean needsSync = false;
131 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
132 if (level <= 0) {
133 member.getBuffManager().removeBuff(buffId);
134 needsSync = true;
135 } else {
136 Buff test = member.getBuffManager().getBuff(buffId);
137 if (test instanceof CRRecoveryBuff) {
138 CRRecoveryBuff buff = (CRRecoveryBuff) test;
139 buff.setDur(buffDur);
140 } else {
141 member.getBuffManager().addBuff(new CRRecoveryBuff(buffId, 0f, buffDur));
142 needsSync = true;
143 }
144 }
145 }
146
147 //if (needsSync || fleet.isPlayerFleet()) {
148 if (needsSync) {
149 fleet.forceSync();
150 }
151
152
153// if (level > 0) {
154// SlipstreamTerrainPlugin slipstream = SlipstreamTerrainPlugin.getSlipstreamPlugin(fleet.getContainingLocation());
155// if (slipstream != null) {
156// slipstream.disrupt(fleet, 0.1f);
157// }
158// }
159 }
160
161 @Override
162 protected void deactivateImpl() {
163 cleanupImpl();
164 }
165
166 @Override
167 protected void cleanupImpl() {
168 CampaignFleetAPI fleet = getFleet();
169 if (fleet == null) return;
170
171 fleet.getStats().getSensorRangeMod().unmodify(getModId());
172 fleet.getStats().getDetectedRangeMod().unmodify(getModId());
173 fleet.getStats().getFleetwideMaxBurnMod().unmodify(getModId());
174 fleet.getStats().getAccelerationMult().unmodify(getModId());
175 //fleet.getCommanderStats().getDynamic().getStat(Stats.NAVIGATION_PENALTY_MULT).unmodify(getModId());
176 }
177
178// @Override
179// public float getActivationDays() {
180// return 0.25f;
181// }
182//
183// @Override
184// public float getCooldownDays() {
185// return 1f;
186// }
187//
188// @Override
189// public float getDeactivationDays() {
190// return 0.25f;
191// }
192//
193// @Override
194// public float getDurationDays() {
195// return 1.5f;
196// }
197
198
199 protected List<FleetMemberAPI> getNonReadyShips() {
200 List<FleetMemberAPI> result = new ArrayList<FleetMemberAPI>();
201 CampaignFleetAPI fleet = getFleet();
202 if (fleet == null) return result;
203
204 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
205 //if (member.isMothballed()) continue;
206 //float crLoss = member.getDeployCost() * CR_COST_MULT * crCostFleetMult;
207 float crLoss = getCRCost(member, fleet);
208 if (Math.round(member.getRepairTracker().getCR() * 100) < Math.round(crLoss * 100)) {
209 result.add(member);
210 }
211 }
212 return result;
213 }
214
215
216// public static boolean isReadyForEBurn(FleetMemberAPI member, CampaignFleetAPI fleet) {
217// float crLoss = getCRCost(member, fleet);
218// return Math.round(member.getRepairTracker().getCR() * 100) < Math.round(crLoss * 100);
219// }
220
221 public static float getCRCost(FleetMemberAPI member, CampaignFleetAPI fleet) {
222 float crCostFleetMult = fleet.getStats().getDynamic().getValue(Stats.EMERGENCY_BURN_CR_MULT);
223 float crLoss = member.getDeployCost() * CR_COST_MULT * crCostFleetMult;
224 return Math.round(crLoss * 100f) / 100f;
225 }
226
227 protected float computeFuelCost() {
228 CampaignFleetAPI fleet = getFleet();
229 if (fleet == null) return 0f;
230
231 float cost = fleet.getLogistics().getFuelCostPerLightYear() * FUEL_USE_MULT;
232 return cost;
233 }
234
235 protected float computeSupplyCost() {
236 CampaignFleetAPI fleet = getFleet();
237 if (fleet == null) return 0f;
238
239 float crCostFleetMult = fleet.getStats().getDynamic().getValue(Stats.EMERGENCY_BURN_CR_MULT);
240
241 float cost = 0f;
242 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
243 cost += member.getDeploymentCostSupplies() * CR_COST_MULT * crCostFleetMult;
244 }
245 return cost;
246 }
247
248
249 @Override
250 public void createTooltip(TooltipMakerAPI tooltip, boolean expanded) {
251 CampaignFleetAPI fleet = getFleet();
252 if (fleet == null) return;
253
254 Color gray = Misc.getGrayColor();
255 Color highlight = Misc.getHighlightColor();
256 Color fuel = Global.getSettings().getColor("progressBarFuelColor");
257 Color bad = Misc.getNegativeHighlightColor();
258
259 LabelAPI title = tooltip.addTitle("Emergency Burn");
260// title.highlightLast(status);
261// title.setHighlightColor(gray);
262
263 float pad = 10f;
264
265 float fuelCost = computeFuelCost();
266 float supplyCost = computeSupplyCost();
267
268 tooltip.addPara("Increases the maximum burn level by %s." +
269 " Reduces sensor range by %s and increases the range at" +
270 " which the fleet can be detected by %s.",// +
271// " The fleet will also be unaffected by most terrain " +
272// "movement penalties and hazards while the ability is active.",
273 pad,
274 highlight,
275 "" + (int) MAX_BURN_MOD,
276 "" + (int)((1f - SENSOR_RANGE_MULT) * 100f) + "%",
277 //"" + (int)((DETECTABILITY_MULT - 1f) * 100f) + "%"
278 "" + (int)(DETECTABILITY_PERCENT) + "%"
279 );
280
281 if (supplyCost > 0) {
282 tooltip.addPara("Consumes %s fuel and reduces the combat readiness" +
283 " of all ships, costing up to %s supplies to recover. Also prevents combat readiness recovery while active.", pad,
284 highlight,
285 Misc.getRoundedValueMaxOneAfterDecimal(fuelCost),
286 Misc.getRoundedValueMaxOneAfterDecimal(supplyCost));
287 } else {
288 tooltip.addPara("Consumes %s fuel and prevents combat readiness recovery while active.", pad,
289 highlight,
290 Misc.getRoundedValueMaxOneAfterDecimal(fuelCost));
291 }
292
293 if (fuelCost > fleet.getCargo().getFuel()) {
294 tooltip.addPara("Not enough fuel.", bad, pad);
295 }
296
297 List<FleetMemberAPI> nonReady = getNonReadyShips();
298 if (!nonReady.isEmpty()) {
299 //tooltip.addPara("Not all ships have enough combat readiness to initiate an emergency burn. Ships that require higher CR:", pad);
300 tooltip.addPara("Some ships don't have enough combat readiness to safely initiate an emergency burn " +
301 "and may suffer damage if the ability is activated:", pad,
302 Misc.getNegativeHighlightColor(), "may suffer damage");
303 //tooltip.beginGridFlipped(getTooltipWidth(), 1, 30, pad);
304 //tooltip.setGridLabelColor(bad);
305 int j = 0;
306 int max = 4;
307 float initPad = 5f;
308 for (FleetMemberAPI member : nonReady) {
309 if (j >= max) {
310 if (nonReady.size() > max + 1) {
311 tooltip.addPara(BaseIntelPlugin.INDENT + "... and several other ships", initPad);
312 break;
313 }
314 }
315
316 //float crLoss = member.getDeployCost() * CR_COST_MULT;
317 //String cost = "" + Math.round(crLoss * 100) + "%";
318 String str = "";
319 if (!member.isFighterWing()) {
320 str += member.getShipName() + ", ";
321 str += member.getHullSpec().getHullNameWithDashClass();
322 } else {
323 str += member.getVariant().getFullDesignationWithHullName();
324 }
325
326 tooltip.addPara(BaseIntelPlugin.INDENT + str, initPad);
327 initPad = 0f;
328 j++;
329
330 //tooltip.addToGrid(0, j++, str, cost, bad);
331 }
332 //tooltip.addGrid(3f);
333 }
334
335 //tooltip.addPara("Disables \"Go Dark\" when activated.", pad);
336 addIncompatibleToTooltip(tooltip, expanded);
337 }
338
339 public boolean hasTooltip() {
340 return true;
341 }
342
343
344 @Override
345 public void fleetLeftBattle(BattleAPI battle, boolean engagedInHostilities) {
346 if (engagedInHostilities) {
347 deactivate();
348 }
349 }
350
351 @Override
352 public void fleetOpenedMarket(MarketAPI market) {
353 deactivate();
354 }
355
356
357
358
359// @Override
360// public boolean showProgressIndicator() {
361// if (true) return true;
362// return !getNonReadyShips().isEmpty();
363// }
364// @Override
365// public float getProgressFraction() {
366// return 1f;
367// }
368// @Override
369// public Color getProgressColor() {
370// Color color = Misc.getNegativeHighlightColor();
371// color = Misc.getHighlightColor();
372// return Misc.scaleAlpha(color, Global.getSector().getCampaignUI().getSharedFader().getBrightness());
373// }
374
375
376 protected boolean showAlarm() {
377 return !getNonReadyShips().isEmpty() && !isOnCooldown() && !isActiveOrInProgress() && isUsable();
378 }
379
380 @Override
381 public boolean isUsable() {
382 return super.isUsable() &&
383 getFleet() != null &&
384 //getNonReadyShips().isEmpty() &&
385 (getFleet().isAIMode() || computeFuelCost() <= getFleet().getCargo().getFuel());
386 }
387 @Override
388 public float getCooldownFraction() {
389 if (showAlarm()) {
390 return 0f;
391 }
392 return super.getCooldownFraction();
393 }
394 @Override
395 public boolean showCooldownIndicator() {
396 return super.showCooldownIndicator();
397 }
398 @Override
399 public boolean isOnCooldown() {
400 return super.getCooldownFraction() < 1f;
401 }
402
403 @Override
404 public Color getCooldownColor() {
405 if (showAlarm()) {
406 Color color = Misc.getNegativeHighlightColor();
407 return Misc.scaleAlpha(color, Global.getSector().getCampaignUI().getSharedFader().getBrightness() * 0.5f);
408 }
409 return super.getCooldownColor();
410 }
411
412 @Override
414 if (showAlarm()) {
415 return true;
416 }
417 return false;
418 }
419}
420
421
422
423
424
static SettingsAPI getSettings()
Definition Global.java:51
static SectorAPI getSector()
Definition Global.java:59
void addIncompatibleToTooltip(TooltipMakerAPI tooltip, boolean expanded)
void fleetLeftBattle(BattleAPI battle, boolean engagedInHostilities)
void createTooltip(TooltipMakerAPI tooltip, boolean expanded)
static float getCRCost(FleetMemberAPI member, CampaignFleetAPI fleet)