Starsector API
Loading...
Searching...
No Matches
ToggleAbilityWithCost.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.BuffManagerAPI.Buff;
9import com.fs.starfarer.api.campaign.CampaignFleetAPI;
10import com.fs.starfarer.api.fleet.FleetMemberAPI;
11import com.fs.starfarer.api.impl.campaign.intel.BaseIntelPlugin;
12import com.fs.starfarer.api.impl.campaign.terrain.CRRecoveryBuff;
13import com.fs.starfarer.api.ui.TooltipMakerAPI;
14import com.fs.starfarer.api.util.Misc;
15import com.fs.starfarer.api.util.Misc.FleetMemberDamageLevel;
16
18
19 public float getFuelCostMult(boolean forTooltip) {
20 return 1f;
21 }
22 public float getCRCostMult(boolean forTooltip) {
23 return 0.25f;
24 }
25
26 public float getActivationAtLowCRShipDamageProbability(boolean forTooltip) {
27 return 0.33f;
28 }
29
30 public FleetMemberDamageLevel getActivationDamageLevel(boolean forTooltip) {
31 return FleetMemberDamageLevel.LOW;
32 }
33
34 public boolean canRecoverCRWhileActive(boolean forTooltip) {
35 return true;
36 }
37
38 public boolean shouldApplyCostWhenDeactivating(boolean forTooltip) {
39 return true;
40 }
41
42 @Override
43 protected void activateImpl() {
44 deductCost();
45 }
46
47 protected void deductCost() {
48 CampaignFleetAPI fleet = getFleet();
49 if (fleet == null) return;
50
51 float crCostMult = getCRCostMult(false);
52 if (crCostMult > 0) {
53 for (FleetMemberAPI member : getNonReadyShips(false)) {
54 if ((float) Math.random() < getActivationAtLowCRShipDamageProbability(false)) {
55 Misc.applyDamage(member, null, getActivationDamageLevel(false), false, null, null,
56 true, null, member.getShipName() + " suffers damage from " + spec.getName() + " activation");
57 }
58 }
59 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
60 float crLoss = getCRCost(member, false);
61 member.getRepairTracker().applyCREvent(-crLoss, Misc.ucFirst(spec.getName().toLowerCase()));
62 }
63 }
64
65 float cost = computeFuelCost(false);
66 fleet.getCargo().removeFuel(cost);
67 }
68
69
70 protected void applyStatsEffect(float amount, float level) {
71
72 }
73
74 protected void unapplyStatsEffect() {
75
76 }
77
78 protected void applyFleetVisual(float amount, float level) {
79
80 }
81
82 @Override
83 protected void applyEffect(float amount, float level) {
84 CampaignFleetAPI fleet = getFleet();
85 if (fleet == null) return;
86
87 applyStatsEffect(amount, level);
88 applyFleetVisual(amount, level);
89
90 if (!canRecoverCRWhileActive(false)) {
91 String buffId = getModId();
92 float buffDur = 0.1f;
93 boolean needsSync = false;
94 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
95 if (level <= 0) {
96 member.getBuffManager().removeBuff(buffId);
97 needsSync = true;
98 } else {
99 Buff test = member.getBuffManager().getBuff(buffId);
100 if (test instanceof CRRecoveryBuff) {
101 CRRecoveryBuff buff = (CRRecoveryBuff) test;
102 buff.setDur(buffDur);
103 } else {
104 member.getBuffManager().addBuff(new CRRecoveryBuff(buffId, 0f, buffDur));
105 needsSync = true;
106 }
107 }
108 }
109
110 if (needsSync) {
111 fleet.forceSync();
112 }
113 }
114
115 }
116
117 @Override
118 protected void deactivateImpl() {
119 cleanupImpl();
121 deductCost();
122 }
123 }
124
125 @Override
126 protected void cleanupImpl() {
128 }
129
130 protected List<FleetMemberAPI> getNonReadyShips(boolean forTooltip) {
131 List<FleetMemberAPI> result = new ArrayList<FleetMemberAPI>();
132 if (getCRCostMult(forTooltip) <= 0f) return result;
133
134 CampaignFleetAPI fleet = getFleet();
135 if (fleet == null) return result;
136
137 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
138 float crLoss = getCRCost(member, forTooltip);
139 if (Math.round(member.getRepairTracker().getCR() * 100) < Math.round(crLoss * 100)) {
140 result.add(member);
141 }
142 }
143 return result;
144 }
145
146 public float getCRCost(FleetMemberAPI member, boolean forTooltip) {
147 float crCostMult = getCRCostMult(forTooltip);
148 float crLoss = member.getDeployCost() * crCostMult;
149 return Math.round(crLoss * 100f) / 100f;
150 }
151
152 protected float computeFuelCost(boolean forTooltip) {
153 CampaignFleetAPI fleet = getFleet();
154 if (fleet == null) return 0f;
155
156 float cost = fleet.getLogistics().getFuelCostPerLightYear() * getFuelCostMult(forTooltip);
157 return cost;
158 }
159
160 protected float computeSupplyCost(boolean forTooltip) {
161 CampaignFleetAPI fleet = getFleet();
162 if (fleet == null) return 0f;
163
164 float crCostMult = getCRCostMult(forTooltip);
165
166 float cost = 0f;
167 for (FleetMemberAPI member : fleet.getFleetData().getMembersListCopy()) {
168 cost += member.getDeploymentCostSupplies() * crCostMult;
169 }
170 return cost;
171 }
172
173
174 public void addOtherNotUsableReason(TooltipMakerAPI tooltip, boolean expanded) {
175
176 }
177 public void addCostTooltipSection(TooltipMakerAPI tooltip, boolean expanded, String prefix) {
178 CampaignFleetAPI fleet = getFleet();
179 if (fleet == null) return;
180
181 Color highlight = Misc.getHighlightColor();
182 Color bad = Misc.getNegativeHighlightColor();
183
184 float pad = 10f;
185
186 float fuelCost = computeFuelCost(true);
187 float supplyCost = computeSupplyCost(true);
188
189 String preventsRecovery = "";
190 if (!canRecoverCRWhileActive(true)) {
191 preventsRecovery = " Prevents combat readiness recovery while active.";
192 }
193
194 String deactivateCost = "";
196 deactivateCost = " The cost is incurred both when activating and deactivating the ability.";
197 }
198 preventsRecovery += deactivateCost;
199
200 if (supplyCost > 0 && fuelCost > 0) {
201 if (prefix == null) {
202 prefix = "C";
203 } else {
204 prefix += " c";
205 }
206 tooltip.addPara(prefix + "onsumes %s fuel and reduces the combat readiness" +
207 " of all ships, costing up to %s supplies to recover." + preventsRecovery, pad,
208 highlight,
209 Misc.getRoundedValueMaxOneAfterDecimal(fuelCost),
210 Misc.getRoundedValueMaxOneAfterDecimal(supplyCost));
211 } else if (supplyCost > 0) {
212 if (prefix == null) {
213 prefix = "R";
214 } else {
215 prefix += " r";
216 }
217 tooltip.addPara(prefix + "educes the combat readiness" +
218 " of all ships, costing up to %s supplies to recover." + preventsRecovery, pad,
219 highlight,
220 Misc.getRoundedValueMaxOneAfterDecimal(supplyCost));
221 } else if (fuelCost > 0) {
222 if (prefix == null) {
223 prefix = "C";
224 } else {
225 prefix += " c";
226 }
227 tooltip.addPara(prefix + "onsumes %s fuel." + preventsRecovery, pad,
228 highlight,
229 Misc.getRoundedValueMaxOneAfterDecimal(fuelCost));
230 }
231
232 if (fuelCost > 0 && fuelCost > fleet.getCargo().getFuel()) {
233 tooltip.addPara("Not enough fuel.", bad, pad);
234 } else {
235 addOtherNotUsableReason(tooltip, expanded);
236 }
237
238 List<FleetMemberAPI> nonReady = getNonReadyShips(true);
239 if (!nonReady.isEmpty()) {
240 tooltip.addPara("Some ships don't have enough combat readiness " +
241 "and may suffer damage if the ability is activated:", pad,
242 Misc.getNegativeHighlightColor(), "may suffer damage");
243 int j = 0;
244 int max = 4;
245 float initPad = 5f;
246 for (FleetMemberAPI member : nonReady) {
247 if (j >= max) {
248 if (nonReady.size() > max + 1) {
249 tooltip.addPara(BaseIntelPlugin.INDENT + "... and several other ships", initPad);
250 break;
251 }
252 }
253 String str = "";
254 if (!member.isFighterWing()) {
255 str += member.getShipName() + ", ";
256 str += member.getHullSpec().getHullNameWithDashClass();
257 } else {
258 str += member.getVariant().getFullDesignationWithHullName();
259 }
260
261 tooltip.addPara(BaseIntelPlugin.INDENT + str, initPad);
262 initPad = 0f;
263 j++;
264 }
265 }
266 }
267
268 public boolean hasTooltip() {
269 return true;
270 }
271
272
273// @Override
274// public void fleetLeftBattle(BattleAPI battle, boolean engagedInHostilities) {
275// if (engagedInHostilities) {
276// deactivate();
277// }
278// }
279//
280// @Override
281// public void fleetOpenedMarket(MarketAPI market) {
282// deactivate();
283// }
284
285 @Override
286 public boolean isOnCooldown() {
287 return super.getCooldownFraction() < 1f;
288 }
289
290 @Override
291 public boolean isUsable() {
292 return super.isUsable() &&
293 getFleet() != null &&
294 (getFleet().isAIMode() || computeFuelCost(false) <= getFleet().getCargo().getFuel());
295 }
296
297 protected boolean showAlarm() {
298 return !getNonReadyShips(false).isEmpty() && !isOnCooldown() && !isActiveOrInProgress() && isUsable();
299 }
300
301 @Override
302 public float getCooldownFraction() {
303 if (showAlarm()) {
304 return 0f;
305 }
306 return super.getCooldownFraction();
307 }
308
309 @Override
310 public Color getCooldownColor() {
311 if (showAlarm()) {
312 Color color = Misc.getNegativeHighlightColor();
313 return Misc.scaleAlpha(color, Global.getSector().getCampaignUI().getSharedFader().getBrightness() * 0.5f);
314 }
315 return super.getCooldownColor();
316 }
317
318 @Override
320 if (showAlarm()) {
321 return true;
322 }
323 return false;
324 }
325}
326
327
328
329
330
static SectorAPI getSector()
Definition Global.java:59
void addOtherNotUsableReason(TooltipMakerAPI tooltip, boolean expanded)
void addCostTooltipSection(TooltipMakerAPI tooltip, boolean expanded, String prefix)