Starsector API
Loading...
Searching...
No Matches
TowCable.java
Go to the documentation of this file.
1package com.fs.starfarer.api.impl.campaign;
2
3import java.util.HashMap;
4import java.util.List;
5import java.util.Map;
6
7import java.awt.Color;
8
9import com.fs.starfarer.api.Global;
10import com.fs.starfarer.api.campaign.BuffManagerAPI.Buff;
11import com.fs.starfarer.api.campaign.CampaignUIAPI.CoreUITradeMode;
12import com.fs.starfarer.api.campaign.FleetDataAPI;
13import com.fs.starfarer.api.campaign.econ.MarketAPI;
14import com.fs.starfarer.api.combat.HullModEffect;
15import com.fs.starfarer.api.combat.MutableShipStatsAPI;
16import com.fs.starfarer.api.combat.MutableStat;
17import com.fs.starfarer.api.combat.MutableStat.StatMod;
18import com.fs.starfarer.api.combat.ShipAPI;
19import com.fs.starfarer.api.combat.ShipAPI.HullSize;
20import com.fs.starfarer.api.combat.ShipVariantAPI;
21import com.fs.starfarer.api.fleet.FleetMemberAPI;
22import com.fs.starfarer.api.loading.HullModSpecAPI;
23import com.fs.starfarer.api.ui.TooltipMakerAPI;
24
25public class TowCable implements HullModEffect {
26
27 public static final String HULLMOD_ID = "tow_cable";
28
29 public void init(HullModSpecAPI spec) {
30
31 }
32
33 public static class TowCableBuff implements Buff {
34 //public boolean wasApplied = false;
35 private String buffId;
36 private int frames = 0;
37
38 public TowCableBuff(String buffId) {
39 this.buffId = buffId;
40 }
41
42 public boolean isExpired() {
43 //return wasApplied;
44 return frames >= 2;
45 }
46 public String getId() {
47 return buffId;
48 }
49 public void apply(FleetMemberAPI member) {
50 // this ensures the buff lasts for exactly one frame unless wasApplied is reset (as it is later)
51 //wasApplied = true;
52 member.getStats().getMaxBurnLevel().modifyFlat(buffId, 1);
53 }
54 public void advance(float days) {
55 frames++;
56 }
57 };
58
59
60 public TowCable() {
61
62 }
63
64 public void advanceInCampaign(FleetMemberAPI member, float amount) {
65 if (member.getFleetData() == null) return;
66 if (member.getFleetData().getFleet() == null) return;
67 if (!member.getFleetData().getFleet().isPlayerFleet()) return;
68
69
70 if (!member.getVariant().getHullMods().contains(HULLMOD_ID)) {
71 cleanUpTowCableBuffBy(member);
72 return;
73 }
74
75 if (!member.canBeDeployedForCombat()) {
76 cleanUpTowCableBuffBy(member);
77 return;
78 }
79
80 FleetDataAPI data = member.getFleetData();
81 List<FleetMemberAPI> all = data.getMembersListCopy();
82
83 int numCables = 0;
84 int thisCableIndex = -1;
85 for (FleetMemberAPI curr : all) {
86 if (!curr.canBeDeployedForCombat()) continue;
87 if (curr.getVariant().getHullMods().contains(HULLMOD_ID)) {
88 if (curr == member) {
89 thisCableIndex = numCables;
90 }
91 numCables++;
92 }
93 }
94 if (numCables <= 0 || thisCableIndex == -1) {
95 cleanUpTowCableBuffBy(member);
96 return;
97 }
98
99 TowCableBuff buff = getTowCableBuffBy(member, true);
100 Map<FleetMemberAPI, Integer> cables = new HashMap<FleetMemberAPI, Integer>();
101 float towSpeed = member.getStats().getMaxBurnLevel().getModifiedValue();
102 FleetMemberAPI thisCableTarget = null;
103
104 for (int cableIndex = 0; cableIndex < numCables; cableIndex++) {
105 FleetMemberAPI slowest = getSlowest(all, towSpeed, cables);
106 if (slowest == null) break;
107 //slowest.getStats().getMaxBurnLevel().getModifiedValue()
108 Integer bonus = cables.get(slowest);
109 if (bonus == null) bonus = new Integer(0);
110 bonus++;
111 cables.put(slowest, bonus);
112
113 if (cableIndex == thisCableIndex) {
114 thisCableTarget = slowest;
115 Buff existing = slowest.getBuffManager().getBuff(buff.getId());
116 if (existing == buff) {
117 // make sure it's using the same buff rather than reapplying it,
118 // which would trigger a full stat recompute for the entire FLEET every frame
119 //buff.wasApplied = false;
120 buff.frames = 0;
121 //System.out.println("renewed on " + slowest);
122 } else {
123 //buff.wasApplied = false;
124 buff.frames = 0;
125 slowest.getBuffManager().addBuff(buff);
126 //System.out.println("Num: " + slowest.getBuffManager().getBuffs().size());
127 //System.out.println("added to " + slowest);
128 }
129 break;
130 }
131 }
132
133 for (FleetMemberAPI curr : all) {
134 if (curr != thisCableTarget) {
135 curr.getBuffManager().removeBuff(buff.getId());
136 }
137 }
138 }
139
140 private FleetMemberAPI getSlowest(List<FleetMemberAPI> all, float speedCutoff, Map<FleetMemberAPI, Integer> cables) {
141 FleetMemberAPI slowest = null;
142 float minLevel = Float.MAX_VALUE;
143 for (FleetMemberAPI curr : all) {
144 if (!isSuitable(curr)) continue;
145
146 float baseBurn = getMaxBurnWithoutCables(curr);
147 Integer bonus = cables.get(curr);
148 if (bonus == null) bonus = new Integer(0);
149
150 if (bonus >= getMaxCablesFor(curr)) continue;
151
152 float burnLevel = baseBurn + bonus;
153
154 if (burnLevel >= speedCutoff) continue;
155
156 if (burnLevel < minLevel) {
157 minLevel = burnLevel;
158 slowest = curr;
159 }
160 }
161 return slowest;
162 }
163
164 private int getMaxCablesFor(FleetMemberAPI member) {
165// switch (member.getHullSpec().getHullSize()) {
166// case CAPITAL_SHIP: return 4;
167// case CRUISER: return 3;
168// case DESTROYER: return 2;
169// case FRIGATE: return 1;
170// }
171 return 1;
172 }
173
174 private float getMaxBurnWithoutCables(FleetMemberAPI member) {
175 MutableStat burn = member.getStats().getMaxBurnLevel();
176 float val = burn.getModifiedValue();
177 float sub = 0;
178 for (StatMod mod : burn.getFlatMods().values()) {
179 if (mod.getSource().startsWith(HULLMOD_ID)) sub++;
180 }
181 return Math.max(0, val - sub);
182 }
183
184 private boolean isSuitable(FleetMemberAPI member) {
185 if (member.isFighterWing()) return false;
186 return true;
187 }
188
189 private void cleanUpTowCableBuffBy(FleetMemberAPI member) {
190 if (member.getFleetData() == null) return;
191 FleetDataAPI data = member.getFleetData();
192 TowCableBuff buff = getTowCableBuffBy(member, false);
193 if (buff != null) {
194 for (FleetMemberAPI curr : data.getMembersListCopy()) {
195 curr.getBuffManager().removeBuff(buff.getId());
196 }
197 }
198 }
199
203 public static final String TOW_CABLE_KEY = "TowCable_PersistentBuffs";
204
205 @SuppressWarnings("unchecked")
206 private TowCableBuff getTowCableBuffBy(FleetMemberAPI member, boolean createIfMissing) {
207 Map<FleetMemberAPI, TowCableBuff> buffs;
208 if (Global.getSector().getPersistentData().containsKey(TOW_CABLE_KEY)) {
209 buffs = (Map<FleetMemberAPI, TowCableBuff>) Global.getSector().getPersistentData().get(TOW_CABLE_KEY);
210 } else {
211 buffs = new HashMap<FleetMemberAPI, TowCableBuff>();
212 Global.getSector().getPersistentData().put(TOW_CABLE_KEY, buffs);
213 }
214
215 //new HashMap<FleetMemberAPI, TowCableBuff>();
216 TowCableBuff buff = buffs.get(member);
217 if (buff == null && createIfMissing) {
218 String id = HULLMOD_ID + "_" + member.getId();
219 buff = new TowCableBuff(id);
220 buffs.put(member, buff);
221 }
222 return buff;
223 }
224
225
226 public void advanceInCombat(ShipAPI ship, float amount) {
227 }
228
229 public void applyEffectsAfterShipCreation(ShipAPI ship, String id) {
230 }
231 public void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id) {
232 }
233 public boolean isApplicableToShip(ShipAPI ship) {
234 return true;
235 }
236
237 public String getDescriptionParam(int index, HullSize hullSize) {
238 return null;
239 }
240
241 public String getUnapplicableReason(ShipAPI ship) {
242 return null;
243 }
244
245 public boolean affectsOPCosts() {
246 return false;
247 }
248
249 public String getDescriptionParam(int index, HullSize hullSize, ShipAPI ship) {
250 return getDescriptionParam(index, hullSize);
251 }
252
253 public boolean canBeAddedOrRemovedNow(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode) {
254 return true;
255 }
256
257 public String getCanNotBeInstalledNowReason(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode) {
258 return null;
259 }
260
261 public boolean shouldAddDescriptionToTooltip(HullSize hullSize, ShipAPI ship, boolean isForModSpec) {
262 return true;
263 }
264 public void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec) {
265
266 }
267
268 public void applyEffectsToFighterSpawnedByShip(ShipAPI fighter, ShipAPI ship, String id) {
269
270 }
271
272 public Color getBorderColor() {
273 // TODO Auto-generated method stub
274 return null;
275 }
276
277 public Color getNameColor() {
278 // TODO Auto-generated method stub
279 return null;
280 }
281
282 public int getDisplaySortOrder() {
283 return 100;
284 }
285
287 return -1;
288 }
289
290 public boolean hasSModEffectSection(HullSize hullSize, ShipAPI ship, boolean isForModSpec) {
291 return false;
292 }
293
294 public void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width,
295 boolean isForModSpec) {
296
297 }
298
299 public void addSModEffectSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width,
300 boolean isForModSpec, boolean isForBuildInList) {
301 // TODO Auto-generated method stub
302
303 }
304
305 public void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width,
306 boolean isForModSpec, boolean isForBuildInList) {
307 // TODO Auto-generated method stub
308
309 }
310
311 public boolean hasSModEffect() {
312 // TODO Auto-generated method stub
313 return false;
314 }
315
316 public String getSModDescriptionParam(int index, HullSize hullSize) {
317 // TODO Auto-generated method stub
318 return null;
319 }
320
321 public String getSModDescriptionParam(int index, HullSize hullSize, ShipAPI ship) {
322 // TODO Auto-generated method stub
323 return null;
324 }
325
326 public float getTooltipWidth() {
327 return 0;
328 }
329
330 public boolean isSModEffectAPenalty() {
331 // TODO Auto-generated method stub
332 return false;
333 }
334
336 return true;
337 }
338
339 @Override
340 public void addRequiredItemSection(TooltipMakerAPI tooltip, FleetMemberAPI member, ShipVariantAPI currentVariant,
341 MarketAPI dockedAt, float width, boolean isForModSpec) {
342 // TODO Auto-generated method stub
343
344 }
345
346}
static SectorAPI getSector()
Definition Global.java:65
void addRequiredItemSection(TooltipMakerAPI tooltip, FleetMemberAPI member, ShipVariantAPI currentVariant, MarketAPI dockedAt, float width, boolean isForModSpec)
boolean canBeAddedOrRemovedNow(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode)
String getDescriptionParam(int index, HullSize hullSize, ShipAPI ship)
String getCanNotBeInstalledNowReason(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode)
void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec)
void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id)
boolean hasSModEffectSection(HullSize hullSize, ShipAPI ship, boolean isForModSpec)
boolean showInRefitScreenModPickerFor(ShipAPI ship)
String getSModDescriptionParam(int index, HullSize hullSize, ShipAPI ship)
String getSModDescriptionParam(int index, HullSize hullSize)
void applyEffectsAfterShipCreation(ShipAPI ship, String id)
void advanceInCampaign(FleetMemberAPI member, float amount)
Definition TowCable.java:64
void advanceInCombat(ShipAPI ship, float amount)
void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec)
void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec, boolean isForBuildInList)
void addSModEffectSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec, boolean isForBuildInList)
void applyEffectsToFighterSpawnedByShip(ShipAPI fighter, ShipAPI ship, String id)
boolean shouldAddDescriptionToTooltip(HullSize hullSize, ShipAPI ship, boolean isForModSpec)
String getDescriptionParam(int index, HullSize hullSize)
List< FleetMemberAPI > getMembersListCopy()
Map< String, Object > getPersistentData()