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