1package com.fs.starfarer.api.impl.campaign;
4import java.util.HashMap;
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;
23public class TowCable implements HullModEffect {
27 public void init(HullModSpecAPI spec) {
31 public static class TowCableBuff
implements Buff {
33 private String buffId;
34 private int frames = 0;
36 public TowCableBuff(String buffId) {
40 public boolean isExpired() {
44 public String getId() {
47 public void apply(FleetMemberAPI member) {
50 member.getStats().getMaxBurnLevel().modifyFlat(buffId, 1);
52 public void advance(
float days) {
63 if (member.getFleetData() ==
null)
return;
64 if (member.getFleetData().getFleet() ==
null)
return;
65 if (!member.getFleetData().getFleet().isPlayerFleet())
return;
68 if (!member.getVariant().getHullMods().contains(
HULLMOD_ID)) {
69 cleanUpTowCableBuffBy(member);
73 if (!member.canBeDeployedForCombat()) {
74 cleanUpTowCableBuffBy(member);
78 FleetDataAPI data = member.getFleetData();
79 List<FleetMemberAPI> all = data.getMembersListCopy();
82 int thisCableIndex = -1;
83 for (FleetMemberAPI curr : all) {
84 if (!curr.canBeDeployedForCombat())
continue;
85 if (curr.getVariant().getHullMods().contains(
HULLMOD_ID)) {
87 thisCableIndex = numCables;
92 if (numCables <= 0 || thisCableIndex == -1) {
93 cleanUpTowCableBuffBy(member);
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;
102 for (
int cableIndex = 0; cableIndex < numCables; cableIndex++) {
103 FleetMemberAPI slowest = getSlowest(all, towSpeed, cables);
104 if (slowest ==
null)
break;
106 Integer bonus = cables.get(slowest);
107 if (bonus ==
null) bonus =
new Integer(0);
109 cables.put(slowest, bonus);
111 if (cableIndex == thisCableIndex) {
112 thisCableTarget = slowest;
113 Buff existing = slowest.getBuffManager().getBuff(buff.getId());
114 if (existing == buff) {
123 slowest.getBuffManager().addBuff(buff);
131 for (FleetMemberAPI curr : all) {
132 if (curr != thisCableTarget) {
133 curr.getBuffManager().removeBuff(buff.getId());
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;
144 float baseBurn = getMaxBurnWithoutCables(curr);
145 Integer bonus = cables.get(curr);
146 if (bonus ==
null) bonus =
new Integer(0);
148 if (bonus >= getMaxCablesFor(curr))
continue;
150 float burnLevel = baseBurn + bonus;
152 if (burnLevel >= speedCutoff)
continue;
154 if (burnLevel < minLevel) {
155 minLevel = burnLevel;
162 private int getMaxCablesFor(FleetMemberAPI member) {
172 private float getMaxBurnWithoutCables(FleetMemberAPI member) {
173 MutableStat burn = member.getStats().getMaxBurnLevel();
174 float val = burn.getModifiedValue();
176 for (StatMod mod : burn.getFlatMods().values()) {
177 if (mod.getSource().startsWith(
HULLMOD_ID)) sub++;
179 return Math.max(0, val - sub);
182 private boolean isSuitable(FleetMemberAPI member) {
183 if (member.isFighterWing())
return false;
187 private void cleanUpTowCableBuffBy(FleetMemberAPI member) {
188 if (member.getFleetData() ==
null)
return;
189 FleetDataAPI data = member.getFleetData();
190 TowCableBuff buff = getTowCableBuffBy(member,
false);
192 for (FleetMemberAPI curr : data.getMembersListCopy()) {
193 curr.getBuffManager().removeBuff(buff.getId());
203 @SuppressWarnings(
"unchecked")
204 private TowCableBuff getTowCableBuffBy(FleetMemberAPI member,
boolean createIfMissing) {
205 Map<FleetMemberAPI, TowCableBuff> buffs;
209 buffs =
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);
292 public void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship,
float width,
293 boolean isForModSpec) {
298 boolean isForModSpec,
boolean isForBuildInList) {
303 public void addSModSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship,
float width,
304 boolean isForModSpec,
boolean isForBuildInList) {
static SectorAPI getSector()
String getUnapplicableReason(ShipAPI ship)
boolean canBeAddedOrRemovedNow(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode)
String getDescriptionParam(int index, HullSize hullSize, ShipAPI ship)
boolean isApplicableToShip(ShipAPI ship)
String getCanNotBeInstalledNowReason(ShipAPI ship, MarketAPI marketOrNull, CoreUITradeMode mode)
boolean isSModEffectAPenalty()
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)
int getDisplayCategoryIndex()
static final String HULLMOD_ID
int getDisplaySortOrder()
void advanceInCombat(ShipAPI ship, float amount)
void init(HullModSpecAPI spec)
void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, ShipAPI ship, float width, boolean isForModSpec)
static final String TOW_CABLE_KEY
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)