1package com.fs.starfarer.api.impl.hullmods;
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.LinkedHashSet;
12import com.fs.starfarer.api.GameState;
13import com.fs.starfarer.api.Global;
14import com.fs.starfarer.api.combat.BaseHullMod;
15import com.fs.starfarer.api.combat.MutableShipStatsAPI;
16import com.fs.starfarer.api.combat.ShipAPI;
17import com.fs.starfarer.api.combat.ShipAPI.HullSize;
18import com.fs.starfarer.api.combat.WeaponAPI;
19import com.fs.starfarer.api.combat.WeaponAPI.WeaponSize;
20import com.fs.starfarer.api.combat.WeaponAPI.WeaponType;
21import com.fs.starfarer.api.impl.campaign.ids.Tags;
22import com.fs.starfarer.api.loading.WeaponSlotAPI;
23import com.fs.starfarer.api.ui.Alignment;
24import com.fs.starfarer.api.ui.TooltipMakerAPI;
25import com.fs.starfarer.api.util.IntervalUtil;
26import com.fs.starfarer.api.util.Misc;
27import com.fs.starfarer.api.util.TimeoutTracker;
31 public static class ReloadCapacityData {
33 public int minW, maxW;
35 public ReloadCapacityData(HullSize size,
int minW,
int maxW,
int capacity) {
39 this.capacity = capacity;
42 public String getSizeStr() {
46 public String getWeaponsString() {
47 if (maxW < 0)
return "" + minW +
"+";
48 if (minW != maxW)
return "" + minW +
"-" + maxW;
55 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.FRIGATE, 1, 1, 6));
56 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.FRIGATE, 2, -1, 4));
58 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.DESTROYER, 1, 1, 9));
59 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.DESTROYER, 2, -1, 4));
61 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CRUISER, 1, 2, 15));
62 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CRUISER, 3, 3, 12));
63 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CRUISER, 4, -1, 8));
65 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CAPITAL_SHIP, 1, 3, 24));
66 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CAPITAL_SHIP, 4, 6, 18));
67 CAPACITY_DATA.add(
new ReloadCapacityData(HullSize.CAPITAL_SHIP, 7, -1, 10));
73 public static String
MA_DATA_KEY =
"core_missile_autoloader_data_key";
75 public static class MissileAutoloaderData {
77 public float opLeft = 0f;
78 public float showExhaustedStatus = 5f;
88 super.advanceInCombat(ship, amount);
94 MissileAutoloaderData data = (MissileAutoloaderData) ship.
getCustomData().get(key);
96 data =
new MissileAutoloaderData();
100 data.opLeft = cap.capacity;
102 data.showExhaustedStatus = 0;
107 if (data.opLeft <= 0.05f) {
109 data.showExhaustedStatus -= amount;
110 if (data.showExhaustedStatus <= 0) {
119 data.cooldown.advance(amount * mult);
120 for (
WeaponAPI w : data.cooldown.getItems()) {
121 w.setRemainingCooldownTo(w.getCooldown());
125 if (data.interval.intervalElapsed()) {
126 boolean playSound =
false;
129 if (data.cooldown.contains(w))
continue;
131 if (w.usesAmmo() && w.getAmmo() <= 0) {
132 float reloadSize = w.getSpec().getMaxAmmo();
134 float salvoSize = w.getSpec().getBurstSize();
135 if (salvoSize < 1) salvoSize = 1;
136 if (reloadCost > data.opLeft) {
137 float f = data.opLeft / reloadCost;
138 if (f <= 0f)
continue;
141 reloadSize /= salvoSize;
142 reloadSize = (float) Math.ceil(reloadSize);
143 reloadSize *= salvoSize;
144 reloadSize = (int) Math.round(reloadSize);
149 w.setAmmo((
int) reloadSize);
150 boolean sMod =
isSMod(ship);
162 data.opLeft -= reloadCost;
165 if (data.opLeft < 0) data.opLeft = 0;
166 if (data.opLeft <= 0)
break;
171 if (playerShip && playSound) {
178 if (data.opLeft <= 0) status =
"CAPACITY EXHAUSTED";
182 status, data.opLeft <= 0);
188 if (ship ==
null)
return null;
197 if (slot.getSlotSize() == WeaponSize.SMALL &&
198 slot.getWeaponType() == WeaponType.MISSILE) {
205 if (count >= data.minW && count <= data.maxW)
return data;
206 if (count >= data.minW && data.maxW < 0)
return data;
213 if (w ==
null)
return false;
214 if (w.
getType() != WeaponType.MISSILE)
return false;
215 if (w.
getSize() != WeaponSize.SMALL)
return false;
237 if (op == 1)
return 1f;
238 if (op == 2 || op == 3)
return 2f;
239 if (op == 4)
return 3f;
240 if (op == 5 || op == 6)
return 4f;
241 if (op == 7 || op == 8)
return 5f;
258 tooltip.
addPara(
"A combat-rated autoloader that provides a limited number of reloads, out of a shared reload capacity, to "
259 +
"missile weapons installed in small missile mounts.", opad, h,
"missile weapons installed in small missile mounts");
264 tooltip.
addPara(
"Does not affect weapons that do not use ammo or regenerate it, or are mounted in any other type of slot."
265 +
" Reload size is not affected by skills or hullmods that "
266 +
"increase missile ammo capacity.", opad);
275 tooltip.
addPara(
"Determined by ship size and number of small missile "
276 +
"slots, both filled and empty. "
277 +
"Having fewer of these simplifies the task and "
278 +
"increases the number of possible reloads.", opad);
284 List<WeaponAPI> weapons =
new ArrayList<WeaponAPI>();
285 Set<String> seen =
new LinkedHashSet<String>();
289 String
id = w.getId();
290 if (seen.contains(
id))
continue;
297 float reloadW = 130f;
298 float sizeW = width - numW - reloadW - 10f;
301 new Object [] {
"Ship size", sizeW,
"Small missiles", numW,
"Reload capacity", reloadW});
305 List<ReloadCapacityData> sortedCap =
new ArrayList<ReloadCapacityData>(
CAPACITY_DATA);
306 Collections.sort(sortedCap,
new Comparator<ReloadCapacityData>() {
307 public int compare(ReloadCapacityData o1, ReloadCapacityData o2) {
309 if (o1.size != o2.size) {
310 return (
int) Math.signum(o1.size.ordinal() - o2.size.ordinal());
312 return (
int) Math.signum(o1.capacity - o2.capacity);
317 HullSize prev = HullSize.FRIGATE;
318 for (ReloadCapacityData curr : sortedCap) {
340 Collections.sort(weapons,
new Comparator<WeaponAPI>() {
344 return (
int) Math.signum(c1 - c2);
352 float nameW = width - costW - 5f;
355 new Object [] {
"Affected weapon", nameW,
"Reload cost", costW});
361 String name = tooltip.
shortenString(w.getDisplayName(), nameW - 20f);
364 if (count >= max)
break;
366 tooltip.
addTable(
"No affected weapons mounted", weapons.size() - max, opad);
369 tooltip.
addPara(
"A partial reload is possible when running out of capacity.", opad);
374 tooltip.
addPara(
"After a reload, the weapon requires an extra %s seconds,"
375 +
" in addition to its normal cooldown, before it can fire again.", opad,
389 return "Ship does not have any small missile slots";
static SettingsAPI getSettings()
static boolean CODEX_TOOLTIP_MODE
static SoundPlayerAPI getSoundPlayer()
static CombatEngineAPI getCombatEngine()
static GameState getCurrentState()
boolean isSMod(MutableShipStatsAPI stats)
void applyEffectsBeforeShipCreation(HullSize hullSize, MutableShipStatsAPI stats, String id)
static boolean isAffected(WeaponAPI w)
static float SMOD_COOLDOWN
boolean isApplicableToShip(ShipAPI ship)
boolean isSModEffectAPenalty()
String getUnapplicableReason(ShipAPI ship)
static List< ReloadCapacityData > CAPACITY_DATA
static float BASIC_COOLDOWN
static String MA_DATA_KEY
boolean shouldAddDescriptionToTooltip(HullSize hullSize, ShipAPI ship, boolean isForModSpec)
String getSModDescriptionParam(int index, HullSize hullSize, ShipAPI ship)
void addPostDescriptionSection(TooltipMakerAPI tooltip, HullSize hullSize, final ShipAPI ship, float width, boolean isForModSpec)
void advanceInCombat(ShipAPI ship, float amount)
static float getReloadCost(WeaponAPI w, ShipAPI ship)
static ReloadCapacityData getCapacityData(ShipAPI ship)
void advance(float amount)
static Color getTextColor()
static Color getNegativeHighlightColor()
static String getHullSizeStr(HullSize size)
static Color getBasePlayerColor()
static Color getGrayColor()
static Color getBrightPlayerColor()
static Color getHighlightColor()
static Color getDarkPlayerColor()
static String getRoundedValueOneAfterDecimalIfNotWhole(float value)
String getSpriteName(String category, String id)
SoundAPI playSound(String id, float pitch, float volume, Vector2f loc, Vector2f vel)
void maintainStatusForPlayerShip(Object key, String spriteName, String title, String data, boolean isDebuff)
void setCustomData(String key, Object data)
Map< String, Object > getCustomData()
MutableStat getMissileRoFMult()
ShipHullSpecAPI getHullSpec()
MutableShipStatsAPI getMutableStats()
List< WeaponAPI > getAllWeapons()
List< WeaponSlotAPI > getAllWeaponSlotsCopy()
WeaponAPI.WeaponSize getSlotSize()
WeaponAPI.WeaponType getWeaponType()
boolean hasTag(String tag)
float getOrdnancePointCost(MutableCharacterStatsAPI stats)